]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.drivers/staging-add-rtl8187se-driver.patch
Reenabled linux-xen and xen-image build
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / staging-add-rtl8187se-driver.patch
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
5 Patch-mainline: 2.6.29
6
7 From: Greg Kroah-Hartman <gregkh@suse.de>
8
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.
13
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.
18
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>
22
23 ---
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(+)
71
72 --- a/drivers/staging/Kconfig
73 +++ b/drivers/staging/Kconfig
74 @@ -51,4 +51,6 @@ source "drivers/staging/rt2860/Kconfig"
75
76 source "drivers/staging/benet/Kconfig"
77
78 +source "drivers/staging/rtl8187se/Kconfig"
79 +
80 endif # STAGING
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/
88 --- /dev/null
89 +++ b/drivers/staging/rtl8187se/dot11d.h
90 @@ -0,0 +1,101 @@
91 +#ifndef __INC_DOT11D_H
92 +#define __INC_DOT11D_H
93 +
94 +#include "ieee80211.h"
95 +
96 +//#define ENABLE_DOT11D
97 +
98 +//#define DOT11D_MAX_CHNL_NUM 83
99 +
100 +typedef struct _CHNL_TXPOWER_TRIPLE {
101 + u8 FirstChnl;
102 + u8 NumChnls;
103 + u8 MaxTxPowerInDbm;
104 +}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
105 +
106 +typedef enum _DOT11D_STATE {
107 + DOT11D_STATE_NONE = 0,
108 + DOT11D_STATE_LEARNED,
109 + DOT11D_STATE_DONE,
110 +}DOT11D_STATE;
111 +
112 +typedef struct _RT_DOT11D_INFO {
113 + //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
114 +
115 + bool bEnabled; // dot11MultiDomainCapabilityEnabled
116 +
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;
121 +
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];
126 +
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))
132 +
133 +#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
134 +#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
135 +
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)
138 +
139 +#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
140 + (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
141 + FALSE : \
142 + (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
143 +
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)
148 +
149 +#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
150 +
151 +
152 +void
153 +Dot11d_Init(
154 + struct ieee80211_device *dev
155 + );
156 +
157 +void
158 +Dot11d_Reset(
159 + struct ieee80211_device *dev
160 + );
161 +
162 +void
163 +Dot11d_UpdateCountryIe(
164 + struct ieee80211_device *dev,
165 + u8 * pTaddr,
166 + u16 CoutryIeLen,
167 + u8 * pCoutryIe
168 + );
169 +
170 +u8
171 +DOT11D_GetMaxTxPwrInDbm(
172 + struct ieee80211_device *dev,
173 + u8 Channel
174 + );
175 +
176 +void
177 +DOT11D_ScanComplete(
178 + struct ieee80211_device * dev
179 + );
180 +
181 +int IsLegalChannel(
182 + struct ieee80211_device * dev,
183 + u8 channel
184 +);
185 +
186 +int ToLegalChannel(
187 + struct ieee80211_device * dev,
188 + u8 channel
189 +);
190 +
191 +#endif // #ifndef __INC_DOT11D_H
192 --- /dev/null
193 +++ b/drivers/staging/rtl8187se/ieee80211_crypt.h
194 @@ -0,0 +1,86 @@
195 +/*
196 + * Original code based on Host AP (software wireless LAN access point) driver
197 + * for Intersil Prism2/2.5/3.
198 + *
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>
202 + *
203 + * Adaption to a generic IEEE 802.11 stack by James Ketrenos
204 + * <jketreno@linux.intel.com>
205 + *
206 + * Copyright (c) 2004, Intel Corporation
207 + *
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
211 + * more details.
212 + */
213 +
214 +/*
215 + * This file defines the interface to the ieee80211 crypto module.
216 + */
217 +#ifndef IEEE80211_CRYPT_H
218 +#define IEEE80211_CRYPT_H
219 +
220 +#include <linux/skbuff.h>
221 +
222 +struct ieee80211_crypto_ops {
223 + const char *name;
224 +
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);
229 +
230 + /* deinitialize crypto context and free allocated private data */
231 + void (*deinit)(void *priv);
232 +
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).
238 + */
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);
241 +
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,
246 + void *priv);
247 +
248 + int (*set_key)(void *key, int len, u8 *seq, void *priv);
249 + int (*get_key)(void *key, int len, u8 *seq, void *priv);
250 +
251 + /* procfs handler for printing out key information and possible
252 + * statistics */
253 + char * (*print_stats)(char *p, void *priv);
254 +
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;
261 +
262 + struct module *owner;
263 +};
264 +
265 +struct ieee80211_crypt_data {
266 + struct list_head list; /* delayed deletion list */
267 + struct ieee80211_crypto_ops *ops;
268 + void *priv;
269 + atomic_t refcnt;
270 +};
271 +
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);
279 +
280 +#endif
281 --- /dev/null
282 +++ b/drivers/staging/rtl8187se/ieee80211/dot11d.c
283 @@ -0,0 +1,246 @@
284 +#ifdef ENABLE_DOT11D
285 +//-----------------------------------------------------------------------------
286 +// File:
287 +// Dot11d.c
288 +//
289 +// Description:
290 +// Implement 802.11d.
291 +//
292 +//-----------------------------------------------------------------------------
293 +
294 +#include "dot11d.h"
295 +
296 +void
297 +Dot11d_Init(struct ieee80211_device *ieee)
298 +{
299 + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
300 +
301 + pDot11dInfo->bEnabled = 0;
302 +
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);
308 +
309 + printk("Dot11d_Init()\n");
310 +}
311 +
312 +//
313 +// Description:
314 +// Reset to the state as we are just entering a regulatory domain.
315 +//
316 +void
317 +Dot11d_Reset(struct ieee80211_device *ieee)
318 +{
319 + u32 i;
320 + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
321 +
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;
328 + }
329 + for (i=12; i<=14; i++) {
330 + (pDot11dInfo->channel_map)[i] = 2;
331 + }
332 +
333 + pDot11dInfo->State = DOT11D_STATE_NONE;
334 + pDot11dInfo->CountryIeLen = 0;
335 + RESET_CIE_WATCHDOG(ieee);
336 +
337 + //printk("Dot11d_Reset()\n");
338 +}
339 +
340 +//
341 +// Description:
342 +// Update country IE from Beacon or Probe Resopnse
343 +// and configure PHY for operation in the regulatory domain.
344 +//
345 +// TODO:
346 +// Configure Tx power.
347 +//
348 +// Assumption:
349 +// 1. IS_DOT11D_ENABLE() is TRUE.
350 +// 2. Input IE is an valid one.
351 +//
352 +void
353 +Dot11d_UpdateCountryIe(
354 + struct ieee80211_device *dev,
355 + u8 * pTaddr,
356 + u16 CoutryIeLen,
357 + u8 * pCoutryIe
358 + )
359 +{
360 + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
361 + u8 i, j, NumTriples, MaxChnlNum;
362 + PCHNL_TXPOWER_TRIPLE pTriple;
363 +
364 + if((CoutryIeLen - 3)%3 != 0)
365 + {
366 + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
367 + Dot11d_Reset(dev);
368 + return;
369 + }
370 +
371 + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
372 + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
373 + MaxChnlNum = 0;
374 + NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.
375 + pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
376 + for(i = 0; i < NumTriples; i++)
377 + {
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");
381 + Dot11d_Reset(dev);
382 + return;
383 + }
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");
387 + Dot11d_Reset(dev);
388 + return;
389 + }
390 +
391 + for(j = 0 ; j < pTriple->NumChnls; j++)
392 + {
393 + pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
394 + pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;
395 + MaxChnlNum = pTriple->FirstChnl + j;
396 + }
397 +
398 + pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);
399 + }
400 +#if 1
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)
405 + printk(" %d", i);
406 + printk("\n");
407 +#endif
408 +
409 + UPDATE_CIE_SRC(dev, pTaddr);
410 +
411 + pDot11dInfo->CountryIeLen = CoutryIeLen;
412 + memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen);
413 + pDot11dInfo->State = DOT11D_STATE_LEARNED;
414 +}
415 +
416 +void dump_chnl_map(u8 * channel_map)
417 +{
418 + int i;
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]);
423 + printk("\n");
424 +}
425 +
426 +u8
427 +DOT11D_GetMaxTxPwrInDbm(
428 + struct ieee80211_device *dev,
429 + u8 Channel
430 + )
431 +{
432 + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
433 + u8 MaxTxPwrInDbm = 255;
434 +
435 + if(MAX_CHANNEL_NUMBER < Channel)
436 + {
437 + printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
438 + return MaxTxPwrInDbm;
439 + }
440 + if(pDot11dInfo->channel_map[Channel])
441 + {
442 + MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
443 + }
444 +
445 + return MaxTxPwrInDbm;
446 +}
447 +
448 +
449 +void
450 +DOT11D_ScanComplete(
451 + struct ieee80211_device * dev
452 + )
453 +{
454 + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
455 +
456 + switch(pDot11dInfo->State)
457 + {
458 + case DOT11D_STATE_LEARNED:
459 + pDot11dInfo->State = DOT11D_STATE_DONE;
460 + break;
461 +
462 + case DOT11D_STATE_DONE:
463 + if( GET_CIE_WATCHDOG(dev) == 0 )
464 + { // Reset country IE if previous one is gone.
465 + Dot11d_Reset(dev);
466 + }
467 + break;
468 + case DOT11D_STATE_NONE:
469 + break;
470 + }
471 +}
472 +
473 +int IsLegalChannel(
474 + struct ieee80211_device * dev,
475 + u8 channel
476 +)
477 +{
478 + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
479 +
480 + if(MAX_CHANNEL_NUMBER < channel)
481 + {
482 + printk("IsLegalChannel(): Invalid Channel\n");
483 + return 0;
484 + }
485 + if(pDot11dInfo->channel_map[channel] > 0)
486 + return 1;
487 + return 0;
488 +}
489 +
490 +int ToLegalChannel(
491 + struct ieee80211_device * dev,
492 + u8 channel
493 +)
494 +{
495 + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
496 + u8 default_chn = 0;
497 + u32 i = 0;
498 +
499 + for (i=1; i<= MAX_CHANNEL_NUMBER; i++)
500 + {
501 + if(pDot11dInfo->channel_map[i] > 0)
502 + {
503 + default_chn = i;
504 + break;
505 + }
506 + }
507 +
508 + if(MAX_CHANNEL_NUMBER < channel)
509 + {
510 + printk("IsLegalChannel(): Invalid Channel\n");
511 + return default_chn;
512 + }
513 +
514 + if(pDot11dInfo->channel_map[channel] > 0)
515 + return channel;
516 +
517 + return default_chn;
518 +}
519 +
520 +#if 0
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);
528 +#endif
529 +#endif
530 --- /dev/null
531 +++ b/drivers/staging/rtl8187se/ieee80211/dot11d.h
532 @@ -0,0 +1,102 @@
533 +#ifndef __INC_DOT11D_H
534 +#define __INC_DOT11D_H
535 +
536 +#include "ieee80211.h"
537 +
538 +//#define ENABLE_DOT11D
539 +
540 +//#define DOT11D_MAX_CHNL_NUM 83
541 +
542 +typedef struct _CHNL_TXPOWER_TRIPLE {
543 + u8 FirstChnl;
544 + u8 NumChnls;
545 + u8 MaxTxPowerInDbm;
546 +}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
547 +
548 +typedef enum _DOT11D_STATE {
549 + DOT11D_STATE_NONE = 0,
550 + DOT11D_STATE_LEARNED,
551 + DOT11D_STATE_DONE,
552 +}DOT11D_STATE;
553 +
554 +typedef struct _RT_DOT11D_INFO {
555 + //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
556 +
557 + bool bEnabled; // dot11MultiDomainCapabilityEnabled
558 +
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;
563 +
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];
568 +
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))
574 +
575 +#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
576 +#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
577 +
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)
580 +
581 +#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
582 + (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
583 + FALSE : \
584 + (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
585 +
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)
590 +
591 +#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
592 +
593 +
594 +void
595 +Dot11d_Init(
596 + struct ieee80211_device *dev
597 + );
598 +
599 +void
600 +Dot11d_Reset(
601 + struct ieee80211_device *dev
602 + );
603 +
604 +void
605 +Dot11d_UpdateCountryIe(
606 + struct ieee80211_device *dev,
607 + u8 * pTaddr,
608 + u16 CoutryIeLen,
609 + u8 * pCoutryIe
610 + );
611 +
612 +u8
613 +DOT11D_GetMaxTxPwrInDbm(
614 + struct ieee80211_device *dev,
615 + u8 Channel
616 + );
617 +
618 +void
619 +DOT11D_ScanComplete(
620 + struct ieee80211_device * dev
621 + );
622 +
623 +int IsLegalChannel(
624 + struct ieee80211_device * dev,
625 + u8 channel
626 +);
627 +
628 +int ToLegalChannel(
629 + struct ieee80211_device * dev,
630 + u8 channel
631 +);
632 +
633 +void dump_chnl_map(u8 * channel_map);
634 +#endif // #ifndef __INC_DOT11D_H
635 --- /dev/null
636 +++ b/drivers/staging/rtl8187se/ieee80211.h
637 @@ -0,0 +1,1755 @@
638 +/*
639 + * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11
640 + * remains copyright by the original authors
641 + *
642 + * Portions of the merged code are based on Host AP (software wireless
643 + * LAN access point) driver for Intersil Prism2/2.5/3.
644 + *
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>
648 + *
649 + * Adaption to a generic IEEE 802.11 stack by James Ketrenos
650 + * <jketreno@linux.intel.com>
651 + * Copyright (c) 2004, Intel Corporation
652 + *
653 + * Modified for Realtek's wi-fi cards by Andrea Merello
654 + * <andreamrl@tiscali.it>
655 + *
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
659 + * more details.
660 + */
661 +#ifndef IEEE80211_H
662 +#define IEEE80211_H
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>
669 +
670 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13))
671 +#include <linux/wireless.h>
672 +#endif
673 +
674 +/*
675 +#ifndef bool
676 +#define bool int
677 +#endif
678 +
679 +#ifndef true
680 +#define true 1
681 +#endif
682 +
683 +#ifndef false
684 +#define false 0
685 +#endif
686 +*/
687 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
688 +#ifndef bool
689 +typedef enum{false = 0, true} bool;
690 +#endif
691 +#endif
692 +//#ifdef JOHN_HWSEC
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
698 +//#endif
699 +
700 +
701 +#define aSifsTime 10
702 +
703 +#define MGMT_QUEUE_NUM 5
704 +
705 +
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
710 +
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
718 +// David, 2006.9.26
719 +#define IEEE_PARAM_WPAX_SELECT 7
720 +//Added for notify the encryption type selection
721 +// David, 2006.9.26
722 +#define IEEE_PROTO_WPA 1
723 +#define IEEE_PROTO_RSN 2
724 +//Added for notify the encryption type selection
725 +// David, 2006.9.26
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
732 +
733 +#define IEEE_KEY_MGMT_IEEE8021X 1
734 +#define IEEE_KEY_MGMT_PSK 2
735 +
736 +
737 +
738 +#define IEEE_MLME_STA_DEAUTH 1
739 +#define IEEE_MLME_STA_DISASSOC 2
740 +
741 +
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
748 +
749 +
750 +#define IEEE_CRYPT_ALG_NAME_LEN 16
751 +
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 +///////////////////////////////
762 +#endif
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
766 +
767 +#define ieee80211_rx ieee80211_rx_rtl
768 +
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
775 +
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
797 +
798 +#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rtl
799 +//by amy for ps
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
804 +//by amy for ps
805 +typedef struct ieee_param {
806 + u32 cmd;
807 + u8 sta_addr[ETH_ALEN];
808 + union {
809 + struct {
810 + u8 name;
811 + u32 value;
812 + } wpa_param;
813 + struct {
814 + u32 len;
815 + u8 reserved[32];
816 + u8 data[0];
817 + } wpa_ie;
818 + struct{
819 + int command;
820 + int reason_code;
821 + } mlme;
822 + struct {
823 + u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
824 + u8 set_tx;
825 + u32 err;
826 + u8 idx;
827 + u8 seq[8]; /* sequence counter (set: RX, get: TX) */
828 + u16 key_len;
829 + u8 key[0];
830 + } crypt;
831 +
832 + } u;
833 +}ieee_param;
834 +
835 +
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
843 +#endif
844 +
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)
849 +{
850 + unsigned long timeout = MSECS(msecs) + 1;
851 +
852 + while (timeout) {
853 + set_current_state(TASK_UNINTERRUPTIBLE);
854 + timeout = schedule_timeout(timeout);
855 + }
856 + return timeout;
857 +}
858 +#else
859 +#define MSECS(t) msecs_to_jiffies(t)
860 +#define msleep_interruptible_rtl msleep_interruptible
861 +#endif
862 +
863 +#define IEEE80211_DATA_LEN 2304
864 +/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
865 + 6.2.1.1.2.
866 +
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) */
871 +
872 +
873 +#define IEEE80211_HLEN 30
874 +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
875 +
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
881 +
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))
885 +
886 +/* this is stolen from ipw2200 driver */
887 +#define IEEE_IBSS_MAC_HASH_SIZE 31
888 +struct ieee_ibss_seq {
889 + u8 mac[ETH_ALEN];
890 + u16 seq_num[17];
891 + u16 frag_num[17];
892 + unsigned long packet_time[17];
893 + struct list_head list;
894 +};
895 +
896 +struct ieee80211_hdr {
897 + u16 frame_ctl;
898 + u16 duration_id;
899 + u8 addr1[ETH_ALEN];
900 + u8 addr2[ETH_ALEN];
901 + u8 addr3[ETH_ALEN];
902 + u16 seq_ctl;
903 + u8 addr4[ETH_ALEN];
904 +} __attribute__ ((packed));
905 +
906 +struct ieee80211_hdr_QOS {
907 + u16 frame_ctl;
908 + u16 duration_id;
909 + u8 addr1[ETH_ALEN];
910 + u8 addr2[ETH_ALEN];
911 + u8 addr3[ETH_ALEN];
912 + u16 seq_ctl;
913 + u8 addr4[ETH_ALEN];
914 + u16 QOS_ctl;
915 +} __attribute__ ((packed));
916 +
917 +struct ieee80211_hdr_3addr {
918 + u16 frame_ctl;
919 + u16 duration_id;
920 + u8 addr1[ETH_ALEN];
921 + u8 addr2[ETH_ALEN];
922 + u8 addr3[ETH_ALEN];
923 + u16 seq_ctl;
924 +} __attribute__ ((packed));
925 +
926 +struct ieee80211_hdr_3addr_QOS {
927 + u16 frame_ctl;
928 + u16 duration_id;
929 + u8 addr1[ETH_ALEN];
930 + u8 addr2[ETH_ALEN];
931 + u8 addr3[ETH_ALEN];
932 + u16 seq_ctl;
933 + u16 QOS_ctl;
934 +} __attribute__ ((packed));
935 +
936 +enum eap_type {
937 + EAP_PACKET = 0,
938 + EAPOL_START,
939 + EAPOL_LOGOFF,
940 + EAPOL_KEY,
941 + EAPOL_ENCAP_ASF_ALERT
942 +};
943 +
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"
950 +};
951 +
952 +static inline const char *eap_get_type(int type)
953 +{
954 + return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
955 +}
956 +
957 +struct eapol {
958 + u8 snap[6];
959 + u16 ethertype;
960 + u8 version;
961 + u8 type;
962 + u16 length;
963 +} __attribute__ ((packed));
964 +
965 +#define IEEE80211_3ADDR_LEN 24
966 +#define IEEE80211_4ADDR_LEN 30
967 +#define IEEE80211_FCS_LEN 4
968 +
969 +#define MIN_FRAG_THRESHOLD 256U
970 +#define MAX_FRAG_THRESHOLD 2346U
971 +
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
985 +
986 +#define IEEE80211_FTYPE_MGMT 0x0000
987 +#define IEEE80211_FTYPE_CTL 0x0004
988 +#define IEEE80211_FTYPE_DATA 0x0008
989 +
990 +/* management */
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
1003 +
1004 +/* control */
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
1011 +
1012 +/* data */
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
1023 +
1024 +
1025 +#define IEEE80211_SCTL_FRAG 0x000F
1026 +#define IEEE80211_SCTL_SEQ 0xFFF0
1027 +
1028 +
1029 +/* debug macros */
1030 +
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)
1037 +#else
1038 +#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
1039 +#endif /* CONFIG_IEEE80211_DEBUG */
1040 +
1041 +/*
1042 + * To use the debug system;
1043 + *
1044 + * If you are defining a new debug classification, simply add it to the #define
1045 + * list here in the form of:
1046 + *
1047 + * #define IEEE80211_DL_xxxx VALUE
1048 + *
1049 + * shifting value to the left one bit from the previous entry. xxxx should be
1050 + * the name of the classification (for example, WEP)
1051 + *
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.
1055 + *
1056 + * To add your debug level to the list of levels seen when you perform
1057 + *
1058 + * % cat /proc/net/ipw/debug_level
1059 + *
1060 + * you simply need to add your entry to the ipw_debug_levels array.
1061 + *
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
1064 + *
1065 + */
1066 +
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)
1075 +
1076 +#define IEEE80211_DL_TX (1<<8)
1077 +#define IEEE80211_DL_RX (1<<9)
1078 +
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)
1082 +
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 */
1096 +
1097 +#ifndef WIRELESS_SPY
1098 +#define WIRELESS_SPY // enable iwspy support
1099 +#endif
1100 +#include <net/iw_handler.h> // new driver API
1101 +
1102 +#ifndef ETH_P_PAE
1103 +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
1104 +#endif /* ETH_P_PAE */
1105 +
1106 +#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
1107 +
1108 +#ifndef ETH_P_80211_RAW
1109 +#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
1110 +#endif
1111 +
1112 +/* IEEE 802.11 defines */
1113 +
1114 +#define P80211_OUI_LEN 3
1115 +
1116 +struct ieee80211_snap_hdr {
1117 +
1118 + u8 dsap; /* always 0xAA */
1119 + u8 ssap; /* always 0xAA */
1120 + u8 ctrl; /* always 0x03 */
1121 + u8 oui[P80211_OUI_LEN]; /* organizational universal id */
1122 +
1123 +} __attribute__ ((packed));
1124 +
1125 +#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
1126 +
1127 +#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
1128 +#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
1129 +
1130 +#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
1131 +#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ)
1132 +
1133 +/* Authentication algorithms */
1134 +#define WLAN_AUTH_OPEN 0
1135 +#define WLAN_AUTH_SHARED_KEY 1
1136 +
1137 +#define WLAN_AUTH_CHALLENGE_LEN 128
1138 +
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)
1148 +
1149 +/* Status codes */
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
1161 +/* 802.11b */
1162 +#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
1163 +#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
1164 +#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
1165 +
1166 +/* Reason codes */
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
1176 +
1177 +
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
1189 +
1190 +#define IEEE80211_MGMT_HDR_LEN 24
1191 +#define IEEE80211_DATA_HDR3_LEN 24
1192 +#define IEEE80211_DATA_HDR4_LEN 30
1193 +
1194 +
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
1200 +
1201 +
1202 +#define IEEE80211_CCK_MODULATION (1<<0)
1203 +#define IEEE80211_OFDM_MODULATION (1<<1)
1204 +
1205 +#define IEEE80211_24GHZ_BAND (1<<0)
1206 +#define IEEE80211_52GHZ_BAND (1<<1)
1207 +
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
1223 +
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)
1236 +
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)
1243 +
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)
1256 +
1257 +#define IEEE80211_NUM_OFDM_RATES 8
1258 +#define IEEE80211_NUM_CCK_RATES 4
1259 +#define IEEE80211_OFDM_SHIFT_MASK_A 4
1260 +
1261 +
1262 +
1263 +
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 {
1268 + u32 mac_time[2];
1269 + u8 signalstrength;
1270 + s8 rssi;
1271 + u8 signal;
1272 + u8 noise;
1273 + u16 rate; /* in 100 kbps */
1274 + u8 received_channel;
1275 + u8 control;
1276 + u8 mask;
1277 + u8 freq;
1278 + u16 len;
1279 + u8 nic_type;
1280 +};
1281 +
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
1287 +
1288 +struct ieee80211_frag_entry {
1289 + unsigned long first_frag_time;
1290 + unsigned int seq;
1291 + unsigned int last_frag;
1292 + struct sk_buff *skb;
1293 + u8 src_addr[ETH_ALEN];
1294 + u8 dst_addr[ETH_ALEN];
1295 +};
1296 +
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;
1319 +};
1320 +
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;
1339 +};
1340 +
1341 +struct ieee80211_device;
1342 +
1343 +#include "ieee80211_crypt.h"
1344 +
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)
1354 +
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 */
1360 +
1361 +#define WEP_KEYS 4
1362 +#define WEP_KEY_LEN 13
1363 +
1364 +#define WEP_KEY_LEN_MODIF 32
1365 +
1366 +struct ieee80211_security {
1367 + u16 active_key:2,
1368 + enabled:1,
1369 + auth_mode:2,
1370 + auth_algo:4,
1371 + unicast_uses_group:1;
1372 + u8 key_sizes[WEP_KEYS];
1373 + u8 keys[WEP_KEYS][WEP_KEY_LEN_MODIF];
1374 + u8 level;
1375 + u16 flags;
1376 +} __attribute__ ((packed));
1377 +
1378 +
1379 +/*
1380 +
1381 + 802.11 data frame from AP
1382 +
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 + `-------------------------------------------------------------------'
1389 +
1390 +Total: 28-2340 bytes
1391 +
1392 +*/
1393 +
1394 +struct ieee80211_header_data {
1395 + u16 frame_ctl;
1396 + u16 duration_id;
1397 + u8 addr1[6];
1398 + u8 addr2[6];
1399 + u8 addr3[6];
1400 + u16 seq_ctrl;
1401 +};
1402 +
1403 +#define BEACON_PROBE_SSID_ID_POSITION 12
1404 +
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
1419 +
1420 +#ifdef ENABLE_DOT11D
1421 +typedef enum
1422 +{
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;
1435 +#endif
1436 +
1437 +struct ieee80211_info_element_hdr {
1438 + u8 id;
1439 + u8 len;
1440 +} __attribute__ ((packed));
1441 +
1442 +struct ieee80211_info_element {
1443 + u8 id;
1444 + u8 len;
1445 + u8 data[0];
1446 +} __attribute__ ((packed));
1447 +
1448 +/*
1449 + * These are the data types that can make up management packets
1450 + *
1451 + u16 auth_algorithm;
1452 + u16 auth_sequence;
1453 + u16 beacon_interval;
1454 + u16 capability;
1455 + u8 current_ap[ETH_ALEN];
1456 + u16 listen_interval;
1457 + struct {
1458 + u16 association_id:14, reserved:2;
1459 + } __attribute__ ((packed));
1460 + u32 time_stamp[2];
1461 + u16 reason;
1462 + u16 status;
1463 +*/
1464 +
1465 +#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
1466 +#define IEEE80211_DEFAULT_BASIC_RATE 10
1467 +
1468 +struct ieee80211_authentication {
1469 + struct ieee80211_header_data header;
1470 + u16 algorithm;
1471 + u16 transaction;
1472 + u16 status;
1473 + //struct ieee80211_info_element_hdr info_element;
1474 +} __attribute__ ((packed));
1475 +
1476 +
1477 +struct ieee80211_probe_response {
1478 + struct ieee80211_header_data header;
1479 + u32 time_stamp[2];
1480 + u16 beacon_interval;
1481 + u16 capability;
1482 + struct ieee80211_info_element info_element;
1483 +} __attribute__ ((packed));
1484 +
1485 +struct ieee80211_probe_request {
1486 + struct ieee80211_header_data header;
1487 + /*struct ieee80211_info_element info_element;*/
1488 +} __attribute__ ((packed));
1489 +
1490 +struct ieee80211_assoc_request_frame {
1491 + struct ieee80211_hdr_3addr header;
1492 + u16 capability;
1493 + u16 listen_interval;
1494 + //u8 current_ap[ETH_ALEN];
1495 + struct ieee80211_info_element_hdr info_element;
1496 +} __attribute__ ((packed));
1497 +
1498 +struct ieee80211_assoc_response_frame {
1499 + struct ieee80211_hdr_3addr header;
1500 + u16 capability;
1501 + u16 status;
1502 + u16 aid;
1503 + struct ieee80211_info_element info_element; /* supported rates */
1504 +} __attribute__ ((packed));
1505 +
1506 +struct ieee80211_disassoc_frame{
1507 + struct ieee80211_hdr_3addr header;
1508 + u16 reasoncode;
1509 +}__attribute__ ((packed));
1510 +
1511 +struct ieee80211_txb {
1512 + u8 nr_frags;
1513 + u8 encrypted;
1514 + u16 reserved;
1515 + u16 frag_size;
1516 + u16 payload_size;
1517 + struct sk_buff *fragments[0];
1518 +};
1519 +
1520 +struct ieee80211_wmm_ac_param {
1521 + u8 ac_aci_acm_aifsn;
1522 + u8 ac_ecwmin_ecwmax;
1523 + u16 ac_txop_limit;
1524 +};
1525 +
1526 +struct ieee80211_wmm_ts_info {
1527 + u8 ac_dir_tid;
1528 + u8 ac_up_psb;
1529 + u8 reserved;
1530 +} __attribute__ ((packed));
1531 +
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;
1538 + u32 inact_inter;
1539 + u32 suspen_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;
1545 + u32 delay_bound;
1546 + u32 min_phy_rate;
1547 + u16 surp_band_allow;
1548 + u16 medium_time;
1549 +}__attribute__((packed));
1550 +
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)
1555 +
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
1569 +
1570 +typedef struct _CHANNEL_LIST{
1571 + u8 Channel[MAX_CHANNEL_NUMBER + 1];
1572 + u8 Len;
1573 +}CHANNEL_LIST, *PCHANNEL_LIST;
1574 +
1575 +#define IEEE80211_SOFTMAC_SCAN_TIME 100//400
1576 +//(HZ / 2)
1577 +//by amy for ps
1578 +#define IEEE80211_WATCH_DOG_TIME 2000
1579 +//by amy for ps
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)
1584 +
1585 +#define CRC_LENGTH 4U
1586 +
1587 +#define MAX_WPA_IE_LEN 64
1588 +
1589 +#define NETWORK_EMPTY_ESSID (1<<0)
1590 +#define NETWORK_HAS_OFDM (1<<1)
1591 +#define NETWORK_HAS_CCK (1<<2)
1592 +
1593 +#define IEEE80211_DTIM_MBCAST 4
1594 +#define IEEE80211_DTIM_UCAST 2
1595 +#define IEEE80211_DTIM_VALID 1
1596 +#define IEEE80211_DTIM_INVALID 0
1597 +
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
1606 +#endif
1607 +
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
1615 +
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 : \
1623 + WME_AC_VO)
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 : \
1629 + 0)
1630 +
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];
1635 + u16 ether_type;
1636 +} __attribute__((packed));
1637 +
1638 +#ifndef ETHERTYPE_PAE
1639 +#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */
1640 +#endif
1641 +#ifndef ETHERTYPE_IP
1642 +#define ETHERTYPE_IP 0x0800 /* IP protocol */
1643 +#endif
1644 +
1645 +struct ieee80211_network {
1646 + /* These entries are used to identify a unique network */
1647 + u8 bssid[ETH_ALEN];
1648 + u8 channel;
1649 + /* Ensure null-terminated for any debug msgs */
1650 + u8 ssid[IW_ESSID_MAX_SIZE + 1];
1651 + u8 ssid_len;
1652 +
1653 + /* These are network statistics */
1654 + struct ieee80211_rx_stats stats;
1655 + u16 capability;
1656 + u8 rates[MAX_RATES_LENGTH];
1657 + u8 rates_len;
1658 + u8 rates_ex[MAX_RATES_EX_LENGTH];
1659 + u8 rates_ex_len;
1660 + unsigned long last_scanned;
1661 + u8 mode;
1662 + u8 flags;
1663 + u32 last_associate;
1664 + u32 time_stamp[2];
1665 + u16 beacon_interval;
1666 + u16 listen_interval;
1667 + u16 atim_window;
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;
1672 + u8 dtim_period;
1673 + u8 dtim_data;
1674 + u32 last_dtim_sta_time[2];
1675 + struct list_head list;
1676 + //appeded for QoS
1677 + u8 wmm_info;
1678 + struct ieee80211_wmm_ac_param wmm_param[4];
1679 + u8 QoS_Enable;
1680 + u8 SignalStrength;
1681 +//by amy 080312
1682 + u8 HighestOperaRate;
1683 +//by amy 080312
1684 +#ifdef THOMAS_TURBO
1685 + u8 Turbo_Enable;//enable turbo mode, added by thomas
1686 +#endif
1687 +#ifdef ENABLE_DOT11D
1688 + u16 CountryIeLen;
1689 + u8 CountryIeBuf[MAX_IE_LEN];
1690 +#endif
1691 +};
1692 +
1693 +enum ieee80211_state {
1694 +
1695 + /* the card is not linked at all */
1696 + IEEE80211_NOLINK = 0,
1697 +
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)
1704 + */
1705 +
1706 + /* the association procedure will start (wq scheduling)*/
1707 + IEEE80211_ASSOCIATING,
1708 + IEEE80211_ASSOCIATING_RETRY,
1709 +
1710 + /* the association procedure is sending AUTH request*/
1711 + IEEE80211_ASSOCIATING_AUTHENTICATING,
1712 +
1713 + /* the association procedure has successfully authentcated
1714 + * and is sending association request
1715 + */
1716 + IEEE80211_ASSOCIATING_AUTHENTICATED,
1717 +
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
1720 + */
1721 + IEEE80211_LINKED,
1722 +
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.
1727 + */
1728 + IEEE80211_LINKED_SCANNING,
1729 +
1730 +};
1731 +
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]
1736 +
1737 +
1738 +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
1739 +extern inline int is_multicast_ether_addr(const u8 *addr)
1740 +{
1741 + return ((addr[0] != 0xff) && (0x01 & addr[0]));
1742 +}
1743 +#endif
1744 +
1745 +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13))
1746 +extern inline int is_broadcast_ether_addr(const u8 *addr)
1747 +{
1748 + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
1749 + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
1750 +}
1751 +#endif
1752 +
1753 +#define CFG_IEEE80211_RESERVE_FCS (1<<0)
1754 +#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
1755 +
1756 +typedef struct tx_pending_t{
1757 + int frag;
1758 + struct ieee80211_txb *txb;
1759 +}tx_pending_t;
1760 +
1761 +
1762 +struct ieee80211_device {
1763 + struct net_device *dev;
1764 +
1765 + /* Bookkeeping structures */
1766 + struct net_device_stats stats;
1767 + struct ieee80211_stats ieee_stats;
1768 + struct ieee80211_softmac_stats softmac_stats;
1769 +
1770 + /* Probe / Beacon management */
1771 + struct list_head network_free_list;
1772 + struct list_head network_list;
1773 + struct ieee80211_network *networks;
1774 + int scans;
1775 + int scan_age;
1776 +
1777 + int iw_mode; /* operating mode (IW_MODE_*) */
1778 +
1779 + spinlock_t lock;
1780 + spinlock_t wpax_suitlist_lock;
1781 +
1782 + int tx_headroom; /* Set to size of any additional room needed at front
1783 + * of allocated Tx SKBs */
1784 + u32 config;
1785 +
1786 + /* WEP and other encryption related settings at the device level */
1787 + int open_wep; /* Set to 1 to allow unencrypted frames */
1788 +
1789 + int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
1790 + * WEP key changes */
1791 +
1792 + /* If the host performs {en,de}cryption, then set to 1 */
1793 + int host_encrypt;
1794 + int host_decrypt;
1795 + int ieee802_1x; /* is IEEE 802.1X used */
1796 +
1797 + /* WPA data */
1798 + int wpa_enabled;
1799 + int drop_unencrypted;
1800 + int tkip_countermeasures;
1801 + int privacy_invoked;
1802 + size_t wpa_ie_len;
1803 + u8 *wpa_ie;
1804 +
1805 + u8 ap_mac_addr[6];
1806 + u16 pairwise_key_type;
1807 + u16 broadcast_key_type;
1808 +
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;
1813 +
1814 + int bcrx_sta_key; /* use individual keys to override default keys even
1815 + * with RX of broad/multicast frames */
1816 +
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 */
1822 +
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
1830 + */
1831 + struct ieee80211_network current_network;
1832 +
1833 +
1834 + enum ieee80211_state state;
1835 +
1836 + int short_slot;
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 */
1841 +
1842 + /* used for forcing the ibss workqueue to terminate
1843 + * without wait for the syncro scan to terminate
1844 + */
1845 + short sync_scan_hurryup;
1846 +
1847 +#ifdef ENABLE_DOT11D
1848 + void * pDot11dInfo;
1849 + bool bGlobalDomain;
1850 +
1851 + // For Liteon Ch12~13 passive scan
1852 + u8 MinPassiveChnlNum;
1853 + u8 IbssStartChnl;
1854 +#else
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];
1858 +#endif
1859 +
1860 + int rate; /* current rate */
1861 + int basic_rate;
1862 + //FIXME: pleace callback, see if redundant with softmac_features
1863 + short active_scan;
1864 +
1865 + /* this contains flags for selectively enable softmac support */
1866 + u16 softmac_features;
1867 +
1868 + /* if the sequence control field is not filled by HW */
1869 + u16 seq_ctrl[5];
1870 +
1871 + /* association procedure transaction sequence number */
1872 + u16 associate_seq;
1873 +
1874 + /* AID for RTXed association responses */
1875 + u16 assoc_id;
1876 +
1877 + /* power save mode related*/
1878 + short ps;
1879 + short sta_sleep;
1880 + int ps_timeout;
1881 + struct tasklet_struct ps_task;
1882 + u32 ps_th;
1883 + u32 ps_tl;
1884 +
1885 + short raw_tx;
1886 + /* used if IEEE_SOFTMAC_TX_QUEUE is set */
1887 + short queue_stop;
1888 + short scanning;
1889 + short proto_started;
1890 +
1891 + struct semaphore wx_sem;
1892 + struct semaphore scan_sem;
1893 +
1894 + spinlock_t mgmt_tx_lock;
1895 + spinlock_t beacon_lock;
1896 +
1897 + short beacon_txing;
1898 +
1899 + short wap_set;
1900 + short ssid_set;
1901 +
1902 + u8 wpax_type_set; //{added by David, 2006.9.28}
1903 + u32 wpax_type_notify; //{added by David, 2006.9.26}
1904 +
1905 + /* QoS related flag */
1906 + char init_wmmparam_flag;
1907 +
1908 + /* for discarding duplicated packets in IBSS */
1909 + struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
1910 +
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];
1915 +
1916 + /* for PS mode */
1917 + unsigned long last_rx_ps_time;
1918 +
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;
1923 +
1924 +
1925 + /* used if IEEE_SOFTMAC_TX_QUEUE is set */
1926 + struct tx_pending_t tx_pending;
1927 +
1928 + /* used if IEEE_SOFTMAC_ASSOCIATE is set */
1929 + struct timer_list associate_timer;
1930 +
1931 + /* used if IEEE_SOFTMAC_BEACONS is set */
1932 + struct timer_list beacon_timer;
1933 +
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;
1944 + bool bInactivePs;
1945 + bool actscanning;
1946 + bool beinretry;
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
1952 + bool bHwRadioOff;
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;
1966 +
1967 +//Added for RF power on power off by lizhaoming 080512
1968 + struct delayed_work GPIOChangeRFWorkItem;
1969 +#else
1970 +
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;
1983 +
1984 +//Added for RF power on power off by lizhaoming 080512
1985 + struct work_struct GPIOChangeRFWorkItem;
1986 +#endif
1987 + struct workqueue_struct *wq;
1988 +
1989 + /* Callback functions */
1990 + void (*set_security)(struct net_device *dev,
1991 + struct ieee80211_security *sec);
1992 +
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
1996 + */
1997 + int (*hard_start_xmit)(struct ieee80211_txb *txb,
1998 + struct net_device *dev);
1999 +
2000 + int (*reset_port)(struct net_device *dev);
2001 +
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.
2008 + */
2009 + int (*softmac_hard_start_xmit)(struct sk_buff *skb,
2010 + struct net_device *dev);
2011 +
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.
2017 + */
2018 + void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
2019 + struct net_device *dev,int rate);
2020 +
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.
2024 + */
2025 + void (*data_hard_stop)(struct net_device *dev);
2026 +
2027 + /* OK this is complementar to data_poll_hard_stop */
2028 + void (*data_hard_resume)(struct net_device *dev);
2029 +
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.
2033 + */
2034 + void (*set_chan)(struct net_device *dev,short ch);
2035 +
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.
2039 + *
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.
2050 + */
2051 + void (*scan_syncro)(struct net_device *dev);
2052 + void (*start_scan)(struct net_device *dev);
2053 + void (*stop_scan)(struct net_device *dev);
2054 +
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
2059 + */
2060 + void (*link_change)(struct net_device *dev);
2061 +
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.
2067 + */
2068 + void (*start_send_beacons) (struct net_device *dev);
2069 + void (*stop_send_beacons) (struct net_device *dev);
2070 +
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);
2076 +
2077 + /* QoS related */
2078 + //void (*wmm_param_update) (struct net_device *dev, u8 *ac_param);
2079 + //void (*wmm_param_update) (struct ieee80211_device *ieee);
2080 +
2081 + /* This must be the last item so that it points to the data
2082 + * allocated beyond this structure by alloc_ieee80211 */
2083 + u8 priv[0];
2084 +};
2085 +
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)
2090 +
2091 +/* Generate a 802.11 header */
2092 +
2093 +/* Uses the channel change callback directly
2094 + * instead of [start/stop] scan callbacks
2095 + */
2096 +#define IEEE_SOFTMAC_SCAN (1<<2)
2097 +
2098 +/* Perform authentication and association handshake */
2099 +#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
2100 +
2101 +/* Generate probe requests */
2102 +#define IEEE_SOFTMAC_PROBERQ (1<<4)
2103 +
2104 +/* Generate respones to probe requests */
2105 +#define IEEE_SOFTMAC_PROBERS (1<<5)
2106 +
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)
2111 +
2112 +/* Uses only the softmac_data_hard_start_xmit
2113 + * even for TX management frames.
2114 + */
2115 +#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
2116 +
2117 +/* Generate beacons. The stack will enqueue beacons
2118 + * to the card
2119 + */
2120 +#define IEEE_SOFTMAC_BEACONS (1<<6)
2121 +
2122 +
2123 +
2124 +static inline void *ieee80211_priv(struct net_device *dev)
2125 +{
2126 + return ((struct ieee80211_device *)netdev_priv(dev))->priv;
2127 +}
2128 +
2129 +extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
2130 +{
2131 + /* Single white space is for Linksys APs */
2132 + if (essid_len == 1 && essid[0] == ' ')
2133 + return 1;
2134 +
2135 + /* Otherwise, if the entire essid is 0, we assume it is hidden */
2136 + while (essid_len) {
2137 + essid_len--;
2138 + if (essid[essid_len] != '\0')
2139 + return 0;
2140 + }
2141 +
2142 + return 1;
2143 +}
2144 +
2145 +extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
2146 +{
2147 + /*
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
2151 + *
2152 + */
2153 + if ((mode & IEEE_A) &&
2154 + (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
2155 + (ieee->freq_band & IEEE80211_52GHZ_BAND))
2156 + return 1;
2157 +
2158 + if ((mode & IEEE_G) &&
2159 + (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
2160 + (ieee->freq_band & IEEE80211_24GHZ_BAND))
2161 + return 1;
2162 +
2163 + if ((mode & IEEE_B) &&
2164 + (ieee->modulation & IEEE80211_CCK_MODULATION) &&
2165 + (ieee->freq_band & IEEE80211_24GHZ_BAND))
2166 + return 1;
2167 +
2168 + return 0;
2169 +}
2170 +
2171 +extern inline int ieee80211_get_hdrlen(u16 fc)
2172 +{
2173 + int hdrlen = 24;
2174 +
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*/
2181 + break;
2182 + case IEEE80211_FTYPE_CTL:
2183 + switch (WLAN_FC_GET_STYPE(fc)) {
2184 + case IEEE80211_STYPE_CTS:
2185 + case IEEE80211_STYPE_ACK:
2186 + hdrlen = 10;
2187 + break;
2188 + default:
2189 + hdrlen = 16;
2190 + break;
2191 + }
2192 + break;
2193 + }
2194 +
2195 + return hdrlen;
2196 +}
2197 +
2198 +
2199 +
2200 +/* ieee80211.c */
2201 +extern void free_ieee80211(struct net_device *dev);
2202 +extern struct net_device *alloc_ieee80211(int sizeof_priv);
2203 +
2204 +extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
2205 +
2206 +/* ieee80211_tx.c */
2207 +
2208 +extern int ieee80211_encrypt_fragment(
2209 + struct ieee80211_device *ieee,
2210 + struct sk_buff *frag,
2211 + int hdr_len);
2212 +
2213 +extern int ieee80211_xmit(struct sk_buff *skb,
2214 + struct net_device *dev);
2215 +extern void ieee80211_txb_free(struct ieee80211_txb *);
2216 +
2217 +
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);
2224 +
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);
2244 +
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,
2251 + u16 stype);
2252 +extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
2253 +
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);
2281 +
2282 +//Add for RF power on power off by lizhaoming 080512
2283 +extern void SendDisassociation(struct ieee80211_device *ieee,
2284 + u8* asSta,
2285 + u8 asRsn);
2286 +
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 */
2292 +
2293 +extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
2294 + struct iw_request_info *info,
2295 + union iwreq_data *wrqu, char *ext);
2296 +
2297 +extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
2298 + struct iw_request_info *info,
2299 + union iwreq_data *awrq,
2300 + char *extra);
2301 +
2302 +extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
2303 +
2304 +extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
2305 + struct iw_request_info *info,
2306 + union iwreq_data *wrqu, char *extra);
2307 +
2308 +extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
2309 + struct iw_request_info *info,
2310 + union iwreq_data *wrqu, char *extra);
2311 +
2312 +extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
2313 + union iwreq_data *wrqu, char *b);
2314 +
2315 +extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
2316 + union iwreq_data *wrqu, char *b);
2317 +
2318 +extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
2319 + struct iw_request_info *a,
2320 + union iwreq_data *wrqu, char *extra);
2321 +
2322 +extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
2323 + union iwreq_data *wrqu, char *b);
2324 +
2325 +extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
2326 + union iwreq_data *wrqu, char *b);
2327 +
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);
2332 +#else
2333 + extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
2334 +#endif
2335 +//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
2336 +
2337 +extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
2338 + struct iw_request_info *info,
2339 + union iwreq_data *wrqu, char *extra);
2340 +
2341 +extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
2342 + struct iw_request_info *info,
2343 + union iwreq_data *wrqu, char *extra);
2344 +
2345 +extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
2346 + struct iw_request_info *info,
2347 + union iwreq_data *wrqu, char *extra);
2348 +
2349 +extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
2350 + struct iw_request_info *info,
2351 + union iwreq_data *wrqu, char *extra);
2352 +
2353 +extern void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee);
2354 +
2355 +extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr);
2356 +
2357 +extern const long ieee80211_wlan_frequencies[];
2358 +
2359 +extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
2360 +{
2361 + ieee->scans++;
2362 +}
2363 +
2364 +extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
2365 +{
2366 + return ieee->scans;
2367 +}
2368 +
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;
2373 +
2374 + if (ieee80211_is_empty_essid(essid, essid_len)) {
2375 + memcpy(escaped, "<hidden>", sizeof("<hidden>"));
2376 + return escaped;
2377 + }
2378 +
2379 + essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
2380 + while (essid_len--) {
2381 + if (*s == '\0') {
2382 + *d++ = '\\';
2383 + *d++ = '0';
2384 + s++;
2385 + } else {
2386 + *d++ = *s++;
2387 + }
2388 + }
2389 + *d = '\0';
2390 + return escaped;
2391 +}
2392 +#endif /* IEEE80211_H */
2393 --- /dev/null
2394 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
2395 @@ -0,0 +1,265 @@
2396 +/*
2397 + * Host AP crypto routines
2398 + *
2399 + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
2400 + * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
2401 + *
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
2405 + * more details.
2406 + *
2407 + */
2408 +
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>
2416 +
2417 +#if (LINUX_VERSION_CODE<KERNEL_VERSION(2,6,18))
2418 +#include<linux/config.h>
2419 +#endif
2420 +
2421 +#include "ieee80211.h"
2422 +
2423 +MODULE_AUTHOR("Jouni Malinen");
2424 +MODULE_DESCRIPTION("HostAP crypto");
2425 +MODULE_LICENSE("GPL");
2426 +
2427 +struct ieee80211_crypto_alg {
2428 + struct list_head list;
2429 + struct ieee80211_crypto_ops *ops;
2430 +};
2431 +
2432 +
2433 +struct ieee80211_crypto {
2434 + struct list_head algs;
2435 + spinlock_t lock;
2436 +};
2437 +
2438 +static struct ieee80211_crypto *hcrypt;
2439 +
2440 +void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
2441 + int force)
2442 +{
2443 + struct list_head *ptr, *n;
2444 + struct ieee80211_crypt_data *entry;
2445 +
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);
2449 +
2450 + if (atomic_read(&entry->refcnt) != 0 && !force)
2451 + continue;
2452 +
2453 + list_del(ptr);
2454 +
2455 + if (entry->ops) {
2456 + entry->ops->deinit(entry->priv);
2457 + module_put(entry->ops->owner);
2458 + }
2459 + kfree(entry);
2460 + }
2461 +}
2462 +
2463 +void ieee80211_crypt_deinit_handler(unsigned long data)
2464 +{
2465 + struct ieee80211_device *ieee = (struct ieee80211_device *)data;
2466 + unsigned long flags;
2467 +
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);
2475 + }
2476 + spin_unlock_irqrestore(&ieee->lock, flags);
2477 +
2478 +}
2479 +
2480 +void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
2481 + struct ieee80211_crypt_data **crypt)
2482 +{
2483 + struct ieee80211_crypt_data *tmp;
2484 + unsigned long flags;
2485 +
2486 + if (*crypt == NULL)
2487 + return;
2488 +
2489 + tmp = *crypt;
2490 + *crypt = NULL;
2491 +
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
2494 + * locking. */
2495 +
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);
2501 + }
2502 + spin_unlock_irqrestore(&ieee->lock, flags);
2503 +}
2504 +
2505 +int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
2506 +{
2507 + unsigned long flags;
2508 + struct ieee80211_crypto_alg *alg;
2509 +
2510 + if (hcrypt == NULL)
2511 + return -1;
2512 +
2513 + alg = kmalloc(sizeof(*alg), GFP_KERNEL);
2514 + if (alg == NULL)
2515 + return -ENOMEM;
2516 +
2517 + memset(alg, 0, sizeof(*alg));
2518 + alg->ops = ops;
2519 +
2520 + spin_lock_irqsave(&hcrypt->lock, flags);
2521 + list_add(&alg->list, &hcrypt->algs);
2522 + spin_unlock_irqrestore(&hcrypt->lock, flags);
2523 +
2524 + printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
2525 + ops->name);
2526 +
2527 + return 0;
2528 +}
2529 +
2530 +int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
2531 +{
2532 + unsigned long flags;
2533 + struct list_head *ptr;
2534 + struct ieee80211_crypto_alg *del_alg = NULL;
2535 +
2536 + if (hcrypt == NULL)
2537 + return -1;
2538 +
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);
2545 + del_alg = alg;
2546 + break;
2547 + }
2548 + }
2549 + spin_unlock_irqrestore(&hcrypt->lock, flags);
2550 +
2551 + if (del_alg) {
2552 + printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
2553 + "'%s'\n", ops->name);
2554 + kfree(del_alg);
2555 + }
2556 +
2557 + return del_alg ? 0 : -1;
2558 +}
2559 +
2560 +
2561 +struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
2562 +{
2563 + unsigned long flags;
2564 + struct list_head *ptr;
2565 + struct ieee80211_crypto_alg *found_alg = NULL;
2566 +
2567 + if (hcrypt == NULL)
2568 + return NULL;
2569 +
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) {
2575 + found_alg = alg;
2576 + break;
2577 + }
2578 + }
2579 + spin_unlock_irqrestore(&hcrypt->lock, flags);
2580 +
2581 + if (found_alg)
2582 + return found_alg->ops;
2583 + else
2584 + return NULL;
2585 +}
2586 +
2587 +
2588 +static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
2589 +static void ieee80211_crypt_null_deinit(void *priv) {}
2590 +
2591 +static struct ieee80211_crypto_ops ieee80211_crypt_null = {
2592 + .name = "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,
2599 + .set_key = NULL,
2600 + .get_key = NULL,
2601 + .extra_prefix_len = 0,
2602 + .extra_postfix_len = 0,
2603 + .owner = THIS_MODULE,
2604 +};
2605 +
2606 +
2607 +int ieee80211_crypto_init(void)
2608 +{
2609 + int ret = -ENOMEM;
2610 +
2611 + hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
2612 + if (!hcrypt)
2613 + goto out;
2614 +
2615 + memset(hcrypt, 0, sizeof(*hcrypt));
2616 + INIT_LIST_HEAD(&hcrypt->algs);
2617 + spin_lock_init(&hcrypt->lock);
2618 +
2619 + ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
2620 + if (ret < 0) {
2621 + kfree(hcrypt);
2622 + hcrypt = NULL;
2623 + }
2624 +out:
2625 + return ret;
2626 +}
2627 +
2628 +
2629 +void ieee80211_crypto_deinit(void)
2630 +{
2631 + struct list_head *ptr, *n;
2632 +
2633 + if (hcrypt == NULL)
2634 + return;
2635 +
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;
2640 + list_del(ptr);
2641 + printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
2642 + "'%s' (deinit)\n", alg->ops->name);
2643 + kfree(alg);
2644 + }
2645 +
2646 + kfree(hcrypt);
2647 +}
2648 +
2649 +#if 0
2650 +EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
2651 +EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
2652 +EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
2653 +
2654 +EXPORT_SYMBOL(ieee80211_register_crypto_ops);
2655 +EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
2656 +EXPORT_SYMBOL(ieee80211_get_crypto_ops);
2657 +#endif
2658 +
2659 +//module_init(ieee80211_crypto_init);
2660 +//module_exit(ieee80211_crypto_deinit);
2661 --- /dev/null
2662 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
2663 @@ -0,0 +1,533 @@
2664 +/*
2665 + * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
2666 + *
2667 + * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
2668 + *
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
2672 + * more details.
2673 + */
2674 +
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>
2687 +
2688 +#include "ieee80211.h"
2689 +
2690 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
2691 +#include "rtl_crypto.h"
2692 +#else
2693 +#include <linux/crypto.h>
2694 +#endif
2695 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
2696 + #include <asm/scatterlist.h>
2697 +#else
2698 + #include <linux/scatterlist.h>
2699 +#endif
2700 +
2701 +//#include <asm/scatterlist.h>
2702 +
2703 +MODULE_AUTHOR("Jouni Malinen");
2704 +MODULE_DESCRIPTION("Host AP crypt: CCMP");
2705 +MODULE_LICENSE("GPL");
2706 +
2707 +#ifdef OPENSUSE_SLED
2708 +#ifndef IN_OPENSUSE_SLED
2709 +#define IN_OPENSUSE_SLED 1
2710 +#endif
2711 +#endif
2712 +
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
2718 +
2719 +struct ieee80211_ccmp_data {
2720 + u8 key[CCMP_TK_LEN];
2721 + int key_set;
2722 +
2723 + u8 tx_pn[CCMP_PN_LEN];
2724 + u8 rx_pn[CCMP_PN_LEN];
2725 +
2726 + u32 dot11RSNAStatsCCMPFormatErrors;
2727 + u32 dot11RSNAStatsCCMPReplays;
2728 + u32 dot11RSNAStatsCCMPDecryptErrors;
2729 +
2730 + int key_idx;
2731 +
2732 + struct crypto_tfm *tfm;
2733 +
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];
2738 +};
2739 +
2740 +void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
2741 + const u8 pt[16], u8 ct[16])
2742 +{
2743 + #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))||(IN_OPENSUSE_SLED))
2744 + crypto_cipher_encrypt_one((void *)tfm, ct, pt);
2745 + #else
2746 + struct scatterlist src, dst;
2747 +
2748 + src.page = virt_to_page(pt);
2749 + src.offset = offset_in_page(pt);
2750 + src.length = AES_BLOCK_LEN;
2751 +
2752 + dst.page = virt_to_page(ct);
2753 + dst.offset = offset_in_page(ct);
2754 + dst.length = AES_BLOCK_LEN;
2755 +
2756 + crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
2757 + #endif
2758 +}
2759 +
2760 +static void * ieee80211_ccmp_init(int key_idx)
2761 +{
2762 + struct ieee80211_ccmp_data *priv;
2763 +
2764 + priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
2765 + if (priv == NULL)
2766 + goto fail;
2767 + memset(priv, 0, sizeof(*priv));
2768 + priv->key_idx = key_idx;
2769 +
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");
2775 + goto fail;
2776 + }
2777 + #else
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");
2782 + priv->tfm = NULL;
2783 + goto fail;
2784 + }
2785 + #endif
2786 + return priv;
2787 +
2788 +fail:
2789 + if (priv) {
2790 + if (priv->tfm)
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);
2794 + #else
2795 + crypto_free_cipher((void *)priv->tfm);
2796 + #endif
2797 + kfree(priv);
2798 + }
2799 +
2800 + return NULL;
2801 +}
2802 +
2803 +
2804 +static void ieee80211_ccmp_deinit(void *priv)
2805 +{
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);
2811 + #else
2812 + crypto_free_cipher((void *)_priv->tfm);
2813 + #endif
2814 + kfree(priv);
2815 +}
2816 +
2817 +
2818 +static inline void xor_block(u8 *b, u8 *a, size_t len)
2819 +{
2820 + int i;
2821 + for (i = 0; i < len; i++)
2822 + b[i] ^= a[i];
2823 +}
2824 +
2825 +#ifndef JOHN_CCMP
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,
2829 + u8 *s0)
2830 +{
2831 + u8 *pos, qc = 0;
2832 + size_t aad_len;
2833 + u16 fc;
2834 + int a4_included, qc_included;
2835 + u8 aad[2 * AES_BLOCK_LEN];
2836 +
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));
2840 + /*
2841 + qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
2842 + (WLAN_FC_GET_STYPE(fc) & 0x08));
2843 + */
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));
2847 + aad_len = 22;
2848 + if (a4_included)
2849 + aad_len += 6;
2850 + if (qc_included) {
2851 + pos = (u8 *) &hdr->addr4;
2852 + if (a4_included)
2853 + pos += 6;
2854 + qc = *pos & 0x0f;
2855 + aad_len += 2;
2856 + }
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
2861 + * Dlen */
2862 + b0[0] = 0x59;
2863 + b0[1] = qc;
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;
2868 +
2869 + /* AAD:
2870 + * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
2871 + * A1 | A2 | A3
2872 + * SC with bits 4..15 (seq#) masked to zero
2873 + * A4 (if present)
2874 + * QC (if present)
2875 + */
2876 + pos = (u8 *) hdr;
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);
2886 + if (a4_included)
2887 + memcpy(aad + 24, hdr->addr4, ETH_ALEN);
2888 + if (qc_included) {
2889 + aad[a4_included ? 30 : 24] = qc;
2890 + /* rest of QC masked */
2891 + }
2892 +
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);
2899 + b0[0] &= 0x07;
2900 + b0[14] = b0[15] = 0;
2901 + ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
2902 +}
2903 +#endif
2904 +
2905 +static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
2906 +{
2907 + struct ieee80211_ccmp_data *key = priv;
2908 + int data_len, i;
2909 + u8 *pos;
2910 + struct ieee80211_hdr *hdr;
2911 +#ifndef JOHN_CCMP
2912 + int blocks, last, len;
2913 + u8 *mic;
2914 + u8 *b0 = key->tx_b0;
2915 + u8 *b = key->tx_b;
2916 + u8 *e = key->tx_e;
2917 + u8 *s0 = key->tx_s0;
2918 +#endif
2919 + if (skb_headroom(skb) < CCMP_HDR_LEN ||
2920 + skb_tailroom(skb) < CCMP_MIC_LEN ||
2921 + skb->len < hdr_len)
2922 + return -1;
2923 +
2924 + data_len = skb->len - hdr_len;
2925 + pos = skb_push(skb, CCMP_HDR_LEN);
2926 + memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
2927 + pos += hdr_len;
2928 +// mic = skb_put(skb, CCMP_MIC_LEN);
2929 +
2930 + i = CCMP_PN_LEN - 1;
2931 + while (i >= 0) {
2932 + key->tx_pn[i]++;
2933 + if (key->tx_pn[i] != 0)
2934 + break;
2935 + i--;
2936 + }
2937 +
2938 + *pos++ = key->tx_pn[5];
2939 + *pos++ = key->tx_pn[4];
2940 + *pos++ = 0;
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];
2946 +
2947 + hdr = (struct ieee80211_hdr *) skb->data;
2948 +#ifndef JOHN_CCMP
2949 + //mic is moved to here by john
2950 + mic = skb_put(skb, CCMP_MIC_LEN);
2951 +
2952 + ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
2953 +
2954 + blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
2955 + last = data_len % AES_BLOCK_LEN;
2956 +
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);
2967 + pos += len;
2968 + }
2969 +
2970 + for (i = 0; i < CCMP_MIC_LEN; i++)
2971 + mic[i] = b[i] ^ s0[i];
2972 +#endif
2973 + return 0;
2974 +}
2975 +
2976 +
2977 +static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
2978 +{
2979 + struct ieee80211_ccmp_data *key = priv;
2980 + u8 keyidx, *pos;
2981 + struct ieee80211_hdr *hdr;
2982 + u8 pn[6];
2983 +#ifndef JOHN_CCMP
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;
2990 +#endif
2991 + if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
2992 + key->dot11RSNAStatsCCMPFormatErrors++;
2993 + return -1;
2994 + }
2995 +
2996 + hdr = (struct ieee80211_hdr *) skb->data;
2997 + pos = skb->data + hdr_len;
2998 + keyidx = pos[3];
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));
3003 + }
3004 + key->dot11RSNAStatsCCMPFormatErrors++;
3005 + return -2;
3006 + }
3007 + keyidx >>= 6;
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);
3011 + return -6;
3012 + }
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);
3018 + }
3019 + return -3;
3020 + }
3021 +
3022 + pn[0] = pos[7];
3023 + pn[1] = pos[6];
3024 + pn[2] = pos[5];
3025 + pn[3] = pos[4];
3026 + pn[4] = pos[1];
3027 + pn[5] = pos[0];
3028 + pos += 8;
3029 +
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),
3036 + MAC_ARG(pn));
3037 + }
3038 + key->dot11RSNAStatsCCMPReplays++;
3039 + return -4;
3040 + }
3041 +
3042 +#ifndef JOHN_CCMP
3043 + ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
3044 + xor_block(mic, b, CCMP_MIC_LEN);
3045 +
3046 + blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
3047 + last = data_len % AES_BLOCK_LEN;
3048 +
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);
3059 + pos += len;
3060 + }
3061 +
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));
3066 + }
3067 + key->dot11RSNAStatsCCMPDecryptErrors++;
3068 + return -5;
3069 + }
3070 +
3071 + memcpy(key->rx_pn, pn, CCMP_PN_LEN);
3072 +
3073 +#endif
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);
3078 +
3079 + return keyidx;
3080 +}
3081 +
3082 +
3083 +static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
3084 +{
3085 + struct ieee80211_ccmp_data *data = priv;
3086 + int keyidx;
3087 + struct crypto_tfm *tfm = data->tfm;
3088 +
3089 + keyidx = data->key_idx;
3090 + memset(data, 0, sizeof(*data));
3091 + data->key_idx = keyidx;
3092 + data->tfm = tfm;
3093 + if (len == CCMP_TK_LEN) {
3094 + memcpy(data->key, key, CCMP_TK_LEN);
3095 + data->key_set = 1;
3096 + if (seq) {
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];
3103 + }
3104 + crypto_cipher_setkey((void *)data->tfm, data->key, CCMP_TK_LEN);
3105 + } else if (len == 0)
3106 + data->key_set = 0;
3107 + else
3108 + return -1;
3109 +
3110 + return 0;
3111 +}
3112 +
3113 +
3114 +static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
3115 +{
3116 + struct ieee80211_ccmp_data *data = priv;
3117 +
3118 + if (len < CCMP_TK_LEN)
3119 + return -1;
3120 +
3121 + if (!data->key_set)
3122 + return 0;
3123 + memcpy(key, data->key, CCMP_TK_LEN);
3124 +
3125 + if (seq) {
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];
3132 + }
3133 +
3134 + return CCMP_TK_LEN;
3135 +}
3136 +
3137 +
3138 +static char * ieee80211_ccmp_print_stats(char *p, void *priv)
3139 +{
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);
3150 +
3151 + return p;
3152 +}
3153 +
3154 +void ieee80211_ccmp_null(void)
3155 +{
3156 +// printk("============>%s()\n", __FUNCTION__);
3157 + return;
3158 +}
3159 +static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
3160 + .name = "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,
3173 +};
3174 +
3175 +
3176 +int ieee80211_crypto_ccmp_init(void)
3177 +{
3178 + return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
3179 +}
3180 +
3181 +
3182 +void ieee80211_crypto_ccmp_exit(void)
3183 +{
3184 + ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
3185 +}
3186 +
3187 +#if 0
3188 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
3189 +EXPORT_SYMBOL(ieee80211_ccmp_null);
3190 +#else
3191 +EXPORT_SYMBOL_NOVERS(ieee80211_ccmp_null);
3192 +#endif
3193 +#endif
3194 +
3195 +//module_init(ieee80211_crypto_ccmp_init);
3196 +//module_exit(ieee80211_crypto_ccmp_exit);
3197 --- /dev/null
3198 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h
3199 @@ -0,0 +1,86 @@
3200 +/*
3201 + * Original code based on Host AP (software wireless LAN access point) driver
3202 + * for Intersil Prism2/2.5/3.
3203 + *
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>
3207 + *
3208 + * Adaption to a generic IEEE 802.11 stack by James Ketrenos
3209 + * <jketreno@linux.intel.com>
3210 + *
3211 + * Copyright (c) 2004, Intel Corporation
3212 + *
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
3216 + * more details.
3217 + */
3218 +
3219 +/*
3220 + * This file defines the interface to the ieee80211 crypto module.
3221 + */
3222 +#ifndef IEEE80211_CRYPT_H
3223 +#define IEEE80211_CRYPT_H
3224 +
3225 +#include <linux/skbuff.h>
3226 +
3227 +struct ieee80211_crypto_ops {
3228 + const char *name;
3229 +
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);
3234 +
3235 + /* deinitialize crypto context and free allocated private data */
3236 + void (*deinit)(void *priv);
3237 +
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).
3243 + */
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);
3246 +
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,
3251 + void *priv);
3252 +
3253 + int (*set_key)(void *key, int len, u8 *seq, void *priv);
3254 + int (*get_key)(void *key, int len, u8 *seq, void *priv);
3255 +
3256 + /* procfs handler for printing out key information and possible
3257 + * statistics */
3258 + char * (*print_stats)(char *p, void *priv);
3259 +
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;
3266 +
3267 + struct module *owner;
3268 +};
3269 +
3270 +struct ieee80211_crypt_data {
3271 + struct list_head list; /* delayed deletion list */
3272 + struct ieee80211_crypto_ops *ops;
3273 + void *priv;
3274 + atomic_t refcnt;
3275 +};
3276 +
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);
3284 +
3285 +#endif
3286 --- /dev/null
3287 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
3288 @@ -0,0 +1,1001 @@
3289 +/*
3290 + * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
3291 + *
3292 + * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
3293 + *
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
3297 + * more details.
3298 + */
3299 +
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>
3311 +
3312 +#include "ieee80211.h"
3313 +
3314 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
3315 +#include "rtl_crypto.h"
3316 +#else
3317 +#include <linux/crypto.h>
3318 +#endif
3319 +//#include <asm/scatterlist.h>
3320 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
3321 + #include <asm/scatterlist.h>
3322 +#else
3323 + #include <linux/scatterlist.h>
3324 +#endif
3325 +
3326 +#include <linux/crc32.h>
3327 +
3328 +MODULE_AUTHOR("Jouni Malinen");
3329 +MODULE_DESCRIPTION("Host AP crypt: TKIP");
3330 +MODULE_LICENSE("GPL");
3331 +
3332 +#ifdef OPENSUSE_SLED
3333 +#ifndef IN_OPENSUSE_SLED
3334 +#define IN_OPENSUSE_SLED 1
3335 +#endif
3336 +#endif
3337 +
3338 +struct ieee80211_tkip_data {
3339 +#define TKIP_KEY_LEN 32
3340 + u8 key[TKIP_KEY_LEN];
3341 + int key_set;
3342 +
3343 + u32 tx_iv32;
3344 + u16 tx_iv16;
3345 + u16 tx_ttak[5];
3346 + int tx_phase1_done;
3347 +
3348 + u32 rx_iv32;
3349 + u16 rx_iv16;
3350 + u16 rx_ttak[5];
3351 + int rx_phase1_done;
3352 + u32 rx_iv32_new;
3353 + u16 rx_iv16_new;
3354 +
3355 + u32 dot11RSNAStatsTKIPReplays;
3356 + u32 dot11RSNAStatsTKIPICVErrors;
3357 + u32 dot11RSNAStatsTKIPLocalMICFailures;
3358 +
3359 + int key_idx;
3360 +
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;
3366 + #endif
3367 +
3368 + struct crypto_tfm *tfm_arc4;
3369 + struct crypto_tfm *tfm_michael;
3370 +
3371 + /* scratch buffers for virt_to_page() (crypto API) */
3372 + u8 rx_hdr[16], tx_hdr[16];
3373 +};
3374 +
3375 +static void * ieee80211_tkip_init(int key_idx)
3376 +{
3377 + struct ieee80211_tkip_data *priv;
3378 +
3379 + priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
3380 + if (priv == NULL)
3381 + goto fail;
3382 + memset(priv, 0, sizeof(*priv));
3383 + priv->key_idx = key_idx;
3384 +
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");
3390 + goto fail;
3391 + }
3392 +
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");
3397 + goto fail;
3398 + }
3399 +
3400 + #else
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;
3407 + goto fail;
3408 + }
3409 +
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;
3416 + goto fail;
3417 + }
3418 +
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;
3425 + goto fail;
3426 + }
3427 +
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;
3434 + goto fail;
3435 + }
3436 + #endif
3437 + return priv;
3438 +
3439 +fail:
3440 + if (priv) {
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);
3446 + #else
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);
3455 + #endif
3456 + kfree(priv);
3457 + }
3458 +
3459 + return NULL;
3460 +}
3461 +
3462 +
3463 +static void ieee80211_tkip_deinit(void *priv)
3464 +{
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);
3471 + #else
3472 + if (_priv) {
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);
3481 + }
3482 + #endif
3483 + kfree(priv);
3484 +}
3485 +
3486 +
3487 +static inline u16 RotR1(u16 val)
3488 +{
3489 + return (val >> 1) | (val << 15);
3490 +}
3491 +
3492 +
3493 +static inline u8 Lo8(u16 val)
3494 +{
3495 + return val & 0xff;
3496 +}
3497 +
3498 +
3499 +static inline u8 Hi8(u16 val)
3500 +{
3501 + return val >> 8;
3502 +}
3503 +
3504 +
3505 +static inline u16 Lo16(u32 val)
3506 +{
3507 + return val & 0xffff;
3508 +}
3509 +
3510 +
3511 +static inline u16 Hi16(u32 val)
3512 +{
3513 + return val >> 16;
3514 +}
3515 +
3516 +
3517 +static inline u16 Mk16(u8 hi, u8 lo)
3518 +{
3519 + return lo | (((u16) hi) << 8);
3520 +}
3521 +
3522 +
3523 +static inline u16 Mk16_le(u16 *v)
3524 +{
3525 + return le16_to_cpu(*v);
3526 +}
3527 +
3528 +
3529 +static const u16 Sbox[256] =
3530 +{
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,
3563 +};
3564 +
3565 +
3566 +static inline u16 _S_(u16 v)
3567 +{
3568 + u16 t = Sbox[Hi8(v)];
3569 + return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
3570 +}
3571 +
3572 +#ifndef JOHN_TKIP
3573 +#define PHASE1_LOOP_COUNT 8
3574 +
3575 +static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
3576 +{
3577 + int i, j;
3578 +
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]);
3585 +
3586 + for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
3587 + j = 2 * (i & 1);
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;
3593 + }
3594 +}
3595 +
3596 +
3597 +static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
3598 + u16 IV16)
3599 +{
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];
3603 +
3604 + /* Step 1 - make copy of TTAK and bring in TSC */
3605 + PPK[0] = TTAK[0];
3606 + PPK[1] = TTAK[1];
3607 + PPK[2] = TTAK[2];
3608 + PPK[3] = TTAK[3];
3609 + PPK[4] = TTAK[4];
3610 + PPK[5] = TTAK[4] + IV16;
3611 +
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]));
3619 +
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]);
3626 +
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);
3633 +
3634 +#ifdef __BIG_ENDIAN
3635 + {
3636 + int i;
3637 + for (i = 0; i < 6; i++)
3638 + PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
3639 + }
3640 +#endif
3641 +}
3642 +#endif
3643 +static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
3644 +{
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};
3648 + #endif
3649 + int len;
3650 + u8 *pos;
3651 + struct ieee80211_hdr *hdr;
3652 +#ifndef JOHN_TKIP
3653 + u8 rc4key[16],*icv;
3654 + u32 crc;
3655 + struct scatterlist sg;
3656 +#endif
3657 + int ret;
3658 +
3659 + ret = 0;
3660 + if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
3661 + skb->len < hdr_len)
3662 + return -1;
3663 +
3664 + hdr = (struct ieee80211_hdr *) skb->data;
3665 +#if 0
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]);
3675 +#endif
3676 +
3677 +#ifndef JOHN_TKIP
3678 + if (!tkey->tx_phase1_done) {
3679 + tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
3680 + tkey->tx_iv32);
3681 + tkey->tx_phase1_done = 1;
3682 + }
3683 + tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
3684 +
3685 +#else
3686 + tkey->tx_phase1_done = 1;
3687 +#endif /*JOHN_TKIP*/
3688 +
3689 + len = skb->len - hdr_len;
3690 + pos = skb_push(skb, 8);
3691 + memmove(pos, pos + 8, hdr_len);
3692 + pos += hdr_len;
3693 +
3694 +#ifdef JOHN_TKIP
3695 + *pos++ = Hi8(tkey->tx_iv16);
3696 + *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
3697 + *pos++ = Lo8(tkey->tx_iv16);
3698 +#else
3699 + *pos++ = rc4key[0];
3700 + *pos++ = rc4key[1];
3701 + *pos++ = rc4key[2];
3702 +#endif
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;
3708 +#ifndef JOHN_TKIP
3709 + icv = skb_put(skb, 4);
3710 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
3711 + crc = ~crc32_le(~0, pos, len);
3712 +#else
3713 + crc = ~ether_crc_le(len, pos);
3714 +#endif
3715 + icv[0] = crc;
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);
3725 + #else
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;
3731 + #else
3732 + sg_init_one(&sg, pos, len+4);
3733 + #endif
3734 + ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
3735 + #endif
3736 +#endif
3737 + tkey->tx_iv16++;
3738 + if (tkey->tx_iv16 == 0) {
3739 + tkey->tx_phase1_done = 0;
3740 + tkey->tx_iv32++;
3741 + }
3742 +#ifndef JOHN_TKIP
3743 + #if((LINUX_VERSION_CODE <KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
3744 + return 0;
3745 + #else
3746 + return ret;
3747 + #endif
3748 +#else
3749 + return 0;
3750 +#endif
3751 +}
3752 +
3753 +static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
3754 +{
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};
3758 + #endif
3759 + u8 keyidx, *pos;
3760 + u32 iv32;
3761 + u16 iv16;
3762 + struct ieee80211_hdr *hdr;
3763 +#ifndef JOHN_TKIP
3764 + u8 icv[4];
3765 + u32 crc;
3766 + struct scatterlist sg;
3767 + u8 rc4key[16];
3768 + int plen;
3769 +#endif
3770 + if (skb->len < hdr_len + 8 + 4)
3771 + return -1;
3772 +
3773 + hdr = (struct ieee80211_hdr *) skb->data;
3774 + pos = skb->data + hdr_len;
3775 + keyidx = pos[3];
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));
3780 + }
3781 + return -2;
3782 + }
3783 + keyidx >>= 6;
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);
3787 + return -6;
3788 + }
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);
3794 + }
3795 + return -3;
3796 + }
3797 + iv16 = (pos[0] << 8) | pos[2];
3798 + iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
3799 + pos += 8;
3800 +#ifndef JOHN_TKIP
3801 +
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);
3809 + }
3810 + tkey->dot11RSNAStatsTKIPReplays++;
3811 + return -4;
3812 + }
3813 +
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;
3817 + }
3818 + tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
3819 +
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);
3827 + #else
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;
3833 + #else
3834 + sg_init_one(&sg, pos, plen+4);
3835 + #endif
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));
3841 + }
3842 + return -7;
3843 + }
3844 + #endif
3845 +
3846 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
3847 + crc = ~crc32_le(~0, pos, plen);
3848 +#else
3849 + crc = ~ether_crc_le(plen, pos);
3850 +#endif
3851 + icv[0] = crc;
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;
3860 + }
3861 + if (net_ratelimit()) {
3862 + printk(KERN_DEBUG "TKIP: ICV error detected: STA="
3863 + MAC_FMT "\n", MAC_ARG(hdr->addr2));
3864 + }
3865 + tkey->dot11RSNAStatsTKIPICVErrors++;
3866 + return -5;
3867 + }
3868 +
3869 +#endif /* JOHN_TKIP */
3870 +
3871 + /* Update real counters only after Michael MIC verification has
3872 + * completed */
3873 + tkey->rx_iv32_new = iv32;
3874 + tkey->rx_iv16_new = iv16;
3875 +
3876 + /* Remove IV and ICV */
3877 + memmove(skb->data + 8, skb->data, hdr_len);
3878 + skb_pull(skb, 8);
3879 + skb_trim(skb, skb->len - 4);
3880 +
3881 +//john's test
3882 +#ifdef JOHN_DUMP
3883 +if( ((u16*)skb->data)[0] & 0x4000){
3884 + printk("@@ rx decrypted skb->data");
3885 + int i;
3886 + for(i=0;i<skb->len;i++){
3887 + if( (i%24)==0 ) printk("\n");
3888 + printk("%2x ", ((u8*)skb->data)[i]);
3889 + }
3890 + printk("\n");
3891 +}
3892 +#endif /*JOHN_DUMP*/
3893 + return keyidx;
3894 +}
3895 +
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)
3899 +{
3900 + struct scatterlist sg[2];
3901 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
3902 + struct hash_desc desc;
3903 + int ret=0;
3904 +#endif
3905 + if (tkey->tfm_michael == NULL) {
3906 + printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
3907 + return -1;
3908 + }
3909 + sg[0].page = virt_to_page(hdr);
3910 + sg[0].offset = offset_in_page(hdr);
3911 + sg[0].length = 16;
3912 +
3913 + sg[1].page = virt_to_page(data);
3914 + sg[1].offset = offset_in_page(data);
3915 + sg[1].length = data_len;
3916 +
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);
3921 +
3922 + //return 0;
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);
3928 +
3929 + return 0;
3930 +#else
3931 +if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
3932 + return -1;
3933 +
3934 +// return 0;
3935 + desc.tfm = tkey->tfm_michael;
3936 + desc.flags = 0;
3937 + ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
3938 + return ret;
3939 +#endif
3940 +}
3941 +#else
3942 +static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
3943 + u8 * data, size_t data_len, u8 * mic)
3944 +{
3945 + struct hash_desc desc;
3946 + struct scatterlist sg[2];
3947 +
3948 + if (tfm_michael == NULL) {
3949 + printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
3950 + return -1;
3951 + }
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;
3959 + #else
3960 + sg_init_table(sg, 2);
3961 + sg_set_buf(&sg[0], hdr, 16);
3962 + sg_set_buf(&sg[1], data, data_len);
3963 + #endif
3964 +
3965 + if (crypto_hash_setkey(tfm_michael, key, 8))
3966 + return -1;
3967 +
3968 + desc.tfm = tfm_michael;
3969 + desc.flags = 0;
3970 + return crypto_hash_digest(&desc, sg, data_len + 16, mic);
3971 +}
3972 +#endif
3973 +
3974 +
3975 +
3976 +static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
3977 +{
3978 + struct ieee80211_hdr *hdr11;
3979 +
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 */
3986 + break;
3987 + case IEEE80211_FCTL_FROMDS:
3988 + memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
3989 + memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
3990 + break;
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 */
3994 + break;
3995 + case 0:
3996 + memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
3997 + memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
3998 + break;
3999 + }
4000 +
4001 + hdr[12] = 0; /* priority */
4002 +
4003 + hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
4004 +}
4005 +
4006 +
4007 +static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
4008 +{
4009 + struct ieee80211_tkip_data *tkey = priv;
4010 + u8 *pos;
4011 + struct ieee80211_hdr *hdr;
4012 +
4013 + hdr = (struct ieee80211_hdr *) skb->data;
4014 +
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);
4019 + return -1;
4020 + }
4021 +
4022 + michael_mic_hdr(skb, tkey->tx_hdr);
4023 +
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;
4028 + }
4029 + // }
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))
4034 + #else
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))
4037 + #endif
4038 + return -1;
4039 +
4040 + return 0;
4041 +}
4042 +
4043 +
4044 +#if WIRELESS_EXT >= 18
4045 +static void ieee80211_michael_mic_failure(struct net_device *dev,
4046 + struct ieee80211_hdr *hdr,
4047 + int keyidx)
4048 +{
4049 + union iwreq_data wrqu;
4050 + struct iw_michaelmicfailure ev;
4051 +
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;
4057 + else
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);
4064 +}
4065 +#elif WIRELESS_EXT >= 15
4066 +static void ieee80211_michael_mic_failure(struct net_device *dev,
4067 + struct ieee80211_hdr *hdr,
4068 + int keyidx)
4069 +{
4070 + union iwreq_data wrqu;
4071 + char buf[128];
4072 +
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);
4080 +}
4081 +#else /* WIRELESS_EXT >= 15 */
4082 +static inline void ieee80211_michael_mic_failure(struct net_device *dev,
4083 + struct ieee80211_hdr *hdr,
4084 + int keyidx)
4085 +{
4086 +}
4087 +#endif /* WIRELESS_EXT >= 15 */
4088 +
4089 +
4090 +static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
4091 + int hdr_len, void *priv)
4092 +{
4093 + struct ieee80211_tkip_data *tkey = priv;
4094 + u8 mic[8];
4095 + struct ieee80211_hdr *hdr;
4096 +
4097 + hdr = (struct ieee80211_hdr *) skb->data;
4098 +
4099 + if (!tkey->key_set)
4100 + return -1;
4101 +
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;
4107 + }
4108 + // }
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))
4112 + #else
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))
4115 + #endif
4116 + return -1;
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),
4123 + keyidx);
4124 + if (skb->dev)
4125 + ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
4126 + tkey->dot11RSNAStatsTKIPLocalMICFailures++;
4127 + return -1;
4128 + }
4129 +
4130 + /* Update TSC counters for RX now that the packet verification has
4131 + * completed. */
4132 + tkey->rx_iv32 = tkey->rx_iv32_new;
4133 + tkey->rx_iv16 = tkey->rx_iv16_new;
4134 +
4135 + skb_trim(skb, skb->len - 8);
4136 +
4137 + return 0;
4138 +}
4139 +
4140 +
4141 +static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
4142 +{
4143 + struct ieee80211_tkip_data *tkey = priv;
4144 + int keyidx;
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;
4148 + #else
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;
4153 + #endif
4154 +
4155 + keyidx = tkey->key_idx;
4156 + memset(tkey, 0, sizeof(*tkey));
4157 + tkey->key_idx = keyidx;
4158 +
4159 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
4160 + tkey->tfm_michael = tfm;
4161 + tkey->tfm_arc4 = tfm2;
4162 + #else
4163 + tkey->tx_tfm_michael = tfm;
4164 + tkey->tx_tfm_arc4 = tfm2;
4165 + tkey->rx_tfm_michael = tfm3;
4166 + tkey->rx_tfm_arc4 = tfm4;
4167 + #endif
4168 +
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 */
4173 + if (seq) {
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];
4177 + }
4178 + } else if (len == 0)
4179 + tkey->key_set = 0;
4180 + else
4181 + return -1;
4182 +
4183 + return 0;
4184 +}
4185 +
4186 +
4187 +static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
4188 +{
4189 + struct ieee80211_tkip_data *tkey = priv;
4190 +
4191 + if (len < TKIP_KEY_LEN)
4192 + return -1;
4193 +
4194 + if (!tkey->key_set)
4195 + return 0;
4196 + memcpy(key, tkey->key, TKIP_KEY_LEN);
4197 +
4198 + if (seq) {
4199 + /* Return the sequence number of the last transmitted frame. */
4200 + u16 iv16 = tkey->tx_iv16;
4201 + u32 iv32 = tkey->tx_iv32;
4202 + if (iv16 == 0)
4203 + iv32--;
4204 + iv16--;
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;
4211 + }
4212 +
4213 + return TKIP_KEY_LEN;
4214 +}
4215 +
4216 +
4217 +static char * ieee80211_tkip_print_stats(char *p, void *priv)
4218 +{
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);
4240 + return p;
4241 +}
4242 +
4243 +
4244 +static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
4245 + .name = "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,
4258 +};
4259 +
4260 +
4261 +int ieee80211_crypto_tkip_init(void)
4262 +{
4263 + return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
4264 +}
4265 +
4266 +
4267 +void ieee80211_crypto_tkip_exit(void)
4268 +{
4269 + ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
4270 +}
4271 +
4272 +
4273 +void ieee80211_tkip_null(void)
4274 +{
4275 +// printk("============>%s()\n", __FUNCTION__);
4276 + return;
4277 +}
4278 +
4279 +#if 0
4280 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
4281 +EXPORT_SYMBOL(ieee80211_tkip_null);
4282 +#else
4283 +EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null);
4284 +#endif
4285 +#endif
4286 +
4287 +
4288 +//module_init(ieee80211_crypto_tkip_init);
4289 +//module_exit(ieee80211_crypto_tkip_exit);
4290 --- /dev/null
4291 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c
4292 @@ -0,0 +1,394 @@
4293 +/*
4294 + * Host AP crypt: host-based WEP encryption implementation for Host AP driver
4295 + *
4296 + * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
4297 + *
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
4301 + * more details.
4302 + */
4303 +
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>
4312 +
4313 +#include "ieee80211.h"
4314 +
4315 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
4316 +#include "rtl_crypto.h"
4317 +#else
4318 +#include <linux/crypto.h>
4319 +#endif
4320 +
4321 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
4322 + #include <asm/scatterlist.h>
4323 +#else
4324 + #include <linux/scatterlist.h>
4325 +#endif
4326 +//#include <asm/scatterlist.h>
4327 +#include <linux/crc32.h>
4328 +
4329 +MODULE_AUTHOR("Jouni Malinen");
4330 +MODULE_DESCRIPTION("Host AP crypt: WEP");
4331 +MODULE_LICENSE("GPL");
4332 +
4333 +#ifdef OPENSUSE_SLED
4334 +#ifndef IN_OPENSUSE_SLED
4335 +#define IN_OPENSUSE_SLED 1
4336 +#endif
4337 +#endif
4338 +
4339 +
4340 +struct prism2_wep_data {
4341 + u32 iv;
4342 +#define WEP_KEY_LEN 13
4343 + u8 key[WEP_KEY_LEN + 1];
4344 + u8 key_len;
4345 + u8 key_idx;
4346 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
4347 + struct crypto_tfm *tfm;
4348 + #else
4349 + struct crypto_blkcipher *tx_tfm;
4350 + struct crypto_blkcipher *rx_tfm;
4351 + #endif
4352 +};
4353 +
4354 +
4355 +static void * prism2_wep_init(int keyidx)
4356 +{
4357 + struct prism2_wep_data *priv;
4358 +
4359 + priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
4360 + if (priv == NULL)
4361 + goto fail;
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");
4369 + goto fail;
4370 + }
4371 + #else
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;
4377 + goto fail;
4378 + }
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;
4384 + goto fail;
4385 + }
4386 + #endif
4387 +
4388 + /* start WEP IV from a random value */
4389 + get_random_bytes(&priv->iv, 4);
4390 +
4391 + return priv;
4392 +
4393 +fail:
4394 + //#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
4395 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
4396 + if (priv) {
4397 + if (priv->tfm)
4398 + crypto_free_tfm(priv->tfm);
4399 + kfree(priv);
4400 + }
4401 + #else
4402 + if (priv) {
4403 + if (priv->tx_tfm)
4404 + crypto_free_blkcipher(priv->tx_tfm);
4405 + if (priv->rx_tfm)
4406 + crypto_free_blkcipher(priv->rx_tfm);
4407 + kfree(priv);
4408 + }
4409 + #endif
4410 + return NULL;
4411 +}
4412 +
4413 +
4414 +static void prism2_wep_deinit(void *priv)
4415 +{
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);
4421 + #else
4422 + if (_priv) {
4423 + if (_priv->tx_tfm)
4424 + crypto_free_blkcipher(_priv->tx_tfm);
4425 + if (_priv->rx_tfm)
4426 + crypto_free_blkcipher(_priv->rx_tfm);
4427 + }
4428 + #endif
4429 + kfree(priv);
4430 +}
4431 +
4432 +
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.
4436 + *
4437 + * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
4438 + */
4439 +static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
4440 +{
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};
4445 +#endif
4446 + u32 klen, len;
4447 + u8 key[WEP_KEY_LEN + 3];
4448 + u8 *pos;
4449 +#ifndef JOHN_HWSEC
4450 + u32 crc;
4451 + u8 *icv;
4452 + struct scatterlist sg;
4453 +#endif
4454 + if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
4455 + skb->len < hdr_len)
4456 + return -1;
4457 +
4458 + len = skb->len - hdr_len;
4459 + pos = skb_push(skb, 4);
4460 + memmove(pos, pos + 4, hdr_len);
4461 + pos += hdr_len;
4462 +
4463 + klen = 3 + wep->key_len;
4464 +
4465 + wep->iv++;
4466 +
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;
4474 + }
4475 +
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;
4481 +
4482 + /* Copy rest of the WEP key (the secret part) */
4483 + memcpy(key + 3, wep->key, wep->key_len);
4484 +
4485 +#ifndef JOHN_HWSEC
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);
4489 +#else
4490 + crc = ~ether_crc_le(len, pos);
4491 +#endif
4492 + icv = skb_put(skb, 4);
4493 + icv[0] = crc;
4494 + icv[1] = crc >> 8;
4495 + icv[2] = crc >> 16;
4496 + icv[3] = crc >> 24;
4497 +
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);
4505 +
4506 + return 0;
4507 + #else
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;
4513 + #else
4514 + sg_init_one(&sg, pos, len+4);
4515 + #endif
4516 + return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
4517 + #endif
4518 +#endif /* JOHN_HWSEC */
4519 + return 0;
4520 +}
4521 +
4522 +
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.
4526 + *
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.
4529 + */
4530 +static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
4531 +{
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};
4536 + #endif
4537 + u32 klen, plen;
4538 + u8 key[WEP_KEY_LEN + 3];
4539 + u8 keyidx, *pos;
4540 +#ifndef JOHN_HWSEC
4541 + u32 crc;
4542 + u8 icv[4];
4543 + struct scatterlist sg;
4544 +#endif
4545 + if (skb->len < hdr_len + 8)
4546 + return -1;
4547 +
4548 + pos = skb->data + hdr_len;
4549 + key[0] = *pos++;
4550 + key[1] = *pos++;
4551 + key[2] = *pos++;
4552 + keyidx = *pos++ >> 6;
4553 + if (keyidx != wep->key_idx)
4554 + return -1;
4555 +
4556 + klen = 3 + wep->key_len;
4557 +
4558 + /* Copy rest of the WEP key (the secret part) */
4559 + memcpy(key + 3, wep->key, wep->key_len);
4560 +
4561 + /* Apply RC4 to data and compute CRC32 over decrypted data */
4562 + plen = skb->len - hdr_len - 8;
4563 +#ifndef JOHN_HWSEC
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);
4571 +#else
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;
4577 + #else
4578 + sg_init_one(&sg, pos, plen+4);
4579 + #endif
4580 + if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
4581 + return -7;
4582 +#endif
4583 +
4584 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
4585 + crc = ~crc32_le(~0, pos, plen);
4586 +#else
4587 + crc = ~ether_crc_le(plen, pos);
4588 +#endif
4589 + icv[0] = crc;
4590 + icv[1] = crc >> 8;
4591 + icv[2] = crc >> 16;
4592 + icv[3] = crc >> 24;
4593 +
4594 + if (memcmp(icv, pos + plen, 4) != 0) {
4595 + /* ICV mismatch - drop frame */
4596 + return -2;
4597 + }
4598 +#endif /* JOHN_HWSEC */
4599 +
4600 + /* Remove IV and ICV */
4601 + memmove(skb->data + 4, skb->data, hdr_len);
4602 + skb_pull(skb, 4);
4603 + skb_trim(skb, skb->len - 4);
4604 + return 0;
4605 +}
4606 +
4607 +
4608 +static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
4609 +{
4610 + struct prism2_wep_data *wep = priv;
4611 +
4612 + if (len < 0 || len > WEP_KEY_LEN)
4613 + return -1;
4614 +
4615 + memcpy(wep->key, key, len);
4616 + wep->key_len = len;
4617 +
4618 + return 0;
4619 +}
4620 +
4621 +
4622 +static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
4623 +{
4624 + struct prism2_wep_data *wep = priv;
4625 +
4626 + if (len < wep->key_len)
4627 + return -1;
4628 +
4629 + memcpy(key, wep->key, wep->key_len);
4630 +
4631 + return wep->key_len;
4632 +}
4633 +
4634 +
4635 +static char * prism2_wep_print_stats(char *p, void *priv)
4636 +{
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);
4640 + return p;
4641 +}
4642 +
4643 +
4644 +static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
4645 + .name = "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,
4658 +};
4659 +
4660 +
4661 +int ieee80211_crypto_wep_init(void)
4662 +{
4663 + return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
4664 +}
4665 +
4666 +
4667 +void ieee80211_crypto_wep_exit(void)
4668 +{
4669 + ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
4670 +}
4671 +
4672 +
4673 +void ieee80211_wep_null(void)
4674 +{
4675 +// printk("============>%s()\n", __FUNCTION__);
4676 + return;
4677 +}
4678 +#if 0
4679 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
4680 +EXPORT_SYMBOL(ieee80211_wep_null);
4681 +#else
4682 +EXPORT_SYMBOL_NOVERS(ieee80211_wep_null);
4683 +#endif
4684 +#endif
4685 +//module_init(ieee80211_crypto_wep_init);
4686 +//module_exit(ieee80211_crypto_wep_exit);
4687 --- /dev/null
4688 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
4689 @@ -0,0 +1,1755 @@
4690 +/*
4691 + * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11
4692 + * remains copyright by the original authors
4693 + *
4694 + * Portions of the merged code are based on Host AP (software wireless
4695 + * LAN access point) driver for Intersil Prism2/2.5/3.
4696 + *
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>
4700 + *
4701 + * Adaption to a generic IEEE 802.11 stack by James Ketrenos
4702 + * <jketreno@linux.intel.com>
4703 + * Copyright (c) 2004, Intel Corporation
4704 + *
4705 + * Modified for Realtek's wi-fi cards by Andrea Merello
4706 + * <andreamrl@tiscali.it>
4707 + *
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
4711 + * more details.
4712 + */
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>
4721 +
4722 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13))
4723 +#include <linux/wireless.h>
4724 +#endif
4725 +
4726 +/*
4727 +#ifndef bool
4728 +#define bool int
4729 +#endif
4730 +
4731 +#ifndef true
4732 +#define true 1
4733 +#endif
4734 +
4735 +#ifndef false
4736 +#define false 0
4737 +#endif
4738 +*/
4739 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
4740 +#ifndef bool
4741 +typedef enum{false = 0, true} bool;
4742 +#endif
4743 +#endif
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
4750 +//#endif
4751 +
4752 +
4753 +#define aSifsTime 10
4754 +
4755 +#define MGMT_QUEUE_NUM 5
4756 +
4757 +
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
4762 +
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
4784 +
4785 +#define IEEE_KEY_MGMT_IEEE8021X 1
4786 +#define IEEE_KEY_MGMT_PSK 2
4787 +
4788 +
4789 +
4790 +#define IEEE_MLME_STA_DEAUTH 1
4791 +#define IEEE_MLME_STA_DISASSOC 2
4792 +
4793 +
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
4800 +
4801 +
4802 +#define IEEE_CRYPT_ALG_NAME_LEN 16
4803 +
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 +///////////////////////////////
4814 +#endif
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
4818 +
4819 +#define ieee80211_rx ieee80211_rx_rtl
4820 +
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
4827 +
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
4849 +
4850 +#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rtl
4851 +//by amy for ps
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
4856 +//by amy for ps
4857 +typedef struct ieee_param {
4858 + u32 cmd;
4859 + u8 sta_addr[ETH_ALEN];
4860 + union {
4861 + struct {
4862 + u8 name;
4863 + u32 value;
4864 + } wpa_param;
4865 + struct {
4866 + u32 len;
4867 + u8 reserved[32];
4868 + u8 data[0];
4869 + } wpa_ie;
4870 + struct{
4871 + int command;
4872 + int reason_code;
4873 + } mlme;
4874 + struct {
4875 + u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
4876 + u8 set_tx;
4877 + u32 err;
4878 + u8 idx;
4879 + u8 seq[8]; /* sequence counter (set: RX, get: TX) */
4880 + u16 key_len;
4881 + u8 key[0];
4882 + } crypt;
4883 +
4884 + } u;
4885 +}ieee_param;
4886 +
4887 +
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
4895 +#endif
4896 +
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)
4901 +{
4902 + unsigned long timeout = MSECS(msecs) + 1;
4903 +
4904 + while (timeout) {
4905 + set_current_state(TASK_UNINTERRUPTIBLE);
4906 + timeout = schedule_timeout(timeout);
4907 + }
4908 + return timeout;
4909 +}
4910 +#else
4911 +#define MSECS(t) msecs_to_jiffies(t)
4912 +#define msleep_interruptible_rtl msleep_interruptible
4913 +#endif
4914 +
4915 +#define IEEE80211_DATA_LEN 2304
4916 +/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
4917 + 6.2.1.1.2.
4918 +
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) */
4923 +
4924 +
4925 +#define IEEE80211_HLEN 30
4926 +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
4927 +
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
4933 +
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))
4937 +
4938 +/* this is stolen from ipw2200 driver */
4939 +#define IEEE_IBSS_MAC_HASH_SIZE 31
4940 +struct ieee_ibss_seq {
4941 + u8 mac[ETH_ALEN];
4942 + u16 seq_num[17];
4943 + u16 frag_num[17];
4944 + unsigned long packet_time[17];
4945 + struct list_head list;
4946 +};
4947 +
4948 +struct ieee80211_hdr {
4949 + u16 frame_ctl;
4950 + u16 duration_id;
4951 + u8 addr1[ETH_ALEN];
4952 + u8 addr2[ETH_ALEN];
4953 + u8 addr3[ETH_ALEN];
4954 + u16 seq_ctl;
4955 + u8 addr4[ETH_ALEN];
4956 +} __attribute__ ((packed));
4957 +
4958 +struct ieee80211_hdr_QOS {
4959 + u16 frame_ctl;
4960 + u16 duration_id;
4961 + u8 addr1[ETH_ALEN];
4962 + u8 addr2[ETH_ALEN];
4963 + u8 addr3[ETH_ALEN];
4964 + u16 seq_ctl;
4965 + u8 addr4[ETH_ALEN];
4966 + u16 QOS_ctl;
4967 +} __attribute__ ((packed));
4968 +
4969 +struct ieee80211_hdr_3addr {
4970 + u16 frame_ctl;
4971 + u16 duration_id;
4972 + u8 addr1[ETH_ALEN];
4973 + u8 addr2[ETH_ALEN];
4974 + u8 addr3[ETH_ALEN];
4975 + u16 seq_ctl;
4976 +} __attribute__ ((packed));
4977 +
4978 +struct ieee80211_hdr_3addr_QOS {
4979 + u16 frame_ctl;
4980 + u16 duration_id;
4981 + u8 addr1[ETH_ALEN];
4982 + u8 addr2[ETH_ALEN];
4983 + u8 addr3[ETH_ALEN];
4984 + u16 seq_ctl;
4985 + u16 QOS_ctl;
4986 +} __attribute__ ((packed));
4987 +
4988 +enum eap_type {
4989 + EAP_PACKET = 0,
4990 + EAPOL_START,
4991 + EAPOL_LOGOFF,
4992 + EAPOL_KEY,
4993 + EAPOL_ENCAP_ASF_ALERT
4994 +};
4995 +
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"
5002 +};
5003 +
5004 +static inline const char *eap_get_type(int type)
5005 +{
5006 + return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
5007 +}
5008 +
5009 +struct eapol {
5010 + u8 snap[6];
5011 + u16 ethertype;
5012 + u8 version;
5013 + u8 type;
5014 + u16 length;
5015 +} __attribute__ ((packed));
5016 +
5017 +#define IEEE80211_3ADDR_LEN 24
5018 +#define IEEE80211_4ADDR_LEN 30
5019 +#define IEEE80211_FCS_LEN 4
5020 +
5021 +#define MIN_FRAG_THRESHOLD 256U
5022 +#define MAX_FRAG_THRESHOLD 2346U
5023 +
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
5037 +
5038 +#define IEEE80211_FTYPE_MGMT 0x0000
5039 +#define IEEE80211_FTYPE_CTL 0x0004
5040 +#define IEEE80211_FTYPE_DATA 0x0008
5041 +
5042 +/* management */
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
5055 +
5056 +/* control */
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
5063 +
5064 +/* data */
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
5075 +
5076 +
5077 +#define IEEE80211_SCTL_FRAG 0x000F
5078 +#define IEEE80211_SCTL_SEQ 0xFFF0
5079 +
5080 +
5081 +/* debug macros */
5082 +
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)
5089 +#else
5090 +#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
5091 +#endif /* CONFIG_IEEE80211_DEBUG */
5092 +
5093 +/*
5094 + * To use the debug system;
5095 + *
5096 + * If you are defining a new debug classification, simply add it to the #define
5097 + * list here in the form of:
5098 + *
5099 + * #define IEEE80211_DL_xxxx VALUE
5100 + *
5101 + * shifting value to the left one bit from the previous entry. xxxx should be
5102 + * the name of the classification (for example, WEP)
5103 + *
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.
5107 + *
5108 + * To add your debug level to the list of levels seen when you perform
5109 + *
5110 + * % cat /proc/net/ipw/debug_level
5111 + *
5112 + * you simply need to add your entry to the ipw_debug_levels array.
5113 + *
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
5116 + *
5117 + */
5118 +
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)
5127 +
5128 +#define IEEE80211_DL_TX (1<<8)
5129 +#define IEEE80211_DL_RX (1<<9)
5130 +
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)
5134 +
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 */
5148 +
5149 +#ifndef WIRELESS_SPY
5150 +#define WIRELESS_SPY // enable iwspy support
5151 +#endif
5152 +#include <net/iw_handler.h> // new driver API
5153 +
5154 +#ifndef ETH_P_PAE
5155 +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
5156 +#endif /* ETH_P_PAE */
5157 +
5158 +#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
5159 +
5160 +#ifndef ETH_P_80211_RAW
5161 +#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
5162 +#endif
5163 +
5164 +/* IEEE 802.11 defines */
5165 +
5166 +#define P80211_OUI_LEN 3
5167 +
5168 +struct ieee80211_snap_hdr {
5169 +
5170 + u8 dsap; /* always 0xAA */
5171 + u8 ssap; /* always 0xAA */
5172 + u8 ctrl; /* always 0x03 */
5173 + u8 oui[P80211_OUI_LEN]; /* organizational universal id */
5174 +
5175 +} __attribute__ ((packed));
5176 +
5177 +#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
5178 +
5179 +#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
5180 +#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
5181 +
5182 +#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
5183 +#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ)
5184 +
5185 +/* Authentication algorithms */
5186 +#define WLAN_AUTH_OPEN 0
5187 +#define WLAN_AUTH_SHARED_KEY 1
5188 +
5189 +#define WLAN_AUTH_CHALLENGE_LEN 128
5190 +
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)
5200 +
5201 +/* Status codes */
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
5213 +/* 802.11b */
5214 +#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
5215 +#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
5216 +#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
5217 +
5218 +/* Reason codes */
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
5228 +
5229 +
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
5241 +
5242 +#define IEEE80211_MGMT_HDR_LEN 24
5243 +#define IEEE80211_DATA_HDR3_LEN 24
5244 +#define IEEE80211_DATA_HDR4_LEN 30
5245 +
5246 +
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
5252 +
5253 +
5254 +#define IEEE80211_CCK_MODULATION (1<<0)
5255 +#define IEEE80211_OFDM_MODULATION (1<<1)
5256 +
5257 +#define IEEE80211_24GHZ_BAND (1<<0)
5258 +#define IEEE80211_52GHZ_BAND (1<<1)
5259 +
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
5275 +
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)
5288 +
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)
5295 +
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)
5308 +
5309 +#define IEEE80211_NUM_OFDM_RATES 8
5310 +#define IEEE80211_NUM_CCK_RATES 4
5311 +#define IEEE80211_OFDM_SHIFT_MASK_A 4
5312 +
5313 +
5314 +
5315 +
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 {
5320 + u32 mac_time[2];
5321 + u8 signalstrength;
5322 + s8 rssi;
5323 + u8 signal;
5324 + u8 noise;
5325 + u16 rate; /* in 100 kbps */
5326 + u8 received_channel;
5327 + u8 control;
5328 + u8 mask;
5329 + u8 freq;
5330 + u16 len;
5331 + u8 nic_type;
5332 +};
5333 +
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
5339 +
5340 +struct ieee80211_frag_entry {
5341 + unsigned long first_frag_time;
5342 + unsigned int seq;
5343 + unsigned int last_frag;
5344 + struct sk_buff *skb;
5345 + u8 src_addr[ETH_ALEN];
5346 + u8 dst_addr[ETH_ALEN];
5347 +};
5348 +
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;
5371 +};
5372 +
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;
5391 +};
5392 +
5393 +struct ieee80211_device;
5394 +
5395 +#include "ieee80211_crypt.h"
5396 +
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)
5406 +
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 */
5412 +
5413 +#define WEP_KEYS 4
5414 +#define WEP_KEY_LEN 13
5415 +
5416 +#define WEP_KEY_LEN_MODIF 32
5417 +
5418 +struct ieee80211_security {
5419 + u16 active_key:2,
5420 + enabled:1,
5421 + auth_mode:2,
5422 + auth_algo:4,
5423 + unicast_uses_group:1;
5424 + u8 key_sizes[WEP_KEYS];
5425 + u8 keys[WEP_KEYS][WEP_KEY_LEN_MODIF];
5426 + u8 level;
5427 + u16 flags;
5428 +} __attribute__ ((packed));
5429 +
5430 +
5431 +/*
5432 +
5433 + 802.11 data frame from AP
5434 +
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 + `-------------------------------------------------------------------'
5441 +
5442 +Total: 28-2340 bytes
5443 +
5444 +*/
5445 +
5446 +struct ieee80211_header_data {
5447 + u16 frame_ctl;
5448 + u16 duration_id;
5449 + u8 addr1[6];
5450 + u8 addr2[6];
5451 + u8 addr3[6];
5452 + u16 seq_ctrl;
5453 +};
5454 +
5455 +#define BEACON_PROBE_SSID_ID_POSITION 12
5456 +
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
5471 +
5472 +#ifdef ENABLE_DOT11D
5473 +typedef enum
5474 +{
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;
5487 +#endif
5488 +
5489 +struct ieee80211_info_element_hdr {
5490 + u8 id;
5491 + u8 len;
5492 +} __attribute__ ((packed));
5493 +
5494 +struct ieee80211_info_element {
5495 + u8 id;
5496 + u8 len;
5497 + u8 data[0];
5498 +} __attribute__ ((packed));
5499 +
5500 +/*
5501 + * These are the data types that can make up management packets
5502 + *
5503 + u16 auth_algorithm;
5504 + u16 auth_sequence;
5505 + u16 beacon_interval;
5506 + u16 capability;
5507 + u8 current_ap[ETH_ALEN];
5508 + u16 listen_interval;
5509 + struct {
5510 + u16 association_id:14, reserved:2;
5511 + } __attribute__ ((packed));
5512 + u32 time_stamp[2];
5513 + u16 reason;
5514 + u16 status;
5515 +*/
5516 +
5517 +#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
5518 +#define IEEE80211_DEFAULT_BASIC_RATE 10
5519 +
5520 +struct ieee80211_authentication {
5521 + struct ieee80211_header_data header;
5522 + u16 algorithm;
5523 + u16 transaction;
5524 + u16 status;
5525 + //struct ieee80211_info_element_hdr info_element;
5526 +} __attribute__ ((packed));
5527 +
5528 +
5529 +struct ieee80211_probe_response {
5530 + struct ieee80211_header_data header;
5531 + u32 time_stamp[2];
5532 + u16 beacon_interval;
5533 + u16 capability;
5534 + struct ieee80211_info_element info_element;
5535 +} __attribute__ ((packed));
5536 +
5537 +struct ieee80211_probe_request {
5538 + struct ieee80211_header_data header;
5539 + /*struct ieee80211_info_element info_element;*/
5540 +} __attribute__ ((packed));
5541 +
5542 +struct ieee80211_assoc_request_frame {
5543 + struct ieee80211_hdr_3addr header;
5544 + u16 capability;
5545 + u16 listen_interval;
5546 + //u8 current_ap[ETH_ALEN];
5547 + struct ieee80211_info_element_hdr info_element;
5548 +} __attribute__ ((packed));
5549 +
5550 +struct ieee80211_assoc_response_frame {
5551 + struct ieee80211_hdr_3addr header;
5552 + u16 capability;
5553 + u16 status;
5554 + u16 aid;
5555 + struct ieee80211_info_element info_element; /* supported rates */
5556 +} __attribute__ ((packed));
5557 +
5558 +struct ieee80211_disassoc_frame{
5559 + struct ieee80211_hdr_3addr header;
5560 + u16 reasoncode;
5561 +}__attribute__ ((packed));
5562 +
5563 +struct ieee80211_txb {
5564 + u8 nr_frags;
5565 + u8 encrypted;
5566 + u16 reserved;
5567 + u16 frag_size;
5568 + u16 payload_size;
5569 + struct sk_buff *fragments[0];
5570 +};
5571 +
5572 +struct ieee80211_wmm_ac_param {
5573 + u8 ac_aci_acm_aifsn;
5574 + u8 ac_ecwmin_ecwmax;
5575 + u16 ac_txop_limit;
5576 +};
5577 +
5578 +struct ieee80211_wmm_ts_info {
5579 + u8 ac_dir_tid;
5580 + u8 ac_up_psb;
5581 + u8 reserved;
5582 +} __attribute__ ((packed));
5583 +
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;
5590 + u32 inact_inter;
5591 + u32 suspen_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;
5597 + u32 delay_bound;
5598 + u32 min_phy_rate;
5599 + u16 surp_band_allow;
5600 + u16 medium_time;
5601 +}__attribute__((packed));
5602 +
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)
5607 +
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
5621 +
5622 +typedef struct _CHANNEL_LIST{
5623 + u8 Channel[MAX_CHANNEL_NUMBER + 1];
5624 + u8 Len;
5625 +}CHANNEL_LIST, *PCHANNEL_LIST;
5626 +
5627 +#define IEEE80211_SOFTMAC_SCAN_TIME 100//400
5628 +//(HZ / 2)
5629 +//by amy for ps
5630 +#define IEEE80211_WATCH_DOG_TIME 2000
5631 +//by amy for ps
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)
5636 +
5637 +#define CRC_LENGTH 4U
5638 +
5639 +#define MAX_WPA_IE_LEN 64
5640 +
5641 +#define NETWORK_EMPTY_ESSID (1<<0)
5642 +#define NETWORK_HAS_OFDM (1<<1)
5643 +#define NETWORK_HAS_CCK (1<<2)
5644 +
5645 +#define IEEE80211_DTIM_MBCAST 4
5646 +#define IEEE80211_DTIM_UCAST 2
5647 +#define IEEE80211_DTIM_VALID 1
5648 +#define IEEE80211_DTIM_INVALID 0
5649 +
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
5658 +#endif
5659 +
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
5667 +
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 : \
5675 + WME_AC_VO)
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 : \
5681 + 0)
5682 +
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];
5687 + u16 ether_type;
5688 +} __attribute__((packed));
5689 +
5690 +#ifndef ETHERTYPE_PAE
5691 +#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */
5692 +#endif
5693 +#ifndef ETHERTYPE_IP
5694 +#define ETHERTYPE_IP 0x0800 /* IP protocol */
5695 +#endif
5696 +
5697 +struct ieee80211_network {
5698 + /* These entries are used to identify a unique network */
5699 + u8 bssid[ETH_ALEN];
5700 + u8 channel;
5701 + /* Ensure null-terminated for any debug msgs */
5702 + u8 ssid[IW_ESSID_MAX_SIZE + 1];
5703 + u8 ssid_len;
5704 +
5705 + /* These are network statistics */
5706 + struct ieee80211_rx_stats stats;
5707 + u16 capability;
5708 + u8 rates[MAX_RATES_LENGTH];
5709 + u8 rates_len;
5710 + u8 rates_ex[MAX_RATES_EX_LENGTH];
5711 + u8 rates_ex_len;
5712 + unsigned long last_scanned;
5713 + u8 mode;
5714 + u8 flags;
5715 + u32 last_associate;
5716 + u32 time_stamp[2];
5717 + u16 beacon_interval;
5718 + u16 listen_interval;
5719 + u16 atim_window;
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;
5724 + u8 dtim_period;
5725 + u8 dtim_data;
5726 + u32 last_dtim_sta_time[2];
5727 + struct list_head list;
5728 + //appeded for QoS
5729 + u8 wmm_info;
5730 + struct ieee80211_wmm_ac_param wmm_param[4];
5731 + u8 QoS_Enable;
5732 + u8 SignalStrength;
5733 +//by amy 080312
5734 + u8 HighestOperaRate;
5735 +//by amy 080312
5736 +#ifdef THOMAS_TURBO
5737 + u8 Turbo_Enable;//enable turbo mode, added by thomas
5738 +#endif
5739 +#ifdef ENABLE_DOT11D
5740 + u16 CountryIeLen;
5741 + u8 CountryIeBuf[MAX_IE_LEN];
5742 +#endif
5743 +};
5744 +
5745 +enum ieee80211_state {
5746 +
5747 + /* the card is not linked at all */
5748 + IEEE80211_NOLINK = 0,
5749 +
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)
5756 + */
5757 +
5758 + /* the association procedure will start (wq scheduling)*/
5759 + IEEE80211_ASSOCIATING,
5760 + IEEE80211_ASSOCIATING_RETRY,
5761 +
5762 + /* the association procedure is sending AUTH request*/
5763 + IEEE80211_ASSOCIATING_AUTHENTICATING,
5764 +
5765 + /* the association procedure has successfully authentcated
5766 + * and is sending association request
5767 + */
5768 + IEEE80211_ASSOCIATING_AUTHENTICATED,
5769 +
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
5772 + */
5773 + IEEE80211_LINKED,
5774 +
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.
5779 + */
5780 + IEEE80211_LINKED_SCANNING,
5781 +
5782 +};
5783 +
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]
5788 +
5789 +
5790 +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
5791 +extern inline int is_multicast_ether_addr(const u8 *addr)
5792 +{
5793 + return ((addr[0] != 0xff) && (0x01 & addr[0]));
5794 +}
5795 +#endif
5796 +
5797 +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13))
5798 +extern inline int is_broadcast_ether_addr(const u8 *addr)
5799 +{
5800 + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
5801 + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
5802 +}
5803 +#endif
5804 +
5805 +#define CFG_IEEE80211_RESERVE_FCS (1<<0)
5806 +#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
5807 +
5808 +typedef struct tx_pending_t{
5809 + int frag;
5810 + struct ieee80211_txb *txb;
5811 +}tx_pending_t;
5812 +
5813 +
5814 +struct ieee80211_device {
5815 + struct net_device *dev;
5816 +
5817 + /* Bookkeeping structures */
5818 + struct net_device_stats stats;
5819 + struct ieee80211_stats ieee_stats;
5820 + struct ieee80211_softmac_stats softmac_stats;
5821 +
5822 + /* Probe / Beacon management */
5823 + struct list_head network_free_list;
5824 + struct list_head network_list;
5825 + struct ieee80211_network *networks;
5826 + int scans;
5827 + int scan_age;
5828 +
5829 + int iw_mode; /* operating mode (IW_MODE_*) */
5830 +
5831 + spinlock_t lock;
5832 + spinlock_t wpax_suitlist_lock;
5833 +
5834 + int tx_headroom; /* Set to size of any additional room needed at front
5835 + * of allocated Tx SKBs */
5836 + u32 config;
5837 +
5838 + /* WEP and other encryption related settings at the device level */
5839 + int open_wep; /* Set to 1 to allow unencrypted frames */
5840 +
5841 + int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
5842 + * WEP key changes */
5843 +
5844 + /* If the host performs {en,de}cryption, then set to 1 */
5845 + int host_encrypt;
5846 + int host_decrypt;
5847 + int ieee802_1x; /* is IEEE 802.1X used */
5848 +
5849 + /* WPA data */
5850 + int wpa_enabled;
5851 + int drop_unencrypted;
5852 + int tkip_countermeasures;
5853 + int privacy_invoked;
5854 + size_t wpa_ie_len;
5855 + u8 *wpa_ie;
5856 +
5857 + u8 ap_mac_addr[6];
5858 + u16 pairwise_key_type;
5859 + u16 broadcast_key_type;
5860 +
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;
5865 +
5866 + int bcrx_sta_key; /* use individual keys to override default keys even
5867 + * with RX of broad/multicast frames */
5868 +
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 */
5874 +
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
5882 + */
5883 + struct ieee80211_network current_network;
5884 +
5885 +
5886 + enum ieee80211_state state;
5887 +
5888 + int short_slot;
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 */
5893 +
5894 + /* used for forcing the ibss workqueue to terminate
5895 + * without wait for the syncro scan to terminate
5896 + */
5897 + short sync_scan_hurryup;
5898 +
5899 +#ifdef ENABLE_DOT11D
5900 + void * pDot11dInfo;
5901 + bool bGlobalDomain;
5902 +
5903 + // For Liteon Ch12~13 passive scan
5904 + u8 MinPassiveChnlNum;
5905 + u8 IbssStartChnl;
5906 +#else
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];
5910 +#endif
5911 +
5912 + int rate; /* current rate */
5913 + int basic_rate;
5914 + //FIXME: pleace callback, see if redundant with softmac_features
5915 + short active_scan;
5916 +
5917 + /* this contains flags for selectively enable softmac support */
5918 + u16 softmac_features;
5919 +
5920 + /* if the sequence control field is not filled by HW */
5921 + u16 seq_ctrl[5];
5922 +
5923 + /* association procedure transaction sequence number */
5924 + u16 associate_seq;
5925 +
5926 + /* AID for RTXed association responses */
5927 + u16 assoc_id;
5928 +
5929 + /* power save mode related*/
5930 + short ps;
5931 + short sta_sleep;
5932 + int ps_timeout;
5933 + struct tasklet_struct ps_task;
5934 + u32 ps_th;
5935 + u32 ps_tl;
5936 +
5937 + short raw_tx;
5938 + /* used if IEEE_SOFTMAC_TX_QUEUE is set */
5939 + short queue_stop;
5940 + short scanning;
5941 + short proto_started;
5942 +
5943 + struct semaphore wx_sem;
5944 + struct semaphore scan_sem;
5945 +
5946 + spinlock_t mgmt_tx_lock;
5947 + spinlock_t beacon_lock;
5948 +
5949 + short beacon_txing;
5950 +
5951 + short wap_set;
5952 + short ssid_set;
5953 +
5954 + u8 wpax_type_set; //{added by David, 2006.9.28}
5955 + u32 wpax_type_notify; //{added by David, 2006.9.26}
5956 +
5957 + /* QoS related flag */
5958 + char init_wmmparam_flag;
5959 +
5960 + /* for discarding duplicated packets in IBSS */
5961 + struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
5962 +
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];
5967 +
5968 + /* for PS mode */
5969 + unsigned long last_rx_ps_time;
5970 +
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;
5975 +
5976 +
5977 + /* used if IEEE_SOFTMAC_TX_QUEUE is set */
5978 + struct tx_pending_t tx_pending;
5979 +
5980 + /* used if IEEE_SOFTMAC_ASSOCIATE is set */
5981 + struct timer_list associate_timer;
5982 +
5983 + /* used if IEEE_SOFTMAC_BEACONS is set */
5984 + struct timer_list beacon_timer;
5985 +
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;
5996 + bool bInactivePs;
5997 + bool actscanning;
5998 + bool beinretry;
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
6004 + bool bHwRadioOff;
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;
6018 +
6019 +//Added for RF power on power off by lizhaoming 080512
6020 + struct delayed_work GPIOChangeRFWorkItem;
6021 +#else
6022 +
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;
6035 +
6036 +//Added for RF power on power off by lizhaoming 080512
6037 + struct work_struct GPIOChangeRFWorkItem;
6038 +#endif
6039 + struct workqueue_struct *wq;
6040 +
6041 + /* Callback functions */
6042 + void (*set_security)(struct net_device *dev,
6043 + struct ieee80211_security *sec);
6044 +
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
6048 + */
6049 + int (*hard_start_xmit)(struct ieee80211_txb *txb,
6050 + struct net_device *dev);
6051 +
6052 + int (*reset_port)(struct net_device *dev);
6053 +
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.
6060 + */
6061 + int (*softmac_hard_start_xmit)(struct sk_buff *skb,
6062 + struct net_device *dev);
6063 +
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.
6069 + */
6070 + void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
6071 + struct net_device *dev,int rate);
6072 +
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.
6076 + */
6077 + void (*data_hard_stop)(struct net_device *dev);
6078 +
6079 + /* OK this is complementar to data_poll_hard_stop */
6080 + void (*data_hard_resume)(struct net_device *dev);
6081 +
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.
6085 + */
6086 + void (*set_chan)(struct net_device *dev,short ch);
6087 +
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.
6091 + *
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.
6102 + */
6103 + void (*scan_syncro)(struct net_device *dev);
6104 + void (*start_scan)(struct net_device *dev);
6105 + void (*stop_scan)(struct net_device *dev);
6106 +
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
6111 + */
6112 + void (*link_change)(struct net_device *dev);
6113 +
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.
6119 + */
6120 + void (*start_send_beacons) (struct net_device *dev);
6121 + void (*stop_send_beacons) (struct net_device *dev);
6122 +
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);
6128 +
6129 + /* QoS related */
6130 + //void (*wmm_param_update) (struct net_device *dev, u8 *ac_param);
6131 + //void (*wmm_param_update) (struct ieee80211_device *ieee);
6132 +
6133 + /* This must be the last item so that it points to the data
6134 + * allocated beyond this structure by alloc_ieee80211 */
6135 + u8 priv[0];
6136 +};
6137 +
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)
6142 +
6143 +/* Generate a 802.11 header */
6144 +
6145 +/* Uses the channel change callback directly
6146 + * instead of [start/stop] scan callbacks
6147 + */
6148 +#define IEEE_SOFTMAC_SCAN (1<<2)
6149 +
6150 +/* Perform authentication and association handshake */
6151 +#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
6152 +
6153 +/* Generate probe requests */
6154 +#define IEEE_SOFTMAC_PROBERQ (1<<4)
6155 +
6156 +/* Generate respones to probe requests */
6157 +#define IEEE_SOFTMAC_PROBERS (1<<5)
6158 +
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)
6163 +
6164 +/* Uses only the softmac_data_hard_start_xmit
6165 + * even for TX management frames.
6166 + */
6167 +#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
6168 +
6169 +/* Generate beacons. The stack will enqueue beacons
6170 + * to the card
6171 + */
6172 +#define IEEE_SOFTMAC_BEACONS (1<<6)
6173 +
6174 +
6175 +
6176 +static inline void *ieee80211_priv(struct net_device *dev)
6177 +{
6178 + return ((struct ieee80211_device *)netdev_priv(dev))->priv;
6179 +}
6180 +
6181 +extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
6182 +{
6183 + /* Single white space is for Linksys APs */
6184 + if (essid_len == 1 && essid[0] == ' ')
6185 + return 1;
6186 +
6187 + /* Otherwise, if the entire essid is 0, we assume it is hidden */
6188 + while (essid_len) {
6189 + essid_len--;
6190 + if (essid[essid_len] != '\0')
6191 + return 0;
6192 + }
6193 +
6194 + return 1;
6195 +}
6196 +
6197 +extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
6198 +{
6199 + /*
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
6203 + *
6204 + */
6205 + if ((mode & IEEE_A) &&
6206 + (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
6207 + (ieee->freq_band & IEEE80211_52GHZ_BAND))
6208 + return 1;
6209 +
6210 + if ((mode & IEEE_G) &&
6211 + (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
6212 + (ieee->freq_band & IEEE80211_24GHZ_BAND))
6213 + return 1;
6214 +
6215 + if ((mode & IEEE_B) &&
6216 + (ieee->modulation & IEEE80211_CCK_MODULATION) &&
6217 + (ieee->freq_band & IEEE80211_24GHZ_BAND))
6218 + return 1;
6219 +
6220 + return 0;
6221 +}
6222 +
6223 +extern inline int ieee80211_get_hdrlen(u16 fc)
6224 +{
6225 + int hdrlen = 24;
6226 +
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*/
6233 + break;
6234 + case IEEE80211_FTYPE_CTL:
6235 + switch (WLAN_FC_GET_STYPE(fc)) {
6236 + case IEEE80211_STYPE_CTS:
6237 + case IEEE80211_STYPE_ACK:
6238 + hdrlen = 10;
6239 + break;
6240 + default:
6241 + hdrlen = 16;
6242 + break;
6243 + }
6244 + break;
6245 + }
6246 +
6247 + return hdrlen;
6248 +}
6249 +
6250 +
6251 +
6252 +/* ieee80211.c */
6253 +extern void free_ieee80211(struct net_device *dev);
6254 +extern struct net_device *alloc_ieee80211(int sizeof_priv);
6255 +
6256 +extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
6257 +
6258 +/* ieee80211_tx.c */
6259 +
6260 +extern int ieee80211_encrypt_fragment(
6261 + struct ieee80211_device *ieee,
6262 + struct sk_buff *frag,
6263 + int hdr_len);
6264 +
6265 +extern int ieee80211_xmit(struct sk_buff *skb,
6266 + struct net_device *dev);
6267 +extern void ieee80211_txb_free(struct ieee80211_txb *);
6268 +
6269 +
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);
6276 +
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);
6296 +
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,
6303 + u16 stype);
6304 +extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
6305 +
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);
6333 +
6334 +//Add for RF power on power off by lizhaoming 080512
6335 +extern void SendDisassociation(struct ieee80211_device *ieee,
6336 + u8* asSta,
6337 + u8 asRsn);
6338 +
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 */
6344 +
6345 +extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
6346 + struct iw_request_info *info,
6347 + union iwreq_data *wrqu, char *ext);
6348 +
6349 +extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
6350 + struct iw_request_info *info,
6351 + union iwreq_data *awrq,
6352 + char *extra);
6353 +
6354 +extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
6355 +
6356 +extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
6357 + struct iw_request_info *info,
6358 + union iwreq_data *wrqu, char *extra);
6359 +
6360 +extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
6361 + struct iw_request_info *info,
6362 + union iwreq_data *wrqu, char *extra);
6363 +
6364 +extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
6365 + union iwreq_data *wrqu, char *b);
6366 +
6367 +extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
6368 + union iwreq_data *wrqu, char *b);
6369 +
6370 +extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
6371 + struct iw_request_info *a,
6372 + union iwreq_data *wrqu, char *extra);
6373 +
6374 +extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
6375 + union iwreq_data *wrqu, char *b);
6376 +
6377 +extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
6378 + union iwreq_data *wrqu, char *b);
6379 +
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);
6384 +#else
6385 + extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
6386 +#endif
6387 +//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
6388 +
6389 +extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
6390 + struct iw_request_info *info,
6391 + union iwreq_data *wrqu, char *extra);
6392 +
6393 +extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
6394 + struct iw_request_info *info,
6395 + union iwreq_data *wrqu, char *extra);
6396 +
6397 +extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
6398 + struct iw_request_info *info,
6399 + union iwreq_data *wrqu, char *extra);
6400 +
6401 +extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
6402 + struct iw_request_info *info,
6403 + union iwreq_data *wrqu, char *extra);
6404 +
6405 +extern void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee);
6406 +
6407 +extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr);
6408 +
6409 +extern const long ieee80211_wlan_frequencies[];
6410 +
6411 +extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
6412 +{
6413 + ieee->scans++;
6414 +}
6415 +
6416 +extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
6417 +{
6418 + return ieee->scans;
6419 +}
6420 +
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;
6425 +
6426 + if (ieee80211_is_empty_essid(essid, essid_len)) {
6427 + memcpy(escaped, "<hidden>", sizeof("<hidden>"));
6428 + return escaped;
6429 + }
6430 +
6431 + essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
6432 + while (essid_len--) {
6433 + if (*s == '\0') {
6434 + *d++ = '\\';
6435 + *d++ = '0';
6436 + s++;
6437 + } else {
6438 + *d++ = *s++;
6439 + }
6440 + }
6441 + *d = '\0';
6442 + return escaped;
6443 +}
6444 +#endif /* IEEE80211_H */
6445 --- /dev/null
6446 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
6447 @@ -0,0 +1,299 @@
6448 +/*******************************************************************************
6449 +
6450 + Copyright(c) 2004 Intel Corporation. All rights reserved.
6451 +
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>
6457 +
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.
6461 +
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
6465 + more details.
6466 +
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.
6470 +
6471 + The full GNU General Public License is included in this distribution in the
6472 + file called LICENSE.
6473 +
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
6477 +
6478 +*******************************************************************************/
6479 +
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>
6501 +
6502 +#include "ieee80211.h"
6503 +
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");
6507 +
6508 +#define DRV_NAME "ieee80211"
6509 +
6510 +static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
6511 +{
6512 + if (ieee->networks)
6513 + return 0;
6514 +
6515 + ieee->networks = kmalloc(
6516 + MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
6517 + GFP_KERNEL);
6518 + if (!ieee->networks) {
6519 + printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
6520 + ieee->dev->name);
6521 + return -ENOMEM;
6522 + }
6523 +
6524 + memset(ieee->networks, 0,
6525 + MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
6526 +
6527 + return 0;
6528 +}
6529 +
6530 +static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
6531 +{
6532 + if (!ieee->networks)
6533 + return;
6534 + kfree(ieee->networks);
6535 + ieee->networks = NULL;
6536 +}
6537 +
6538 +static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
6539 +{
6540 + int i;
6541 +
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);
6546 +}
6547 +
6548 +
6549 +struct net_device *alloc_ieee80211(int sizeof_priv)
6550 +{
6551 + struct ieee80211_device *ieee;
6552 + struct net_device *dev;
6553 + int i,err;
6554 +
6555 + IEEE80211_DEBUG_INFO("Initializing...\n");
6556 +
6557 + dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
6558 + if (!dev) {
6559 + IEEE80211_ERROR("Unable to network device.\n");
6560 + goto failed;
6561 + }
6562 + ieee = netdev_priv(dev);
6563 + dev->hard_start_xmit = ieee80211_xmit;
6564 +
6565 + ieee->dev = dev;
6566 +
6567 + err = ieee80211_networks_allocate(ieee);
6568 + if (err) {
6569 + IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
6570 + err);
6571 + goto failed;
6572 + }
6573 + ieee80211_networks_initialize(ieee);
6574 +
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;
6579 +
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 */
6584 +
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;
6589 +
6590 + spin_lock_init(&ieee->lock);
6591 + spin_lock_init(&ieee->wpax_suitlist_lock);
6592 +
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;
6599 + ieee->raw_tx = 0;
6600 +
6601 + ieee80211_softmac_init(ieee);
6602 +
6603 + for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
6604 + INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
6605 +
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;
6610 + }
6611 +//These function were added to load crypte module autoly
6612 + ieee80211_tkip_null();
6613 + ieee80211_wep_null();
6614 + ieee80211_ccmp_null();
6615 + return dev;
6616 +
6617 + failed:
6618 + if (dev)
6619 + free_netdev(dev);
6620 + return NULL;
6621 +}
6622 +
6623 +
6624 +void free_ieee80211(struct net_device *dev)
6625 +{
6626 + struct ieee80211_device *ieee = netdev_priv(dev);
6627 +
6628 + int i;
6629 + struct list_head *p, *q;
6630 +
6631 +
6632 + ieee80211_softmac_free(ieee);
6633 + del_timer_sync(&ieee->crypt_deinit_timer);
6634 + ieee80211_crypt_deinit_entries(ieee, 1);
6635 +
6636 + for (i = 0; i < WEP_KEYS; i++) {
6637 + struct ieee80211_crypt_data *crypt = ieee->crypt[i];
6638 + if (crypt) {
6639 + if (crypt->ops) {
6640 + crypt->ops->deinit(crypt->priv);
6641 + module_put(crypt->ops->owner);
6642 + }
6643 + kfree(crypt);
6644 + ieee->crypt[i] = NULL;
6645 + }
6646 + }
6647 +
6648 + ieee80211_networks_free(ieee);
6649 +
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));
6653 + list_del(p);
6654 + }
6655 + }
6656 +
6657 +
6658 + free_netdev(dev);
6659 +}
6660 +
6661 +#ifdef CONFIG_IEEE80211_DEBUG
6662 +
6663 +static int debug = 0;
6664 +u32 ieee80211_debug_level = 0;
6665 +struct proc_dir_entry *ieee80211_proc = NULL;
6666 +
6667 +static int show_debug_level(char *page, char **start, off_t offset,
6668 + int count, int *eof, void *data)
6669 +{
6670 + return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
6671 +}
6672 +
6673 +static int store_debug_level(struct file *file, const char *buffer,
6674 + unsigned long count, void *data)
6675 +{
6676 + char buf[] = "0x00000000";
6677 + unsigned long len = min(sizeof(buf) - 1, (u32)count);
6678 + char *p = (char *)buf;
6679 + unsigned long val;
6680 +
6681 + if (copy_from_user(buf, buffer, len))
6682 + return count;
6683 + buf[len] = 0;
6684 + if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
6685 + p++;
6686 + if (p[0] == 'x' || p[0] == 'X')
6687 + p++;
6688 + val = simple_strtoul(p, &p, 16);
6689 + } else
6690 + val = simple_strtoul(p, &p, 10);
6691 + if (p == buf)
6692 + printk(KERN_INFO DRV_NAME
6693 + ": %s is not in hex or decimal form.\n", buf);
6694 + else
6695 + ieee80211_debug_level = val;
6696 +
6697 + return strnlen(buf, count);
6698 +}
6699 +
6700 +static int __init ieee80211_init(void)
6701 +{
6702 + struct proc_dir_entry *e;
6703 +
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");
6709 + return -EIO;
6710 + }
6711 + e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
6712 + ieee80211_proc);
6713 + if (!e) {
6714 + remove_proc_entry(DRV_NAME, proc_net);
6715 + ieee80211_proc = NULL;
6716 + return -EIO;
6717 + }
6718 + e->read_proc = show_debug_level;
6719 + e->write_proc = store_debug_level;
6720 + e->data = NULL;
6721 +
6722 + return 0;
6723 +}
6724 +
6725 +static void __exit ieee80211_exit(void)
6726 +{
6727 + if (ieee80211_proc) {
6728 + remove_proc_entry("debug_level", ieee80211_proc);
6729 + remove_proc_entry(DRV_NAME, proc_net);
6730 + ieee80211_proc = NULL;
6731 + }
6732 +}
6733 +
6734 +#include <linux/moduleparam.h>
6735 +module_param(debug, int, 0444);
6736 +MODULE_PARM_DESC(debug, "debug output mask");
6737 +
6738 +
6739 +module_exit(ieee80211_exit);
6740 +module_init(ieee80211_init);
6741 +#endif
6742 +
6743 +#if 0
6744 +EXPORT_SYMBOL(alloc_ieee80211);
6745 +EXPORT_SYMBOL(free_ieee80211);
6746 +#endif
6747 --- /dev/null
6748 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
6749 @@ -0,0 +1,1971 @@
6750 +/*
6751 + * Original code based Host AP (software wireless LAN access point) driver
6752 + * for Intersil Prism2/2.5/3 - hostap.o module, common routines
6753 + *
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
6758 + *
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
6762 + * more details.
6763 + ******************************************************************************
6764 +
6765 + Few modifications for Realtek's Wi-Fi drivers by
6766 + Andrea Merello <andreamrl@tiscali.it>
6767 +
6768 + A special thanks goes to Realtek for their support !
6769 +
6770 +******************************************************************************/
6771 +
6772 +
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>
6794 +
6795 +#include "ieee80211.h"
6796 +#ifdef ENABLE_DOT11D
6797 +#include "dot11d.h"
6798 +#endif
6799 +static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
6800 + struct sk_buff *skb,
6801 + struct ieee80211_rx_stats *rx_stats)
6802 +{
6803 + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
6804 + u16 fc = le16_to_cpu(hdr->frame_ctl);
6805 +
6806 + skb->dev = ieee->dev;
6807 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
6808 + skb_reset_mac_header(skb);
6809 +#else
6810 + skb->mac.raw = skb->data;
6811 +#endif
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));
6816 + netif_rx(skb);
6817 +}
6818 +
6819 +
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)
6824 +{
6825 + struct ieee80211_frag_entry *entry;
6826 + int i;
6827 +
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;
6838 + }
6839 +
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)
6844 + return entry;
6845 + }
6846 +
6847 + return NULL;
6848 +}
6849 +
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)
6854 +{
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;
6863 + u8 tid;
6864 +
6865 +#ifdef _RTL8187_EXT_PATCH_
6866 + if(ieee->iw_mode == ieee->iw_ext_mode)
6867 + {
6868 + tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
6869 + }
6870 + else
6871 +#endif
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;
6875 + tid = UP2AC(tid);
6876 + 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;
6880 + tid = UP2AC(tid);
6881 + tid ++;
6882 + } else {
6883 + tid = 0;
6884 + }
6885 +
6886 + if (frag == 0) {
6887 + /* Reserve enough space to fit maximum frame length */
6888 + skb = dev_alloc_skb(ieee->dev->mtu +
6889 + sizeof(struct ieee80211_hdr) +
6890 + 8 /* LLC */ +
6891 + 2 /* alignment */ +
6892 + 8 /* WEP */ +
6893 + ETH_ALEN /* WDS */ +
6894 + (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */);
6895 + if (skb == NULL)
6896 + return NULL;
6897 +
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;
6902 +
6903 + if (entry->skb != NULL)
6904 + dev_kfree_skb_any(entry->skb);
6905 +
6906 + entry->first_frag_time = jiffies;
6907 + entry->seq = seq;
6908 + entry->last_frag = frag;
6909 + entry->skb = skb;
6910 + memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
6911 + memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
6912 + } else {
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,
6916 + hdr->addr1);
6917 + if (entry != NULL) {
6918 + entry->last_frag = frag;
6919 + skb = entry->skb;
6920 + }
6921 + }
6922 +
6923 + return skb;
6924 +}
6925 +
6926 +
6927 +/* Called only as a tasklet (software IRQ) */
6928 +static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
6929 + struct ieee80211_hdr *hdr)
6930 +{
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;
6937 + u8 tid;
6938 +
6939 +#ifdef _RTL8187_EXT_PATCH_
6940 + if(ieee->iw_mode == ieee->iw_ext_mode)
6941 + {
6942 + tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
6943 + }
6944 + else
6945 +#endif
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;
6949 + tid = UP2AC(tid);
6950 + 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;
6954 + tid = UP2AC(tid);
6955 + tid ++;
6956 + } else {
6957 + tid = 0;
6958 + }
6959 +
6960 + entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->addr2,
6961 + hdr->addr1);
6962 +
6963 + if (entry == NULL) {
6964 + IEEE80211_DEBUG_FRAG(
6965 + "could not invalidate fragment cache "
6966 + "entry (seq=%u)\n", seq);
6967 + return -1;
6968 + }
6969 +
6970 + entry->skb = NULL;
6971 + return 0;
6972 +}
6973 +
6974 +
6975 +
6976 +/* ieee80211_rx_frame_mgtmt
6977 + *
6978 + * Responsible for handling management control frames
6979 + *
6980 + * Called by ieee80211_rx */
6981 +static inline int
6982 +ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
6983 + struct ieee80211_rx_stats *rx_stats, u16 type,
6984 + u16 stype)
6985 +{
6986 + struct ieee80211_hdr *hdr;
6987 +
6988 + // cheat the the hdr type
6989 + hdr = (struct ieee80211_hdr *)skb->data;
6990 +
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
6994 + */
6995 + rx_stats->len = skb->len;
6996 + ieee80211_rx_mgt(ieee,(struct ieee80211_hdr *)skb->data,rx_stats);
6997 +
6998 + if((ieee->state == IEEE80211_LINKED)&&(memcmp(hdr->addr3,ieee->current_network.bssid,ETH_ALEN))) {
6999 + dev_kfree_skb_any(skb);
7000 + return 0;
7001 + }
7002 +
7003 + ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
7004 +
7005 + dev_kfree_skb_any(skb);
7006 +
7007 + return 0;
7008 +
7009 + #ifdef NOT_YET
7010 + if (ieee->iw_mode == IW_MODE_MASTER) {
7011 + printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
7012 + ieee->dev->name);
7013 + return 0;
7014 +/*
7015 + hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)
7016 + skb->data);*/
7017 + }
7018 +
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);
7026 + if (skb2)
7027 + hostap_rx(skb2->dev, skb2, rx_stats);
7028 + }
7029 +
7030 + /* send management frames to the user space daemon for
7031 + * processing */
7032 + ieee->apdevstats.rx_packets++;
7033 + ieee->apdevstats.rx_bytes += skb->len;
7034 + prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
7035 + return 0;
7036 + }
7037 +
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);
7043 + return -1;
7044 + }
7045 +
7046 + hostap_rx(skb->dev, skb, rx_stats);
7047 + return 0;
7048 + }
7049 +
7050 + printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
7051 + "received in non-Host AP mode\n", skb->dev->name);
7052 + return -1;
7053 + #endif
7054 +}
7055 +
7056 +
7057 +
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) */
7066 +
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)
7070 +{
7071 + struct net_device *dev = ieee->dev;
7072 + u16 fc, ethertype;
7073 + struct ieee80211_hdr *hdr;
7074 + u8 *pos;
7075 +
7076 + if (skb->len < 24)
7077 + return 0;
7078 +
7079 + hdr = (struct ieee80211_hdr *) skb->data;
7080 + fc = le16_to_cpu(hdr->frame_ctl);
7081 +
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 */
7092 + } else
7093 + return 0;
7094 +
7095 + if (skb->len < 24 + 8)
7096 + return 0;
7097 +
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)
7103 + return 1;
7104 +
7105 + return 0;
7106 +}
7107 +
7108 +/* Called only as a tasklet (software IRQ), by ieee80211_rx */
7109 +static inline int
7110 +ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
7111 + struct ieee80211_crypt_data *crypt)
7112 +{
7113 + struct ieee80211_hdr *hdr;
7114 + int res, hdrlen;
7115 +
7116 + if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
7117 + return 0;
7118 +
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))
7122 + {
7123 + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
7124 + }
7125 + else
7126 +#endif
7127 + hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
7128 +
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));
7136 + }
7137 + return -1;
7138 + }
7139 +#endif
7140 +
7141 + atomic_inc(&crypt->refcnt);
7142 + res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
7143 + atomic_dec(&crypt->refcnt);
7144 + if (res < 0) {
7145 + IEEE80211_DEBUG_DROP(
7146 + "decryption failed (SA=" MAC_FMT
7147 + ") res=%d\n", MAC_ARG(hdr->addr2), res);
7148 + if (res == -2)
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++;
7153 + return -1;
7154 + }
7155 +
7156 + return res;
7157 +}
7158 +
7159 +
7160 +/* Called only as a tasklet (software IRQ), by ieee80211_rx */
7161 +static inline int
7162 +ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,
7163 + int keyidx, struct ieee80211_crypt_data *crypt)
7164 +{
7165 + struct ieee80211_hdr *hdr;
7166 + int res, hdrlen;
7167 +
7168 + if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
7169 + return 0;
7170 +
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))
7174 + {
7175 + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
7176 + }
7177 + else
7178 +#endif
7179 + hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
7180 +
7181 + atomic_inc(&crypt->refcnt);
7182 + res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
7183 + atomic_dec(&crypt->refcnt);
7184 + if (res < 0) {
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);
7188 + return -1;
7189 + }
7190 +
7191 + return 0;
7192 +}
7193 +
7194 +
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)
7199 +{
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;
7208 + u8 tid;
7209 +
7210 +#ifdef _RTL8187_EXT_PATCH_
7211 + if(ieee->iw_mode == ieee->iw_ext_mode)
7212 + {
7213 + tid = (header->addr2[ETH_ALEN-2] ^ header->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
7214 + }
7215 + else
7216 +#endif
7217 + //TO2DS and QoS
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;
7221 + tid = UP2AC(tid);
7222 + 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;
7226 + tid = UP2AC(tid);
7227 + tid ++;
7228 + } else { // no QoS
7229 + tid = 0;
7230 + }
7231 + switch (ieee->iw_mode) {
7232 + case IW_MODE_ADHOC:
7233 + {
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))
7242 + break;
7243 + }
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);
7247 + if (!entry) {
7248 + printk(KERN_WARNING "Cannot malloc new mac entry\n");
7249 + return 0;
7250 + }
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]);
7256 + return 0;
7257 + }
7258 + last_seq = &entry->seq_num[tid];
7259 + last_frag = &entry->frag_num[tid];
7260 + last_time = &entry->packet_time[tid];
7261 + break;
7262 + }
7263 +
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];
7268 +
7269 + break;
7270 + default:
7271 +#ifdef _RTL8187_EXT_PATCH_
7272 + if(ieee->iw_mode == ieee->iw_ext_mode)
7273 + {
7274 + last_seq = &ieee->last_rxseq_num[tid];
7275 + last_frag = &ieee->last_rxfrag_num[tid];
7276 + last_time = &ieee->last_packet_time[tid];
7277 + break;
7278 + }
7279 + else
7280 +#endif
7281 + return 0;
7282 + }
7283 +
7284 +// if(tid != 0) {
7285 +// printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl);
7286 +// }
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");
7291 + goto drop;
7292 +
7293 + }
7294 + if (*last_frag + 1 != frag)
7295 + /* out-of-order fragment */
7296 + //printk(KERN_WARNING "[2] go drop!\n");
7297 + goto drop;
7298 + } else
7299 + *last_seq = seq;
7300 +
7301 + *last_frag = frag;
7302 + *last_time = jiffies;
7303 + return 0;
7304 +
7305 +drop:
7306 +// BUG_ON(!(fc & IEEE80211_FCTL_RETRY));
7307 +// printk("DUP\n");
7308 +
7309 + return 1;
7310 +}
7311 +
7312 +
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)
7318 +{
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;
7323 +
7324 + size_t hdrlen;
7325 + u16 fc, type, stype, sc;
7326 + struct net_device_stats *stats;
7327 + unsigned int frag;
7328 + u8 *payload;
7329 + u16 ethertype;
7330 +#ifdef NOT_YET
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;
7336 + void *sta = NULL;
7337 +#endif
7338 +// u16 QOS_ctl = 0;
7339 + u8 dst[ETH_ALEN];
7340 + u8 src[ETH_ALEN];
7341 + u8 bssid[ETH_ALEN];
7342 + struct ieee80211_crypt_data *crypt = NULL;
7343 + int keyidx = 0;
7344 +
7345 + //Added for mesh by Lawrence.
7346 +#ifdef _RTL8187_EXT_PATCH_
7347 + u8 status;
7348 + u32 flags;
7349 +#endif
7350 + // cheat the the hdr type
7351 + hdr = (struct ieee80211_hdr *)skb->data;
7352 + stats = &ieee->stats;
7353 +
7354 + if (skb->len < 10) {
7355 + printk(KERN_INFO "%s: SKB length < 10\n",
7356 + dev->name);
7357 + goto rx_dropped;
7358 + }
7359 +
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);
7364 +
7365 + frag = WLAN_GET_SEQ_FRAG(sc);
7366 +
7367 +//YJ,add,080828,for keep alive
7368 + if((fc & IEEE80211_FCTL_TODS) != IEEE80211_FCTL_TODS)
7369 + {
7370 + if(!memcmp(hdr->addr1,dev->dev_addr, ETH_ALEN))
7371 + {
7372 + ieee->NumRxUnicast++;
7373 + }
7374 + }
7375 + else
7376 + {
7377 + if(!memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN))
7378 + {
7379 + ieee->NumRxUnicast++;
7380 + }
7381 + }
7382 +//YJ,add,080828,for keep alive,end
7383 +
7384 +#ifdef _RTL8187_EXT_PATCH_
7385 + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
7386 + {
7387 + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
7388 + if(skb->len < hdrlen)
7389 + goto rx_dropped;
7390 + }
7391 + else
7392 +#endif
7393 + hdrlen = ieee80211_get_hdrlen(fc);
7394 +
7395 +#ifdef NOT_YET
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);
7408 + }
7409 +#endif /* IW_WIRELESS_SPY */
7410 +#endif /* WIRELESS_EXT > 15 */
7411 + hostap_update_rx_stats(local->ap, hdr, rx_stats);
7412 +#endif
7413 +
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;
7419 + return 1;
7420 + }
7421 +#endif
7422 + if (ieee->host_decrypt) {
7423 + int idx = 0;
7424 + if (skb->len >= hdrlen + 3)
7425 + idx = skb->data[hdrlen + 3] >> 6;
7426 + crypt = ieee->crypt[idx];
7427 +#ifdef NOT_YET
7428 + sta = NULL;
7429 +
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). */
7436 +
7437 + if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
7438 + (void) hostap_handle_sta_crypto(local, hdr, &crypt,
7439 + &sta);
7440 +#endif
7441 +
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))
7446 + crypt = NULL;
7447 +
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++;
7457 + goto rx_dropped;
7458 + }
7459 + }
7460 +
7461 + if (skb->len < IEEE80211_DATA_HDR3_LEN)
7462 + goto rx_dropped;
7463 +
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 );
7467 +#endif
7468 +
7469 + // if QoS enabled, should check the sequence for each of the AC
7470 + if (is_duplicate_packet(ieee, hdr))
7471 + goto rx_dropped;
7472 +
7473 +
7474 + if (type == IEEE80211_FTYPE_MGMT) {
7475 +
7476 + #if 0
7477 + if ( stype == IEEE80211_STYPE_AUTH &&
7478 + fc & IEEE80211_FCTL_WEP && ieee->host_decrypt &&
7479 + (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0)
7480 + {
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 */
7486 + goto rx_dropped;
7487 + }
7488 + #endif
7489 +
7490 +
7491 + if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
7492 + goto rx_dropped;
7493 + else
7494 + goto rx_exit;
7495 + }
7496 +#ifdef _RTL8187_EXT_PATCH_
7497 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_on_rx)
7498 + {
7499 + if(ieee->ext_patch_ieee80211_rx_on_rx(ieee, skb, rx_stats, type, stype)==0)
7500 + {
7501 + goto rx_exit;
7502 + }
7503 + }
7504 +#endif
7505 +
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);
7512 + break;
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);
7517 + break;
7518 + case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
7519 + if (skb->len < IEEE80211_DATA_HDR4_LEN)
7520 + goto rx_dropped;
7521 + memcpy(dst, hdr->addr3, ETH_ALEN);
7522 + memcpy(src, hdr->addr4, ETH_ALEN);
7523 + memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
7524 + break;
7525 + case 0:
7526 + memcpy(dst, hdr->addr1, ETH_ALEN);
7527 + memcpy(src, hdr->addr2, ETH_ALEN);
7528 + memcpy(bssid,hdr->addr3,ETH_ALEN);
7529 + break;
7530 + }
7531 +
7532 +#ifdef NOT_YET
7533 + if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
7534 + goto rx_dropped;
7535 + if (wds) {
7536 + skb->dev = dev = wds;
7537 + stats = hostap_get_stats(dev);
7538 + }
7539 +
7540 + if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
7541 + (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
7542 + ieee->stadev &&
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;
7548 + }
7549 +#endif
7550 +
7551 + dev->last_rx = jiffies;
7552 +
7553 +#ifdef NOT_YET
7554 + if ((ieee->iw_mode == IW_MODE_MASTER ||
7555 + ieee->iw_mode == IW_MODE_REPEAT) &&
7556 + !from_assoc_ap) {
7557 + switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
7558 + wds != NULL)) {
7559 + case AP_RX_CONTINUE_NOT_AUTHORIZED:
7560 + frame_authorized = 0;
7561 + break;
7562 + case AP_RX_CONTINUE:
7563 + frame_authorized = 1;
7564 + break;
7565 + case AP_RX_DROP:
7566 + goto rx_dropped;
7567 + case AP_RX_EXIT:
7568 + goto rx_exit;
7569 + }
7570 + }
7571 +#endif
7572 +
7573 +#ifdef _RTL8187_EXT_PATCH_
7574 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_is_valid_framectl)
7575 + {
7576 + if(ieee->ext_patch_ieee80211_rx_is_valid_framectl(ieee, fc, type, stype)==0)
7577 + goto rx_dropped;
7578 + }
7579 + else
7580 +#endif
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
7588 + ) {
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);
7595 + goto rx_dropped;
7596 + }
7597 + if(memcmp(bssid,ieee->current_network.bssid,ETH_ALEN)) {
7598 + goto rx_dropped;
7599 + }
7600 +
7601 + ieee->NumRxDataInPeriod++;
7602 + ieee->NumRxOkTotal++;
7603 + /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
7604 +
7605 + if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
7606 + (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
7607 + goto rx_dropped;
7608 +
7609 + hdr = (struct ieee80211_hdr *) skb->data;
7610 +
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))) {
7615 + int flen;
7616 + struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
7617 + IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
7618 +
7619 + if (!frag_skb) {
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);
7625 + goto rx_dropped;
7626 + }
7627 + flen = skb->len;
7628 + if (frag != 0)
7629 + flen -= hdrlen;
7630 +
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",
7634 + dev->name);
7635 + ieee80211_frag_cache_invalidate(ieee, hdr);
7636 + goto rx_dropped;
7637 + }
7638 +
7639 + if (frag == 0) {
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);
7643 + } else {
7644 + /* append frame payload to the end of the fragment
7645 + * cache skb */
7646 + memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
7647 + flen);
7648 + }
7649 + dev_kfree_skb_any(skb);
7650 + skb = NULL;
7651 +
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 */
7656 + goto rx_exit;
7657 + }
7658 +
7659 + /* this was the last fragment and the frame will be
7660 + * delivered, so remove skb from fragment cache */
7661 + skb = frag_skb;
7662 + hdr = (struct ieee80211_hdr *) skb->data;
7663 + ieee80211_frag_cache_invalidate(ieee, hdr);
7664 + }
7665 +
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))
7670 + goto rx_dropped;
7671 +
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)) {
7676 +
7677 +#ifdef CONFIG_IEEE80211_DEBUG
7678 + /* pass unencrypted EAPOL frames even if encryption is
7679 + * configured */
7680 + struct eapol *eap = (struct eapol *)(skb->data +
7681 + 24);
7682 + IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
7683 + eap_get_type(eap->type));
7684 +#endif
7685 + } else {
7686 + IEEE80211_DEBUG_DROP(
7687 + "encryption configured, but RX "
7688 + "frame not encrypted (SA=" MAC_FMT ")\n",
7689 + MAC_ARG(hdr->addr2));
7690 + goto rx_dropped;
7691 + }
7692 + }
7693 +
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 +
7698 + 24);
7699 + IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
7700 + eap_get_type(eap->type));
7701 + }
7702 +#endif
7703 +
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));
7711 + goto rx_dropped;
7712 + }
7713 +/*
7714 + if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
7715 + printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n");
7716 + }
7717 +*/
7718 + /* skb: hdr + (possible reassembled) full plaintext payload */
7719 + payload = skb->data + hdrlen;
7720 + ethertype = (payload[6] << 8) | payload[7];
7721 +
7722 +#ifdef NOT_YET
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",
7728 + dev->name);
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,
7733 + PRISM2_RX_MGMT);
7734 + ieee->apdevstats.rx_packets++;
7735 + ieee->apdevstats.rx_bytes += skb->len;
7736 + goto rx_exit;
7737 + }
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);
7743 + goto rx_dropped;
7744 + }
7745 + }
7746 +#endif
7747 +
7748 +#ifdef _RTL8187_EXT_PATCH_
7749 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_process_dataframe)
7750 + {
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);
7755 +
7756 + if(status)
7757 +// if(ieee->ext_patch_ieee80211_rx_process_dataframe(ieee, skb, rx_stats))
7758 + goto rx_exit;
7759 + else
7760 + goto rx_dropped;
7761 + }
7762 +#endif
7763 +
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);
7774 + } else {
7775 + u16 len;
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);
7782 + }
7783 +
7784 +#ifdef NOT_YET
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
7789 + * the payload */
7790 + memcpy(skb->data + ETH_ALEN,
7791 + skb->data + skb->len - ETH_ALEN, ETH_ALEN);
7792 + skb_trim(skb, skb->len - ETH_ALEN);
7793 + }
7794 +#endif
7795 +
7796 + stats->rx_packets++;
7797 + stats->rx_bytes += skb->len;
7798 +
7799 +#ifdef NOT_YET
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);
7807 + if (skb2 == NULL)
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++;
7814 + skb2 = skb;
7815 + skb = NULL;
7816 + }
7817 + }
7818 +
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; */
7824 + skb2->dev = dev;
7825 + dev_queue_xmit(skb2);
7826 + }
7827 +
7828 +#endif
7829 + if (skb) {
7830 + skb->protocol = eth_type_trans(skb, dev);
7831 + memset(skb->cb, 0, sizeof(skb->cb));
7832 + skb->dev = dev;
7833 + skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
7834 + ieee->last_rx_ps_time = jiffies;
7835 + netif_rx(skb);
7836 + }
7837 +
7838 + rx_exit:
7839 +#ifdef NOT_YET
7840 + if (sta)
7841 + hostap_handle_sta_release(sta);
7842 +#endif
7843 + return 1;
7844 +
7845 + rx_dropped:
7846 + stats->rx_dropped++;
7847 +
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 */
7851 + return 0;
7852 +}
7853 +
7854 +#ifdef _RTL8187_EXT_PATCH_
7855 +int ieee_ext_skb_p80211_to_ether(struct sk_buff *skb, int hdrlen, u8 *dst, u8 *src)
7856 +{
7857 + u8 *payload;
7858 + u16 ethertype;
7859 +
7860 + /* skb: hdr + (possible reassembled) full plaintext payload */
7861 + payload = skb->data + hdrlen;
7862 + ethertype = (payload[6] << 8) | payload[7];
7863 +
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);
7874 + } else {
7875 + u16 len;
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);
7882 + }
7883 +
7884 + return 1;
7885 +}
7886 +#endif // _RTL8187_EXT_PATCH_
7887 +
7888 +
7889 +#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
7890 +
7891 +static inline int ieee80211_is_ofdm_rate(u8 rate)
7892 +{
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:
7902 + return 1;
7903 + }
7904 + return 0;
7905 +}
7906 +
7907 +static inline int ieee80211_SignalStrengthTranslate(
7908 + int CurrSS
7909 + )
7910 +{
7911 + int RetSS;
7912 +
7913 + // Step 1. Scale mapping.
7914 + if(CurrSS >= 71 && CurrSS <= 100)
7915 + {
7916 + RetSS = 90 + ((CurrSS - 70) / 3);
7917 + }
7918 + else if(CurrSS >= 41 && CurrSS <= 70)
7919 + {
7920 + RetSS = 78 + ((CurrSS - 40) / 3);
7921 + }
7922 + else if(CurrSS >= 31 && CurrSS <= 40)
7923 + {
7924 + RetSS = 66 + (CurrSS - 30);
7925 + }
7926 + else if(CurrSS >= 21 && CurrSS <= 30)
7927 + {
7928 + RetSS = 54 + (CurrSS - 20);
7929 + }
7930 + else if(CurrSS >= 5 && CurrSS <= 20)
7931 + {
7932 + RetSS = 42 + (((CurrSS - 5) * 2) / 3);
7933 + }
7934 + else if(CurrSS == 4)
7935 + {
7936 + RetSS = 36;
7937 + }
7938 + else if(CurrSS == 3)
7939 + {
7940 + RetSS = 27;
7941 + }
7942 + else if(CurrSS == 2)
7943 + {
7944 + RetSS = 18;
7945 + }
7946 + else if(CurrSS == 1)
7947 + {
7948 + RetSS = 9;
7949 + }
7950 + else
7951 + {
7952 + RetSS = CurrSS;
7953 + }
7954 + //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
7955 +
7956 + // Step 2. Smoothing.
7957 +
7958 + //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
7959 +
7960 + return RetSS;
7961 +}
7962 +
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,
7968 + u8 * addr2
7969 +)
7970 +{
7971 +#if 0
7972 + u32 i = 0;
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");
7979 +#endif
7980 + if(IS_DOT11D_ENABLE(ieee))
7981 + {
7982 + if(info_element->len!= 0)
7983 + {
7984 + memcpy(network->CountryIeBuf, info_element->data, info_element->len);
7985 + network->CountryIeLen = info_element->len;
7986 +
7987 + if(!IS_COUNTRY_IE_VALID(ieee))
7988 + {
7989 + Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
7990 + }
7991 + }
7992 +
7993 + //
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.
7997 + //
7998 + if(IS_EQUAL_CIE_SRC(ieee, addr2) )
7999 + {
8000 + UPDATE_CIE_WATCHDOG(ieee);
8001 + }
8002 + }
8003 +
8004 +}
8005 +#endif
8006 +
8007 +int
8008 +ieee80211_TranslateToDbm(
8009 + unsigned char SignalStrengthIndex // 0-100 index.
8010 + )
8011 +{
8012 + unsigned char SignalPower; // in dBm.
8013 +
8014 + // Translate to dBm (x=0.5y-95).
8015 + SignalPower = (int)SignalStrengthIndex * 7 / 10;
8016 + SignalPower -= 95;
8017 +
8018 + return SignalPower;
8019 +}
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)
8025 +{
8026 +#ifdef CONFIG_IEEE80211_DEBUG
8027 + char rates_str[64];
8028 + char *p;
8029 +#endif
8030 + struct ieee80211_info_element *info_element;
8031 + u16 left;
8032 + u8 i;
8033 + short offset;
8034 + u8 curRate = 0,hOpRate = 0,curRate_ex = 0;
8035 +
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;
8051 +//by amy 080312
8052 + network->HighestOperaRate = 0;
8053 +//by amy 080312
8054 +#ifdef THOMAS_TURBO
8055 + network->Turbo_Enable = 0;
8056 +#endif
8057 +#ifdef ENABLE_DOT11D
8058 + network->CountryIeLen = 0;
8059 + memset(network->CountryIeBuf, 0, MAX_IE_LEN);
8060 +#endif
8061 +
8062 + if (stats->freq == IEEE80211_52GHZ_BAND) {
8063 + /* for A band (No DS info) */
8064 + network->channel = stats->received_channel;
8065 + } else
8066 + network->flags |= NETWORK_HAS_CCK;
8067 +
8068 + network->wpa_ie_len = 0;
8069 + network->rsn_ie_len = 0;
8070 +
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),
8077 + left);
8078 + return 1;
8079 + }
8080 +
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;
8086 + break;
8087 + }
8088 +
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);
8095 +
8096 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
8097 + network->ssid, network->ssid_len);
8098 + break;
8099 +
8100 + case MFIE_TYPE_RATES:
8101 +#ifdef CONFIG_IEEE80211_DEBUG
8102 + p = rates_str;
8103 +#endif
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]);
8112 +#endif
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)
8117 + network->flags &=
8118 + ~NETWORK_HAS_CCK;
8119 + }
8120 + }
8121 +
8122 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
8123 + rates_str, network->rates_len);
8124 + break;
8125 +
8126 + case MFIE_TYPE_RATES_EX:
8127 +#ifdef CONFIG_IEEE80211_DEBUG
8128 + p = rates_str;
8129 +#endif
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]);
8138 +#endif
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)
8143 + network->flags &=
8144 + ~NETWORK_HAS_CCK;
8145 + }
8146 + }
8147 +
8148 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
8149 + rates_str, network->rates_ex_len);
8150 + break;
8151 +
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];
8157 + break;
8158 +
8159 + case MFIE_TYPE_FH_SET:
8160 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
8161 + break;
8162 +
8163 + case MFIE_TYPE_CF_SET:
8164 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
8165 + break;
8166 +
8167 + case MFIE_TYPE_TIM:
8168 +
8169 + if(info_element->len < 4)
8170 + break;
8171 +
8172 + network->dtim_period = info_element->data[1];
8173 +
8174 + if(ieee->state != IEEE80211_LINKED)
8175 + break;
8176 +#if 0
8177 + network->last_dtim_sta_time[0] = stats->mac_time[0];
8178 +#else
8179 + network->last_dtim_sta_time[0] = jiffies;
8180 +#endif
8181 + network->last_dtim_sta_time[1] = stats->mac_time[1];
8182 +
8183 + network->dtim_data = IEEE80211_DTIM_VALID;
8184 +
8185 + if(info_element->data[0] != 0)
8186 + break;
8187 +
8188 + if(info_element->data[2] & 1)
8189 + network->dtim_data |= IEEE80211_DTIM_MBCAST;
8190 +
8191 + offset = (info_element->data[2] >> 1)*2;
8192 +
8193 + //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id);
8194 +
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)) {
8198 + break;
8199 + }
8200 +
8201 + offset = (ieee->assoc_id/8) - offset;// + ((aid % 8)? 0 : 1) ;
8202 +
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)));
8206 +
8207 + if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8))) {
8208 + network->dtim_data |= IEEE80211_DTIM_UCAST;
8209 + }
8210 + break;
8211 +
8212 + case MFIE_TYPE_IBSS_SET:
8213 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
8214 + break;
8215 +
8216 + case MFIE_TYPE_CHALLENGE:
8217 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
8218 + break;
8219 +
8220 + case MFIE_TYPE_GENERIC:
8221 + //nic is 87B
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,
8230 + MAX_WPA_IE_LEN);
8231 + memcpy(network->wpa_ie, info_element,
8232 + network->wpa_ie_len);
8233 + }
8234 +
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;
8243 + }
8244 +#endif
8245 + if (1 == stats->nic_type) {//nic 87
8246 + break;
8247 + }
8248 +
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;
8259 + }
8260 +
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&param 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;
8274 + }
8275 + break;
8276 +
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,
8281 + MAX_WPA_IE_LEN);
8282 + memcpy(network->rsn_ie, info_element,
8283 + network->rsn_ie_len);
8284 + break;
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);
8291 + break;
8292 +#endif
8293 + default:
8294 + IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
8295 + info_element->id);
8296 + break;
8297 + }
8298 +
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];
8303 + }
8304 +//by amy 080312
8305 + network->HighestOperaRate = hOpRate;
8306 +//by amy 080312
8307 + network->mode = 0;
8308 + if (stats->freq == IEEE80211_52GHZ_BAND)
8309 + network->mode = IEEE_A;
8310 + else {
8311 + if (network->flags & NETWORK_HAS_OFDM)
8312 + network->mode |= IEEE_G;
8313 + if (network->flags & NETWORK_HAS_CCK)
8314 + network->mode |= IEEE_B;
8315 + }
8316 +
8317 + if (network->mode == 0) {
8318 + IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
8319 + "network.\n",
8320 + escape_essid(network->ssid,
8321 + network->ssid_len),
8322 + MAC_ARG(network->bssid));
8323 + return 1;
8324 + }
8325 +
8326 + if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
8327 + network->flags |= NETWORK_EMPTY_ESSID;
8328 +#if 0
8329 + stats->signal = ieee80211_SignalStrengthTranslate(stats->signal);
8330 +#endif
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));
8335 +
8336 + return 0;
8337 +}
8338 +
8339 +static inline int is_same_network(struct ieee80211_network *src,
8340 + struct ieee80211_network *dst,
8341 + struct ieee80211_device * ieee)
8342 +{
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)));
8357 +}
8358 +
8359 +inline void update_network(struct ieee80211_network *dst,
8360 + struct ieee80211_network *src)
8361 +{
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;
8367 + }
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;
8379 +
8380 +
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);
8388 +
8389 + //YJ,add,080819,for hidden ap
8390 + if(src->ssid_len > 0)
8391 + {
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);
8397 + }
8398 + //YJ,add,080819,for hidden ap,end
8399 +
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];
8405 +
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;
8418 +
8419 + dst->last_scanned = jiffies;
8420 + /* dst->last_associate is not overwritten */
8421 +// disable QoS process now, added by David 2006/7/25
8422 +#if 1
8423 + dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
8424 +/*
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);
8427 + }
8428 +*/
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);
8434 + }
8435 + dst->QoS_Enable = src->QoS_Enable;
8436 +#else
8437 + dst->QoS_Enable = 1;//for Rtl8187 simulation
8438 +#endif
8439 + dst->SignalStrength = src->SignalStrength;
8440 +#ifdef THOMAS_TURBO
8441 + dst->Turbo_Enable = src->Turbo_Enable;
8442 +#endif
8443 +#ifdef ENABLE_DOT11D
8444 + dst->CountryIeLen = src->CountryIeLen;
8445 + memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
8446 +#endif
8447 +}
8448 +
8449 +
8450 +inline void ieee80211_process_probe_response(
8451 + struct ieee80211_device *ieee,
8452 + struct ieee80211_probe_response *beacon,
8453 + struct ieee80211_rx_stats *stats)
8454 +{
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;
8460 +#endif
8461 + unsigned long flags;
8462 + short renew;
8463 + u8 wmm_info;
8464 + u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON)? 1:0; //YJ,add,080819,for hidden ap
8465 +
8466 + memset(&network, 0, sizeof(struct ieee80211_network));
8467 +//rz
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);
8471 + return;
8472 + }
8473 +#endif
8474 +
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');
8495 +#if 0
8496 + if(strcmp(escape_essid(beacon->info_element.data, beacon->info_element.len), "rtl_softap") == 0)
8497 + {
8498 + if(WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON)
8499 + {
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");
8507 + }
8508 + }
8509 +#endif
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");
8518 + return;
8519 + }
8520 +
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)
8529 + {
8530 + if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
8531 + {
8532 + // Case 1: Country code
8533 + if(IS_COUNTRY_IE_VALID(ieee) )
8534 + {
8535 + if( !IsLegalChannel(ieee, network.channel) )
8536 + {
8537 + printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
8538 + return;
8539 + }
8540 + }
8541 + // Case 2: No any country code.
8542 + else
8543 + {
8544 + // Filter over channel ch12~14
8545 + if(network.channel > 11)
8546 + {
8547 + printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
8548 + return;
8549 + }
8550 + }
8551 + }
8552 + else
8553 + {
8554 + // Case 1: Country code
8555 + if(IS_COUNTRY_IE_VALID(ieee) )
8556 + {
8557 + if( !IsLegalChannel(ieee, network.channel) )
8558 + {
8559 + printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel);
8560 + return;
8561 + }
8562 + }
8563 + // Case 2: No any country code.
8564 + else
8565 + {
8566 + // Filter over channel ch12~14
8567 + if(network.channel > 14)
8568 + {
8569 + printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel);
8570 + return;
8571 + }
8572 + }
8573 + }
8574 + }
8575 +#endif
8576 + /* The network parsed correctly -- so now we scan our known networks
8577 + * to see if we can find it in our list.
8578 + *
8579 + * NOTE: This search is definitely not optimized. Once its doing
8580 + * the "right thing" we'll optimize it for efficiency if
8581 + * necessary */
8582 +
8583 + /* Search for this entry in the list and update it if it is
8584 + * already there. */
8585 +
8586 + spin_lock_irqsave(&ieee->lock, flags);
8587 +
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);
8598 + }
8599 +
8600 + list_for_each_entry(target, &ieee->network_list, list) {
8601 + if (is_same_network(target, &network, ieee))
8602 + break;
8603 + if ((oldest == NULL) ||
8604 + (target->last_scanned < oldest->last_scanned))
8605 + oldest = target;
8606 + }
8607 +
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);
8614 + target = oldest;
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));
8620 + } else {
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);
8625 + }
8626 +
8627 +
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");
8636 +#endif
8637 +
8638 +#ifdef _RTL8187_EXT_PATCH_
8639 + network.ext_entry = target->ext_entry;
8640 +#endif
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);
8645 + } else {
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");
8653 +
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
8657 + */
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))))
8667 + renew = 1;
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);
8672 + }
8673 +
8674 + spin_unlock_irqrestore(&ieee->lock, flags);
8675 +}
8676 +
8677 +void ieee80211_rx_mgt(struct ieee80211_device *ieee,
8678 + struct ieee80211_hdr *header,
8679 + struct ieee80211_rx_stats *stats)
8680 +{
8681 + switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
8682 +
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);
8689 + break;
8690 +
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);
8697 + break;
8698 +//rz
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");
8704 + ///
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);
8707 + break;
8708 +#endif // _RTL8187_EXT_PATCH_
8709 +
8710 + }
8711 +}
8712 +
8713 +#if 0
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);
8719 +#endif
8720 +#endif
8721 --- /dev/null
8722 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
8723 @@ -0,0 +1,4029 @@
8724 +/* IEEE 802.11 SoftMAC layer
8725 + * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
8726 + *
8727 + * Mostly extracted from the rtl8180-sa2400 driver for the
8728 + * in-kernel generic ieee802.11 stack.
8729 + *
8730 + * Few lines might be stolen from other part of the ieee80211
8731 + * stack. Copyright who own it's copyright
8732 + *
8733 + * WPA code stolen from the ipw2200 driver.
8734 + * Copyright who own it's copyright.
8735 + *
8736 + * released under the GPL
8737 + */
8738 +
8739 +
8740 +#include "ieee80211.h"
8741 +
8742 +#include <linux/random.h>
8743 +#include <linux/delay.h>
8744 +#include <linux/version.h>
8745 +#include <asm/uaccess.h>
8746 +
8747 +#ifdef ENABLE_DOT11D
8748 +#include "dot11d.h"
8749 +#endif
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
8757 +};
8758 +
8759 +short ieee80211_is_54g(struct ieee80211_network net)
8760 +{
8761 + return ((net.rates_ex_len > 0) || (net.rates_len > 4));
8762 +}
8763 +
8764 +short ieee80211_is_shortslot(struct ieee80211_network net)
8765 +{
8766 + return (net.capability & WLAN_CAPABILITY_SHORT_SLOT);
8767 +}
8768 +
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
8772 + */
8773 +unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
8774 +{
8775 + unsigned int rate_len = 0;
8776 +
8777 + if (ieee->modulation & IEEE80211_CCK_MODULATION)
8778 + rate_len = IEEE80211_CCK_RATE_LEN + 2;
8779 +
8780 + if (ieee->modulation & IEEE80211_OFDM_MODULATION)
8781 +
8782 + rate_len += IEEE80211_OFDM_RATE_LEN + 2;
8783 +
8784 + return rate_len;
8785 +}
8786 +
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.
8790 + */
8791 +void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
8792 +{
8793 + u8 *tag = *tag_p;
8794 +
8795 + if (ieee->modulation & IEEE80211_CCK_MODULATION){
8796 + *tag++ = MFIE_TYPE_RATES;
8797 + *tag++ = 4;
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;
8802 + }
8803 +
8804 + /* We may add an option for custom rates that specific HW might support */
8805 + *tag_p = tag;
8806 +}
8807 +
8808 +void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
8809 +{
8810 + u8 *tag = *tag_p;
8811 +
8812 + if (ieee->modulation & IEEE80211_OFDM_MODULATION){
8813 +
8814 + *tag++ = MFIE_TYPE_RATES_EX;
8815 + *tag++ = 8;
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;
8824 +
8825 + }
8826 +
8827 + /* We may add an option for custom rates that specific HW might support */
8828 + *tag_p = tag;
8829 +}
8830 +
8831 +
8832 +void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
8833 + u8 *tag = *tag_p;
8834 +
8835 + *tag++ = MFIE_TYPE_GENERIC; //0
8836 + *tag++ = 7;
8837 + *tag++ = 0x00;
8838 + *tag++ = 0x50;
8839 + *tag++ = 0xf2;
8840 + *tag++ = 0x02;//5
8841 + *tag++ = 0x00;
8842 + *tag++ = 0x01;
8843 +#ifdef SUPPORT_USPD
8844 + if(ieee->current_network.wmm_info & 0x80) {
8845 + *tag++ = 0x0f|MAX_SP_Len;
8846 + } else {
8847 + *tag++ = MAX_SP_Len;
8848 + }
8849 +#else
8850 + *tag++ = MAX_SP_Len;
8851 +#endif
8852 + *tag_p = tag;
8853 +}
8854 +
8855 +#ifdef THOMAS_TURBO
8856 +void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
8857 + u8 *tag = *tag_p;
8858 +
8859 + *tag++ = MFIE_TYPE_GENERIC; //0
8860 + *tag++ = 7;
8861 + *tag++ = 0x00;
8862 + *tag++ = 0xe0;
8863 + *tag++ = 0x4c;
8864 + *tag++ = 0x01;//5
8865 + *tag++ = 0x02;
8866 + *tag++ = 0x11;
8867 + *tag++ = 0x00;
8868 +
8869 + *tag_p = tag;
8870 + printk(KERN_ALERT "This is enable turbo mode IE process\n");
8871 +}
8872 +#endif
8873 +
8874 +void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
8875 +{
8876 + int nh;
8877 + nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
8878 +
8879 +/*
8880 + * if the queue is full but we have newer frames then
8881 + * just overwrites the oldest.
8882 + *
8883 + * if (nh == ieee->mgmt_queue_tail)
8884 + * return -1;
8885 + */
8886 + ieee->mgmt_queue_head = nh;
8887 + ieee->mgmt_queue_ring[nh] = skb;
8888 +
8889 + //return 0;
8890 +}
8891 +
8892 +struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
8893 +{
8894 + struct sk_buff *ret;
8895 +
8896 + if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
8897 + return NULL;
8898 +
8899 + ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
8900 +
8901 + ieee->mgmt_queue_tail =
8902 + (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
8903 +
8904 + return ret;
8905 +}
8906 +
8907 +void init_mgmt_queue(struct ieee80211_device *ieee)
8908 +{
8909 + ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
8910 +}
8911 +
8912 +
8913 +void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
8914 +
8915 +inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
8916 +{
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;
8921 +
8922 +
8923 + spin_lock_irqsave(&ieee->lock, flags);
8924 +
8925 + /* called with 2nd param 0, no mgmt lock required */
8926 + ieee80211_sta_wakeup(ieee,0);
8927 +
8928 + if(single){
8929 + if(ieee->queue_stop){
8930 +
8931 + enqueue_mgmt(ieee,skb);
8932 + }else{
8933 + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
8934 +
8935 + if (ieee->seq_ctrl[0] == 0xFFF)
8936 + ieee->seq_ctrl[0] = 0;
8937 + else
8938 + ieee->seq_ctrl[0]++;
8939 +
8940 + /* avoid watchdog triggers */
8941 + ieee->dev->trans_start = jiffies;
8942 + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
8943 + }
8944 +
8945 + spin_unlock_irqrestore(&ieee->lock, flags);
8946 + }else{
8947 + spin_unlock_irqrestore(&ieee->lock, flags);
8948 + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
8949 +
8950 + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
8951 +
8952 + if (ieee->seq_ctrl[0] == 0xFFF)
8953 + ieee->seq_ctrl[0] = 0;
8954 + else
8955 + ieee->seq_ctrl[0]++;
8956 +
8957 + /* avoid watchdog triggers */
8958 + ieee->dev->trans_start = jiffies;
8959 + ieee->softmac_hard_start_xmit(skb,ieee->dev);
8960 +
8961 + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
8962 + }
8963 +}
8964 +
8965 +
8966 +inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
8967 +{
8968 +
8969 + short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
8970 + struct ieee80211_hdr_3addr *header =
8971 + (struct ieee80211_hdr_3addr *) skb->data;
8972 +
8973 +
8974 + if(single){
8975 +
8976 + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
8977 +
8978 + if (ieee->seq_ctrl[0] == 0xFFF)
8979 + ieee->seq_ctrl[0] = 0;
8980 + else
8981 + ieee->seq_ctrl[0]++;
8982 +
8983 + /* avoid watchdog triggers */
8984 + ieee->dev->trans_start = jiffies;
8985 + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
8986 +
8987 + }else{
8988 +
8989 + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
8990 +
8991 + if (ieee->seq_ctrl[0] == 0xFFF)
8992 + ieee->seq_ctrl[0] = 0;
8993 + else
8994 + ieee->seq_ctrl[0]++;
8995 +
8996 + /* avoid watchdog triggers */
8997 + ieee->dev->trans_start = jiffies;
8998 + ieee->softmac_hard_start_xmit(skb,ieee->dev);
8999 +
9000 + }
9001 +// dev_kfree_skb_any(skb);//edit by thomas
9002 +}
9003 +//by amy for power save
9004 +inline struct sk_buff *ieee80211_disassociate_skb(
9005 + struct ieee80211_network *beacon,
9006 + struct ieee80211_device *ieee,
9007 + u8 asRsn)
9008 +{
9009 + struct sk_buff *skb;
9010 + struct ieee80211_disassoc_frame *disass;
9011 +
9012 + skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc_frame));
9013 + if (!skb)
9014 + return NULL;
9015 +
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;
9019 +
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);
9023 +
9024 + disass->reasoncode = asRsn;
9025 + return skb;
9026 +}
9027 +void
9028 +SendDisassociation(
9029 + struct ieee80211_device *ieee,
9030 + u8* asSta,
9031 + u8 asRsn
9032 +)
9033 +{
9034 + struct ieee80211_network *beacon = &ieee->current_network;
9035 + struct sk_buff *skb;
9036 + skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
9037 + if (skb){
9038 + softmac_mgmt_xmit(skb, ieee);
9039 + //dev_kfree_skb_any(skb);//edit by thomas
9040 + }
9041 +}
9042 +
9043 +//by amy for power save
9044 +inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
9045 +{
9046 + unsigned int len,rate_len;
9047 + u8 *tag;
9048 + struct sk_buff *skb;
9049 + struct ieee80211_probe_request *req;
9050 +
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);
9055 +#endif
9056 +
9057 + len = ieee->current_network.ssid_len;
9058 +
9059 + rate_len = ieee80211_MFIE_rate_len(ieee);
9060 +
9061 +#ifdef _RTL8187_EXT_PATCH_
9062 + if(!extMore)
9063 +#endif
9064 + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
9065 + 2 + len + rate_len);
9066 +#ifdef _RTL8187_EXT_PATCH_
9067 + else
9068 + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
9069 + 2 + len + rate_len+128); // MESHID + CAP
9070 +#endif
9071 +
9072 + if (!skb)
9073 + return NULL;
9074 +
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 ?
9078 +
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);
9082 +
9083 + tag = (u8 *) skb_put(skb,len+2+rate_len);
9084 +
9085 + *tag++ = MFIE_TYPE_SSID;
9086 + *tag++ = len;
9087 + memcpy(tag, ieee->current_network.ssid, len);
9088 + tag += len;
9089 + ieee80211_MFIE_Brate(ieee,&tag);
9090 + ieee80211_MFIE_Grate(ieee,&tag);
9091 +
9092 +#ifdef _RTL8187_EXT_PATCH_
9093 + if(extMore)
9094 + ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag);
9095 +#endif
9096 + return skb;
9097 +}
9098 +
9099 +struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
9100 +
9101 +//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
9102 +//void ext_ieee80211_send_beacon_wq(struct work_struct *work)
9103 +//{
9104 +// struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_send_beacon_wq);
9105 +//#else
9106 +void ext_ieee80211_send_beacon_wq(struct ieee80211_device *ieee)
9107 +{
9108 +//#endif
9109 +
9110 + struct sk_buff *skb;
9111 +
9112 + //unsigned long flags;
9113 +
9114 + skb = ieee80211_get_beacon_(ieee);
9115 +
9116 + if (skb){
9117 + softmac_mgmt_xmit(skb, ieee);
9118 + ieee->softmac_stats.tx_beacons++;
9119 + dev_kfree_skb_any(skb);//edit by thomas
9120 + }
9121 +
9122 +
9123 + //printk(KERN_WARNING "[1] beacon sending!\n");
9124 + ieee->beacon_timer.expires = jiffies +
9125 + (MSECS( ieee->current_network.beacon_interval -5));
9126 +
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);
9131 +}
9132 +
9133 +void ieee80211_send_beacon(struct ieee80211_device *ieee)
9134 +{
9135 + struct sk_buff *skb;
9136 +
9137 + //unsigned long flags;
9138 +
9139 + skb = ieee80211_get_beacon_(ieee);
9140 +
9141 + if (skb){
9142 + softmac_mgmt_xmit(skb, ieee);
9143 + ieee->softmac_stats.tx_beacons++;
9144 + dev_kfree_skb_any(skb);//edit by thomas
9145 + }
9146 +
9147 + //printk(KERN_WARNING "[1] beacon sending!\n");
9148 + ieee->beacon_timer.expires = jiffies +
9149 + (MSECS( ieee->current_network.beacon_interval -5));
9150 +
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);
9155 +}
9156 +
9157 +
9158 +void ieee80211_send_beacon_cb(unsigned long _ieee)
9159 +{
9160 + struct ieee80211_device *ieee =
9161 + (struct ieee80211_device *) _ieee;
9162 + unsigned long flags;
9163 +
9164 + spin_lock_irqsave(&ieee->beacon_lock, flags);
9165 + ieee80211_send_beacon(ieee);
9166 + spin_unlock_irqrestore(&ieee->beacon_lock, flags);
9167 +}
9168 +
9169 +#ifdef _RTL8187_EXT_PATCH_
9170 +
9171 +inline struct sk_buff *ieee80211_probe_req_with_SSID(struct ieee80211_device *ieee, char *ssid, int len_ssid)
9172 +{
9173 + unsigned int len,rate_len;
9174 + u8 *tag;
9175 + struct sk_buff *skb;
9176 + struct ieee80211_probe_request *req;
9177 +
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);
9182 +#endif
9183 +
9184 + len = len_ssid;
9185 +
9186 + rate_len = ieee80211_MFIE_rate_len(ieee);
9187 +
9188 +#ifdef _RTL8187_EXT_PATCH_
9189 + if(!extMore)
9190 +#endif
9191 + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
9192 + 2 + len + rate_len);
9193 +#ifdef _RTL8187_EXT_PATCH_
9194 + else
9195 + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
9196 + 2 + len + rate_len+128); // MESHID + CAP
9197 +#endif
9198 +
9199 + if (!skb)
9200 + return NULL;
9201 +
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 ?
9205 +
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);
9209 +
9210 + tag = (u8 *) skb_put(skb,len+2+rate_len);
9211 +
9212 + *tag++ = MFIE_TYPE_SSID;
9213 + *tag++ = len;
9214 + if(len)
9215 + {
9216 + memcpy(tag, ssid, len);
9217 + tag += len;
9218 + }
9219 +
9220 + ieee80211_MFIE_Brate(ieee,&tag);
9221 + ieee80211_MFIE_Grate(ieee,&tag);
9222 +
9223 +#ifdef _RTL8187_EXT_PATCH_
9224 + if(extMore)
9225 + ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag);
9226 +#endif
9227 + return skb;
9228 +}
9229 +
9230 +#endif // _RTL8187_EXT_PATCH_
9231 +
9232 +
9233 +void ieee80211_send_probe(struct ieee80211_device *ieee)
9234 +{
9235 + struct sk_buff *skb;
9236 +
9237 +#ifdef _RTL8187_EXT_PATCH_
9238 + if(ieee->iw_mode == ieee->iw_ext_mode)
9239 + skb = ieee80211_probe_req_with_SSID(ieee, NULL, 0);
9240 + else
9241 +#endif
9242 + skb = ieee80211_probe_req(ieee);
9243 + if (skb){
9244 + softmac_mgmt_xmit(skb, ieee);
9245 + ieee->softmac_stats.tx_probe_rq++;
9246 + //dev_kfree_skb_any(skb);//edit by thomas
9247 + }
9248 +}
9249 +
9250 +void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
9251 +{
9252 + if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
9253 + ieee80211_send_probe(ieee);
9254 + ieee80211_send_probe(ieee);
9255 + }
9256 +}
9257 +
9258 +/* this performs syncro scan blocking the caller until all channels
9259 + * in the allowed channel map has been checked.
9260 + */
9261 +void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
9262 +{
9263 + short ch = 0;
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);
9267 +#endif
9268 + down(&ieee->scan_sem);
9269 +// printk("==================> Sync scan\n");
9270 +// dump_chnl_map(channel_map);
9271 +
9272 + while(1)
9273 + {
9274 +
9275 + do{
9276 + ch++;
9277 + if (ch > MAX_CHANNEL_NUMBER)
9278 + goto out; /* scan completed */
9279 +
9280 +#ifdef ENABLE_DOT11D
9281 + }while(!channel_map[ch]);
9282 +#else
9283 + }while(!ieee->channel_map[ch]);
9284 +#endif
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
9293 + * scanning
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
9302 + */
9303 +
9304 + if (ieee->state == IEEE80211_LINKED)
9305 + goto out;
9306 +
9307 + ieee->set_chan(ieee->dev, ch);
9308 +// printk("=====>channel=%d ",ch);
9309 +#ifdef ENABLE_DOT11D
9310 + if(channel_map[ch] == 1)
9311 +#endif
9312 + {
9313 +// printk("====send probe request\n");
9314 + ieee80211_send_probe_requests(ieee);
9315 + }
9316 + /* this prevent excessive time wait when we
9317 + * need to wait for a syncro scan to end..
9318 + */
9319 + if (ieee->sync_scan_hurryup)
9320 + goto out;
9321 +
9322 +
9323 + msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
9324 +
9325 + }
9326 +out:
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);
9332 +#endif
9333 +}
9334 +
9335 +void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee)
9336 +{
9337 + int ch;
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);
9342 +#endif
9343 + down(&ieee->scan_sem);
9344 + ch = ieee->current_network.channel;
9345 +// if(ieee->sync_scan_hurryup)
9346 +// {
9347 +
9348 +// printk("stop scan sync\n");
9349 +// goto out;
9350 +// }
9351 +// printk("=======hh===============>ips scan\n");
9352 + while(1)
9353 + {
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
9362 + * scanning
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
9371 + */
9372 + if (ieee->state == IEEE80211_LINKED)
9373 + {
9374 + goto out;
9375 + }
9376 +#ifdef ENABLE_DOT11D
9377 + if(channel_map[ieee->current_network.channel] > 0)
9378 +#endif
9379 + {
9380 + ieee->set_chan(ieee->dev, ieee->current_network.channel);
9381 +// printk("======>channel=%d ",ieee->current_network.channel);
9382 + }
9383 +#ifdef ENABLE_DOT11D
9384 + if(channel_map[ieee->current_network.channel] == 1)
9385 +#endif
9386 + {
9387 +// printk("====send probe request\n");
9388 + ieee80211_send_probe_requests(ieee);
9389 + }
9390 + /* this prevent excessive time wait when we
9391 + * need to wait for a syncro scan to end..
9392 + */
9393 +// if (ieee->sync_scan_hurryup)
9394 +// goto out;
9395 +
9396 + msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
9397 +
9398 + do{
9399 + if (watch_dog++ >= MAX_CHANNEL_NUMBER)
9400 + // if (++watch_dog >= 15);//MAX_CHANNEL_NUMBER) //YJ,modified,080630
9401 + goto out; /* scan completed */
9402 +
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]);
9406 +#else
9407 + }while(!ieee->channel_map[ieee->current_network.channel]);
9408 +#endif
9409 + }
9410 +out:
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);
9419 +#endif
9420 +}
9421 +
9422 +
9423 +#if 0
9424 +/* called both by wq with ieee->lock held */
9425 +void ieee80211_softmac_scan(struct ieee80211_device *ieee)
9426 +{
9427 + short watchdog = 0;
9428 +
9429 + do{
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 */
9434 +
9435 + }while(!ieee->channel_map[ieee->current_network.channel]);
9436 +
9437 +
9438 + schedule_work(&ieee->softmac_scan_wq);
9439 +}
9440 +#endif
9441 +#ifdef ENABLE_IPS
9442 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
9443 +void ieee80211_softmac_scan_wq(struct work_struct *work)
9444 +{
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);
9447 +#else
9448 +void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
9449 +{
9450 +#endif
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);
9455 +#endif
9456 +// printk("ieee80211_softmac_scan_wq ENABLE_IPS\n");
9457 +// printk("in %s\n",__FUNCTION__);
9458 + down(&ieee->scan_sem);
9459 +
9460 + do{
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 */
9465 +
9466 +#ifdef ENABLE_DOT11D
9467 + }while(!channel_map[ieee->current_network.channel]);
9468 +#else
9469 + }while(!ieee->channel_map[ieee->current_network.channel]);
9470 +#endif
9471 +
9472 + //printk("current_network.channel:%d\n", ieee->current_network.channel);
9473 + if (ieee->scanning == 0 )
9474 + {
9475 + printk("error out, scanning = 0\n");
9476 + goto out;
9477 + }
9478 + ieee->set_chan(ieee->dev, ieee->current_network.channel);
9479 +#ifdef ENABLE_DOT11D
9480 + if(channel_map[ieee->current_network.channel] == 1)
9481 +#endif
9482 + ieee80211_send_probe_requests(ieee);
9483 +
9484 + queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
9485 + up(&ieee->scan_sem);
9486 + return;
9487 +out:
9488 + ieee->actscanning = false;
9489 + watchdog = 0;
9490 + ieee->scanning = 0;
9491 + up(&ieee->scan_sem);
9492 +
9493 +#ifdef ENABLE_DOT11D
9494 + if(IS_DOT11D_ENABLE(ieee))
9495 + DOT11D_ScanComplete(ieee);
9496 +#endif
9497 + return;
9498 +}
9499 +#else
9500 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
9501 +void ieee80211_softmac_scan_wq(struct work_struct *work)
9502 +{
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);
9505 +#else
9506 +void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
9507 +{
9508 +#endif
9509 +
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);
9514 +#endif
9515 +// printk("enter scan wq,watchdog is %d\n",watchdog);
9516 + down(&ieee->scan_sem);
9517 +
9518 + do{
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 */
9523 +
9524 +#ifdef ENABLE_DOT11D
9525 + }while(!channel_map[ieee->current_network.channel]);
9526 +#else
9527 + }while(!ieee->channel_map[ieee->current_network.channel]);
9528 +#endif
9529 +
9530 +// printk("current_network.channel:%d\n", ieee->current_network.channel);
9531 + if (ieee->scanning == 0 )
9532 + {
9533 + printk("error out, scanning = 0\n");
9534 + goto out;
9535 + }
9536 + ieee->set_chan(ieee->dev, ieee->current_network.channel);
9537 +#ifdef ENABLE_DOT11D
9538 + if(channel_map[ieee->current_network.channel] == 1)
9539 +#endif
9540 + ieee80211_send_probe_requests(ieee);
9541 +
9542 + queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
9543 +out:
9544 + up(&ieee->scan_sem);
9545 +#ifdef ENABLE_DOT11D
9546 + if(IS_DOT11D_ENABLE(ieee))
9547 + DOT11D_ScanComplete(ieee);
9548 +#endif
9549 +}
9550 +
9551 +#endif
9552 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
9553 +void ieee80211_softmac_scan_cb(unsigned long _dev)
9554 +{
9555 + unsigned long flags;
9556 + struct ieee80211_device *ieee = (struct ieee80211_device *)_dev;
9557 +
9558 + spin_lock_irqsave(&ieee->lock, flags);
9559 + ieee80211_softmac_scan(ieee);
9560 + spin_unlock_irqrestore(&ieee->lock, flags);
9561 +}
9562 +#endif
9563 +
9564 +
9565 +void ieee80211_beacons_start(struct ieee80211_device *ieee)
9566 +{
9567 + unsigned long flags;
9568 +
9569 + spin_lock_irqsave(&ieee->beacon_lock,flags);
9570 +
9571 + ieee->beacon_txing = 1;
9572 + ieee80211_send_beacon(ieee);
9573 +
9574 + spin_unlock_irqrestore(&ieee->beacon_lock,flags);
9575 +}
9576 +
9577 +void ieee80211_beacons_stop(struct ieee80211_device *ieee)
9578 +{
9579 + unsigned long flags;
9580 +
9581 + spin_lock_irqsave(&ieee->beacon_lock,flags);
9582 +
9583 + ieee->beacon_txing = 0;
9584 + del_timer_sync(&ieee->beacon_timer);
9585 +
9586 + spin_unlock_irqrestore(&ieee->beacon_lock,flags);
9587 +
9588 +}
9589 +
9590 +
9591 +void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
9592 +{
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);
9597 +}
9598 +
9599 +
9600 +void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
9601 +{
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);
9606 +}
9607 +
9608 +
9609 +void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
9610 +{
9611 +// unsigned long flags;
9612 +
9613 + //ieee->sync_scan_hurryup = 1;
9614 +
9615 + down(&ieee->scan_sem);
9616 +// spin_lock_irqsave(&ieee->lock, flags);
9617 +
9618 + if (ieee->scanning == 1){
9619 + ieee->scanning = 0;
9620 + //del_timer_sync(&ieee->scan_timer);
9621 + cancel_delayed_work(&ieee->softmac_scan_wq);
9622 + }
9623 +
9624 +// spin_unlock_irqrestore(&ieee->lock, flags);
9625 + up(&ieee->scan_sem);
9626 +}
9627 +
9628 +void ieee80211_stop_scan(struct ieee80211_device *ieee)
9629 +{
9630 + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
9631 + ieee80211_softmac_stop_scan(ieee);
9632 + else
9633 + ieee->stop_scan(ieee->dev);
9634 +}
9635 +
9636 +/* called with ieee->lock held */
9637 +void ieee80211_start_scan(struct ieee80211_device *ieee)
9638 +{
9639 +#ifdef ENABLE_DOT11D
9640 + if(IS_DOT11D_ENABLE(ieee) )
9641 + {
9642 + if(IS_COUNTRY_IE_VALID(ieee))
9643 + {
9644 + RESET_CIE_WATCHDOG(ieee);
9645 + }
9646 + }
9647 +#endif
9648 + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
9649 + if (ieee->scanning == 0)
9650 + {
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
9655 +#if 1
9656 + queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq,0);
9657 +#endif
9658 + }
9659 + }else
9660 + ieee->start_scan(ieee->dev);
9661 +
9662 +}
9663 +
9664 +/* called with wx_sem held */
9665 +void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
9666 +{
9667 +#ifdef ENABLE_DOT11D
9668 + if(IS_DOT11D_ENABLE(ieee) )
9669 + {
9670 + if(IS_COUNTRY_IE_VALID(ieee))
9671 + {
9672 + RESET_CIE_WATCHDOG(ieee);
9673 + }
9674 + }
9675 +#endif
9676 + ieee->sync_scan_hurryup = 0;
9677 +
9678 + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
9679 + ieee80211_softmac_scan_syncro(ieee);
9680 + else
9681 + ieee->scan_syncro(ieee->dev);
9682 +
9683 +}
9684 +
9685 +inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
9686 + struct ieee80211_device *ieee, int challengelen)
9687 +{
9688 + struct sk_buff *skb;
9689 + struct ieee80211_authentication *auth;
9690 +
9691 + skb = dev_alloc_skb(sizeof(struct ieee80211_authentication) + challengelen);
9692 +
9693 + if (!skb) return NULL;
9694 +
9695 + auth = (struct ieee80211_authentication *)
9696 + skb_put(skb, sizeof(struct ieee80211_authentication));
9697 +
9698 + auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
9699 + if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
9700 +
9701 + auth->header.duration_id = 0x013a; //FIXME
9702 +
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);
9706 +
9707 + auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
9708 +
9709 + auth->transaction = cpu_to_le16(ieee->associate_seq);
9710 + ieee->associate_seq++;
9711 +
9712 + auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
9713 +
9714 + return skb;
9715 +
9716 +}
9717 +
9718 +static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
9719 +{
9720 + u8 *tag;
9721 + int beacon_size;
9722 + struct ieee80211_probe_response *beacon_buf;
9723 + struct sk_buff *skb;
9724 + int encrypt;
9725 + int atim_len,erp_len;
9726 + struct ieee80211_crypt_data* crypt;
9727 +
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;
9734 +
9735 + if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
9736 + atim_len = 4;
9737 + else
9738 + atim_len = 0;
9739 +
9740 + if(ieee80211_is_54g(ieee->current_network))
9741 + erp_len = 3;
9742 + else
9743 + erp_len = 0;
9744 +
9745 + beacon_size = sizeof(struct ieee80211_probe_response)+
9746 + ssid_len
9747 + +3 //channel
9748 + +rate_len
9749 + +rate_ex_len
9750 + +atim_len
9751 + +wpa_ie_len
9752 + +erp_len;
9753 +
9754 + skb = dev_alloc_skb(beacon_size);
9755 +
9756 + if (!skb)
9757 + return NULL;
9758 +
9759 + beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size);
9760 +
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);
9764 +
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);
9770 +
9771 + if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
9772 + cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
9773 +
9774 + crypt = ieee->crypt[ieee->tx_keyidx];
9775 +
9776 + encrypt = ieee->host_encrypt && crypt && crypt->ops &&
9777 + ((0 == strcmp(crypt->ops->name, "WEP")) || wpa_ie_len);
9778 +
9779 + if (encrypt)
9780 + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
9781 +
9782 +
9783 + beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
9784 +
9785 + beacon_buf->info_element.id = MFIE_TYPE_SSID;
9786 + beacon_buf->info_element.len = ssid_len;
9787 +
9788 + tag = (u8*) beacon_buf->info_element.data;
9789 +
9790 + memcpy(tag, ssid, ssid_len);
9791 +
9792 + tag += ssid_len;
9793 +
9794 + *(tag++) = MFIE_TYPE_RATES;
9795 + *(tag++) = rate_len-2;
9796 + memcpy(tag,ieee->current_network.rates,rate_len-2);
9797 + tag+=rate_len-2;
9798 +
9799 + *(tag++) = MFIE_TYPE_DS_SET;
9800 + *(tag++) = 1;
9801 + *(tag++) = ieee->current_network.channel;
9802 +
9803 + if(atim_len){
9804 + *(tag++) = MFIE_TYPE_IBSS_SET;
9805 + *(tag++) = 2;
9806 + *((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
9807 + tag+=2;
9808 + }
9809 +
9810 + if(erp_len){
9811 + *(tag++) = MFIE_TYPE_ERP;
9812 + *(tag++) = 1;
9813 + *(tag++) = 0;
9814 + }
9815 +
9816 + if(rate_ex_len){
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;
9821 + }
9822 +
9823 + if (wpa_ie_len)
9824 + {
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);
9828 + }
9829 +
9830 + memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
9831 + }
9832 +
9833 + skb->dev = ieee->dev;
9834 + return skb;
9835 +}
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)
9838 +{
9839 + u8 *tag;
9840 + int beacon_size;
9841 + struct ieee80211_probe_response *beacon_buf;
9842 + struct sk_buff *skb;
9843 + int encrypt;
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;
9850 +
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;
9854 +
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)
9858 + {
9859 +
9860 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
9861 + queue_work(ieee->wq, &ieee->ext_stop_scan_wq);
9862 +#else
9863 + schedule_task(&ieee->ext_stop_scan_wq);
9864 +#endif
9865 + }
9866 + if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS) // use current_network here
9867 + atim_len = 4;
9868 + else
9869 + atim_len = 0;
9870 +
9871 + if(ieee80211_is_54g(*net))
9872 + erp_len = 3;
9873 + else
9874 + erp_len = 0;
9875 +
9876 + beacon_size = sizeof(struct ieee80211_probe_response)+
9877 + ssid_len
9878 + +3 //channel
9879 + +rate_len
9880 + +rate_ex_len
9881 + +atim_len
9882 + +erp_len;
9883 +//b
9884 + skb = dev_alloc_skb(beacon_size+196);
9885 +
9886 + if (!skb)
9887 + return NULL;
9888 +
9889 + beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size);
9890 +
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);
9894 +
9895 + beacon_buf->header.duration_id = 0; //FIXME
9896 +
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);
9901 +
9902 + if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
9903 + cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
9904 +
9905 + crypt = ieee->crypt[ieee->tx_keyidx];
9906 +
9907 + encrypt = ieee->host_encrypt && crypt && crypt->ops &&
9908 + ((0 == strcmp(crypt->ops->name, "WEP"))||wpa_ie_len);
9909 +
9910 + if (encrypt)
9911 + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
9912 +
9913 +
9914 + beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
9915 +
9916 + beacon_buf->info_element.id = MFIE_TYPE_SSID;
9917 + beacon_buf->info_element.len = ssid_len;
9918 +
9919 + tag = (u8*) beacon_buf->info_element.data;
9920 +
9921 + // brocad cast / probe rsp
9922 + if(memcmp(dest, broadcast_addr, ETH_ALEN ))
9923 + memcpy(tag, ssid, ssid_len);
9924 + else
9925 + ssid_len=0;
9926 +
9927 + tag += ssid_len;
9928 +
9929 +//get_bssrate_set(priv, _SUPPORTEDRATES_IE_, &pbssrate, &bssrate_len);
9930 +//pbuf = set_ie(pbuf, _SUPPORTEDRATES_IE_, bssrate_len, pbssrate, &frlen);
9931 +
9932 + *(tag++) = MFIE_TYPE_RATES;
9933 + *(tag++) = rate_len-2;
9934 + memcpy(tag,ieee->current_network.rates,rate_len-2);
9935 + tag+=rate_len-2;
9936 +
9937 + *(tag++) = MFIE_TYPE_DS_SET;
9938 + *(tag++) = 1;
9939 + *(tag++) = ieee->current_network.channel; // use current_network here
9940 +
9941 +
9942 + if(atim_len){
9943 + *(tag++) = MFIE_TYPE_IBSS_SET;
9944 + *(tag++) = 2;
9945 + *((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window); // use current_network here
9946 + tag+=2;
9947 + }
9948 +
9949 + if(erp_len){
9950 + *(tag++) = MFIE_TYPE_ERP;
9951 + *(tag++) = 1;
9952 + *(tag++) = 0;
9953 + }
9954 +
9955 + if(rate_ex_len){
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;
9960 + }
9961 + if (wpa_ie_len)
9962 + memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
9963 +
9964 + skb->dev = ieee->dev;
9965 + return skb;
9966 +}
9967 +#endif // _RTL8187_EXT_PATCH_
9968 +
9969 +struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
9970 +{
9971 + struct sk_buff *skb;
9972 + u8* tag;
9973 +
9974 + struct ieee80211_crypt_data* crypt;
9975 + struct ieee80211_assoc_response_frame *assoc;
9976 + short encrypt;
9977 +
9978 + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
9979 + int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
9980 +
9981 + skb = dev_alloc_skb(len);
9982 +
9983 + if (!skb)
9984 + return NULL;
9985 +
9986 + assoc = (struct ieee80211_assoc_response_frame *)
9987 + skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
9988 +
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);
9995 +
9996 +
9997 + if(ieee->short_slot)
9998 + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
9999 +
10000 + if (ieee->host_encrypt)
10001 + crypt = ieee->crypt[ieee->tx_keyidx];
10002 + else crypt = NULL;
10003 +
10004 + encrypt = ( crypt && crypt->ops);
10005 +
10006 + if (encrypt)
10007 + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
10008 +
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++;
10013 +
10014 + tag = (u8*) skb_put(skb, rate_len);
10015 +
10016 + ieee80211_MFIE_Brate(ieee, &tag);
10017 + ieee80211_MFIE_Grate(ieee, &tag);
10018 +
10019 + return skb;
10020 +}
10021 +
10022 +struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
10023 +{
10024 + struct sk_buff *skb;
10025 + struct ieee80211_authentication *auth;
10026 +
10027 + skb = dev_alloc_skb(sizeof(struct ieee80211_authentication)+1);
10028 +
10029 + if (!skb)
10030 + return NULL;
10031 +
10032 + skb->len = sizeof(struct ieee80211_authentication);
10033 +
10034 + auth = (struct ieee80211_authentication *)skb->data;
10035 +
10036 + auth->status = cpu_to_le16(status);
10037 + auth->transaction = cpu_to_le16(2);
10038 + auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
10039 +
10040 +#ifdef _RTL8187_EXT_PATCH_
10041 + if(ieee->iw_mode == ieee->iw_ext_mode)
10042 + memcpy(auth->header.addr3, dest, ETH_ALEN);
10043 +#else
10044 + memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
10045 +#endif
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);
10049 + return skb;
10050 +
10051 +
10052 +}
10053 +
10054 +struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
10055 +{
10056 + struct sk_buff *skb;
10057 + struct ieee80211_hdr_3addr* hdr;
10058 +
10059 + skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
10060 +
10061 + if (!skb)
10062 + return NULL;
10063 +
10064 + hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
10065 +
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);
10069 +
10070 + hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
10071 + IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
10072 + (pwr ? IEEE80211_FCTL_PM:0));
10073 +
10074 + return skb;
10075 +
10076 +
10077 +}
10078 +
10079 +
10080 +void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
10081 +{
10082 + struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
10083 +
10084 + if (buf){
10085 + softmac_mgmt_xmit(buf, ieee);
10086 + dev_kfree_skb_any(buf);//edit by thomas
10087 + }
10088 +}
10089 +
10090 +
10091 +void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest)
10092 +{
10093 + struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
10094 +
10095 + if (buf){
10096 + softmac_mgmt_xmit(buf, ieee);
10097 + dev_kfree_skb_any(buf);//edit by thomas
10098 + }
10099 +}
10100 +
10101 +
10102 +void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
10103 +{
10104 +
10105 + struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
10106 +
10107 + if (buf) {
10108 + softmac_mgmt_xmit(buf, ieee);
10109 + dev_kfree_skb_any(buf);//edit by thomas
10110 + }
10111 +}
10112 +
10113 +
10114 +inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
10115 +{
10116 + struct sk_buff *skb;
10117 + //unsigned long flags;
10118 +
10119 + struct ieee80211_assoc_request_frame *hdr;
10120 + u8 *tag;
10121 + //short info_addr = 0;
10122 + //int i;
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;
10128 + //u8 *buff;
10129 + //u8 *p;
10130 +#if 1
10131 + // for testing purpose
10132 + unsigned int rsn_len = beacon->rsn_ie_len;
10133 +#else
10134 + unsigned int rsn_len = beacon->rsn_ie_len - 4;
10135 +#endif
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;
10140 +#endif
10141 +
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;
10145 +
10146 + int len = 0;
10147 +
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) {
10153 + rsn_len = 0;
10154 + } else if (IEEE_PROTO_RSN == encry_proto) {
10155 + wpa_len = 0;
10156 + }
10157 + }
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
10162 + + wpa_len
10163 + + rsn_len
10164 + + wmm_info_len
10165 + + turbo_info_len;
10166 +#else
10167 + len = sizeof(struct ieee80211_assoc_request_frame)+
10168 + + beacon->ssid_len//essid tagged val
10169 + + rate_len//rates tagged val
10170 + + wpa_len
10171 + + rsn_len
10172 + + wmm_info_len;
10173 +#endif
10174 +
10175 +#ifdef _RTL8187_EXT_PATCH_
10176 + if(ieee->iw_mode == ieee->iw_ext_mode)
10177 + skb = dev_alloc_skb(len+256); // stanley
10178 + else
10179 +#endif
10180 + skb = dev_alloc_skb(len);
10181 +
10182 + if (!skb)
10183 + return NULL;
10184 +
10185 + hdr = (struct ieee80211_assoc_request_frame *)
10186 + skb_put(skb, sizeof(struct ieee80211_assoc_request_frame));
10187 +
10188 +
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
10195 +
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);
10201 +
10202 + if(ieee->short_slot)
10203 + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
10204 +
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);
10208 +#endif
10209 +
10210 + hdr->listen_interval = 0xa; //FIXME
10211 +
10212 + hdr->info_element.id = MFIE_TYPE_SSID;
10213 +
10214 + hdr->info_element.len = beacon->ssid_len;
10215 + tag = skb_put(skb, beacon->ssid_len);
10216 + memcpy(tag, beacon->ssid, beacon->ssid_len);
10217 +
10218 + tag = skb_put(skb, rate_len);
10219 +
10220 + ieee80211_MFIE_Brate(ieee, &tag);
10221 + ieee80211_MFIE_Grate(ieee, &tag);
10222 +
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
10225 +#if 0
10226 + if(rsn_len == 0){
10227 +
10228 + tag = skb_put(skb,wpa_len);
10229 +
10230 + if(wpa_len) {
10231 +
10232 +
10233 + //{add by david. 2006.8.31
10234 + //fix linksys compatibility bug
10235 + //}
10236 + if(wpa_len > 24) {//22+2, mean include the capability
10237 + beacon->wpa_ie[wpa_len - 2] = 0;
10238 + }
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;
10242 + }
10243 + else if( beacon->wpa_ie[11]==0x4 ){//0x0050f204 is the oui of ccmp
10244 + ieee->broadcast_key_type = KEY_TYPE_CCMP;
10245 + }
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;
10252 + }
10253 +
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;
10259 + }
10260 + //indicate the wpa_ie content to WPA_SUPPLICANT
10261 + buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
10262 + memset(buff, 0, IW_CUSTOM_MAX);
10263 + p=buff;
10264 + p += sprintf(p, "ASSOCINFO(ReqIEs=");
10265 + for(i=0;i<wpa_len;i++){
10266 + p += sprintf(p, "%02x", beacon->wpa_ie[i]);
10267 + }
10268 + p += sprintf(p, ")");
10269 + memset(&wrqu, 0, sizeof(wrqu) );
10270 + wrqu.data.length = p - buff;
10271 +
10272 + wireless_send_event(dev, IWEVCUSTOM, &wrqu, buff);
10273 + memcpy(tag,beacon->wpa_ie,wpa_len);
10274 + }
10275 +
10276 + }
10277 +
10278 + if(rsn_len > 22) {
10279 +
10280 + if( beacon->rsn_ie[4]==0x0 &&
10281 + beacon->rsn_ie[5]==0xf &&
10282 + beacon->rsn_ie[6]==0xac){
10283 +
10284 + switch(beacon->rsn_ie[7]){
10285 + case 0x1:
10286 + ieee->broadcast_key_type = KEY_TYPE_WEP40;
10287 + break;
10288 + case 0x2:
10289 + ieee->broadcast_key_type = KEY_TYPE_TKIP;
10290 + break;
10291 + case 0x4:
10292 + ieee->broadcast_key_type = KEY_TYPE_CCMP;
10293 + break;
10294 + case 0x5:
10295 + ieee->broadcast_key_type = KEY_TYPE_WEP104;
10296 + break;
10297 + default:
10298 + printk("fault suite type in RSN broadcast key\n");
10299 + break;
10300 + }
10301 + }
10302 +
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]){
10308 + case 0x2:
10309 + ieee->pairwise_key_type = KEY_TYPE_TKIP;
10310 + break;
10311 + case 0x4:
10312 + ieee->pairwise_key_type = KEY_TYPE_CCMP;
10313 + break;
10314 + default:
10315 + printk("fault suite type in RSN pairwise key\n");
10316 + break;
10317 + }
10318 + }
10319 + else if(beacon->rsn_ie[8]==2){//mixed mode
10320 + ieee->pairwise_key_type = KEY_TYPE_CCMP;
10321 + }
10322 + }
10323 +
10324 +
10325 +
10326 + tag = skb_put(skb,22);
10327 + memcpy(tag,(beacon->rsn_ie + info_addr),8);
10328 + tag[1] = 20;
10329 + tag += 8;
10330 + info_addr += 8;
10331 +
10332 + spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
10333 + for (i = 0; i < 2; i++) {
10334 + tag[0] = 1;
10335 + tag[1] = 0;
10336 + tag += 2;
10337 + suite_count = beacon->rsn_ie[info_addr] + \
10338 + (beacon->rsn_ie[info_addr + 1] << 8);
10339 + info_addr += 2;
10340 + if(1 == suite_count) {
10341 + memcpy(tag,(beacon->rsn_ie + info_addr),4);
10342 + info_addr += 4;
10343 + } else {
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);
10349 + } else {
10350 + //default set as ccmp, or none authentication
10351 + if(i == 0) {
10352 + memcpy(tag,rsn_authen_cipher_suite[4],4);
10353 + } else {
10354 + memcpy(tag,rsn_authen_cipher_suite[2],4);
10355 + }
10356 +
10357 + }
10358 +
10359 + info_addr += (suite_count * 4);
10360 + }
10361 + tag += 4;
10362 + }
10363 + spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
10364 +
10365 + tag[0] = 0;
10366 + tag[1] = beacon->rsn_ie[info_addr+1];
10367 +
10368 + } else {
10369 + tag = skb_put(skb,rsn_len);
10370 + if(rsn_len) {
10371 +
10372 +
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]){
10377 + case 0x1:
10378 + ieee->broadcast_key_type = KEY_TYPE_WEP40;
10379 + break;
10380 + case 0x2:
10381 + ieee->broadcast_key_type = KEY_TYPE_TKIP;
10382 + break;
10383 + case 0x4:
10384 + ieee->broadcast_key_type = KEY_TYPE_CCMP;
10385 + break;
10386 + case 0x5:
10387 + ieee->broadcast_key_type = KEY_TYPE_WEP104;
10388 + break;
10389 + default:
10390 + printk("fault suite type in RSN broadcast key\n");
10391 + break;
10392 + }
10393 + }
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]){
10399 + case 0x2:
10400 + ieee->pairwise_key_type = KEY_TYPE_TKIP;
10401 + break;
10402 + case 0x4:
10403 + ieee->pairwise_key_type = KEY_TYPE_CCMP;
10404 + break;
10405 + default:
10406 + printk("fault suite type in RSN pairwise key\n");
10407 + break;
10408 + }
10409 +
10410 + }
10411 + else if(beacon->rsn_ie[8]==2){//mixed mode
10412 + ieee->pairwise_key_type = KEY_TYPE_CCMP;
10413 + }
10414 + }
10415 +
10416 +
10417 + beacon->rsn_ie[rsn_len - 2] = 0;
10418 + memcpy(tag,beacon->rsn_ie,rsn_len);
10419 + }
10420 + }
10421 +#else
10422 + tag = skb_put(skb,ieee->wpa_ie_len);
10423 + memcpy(tag,ieee->wpa_ie,ieee->wpa_ie_len);
10424 +#endif
10425 + tag = skb_put(skb,wmm_info_len);
10426 + if(wmm_info_len) {
10427 + ieee80211_WMM_Info(ieee, &tag);
10428 + }
10429 +#ifdef THOMAS_TURBO
10430 + tag = skb_put(skb,turbo_info_len);
10431 + if(turbo_info_len) {
10432 + ieee80211_TURBO_Info(ieee, &tag);
10433 + }
10434 +#endif
10435 +
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);
10439 +#endif
10440 +
10441 + return skb;
10442 +}
10443 +
10444 +void ieee80211_associate_abort(struct ieee80211_device *ieee)
10445 +{
10446 +
10447 + unsigned long flags;
10448 + spin_lock_irqsave(&ieee->lock, flags);
10449 +
10450 + ieee->associate_seq++;
10451 +
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
10457 + */
10458 + if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
10459 + IEEE80211_DEBUG_MGMT("Authentication failed\n");
10460 + ieee->softmac_stats.no_auth_rs++;
10461 + }else{
10462 + IEEE80211_DEBUG_MGMT("Association failed\n");
10463 + ieee->softmac_stats.no_ass_rs++;
10464 + }
10465 +
10466 + ieee->state = IEEE80211_ASSOCIATING_RETRY;
10467 +
10468 + queue_delayed_work(ieee->wq, &ieee->associate_retry_wq,IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
10469 +
10470 + spin_unlock_irqrestore(&ieee->lock, flags);
10471 +}
10472 +
10473 +void ieee80211_associate_abort_cb(unsigned long dev)
10474 +{
10475 + ieee80211_associate_abort((struct ieee80211_device *) dev);
10476 +}
10477 +
10478 +
10479 +void ieee80211_associate_step1(struct ieee80211_device *ieee)
10480 +{
10481 + struct ieee80211_network *beacon = &ieee->current_network;
10482 + struct sk_buff *skb;
10483 +
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 ) {
10489 + if(skb)
10490 + softmac_mgmt_xmit(skb, ieee);
10491 + return;
10492 + }else
10493 +#endif
10494 + if (!skb){
10495 +
10496 + ieee80211_associate_abort(ieee);
10497 + }
10498 + else{
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);
10507 + }
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
10513 + }
10514 +}
10515 +
10516 +void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
10517 +{
10518 + u8 *c;
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++;
10525 +
10526 + skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
10527 + if (!skb)
10528 + ieee80211_associate_abort(ieee);
10529 + else{
10530 + c = skb_put(skb, chlen+2);
10531 + *(c++) = MFIE_TYPE_CHALLENGE;
10532 + *(c++) = chlen;
10533 + memcpy(c, challenge, chlen);
10534 +
10535 + IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
10536 +
10537 + ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr ));
10538 +
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);
10544 + }
10545 + dev_kfree_skb_any(skb);//edit by thomas
10546 + }
10547 + kfree(challenge);
10548 +}
10549 +
10550 +#ifdef _RTL8187_EXT_PATCH_
10551 +
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)
10554 +{
10555 + struct sk_buff *skb;
10556 + u8* tag;
10557 +
10558 + struct ieee80211_crypt_data* crypt;
10559 + struct ieee80211_assoc_response_frame *assoc;
10560 + short encrypt;
10561 +
10562 + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
10563 + int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
10564 +
10565 + if(ieee->iw_mode == ieee->iw_ext_mode)
10566 + skb = dev_alloc_skb(len+256); // stanley
10567 + else
10568 + skb = dev_alloc_skb(len);
10569 +
10570 + if (!skb)
10571 + return NULL;
10572 +
10573 + assoc = (struct ieee80211_assoc_response_frame *)
10574 + skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
10575 +
10576 + assoc->header.frame_ctl = cpu_to_le16(pkt_type);
10577 +
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);
10583 +
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);
10586 +
10587 + if(ieee->short_slot)
10588 + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
10589 +
10590 + if (ieee->host_encrypt)
10591 + crypt = ieee->crypt[ieee->tx_keyidx];
10592 + else crypt = NULL;
10593 +
10594 + encrypt = ( crypt && crypt->ops);
10595 +
10596 + if (encrypt)
10597 + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
10598 +
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++;
10603 +
10604 + assoc->info_element.id = 230; // Stanley, an unused id (just a hot fix)
10605 + assoc->info_element.len = 0;
10606 +
10607 + tag = (u8*) skb_put(skb, rate_len);
10608 +
10609 + ieee80211_MFIE_Brate(ieee, &tag);
10610 + ieee80211_MFIE_Grate(ieee, &tag);
10611 +
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);
10614 +
10615 + return skb;
10616 +}
10617 +
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)
10620 +{
10621 + struct sk_buff *buf = ieee80211_assoc_resp_by_net(ieee, dest, status, pstat, pkt_type);
10622 +
10623 + if (buf)
10624 + softmac_mgmt_xmit(buf, ieee);
10625 +}
10626 +
10627 +// based on ieee80211_associate_step2
10628 +void ieee80211_ext_issue_assoc_req(struct ieee80211_device *ieee, struct ieee80211_network *pstat)
10629 +{
10630 +
10631 + struct sk_buff* skb;
10632 +
10633 + // printk("@@@@@ ieee80211_ext_issue_assoc_req on channel: %d\n", ieee->current_network.channel);
10634 +
10635 + ieee->softmac_stats.tx_ass_rq++;
10636 + skb=ieee80211_association_req(pstat, ieee);
10637 + if (skb)
10638 + softmac_mgmt_xmit(skb, ieee);
10639 +}
10640 +
10641 +void ieee80211_ext_issue_disassoc(struct ieee80211_device *ieee, struct ieee80211_network *pstat, int reason, unsigned char extReason)
10642 +{
10643 + // do nothing
10644 + // printk("@@@@@ ieee80211_ext_issue_disassoc\n");
10645 + return;
10646 +}
10647 +#endif // _RTL8187_EXT_PATCH_
10648 +
10649 +void ieee80211_associate_step2(struct ieee80211_device *ieee)
10650 +{
10651 + struct sk_buff* skb;
10652 + struct ieee80211_network *beacon = &ieee->current_network;
10653 +
10654 + del_timer_sync(&ieee->associate_timer);
10655 +
10656 + IEEE80211_DEBUG_MGMT("Sending association request\n");
10657 + ieee->softmac_stats.tx_ass_rq++;
10658 + skb=ieee80211_association_req(beacon, ieee);
10659 + if (!skb)
10660 + ieee80211_associate_abort(ieee);
10661 + else{
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);
10666 + }
10667 + //dev_kfree_skb_any(skb);//edit by thomas
10668 + }
10669 +}
10670 +
10671 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
10672 +void ieee80211_associate_complete_wq(struct work_struct *work)
10673 +{
10674 + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
10675 +#else
10676 +void ieee80211_associate_complete_wq(struct ieee80211_device *ieee)
10677 +{
10678 +#endif
10679 + printk(KERN_INFO "Associated successfully\n");
10680 + if(ieee80211_is_54g(ieee->current_network) &&
10681 + (ieee->modulation & IEEE80211_OFDM_MODULATION)){
10682 +
10683 + ieee->rate = 540;
10684 + printk(KERN_INFO"Using G rates\n");
10685 + }else{
10686 + ieee->rate = 110;
10687 + printk(KERN_INFO"Using B rates\n");
10688 + }
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);
10694 +}
10695 +
10696 +void ieee80211_associate_complete(struct ieee80211_device *ieee)
10697 +{
10698 + int i;
10699 + del_timer_sync(&ieee->associate_timer);
10700 +
10701 + for(i = 0; i < 6; i++) {
10702 + //ieee->seq_ctrl[i] = 0;
10703 + }
10704 + ieee->state = IEEE80211_LINKED;
10705 + IEEE80211_DEBUG_MGMT("Successfully associated\n");
10706 +
10707 + queue_work(ieee->wq, &ieee->associate_complete_wq);
10708 +}
10709 +
10710 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
10711 +void ieee80211_associate_procedure_wq(struct work_struct *work)
10712 +{
10713 + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
10714 +#else
10715 +void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
10716 +{
10717 +#endif
10718 + ieee->sync_scan_hurryup = 1;
10719 + down(&ieee->wx_sem);
10720 +
10721 + if (ieee->data_hard_stop)
10722 + ieee->data_hard_stop(ieee->dev);
10723 +
10724 + ieee80211_stop_scan(ieee);
10725 + ieee->set_chan(ieee->dev, ieee->current_network.channel);
10726 +
10727 + ieee->associate_seq = 1;
10728 + ieee80211_associate_step1(ieee);
10729 +
10730 + up(&ieee->wx_sem);
10731 +}
10732 +#ifdef _RTL8187_EXT_PATCH_
10733 +// based on ieee80211_associate_procedure_wq
10734 +
10735 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
10736 +void ieee80211_ext_stop_scan_wq(struct work_struct *work)
10737 +{
10738 + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_stop_scan_wq);
10739 +#else
10740 +void ieee80211_ext_stop_scan_wq(struct ieee80211_device *ieee)
10741 +{
10742 +#endif
10743 + if (ieee->scanning == 0)
10744 + {
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) ) )
10747 + return;
10748 + }
10749 +
10750 + ieee->sync_scan_hurryup = 1;
10751 +
10752 + down(&ieee->wx_sem);
10753 +
10754 + // printk("@@@@@@@@@@ ieee80211_ext_stop_scan_wq\n");
10755 + if (ieee->data_hard_stop)
10756 + ieee->data_hard_stop(ieee->dev);
10757 +
10758 + ieee80211_stop_scan(ieee);
10759 +
10760 + // set channel
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));
10763 + else
10764 + ieee->set_chan(ieee->dev, ieee->current_network.channel);
10765 + //
10766 + up(&ieee->wx_sem);
10767 +}
10768 +
10769 +
10770 +void ieee80211_ext_send_11s_beacon(struct ieee80211_device *ieee)
10771 +{
10772 + #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
10773 + queue_work(ieee->wq, &ieee->ext_send_beacon_wq);
10774 + #else
10775 + schedule_task(&ieee->ext_send_beacon_wq);
10776 + #endif
10777 +
10778 +}
10779 +
10780 +#endif // _RTL8187_EXT_PATCH_
10781 +
10782 +inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
10783 +{
10784 + u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
10785 + int tmp_ssid_len = 0;
10786 +
10787 + short apset,ssidset,ssidbroad,apmatch,ssidmatch;
10788 +
10789 + /* we are interested in new new only if we are not associated
10790 + * and we are not associating / authenticating
10791 + */
10792 + if (ieee->state != IEEE80211_NOLINK)
10793 + return;
10794 +
10795 + if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
10796 + return;
10797 +
10798 + if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
10799 + return;
10800 +
10801 +
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.
10806 + */
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);
10811 +
10812 + if(ieee->current_network.ssid_len != net->ssid_len)
10813 + ssidmatch = 0;
10814 + else
10815 + ssidmatch = (0==strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
10816 +
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);
10819 +
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
10824 + */
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
10829 + */
10830 + (!apset && ssidset && ssidbroad && ssidmatch)
10831 + ){
10832 +
10833 +
10834 + /* if the essid is hidden replace it with the
10835 + * essid provided by the user.
10836 + */
10837 + if (!ssidbroad){
10838 + strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
10839 + tmp_ssid_len = ieee->current_network.ssid_len;
10840 + }
10841 + memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
10842 +
10843 + if (!ssidbroad){
10844 + strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
10845 + ieee->current_network.ssid_len = tmp_ssid_len;
10846 + }
10847 + printk(KERN_INFO"Linking with %s: channel is %d\n",ieee->current_network.ssid,ieee->current_network.channel);
10848 +
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);
10853 + }else{
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");
10858 + }else{
10859 + ieee->rate = 110;
10860 + printk(KERN_INFO"Using B rates\n");
10861 + }
10862 + ieee->state = IEEE80211_LINKED;
10863 + ieee->beinretry = false;
10864 + }
10865 +
10866 + }
10867 + }
10868 +
10869 +}
10870 +
10871 +void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
10872 +{
10873 + unsigned long flags;
10874 + struct ieee80211_network *target;
10875 +
10876 + spin_lock_irqsave(&ieee->lock, flags);
10877 + list_for_each_entry(target, &ieee->network_list, list) {
10878 +
10879 + /* if the state become different that NOLINK means
10880 + * we had found what we are searching for
10881 + */
10882 +
10883 + if (ieee->state != IEEE80211_NOLINK)
10884 + break;
10885 +
10886 + if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
10887 + ieee80211_softmac_new_net(ieee, target);
10888 + }
10889 +
10890 + spin_unlock_irqrestore(&ieee->lock, flags);
10891 +
10892 +}
10893 +
10894 +
10895 +static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
10896 +{
10897 + struct ieee80211_authentication *a;
10898 + u8 *t;
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);
10901 + return 0xcafe;
10902 + }
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);
10907 +
10908 + if(*(t++) == MFIE_TYPE_CHALLENGE){
10909 + *chlen = *(t++);
10910 + *challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC);
10911 + memcpy(*challenge, t, *chlen);
10912 + }
10913 + }
10914 +
10915 + return cpu_to_le16(a->status);
10916 +
10917 +}
10918 +
10919 +
10920 +int auth_rq_parse(struct sk_buff *skb,u8* dest)
10921 +{
10922 + struct ieee80211_authentication *a;
10923 +
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);
10926 + return -1;
10927 + }
10928 + a = (struct ieee80211_authentication*) skb->data;
10929 +
10930 + memcpy(dest,a->header.addr2, ETH_ALEN);
10931 +
10932 + if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
10933 + return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
10934 +
10935 + return WLAN_STATUS_SUCCESS;
10936 +}
10937 +
10938 +static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
10939 +{
10940 + u8 *tag;
10941 + u8 *skbend;
10942 + u8 *ssid=NULL;
10943 + u8 ssidlen = 0;
10944 +
10945 + struct ieee80211_hdr_3addr *header =
10946 + (struct ieee80211_hdr_3addr *) skb->data;
10947 +
10948 + if (skb->len < sizeof (struct ieee80211_hdr_3addr ))
10949 + return -1; /* corrupted */
10950 +
10951 + memcpy(src,header->addr2, ETH_ALEN);
10952 +
10953 + skbend = (u8*)skb->data + skb->len;
10954 +
10955 + tag = skb->data + sizeof (struct ieee80211_hdr_3addr );
10956 +
10957 + while (tag+1 < skbend){
10958 + if (*tag == 0){
10959 + ssid = tag+2;
10960 + ssidlen = *(tag+1);
10961 + break;
10962 + }
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 */
10966 + }
10967 +
10968 + //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
10969 + if (ssidlen == 0) return 1;
10970 +
10971 + if (!ssid) return 1; /* ssid not found in tagged param */
10972 + return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
10973 +
10974 +}
10975 +
10976 +int assoc_rq_parse(struct sk_buff *skb,u8* dest)
10977 +{
10978 + struct ieee80211_assoc_request_frame *a;
10979 +
10980 + if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
10981 + sizeof(struct ieee80211_info_element))) {
10982 +
10983 + IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
10984 + return -1;
10985 + }
10986 +
10987 + a = (struct ieee80211_assoc_request_frame*) skb->data;
10988 +
10989 + memcpy(dest,a->header.addr2,ETH_ALEN);
10990 +
10991 + return 0;
10992 +}
10993 +
10994 +static inline u16 assoc_parse(struct sk_buff *skb, int *aid)
10995 +{
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);
10999 + return 0xcafe;
11000 + }
11001 +
11002 + a = (struct ieee80211_assoc_response_frame*) skb->data;
11003 + *aid = le16_to_cpu(a->aid) & 0x3fff;
11004 + return le16_to_cpu(a->status);
11005 +}
11006 +
11007 +static inline void
11008 +ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
11009 +{
11010 + u8 dest[ETH_ALEN];
11011 +
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);
11019 + }
11020 +}
11021 +
11022 +inline void
11023 +ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
11024 +{
11025 + u8 dest[ETH_ALEN];
11026 + int status;
11027 + //IEEE80211DMESG("Rx probe");
11028 + ieee->softmac_stats.rx_auth_rq++;
11029 +
11030 + if ((status = auth_rq_parse(skb, dest))!= -1){
11031 + ieee80211_resp_to_auth(ieee, status, dest);
11032 + }
11033 + //DMESG("Dest is "MACSTR, MAC2STR(dest));
11034 +
11035 +}
11036 +
11037 + inline void
11038 +ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
11039 +{
11040 +
11041 + u8 dest[ETH_ALEN];
11042 + //unsigned long flags;
11043 +
11044 + ieee->softmac_stats.rx_ass_rq++;
11045 + if (assoc_rq_parse(skb,dest) != -1){
11046 + ieee80211_resp_to_assoc_rq(ieee, dest);
11047 + }
11048 +
11049 + printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
11050 + //FIXME
11051 + #if 0
11052 + spin_lock_irqsave(&ieee->lock,flags);
11053 + add_associate(ieee,dest);
11054 + spin_unlock_irqrestore(&ieee->lock,flags);
11055 + #endif
11056 +}
11057 +
11058 +
11059 +
11060 +void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
11061 +{
11062 +
11063 + struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
11064 +
11065 + if (buf)
11066 + softmac_ps_mgmt_xmit(buf, ieee);
11067 +
11068 +}
11069 +
11070 +
11071 +short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
11072 +{
11073 +#if 0
11074 + int timeout = ieee->ps_timeout;
11075 +#else
11076 + int timeout = 0;
11077 +#endif
11078 + u8 dtim;
11079 + /*if(ieee->ps == IEEE80211_PS_DISABLED ||
11080 + ieee->iw_mode != IW_MODE_INFRA ||
11081 + ieee->state != IEEE80211_LINKED)
11082 +
11083 + return 0;
11084 + */
11085 + dtim = ieee->current_network.dtim_data;
11086 + //printk("DTIM\n");
11087 +
11088 + if(!(dtim & IEEE80211_DTIM_VALID))
11089 + return 0;
11090 + else
11091 + timeout = ieee->current_network.beacon_interval;
11092 +
11093 + //printk("VALID\n");
11094 + ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
11095 +
11096 + if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
11097 + return 2;
11098 +
11099 + if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
11100 + return 0;
11101 +
11102 + if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
11103 + return 0;
11104 +
11105 + if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
11106 + (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
11107 + return 0;
11108 +#if 0
11109 + if(time_l){
11110 + *time_l = ieee->current_network.last_dtim_sta_time[0]
11111 + + (ieee->current_network.beacon_interval
11112 + * ieee->current_network.dtim_period) * 1000;
11113 + }
11114 +#else
11115 + if(time_l){
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);
11120 + }
11121 +
11122 +#endif
11123 + if(time_h){
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])
11126 + *time_h += 1;
11127 + }
11128 +
11129 + return 1;
11130 +
11131 +
11132 +}
11133 +
11134 +inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
11135 +{
11136 +
11137 + u32 th,tl;
11138 + short sleep;
11139 +
11140 + unsigned long flags,flags2;
11141 +
11142 + spin_lock_irqsave(&ieee->lock, flags);
11143 +
11144 + if((ieee->ps == IEEE80211_PS_DISABLED ||
11145 +
11146 + ieee->iw_mode != IW_MODE_INFRA ||
11147 + ieee->state != IEEE80211_LINKED)){
11148 +
11149 + //#warning CHECK_LOCK_HERE
11150 + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
11151 +
11152 + ieee80211_sta_wakeup(ieee, 1);
11153 +
11154 + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
11155 + }
11156 +
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 */
11160 + if(sleep == 0)
11161 + goto out;
11162 +
11163 + if(sleep == 1){
11164 +
11165 + if(ieee->sta_sleep == 1)
11166 + ieee->enter_sleep_state(ieee->dev,th,tl);
11167 +
11168 + else if(ieee->sta_sleep == 0){
11169 + // printk("send null 1\n");
11170 + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
11171 +
11172 + if(ieee->ps_is_queue_empty(ieee->dev)){
11173 +
11174 +
11175 + ieee->sta_sleep = 2;
11176 +
11177 + ieee->ps_request_tx_ack(ieee->dev);
11178 +
11179 + ieee80211_sta_ps_send_null_frame(ieee,1);
11180 +
11181 + ieee->ps_th = th;
11182 + ieee->ps_tl = tl;
11183 + }
11184 + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
11185 +
11186 + }
11187 +
11188 +
11189 + }else if(sleep == 2){
11190 +//#warning CHECK_LOCK_HERE
11191 + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
11192 +
11193 + // printk("send wakeup packet\n");
11194 + ieee80211_sta_wakeup(ieee,1);
11195 +
11196 + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
11197 + }
11198 +
11199 +out:
11200 + spin_unlock_irqrestore(&ieee->lock, flags);
11201 +
11202 +}
11203 +
11204 +void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
11205 +{
11206 + if(ieee->sta_sleep == 0){
11207 + if(nl){
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);
11211 + }
11212 + return;
11213 +
11214 + }
11215 +
11216 + if(ieee->sta_sleep == 1)
11217 + ieee->sta_wake_up(ieee->dev);
11218 +
11219 + ieee->sta_sleep = 0;
11220 +
11221 + if(nl){
11222 + ieee->ps_request_tx_ack(ieee->dev);
11223 + ieee80211_sta_ps_send_null_frame(ieee, 0);
11224 + }
11225 +}
11226 +
11227 +void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
11228 +{
11229 + unsigned long flags,flags2;
11230 +
11231 + spin_lock_irqsave(&ieee->lock, flags);
11232 + if(ieee->sta_sleep == 2){
11233 + /* Null frame with PS bit set */
11234 + if(success){
11235 +
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);
11239 + }
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
11242 + */
11243 + }
11244 + /* 21112005 - tx again null without PS bit if lost */
11245 + else {
11246 +
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);
11251 + }
11252 + }
11253 + spin_unlock_irqrestore(&ieee->lock, flags);
11254 +}
11255 +
11256 +inline int
11257 +ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
11258 + struct ieee80211_rx_stats *rx_stats, u16 type,
11259 + u16 stype)
11260 +{
11261 + struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
11262 + u16 errcode;
11263 + u8* challenge=NULL;
11264 + int chlen=0;
11265 + int aid=0;
11266 + struct ieee80211_assoc_response_frame *assoc_resp;
11267 + struct ieee80211_info_element *info_element;
11268 +
11269 + if(!ieee->proto_started)
11270 + return 0;
11271 +
11272 + if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
11273 + ieee->iw_mode == IW_MODE_INFRA &&
11274 + ieee->state == IEEE80211_LINKED))
11275 +
11276 + tasklet_schedule(&ieee->ps_task);
11277 +
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;
11281 +
11282 + switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
11283 +
11284 + case IEEE80211_STYPE_ASSOC_RESP:
11285 + case IEEE80211_STYPE_REASSOC_RESP:
11286 +
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))){
11293 + u16 left;
11294 +
11295 + ieee->state=IEEE80211_LINKED;
11296 + ieee->assoc_id = aid;
11297 + ieee->softmac_stats.rx_ass_ok++;
11298 +
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
11301 + {
11302 + goto associate_complete;
11303 + }
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);
11307 +
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!");
11311 + return 1;
11312 + }
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));
11326 +
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);
11333 +
11334 + }
11335 + //update info_element for current network
11336 + ieee->current_network.wmm_info = info_element->data[6];
11337 + }
11338 + break;
11339 + default:
11340 + //nothing to do at present!!!
11341 + break;
11342 + }
11343 +
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];
11348 + }
11349 + if(!ieee->init_wmmparam_flag) //legacy AP, reset the AC_xx_param register
11350 + {
11351 + queue_work(ieee->wq,&ieee->wmm_param_update_wq);
11352 + ieee->init_wmmparam_flag = 1;//indicate AC_xx_param upated since last associate
11353 + }
11354 +associate_complete:
11355 + ieee80211_associate_complete(ieee);
11356 + }else{
11357 + ieee->softmac_stats.rx_ass_err++;
11358 + IEEE80211_DEBUG_MGMT(
11359 + "Association response status code 0x%x\n",
11360 + errcode);
11361 + ieee80211_associate_abort(ieee);
11362 + }
11363 + }
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)
11366 + {
11367 + ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp(ieee, skb);
11368 + }
11369 +#endif
11370 + break;
11371 +
11372 + case IEEE80211_STYPE_ASSOC_REQ:
11373 + case IEEE80211_STYPE_REASSOC_REQ:
11374 +
11375 + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
11376 + ieee->iw_mode == IW_MODE_MASTER)
11377 +
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)
11381 + {
11382 + ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req(ieee, skb);
11383 + }
11384 +#endif
11385 + break;
11386 +
11387 + case IEEE80211_STYPE_AUTH:
11388 +
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) );
11393 +#endif
11394 + if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
11395 + if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
11396 + ieee->iw_mode == IW_MODE_INFRA){
11397 +
11398 + IEEE80211_DEBUG_MGMT("Received authentication response");
11399 +
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++;
11404 +
11405 + ieee80211_associate_step2(ieee);
11406 + }else{
11407 + ieee80211_auth_challenge(ieee, challenge, chlen);
11408 + }
11409 + }else{
11410 + ieee->softmac_stats.rx_auth_rs_err++;
11411 + IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
11412 + ieee80211_associate_abort(ieee);
11413 + }
11414 +
11415 + }else if (ieee->iw_mode == IW_MODE_MASTER){
11416 + ieee80211_rx_auth_rq(ieee, skb);
11417 + }
11418 + }
11419 + break;
11420 +
11421 + case IEEE80211_STYPE_PROBE_REQ:
11422 +
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))
11427 +
11428 + ieee80211_rx_probe_rq(ieee, skb);
11429 + break;
11430 +
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) ) ;
11437 +#endif
11438 + /* FIXME for now repeat all the association procedure
11439 + * both for disassociation and deauthentication
11440 + */
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++;
11447 +
11448 + //notify_wx_assoc_event(ieee); //YJ,del,080828, do not notify os here
11449 + queue_work(ieee->wq, &ieee->associate_procedure_wq);
11450 + }
11451 +
11452 + break;
11453 +
11454 + default:
11455 + return -1;
11456 + break;
11457 + }
11458 +
11459 + //dev_kfree_skb_any(skb);
11460 + return 0;
11461 +}
11462 +
11463 +
11464 +
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.
11482 + */
11483 +
11484 +void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
11485 +{
11486 +
11487 +
11488 + unsigned long flags;
11489 + int i;
11490 +#ifdef _RTL8187_EXT_PATCH_
11491 + int rate = ieee->rate;
11492 +#endif
11493 +
11494 + spin_lock_irqsave(&ieee->lock,flags);
11495 + #if 0
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);
11501 + err = 1;
11502 + goto exit;
11503 + }
11504 +
11505 + ieee->stats.tx_bytes+=skb->len;
11506 +
11507 +
11508 + txb=ieee80211_skb_to_txb(ieee,skb);
11509 +
11510 +
11511 + if(txb==NULL){
11512 + IEEE80211DMESG("WW: IEEE stack failed to provide txb");
11513 + //dev_kfree_skb_any(skb);
11514 + err = 1;
11515 + goto exit;
11516 + }
11517 + #endif
11518 +
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)
11521 + {
11522 + rate = ieee->ext_patch_ieee80211_softmac_xmit_get_rate(ieee, txb->fragments[0]);
11523 + }
11524 +#endif
11525 + /* called with 2nd parm 0, no tx mgmt lock required */
11526 + ieee80211_sta_wakeup(ieee,0);
11527 +
11528 + for(i = 0; i < txb->nr_frags; i++) {
11529 +
11530 + if (ieee->queue_stop){
11531 + ieee->tx_pending.txb = txb;
11532 + ieee->tx_pending.frag = i;
11533 + goto exit;
11534 + }else{
11535 + ieee->softmac_data_hard_start_xmit(
11536 + txb->fragments[i],
11537 +#ifdef _RTL8187_EXT_PATCH_
11538 + ieee->dev, rate);
11539 +#else
11540 + ieee->dev,ieee->rate);
11541 +#endif
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;
11546 + }
11547 + }
11548 +
11549 + ieee80211_txb_free(txb);
11550 +
11551 + exit:
11552 + spin_unlock_irqrestore(&ieee->lock,flags);
11553 +
11554 +}
11555 +
11556 +/* called with ieee->lock acquired */
11557 +void ieee80211_resume_tx(struct ieee80211_device *ieee)
11558 +{
11559 + int i;
11560 + for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
11561 +
11562 + if (ieee->queue_stop){
11563 + ieee->tx_pending.frag = i;
11564 + return;
11565 + }else{
11566 +
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;
11573 + }
11574 + }
11575 +
11576 +
11577 + ieee80211_txb_free(ieee->tx_pending.txb);
11578 + ieee->tx_pending.txb = NULL;
11579 +}
11580 +
11581 +
11582 +void ieee80211_reset_queue(struct ieee80211_device *ieee)
11583 +{
11584 + unsigned long flags;
11585 +
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;
11591 + }
11592 + ieee->queue_stop = 0;
11593 + spin_unlock_irqrestore(&ieee->lock,flags);
11594 +
11595 +}
11596 +
11597 +void ieee80211_wake_queue(struct ieee80211_device *ieee)
11598 +{
11599 +
11600 + unsigned long flags;
11601 + struct sk_buff *skb;
11602 + struct ieee80211_hdr_3addr *header;
11603 +
11604 + spin_lock_irqsave(&ieee->lock,flags);
11605 + if (! ieee->queue_stop) goto exit;
11606 +
11607 + ieee->queue_stop = 0;
11608 +
11609 + if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
11610 + while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
11611 +
11612 + header = (struct ieee80211_hdr_3addr *) skb->data;
11613 +
11614 + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
11615 +
11616 + if (ieee->seq_ctrl[0] == 0xFFF)
11617 + ieee->seq_ctrl[0] = 0;
11618 + else
11619 + ieee->seq_ctrl[0]++;
11620 +
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
11624 + }
11625 + }
11626 + if (!ieee->queue_stop && ieee->tx_pending.txb)
11627 + ieee80211_resume_tx(ieee);
11628 +
11629 + if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
11630 + ieee->softmac_stats.swtxawake++;
11631 + netif_wake_queue(ieee->dev);
11632 + }
11633 +
11634 +exit :
11635 + spin_unlock_irqrestore(&ieee->lock,flags);
11636 +}
11637 +
11638 +
11639 +void ieee80211_stop_queue(struct ieee80211_device *ieee)
11640 +{
11641 + //unsigned long flags;
11642 + //spin_lock_irqsave(&ieee->lock,flags);
11643 +
11644 + if (! netif_queue_stopped(ieee->dev)){
11645 + netif_stop_queue(ieee->dev);
11646 + ieee->softmac_stats.swtxstop++;
11647 + }
11648 + ieee->queue_stop = 1;
11649 + //spin_unlock_irqrestore(&ieee->lock,flags);
11650 +
11651 +}
11652 +
11653 +
11654 +inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
11655 +{
11656 +
11657 + get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
11658 +
11659 + /* an IBSS cell address must have the two less significant
11660 + * bits of the first byte = 2
11661 + */
11662 + ieee->current_network.bssid[0] &= ~0x01;
11663 + ieee->current_network.bssid[0] |= 0x02;
11664 +}
11665 +
11666 +/* called in user context only */
11667 +void ieee80211_start_master_bss(struct ieee80211_device *ieee)
11668 +{
11669 + ieee->assoc_id = 1;
11670 +
11671 + if (ieee->current_network.ssid_len == 0){
11672 + strncpy(ieee->current_network.ssid,
11673 + IEEE80211_DEFAULT_TX_ESSID,
11674 + IW_ESSID_MAX_SIZE);
11675 +
11676 + ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
11677 + ieee->ssid_set = 1;
11678 + }
11679 +
11680 + memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
11681 +
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);
11686 +
11687 + if (ieee->data_hard_resume)
11688 + ieee->data_hard_resume(ieee->dev);
11689 +
11690 + netif_carrier_on(ieee->dev);
11691 +}
11692 +
11693 +void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
11694 +{
11695 + if(ieee->raw_tx){
11696 +
11697 + if (ieee->data_hard_resume)
11698 + ieee->data_hard_resume(ieee->dev);
11699 +
11700 + netif_carrier_on(ieee->dev);
11701 + }
11702 +}
11703 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
11704 +void ieee80211_start_ibss_wq(struct work_struct *work)
11705 +{
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);
11708 +#else
11709 +void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
11710 +{
11711 +#endif
11712 +
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
11719 + */
11720 +
11721 + down(&ieee->wx_sem);
11722 +
11723 +
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;
11728 + }
11729 +
11730 + /* check if we have this cell in our network list */
11731 + ieee80211_softmac_check_all_nets(ieee);
11732 +
11733 +#ifdef ENABLE_DOT11D
11734 + if(ieee->state == IEEE80211_NOLINK)
11735 + ieee->current_network.channel = 10;
11736 +#endif
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
11749 + * associated.
11750 + */
11751 + if (ieee->state == IEEE80211_NOLINK)
11752 + ieee80211_start_scan_syncro(ieee);
11753 +
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);
11759 +
11760 + if(ieee->modulation & IEEE80211_CCK_MODULATION){
11761 +
11762 + ieee->current_network.rates_len = 4;
11763 +
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;
11768 +
11769 + }else
11770 + ieee->current_network.rates_len = 0;
11771 +
11772 + if(ieee->modulation & IEEE80211_OFDM_MODULATION){
11773 + ieee->current_network.rates_ex_len = 8;
11774 +
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;
11783 +
11784 + ieee->rate = 540;
11785 + }else{
11786 + ieee->current_network.rates_ex_len = 0;
11787 + ieee->rate = 110;
11788 + }
11789 +
11790 + // By default, WMM function will be disabled in IBSS mode
11791 + ieee->current_network.QoS_Enable = 0;
11792 +
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;
11797 +
11798 + }
11799 +
11800 + ieee->state = IEEE80211_LINKED;
11801 + ieee->set_chan(ieee->dev, ieee->current_network.channel);
11802 + ieee->link_change(ieee->dev);
11803 +
11804 + notify_wx_assoc_event(ieee);
11805 +
11806 + ieee80211_start_send_beacons(ieee);
11807 + printk(KERN_WARNING "after sending beacon packet!\n");
11808 +
11809 + if (ieee->data_hard_resume)
11810 + ieee->data_hard_resume(ieee->dev);
11811 +
11812 + netif_carrier_on(ieee->dev);
11813 +
11814 + up(&ieee->wx_sem);
11815 +}
11816 +inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
11817 +{
11818 + queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 100);
11819 +}
11820 +
11821 +/* this is called only in user context, with wx_sem held */
11822 +void ieee80211_start_bss(struct ieee80211_device *ieee)
11823 +{
11824 + unsigned long flags;
11825 +#ifdef ENABLE_DOT11D
11826 + //
11827 + // Ref: 802.11d 11.1.3.3
11828 + // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
11829 + //
11830 + if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
11831 + {
11832 + if(! ieee->bGlobalDomain)
11833 + {
11834 + return;
11835 + }
11836 + }
11837 +#endif
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.
11842 + */
11843 + ieee80211_softmac_check_all_nets(ieee);
11844 +
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
11851 + */
11852 + spin_lock_irqsave(&ieee->lock, flags);
11853 +
11854 +//#ifdef ENABLE_IPS
11855 +// printk("start bss ENABLE_IPS\n");
11856 +//#else
11857 + if (ieee->state == IEEE80211_NOLINK){
11858 + ieee->actscanning = true;
11859 + ieee80211_start_scan(ieee);
11860 + }
11861 +//#endif
11862 + spin_unlock_irqrestore(&ieee->lock, flags);
11863 +}
11864 +
11865 +/* called only in userspace context */
11866 +void ieee80211_disassociate(struct ieee80211_device *ieee)
11867 +{
11868 + netif_carrier_off(ieee->dev);
11869 +
11870 + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
11871 + ieee80211_reset_queue(ieee);
11872 +
11873 + if (ieee->data_hard_stop)
11874 + ieee->data_hard_stop(ieee->dev);
11875 +
11876 +#ifdef ENABLE_DOT11D
11877 + if(IS_DOT11D_ENABLE(ieee))
11878 + Dot11d_Reset(ieee);
11879 +#endif
11880 + ieee->state = IEEE80211_NOLINK;
11881 + ieee->link_change(ieee->dev);
11882 + notify_wx_assoc_event(ieee);
11883 +
11884 +}
11885 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
11886 +void ieee80211_associate_retry_wq(struct work_struct *work)
11887 +{
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);
11890 +#else
11891 +void ieee80211_associate_retry_wq(struct ieee80211_device *ieee)
11892 +{
11893 +#endif
11894 + unsigned long flags;
11895 + down(&ieee->wx_sem);
11896 + if(!ieee->proto_started)
11897 + goto exit;
11898 + if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
11899 + goto exit;
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.
11912 + */
11913 + ieee->state = IEEE80211_NOLINK;
11914 + ieee->beinretry = true;
11915 + ieee80211_softmac_check_all_nets(ieee);
11916 +
11917 + spin_lock_irqsave(&ieee->lock, flags);
11918 +
11919 + if(ieee->state == IEEE80211_NOLINK){
11920 + ieee->beinretry = false;
11921 + ieee->actscanning = true;
11922 + ieee80211_start_scan(ieee);
11923 + }
11924 + //YJ,add,080828, notify os here
11925 + if(ieee->state == IEEE80211_NOLINK)
11926 + {
11927 + notify_wx_assoc_event(ieee);
11928 + }
11929 + //YJ,add,080828,end
11930 + spin_unlock_irqrestore(&ieee->lock, flags);
11931 +
11932 +exit:
11933 + up(&ieee->wx_sem);
11934 +}
11935 +
11936 +struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
11937 +{
11938 + u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
11939 +
11940 + struct sk_buff *skb = NULL;
11941 + struct ieee80211_probe_response *b;
11942 +
11943 +//rz
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));
11947 + else
11948 + skb = ieee80211_probe_resp(ieee, broadcast_addr);
11949 +#else
11950 + skb = ieee80211_probe_resp(ieee, broadcast_addr);
11951 +#endif
11952 +//
11953 + if (!skb)
11954 + return NULL;
11955 +
11956 + b = (struct ieee80211_probe_response *) skb->data;
11957 + b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
11958 +
11959 + return skb;
11960 +
11961 +}
11962 +
11963 +struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
11964 +{
11965 + struct sk_buff *skb;
11966 + struct ieee80211_probe_response *b;
11967 +
11968 + skb = ieee80211_get_beacon_(ieee);
11969 + if(!skb)
11970 + return NULL;
11971 +
11972 + b = (struct ieee80211_probe_response *) skb->data;
11973 + b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
11974 +
11975 + if (ieee->seq_ctrl[0] == 0xFFF)
11976 + ieee->seq_ctrl[0] = 0;
11977 + else
11978 + ieee->seq_ctrl[0]++;
11979 +
11980 + return skb;
11981 +}
11982 +
11983 +void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
11984 +{
11985 + ieee->sync_scan_hurryup = 1;
11986 + down(&ieee->wx_sem);
11987 + ieee80211_stop_protocol(ieee);
11988 + up(&ieee->wx_sem);
11989 +}
11990 +
11991 +
11992 +void ieee80211_stop_protocol(struct ieee80211_device *ieee)
11993 +{
11994 + if (!ieee->proto_started)
11995 + return;
11996 +
11997 + ieee->proto_started = 0;
11998 +
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);
12007 +#endif
12008 +#endif // _RTL8187_EXT_PATCH_
12009 +
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);
12013 + }
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);
12018 +
12019 + ieee80211_disassociate(ieee);
12020 +}
12021 +
12022 +void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
12023 +{
12024 + ieee->sync_scan_hurryup = 0;
12025 + down(&ieee->wx_sem);
12026 + ieee80211_start_protocol(ieee);
12027 + up(&ieee->wx_sem);
12028 +}
12029 +
12030 +void ieee80211_start_protocol(struct ieee80211_device *ieee)
12031 +{
12032 + short ch = 0;
12033 + int i = 0;
12034 +
12035 + if (ieee->proto_started)
12036 + return;
12037 +
12038 + ieee->proto_started = 1;
12039 +
12040 + if (ieee->current_network.channel == 0){
12041 + do{
12042 + ch++;
12043 + if (ch > MAX_CHANNEL_NUMBER)
12044 + return; /* no channel found */
12045 +
12046 +#ifdef ENABLE_DOT11D
12047 + }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
12048 +#else
12049 + }while(!ieee->channel_map[ch]);
12050 +#endif
12051 +
12052 + ieee->current_network.channel = ch;
12053 + }
12054 +
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);
12058 +
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;
12063 + }
12064 +
12065 + ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
12066 +
12067 +
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 ??
12072 + */
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);
12079 + break;
12080 +
12081 + case IW_MODE_ADHOC:
12082 + ieee80211_start_ibss(ieee);
12083 + break;
12084 +
12085 + case IW_MODE_MASTER:
12086 + ieee80211_start_master_bss(ieee);
12087 + break;
12088 +
12089 + case IW_MODE_MONITOR:
12090 + ieee80211_start_monitor_mode(ieee);
12091 + break;
12092 +
12093 + default:
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);
12100 +#endif
12101 + // By default, WMM function will be disabled in
12102 + // EXTENSION mode
12103 + ieee->current_network.QoS_Enable = 0;
12104 +
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;
12119 + }else
12120 + ieee->current_network.rates_len = 0;
12121 +
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;
12149 + }else{
12150 + ieee->current_network.rates_ex_len = 0;
12151 + ieee->rate = 110;
12152 + }
12153 +
12154 + /*
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);
12159 +
12160 + spin_unlock_irqrestore(&ieee->lock, flags);
12161 + */
12162 + memcpy(ieee->current_network.bssid, ieee->dev->dev_addr,\
12163 + ETH_ALEN);
12164 + ieee->link_change(ieee->dev);
12165 + notify_wx_assoc_event(ieee);
12166 +
12167 + if (ieee->data_hard_resume)
12168 + ieee->data_hard_resume(ieee->dev);
12169 +
12170 + netif_carrier_on(ieee->dev);
12171 + } else {
12172 + ieee->iw_mode = IW_MODE_INFRA;
12173 + ieee80211_start_bss(ieee);
12174 + }
12175 +#else
12176 + ieee->iw_mode = IW_MODE_INFRA;
12177 + ieee80211_start_bss(ieee);
12178 +
12179 +#endif
12180 + break;
12181 + }
12182 +}
12183 +
12184 +
12185 +#define DRV_NAME "Ieee80211"
12186 +void ieee80211_softmac_init(struct ieee80211_device *ieee)
12187 +{
12188 + int i;
12189 + memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
12190 +
12191 + ieee->state = IEEE80211_NOLINK;
12192 + ieee->sync_scan_hurryup = 0;
12193 + for(i = 0; i < 5; i++) {
12194 + ieee->seq_ctrl[i] = 0;
12195 + }
12196 +
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;
12205 + ieee->rate = 3;
12206 +//#ifdef ENABLE_LPS
12207 + ieee->ps = IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST;
12208 +//#else
12209 +// ieee->ps = IEEE80211_PS_DISABLED;
12210 +//#endif
12211 + ieee->sta_sleep = 0;
12212 +//by amy
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;
12222 +//by amy
12223 +#ifdef _RTL8187_EXT_PATCH_
12224 + ieee->iw_ext_mode = 999;
12225 +#endif
12226 +
12227 + init_mgmt_queue(ieee);
12228 +#if 0
12229 + init_timer(&ieee->scan_timer);
12230 + ieee->scan_timer.data = (unsigned long)ieee;
12231 + ieee->scan_timer.function = ieee80211_softmac_scan_cb;
12232 +#endif
12233 + ieee->tx_pending.txb = NULL;
12234 +
12235 + init_timer(&ieee->associate_timer);
12236 + ieee->associate_timer.data = (unsigned long)ieee;
12237 + ieee->associate_timer.function = ieee80211_associate_abort_cb;
12238 +
12239 + init_timer(&ieee->beacon_timer);
12240 + ieee->beacon_timer.data = (unsigned long) ieee;
12241 + ieee->beacon_timer.function = ieee80211_send_beacon_cb;
12242 +
12243 +#ifdef PF_SYNCTHREAD
12244 + ieee->wq = create_workqueue(DRV_NAME,0);
12245 +#else
12246 + ieee->wq = create_workqueue(DRV_NAME);
12247 +#endif
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_
12262 +#else
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);
12274 +#endif
12275 +#endif
12276 + sema_init(&ieee->wx_sem, 1);
12277 + sema_init(&ieee->scan_sem, 1);
12278 +
12279 + spin_lock_init(&ieee->mgmt_tx_lock);
12280 + spin_lock_init(&ieee->beacon_lock);
12281 +
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);
12287 +#endif
12288 +}
12289 +
12290 +void ieee80211_softmac_free(struct ieee80211_device *ieee)
12291 +{
12292 + down(&ieee->wx_sem);
12293 +
12294 + del_timer_sync(&ieee->associate_timer);
12295 + cancel_delayed_work(&ieee->associate_retry_wq);
12296 +
12297 +
12298 + //add for RF power on power of by lizhaoming 080512
12299 + cancel_delayed_work(&ieee->GPIOChangeRFWorkItem);
12300 +
12301 +#ifdef _RTL8187_EXT_PATCH_
12302 + cancel_delayed_work(&ieee->ext_stop_scan_wq);
12303 + cancel_delayed_work(&ieee->ext_send_beacon_wq);
12304 +#endif
12305 + destroy_workqueue(ieee->wq);
12306 +#ifdef ENABLE_DOT11D
12307 + if(NULL != ieee->pDot11dInfo)
12308 + kfree(ieee->pDot11dInfo);
12309 +#endif
12310 + up(&ieee->wx_sem);
12311 +}
12312 +
12313 +/********************************************************
12314 + * Start of WPA code. *
12315 + * this is stolen from the ipw2200 driver *
12316 + ********************************************************/
12317 +
12318 +
12319 +static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
12320 +{
12321 + /* This is called when wpa_supplicant loads and closes the driver
12322 + * interface. */
12323 + printk("%s WPA\n",value ? "enabling" : "disabling");
12324 + ieee->wpa_enabled = value;
12325 + return 0;
12326 +}
12327 +
12328 +
12329 +void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
12330 +{
12331 + /* make sure WPA is enabled */
12332 + ieee80211_wpa_enable(ieee, 1);
12333 +
12334 + ieee80211_disassociate(ieee);
12335 +}
12336 +
12337 +
12338 +static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
12339 +{
12340 +
12341 + int ret = 0;
12342 +
12343 + switch (command) {
12344 + case IEEE_MLME_STA_DEAUTH:
12345 + // silently ignore
12346 + break;
12347 +
12348 + case IEEE_MLME_STA_DISASSOC:
12349 + ieee80211_disassociate(ieee);
12350 + break;
12351 +
12352 + default:
12353 + printk("Unknown MLME request: %d\n", command);
12354 + ret = -EOPNOTSUPP;
12355 + }
12356 +
12357 + return ret;
12358 +}
12359 +
12360 +
12361 +static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
12362 + struct ieee_param *param, int plen)
12363 +{
12364 + u8 *buf;
12365 +
12366 + if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
12367 + (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
12368 + return -EINVAL;
12369 +
12370 + if (param->u.wpa_ie.len) {
12371 + buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
12372 + if (buf == NULL)
12373 + return -ENOMEM;
12374 +
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;
12379 + } else {
12380 + kfree(ieee->wpa_ie);
12381 + ieee->wpa_ie = NULL;
12382 + ieee->wpa_ie_len = 0;
12383 + }
12384 +
12385 + ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
12386 + return 0;
12387 +}
12388 +
12389 +#define AUTH_ALG_OPEN_SYSTEM 0x1
12390 +#define AUTH_ALG_SHARED_KEY 0x2
12391 +
12392 +static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
12393 +{
12394 +
12395 + struct ieee80211_security sec = {
12396 + .flags = SEC_AUTH_MODE,
12397 + };
12398 + int ret = 0;
12399 +
12400 + if (value & AUTH_ALG_SHARED_KEY) {
12401 + sec.auth_mode = WLAN_AUTH_SHARED_KEY;
12402 + ieee->open_wep = 0;
12403 + } else {
12404 + sec.auth_mode = WLAN_AUTH_OPEN;
12405 + ieee->open_wep = 1;
12406 + }
12407 +
12408 + if (ieee->set_security)
12409 + ieee->set_security(ieee->dev, &sec);
12410 + else
12411 + ret = -EOPNOTSUPP;
12412 +
12413 + return ret;
12414 +}
12415 +
12416 +static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
12417 +{
12418 + int ret=0;
12419 + unsigned long flags;
12420 +
12421 + switch (name) {
12422 + case IEEE_PARAM_WPA_ENABLED:
12423 + ret = ieee80211_wpa_enable(ieee, value);
12424 + break;
12425 +
12426 + case IEEE_PARAM_TKIP_COUNTERMEASURES:
12427 + ieee->tkip_countermeasures=value;
12428 + break;
12429 +
12430 + case IEEE_PARAM_DROP_UNENCRYPTED: {
12431 + /* HACK:
12432 + *
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
12440 + * be set.
12441 + */
12442 + struct ieee80211_security sec = {
12443 + .flags = SEC_ENABLED,
12444 + .enabled = value,
12445 + };
12446 + ieee->drop_unencrypted = value;
12447 + /* We only change SEC_LEVEL for open mode. Others
12448 + * are set by ipw_wpa_set_encryption.
12449 + */
12450 + if (!value) {
12451 + sec.flags |= SEC_LEVEL;
12452 + sec.level = SEC_LEVEL_0;
12453 + }
12454 + else {
12455 + sec.flags |= SEC_LEVEL;
12456 + sec.level = SEC_LEVEL_1;
12457 + }
12458 + if (ieee->set_security)
12459 + ieee->set_security(ieee->dev, &sec);
12460 + break;
12461 + }
12462 +
12463 + case IEEE_PARAM_PRIVACY_INVOKED:
12464 + ieee->privacy_invoked=value;
12465 + break;
12466 +
12467 + case IEEE_PARAM_AUTH_ALGS:
12468 + ret = ieee80211_wpa_set_auth_algs(ieee, value);
12469 + break;
12470 +
12471 + case IEEE_PARAM_IEEE_802_1X:
12472 + ieee->ieee802_1x=value;
12473 + break;
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);
12481 + break;
12482 +
12483 + default:
12484 + printk("Unknown WPA param: %d\n",name);
12485 + ret = -EOPNOTSUPP;
12486 + }
12487 +
12488 + return ret;
12489 +}
12490 +
12491 +/* implementation borrowed from hostap driver */
12492 +
12493 +static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
12494 + struct ieee_param *param, int param_len)
12495 +{
12496 + int ret = 0;
12497 +
12498 + struct ieee80211_crypto_ops *ops;
12499 + struct ieee80211_crypt_data **crypt;
12500 +
12501 + struct ieee80211_security sec = {
12502 + .flags = 0,
12503 + };
12504 +
12505 + param->u.crypt.err = 0;
12506 + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
12507 +
12508 + if (param_len !=
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);
12513 + return -EINVAL;
12514 + }
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)
12519 + return -EINVAL;
12520 + crypt = &ieee->crypt[param->u.crypt.idx];
12521 + } else {
12522 + return -EINVAL;
12523 + }
12524 +
12525 + if (strcmp(param->u.crypt.alg, "none") == 0) {
12526 + if (crypt) {
12527 + sec.enabled = 0;
12528 + // FIXME FIXME
12529 + //sec.encrypt = 0;
12530 + sec.level = SEC_LEVEL_0;
12531 + sec.flags |= SEC_ENABLED | SEC_LEVEL;
12532 + ieee80211_crypt_delayed_deinit(ieee, crypt);
12533 + }
12534 + goto done;
12535 + }
12536 + sec.enabled = 1;
12537 +// FIXME FIXME
12538 +// sec.encrypt = 1;
12539 + sec.flags |= SEC_ENABLED;
12540 +
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;
12545 +
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);
12556 + }
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;
12560 + ret = -EINVAL;
12561 + goto done;
12562 + }
12563 +
12564 + if (*crypt == NULL || (*crypt)->ops != ops) {
12565 + struct ieee80211_crypt_data *new_crypt;
12566 +
12567 + ieee80211_crypt_delayed_deinit(ieee, crypt);
12568 +
12569 + new_crypt = (struct ieee80211_crypt_data *)
12570 + kmalloc(sizeof(*new_crypt), GFP_KERNEL);
12571 + if (new_crypt == NULL) {
12572 + ret = -ENOMEM;
12573 + goto done;
12574 + }
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);
12580 +
12581 + if (new_crypt->priv == NULL) {
12582 + kfree(new_crypt);
12583 + param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
12584 + ret = -EINVAL;
12585 + goto done;
12586 + }
12587 +
12588 + *crypt = new_crypt;
12589 + }
12590 +
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;
12597 + ret = -EINVAL;
12598 + goto done;
12599 + }
12600 +
12601 + skip_host_crypt:
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;
12606 + } else
12607 + sec.flags &= ~SEC_ACTIVE_KEY;
12608 +
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);
12615 +
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;
12625 + }
12626 + }
12627 + done:
12628 + if (ieee->set_security)
12629 + ieee->set_security(ieee->dev, &sec);
12630 +
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;
12642 + return -EINVAL;
12643 + }
12644 +
12645 + return ret;
12646 +}
12647 +
12648 +int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
12649 +{
12650 + struct ieee_param *param;
12651 + int ret=0;
12652 +
12653 + down(&ieee->wx_sem);
12654 + //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
12655 +
12656 + if (p->length < sizeof(struct ieee_param) || !p->pointer){
12657 + ret = -EINVAL;
12658 + goto out;
12659 + }
12660 +
12661 + param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
12662 + if (param == NULL){
12663 + ret = -ENOMEM;
12664 + goto out;
12665 + }
12666 + if (copy_from_user(param, p->pointer, p->length)) {
12667 + kfree(param);
12668 + ret = -EFAULT;
12669 + goto out;
12670 + }
12671 +
12672 + switch (param->cmd) {
12673 +
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);
12677 + break;
12678 +
12679 + case IEEE_CMD_SET_WPA_IE:
12680 + ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
12681 + break;
12682 +
12683 + case IEEE_CMD_SET_ENCRYPTION:
12684 + ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
12685 + break;
12686 +
12687 + case IEEE_CMD_MLME:
12688 + ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
12689 + param->u.mlme.reason_code);
12690 + break;
12691 +
12692 + default:
12693 + printk("Unknown WPA supplicant request: %d\n",param->cmd);
12694 + ret = -EOPNOTSUPP;
12695 + break;
12696 + }
12697 +
12698 + if (ret == 0 && copy_to_user(p->pointer, param, p->length))
12699 + ret = -EFAULT;
12700 +
12701 + kfree(param);
12702 +out:
12703 + up(&ieee->wx_sem);
12704 +
12705 + return ret;
12706 +}
12707 +
12708 +void notify_wx_assoc_event(struct ieee80211_device *ieee)
12709 +{
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);
12714 + else
12715 + memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
12716 + wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
12717 +}
12718 +
12719 +
12720 +#if 0
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);
12752 +#endif
12753 --- /dev/null
12754 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
12755 @@ -0,0 +1,602 @@
12756 +/* IEEE 802.11 SoftMAC layer
12757 + * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
12758 + *
12759 + * Mostly extracted from the rtl8180-sa2400 driver for the
12760 + * in-kernel generic ieee802.11 stack.
12761 + *
12762 + * Some pieces of code might be stolen from ipw2100 driver
12763 + * copyright of who own it's copyright ;-)
12764 + *
12765 + * PS wx handler mostly stolen from hostap, copyright who
12766 + * own it's copyright ;-)
12767 + *
12768 + * released under the GPL
12769 + */
12770 +
12771 +
12772 +#include "ieee80211.h"
12773 +
12774 +/* FIXME: add A freqs */
12775 +
12776 +const long ieee80211_wlan_frequencies[] = {
12777 + 2412, 2417, 2422, 2427,
12778 + 2432, 2437, 2442, 2447,
12779 + 2452, 2457, 2462, 2467,
12780 + 2472, 2484
12781 +};
12782 +
12783 +
12784 +int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
12785 + union iwreq_data *wrqu, char *b)
12786 +{
12787 + int ret;
12788 + struct iw_freq *fwrq = & wrqu->freq;
12789 +// printk("in %s\n",__FUNCTION__);
12790 + down(&ieee->wx_sem);
12791 +
12792 + if(ieee->iw_mode == IW_MODE_INFRA){
12793 + ret = -EOPNOTSUPP;
12794 + goto out;
12795 + }
12796 +
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;
12802 + int c = 0;
12803 +
12804 + while ((c < 14) && (f != ieee80211_wlan_frequencies[c]))
12805 + c++;
12806 +
12807 + /* hack to fall through */
12808 + fwrq->e = 0;
12809 + fwrq->m = c + 1;
12810 + }
12811 + }
12812 +
12813 + if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){
12814 + ret = -EOPNOTSUPP;
12815 + goto out;
12816 +
12817 + }else { /* Set the channel */
12818 +
12819 +
12820 + ieee->current_network.channel = fwrq->m;
12821 + ieee->set_chan(ieee->dev, ieee->current_network.channel);
12822 +
12823 + if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
12824 + if(ieee->state == IEEE80211_LINKED){
12825 +
12826 + ieee80211_stop_send_beacons(ieee);
12827 + ieee80211_start_send_beacons(ieee);
12828 + }
12829 + }
12830 +
12831 + ret = 0;
12832 +out:
12833 + up(&ieee->wx_sem);
12834 + return ret;
12835 +}
12836 +
12837 +
12838 +int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
12839 + struct iw_request_info *a,
12840 + union iwreq_data *wrqu, char *b)
12841 +{
12842 + struct iw_freq *fwrq = & wrqu->freq;
12843 +
12844 + if (ieee->current_network.channel == 0)
12845 + return -1;
12846 +
12847 + fwrq->m = ieee->current_network.channel;
12848 + fwrq->e = 0;
12849 +
12850 + return 0;
12851 +}
12852 +
12853 +int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
12854 + struct iw_request_info *info,
12855 + union iwreq_data *wrqu, char *extra)
12856 +{
12857 + unsigned long flags;
12858 +
12859 + wrqu->ap_addr.sa_family = ARPHRD_ETHER;
12860 +
12861 + if (ieee->iw_mode == IW_MODE_MONITOR)
12862 + return -1;
12863 +
12864 + /* We want avoid to give to the user inconsistent infos*/
12865 + spin_lock_irqsave(&ieee->lock, flags);
12866 +
12867 + if (ieee->state != IEEE80211_LINKED &&
12868 + ieee->state != IEEE80211_LINKED_SCANNING &&
12869 + ieee->wap_set == 0)
12870 +
12871 + memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
12872 + else
12873 + memcpy(wrqu->ap_addr.sa_data,
12874 + ieee->current_network.bssid, ETH_ALEN);
12875 +
12876 + spin_unlock_irqrestore(&ieee->lock, flags);
12877 +
12878 + return 0;
12879 +}
12880 +
12881 +
12882 +int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
12883 + struct iw_request_info *info,
12884 + union iwreq_data *awrq,
12885 + char *extra)
12886 +{
12887 +
12888 + int ret = 0;
12889 + u8 zero[] = {0,0,0,0,0,0};
12890 + unsigned long flags;
12891 +
12892 + short ifup = ieee->proto_started;//dev->flags & IFF_UP;
12893 + struct sockaddr *temp = (struct sockaddr *)awrq;
12894 +
12895 + //printk("=======Set WAP:");
12896 + ieee->sync_scan_hurryup = 1;
12897 +
12898 + down(&ieee->wx_sem);
12899 + /* use ifconfig hw ether */
12900 + if (ieee->iw_mode == IW_MODE_MASTER){
12901 + ret = -1;
12902 + goto out;
12903 + }
12904 +
12905 + if (temp->sa_family != ARPHRD_ETHER){
12906 + ret = -EINVAL;
12907 + goto out;
12908 + }
12909 +
12910 + if (ifup)
12911 + ieee80211_stop_protocol(ieee);
12912 +
12913 + /* just to avoid to give inconsistent infos in the
12914 + * get wx method. not really needed otherwise
12915 + */
12916 + spin_lock_irqsave(&ieee->lock, flags);
12917 +
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]);
12921 +
12922 + spin_unlock_irqrestore(&ieee->lock, flags);
12923 +
12924 + if (ifup)
12925 + ieee80211_start_protocol(ieee);
12926 +
12927 +out:
12928 + up(&ieee->wx_sem);
12929 + return ret;
12930 +}
12931 +
12932 + int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b)
12933 +{
12934 + int len,ret = 0;
12935 + unsigned long flags;
12936 +
12937 + if (ieee->iw_mode == IW_MODE_MONITOR)
12938 + return -1;
12939 +
12940 + /* We want avoid to give to the user inconsistent infos*/
12941 + spin_lock_irqsave(&ieee->lock, flags);
12942 +
12943 + if (ieee->current_network.ssid[0] == '\0' ||
12944 + ieee->current_network.ssid_len == 0){
12945 + ret = -1;
12946 + goto out;
12947 + }
12948 +
12949 + if (ieee->state != IEEE80211_LINKED &&
12950 + ieee->state != IEEE80211_LINKED_SCANNING &&
12951 + ieee->ssid_set == 0){
12952 + ret = -1;
12953 + goto out;
12954 + }
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;
12959 +
12960 +out:
12961 + spin_unlock_irqrestore(&ieee->lock, flags);
12962 +
12963 + return ret;
12964 +
12965 +}
12966 +
12967 +int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
12968 + struct iw_request_info *info,
12969 + union iwreq_data *wrqu, char *extra)
12970 +{
12971 +
12972 + u32 target_rate = wrqu->bitrate.value;
12973 +
12974 + //added by lizhaoming for auto mode
12975 + if(target_rate == -1){
12976 + ieee->rate = 110;
12977 + } else {
12978 + ieee->rate = target_rate/100000;
12979 + }
12980 + //FIXME: we might want to limit rate also in management protocols.
12981 + return 0;
12982 +}
12983 +
12984 +
12985 +
12986 +int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
12987 + struct iw_request_info *info,
12988 + union iwreq_data *wrqu, char *extra)
12989 +{
12990 +
12991 + wrqu->bitrate.value = ieee->rate * 100000;
12992 +
12993 + return 0;
12994 +}
12995 +
12996 +int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
12997 + union iwreq_data *wrqu, char *b)
12998 +{
12999 +
13000 + ieee->sync_scan_hurryup = 1;
13001 +
13002 + down(&ieee->wx_sem);
13003 +
13004 + if (wrqu->mode == ieee->iw_mode)
13005 + goto out;
13006 +
13007 + if (wrqu->mode == IW_MODE_MONITOR){
13008 +
13009 + ieee->dev->type = ARPHRD_IEEE80211;
13010 + }else{
13011 + ieee->dev->type = ARPHRD_ETHER;
13012 + }
13013 +
13014 + if (!ieee->proto_started){
13015 + ieee->iw_mode = wrqu->mode;
13016 + }else{
13017 + ieee80211_stop_protocol(ieee);
13018 + ieee->iw_mode = wrqu->mode;
13019 + ieee80211_start_protocol(ieee);
13020 + }
13021 +
13022 +out:
13023 + up(&ieee->wx_sem);
13024 + return 0;
13025 +}
13026 +
13027 +
13028 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
13029 +void ieee80211_wx_sync_scan_wq(struct work_struct *work)
13030 +{
13031 + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
13032 +#else
13033 +void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
13034 +{
13035 +#endif
13036 +//void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
13037 +//{
13038 + short chan;
13039 +
13040 + chan = ieee->current_network.channel;
13041 +
13042 + netif_carrier_off(ieee->dev);
13043 +
13044 + if (ieee->data_hard_stop)
13045 + ieee->data_hard_stop(ieee->dev);
13046 +
13047 + ieee80211_stop_send_beacons(ieee);
13048 +
13049 + ieee->state = IEEE80211_LINKED_SCANNING;
13050 + ieee->link_change(ieee->dev);
13051 +
13052 + ieee80211_start_scan_syncro(ieee);
13053 +
13054 + ieee->set_chan(ieee->dev, chan);
13055 +
13056 + ieee->state = IEEE80211_LINKED;
13057 + ieee->link_change(ieee->dev);
13058 +
13059 + if (ieee->data_hard_resume)
13060 + ieee->data_hard_resume(ieee->dev);
13061 +
13062 + if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
13063 + ieee80211_start_send_beacons(ieee);
13064 +
13065 + netif_carrier_on(ieee->dev);
13066 +
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
13070 +
13071 + up(&ieee->wx_sem);
13072 +
13073 +}
13074 +
13075 +int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
13076 + union iwreq_data *wrqu, char *b)
13077 +{
13078 + int ret = 0;
13079 +
13080 + down(&ieee->wx_sem);
13081 +
13082 + if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){
13083 + ret = -1;
13084 + goto out;
13085 + }
13086 + //YJ,add,080828
13087 + //In prevent of lossing ping packet during scanning
13088 + //ieee80211_sta_ps_send_null_frame(ieee, true);
13089 + //YJ,add,080828,end
13090 +
13091 + if ( ieee->state == IEEE80211_LINKED){
13092 + queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
13093 + /* intentionally forget to up sem */
13094 + return 0;
13095 + }
13096 +
13097 +out:
13098 + up(&ieee->wx_sem);
13099 + return ret;
13100 +}
13101 +
13102 +int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
13103 + struct iw_request_info *a,
13104 + union iwreq_data *wrqu, char *extra)
13105 +{
13106 +
13107 + int ret=0,len;
13108 + short proto_started;
13109 + unsigned long flags;
13110 +
13111 + ieee->sync_scan_hurryup = 1;
13112 +
13113 + down(&ieee->wx_sem);
13114 +
13115 + proto_started = ieee->proto_started;
13116 +
13117 + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
13118 + ret= -E2BIG;
13119 + goto out;
13120 + }
13121 +
13122 + if (ieee->iw_mode == IW_MODE_MONITOR){
13123 + ret= -1;
13124 + goto out;
13125 + }
13126 +
13127 + if(proto_started)
13128 + ieee80211_stop_protocol(ieee);
13129 +
13130 + /* this is just to be sure that the GET wx callback
13131 + * has consisten infos. not needed otherwise
13132 + */
13133 + spin_lock_irqsave(&ieee->lock, flags);
13134 +
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;
13139 +#else
13140 + len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length) : IW_ESSID_MAX_SIZE;
13141 +#endif
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
13147 +
13148 + //YJ,add,080819,for hidden ap
13149 + if(len == 0){
13150 + memset(ieee->current_network.bssid, 0, ETH_ALEN);
13151 + ieee->current_network.capability = 0;
13152 + }
13153 + //YJ,add,080819,for hidden ap,end
13154 + }
13155 + else{
13156 + ieee->ssid_set = 0;
13157 + ieee->current_network.ssid[0] = '\0';
13158 + ieee->current_network.ssid_len = 0;
13159 + }
13160 + //printk("==========set essid %s!\n",ieee->current_network.ssid);
13161 + spin_unlock_irqrestore(&ieee->lock, flags);
13162 +
13163 + if (proto_started)
13164 + ieee80211_start_protocol(ieee);
13165 +out:
13166 + up(&ieee->wx_sem);
13167 + return ret;
13168 +}
13169 +
13170 + int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
13171 + union iwreq_data *wrqu, char *b)
13172 +{
13173 +
13174 + wrqu->mode = ieee->iw_mode;
13175 + return 0;
13176 +}
13177 +
13178 + int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
13179 + struct iw_request_info *info,
13180 + union iwreq_data *wrqu, char *extra)
13181 +{
13182 +
13183 + int *parms = (int *)extra;
13184 + int enable = (parms[0] > 0);
13185 + short prev = ieee->raw_tx;
13186 +
13187 + down(&ieee->wx_sem);
13188 +
13189 + if(enable)
13190 + ieee->raw_tx = 1;
13191 + else
13192 + ieee->raw_tx = 0;
13193 +
13194 + printk(KERN_INFO"raw TX is %s\n",
13195 + ieee->raw_tx ? "enabled" : "disabled");
13196 +
13197 + if(ieee->iw_mode == IW_MODE_MONITOR)
13198 + {
13199 + if(prev == 0 && ieee->raw_tx){
13200 + if (ieee->data_hard_resume)
13201 + ieee->data_hard_resume(ieee->dev);
13202 +
13203 + netif_carrier_on(ieee->dev);
13204 + }
13205 +
13206 + if(prev && ieee->raw_tx == 1)
13207 + netif_carrier_off(ieee->dev);
13208 + }
13209 +
13210 + up(&ieee->wx_sem);
13211 +
13212 + return 0;
13213 +}
13214 +
13215 +int ieee80211_wx_get_name(struct ieee80211_device *ieee,
13216 + struct iw_request_info *info,
13217 + union iwreq_data *wrqu, char *extra)
13218 +{
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");
13226 +
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..");
13232 +
13233 +
13234 + return 0;
13235 +}
13236 +
13237 +
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)
13242 +{
13243 + int ret = 0;
13244 +
13245 + if(
13246 + (!ieee->sta_wake_up) ||
13247 + (!ieee->ps_request_tx_ack) ||
13248 + (!ieee->enter_sleep_state) ||
13249 + (!ieee->ps_is_queue_empty)){
13250 +
13251 + printk("ERROR. PS mode is tryied to be use but\
13252 +driver missed a callback\n\n");
13253 +
13254 + return -1;
13255 + }
13256 +
13257 + down(&ieee->wx_sem);
13258 +
13259 + if (wrqu->power.disabled){
13260 + ieee->ps = IEEE80211_PS_DISABLED;
13261 +
13262 + goto exit;
13263 + }
13264 + switch (wrqu->power.flags & IW_POWER_MODE) {
13265 + case IW_POWER_UNICAST_R:
13266 + ieee->ps = IEEE80211_PS_UNICAST;
13267 +
13268 + break;
13269 + case IW_POWER_ALL_R:
13270 + ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST;
13271 + break;
13272 +
13273 + case IW_POWER_ON:
13274 + ieee->ps = IEEE80211_PS_DISABLED;
13275 + break;
13276 +
13277 + default:
13278 + ret = -EINVAL;
13279 + goto exit;
13280 + }
13281 +
13282 + if (wrqu->power.flags & IW_POWER_TIMEOUT) {
13283 +
13284 + ieee->ps_timeout = wrqu->power.value / 1000;
13285 + printk("Timeout %d\n",ieee->ps_timeout);
13286 + }
13287 +
13288 + if (wrqu->power.flags & IW_POWER_PERIOD) {
13289 +
13290 + ret = -EOPNOTSUPP;
13291 + goto exit;
13292 + //wrq->value / 1024;
13293 +
13294 + }
13295 +exit:
13296 + up(&ieee->wx_sem);
13297 + return ret;
13298 +
13299 +}
13300 +
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)
13305 +{
13306 + int ret =0;
13307 +
13308 + down(&ieee->wx_sem);
13309 +
13310 + if(ieee->ps == IEEE80211_PS_DISABLED){
13311 + wrqu->power.disabled = 1;
13312 + goto exit;
13313 + }
13314 +
13315 + wrqu->power.disabled = 0;
13316 +
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;
13320 +// } else {
13321 +// ret = -EOPNOTSUPP;
13322 +// goto exit;
13323 + //wrqu->power.flags = IW_POWER_PERIOD;
13324 + //wrqu->power.value = ieee->current_network.dtim_period *
13325 + // ieee->current_network.beacon_interval * 1024;
13326 +// }
13327 +
13328 +
13329 + if (ieee->ps & IEEE80211_PS_MBCAST)
13330 + wrqu->power.flags |= IW_POWER_ALL_R;
13331 + else
13332 + wrqu->power.flags |= IW_POWER_UNICAST_R;
13333 +
13334 +exit:
13335 + up(&ieee->wx_sem);
13336 + return ret;
13337 +
13338 +}
13339 +
13340 +#if 0
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);
13357 +#endif
13358 --- /dev/null
13359 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
13360 @@ -0,0 +1,828 @@
13361 +/******************************************************************************
13362 +
13363 + Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
13364 +
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.
13368 +
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
13372 + more details.
13373 +
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.
13377 +
13378 + The full GNU General Public License is included in this distribution in the
13379 + file called LICENSE.
13380 +
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
13384 +
13385 +******************************************************************************
13386 +
13387 + Few modifications for Realtek's Wi-Fi drivers by
13388 + Andrea Merello <andreamrl@tiscali.it>
13389 +
13390 + A special thanks goes to Realtek for their support !
13391 +
13392 +******************************************************************************/
13393 +
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>
13415 +
13416 +#include "ieee80211.h"
13417 +
13418 +
13419 +/*
13420 +
13421 +
13422 +802.11 Data Frame
13423 +
13424 +
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 + '-----------------------------------------------------------------------------------------'
13434 + /\
13435 + |
13436 +802.11 Data Frame |
13437 + ,--------- 'ctrl' expands to >-----------'
13438 + |
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 `----.----'
13446 + |
13447 + .- 'Frame data' expands to <---------------------------'
13448 + |
13449 + V
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 `----.----'
13458 + |
13459 + .- 'IP Packet' expands, if WEP enabled, to <--'
13460 + |
13461 + V
13462 + ,-----------------------.
13463 +Bytes | 4 | 0-2296 | 4 |
13464 + |-----|-----------|-----|
13465 +Desc. | IV | Encrypted | ICV |
13466 + | | IP Packet | |
13467 + `-----------------------'
13468 +Total: 8 non-data bytes
13469 +
13470 +
13471 +802.3 Ethernet Data Frame
13472 +
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
13480 +
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.
13484 +
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.
13490 +
13491 +* SKB visualization
13492 +*
13493 +* ,- skb->data
13494 +* |
13495 +* | ETHERNET HEADER ,-<-- PAYLOAD
13496 +* | | 14 bytes from skb->data
13497 +* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
13498 +* | | | |
13499 +* |,-Dest.--. ,--Src.---. | | |
13500 +* | 6 bytes| | 6 bytes | | | |
13501 +* v | | | | | |
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
13504 +* ^ | ^ | ^ |
13505 +* | | | | | |
13506 +* | | | | `T' <---- 2 bytes for Type
13507 +* | | | |
13508 +* | | '---SNAP--' <-------- 6 bytes for SNAP
13509 +* | |
13510 +* `-IV--' <-------------------- 4 bytes for IV (WEP)
13511 +*
13512 +* SNAP HEADER
13513 +*
13514 +*/
13515 +
13516 +static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
13517 +static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
13518 +
13519 +static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
13520 +{
13521 + struct ieee80211_snap_hdr *snap;
13522 + u8 *oui;
13523 +
13524 + snap = (struct ieee80211_snap_hdr *)data;
13525 + snap->dsap = 0xaa;
13526 + snap->ssap = 0xaa;
13527 + snap->ctrl = 0x03;
13528 +
13529 + if (h_proto == 0x8137 || h_proto == 0x80f3)
13530 + oui = P802_1H_OUI;
13531 + else
13532 + oui = RFC1042_OUI;
13533 + snap->oui[0] = oui[0];
13534 + snap->oui[1] = oui[1];
13535 + snap->oui[2] = oui[2];
13536 +
13537 + *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
13538 +
13539 + return SNAP_SIZE + sizeof(u16);
13540 +}
13541 +
13542 +int ieee80211_encrypt_fragment(
13543 + struct ieee80211_device *ieee,
13544 + struct sk_buff *frag,
13545 + int hdr_len)
13546 +{
13547 + struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
13548 + int res;
13549 +
13550 + /*added to care about null crypt condition, to solve that system hangs when shared keys error*/
13551 + if (!crypt || !crypt->ops)
13552 + return -1;
13553 +
13554 +#ifdef CONFIG_IEEE80211_CRYPT_TKIP
13555 + struct ieee80211_hdr *header;
13556 +
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));
13564 + }
13565 + return -1;
13566 + }
13567 +#endif
13568 + /* To encrypt, frame format is:
13569 + * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
13570 +
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);
13575 + res = 0;
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);
13580 +
13581 + atomic_dec(&crypt->refcnt);
13582 + if (res < 0) {
13583 + printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
13584 + ieee->dev->name, frag->len);
13585 + ieee->ieee_stats.tx_discards++;
13586 + return -1;
13587 + }
13588 +
13589 + return 0;
13590 +}
13591 +
13592 +
13593 +void ieee80211_txb_free(struct ieee80211_txb *txb) {
13594 + int i;
13595 + if (unlikely(!txb))
13596 + return;
13597 + for (i = 0; i < txb->nr_frags; i++)
13598 + if (txb->fragments[i])
13599 + dev_kfree_skb_any(txb->fragments[i]);
13600 + kfree(txb);
13601 +}
13602 +
13603 +struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
13604 + int gfp_mask)
13605 +{
13606 + struct ieee80211_txb *txb;
13607 + int i;
13608 + txb = kmalloc(
13609 + sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
13610 + gfp_mask);
13611 + if (!txb)
13612 + return NULL;
13613 +
13614 + memset(txb, 0, sizeof(struct ieee80211_txb));
13615 + txb->nr_frags = nr_frags;
13616 + txb->frag_size = txb_size;
13617 +
13618 + for (i = 0; i < nr_frags; i++) {
13619 + txb->fragments[i] = dev_alloc_skb(txb_size);
13620 + if (unlikely(!txb->fragments[i])) {
13621 + i--;
13622 + break;
13623 + }
13624 + }
13625 + if (unlikely(i != nr_frags)) {
13626 + while (i >= 0)
13627 + dev_kfree_skb_any(txb->fragments[i--]);
13628 + kfree(txb);
13629 + return NULL;
13630 + }
13631 + return txb;
13632 +}
13633 +
13634 +// Classify the to-be send data packet
13635 +// Need to acquire the sent queue index.
13636 +static int
13637 +ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
13638 +{
13639 + struct ether_header *eh = (struct ether_header*)skb->data;
13640 + unsigned int wme_UP = 0;
13641 +
13642 + if(!network->QoS_Enable) {
13643 + skb->priority = 0;
13644 + return(wme_UP);
13645 + }
13646 +
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 */
13655 +#endif
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");
13660 + wme_UP = 7;
13661 + }
13662 +
13663 + skb->priority = wme_UP;
13664 + return(wme_UP);
13665 +}
13666 +
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)
13670 +{
13671 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
13672 + struct ieee80211_device *ieee = netdev_priv(dev);
13673 +#else
13674 + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
13675 +#endif
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;
13679 + int ether_type;
13680 + int bytes, QOS_ctl;
13681 + struct sk_buff *skb_frag;
13682 +
13683 + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
13684 +
13685 + /* Advance the SKB to the start of the payload */
13686 + skb_pull(skb, sizeof(struct ethhdr));
13687 +
13688 + /* Determine total amount of storage required for TXB packets */
13689 + bytes = skb->len + SNAP_SIZE + sizeof(u16);
13690 +
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;
13699 + }
13700 + else {
13701 + //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
13702 + frag_size = ieee->fts;//default:392
13703 + QOS_ctl = 0;
13704 + }
13705 +
13706 + if(isQoS) {
13707 + QOS_ctl |= skb->priority; //set in the ieee80211_classify
13708 + *pQOS_ctl = cpu_to_le16(QOS_ctl);
13709 + }
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;
13720 +
13721 + /* Each fragment may need to have room for encryptiong pre/postfix */
13722 + if (isEncrypt)
13723 + bytes_per_frag -= crypt->ops->extra_prefix_len +
13724 + crypt->ops->extra_postfix_len;
13725 +
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)
13731 + nr_frags++;
13732 + else
13733 + bytes_last_frag = bytes_per_frag;
13734 +
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);
13742 + return NULL;
13743 + }
13744 + txb->encrypted = isEncrypt;
13745 + txb->payload_size = bytes;
13746 +
13747 + for (i = 0; i < nr_frags; i++) {
13748 + skb_frag = txb->fragments[i];
13749 + skb_frag->priority = UP2AC(skb->priority);
13750 + if (isEncrypt)
13751 + skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
13752 +
13753 + frag_hdr = (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
13754 + memcpy(frag_hdr, (void *)header, hdr_len);
13755 +
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;
13762 +
13763 + } else {
13764 + /* The last fragment takes the remaining length */
13765 + bytes = bytes_last_frag;
13766 + }
13767 +
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);
13770 + //
13771 +
13772 + /* Put a SNAP header on the first fragment */
13773 + if (i == 0) {
13774 + ieee80211_put_snap(
13775 + skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), ether_type);
13776 + bytes -= SNAP_SIZE + sizeof(u16);
13777 + }
13778 +
13779 + memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
13780 +
13781 + /* Advance the SKB... */
13782 + skb_pull(skb, bytes);
13783 +
13784 + /* Encryption routine will move the header forward in order
13785 + * to insert the IV between the header and the payload */
13786 + if (isEncrypt)
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);
13791 + }
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;
13796 + else
13797 + ieee->seq_ctrl[0]++;
13798 + // stanley, just for debug
13799 +/*
13800 +{
13801 + int j=0;
13802 + for(j=0;j<nr_frags;j++)
13803 + {
13804 + int i;
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);
13809 + printk("\n");
13810 + }
13811 +}
13812 +*/
13813 +
13814 + return txb;
13815 +}
13816 +
13817 +
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)
13821 +{
13822 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
13823 + struct ieee80211_device *ieee = netdev_priv(dev);
13824 +#else
13825 + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
13826 +#endif
13827 + struct ieee80211_txb *txb = NULL;
13828 + struct ieee80211_hdr_3addr *frag_hdr;
13829 + int ether_type;
13830 + int bytes, QOS_ctl;
13831 +
13832 + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
13833 +
13834 + /* Advance the SKB to the start of the payload */
13835 + skb_pull(skb, sizeof(struct ethhdr));
13836 +
13837 + /* Determine total amount of storage required for TXB packets */
13838 + bytes = skb->len + SNAP_SIZE + sizeof(u16);
13839 +
13840 + if (is_multicast_ether_addr(header->addr1) ||
13841 + is_broadcast_ether_addr(header->addr1)) {
13842 + QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
13843 + }
13844 + else {
13845 + QOS_ctl = 0;
13846 + }
13847 +
13848 + if(isQoS) {
13849 + QOS_ctl |= skb->priority; //set in the ieee80211_classify
13850 + *pQOS_ctl = cpu_to_le16(QOS_ctl);
13851 + }
13852 +
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);
13857 + return NULL;
13858 + }
13859 +
13860 + txb->nr_frags = 1;
13861 + txb->frag_size = bytes;
13862 + txb->encrypted = isEncrypt;
13863 + txb->payload_size = bytes;
13864 +
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);
13872 +
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;
13877 + else
13878 + ieee->seq_ctrl[0]++;
13879 +
13880 + return txb;
13881 +}
13882 +
13883 +#endif // _RTL8187_EXT_PATCH_
13884 +
13885 +/* SKBs are added to the ieee->tx_queue. */
13886 +int ieee80211_xmit(struct sk_buff *skb,
13887 + struct net_device *dev)
13888 +{
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,
13900 + // .seq_ctl = 0
13901 + //};
13902 + struct ieee80211_hdr_3addr_QOS header = { /* Ensure zero initialized */
13903 + .duration_id = 0,
13904 + .seq_ctl = 0,
13905 + .QOS_ctl = 0
13906 + };
13907 + u8 dest[ETH_ALEN], src[ETH_ALEN];
13908 +
13909 + struct ieee80211_crypt_data* crypt;
13910 +
13911 + //printk(KERN_WARNING "upper layer packet!\n");
13912 + spin_lock_irqsave(&ieee->lock, flags);
13913 +
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);
13920 + goto success;
13921 + }
13922 +
13923 + ieee80211_classify(skb,&ieee->current_network);
13924 + if(likely(ieee->raw_tx == 0)){
13925 +
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);
13929 + goto success;
13930 + }
13931 +
13932 +
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))
13936 + {
13937 + txb = ieee->ext_patch_ieee80211_xmit(skb, dev);
13938 + goto success;
13939 + }
13940 +#endif
13941 +
13942 + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
13943 +
13944 + crypt = ieee->crypt[ieee->tx_keyidx];
13945 +
13946 + encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
13947 + ieee->host_encrypt && crypt && crypt->ops;
13948 +
13949 + if (!encrypt && ieee->ieee802_1x &&
13950 + ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
13951 + stats->tx_dropped++;
13952 + goto success;
13953 + }
13954 +
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));
13961 + }
13962 + #endif
13963 +
13964 + /* Save source and destination addresses */
13965 + memcpy(&dest, skb->data, ETH_ALEN);
13966 + memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
13967 +
13968 + /* Advance the SKB to the start of the payload */
13969 + skb_pull(skb, sizeof(struct ethhdr));
13970 +
13971 + /* Determine total amount of storage required for TXB packets */
13972 + bytes = skb->len + SNAP_SIZE + sizeof(u16);
13973 +
13974 + if(ieee->current_network.QoS_Enable) {
13975 + if (encrypt)
13976 + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA |
13977 + IEEE80211_FCTL_WEP;
13978 + else
13979 + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
13980 +
13981 + } else {
13982 + if (encrypt)
13983 + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
13984 + IEEE80211_FCTL_WEP;
13985 + else
13986 + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
13987 + }
13988 +
13989 + if (ieee->iw_mode == IW_MODE_INFRA) {
13990 + fc |= IEEE80211_FCTL_TODS;
13991 + /* To DS: Addr1 = BSSID, Addr2 = SA,
13992 + Addr3 = DA */
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,
13998 + Addr3 = BSSID */
13999 + memcpy(&header.addr1, dest, ETH_ALEN);
14000 + memcpy(&header.addr2, src, ETH_ALEN);
14001 + memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
14002 + }
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;
14006 +
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;
14015 + }
14016 + else {
14017 + //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
14018 + frag_size = ieee->fts;//default:392
14019 + QOS_ctl = 0;
14020 + }
14021 +
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);
14026 + } else {
14027 + hdr_len = IEEE80211_3ADDR_LEN;
14028 + }
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;
14039 +
14040 + /* Each fragment may need to have room for encryptiong pre/postfix */
14041 + if (encrypt)
14042 + bytes_per_frag -= crypt->ops->extra_prefix_len +
14043 + crypt->ops->extra_postfix_len;
14044 +
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)
14050 + nr_frags++;
14051 + else
14052 + bytes_last_frag = bytes_per_frag;
14053 +
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);
14061 + goto failed;
14062 + }
14063 + txb->encrypted = encrypt;
14064 + txb->payload_size = bytes;
14065 +
14066 + for (i = 0; i < nr_frags; i++) {
14067 + skb_frag = txb->fragments[i];
14068 + skb_frag->priority = UP2AC(skb->priority);
14069 + if (encrypt)
14070 + skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
14071 +
14072 + frag_hdr = (struct ieee80211_hdr_3addr_QOS *)skb_put(skb_frag, hdr_len);
14073 + memcpy(frag_hdr, &header, hdr_len);
14074 +
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;
14081 +
14082 + } else {
14083 + /* The last fragment takes the remaining length */
14084 + bytes = bytes_last_frag;
14085 + }
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]);
14091 + } else {
14092 + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
14093 + }
14094 + //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
14095 + //
14096 +
14097 + /* Put a SNAP header on the first fragment */
14098 + if (i == 0) {
14099 + ieee80211_put_snap(
14100 + skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
14101 + ether_type);
14102 + bytes -= SNAP_SIZE + sizeof(u16);
14103 + }
14104 +
14105 + memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
14106 +
14107 + /* Advance the SKB... */
14108 + skb_pull(skb, bytes);
14109 +
14110 + /* Encryption routine will move the header forward in order
14111 + * to insert the IV between the header and the payload */
14112 + if (encrypt)
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);
14117 + }
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;
14123 + else
14124 + ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
14125 + } else {
14126 + if (ieee->seq_ctrl[0] == 0xFFF)
14127 + ieee->seq_ctrl[0] = 0;
14128 + else
14129 + ieee->seq_ctrl[0]++;
14130 + }
14131 + //---
14132 + }else{
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);
14136 + goto success;
14137 + }
14138 +
14139 + txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
14140 + if(!txb){
14141 + printk(KERN_WARNING "%s: Could not allocate TXB\n",
14142 + ieee->dev->name);
14143 + goto failed;
14144 + }
14145 +
14146 + txb->encrypted = 0;
14147 + txb->payload_size = skb->len;
14148 + memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
14149 + }
14150 +
14151 + success:
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)) )
14156 +#endif
14157 + dev_kfree_skb_any(skb);
14158 + if (txb) {
14159 + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
14160 + ieee80211_softmac_xmit(txb, ieee);
14161 + }else{
14162 + if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
14163 + stats->tx_packets++;
14164 + stats->tx_bytes += txb->payload_size;
14165 + return 0;
14166 + }
14167 + ieee80211_txb_free(txb);
14168 + }
14169 + }
14170 +
14171 + return 0;
14172 +
14173 + failed:
14174 + spin_unlock_irqrestore(&ieee->lock, flags);
14175 + netif_stop_queue(dev);
14176 + stats->tx_errors++;
14177 + return 1;
14178 +
14179 +}
14180 +
14181 +#if 0
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_
14188 +#endif
14189 --- /dev/null
14190 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
14191 @@ -0,0 +1,884 @@
14192 +/******************************************************************************
14193 +
14194 + Copyright(c) 2004 Intel Corporation. All rights reserved.
14195 +
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>
14201 +
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.
14205 +
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
14209 + more details.
14210 +
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.
14214 +
14215 + The full GNU General Public License is included in this distribution in the
14216 + file called LICENSE.
14217 +
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
14221 +
14222 +******************************************************************************/
14223 +#include <linux/wireless.h>
14224 +#include <linux/version.h>
14225 +#include <linux/kmod.h>
14226 +#include <linux/module.h>
14227 +
14228 +#include "ieee80211.h"
14229 +static const char *ieee80211_modes[] = {
14230 + "?", "a", "b", "ab", "g", "ag", "bg", "abg"
14231 +};
14232 +
14233 +#ifdef FEDORACORE_9
14234 +#define IN_FEDORACORE_9 1
14235 +#else
14236 +#define IN_FEDORACORE_9 0
14237 +#endif
14238 +
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)
14244 +{
14245 + char custom[MAX_CUSTOM_LEN];
14246 + char *p;
14247 + struct iw_event iwe;
14248 + int i, j;
14249 + u8 max_rate, rate;
14250 +
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);
14257 +#else
14258 + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
14259 +#endif
14260 +
14261 + /* Remaining entries will be displayed in the order we provide them */
14262 +
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>");
14273 +#else
14274 + start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
14275 +#endif
14276 + } else {
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);
14280 +#else
14281 + start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
14282 +#endif
14283 + }
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);
14290 +#else
14291 + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
14292 +#endif
14293 +
14294 + /* Add mode */
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;
14300 + else
14301 + iwe.u.mode = IW_MODE_ADHOC;
14302 +
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);
14305 +#else
14306 + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
14307 +#endif
14308 + }
14309 +
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);
14319 +#else
14320 + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
14321 +#endif
14322 +
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;
14327 + else
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);
14332 +#else
14333 + start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
14334 +#endif
14335 +
14336 + /* Add basic and extended rates */
14337 + max_rate = 0;
14338 + p = custom;
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;
14345 + else
14346 + rate = network->rates[i++] & 0x7F;
14347 + if (rate > max_rate)
14348 + max_rate = rate;
14349 + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
14350 + "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
14351 + }
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)
14357 + max_rate = rate;
14358 + }
14359 +
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);
14365 +#else
14366 + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_PARAM_LEN);
14367 +#endif
14368 +
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);
14374 +#else
14375 + start = iwe_stream_add_point(start, stop, &iwe, custom);
14376 +#endif
14377 +
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);
14397 +#else
14398 + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
14399 +#endif
14400 +
14401 + iwe.cmd = IWEVCUSTOM;
14402 + p = custom;
14403 +
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);
14408 +#else
14409 + start = iwe_stream_add_point(start, stop, &iwe, custom);
14410 +#endif
14411 +
14412 +#if 0
14413 + if (ieee->wpa_enabled && network->wpa_ie_len){
14414 + char buf[MAX_WPA_IE_LEN * 2 + 30];
14415 + // printk("WPA IE\n");
14416 + u8 *p = buf;
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]);
14420 + }
14421 +
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);
14427 +#else
14428 + start = iwe_stream_add_point(start, stop, &iwe, buf);
14429 +#endif
14430 + }
14431 +
14432 + if (ieee->wpa_enabled && network->rsn_ie_len){
14433 + char buf[MAX_WPA_IE_LEN * 2 + 30];
14434 +
14435 + u8 *p = buf;
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]);
14439 + }
14440 +
14441 +
14442 +#else
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);
14452 +#else
14453 + start = iwe_stream_add_point(start, stop, &iwe, buf);
14454 +#endif
14455 + }
14456 +
14457 + memset(&iwe, 0, sizeof(iwe));
14458 + if (network->rsn_ie_len) {
14459 + // printk("=====>rsn_ie_len:\n", network->rsn_ie_len);
14460 + #if 0
14461 + {
14462 + int i;
14463 + for (i=0; i<network->rsn_ie_len; i++);
14464 + printk("%2x ", network->rsn_ie[i]);
14465 + printk("\n");
14466 + }
14467 + #endif
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);
14474 +#else
14475 + start = iwe_stream_add_point(start, stop, &iwe, buf);
14476 +#endif
14477 + }
14478 +
14479 +#endif
14480 +
14481 + /* Add EXTRA: Age to display seconds since last beacon/probe response
14482 + * for given network. */
14483 + iwe.cmd = IWEVCUSTOM;
14484 + p = custom;
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);
14491 +#else
14492 + start = iwe_stream_add_point(start, stop, &iwe, custom);
14493 +#endif
14494 +
14495 + return start;
14496 +}
14497 +
14498 +int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
14499 + struct iw_request_info *info,
14500 + union iwreq_data *wrqu, char *extra)
14501 +{
14502 + struct ieee80211_network *network;
14503 + unsigned long flags;
14504 + int err = 0;
14505 + char *ev = extra;
14506 + char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
14507 + //char *stop = ev + IW_SCAN_MAX_DATA;
14508 + int i = 0;
14509 +
14510 + IEEE80211_DEBUG_WX("Getting scan\n");
14511 + down(&ieee->wx_sem);
14512 + spin_lock_irqsave(&ieee->lock, flags);
14513 +
14514 + if(!ieee->bHwRadioOff)
14515 + {
14516 + list_for_each_entry(network, &ieee->network_list, list) {
14517 + i++;
14518 +
14519 + if((stop-ev)<200)
14520 + {
14521 + err = -E2BIG;
14522 + break;
14523 + }
14524 + if (ieee->scan_age == 0 ||
14525 + time_after(network->last_scanned + ieee->scan_age, jiffies))
14526 + {
14527 + ev = rtl818x_translate_scan(ieee, ev, stop, network, info);
14528 + }
14529 + else
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));
14537 + }
14538 + }
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);
14544 +
14545 + return err;
14546 +}
14547 +
14548 +int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
14549 + struct iw_request_info *info,
14550 + union iwreq_data *wrqu, char *keybuf)
14551 +{
14552 + struct iw_point *erq = &(wrqu->encoding);
14553 + struct net_device *dev = ieee->dev;
14554 + struct ieee80211_security sec = {
14555 + .flags = 0
14556 + };
14557 + int i, key, key_provided, len;
14558 + struct ieee80211_crypt_data **crypt;
14559 +
14560 + IEEE80211_DEBUG_WX("SET_ENCODE\n");
14561 +
14562 + key = erq->flags & IW_ENCODE_INDEX;
14563 + if (key) {
14564 + if (key > WEP_KEYS)
14565 + return -EINVAL;
14566 + key--;
14567 + key_provided = 1;
14568 + } else {
14569 + key_provided = 0;
14570 + key = ieee->tx_keyidx;
14571 + }
14572 +
14573 + IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
14574 + "provided" : "default");
14575 +
14576 + crypt = &ieee->crypt[key];
14577 +
14578 + if (erq->flags & IW_ENCODE_DISABLED) {
14579 + if (key_provided && *crypt) {
14580 + IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
14581 + key);
14582 + ieee80211_crypt_delayed_deinit(ieee, crypt);
14583 + } else
14584 + IEEE80211_DEBUG_WX("Disabling encryption.\n");
14585 +
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)
14591 + break;
14592 + ieee80211_crypt_delayed_deinit(
14593 + ieee, &ieee->crypt[i]);
14594 + }
14595 + }
14596 +
14597 + if (i == WEP_KEYS) {
14598 + sec.enabled = 0;
14599 + sec.level = SEC_LEVEL_0;
14600 + sec.flags |= SEC_ENABLED | SEC_LEVEL;
14601 + }
14602 +
14603 + goto done;
14604 + }
14605 +
14606 +
14607 +
14608 + sec.enabled = 1;
14609 + sec.flags |= SEC_ENABLED;
14610 +
14611 + if (*crypt != NULL && (*crypt)->ops != NULL &&
14612 + strcmp((*crypt)->ops->name, "WEP") != 0) {
14613 + /* changing to use WEP; deinit previously used algorithm
14614 + * on this key */
14615 + ieee80211_crypt_delayed_deinit(ieee, crypt);
14616 + }
14617 +
14618 + if (*crypt == NULL) {
14619 + struct ieee80211_crypt_data *new_crypt;
14620 +
14621 + /* take WEP into use */
14622 + new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data),
14623 + GFP_KERNEL);
14624 + if (new_crypt == NULL)
14625 + return -ENOMEM;
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");
14631 + }
14632 +
14633 + if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
14634 + new_crypt->priv = new_crypt->ops->init(key);
14635 +
14636 + if (!new_crypt->ops || !new_crypt->priv) {
14637 + kfree(new_crypt);
14638 + new_crypt = NULL;
14639 +
14640 + printk(KERN_WARNING "%s: could not initialize WEP: "
14641 + "load module ieee80211_crypt_wep\n",
14642 + dev->name);
14643 + return -EOPNOTSUPP;
14644 + }
14645 + *crypt = new_crypt;
14646 + }
14647 +
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,
14660 + (*crypt)->priv);
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
14667 + } else {
14668 + len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
14669 + NULL, (*crypt)->priv);
14670 + if (len == 0) {
14671 + /* Set a default key of all 0 */
14672 + IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
14673 + key);
14674 + memset(sec.keys[key], 0, 13);
14675 + (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
14676 + (*crypt)->priv);
14677 + sec.key_sizes[key] = 13;
14678 + sec.flags |= (1 << key);
14679 + }
14680 +
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;
14688 + }
14689 + }
14690 +
14691 + done:
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");
14697 +
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 */
14702 +
14703 + if (ieee->set_security)
14704 + ieee->set_security(dev, &sec);
14705 +
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);
14715 + return -EINVAL;
14716 + }
14717 + return 0;
14718 +}
14719 +
14720 +int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
14721 + struct iw_request_info *info,
14722 + union iwreq_data *wrqu, char *keybuf)
14723 +{
14724 + struct iw_point *erq = &(wrqu->encoding);
14725 + int len, key;
14726 + struct ieee80211_crypt_data *crypt;
14727 +
14728 + IEEE80211_DEBUG_WX("GET_ENCODE\n");
14729 +
14730 + if(ieee->iw_mode == IW_MODE_MONITOR)
14731 + return -1;
14732 +
14733 + key = erq->flags & IW_ENCODE_INDEX;
14734 + if (key) {
14735 + if (key > WEP_KEYS)
14736 + return -EINVAL;
14737 + key--;
14738 + } else
14739 + key = ieee->tx_keyidx;
14740 +
14741 + crypt = ieee->crypt[key];
14742 + erq->flags = key + 1;
14743 +
14744 + if (crypt == NULL || crypt->ops == NULL) {
14745 + erq->length = 0;
14746 + erq->flags |= IW_ENCODE_DISABLED;
14747 + return 0;
14748 + }
14749 +
14750 + if (strcmp(crypt->ops->name, "WEP") != 0) {
14751 + /* only WEP is supported with wireless extensions, so just
14752 + * report that encryption is used */
14753 + erq->length = 0;
14754 + erq->flags |= IW_ENCODE_ENABLED;
14755 + return 0;
14756 + }
14757 +
14758 + len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
14759 + erq->length = (len >= 0 ? len : 0);
14760 +
14761 + erq->flags |= IW_ENCODE_ENABLED;
14762 +
14763 + if (ieee->open_wep)
14764 + erq->flags |= IW_ENCODE_OPEN;
14765 + else
14766 + erq->flags |= IW_ENCODE_RESTRICTED;
14767 +
14768 + return 0;
14769 +}
14770 +
14771 +int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
14772 + struct iw_request_info *info,
14773 + union iwreq_data *wrqu, char *extra)
14774 +{
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;
14783 +
14784 + struct ieee80211_security sec = {
14785 + .flags = 0,
14786 + };
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;
14789 + if (idx) {
14790 + if (idx < 1 || idx > WEP_KEYS)
14791 + return -EINVAL;
14792 + idx--;
14793 + } else
14794 + idx = ieee->tx_keyidx;
14795 +
14796 + if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
14797 + crypt = &ieee->crypt[idx];
14798 + group_key = 1;
14799 + } else {
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)
14803 + return -EINVAL;
14804 + if (ieee->iw_mode == IW_MODE_INFRA)
14805 + crypt = &ieee->crypt[idx];
14806 + else
14807 + return -EINVAL;
14808 + }
14809 +
14810 + sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
14811 + if ((encoding->flags & IW_ENCODE_DISABLED) ||
14812 + ext->alg == IW_ENCODE_ALG_NONE) {
14813 + if (*crypt)
14814 + ieee80211_crypt_delayed_deinit(ieee, crypt);
14815 +
14816 + for (i = 0; i < WEP_KEYS; i++)
14817 + if (ieee->crypt[i] != NULL)
14818 + break;
14819 +
14820 + if (i == WEP_KEYS) {
14821 + sec.enabled = 0;
14822 + // sec.encrypt = 0;
14823 + sec.level = SEC_LEVEL_0;
14824 + sec.flags |= SEC_LEVEL;
14825 + }
14826 + //printk("disabled: flag:%x\n", encoding->flags);
14827 + goto done;
14828 + }
14829 +
14830 + sec.enabled = 1;
14831 + // sec.encrypt = 1;
14832 +#if 0
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;
14837 +#endif
14838 + switch (ext->alg) {
14839 + case IW_ENCODE_ALG_WEP:
14840 + alg = "WEP";
14841 + module = "ieee80211_crypt_wep";
14842 + break;
14843 + case IW_ENCODE_ALG_TKIP:
14844 + alg = "TKIP";
14845 + module = "ieee80211_crypt_tkip";
14846 + break;
14847 + case IW_ENCODE_ALG_CCMP:
14848 + alg = "CCMP";
14849 + module = "ieee80211_crypt_ccmp";
14850 + break;
14851 + default:
14852 + IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
14853 + dev->name, ext->alg);
14854 + ret = -EINVAL;
14855 + goto done;
14856 + }
14857 +// printk("8-09-08-9=====>%s, alg name:%s\n",__FUNCTION__, alg);
14858 +
14859 + ops = ieee80211_get_crypto_ops(alg);
14860 + if (ops == NULL) {
14861 + request_module(module);
14862 + ops = ieee80211_get_crypto_ops(alg);
14863 + }
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);
14868 + ret = -EINVAL;
14869 + goto done;
14870 + }
14871 +
14872 + if (*crypt == NULL || (*crypt)->ops != ops) {
14873 + struct ieee80211_crypt_data *new_crypt;
14874 +
14875 + ieee80211_crypt_delayed_deinit(ieee, crypt);
14876 +
14877 + new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
14878 + if (new_crypt == NULL) {
14879 + ret = -ENOMEM;
14880 + goto done;
14881 + }
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);
14887 + ret = -EINVAL;
14888 + goto done;
14889 + }
14890 + *crypt = new_crypt;
14891 +
14892 + }
14893 +
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");
14899 + ret = -EINVAL;
14900 + goto done;
14901 + }
14902 +#if 1
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;
14909 + }
14910 +
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;
14927 + }
14928 + /* Don't set sec level for group keys. */
14929 + if (group_key)
14930 + sec.flags &= ~SEC_LEVEL;
14931 + }
14932 +#endif
14933 +done:
14934 + if (ieee->set_security)
14935 + ieee->set_security(ieee->dev, &sec);
14936 +
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);
14941 + return -EINVAL;
14942 + }
14943 +
14944 + return ret;
14945 +}
14946 +int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
14947 + struct iw_request_info *info,
14948 + union iwreq_data *wrqu, char *extra)
14949 +{
14950 + struct iw_mlme *mlme = (struct iw_mlme *) extra;
14951 +// printk("\ndkgadfslkdjgalskdf===============>%s(), cmd:%x\n", __FUNCTION__, mlme->cmd);
14952 +#if 1
14953 + switch (mlme->cmd) {
14954 + case IW_MLME_DEAUTH:
14955 + case IW_MLME_DISASSOC:
14956 + // printk("disassoc now\n");
14957 + ieee80211_disassociate(ieee);
14958 + break;
14959 + default:
14960 + return -EOPNOTSUPP;
14961 + }
14962 +#endif
14963 + return 0;
14964 +}
14965 +
14966 +int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
14967 + struct iw_request_info *info,
14968 + struct iw_param *data, char *extra)
14969 +{
14970 +/*
14971 + struct ieee80211_security sec = {
14972 + .flags = SEC_AUTH_MODE,
14973 + }
14974 +*/
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);
14980 + break;
14981 + case IW_AUTH_CIPHER_PAIRWISE:
14982 + case IW_AUTH_CIPHER_GROUP:
14983 + case IW_AUTH_KEY_MGMT:
14984 + /*
14985 + * * Host AP driver does not use these parameters and allows
14986 + * * wpa_supplicant to control them internally.
14987 + * */
14988 + break;
14989 + case IW_AUTH_TKIP_COUNTERMEASURES:
14990 + ieee->tkip_countermeasures = data->value;
14991 + break;
14992 + case IW_AUTH_DROP_UNENCRYPTED:
14993 + ieee->drop_unencrypted = data->value;
14994 + break;
14995 +
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);
14999 + break;
15000 +
15001 +#if 1
15002 + case IW_AUTH_WPA_ENABLED:
15003 + ieee->wpa_enabled = (data->value)?1:0;
15004 + //printk("enalbe wpa:%d\n", ieee->wpa_enabled);
15005 + break;
15006 +
15007 +#endif
15008 + case IW_AUTH_RX_UNENCRYPTED_EAPOL:
15009 + ieee->ieee802_1x = data->value;
15010 + break;
15011 + case IW_AUTH_PRIVACY_INVOKED:
15012 + ieee->privacy_invoked = data->value;
15013 + break;
15014 + default:
15015 + return -EOPNOTSUPP;
15016 + }
15017 + return 0;
15018 +}
15019 +
15020 +#if 1
15021 +int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
15022 +{
15023 +#if 0
15024 + printk("====>%s()\n", __FUNCTION__);
15025 + {
15026 + int i;
15027 + for (i=0; i<len; i++)
15028 + printk("%2x ", ie[i]&0xff);
15029 + printk("\n");
15030 + }
15031 +#endif
15032 + u8 *buf = NULL;
15033 +
15034 + if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
15035 + {
15036 + printk("return error out, len:%d\n", len);
15037 + return -EINVAL;
15038 + }
15039 +
15040 + if (len)
15041 + {
15042 + if (len != ie[1]+2){
15043 + printk("len:%d, ie:%d\n", len, ie[1]);
15044 + return -EINVAL;
15045 + }
15046 + buf = kmalloc(len, GFP_KERNEL);
15047 + if (buf == NULL)
15048 + return -ENOMEM;
15049 + memcpy(buf, ie, len);
15050 + kfree(ieee->wpa_ie);
15051 + ieee->wpa_ie = buf;
15052 + ieee->wpa_ie_len = len;
15053 + }
15054 + else{
15055 + if (ieee->wpa_ie)
15056 + kfree(ieee->wpa_ie);
15057 + ieee->wpa_ie = NULL;
15058 + ieee->wpa_ie_len = 0;
15059 + }
15060 +// printk("<=====out %s()\n", __FUNCTION__);
15061 +
15062 + return 0;
15063 +
15064 +}
15065 +#endif
15066 +
15067 +#if 0
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);
15075 +#endif
15076 --- /dev/null
15077 +++ b/drivers/staging/rtl8187se/ieee80211/internal.h
15078 @@ -0,0 +1,115 @@
15079 +/*
15080 + * Cryptographic API.
15081 + *
15082 + * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
15083 + *
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.
15088 + *
15089 + */
15090 +#ifndef _CRYPTO_INTERNAL_H
15091 +#define _CRYPTO_INTERNAL_H
15092 +
15093 +
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>
15102 +
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))
15110 +
15111 +static inline void cond_resched(void)
15112 +{
15113 + if (need_resched()) {
15114 + set_current_state(TASK_RUNNING);
15115 + schedule();
15116 + }
15117 +}
15118 +#endif
15119 +
15120 +extern enum km_type crypto_km_types[];
15121 +
15122 +static inline enum km_type crypto_kmap_type(int out)
15123 +{
15124 + return crypto_km_types[(in_softirq() ? 2 : 0) + out];
15125 +}
15126 +
15127 +static inline void *crypto_kmap(struct page *page, int out)
15128 +{
15129 + return kmap_atomic(page, crypto_kmap_type(out));
15130 +}
15131 +
15132 +static inline void crypto_kunmap(void *vaddr, int out)
15133 +{
15134 + kunmap_atomic(vaddr, crypto_kmap_type(out));
15135 +}
15136 +
15137 +static inline void crypto_yield(struct crypto_tfm *tfm)
15138 +{
15139 + if (!in_softirq())
15140 + cond_resched();
15141 +}
15142 +
15143 +static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
15144 +{
15145 + return (void *)&tfm[1];
15146 +}
15147 +
15148 +struct crypto_alg *crypto_alg_lookup(const char *name);
15149 +
15150 +#ifdef CONFIG_KMOD
15151 +void crypto_alg_autoload(const char *name);
15152 +struct crypto_alg *crypto_alg_mod_lookup(const char *name);
15153 +#else
15154 +static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
15155 +{
15156 + return crypto_alg_lookup(name);
15157 +}
15158 +#endif
15159 +
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);
15163 +#else
15164 +static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
15165 +{
15166 + return 0;
15167 +}
15168 +
15169 +static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
15170 +{ }
15171 +#endif
15172 +
15173 +#ifdef CONFIG_PROC_FS
15174 +void __init crypto_init_proc(void);
15175 +#else
15176 +static inline void crypto_init_proc(void)
15177 +{ }
15178 +#endif
15179 +
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);
15183 +
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);
15187 +
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);
15191 +
15192 +#endif /* _CRYPTO_INTERNAL_H */
15193 +
15194 --- /dev/null
15195 +++ b/drivers/staging/rtl8187se/ieee80211/rtl_crypto.h
15196 @@ -0,0 +1,399 @@
15197 +/*
15198 + * Scatterlist Cryptographic API.
15199 + *
15200 + * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
15201 + * Copyright (c) 2002 David S. Miller (davem@redhat.com)
15202 + *
15203 + * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
15204 + * and Nettle, by Niels Mé°ˆler.
15205 + *
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.
15210 + *
15211 + */
15212 +#ifndef _LINUX_CRYPTO_H
15213 +#define _LINUX_CRYPTO_H
15214 +
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>
15222 +
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
15228 +
15229 +/*
15230 + * Algorithm masks and types.
15231 + */
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
15236 +
15237 +/*
15238 + * Transform masks and values (for crt_flags).
15239 + */
15240 +#define CRYPTO_TFM_MODE_MASK 0x000000ff
15241 +#define CRYPTO_TFM_REQ_MASK 0x000fff00
15242 +#define CRYPTO_TFM_RES_MASK 0xfff00000
15243 +
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
15248 +
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
15255 +
15256 +/*
15257 + * Miscellaneous stuff.
15258 + */
15259 +#define CRYPTO_UNSPEC 0
15260 +#define CRYPTO_MAX_ALG_NAME 64
15261 +
15262 +struct scatterlist;
15263 +
15264 +/*
15265 + * Algorithms: modular crypto algorithm implementations, managed
15266 + * via crypto_register_alg() and crypto_unregister_alg().
15267 + */
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);
15275 +};
15276 +
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);
15284 +};
15285 +
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);
15293 +};
15294 +
15295 +#define cra_cipher cra_u.cipher
15296 +#define cra_digest cra_u.digest
15297 +#define cra_compress cra_u.compress
15298 +
15299 +struct crypto_alg {
15300 + struct list_head cra_list;
15301 + u32 cra_flags;
15302 + unsigned int cra_blocksize;
15303 + unsigned int cra_ctxsize;
15304 + const char cra_name[CRYPTO_MAX_ALG_NAME];
15305 +
15306 + union {
15307 + struct cipher_alg cipher;
15308 + struct digest_alg digest;
15309 + struct compress_alg compress;
15310 + } cra_u;
15311 +
15312 + struct module *cra_module;
15313 +};
15314 +
15315 +/*
15316 + * Algorithm registration interface.
15317 + */
15318 +int crypto_register_alg(struct crypto_alg *alg);
15319 +int crypto_unregister_alg(struct crypto_alg *alg);
15320 +
15321 +/*
15322 + * Algorithm query interface.
15323 + */
15324 +int crypto_alg_available(const char *name, u32 flags);
15325 +
15326 +/*
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.
15330 + */
15331 +struct crypto_tfm;
15332 +
15333 +struct cipher_tfm {
15334 + void *cit_iv;
15335 + unsigned int cit_ivsize;
15336 + u32 cit_mode;
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);
15356 +};
15357 +
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;
15369 +#endif
15370 +};
15371 +
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);
15379 +};
15380 +
15381 +#define crt_cipher crt_u.cipher
15382 +#define crt_digest crt_u.digest
15383 +#define crt_compress crt_u.compress
15384 +
15385 +struct crypto_tfm {
15386 +
15387 + u32 crt_flags;
15388 +
15389 + union {
15390 + struct cipher_tfm cipher;
15391 + struct digest_tfm digest;
15392 + struct compress_tfm compress;
15393 + } crt_u;
15394 +
15395 + struct crypto_alg *__crt_alg;
15396 +};
15397 +
15398 +/*
15399 + * Transform user interface.
15400 + */
15401 +
15402 +/*
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.
15407 + *
15408 + * crypto_free_tfm() frees up the transform and any associated resources,
15409 + * then drops the refcount on the associated algorithm.
15410 + */
15411 +struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
15412 +void crypto_free_tfm(struct crypto_tfm *tfm);
15413 +
15414 +/*
15415 + * Transform helpers which query the underlying algorithm.
15416 + */
15417 +static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm)
15418 +{
15419 + return tfm->__crt_alg->cra_name;
15420 +}
15421 +
15422 +static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm)
15423 +{
15424 + struct crypto_alg *alg = tfm->__crt_alg;
15425 +
15426 + if (alg->cra_module)
15427 + return alg->cra_module->name;
15428 + else
15429 + return NULL;
15430 +}
15431 +
15432 +static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
15433 +{
15434 + return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
15435 +}
15436 +
15437 +static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm)
15438 +{
15439 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15440 + return tfm->__crt_alg->cra_cipher.cia_min_keysize;
15441 +}
15442 +
15443 +static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm)
15444 +{
15445 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15446 + return tfm->__crt_alg->cra_cipher.cia_max_keysize;
15447 +}
15448 +
15449 +static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm)
15450 +{
15451 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15452 + return tfm->crt_cipher.cit_ivsize;
15453 +}
15454 +
15455 +static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm)
15456 +{
15457 + return tfm->__crt_alg->cra_blocksize;
15458 +}
15459 +
15460 +static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm)
15461 +{
15462 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
15463 + return tfm->__crt_alg->cra_digest.dia_digestsize;
15464 +}
15465 +
15466 +/*
15467 + * API wrappers.
15468 + */
15469 +static inline void crypto_digest_init(struct crypto_tfm *tfm)
15470 +{
15471 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
15472 + tfm->crt_digest.dit_init(tfm);
15473 +}
15474 +
15475 +static inline void crypto_digest_update(struct crypto_tfm *tfm,
15476 + struct scatterlist *sg,
15477 + unsigned int nsg)
15478 +{
15479 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
15480 + tfm->crt_digest.dit_update(tfm, sg, nsg);
15481 +}
15482 +
15483 +static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
15484 +{
15485 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
15486 + tfm->crt_digest.dit_final(tfm, out);
15487 +}
15488 +
15489 +static inline void crypto_digest_digest(struct crypto_tfm *tfm,
15490 + struct scatterlist *sg,
15491 + unsigned int nsg, u8 *out)
15492 +{
15493 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
15494 + tfm->crt_digest.dit_digest(tfm, sg, nsg, out);
15495 +}
15496 +
15497 +static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
15498 + const u8 *key, unsigned int keylen)
15499 +{
15500 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
15501 + if (tfm->crt_digest.dit_setkey == NULL)
15502 + return -ENOSYS;
15503 + return tfm->crt_digest.dit_setkey(tfm, key, keylen);
15504 +}
15505 +
15506 +static inline int crypto_cipher_setkey(struct crypto_tfm *tfm,
15507 + const u8 *key, unsigned int keylen)
15508 +{
15509 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15510 + return tfm->crt_cipher.cit_setkey(tfm, key, keylen);
15511 +}
15512 +
15513 +static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
15514 + struct scatterlist *dst,
15515 + struct scatterlist *src,
15516 + unsigned int nbytes)
15517 +{
15518 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15519 + return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
15520 +}
15521 +
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)
15526 +{
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);
15530 +}
15531 +
15532 +static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
15533 + struct scatterlist *dst,
15534 + struct scatterlist *src,
15535 + unsigned int nbytes)
15536 +{
15537 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15538 + return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
15539 +}
15540 +
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)
15545 +{
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);
15549 +}
15550 +
15551 +static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
15552 + const u8 *src, unsigned int len)
15553 +{
15554 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15555 + memcpy(tfm->crt_cipher.cit_iv, src, len);
15556 +}
15557 +
15558 +static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
15559 + u8 *dst, unsigned int len)
15560 +{
15561 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15562 + memcpy(dst, tfm->crt_cipher.cit_iv, len);
15563 +}
15564 +
15565 +static inline int crypto_comp_compress(struct crypto_tfm *tfm,
15566 + const u8 *src, unsigned int slen,
15567 + u8 *dst, unsigned int *dlen)
15568 +{
15569 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
15570 + return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen);
15571 +}
15572 +
15573 +static inline int crypto_comp_decompress(struct crypto_tfm *tfm,
15574 + const u8 *src, unsigned int slen,
15575 + u8 *dst, unsigned int *dlen)
15576 +{
15577 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
15578 + return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen);
15579 +}
15580 +
15581 +/*
15582 + * HMAC support.
15583 + */
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 */
15593 +
15594 +#endif /* _LINUX_CRYPTO_H */
15595 +
15596 --- /dev/null
15597 +++ b/drivers/staging/rtl8187se/Kconfig
15598 @@ -0,0 +1,5 @@
15599 +config RTL8187SE
15600 + tristate "RealTek RTL8187SE Wireless LAN NIC driver"
15601 + depends on PCI
15602 + default N
15603 + ---help---
15604 --- /dev/null
15605 +++ b/drivers/staging/rtl8187se/Makefile
15606 @@ -0,0 +1,55 @@
15607 +
15608 +#EXTRA_CFLAGS += -DCONFIG_IEEE80211_NOWEP=y
15609 +#EXTRA_CFLAGS += -DCONFIG_RTL8180_IOMAP
15610 +#EXTRA_CFLAGS += -std=gnu89
15611 +#EXTRA_CFLAGS += -O2
15612 +#CC = gcc
15613 +EXTRA_CFLAGS += -DTHOMAS_TURBO
15614 +#CFLAGS += -DCONFIG_RTL8185B
15615 +#CFLAGS += -DCONFIG_RTL818x_S
15616 +
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
15625 +
15626 +#+YJ,080626
15627 +EXTRA_CFLAGS += -DENABLE_DOT11D
15628 +
15629 +#enable it for legacy power save, disable it for leisure power save
15630 +EXTRA_CFLAGS += -DENABLE_LPS
15631 +
15632 +
15633 +#EXTRA_CFLAGS += -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y
15634 +
15635 +rtl8187se-objs := \
15636 + r8180_core.o \
15637 + r8180_sa2400.o \
15638 + r8180_93cx6.o \
15639 + r8180_wx.o \
15640 + r8180_max2820.o \
15641 + r8180_gct.o \
15642 + r8180_rtl8225.o \
15643 + r8180_rtl8255.o \
15644 + r8180_rtl8225z2.o \
15645 + r8185b_init.o \
15646 + r8180_dm.o \
15647 + r8180_pm.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
15659 +
15660 +obj-$(CONFIG_RTL8187SE) += rtl8187se.o
15661 +
15662 --- /dev/null
15663 +++ b/drivers/staging/rtl8187se/r8180_93cx6.c
15664 @@ -0,0 +1,146 @@
15665 +/*
15666 + This files contains card eeprom (93c46 or 93c56) programming routines,
15667 + memory is addressed by 16 bits words.
15668 +
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)
15672 +
15673 + Parts of this driver are based on the GPL part of the
15674 + official realtek driver.
15675 +
15676 + Parts of this driver are based on the rtl8180 driver skeleton
15677 + from Patric Schenke & Andres Salomon.
15678 +
15679 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
15680 +
15681 + We want to tanks the Authors of those projects and the Ndiswrapper
15682 + project Authors.
15683 +*/
15684 +
15685 +#include "r8180_93cx6.h"
15686 +
15687 +void eprom_cs(struct net_device *dev, short bit)
15688 +{
15689 + if(bit)
15690 + write_nic_byte(dev, EPROM_CMD,
15691 + (1<<EPROM_CS_SHIFT) | \
15692 + read_nic_byte(dev, EPROM_CMD)); //enable EPROM
15693 + else
15694 + write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
15695 + &~(1<<EPROM_CS_SHIFT)); //disable EPROM
15696 +
15697 + force_pci_posting(dev);
15698 + udelay(EPROM_DELAY);
15699 +}
15700 +
15701 +
15702 +void eprom_ck_cycle(struct net_device *dev)
15703 +{
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);
15712 +}
15713 +
15714 +
15715 +void eprom_w(struct net_device *dev,short bit)
15716 +{
15717 + if(bit)
15718 + write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
15719 + read_nic_byte(dev,EPROM_CMD));
15720 + else
15721 + write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\
15722 + &~(1<<EPROM_W_SHIFT));
15723 +
15724 + force_pci_posting(dev);
15725 + udelay(EPROM_DELAY);
15726 +}
15727 +
15728 +
15729 +short eprom_r(struct net_device *dev)
15730 +{
15731 + short bit;
15732 +
15733 + bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) );
15734 + udelay(EPROM_DELAY);
15735 +
15736 + if(bit) return 1;
15737 + return 0;
15738 +}
15739 +
15740 +
15741 +void eprom_send_bits_string(struct net_device *dev, short b[], int len)
15742 +{
15743 + int i;
15744 +
15745 + for(i=0; i<len; i++){
15746 + eprom_w(dev, b[i]);
15747 + eprom_ck_cycle(dev);
15748 + }
15749 +}
15750 +
15751 +
15752 +u32 eprom_read(struct net_device *dev, u32 addr)
15753 +{
15754 + struct r8180_priv *priv = ieee80211_priv(dev);
15755 + short read_cmd[]={1,1,0};
15756 + short addr_str[8];
15757 + int i;
15758 + int addr_len;
15759 + u32 ret;
15760 +
15761 + ret=0;
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);
15767 +
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);
15777 + addr_len=8;
15778 + }else{
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);
15785 + addr_len=6;
15786 + }
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);
15791 +
15792 + //keep chip pin D to low state while reading.
15793 + //I'm unsure if it is necessary, but anyway shouldn't hurt
15794 + eprom_w(dev, 0);
15795 +
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));
15801 + }
15802 +
15803 + eprom_cs(dev, 0);
15804 + eprom_ck_cycle(dev);
15805 +
15806 + //disable EPROM programming
15807 + write_nic_byte(dev, EPROM_CMD,
15808 + (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
15809 + return ret;
15810 +}
15811 --- /dev/null
15812 +++ b/drivers/staging/rtl8187se/r8180_93cx6.h
15813 @@ -0,0 +1,59 @@
15814 +/*
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)
15818 +
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
15822 +
15823 + We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
15824 +*/
15825 +
15826 +/*This files contains card eeprom (93c46 or 93c56) programming routines*/
15827 +/*memory is addressed by WORDS*/
15828 +
15829 +#include "r8180.h"
15830 +#include "r8180_hw.h"
15831 +
15832 +#define EPROM_DELAY 10
15833 +
15834 +#define EPROM_ANAPARAM_ADDRLWORD 0xd
15835 +#define EPROM_ANAPARAM_ADDRHWORD 0xe
15836 +
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
15848 +#endif
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
15858 +
15859 +#define CIS 0x18
15860 +
15861 +#define EPROM_TXPW_OFDM_CH1_2 0x20
15862 +
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
15871 +
15872 +u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word
15873 --- /dev/null
15874 +++ b/drivers/staging/rtl8187se/r8180_core.c
15875 @@ -0,0 +1,6828 @@
15876 +/*
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)
15880 +
15881 + Parts of this driver are based on the GPL part of the official
15882 + Realtek driver.
15883 +
15884 + Parts of this driver are based on the rtl8180 driver skeleton
15885 + from Patric Schenke & Andres Salomon.
15886 +
15887 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
15888 +
15889 + Parts of BB/RF code are derived from David Young rtl8180 netbsd driver.
15890 +
15891 + RSSI calc function from 'The Deuce'
15892 +
15893 + Some ideas borrowed from the 8139too.c driver included in linux kernel.
15894 +
15895 + We (I?) want to thanks the Authors of those projecs and also the
15896 + Ndiswrapper's project Authors.
15897 +
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.
15900 +*/
15901 +
15902 +#if 0
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;}
15909 +#endif
15910 +
15911 +
15912 +#undef DEBUG_TX_DESC2
15913 +#undef RX_DONT_PASS_UL
15914 +#undef DEBUG_EPROM
15915 +#undef DEBUG_RX_VERBOSE
15916 +#undef DUMMY_RX
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
15922 +#undef DEBUG_TX
15923 +#undef DEBUG_IRQ
15924 +#undef DEBUG_RX
15925 +#undef DEBUG_RXALLOC
15926 +#undef DEBUG_REGISTERS
15927 +#undef DEBUG_RING
15928 +#undef DEBUG_IRQ_TASKLET
15929 +#undef DEBUG_TX_ALLOC
15930 +#undef DEBUG_TX_DESC
15931 +
15932 +//#define DEBUG_TX
15933 +//#define DEBUG_TX_DESC2
15934 +//#define DEBUG_RX
15935 +//#define DEBUG_RX_SKB
15936 +
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"
15951 +
15952 +#ifdef CONFIG_RTL8180_PM
15953 +#include "r8180_pm.h"
15954 +#endif
15955 +
15956 +#ifdef ENABLE_DOT11D
15957 +#include "dot11d.h"
15958 +#endif
15959 +
15960 +#ifdef CONFIG_RTL8185B
15961 +//#define CONFIG_RTL8180_IO_MAP
15962 +#endif
15963 +
15964 +#ifndef PCI_VENDOR_ID_BELKIN
15965 + #define PCI_VENDOR_ID_BELKIN 0x1799
15966 +#endif
15967 +#ifndef PCI_VENDOR_ID_DLINK
15968 + #define PCI_VENDOR_ID_DLINK 0x1186
15969 +#endif
15970 +
15971 +static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = {
15972 + {
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,
15979 + },
15980 +#if 0
15981 + {
15982 + .vendor = PCI_VENDOR_ID_BELKIN,
15983 + .device = 0x6001,
15984 + .subvendor = PCI_ANY_ID,
15985 + .subdevice = PCI_ANY_ID,
15986 + .driver_data = 1,
15987 + },
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,
15994 + },
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,
16001 + },
16002 + {
16003 + .vendor = PCI_VENDOR_ID_REALTEK,
16004 + .device = 0x8185,
16005 + .subvendor = PCI_ANY_ID,
16006 + .subdevice = PCI_ANY_ID,
16007 + .driver_data = 4,
16008 + },
16009 +#endif
16010 + {
16011 + .vendor = 0,
16012 + .device = 0,
16013 + .subvendor = 0,
16014 + .subdevice = 0,
16015 + .driver_data = 0,
16016 + }
16017 +};
16018 +
16019 +
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;
16025 +
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");
16032 +
16033 +
16034 +
16035 +/*
16036 +MODULE_PARM(ifname, "s");
16037 +MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
16038 +
16039 +MODULE_PARM(hwseqnum,"i");
16040 +MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
16041 +
16042 +MODULE_PARM(hwwep,"i");
16043 +MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
16044 +
16045 +MODULE_PARM(channels,"i");
16046 +MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
16047 +*/
16048 +
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);
16054 +#else
16055 +MODULE_PARM(ifname, "s");
16056 +MODULE_PARM(hwseqnum,"i");
16057 +MODULE_PARM(hwwep,"i");
16058 +MODULE_PARM(channels,"i");
16059 +#endif
16060 +
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");
16066 +
16067 +
16068 +static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
16069 + const struct pci_device_id *id);
16070 +
16071 +static void __devexit rtl8180_pci_remove(struct pci_dev *pdev);
16072 +
16073 +static void rtl8180_shutdown (struct pci_dev *pdev)
16074 +{
16075 + struct net_device *dev = pci_get_drvdata(pdev);
16076 + dev->stop(dev);
16077 + pci_disable_device(pdev);
16078 +}
16079 +
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 */
16088 +#else
16089 + .suspend = NULL, /* PM suspend fn */
16090 + .resume = NULL, /* PM resume fn */
16091 +#endif
16092 + .shutdown = rtl8180_shutdown,
16093 +};
16094 +
16095 +
16096 +
16097 +#ifdef CONFIG_RTL8180_IO_MAP
16098 +
16099 +u8 read_nic_byte(struct net_device *dev, int x)
16100 +{
16101 + return 0xff&inb(dev->base_addr +x);
16102 +}
16103 +
16104 +u32 read_nic_dword(struct net_device *dev, int x)
16105 +{
16106 + return inl(dev->base_addr +x);
16107 +}
16108 +
16109 +u16 read_nic_word(struct net_device *dev, int x)
16110 +{
16111 + return inw(dev->base_addr +x);
16112 +}
16113 +
16114 +void write_nic_byte(struct net_device *dev, int x,u8 y)
16115 +{
16116 + outb(y&0xff,dev->base_addr +x);
16117 +}
16118 +
16119 +void write_nic_word(struct net_device *dev, int x,u16 y)
16120 +{
16121 + outw(y,dev->base_addr +x);
16122 +}
16123 +
16124 +void write_nic_dword(struct net_device *dev, int x,u32 y)
16125 +{
16126 + outl(y,dev->base_addr +x);
16127 +}
16128 +
16129 +#else /* RTL_IO_MAP */
16130 +
16131 +u8 read_nic_byte(struct net_device *dev, int x)
16132 +{
16133 + return 0xff&readb((u8*)dev->mem_start +x);
16134 +}
16135 +
16136 +u32 read_nic_dword(struct net_device *dev, int x)
16137 +{
16138 + return readl((u8*)dev->mem_start +x);
16139 +}
16140 +
16141 +u16 read_nic_word(struct net_device *dev, int x)
16142 +{
16143 + return readw((u8*)dev->mem_start +x);
16144 +}
16145 +
16146 +void write_nic_byte(struct net_device *dev, int x,u8 y)
16147 +{
16148 + writeb(y,(u8*)dev->mem_start +x);
16149 + udelay(20);
16150 +}
16151 +
16152 +void write_nic_dword(struct net_device *dev, int x,u32 y)
16153 +{
16154 + writel(y,(u8*)dev->mem_start +x);
16155 + udelay(20);
16156 +}
16157 +
16158 +void write_nic_word(struct net_device *dev, int x,u16 y)
16159 +{
16160 + writew(y,(u8*)dev->mem_start +x);
16161 + udelay(20);
16162 +}
16163 +
16164 +#endif /* RTL_IO_MAP */
16165 +
16166 +
16167 +
16168 +
16169 +
16170 +inline void force_pci_posting(struct net_device *dev)
16171 +{
16172 + read_nic_byte(dev,EPROM_CMD);
16173 +#ifndef CONFIG_RTL8180_IO_MAP
16174 + mb();
16175 +#endif
16176 +}
16177 +
16178 +
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);
16185 +
16186 +/****************************************************************************
16187 + -----------------------------PROCFS STUFF-------------------------
16188 +*****************************************************************************/
16189 +
16190 +static struct proc_dir_entry *rtl8180_proc = NULL;
16191 +
16192 +static int proc_get_registers(char *page, char **start,
16193 + off_t offset, int count,
16194 + int *eof, void *data)
16195 +{
16196 + struct net_device *dev = data;
16197 +// struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16198 +
16199 + int len = 0;
16200 + int i,n;
16201 +
16202 + int max=0xff;
16203 +
16204 + /* This dump the current register page */
16205 + for(n=0;n<=max;)
16206 + {
16207 + //printk( "\nD: %2x> ", n);
16208 + len += snprintf(page + len, count - len,
16209 + "\nD: %2x > ",n);
16210 +
16211 + for(i=0;i<16 && n<=max;i++,n++)
16212 + len += snprintf(page + len, count - len,
16213 + "%2x ",read_nic_byte(dev,n));
16214 +
16215 + // printk("%2x ",read_nic_byte(dev,n));
16216 + }
16217 + len += snprintf(page + len, count - len,"\n");
16218 +
16219 +
16220 +
16221 + *eof = 1;
16222 + return len;
16223 +
16224 +}
16225 +
16226 +int get_curr_tx_free_desc(struct net_device *dev, int priority);
16227 +
16228 +static int proc_get_stats_hw(char *page, char **start,
16229 + off_t offset, int count,
16230 + int *eof, void *data)
16231 +{
16232 + //struct net_device *dev = data;
16233 + //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16234 +
16235 + int len = 0;
16236 +#ifdef CONFIG_RTL8185B
16237 +
16238 +#else
16239 + len += snprintf(page + len, count - len,
16240 + "NIC int: %lu\n"
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);
16276 +#endif
16277 + *eof = 1;
16278 + return len;
16279 +}
16280 +
16281 +
16282 +static int proc_get_stats_rx(char *page, char **start,
16283 + off_t offset, int count,
16284 + int *eof, void *data)
16285 +{
16286 + struct net_device *dev = data;
16287 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16288 +
16289 + int len = 0;
16290 +
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"
16300 + "RX int: %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 */
16316 + "RX OK: %lu\n"
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
16328 + );
16329 +
16330 + *eof = 1;
16331 + return len;
16332 +}
16333 +
16334 +#if 0
16335 +static int proc_get_stats_ieee(char *page, char **start,
16336 + off_t offset, int count,
16337 + int *eof, void *data)
16338 +{
16339 + struct net_device *dev = data;
16340 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16341 +
16342 + int len = 0;
16343 +
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);
16373 +
16374 + *eof = 1;
16375 + return len;
16376 +}
16377 +#endif
16378 +#if 0
16379 +static int proc_get_stats_ap(char *page, char **start,
16380 + off_t offset, int count,
16381 + int *eof, void *data)
16382 +{
16383 + struct net_device *dev = data;
16384 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16385 + struct mac_htable_t *list;
16386 + int i;
16387 + int len = 0;
16388 +
16389 + if(priv->ieee80211->iw_mode != IW_MODE_MASTER){
16390 + len += snprintf(page + len, count - len,
16391 + "Card is not acting as AP...\n"
16392 + );
16393 + }else{
16394 + len += snprintf(page + len, count - len,
16395 + "List of associated STA:\n"
16396 + );
16397 +
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));
16402 + }
16403 +
16404 + }
16405 + *eof = 1;
16406 + return len;
16407 +}
16408 +#endif
16409 +
16410 +static int proc_get_stats_tx(char *page, char **start,
16411 + off_t offset, int count,
16412 + int *eof, void *data)
16413 +{
16414 + struct net_device *dev = data;
16415 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16416 +
16417 + int len = 0;
16418 + unsigned long totalOK;
16419 +
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 */
16452 + "TX OK: %lu\n"
16453 + "TX Error: %lu\n"
16454 + "TX Retry: %lu\n"
16455 + "TX beacon OK: %lu\n"
16456 + "TX beacon error: %lu\n",
16457 + totalOK,
16458 + priv->stats.txnperr+priv->stats.txhperr+priv->stats.txlperr,
16459 + priv->stats.txretry,
16460 + priv->stats.txbeacon,
16461 + priv->stats.txbeaconerr
16462 + );
16463 +
16464 + *eof = 1;
16465 + return len;
16466 +}
16467 +
16468 +
16469 +#if WIRELESS_EXT < 17
16470 +static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
16471 +{
16472 + struct r8180_priv *priv = ieee80211_priv(dev);
16473 +
16474 + return &priv->wstats;
16475 +}
16476 +#endif
16477 +void rtl8180_proc_module_init(void)
16478 +{
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);
16482 +#else
16483 + rtl8180_proc=create_proc_entry(RTL8180_MODULE_NAME, S_IFDIR, init_net.proc_net);
16484 +#endif
16485 +}
16486 +
16487 +
16488 +void rtl8180_proc_module_remove(void)
16489 +{
16490 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
16491 + remove_proc_entry(RTL8180_MODULE_NAME, proc_net);
16492 +#else
16493 + remove_proc_entry(RTL8180_MODULE_NAME, init_net.proc_net);
16494 +#endif
16495 +}
16496 +
16497 +
16498 +void rtl8180_proc_remove_one(struct net_device *dev)
16499 +{
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;
16510 + }
16511 +}
16512 +
16513 +
16514 +void rtl8180_proc_init_one(struct net_device *dev)
16515 +{
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,
16520 + rtl8180_proc);
16521 + if (!priv->dir_dev) {
16522 + DMESGE("Unable to initialize /proc/net/rtl8180/%s\n",
16523 + dev->name);
16524 + return;
16525 + }
16526 +
16527 + e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO,
16528 + priv->dir_dev, proc_get_stats_hw, dev);
16529 +
16530 + if (!e) {
16531 + DMESGE("Unable to initialize "
16532 + "/proc/net/rtl8180/%s/stats-hw\n",
16533 + dev->name);
16534 + }
16535 +
16536 + e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
16537 + priv->dir_dev, proc_get_stats_rx, dev);
16538 +
16539 + if (!e) {
16540 + DMESGE("Unable to initialize "
16541 + "/proc/net/rtl8180/%s/stats-rx\n",
16542 + dev->name);
16543 + }
16544 +
16545 +
16546 + e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
16547 + priv->dir_dev, proc_get_stats_tx, dev);
16548 +
16549 + if (!e) {
16550 + DMESGE("Unable to initialize "
16551 + "/proc/net/rtl8180/%s/stats-tx\n",
16552 + dev->name);
16553 + }
16554 + #if 0
16555 + e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO,
16556 + priv->dir_dev, proc_get_stats_ieee, dev);
16557 +
16558 + if (!e) {
16559 + DMESGE("Unable to initialize "
16560 + "/proc/net/rtl8180/%s/stats-ieee\n",
16561 + dev->name);
16562 + }
16563 + #endif
16564 + #if 0
16565 + e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
16566 + priv->dir_dev, proc_get_stats_ap, dev);
16567 +
16568 + if (!e) {
16569 + DMESGE("Unable to initialize "
16570 + "/proc/net/rtl8180/%s/stats-ap\n",
16571 + dev->name);
16572 + }
16573 + #endif
16574 +
16575 + e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
16576 + priv->dir_dev, proc_get_registers, dev);
16577 +
16578 + if (!e) {
16579 + DMESGE("Unable to initialize "
16580 + "/proc/net/rtl8180/%s/registers\n",
16581 + dev->name);
16582 + }
16583 +}
16584 +/****************************************************************************
16585 + -----------------------------MISC STUFF-------------------------
16586 +*****************************************************************************/
16587 +/*
16588 + FIXME: check if we can use some standard already-existent
16589 + data type+functions in kernel
16590 +*/
16591 +
16592 +short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma,
16593 + struct buffer **bufferhead)
16594 +{
16595 +#ifdef DEBUG_RING
16596 + DMESG("adding buffer to TX/RX struct");
16597 +#endif
16598 +
16599 + struct buffer *tmp;
16600 +
16601 + if(! *buffer){
16602 +
16603 + *buffer = kmalloc(sizeof(struct buffer),GFP_KERNEL);
16604 +
16605 + if (*buffer == NULL) {
16606 + DMESGE("Failed to kmalloc head of TX/RX struct");
16607 + return -1;
16608 + }
16609 + (*buffer)->next=*buffer;
16610 + (*buffer)->buf=buf;
16611 + (*buffer)->dma=dma;
16612 + if(bufferhead !=NULL)
16613 + (*bufferhead) = (*buffer);
16614 + return 0;
16615 + }
16616 + tmp=*buffer;
16617 +
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");
16621 + return -1;
16622 + }
16623 + tmp->next->buf=buf;
16624 + tmp->next->dma=dma;
16625 + tmp->next->next=*buffer;
16626 +
16627 + return 0;
16628 +}
16629 +
16630 +
16631 +void buffer_free(struct net_device *dev,struct buffer **buffer,int len,short
16632 +consistent)
16633 +{
16634 +
16635 + struct buffer *tmp,*next;
16636 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16637 + struct pci_dev *pdev=priv->pdev;
16638 + //int i;
16639 +
16640 + if(! *buffer) return;
16641 +
16642 + /*for(tmp=*buffer; tmp->next != *buffer; tmp=tmp->next)
16643 +
16644 + */
16645 + tmp=*buffer;
16646 + do{
16647 + next=tmp->next;
16648 + if(consistent){
16649 + pci_free_consistent(pdev,len,
16650 + tmp->buf,tmp->dma);
16651 + }else{
16652 + pci_unmap_single(pdev, tmp->dma,
16653 + len,PCI_DMA_FROMDEVICE);
16654 + kfree(tmp->buf);
16655 + }
16656 + kfree(tmp);
16657 + tmp = next;
16658 + }
16659 + while(next != *buffer);
16660 +
16661 + *buffer=NULL;
16662 +}
16663 +
16664 +
16665 +void print_buffer(u32 *buffer, int len)
16666 +{
16667 + int i;
16668 + u8 *buf =(u8*)buffer;
16669 +
16670 + printk("ASCII BUFFER DUMP (len: %x):\n",len);
16671 +
16672 + for(i=0;i<len;i++)
16673 + printk("%c",buf[i]);
16674 +
16675 + printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
16676 +
16677 + for(i=0;i<len;i++)
16678 + printk("%02x",buf[i]);
16679 +
16680 + printk("\n");
16681 +}
16682 +
16683 +
16684 +int get_curr_tx_free_desc(struct net_device *dev, int priority)
16685 +{
16686 + struct r8180_priv *priv = ieee80211_priv(dev);
16687 + u32* tail;
16688 + u32* head;
16689 + int ret;
16690 +
16691 + switch (priority){
16692 + case MANAGE_PRIORITY:
16693 + head = priv->txmapringhead;
16694 + tail = priv->txmapringtail;
16695 + break;
16696 + case BK_PRIORITY:
16697 + head = priv->txbkpringhead;
16698 + tail = priv->txbkpringtail;
16699 + break;
16700 + case BE_PRIORITY:
16701 + head = priv->txbepringhead;
16702 + tail = priv->txbepringtail;
16703 + break;
16704 + case VI_PRIORITY:
16705 + head = priv->txvipringhead;
16706 + tail = priv->txvipringtail;
16707 + break;
16708 + case VO_PRIORITY:
16709 + head = priv->txvopringhead;
16710 + tail = priv->txvopringtail;
16711 + break;
16712 + case HI_PRIORITY:
16713 + head = priv->txhpringhead;
16714 + tail = priv->txhpringtail;
16715 + break;
16716 + default:
16717 + return -1;
16718 + }
16719 +
16720 + //DMESG("%x %x", head, tail);
16721 +
16722 + /* FIXME FIXME FIXME FIXME */
16723 +
16724 +#if 0
16725 + if( head <= tail ) return priv->txringcount-1 - (tail - head)/8;
16726 + return (head - tail)/8/4;
16727 +#else
16728 + if( head <= tail )
16729 + ret = priv->txringcount - (tail - head)/8;
16730 + else
16731 + ret = (head - tail)/8;
16732 +
16733 + if(ret > priv->txringcount ) DMESG("BUG");
16734 + return ret;
16735 +#endif
16736 +}
16737 +
16738 +
16739 +short check_nic_enought_desc(struct net_device *dev, int priority)
16740 +{
16741 + struct r8180_priv *priv = ieee80211_priv(dev);
16742 + struct ieee80211_device *ieee = netdev_priv(dev);
16743 +
16744 + int requiredbyte, required;
16745 + requiredbyte = priv->ieee80211->fts + sizeof(struct ieee80211_header_data);
16746 +
16747 + if(ieee->current_network.QoS_Enable) {
16748 + requiredbyte += 2;
16749 + };
16750 +
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
16755 + */
16756 +
16757 + return (required+2 < get_curr_tx_free_desc(dev,priority));
16758 +}
16759 +
16760 +
16761 +/* This function is only for debuging purpose */
16762 +void check_tx_ring(struct net_device *dev, int pri)
16763 +{
16764 + static int maxlog =3;
16765 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16766 + u32* tmp;
16767 + struct buffer *buf;
16768 + int i;
16769 + int nic;
16770 + u32* tail;
16771 + u32* head;
16772 + u32* begin;
16773 + u32 nicbegin;
16774 + struct buffer* buffer;
16775 +
16776 + maxlog --;
16777 + if (maxlog <0 ) return;
16778 +
16779 + switch(pri) {
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;
16787 + break;
16788 +
16789 +
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;
16797 + break;
16798 +
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;
16806 + break;
16807 +
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;
16815 + break;
16816 +
16817 +
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;
16825 + break;
16826 +
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;
16834 + break;
16835 +
16836 + default:
16837 + return ;
16838 + break;
16839 + }
16840 +
16841 + if(!priv->txvopbufs)
16842 + DMESGE ("NIC TX ack, but TX queue corrupted!");
16843 + else{
16844 +
16845 + for(i=0,buf=buffer, tmp=begin;
16846 + tmp<begin+(priv->txringcount)*8;
16847 + tmp+=8,buf=buf->next,i++)
16848 +
16849 + DMESG("BUF%d %s %x %s. Next : %x",i,
16850 + *tmp & (1<<31) ? "filled" : "empty",
16851 + *(buf->buf),
16852 + *tmp & (1<<15)? "ok": "err", *(tmp+4));
16853 + }
16854 +
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);
16862 + return;
16863 +}
16864 +
16865 +
16866 +
16867 +/* this function is only for debugging purpose */
16868 +void check_rxbuf(struct net_device *dev)
16869 +{
16870 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16871 + u32* tmp;
16872 + struct buffer *buf;
16873 + u8 rx_desc_size;
16874 +
16875 +#ifdef CONFIG_RTL8185B
16876 + rx_desc_size = 8;
16877 +#else
16878 + rx_desc_size = 4;
16879 +#endif
16880 +
16881 + if(!priv->rxbuffer)
16882 + DMESGE ("NIC RX ack, but RX queue corrupted!");
16883 +
16884 + else{
16885 +
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)
16889 +
16890 + DMESG("BUF %s %x",
16891 + *tmp & (1<<31) ? "empty" : "filled",
16892 + *(buf->buf));
16893 + }
16894 +
16895 + return;
16896 +}
16897 +
16898 +
16899 +void dump_eprom(struct net_device *dev)
16900 +{
16901 + int i;
16902 + for(i=0; i<63; i++)
16903 + DMESG("EEPROM addr %x : %x", i, eprom_read(dev,i));
16904 +}
16905 +
16906 +
16907 +void rtl8180_dump_reg(struct net_device *dev)
16908 +{
16909 + int i;
16910 + int n;
16911 + int max=0xff;
16912 +
16913 + DMESG("Dumping NIC register map");
16914 +
16915 + for(n=0;n<=max;)
16916 + {
16917 + printk( "\nD: %2x> ", n);
16918 + for(i=0;i<16 && n<=max;i++,n++)
16919 + printk("%2x ",read_nic_byte(dev,n));
16920 + }
16921 + printk("\n");
16922 +}
16923 +
16924 +
16925 +void fix_tx_fifo(struct net_device *dev)
16926 +{
16927 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16928 + u32 *tmp;
16929 + int i;
16930 +#ifdef DEBUG_TX_ALLOC
16931 + DMESG("FIXING TX FIFOs");
16932 +#endif
16933 + for (tmp=priv->txmapring, i=0;
16934 + i < priv->txringcount;
16935 + tmp+=8, i++){
16936 + *tmp = *tmp &~ (1<<31);
16937 + }
16938 +
16939 + for (tmp=priv->txbkpring, i=0;
16940 + i < priv->txringcount;
16941 + tmp+=8, i++) {
16942 + *tmp = *tmp &~ (1<<31);
16943 + }
16944 +
16945 + for (tmp=priv->txbepring, i=0;
16946 + i < priv->txringcount;
16947 + tmp+=8, i++){
16948 + *tmp = *tmp &~ (1<<31);
16949 + }
16950 + for (tmp=priv->txvipring, i=0;
16951 + i < priv->txringcount;
16952 + tmp+=8, i++) {
16953 + *tmp = *tmp &~ (1<<31);
16954 + }
16955 +
16956 + for (tmp=priv->txvopring, i=0;
16957 + i < priv->txringcount;
16958 + tmp+=8, i++){
16959 + *tmp = *tmp &~ (1<<31);
16960 + }
16961 +
16962 + for (tmp=priv->txhpring, i=0;
16963 + i < priv->txringcount;
16964 + tmp+=8,i++){
16965 + *tmp = *tmp &~ (1<<31);
16966 + }
16967 +
16968 + for (tmp=priv->txbeaconring, i=0;
16969 + i < priv->txbeaconcount;
16970 + tmp+=8, i++){
16971 + *tmp = *tmp &~ (1<<31);
16972 + }
16973 +#ifdef DEBUG_TX_ALLOC
16974 + DMESG("TX FIFOs FIXED");
16975 +#endif
16976 + priv->txmapringtail = priv->txmapring;
16977 + priv->txmapringhead = priv->txmapring;
16978 + priv->txmapbufstail = priv->txmapbufs;
16979 +
16980 + priv->txbkpringtail = priv->txbkpring;
16981 + priv->txbkpringhead = priv->txbkpring;
16982 + priv->txbkpbufstail = priv->txbkpbufs;
16983 +
16984 + priv->txbepringtail = priv->txbepring;
16985 + priv->txbepringhead = priv->txbepring;
16986 + priv->txbepbufstail = priv->txbepbufs;
16987 +
16988 + priv->txvipringtail = priv->txvipring;
16989 + priv->txvipringhead = priv->txvipring;
16990 + priv->txvipbufstail = priv->txvipbufs;
16991 +
16992 + priv->txvopringtail = priv->txvopring;
16993 + priv->txvopringhead = priv->txvopring;
16994 + priv->txvopbufstail = priv->txvopbufs;
16995 +
16996 + priv->txhpringtail = priv->txhpring;
16997 + priv->txhpringhead = priv->txhpring;
16998 + priv->txhpbufstail = priv->txhpbufs;
16999 +
17000 + priv->txbeaconringtail = priv->txbeaconring;
17001 + priv->txbeaconbufstail = priv->txbeaconbufs;
17002 + set_nic_txring(dev);
17003 +
17004 + ieee80211_reset_queue(priv->ieee80211);
17005 + priv->ack_tx_to_ieee = 0;
17006 +}
17007 +
17008 +
17009 +void fix_rx_fifo(struct net_device *dev)
17010 +{
17011 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17012 + u32 *tmp;
17013 + struct buffer *rxbuf;
17014 + u8 rx_desc_size;
17015 +
17016 +#ifdef CONFIG_RTL8185B
17017 + rx_desc_size = 8; // 4*8 = 32 bytes
17018 +#else
17019 + rx_desc_size = 4;
17020 +#endif
17021 +
17022 +#ifdef DEBUG_RXALLOC
17023 + DMESG("FIXING RX FIFO");
17024 + check_rxbuf(dev);
17025 +#endif
17026 +
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;
17033 + *tmp |= (1<<31);
17034 + }
17035 +
17036 +#ifdef DEBUG_RXALLOC
17037 + DMESG("RX FIFO FIXED");
17038 + check_rxbuf(dev);
17039 +#endif
17040 +
17041 + priv->rxringtail=priv->rxring;
17042 + priv->rxbuffer=priv->rxbufferhead;
17043 + priv->rx_skb_complete=1;
17044 + set_nic_rxring(dev);
17045 +}
17046 +
17047 +
17048 +/****************************************************************************
17049 + ------------------------------HW STUFF---------------------------
17050 +*****************************************************************************/
17051 +
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
17063 +};
17064 +
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
17076 +};
17077 +
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);
17081 + u32 temp;
17082 + u32 temp2;
17083 + u32 temp3;
17084 + u32 lsb;
17085 + u32 q;
17086 + u32 orig_qual;
17087 + u8 _rssi;
17088 +
17089 + q = *qual;
17090 + orig_qual = *qual;
17091 + _rssi = 0; // avoid gcc complains..
17092 +
17093 + if (q <= 0x4e) {
17094 + temp = QUALITY_MAP[q];
17095 + } else {
17096 + if( q & 0x80 ) {
17097 + temp = 0x32;
17098 + } else {
17099 + temp = 1;
17100 + }
17101 + }
17102 +
17103 + *qual = temp;
17104 + temp2 = *rssi;
17105 +
17106 + switch(priv->rf_chip){
17107 + case RFCHIPID_RFMD:
17108 + lsb = temp2 & 1;
17109 + temp2 &= 0x7e;
17110 + if ( !lsb || !(temp2 <= 0x3c) ) {
17111 + temp2 = 0x64;
17112 + } else {
17113 + temp2 = 100 * temp2 / 0x3c;
17114 + }
17115 + *rssi = temp2 & 0xff;
17116 + _rssi = temp2 & 0xff;
17117 + break;
17118 + case RFCHIPID_INTERSIL:
17119 + lsb = temp2;
17120 + temp2 &= 0xfffffffe;
17121 + temp2 *= 251;
17122 + temp3 = temp2;
17123 + temp2 <<= 6;
17124 + temp3 += temp2;
17125 + temp3 <<= 1;
17126 + temp2 = 0x4950df;
17127 + temp2 -= temp3;
17128 + lsb &= 1;
17129 + if ( temp2 <= 0x3e0000 ) {
17130 + if ( temp2 < 0xffef0000 )
17131 + temp2 = 0xffef0000;
17132 + } else {
17133 + temp2 = 0x3e0000;
17134 + }
17135 + if ( !lsb ) {
17136 + temp2 -= 0xf0000;
17137 + } else {
17138 + temp2 += 0xf0000;
17139 + }
17140 +
17141 + temp3 = 0x4d0000;
17142 + temp3 -= temp2;
17143 + temp3 *= 100;
17144 + temp3 = temp3 / 0x6d;
17145 + temp3 >>= 0x10;
17146 + _rssi = temp3 & 0xff;
17147 + *rssi = temp3 & 0xff;
17148 + break;
17149 + case RFCHIPID_GCT:
17150 + lsb = temp2 & 1;
17151 + temp2 &= 0x7e;
17152 + if ( ! lsb || !(temp2 <= 0x3c) ){
17153 + temp2 = 0x64;
17154 + } else {
17155 + temp2 = (100 * temp2) / 0x3c;
17156 + }
17157 + *rssi = temp2 & 0xff;
17158 + _rssi = temp2 & 0xff;
17159 + break;
17160 + case RFCHIPID_PHILIPS:
17161 + if( orig_qual <= 0x4e ){
17162 + _rssi = STRENGTH_MAP[orig_qual];
17163 + *rssi = _rssi;
17164 + } else {
17165 + orig_qual -= 0x80;
17166 + if ( !orig_qual ){
17167 + _rssi = 1;
17168 + *rssi = 1;
17169 + } else {
17170 + _rssi = 0x32;
17171 + *rssi = 0x32;
17172 + }
17173 + }
17174 + break;
17175 +
17176 + /* case 4 */
17177 + case RFCHIPID_MAXIM:
17178 + lsb = temp2 & 1;
17179 + temp2 &= 0x7e;
17180 + temp2 >>= 1;
17181 + temp2 += 0x42;
17182 + if( lsb != 0 ){
17183 + temp2 += 0xa;
17184 + }
17185 + *rssi = temp2 & 0xff;
17186 + _rssi = temp2 & 0xff;
17187 + break;
17188 + }
17189 +
17190 + if ( _rssi < 0x64 ){
17191 + if ( _rssi == 0 ) {
17192 + *rssi = 1;
17193 + }
17194 + } else {
17195 + *rssi = 0x64;
17196 + }
17197 +
17198 + return;
17199 +}
17200 +
17201 +
17202 +void rtl8180_irq_enable(struct net_device *dev)
17203 +{
17204 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17205 + priv->irq_enabled = 1;
17206 +/*
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);
17211 +*/
17212 + write_nic_word(dev,INTA_MASK, priv->irq_mask);
17213 +}
17214 +
17215 +
17216 +void rtl8180_irq_disable(struct net_device *dev)
17217 +{
17218 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17219 +
17220 +#ifdef CONFIG_RTL8185B
17221 + write_nic_dword(dev,IMR,0);
17222 +#else
17223 + write_nic_word(dev,INTA_MASK,0);
17224 +#endif
17225 + force_pci_posting(dev);
17226 + priv->irq_enabled = 0;
17227 +}
17228 +
17229 +
17230 +void rtl8180_set_mode(struct net_device *dev,int mode)
17231 +{
17232 + u8 ecmd;
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);
17239 +}
17240 +
17241 +void rtl8180_adapter_start(struct net_device *dev);
17242 +void rtl8180_beacon_tx_enable(struct net_device *dev);
17243 +
17244 +void rtl8180_update_msr(struct net_device *dev)
17245 +{
17246 + struct r8180_priv *priv = ieee80211_priv(dev);
17247 + u8 msr;
17248 + u32 rxconf;
17249 +
17250 + msr = read_nic_byte(dev, MSR);
17251 + msr &= ~ MSR_LINK_MASK;
17252 +
17253 + rxconf=read_nic_dword(dev,RX_CONF);
17254 +
17255 + if(priv->ieee80211->state == IEEE80211_LINKED)
17256 + {
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);
17263 + else
17264 + msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
17265 + rxconf |= (1<<RX_CHECK_BSSID_SHIFT);
17266 +
17267 + }else {
17268 + msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
17269 + rxconf &= ~(1<<RX_CHECK_BSSID_SHIFT);
17270 + }
17271 +
17272 + write_nic_byte(dev, MSR, msr);
17273 + write_nic_dword(dev, RX_CONF, rxconf);
17274 +
17275 +}
17276 +
17277 +
17278 +
17279 +void rtl8180_set_chan(struct net_device *dev,short ch)
17280 +{
17281 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17282 +
17283 + if((ch > 14) || (ch < 1))
17284 + {
17285 + printk("In %s: Invalid chnanel %d\n", __FUNCTION__, ch);
17286 + return;
17287 + }
17288 +
17289 + priv->chan=ch;
17290 + //printk("in %s:channel is %d\n",__FUNCTION__,ch);
17291 + priv->rf_set_chan(dev,priv->chan);
17292 +
17293 +}
17294 +
17295 +
17296 +void rtl8180_rx_enable(struct net_device *dev)
17297 +{
17298 + u8 cmd;
17299 + u32 rxconf;
17300 + /* for now we accept data, management & ctl frame*/
17301 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17302 +
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");
17311 +
17312 + if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
17313 + dev->flags & IFF_PROMISC){
17314 + rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
17315 + }else{
17316 + rxconf = rxconf | (1<<ACCEPT_NICMAC_FRAME_SHIFT);
17317 + if(priv->card_8185 == 0)
17318 + rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
17319 + }
17320 +
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);
17324 + }*/
17325 +
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);
17330 + }
17331 +
17332 + if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
17333 + rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
17334 +
17335 + //if(!priv->card_8185){
17336 + rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
17337 + rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
17338 + //}
17339 +
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);
17343 +
17344 + //if(!priv->card_8185)
17345 + rxconf = rxconf | RCR_ONLYERLPKT;
17346 +
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);
17353 +
17354 + fix_rx_fifo(dev);
17355 +
17356 +#ifdef DEBUG_RX
17357 + DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RX_CONF));
17358 +#endif
17359 + cmd=read_nic_byte(dev,CMD);
17360 + write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
17361 +
17362 + /* In rtl8139 driver seems that DMA threshold has to be written
17363 + * after enabling RX, so we rewrite RX_CONFIG register
17364 + */
17365 + //mdelay(100);
17366 +// write_nic_dword(dev, RX_CONF, rxconf);
17367 +
17368 +}
17369 +
17370 +
17371 +void set_nic_txring(struct net_device *dev)
17372 +{
17373 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17374 +// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
17375 +
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));
17388 +
17389 + write_nic_dword(dev, TX_BEACON_RING_ADDR, priv->txbeaconringdma);
17390 +}
17391 +
17392 +
17393 +void rtl8180_conttx_enable(struct net_device *dev)
17394 +{
17395 + u32 txconf;
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);
17400 +}
17401 +
17402 +
17403 +void rtl8180_conttx_disable(struct net_device *dev)
17404 +{
17405 + u32 txconf;
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);
17410 +}
17411 +
17412 +
17413 +void rtl8180_tx_enable(struct net_device *dev)
17414 +{
17415 + u8 cmd;
17416 + u8 tx_agc_ctl;
17417 + u8 byte;
17418 + u32 txconf;
17419 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17420 + txconf= read_nic_dword(dev,TX_CONF);
17421 +
17422 +
17423 + if(priv->card_8185){
17424 +
17425 +
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);
17430 +
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);
17436 + /*
17437 + write_nic_word(dev, 0x5e, 0x01);
17438 + force_pci_posting(dev);
17439 + mdelay(1);
17440 + write_nic_word(dev, 0xfe, 0x10);
17441 + force_pci_posting(dev);
17442 + mdelay(1);
17443 + write_nic_word(dev, 0x5e, 0x00);
17444 + force_pci_posting(dev);
17445 + mdelay(1);
17446 + */
17447 + write_nic_byte(dev, 0xec, 0x3f); /* Disable early TX */
17448 + }
17449 +
17450 + if(priv->card_8185){
17451 +
17452 + txconf = txconf &~ (1<<TCR_PROBE_NOTIMESTAMP_SHIFT);
17453 +
17454 + }else{
17455 +
17456 + if(hwseqnum)
17457 + txconf= txconf &~ (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
17458 + else
17459 + txconf= txconf | (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
17460 + }
17461 +
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);
17469 +
17470 + if(priv->card_8185){
17471 + if(priv->hw_plcp_len)
17472 + txconf = txconf &~ TCR_PLCP_LEN;
17473 + else
17474 + txconf = txconf | TCR_PLCP_LEN;
17475 + }else{
17476 + txconf = txconf &~ TCR_SAT;
17477 + }
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;
17482 +
17483 +// if(priv->ieee80211->hw_wep)
17484 +// txconf=txconf &~ (1<<TX_NOICV_SHIFT);
17485 +// else
17486 + txconf=txconf | (1<<TX_NOICV_SHIFT);
17487 +
17488 + write_nic_dword(dev,TX_CONF,txconf);
17489 +
17490 +
17491 + fix_tx_fifo(dev);
17492 +
17493 +#ifdef DEBUG_TX
17494 + DMESG("txconf: %x %x",txconf,read_nic_dword(dev,TX_CONF));
17495 +#endif
17496 +
17497 + cmd=read_nic_byte(dev,CMD);
17498 + write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
17499 +
17500 +// mdelay(100);
17501 + write_nic_dword(dev,TX_CONF,txconf);
17502 +// #endif
17503 +/*
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);
17507 + */
17508 +}
17509 +
17510 +
17511 +void rtl8180_beacon_tx_enable(struct net_device *dev)
17512 +{
17513 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17514 +
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);
17519 +#else
17520 + priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
17521 + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
17522 +#endif
17523 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
17524 +}
17525 +
17526 +
17527 +void rtl8180_beacon_tx_disable(struct net_device *dev)
17528 +{
17529 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17530 +
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);
17535 +#else
17536 + priv->dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
17537 + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
17538 +#endif
17539 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
17540 +
17541 +}
17542 +
17543 +
17544 +void rtl8180_rtx_disable(struct net_device *dev)
17545 +{
17546 + u8 cmd;
17547 + struct r8180_priv *priv = ieee80211_priv(dev);
17548 +
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);
17553 + mdelay(10);
17554 + /*while (read_nic_byte(dev,CMD) & (1<<CMD_RX_ENABLE_SHIFT))
17555 + udelay(10);
17556 + */
17557 +
17558 + if(!priv->rx_skb_complete)
17559 + dev_kfree_skb_any(priv->rx_skb);
17560 +}
17561 +
17562 +#if 0
17563 +int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
17564 +{
17565 + int i;
17566 + u32 *tmp;
17567 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17568 +
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
17575 + /*
17576 + *(tmp+2) = (u32)dma_tmp;
17577 + *(tmp+3) = bufsize;
17578 + */
17579 + if(i+1<count)
17580 + *(tmp+4) = (u32)priv->txbeaconringdma+((i+1)*8*4);
17581 + else
17582 + *(tmp+4) = (u32)priv->txbeaconringdma;
17583 +
17584 + tmp=tmp+8;
17585 + }
17586 + return 0;
17587 +}
17588 +#endif
17589 +
17590 +short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
17591 + int addr)
17592 +{
17593 + int i;
17594 + u32 *desc;
17595 + u32 *tmp;
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;
17599 + void *buf;
17600 +
17601 + if((bufsize & 0xfff) != bufsize) {
17602 + DMESGE ("TX buffer allocation too large");
17603 + return 0;
17604 + }
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){
17609 +
17610 + /*
17611 + * descriptor's buffer must be 256 byte aligned
17612 + * we shouldn't be here, since we set DMA mask !
17613 + */
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);
17620 +#else
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);
17624 +#endif
17625 + }
17626 + tmp=desc;
17627 + for (i=0;i<count;i++)
17628 + {
17629 + buf = (void*)pci_alloc_consistent(pdev,bufsize,&dma_tmp);
17630 + if (buf == NULL) return -ENOMEM;
17631 +
17632 + switch(addr) {
17633 +#if 0
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");
17637 + return -ENOMEM;
17638 + }
17639 + break;
17640 +
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");
17644 + return -ENOMEM;
17645 + }
17646 + break;
17647 +
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");
17651 + return -ENOMEM;
17652 + }
17653 + break;
17654 +#else
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");
17658 + return -ENOMEM;
17659 + }
17660 + break;
17661 +
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");
17665 + return -ENOMEM;
17666 + }
17667 + break;
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");
17671 + return -ENOMEM;
17672 + }
17673 + break;
17674 +
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");
17678 + return -ENOMEM;
17679 + }
17680 + break;
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");
17684 + return -ENOMEM;
17685 + }
17686 + break;
17687 +#endif
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");
17691 + return -ENOMEM;
17692 + }
17693 + break;
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");
17697 + return -ENOMEM;
17698 + }
17699 + break;
17700 + }
17701 + *tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv
17702 + *(tmp+2) = (u32)dma_tmp;
17703 + *(tmp+3) = bufsize;
17704 +
17705 + if(i+1<count)
17706 + *(tmp+4) = (u32)dma_desc+((i+1)*8*4);
17707 + else
17708 + *(tmp+4) = (u32)dma_desc;
17709 +
17710 + tmp=tmp+8;
17711 + }
17712 +
17713 + switch(addr) {
17714 + case TX_MANAGEPRIORITY_RING_ADDR:
17715 + priv->txmapringdma=dma_desc;
17716 + priv->txmapring=desc;
17717 + break;
17718 +
17719 + case TX_BKPRIORITY_RING_ADDR:
17720 + priv->txbkpringdma=dma_desc;
17721 + priv->txbkpring=desc;
17722 + break;
17723 +
17724 + case TX_BEPRIORITY_RING_ADDR:
17725 + priv->txbepringdma=dma_desc;
17726 + priv->txbepring=desc;
17727 + break;
17728 +
17729 + case TX_VIPRIORITY_RING_ADDR:
17730 + priv->txvipringdma=dma_desc;
17731 + priv->txvipring=desc;
17732 + break;
17733 +
17734 + case TX_VOPRIORITY_RING_ADDR:
17735 + priv->txvopringdma=dma_desc;
17736 + priv->txvopring=desc;
17737 + break;
17738 +
17739 + case TX_HIGHPRIORITY_RING_ADDR:
17740 + priv->txhpringdma=dma_desc;
17741 + priv->txhpring=desc;
17742 + break;
17743 +
17744 + case TX_BEACON_RING_ADDR:
17745 + priv->txbeaconringdma=dma_desc;
17746 + priv->txbeaconring=desc;
17747 + break;
17748 +
17749 + }
17750 +
17751 +#ifdef DEBUG_TX
17752 + DMESG("Tx dma physical address: %x",dma_desc);
17753 +#endif
17754 +
17755 + return 0;
17756 +}
17757 +
17758 +
17759 +void free_tx_desc_rings(struct net_device *dev)
17760 +{
17761 +
17762 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17763 + struct pci_dev *pdev=priv->pdev;
17764 + int count = priv->txringcount;
17765 +
17766 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17767 + priv->txmapring, priv->txmapringdma);
17768 + buffer_free(dev,&(priv->txmapbufs),priv->txbuffsize,1);
17769 +
17770 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17771 + priv->txbkpring, priv->txbkpringdma);
17772 + buffer_free(dev,&(priv->txbkpbufs),priv->txbuffsize,1);
17773 +
17774 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17775 + priv->txbepring, priv->txbepringdma);
17776 + buffer_free(dev,&(priv->txbepbufs),priv->txbuffsize,1);
17777 +
17778 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17779 + priv->txvipring, priv->txvipringdma);
17780 + buffer_free(dev,&(priv->txvipbufs),priv->txbuffsize,1);
17781 +
17782 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17783 + priv->txvopring, priv->txvopringdma);
17784 + buffer_free(dev,&(priv->txvopbufs),priv->txbuffsize,1);
17785 +
17786 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17787 + priv->txhpring, priv->txhpringdma);
17788 + buffer_free(dev,&(priv->txhpbufs),priv->txbuffsize,1);
17789 +
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);
17794 +}
17795 +
17796 +#if 0
17797 +void free_beacon_desc_ring(struct net_device *dev,int count)
17798 +{
17799 +
17800 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17801 + struct pci_dev *pdev=priv->pdev;
17802 +
17803 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17804 + priv->txbeaconring, priv->txbeaconringdma);
17805 +
17806 + if (priv->beacon_buf)
17807 + pci_free_consistent(priv->pdev,
17808 + priv->master_beaconsize,priv->beacon_buf,priv->beacondmabuf);
17809 +
17810 +}
17811 +#endif
17812 +void free_rx_desc_ring(struct net_device *dev)
17813 +{
17814 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17815 + struct pci_dev *pdev = priv->pdev;
17816 +
17817 + int count = priv->rxringcount;
17818 +
17819 +#ifdef CONFIG_RTL8185B
17820 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17821 + priv->rxring, priv->rxringdma);
17822 +#else
17823 + pci_free_consistent(pdev, sizeof(u32)*4*count+256,
17824 + priv->rxring, priv->rxringdma);
17825 +#endif
17826 +
17827 + buffer_free(dev,&(priv->rxbuffer),priv->rxbuffersize,0);
17828 +}
17829 +
17830 +
17831 +short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count)
17832 +{
17833 + int i;
17834 + u32 *desc;
17835 + u32 *tmp;
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;
17839 + void *buf;
17840 + u8 rx_desc_size;
17841 +
17842 +#ifdef CONFIG_RTL8185B
17843 + rx_desc_size = 8; // 4*8 = 32 bytes
17844 +#else
17845 + rx_desc_size = 4;
17846 +#endif
17847 +
17848 + if((bufsize & 0xfff) != bufsize){
17849 + DMESGE ("RX buffer allocation too large");
17850 + return -1;
17851 + }
17852 +
17853 + desc = (u32*)pci_alloc_consistent(pdev,sizeof(u32)*rx_desc_size*count+256,
17854 + &dma_desc);
17855 +
17856 + if(dma_desc & 0xff){
17857 +
17858 + /*
17859 + * descriptor's buffer must be 256 byte aligned
17860 + * should never happen since we specify the DMA mask
17861 + */
17862 +
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);
17869 +#else
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);
17873 +#endif
17874 + }
17875 +
17876 + priv->rxring=desc;
17877 + priv->rxringdma=dma_desc;
17878 + tmp=desc;
17879 +
17880 + for (i=0;i<count;i++){
17881 +
17882 + if ((buf= kmalloc(bufsize * sizeof(u8),GFP_ATOMIC)) == NULL){
17883 + DMESGE("Failed to kmalloc RX buffer");
17884 + return -1;
17885 + }
17886 +
17887 + dma_tmp = pci_map_single(pdev,buf,bufsize * sizeof(u8),
17888 + PCI_DMA_FROMDEVICE);
17889 +
17890 +#ifdef DEBUG_ZERO_RX
17891 + int j;
17892 + for(j=0;j<bufsize;j++) ((u8*)buf)[i] = 0;
17893 +#endif
17894 +
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");
17899 + return -1;
17900 + }
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
17905 +
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);
17909 +#endif
17910 +
17911 + tmp=tmp+rx_desc_size;
17912 + }
17913 +
17914 + *(tmp-rx_desc_size) = *(tmp-rx_desc_size) | (1<<30); // this is the last descriptor
17915 +
17916 +
17917 +#ifdef DEBUG_RXALLOC
17918 + DMESG("RX DMA physical address: %x",dma_desc);
17919 +#endif
17920 +
17921 + return 0;
17922 +}
17923 +
17924 +
17925 +void set_nic_rxring(struct net_device *dev)
17926 +{
17927 + u8 pgreg;
17928 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17929 +
17930 + //rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
17931 +
17932 + pgreg=read_nic_byte(dev, PGSELECT);
17933 + write_nic_byte(dev, PGSELECT, pgreg &~ (1<<PGSELECT_PG_SHIFT));
17934 +
17935 + //rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
17936 +
17937 + write_nic_dword(dev, RXRING_ADDR,priv->rxringdma);
17938 +}
17939 +
17940 +
17941 +void rtl8180_reset(struct net_device *dev)
17942 +{
17943 + //u32 txconf = 0x80e00707; //FIXME: Make me understandable
17944 + u8 cr;
17945 +
17946 + //write_nic_dword(dev,TX_CONF,txconf);
17947 +
17948 + rtl8180_irq_disable(dev);
17949 +
17950 + cr=read_nic_byte(dev,CMD);
17951 + cr = cr & 2;
17952 + cr = cr | (1<<CMD_RST_SHIFT);
17953 + write_nic_byte(dev,CMD,cr);
17954 +
17955 + force_pci_posting(dev);
17956 +
17957 + mdelay(200);
17958 +
17959 + if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT))
17960 + DMESGW("Card reset timeout!");
17961 + else
17962 + DMESG("Card successfully reset");
17963 +
17964 +//#ifndef CONFIG_RTL8185B
17965 + rtl8180_set_mode(dev,EPROM_CMD_LOAD);
17966 + force_pci_posting(dev);
17967 + mdelay(200);
17968 +//#endif
17969 +}
17970 +
17971 +inline u16 ieeerate2rtlrate(int rate)
17972 +{
17973 + switch(rate){
17974 + case 10:
17975 + return 0;
17976 + case 20:
17977 + return 1;
17978 + case 55:
17979 + return 2;
17980 + case 110:
17981 + return 3;
17982 + case 60:
17983 + return 4;
17984 + case 90:
17985 + return 5;
17986 + case 120:
17987 + return 6;
17988 + case 180:
17989 + return 7;
17990 + case 240:
17991 + return 8;
17992 + case 360:
17993 + return 9;
17994 + case 480:
17995 + return 10;
17996 + case 540:
17997 + return 11;
17998 + default:
17999 + return 3;
18000 +
18001 + }
18002 +}
18003 +
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)
18006 +{
18007 + if (rate >12) return 10;
18008 + return rtl_rate[rate];
18009 +}
18010 +inline u8 rtl8180_IsWirelessBMode(u16 rate)
18011 +{
18012 + if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
18013 + return 1;
18014 + else return 0;
18015 +}
18016 +u16 N_DBPSOfRate(u16 DataRate);
18017 +u16 ComputeTxTime(
18018 + u16 FrameLength,
18019 + u16 DataRate,
18020 + u8 bManagementFrame,
18021 + u8 bShortPreamble
18022 +)
18023 +{
18024 + u16 FrameTime;
18025 + u16 N_DBPS;
18026 + u16 Ceiling;
18027 +
18028 + if( rtl8180_IsWirelessBMode(DataRate) )
18029 + {
18030 + if( bManagementFrame || !bShortPreamble || DataRate == 10 )
18031 + { // long preamble
18032 + FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
18033 + }
18034 + else
18035 + { // Short preamble
18036 + FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
18037 + }
18038 + if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
18039 + FrameTime ++;
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);
18045 + }
18046 + return FrameTime;
18047 +}
18048 +u16 N_DBPSOfRate(u16 DataRate)
18049 +{
18050 + u16 N_DBPS = 24;
18051 +
18052 + switch(DataRate)
18053 + {
18054 + case 60:
18055 + N_DBPS = 24;
18056 + break;
18057 +
18058 + case 90:
18059 + N_DBPS = 36;
18060 + break;
18061 +
18062 + case 120:
18063 + N_DBPS = 48;
18064 + break;
18065 +
18066 + case 180:
18067 + N_DBPS = 72;
18068 + break;
18069 +
18070 + case 240:
18071 + N_DBPS = 96;
18072 + break;
18073 +
18074 + case 360:
18075 + N_DBPS = 144;
18076 + break;
18077 +
18078 + case 480:
18079 + N_DBPS = 192;
18080 + break;
18081 +
18082 + case 540:
18083 + N_DBPS = 216;
18084 + break;
18085 +
18086 + default:
18087 + break;
18088 + }
18089 +
18090 + return N_DBPS;
18091 +}
18092 +
18093 +//{by amy 080312
18094 +//
18095 +// Description:
18096 +// For Netgear case, they want good-looking singal strength.
18097 +// 2004.12.05, by rcnjko.
18098 +//
18099 +long
18100 +NetgearSignalStrengthTranslate(
18101 + long LastSS,
18102 + long CurrSS
18103 + )
18104 +{
18105 + long RetSS;
18106 +
18107 + // Step 1. Scale mapping.
18108 + if(CurrSS >= 71 && CurrSS <= 100)
18109 + {
18110 + RetSS = 90 + ((CurrSS - 70) / 3);
18111 + }
18112 + else if(CurrSS >= 41 && CurrSS <= 70)
18113 + {
18114 + RetSS = 78 + ((CurrSS - 40) / 3);
18115 + }
18116 + else if(CurrSS >= 31 && CurrSS <= 40)
18117 + {
18118 + RetSS = 66 + (CurrSS - 30);
18119 + }
18120 + else if(CurrSS >= 21 && CurrSS <= 30)
18121 + {
18122 + RetSS = 54 + (CurrSS - 20);
18123 + }
18124 + else if(CurrSS >= 5 && CurrSS <= 20)
18125 + {
18126 + RetSS = 42 + (((CurrSS - 5) * 2) / 3);
18127 + }
18128 + else if(CurrSS == 4)
18129 + {
18130 + RetSS = 36;
18131 + }
18132 + else if(CurrSS == 3)
18133 + {
18134 + RetSS = 27;
18135 + }
18136 + else if(CurrSS == 2)
18137 + {
18138 + RetSS = 18;
18139 + }
18140 + else if(CurrSS == 1)
18141 + {
18142 + RetSS = 9;
18143 + }
18144 + else
18145 + {
18146 + RetSS = CurrSS;
18147 + }
18148 + //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
18149 +
18150 + // Step 2. Smoothing.
18151 + if(LastSS > 0)
18152 + {
18153 + RetSS = ((LastSS * 5) + (RetSS)+ 5) / 6;
18154 + }
18155 + //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
18156 +
18157 + return RetSS;
18158 +}
18159 +//
18160 +// Description:
18161 +// Translate 0-100 signal strength index into dBm.
18162 +//
18163 +long
18164 +TranslateToDbm8185(
18165 + u8 SignalStrengthIndex // 0-100 index.
18166 + )
18167 +{
18168 + long SignalPower; // in dBm.
18169 +
18170 + // Translate to dBm (x=0.5y-95).
18171 + SignalPower = (long)((SignalStrengthIndex + 1) >> 1);
18172 + SignalPower -= 95;
18173 +
18174 + return SignalPower;
18175 +}
18176 +//
18177 +// Description:
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.
18183 +//
18184 +void
18185 +PerformUndecoratedSignalSmoothing8185(
18186 + struct r8180_priv *priv,
18187 + bool bCckRate
18188 + )
18189 +{
18190 +
18191 +
18192 + // Determin the current packet is CCK rate.
18193 + priv->bCurCCKPkt = bCckRate;
18194 +
18195 + if(priv->UndecoratedSmoothedSS >= 0)
18196 + {
18197 + priv->UndecoratedSmoothedSS = ( (priv->UndecoratedSmoothedSS * 5) + (priv->SignalStrength * 10) ) / 6;
18198 + }
18199 + else
18200 + {
18201 + priv->UndecoratedSmoothedSS = priv->SignalStrength * 10;
18202 + }
18203 +
18204 + priv->UndercorateSmoothedRxPower = ( (priv->UndercorateSmoothedRxPower * 50) + (priv->RxPower* 11)) / 60;
18205 +
18206 +// printk("Sommthing SignalSterngth (%d) => UndecoratedSmoothedSS (%d)\n", priv->SignalStrength, priv->UndecoratedSmoothedSS);
18207 +// printk("Sommthing RxPower (%d) => UndecoratedRxPower (%d)\n", priv->RxPower, priv->UndercorateSmoothedRxPower);
18208 +
18209 + //if(priv->CurCCKRSSI >= 0 && bCckRate)
18210 + if(bCckRate)
18211 + {
18212 + priv->CurCCKRSSI = priv->RSSI;
18213 + }
18214 + else
18215 + {
18216 + priv->CurCCKRSSI = 0;
18217 + }
18218 +
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)
18223 + {
18224 +// printk("UndecoratedSmoothedSS(%d) overflow, SignalStrength(%d)\n", priv->UndecoratedSmoothedSS, priv->SignalStrength);
18225 + }
18226 + if(priv->UndecoratedSmoothedSS < 0)
18227 + {
18228 +// printk("UndecoratedSmoothedSS(%d) underflow, SignalStrength(%d)\n", priv->UndecoratedSmoothedSS, priv->SignalStrength);
18229 + }
18230 +
18231 +}
18232 +
18233 +//by amy 080312}
18234 +
18235 +/* This is rough RX isr handling routine*/
18236 +void rtl8180_rx(struct net_device *dev)
18237 +{
18238 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
18239 + struct sk_buff *tmp_skb;
18240 +
18241 + //struct sk_buff *skb;
18242 + short first,last;
18243 + u32 len;
18244 + int lastlen;
18245 + unsigned char quality, signal;
18246 + u8 rate;
18247 + //u32 *prism_hdr;
18248 + u32 *tmp,*tmp2;
18249 + u8 rx_desc_size;
18250 + u8 padding;
18251 + //u32 count=0;
18252 + char rxpower = 0;
18253 + u32 RXAGC = 0;
18254 + long RxAGC_dBm = 0;
18255 + u8 LNA=0, BB=0;
18256 + u8 LNA_gain[4]={02, 17, 29, 39};
18257 + u8 Antenna = 0;
18258 + struct ieee80211_hdr *hdr;//by amy
18259 + u16 fc,type;
18260 + u8 bHwError = 0,bCRC = 0,bICV = 0;
18261 + //bHwError = 0;
18262 + //bCRC = 0;
18263 + //bICV = 0;
18264 + bool bCckRate = false;
18265 + u8 RSSI = 0;
18266 + long SignalStrengthIndex = 0;//+by amy 080312
18267 +// u8 SignalStrength = 0;
18268 + struct ieee80211_rx_stats stats = {
18269 + .signal = 0,
18270 + .noise = -98,
18271 + .rate = 0,
18272 + // .mac_time = jiffies,
18273 + .freq = IEEE80211_24GHZ_BAND,
18274 + };
18275 +
18276 +#ifdef CONFIG_RTL8185B
18277 + stats.nic_type = NIC_8185B;
18278 + rx_desc_size = 8;
18279 +
18280 +#else
18281 + stats.nic_type = NIC_8185;
18282 + rx_desc_size = 4;
18283 +#endif
18284 + //printk("receive frame!%d\n",count++);
18285 + //if (!priv->rxbuffer) DMESG ("EE: NIC RX ack, but RX queue corrupted!");
18286 + //else {
18287 +
18288 + if ((*(priv->rxringtail)) & (1<<31)) {
18289 +
18290 + /* we have got an RX int, but the descriptor
18291 + * we are pointing is empty*/
18292 +
18293 + priv->stats.rxnodata++;
18294 + priv->ieee80211->stats.rx_errors++;
18295 +
18296 + /* if (! *(priv->rxring) & (1<<31)) {
18297 +
18298 + priv->stats.rxreset++;
18299 + priv->rxringtail=priv->rxring;
18300 + priv->rxbuffer=priv->rxbufferhead;
18301 +
18302 + }else{*/
18303 +
18304 + #if 0
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
18314 + */
18315 +
18316 + //priv->stats.rxwrkaround++;
18317 +
18318 + tmp = priv->rxringtail;
18319 + while (*(priv->rxringtail) & (1<<31)){
18320 +
18321 + priv->rxringtail+=4;
18322 +
18323 + if(priv->rxringtail >=
18324 + (priv->rxring)+(priv->rxringcount )*4)
18325 + priv->rxringtail=priv->rxring;
18326 +
18327 + priv->rxbuffer=(priv->rxbuffer->next);
18328 +
18329 + if(priv->rxringtail == tmp ){
18330 + //DMESG("EE: Could not find RX pointer");
18331 + priv->stats.rxnopointer++;
18332 + break;
18333 + }
18334 + }
18335 + #else
18336 +
18337 + tmp2 = NULL;
18338 + tmp = priv->rxringtail;
18339 + do{
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;
18343 + else
18344 + tmp -= rx_desc_size;
18345 +
18346 + if(! (*tmp & (1<<31)))
18347 + tmp2 = tmp;
18348 + }while(tmp != priv->rxring);
18349 +
18350 + if(tmp2) priv->rxringtail = tmp2;
18351 + #endif
18352 + //}
18353 + }
18354 +
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++;
18361 +
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);
18365 + goto drop;
18366 + }
18367 +
18368 + pci_dma_sync_single_for_cpu(priv->pdev,
18369 + priv->rxbuffer->dma,
18370 + priv->rxbuffersize * \
18371 + sizeof(u8),
18372 + PCI_DMA_FROMDEVICE);
18373 +
18374 + first = *(priv->rxringtail) & (1<<29) ? 1:0;
18375 + if(first) priv->rx_prevlen=0;
18376 +
18377 + last = *(priv->rxringtail) & (1<<28) ? 1:0;
18378 + if(last){
18379 + lastlen=((*priv->rxringtail) &0xfff);
18380 +
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
18385 + * problem..
18386 + * workaround to prevent kernel panic
18387 + */
18388 + if(lastlen < priv->rx_prevlen)
18389 + len=0;
18390 + else
18391 + len=lastlen-priv->rx_prevlen;
18392 +
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++;
18399 + else
18400 + priv->stats.rxcrcerrmid++;
18401 +
18402 + }
18403 +
18404 + }else{
18405 + len = priv->rxbuffersize;
18406 + }
18407 +
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;
18413 + if(padding) {
18414 + len -= 2;
18415 + }
18416 + }else {
18417 + padding = 0;
18418 + }
18419 +#ifdef CONFIG_RTL818X_S
18420 + padding = 0;
18421 +#endif
18422 +#endif
18423 + priv->rx_prevlen+=len;
18424 +
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
18430 + */
18431 + if(!priv->rx_skb_complete)
18432 + dev_kfree_skb_any(priv->rx_skb);
18433 + priv->rx_skb_complete = 1;
18434 + }
18435 +
18436 +#ifdef DEBUG_RX_FRAG
18437 + DMESG("Iteration.. len %x",len);
18438 + if(first) DMESG ("First descriptor");
18439 + if(last) DMESG("Last descriptor");
18440 +
18441 +#endif
18442 +#ifdef DEBUG_RX_VERBOSE
18443 + print_buffer( priv->rxbuffer->buf, len);
18444 +#endif
18445 +
18446 +#ifdef CONFIG_RTL8185B
18447 + signal=(unsigned char)(((*(priv->rxringtail+3))& (0x00ff0000))>>16);
18448 + signal=(signal&0xfe)>>1; // Modify by hikaru 6.6
18449 +
18450 + quality=(unsigned char)((*(priv->rxringtail+3)) & (0xff));
18451 +
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);
18456 +
18457 +#else
18458 + signal=((*(priv->rxringtail+1))& (0xff0000))>>16;
18459 + signal=(signal&0xfe)>>1; // Modify by hikaru 6.6
18460 +
18461 + quality=((*(priv->rxringtail+1)) & (0xff));
18462 +
18463 + stats.mac_time[0] = *(priv->rxringtail+2);
18464 + stats.mac_time[1] = *(priv->rxringtail+3);
18465 +#endif
18466 + rate=((*(priv->rxringtail)) &
18467 + ((1<<23)|(1<<22)|(1<<21)|(1<<20)))>>20;
18468 +
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))
18475 + { // OFDM rate.
18476 +
18477 + RxAGC_dBm = rxpower+1; //bias
18478 + }
18479 + else
18480 + { // CCK rate.
18481 + RxAGC_dBm = signal;//bit 0 discard
18482 +
18483 + LNA = (u8) (RxAGC_dBm & 0x60 ) >> 5 ; //bit 6~ bit 5
18484 + BB = (u8) (RxAGC_dBm & 0x1F); // bit 4 ~ bit 0
18485 +
18486 + RxAGC_dBm = -( LNA_gain[LNA] + (BB *2) ); //Pin_11b=-(LNA_gain+BB_gain) (dBm)
18487 +
18488 + RxAGC_dBm +=4; //bias
18489 + }
18490 +
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))
18496 + { // OFDM rate.
18497 + if(RXAGC>90)
18498 + RXAGC=90;
18499 + else if(RXAGC<25)
18500 + RXAGC=25;
18501 + RXAGC=(90-RXAGC)*100/65;
18502 + }
18503 + else
18504 + { // CCK rate.
18505 + if(RXAGC>95)
18506 + RXAGC=95;
18507 + else if(RXAGC<30)
18508 + RXAGC=30;
18509 + RXAGC=(95-RXAGC)*100/65;
18510 + }
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;
18515 +//{by amy 080312
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)
18520 + quality = 100;
18521 + else
18522 + quality = 127 - quality;
18523 + priv->SignalQuality = quality;
18524 + if(!priv->card_8185)
18525 + printk("check your card type\n");
18526 +
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;
18535 +//by amy 080312}
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);
18543 +
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))
18547 + {
18548 +//by amy 080312
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);
18554 + //
18555 + // For good-looking singal strength.
18556 + //
18557 + SignalStrengthIndex = NetgearSignalStrengthTranslate(
18558 + priv->LastSignalStrengthInPercent,
18559 + priv->SignalStrength);
18560 +
18561 + priv->LastSignalStrengthInPercent = SignalStrengthIndex;
18562 + priv->Stats_SignalStrength = TranslateToDbm8185((u8)SignalStrengthIndex);
18563 + //
18564 + // We need more correct power of received packets and the "SignalStrength" of RxStats is beautified,
18565 + // so we record the correct power here.
18566 + //
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;
18569 +
18570 + // Figure out which antenna that received the lasted packet.
18571 + priv->LastRxPktAntenna = Antenna ? 1 : 0; // 0: aux, 1: main.
18572 +//by amy 080312
18573 + SwAntennaDiversityRxOk8185(dev, priv->SignalStrength);
18574 + }
18575 +
18576 +//by amy for antenna
18577 +
18578 +
18579 +
18580 +
18581 +
18582 +
18583 +#ifndef DUMMY_RX
18584 + if(first){
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");
18590 +#endif
18591 + dev_kfree_skb_any(priv->rx_skb);
18592 + priv->stats.rxnolast++;
18593 +#ifdef DEBUG_RX_SKB
18594 + DMESG("free incomplete skb OK");
18595 +#endif
18596 + }
18597 + /* support for prism header has been originally added by Christian */
18598 + if(priv->prism_hdr && priv->ieee80211->iw_mode == IW_MODE_MONITOR){
18599 +
18600 +#if 0
18601 + priv->rx_skb = dev_alloc_skb(len+2+PRISM_HDR_SIZE);
18602 + if(! priv->rx_skb) goto drop;
18603 +
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
18622 +
18623 +#endif
18624 + }else{
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);
18629 +#endif
18630 + }
18631 +
18632 + priv->rx_skb_complete=0;
18633 + priv->rx_skb->dev=dev;
18634 + }else{
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....
18640 + */
18641 + if(!priv->rx_skb_complete){
18642 +
18643 + tmp_skb= dev_alloc_skb(priv->rx_skb->len +len+2);
18644 +
18645 + if(!tmp_skb) goto drop;
18646 +
18647 + tmp_skb->dev=dev;
18648 +#ifdef DEBUG_RX_SKB
18649 + DMESG("Realloc skb %x",len+2);
18650 +#endif
18651 +
18652 +#ifdef DEBUG_RX_SKB
18653 + DMESG("going copy prev frag %x",priv->rx_skb->len);
18654 +#endif
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");
18660 +#endif
18661 +
18662 + dev_kfree_skb_any(priv->rx_skb);
18663 +#ifdef DEBUG_RX_SKB
18664 + DMESG("prev skb free ok");
18665 +#endif
18666 +
18667 + priv->rx_skb=tmp_skb;
18668 + }
18669 + }
18670 +#ifdef DEBUG_RX_SKB
18671 + DMESG("going to copy current payload %x",len);
18672 +#endif
18673 + if(!priv->rx_skb_complete) {
18674 +#ifdef CONFIG_RTL8185B
18675 + if(padding) {
18676 + memcpy(skb_put(priv->rx_skb,len),
18677 + (((unsigned char *)priv->rxbuffer->buf) + 2),len);
18678 + } else {
18679 +#endif
18680 + memcpy(skb_put(priv->rx_skb,len),
18681 + priv->rxbuffer->buf,len);
18682 +#ifdef CONFIG_RTL8185B
18683 + }
18684 +#endif
18685 + }
18686 +#ifdef DEBUG_RX_SKB
18687 + DMESG("current fragment skb copy complete");
18688 +#endif
18689 +
18690 + if(last && !priv->rx_skb_complete){
18691 +
18692 +#ifdef DEBUG_RX_SKB
18693 + DMESG("Got last fragment");
18694 +#endif
18695 +
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");
18700 +#endif
18701 +
18702 +#ifndef RX_DONT_PASS_UL
18703 + if(!ieee80211_rx(priv->ieee80211,
18704 + priv->rx_skb, &stats)){
18705 +#ifdef DEBUG_RX
18706 + DMESGW("Packet not consumed");
18707 +#endif
18708 +#endif // RX_DONT_PASS_UL
18709 +
18710 + dev_kfree_skb_any(priv->rx_skb);
18711 +#ifndef RX_DONT_PASS_UL
18712 + }
18713 +#endif
18714 +#ifdef DEBUG_RX
18715 + else{
18716 + DMESG("Rcv frag");
18717 + }
18718 +#endif
18719 + priv->rx_skb_complete=1;
18720 + }
18721 +
18722 +#endif //DUMMY_RX
18723 +
18724 + pci_dma_sync_single_for_device(priv->pdev,
18725 + priv->rxbuffer->dma,
18726 + priv->rxbuffersize * \
18727 + sizeof(u8),
18728 + PCI_DMA_FROMDEVICE);
18729 +
18730 +
18731 +drop: // this is used when we have not enought mem
18732 +
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;
18738 +
18739 + *(priv->rxringtail)=
18740 + *(priv->rxringtail) | (1<<31);
18741 + //^empty descriptor
18742 +
18743 + //wmb();
18744 +
18745 +#ifdef DEBUG_RX
18746 + DMESG("Current descriptor: %x",(u32)priv->rxringtail);
18747 +#endif
18748 + //unsigned long flags;
18749 + //spin_lock_irqsave(&priv->irq_lock,flags);
18750 +
18751 + priv->rxringtail+=rx_desc_size;
18752 + if(priv->rxringtail >=
18753 + (priv->rxring)+(priv->rxringcount )*rx_desc_size)
18754 + priv->rxringtail=priv->rxring;
18755 +
18756 + //spin_unlock_irqrestore(&priv->irq_lock,flags);
18757 +
18758 +
18759 + priv->rxbuffer=(priv->rxbuffer->next);
18760 +
18761 + }
18762 +
18763 +
18764 +
18765 +// if(get_curr_tx_free_desc(dev,priority))
18766 +// ieee80211_sta_ps_sleep(priv->ieee80211, &tmp, &tmp2);
18767 +
18768 +
18769 +
18770 +}
18771 +
18772 +
18773 +void rtl8180_dma_kick(struct net_device *dev, int priority)
18774 +{
18775 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
18776 +
18777 + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
18778 +/*
18779 +
18780 + switch(priority){
18781 +
18782 + case LOW_PRIORITY:
18783 +
18784 + write_nic_byte(dev,TX_DMA_POLLING,
18785 + (1<< TX_DMA_POLLING_LOWPRIORITY_SHIFT) |
18786 + priv->dma_poll_mask);
18787 + break;
18788 +
18789 + case NORM_PRIORITY:
18790 +
18791 + write_nic_byte(dev,TX_DMA_POLLING,
18792 + (1<< TX_DMA_POLLING_NORMPRIORITY_SHIFT) |
18793 + priv->dma_poll_mask);
18794 + break;
18795 +
18796 + case HI_PRIORITY:
18797 +
18798 + write_nic_byte(dev,TX_DMA_POLLING,
18799 + (1<< TX_DMA_POLLING_HIPRIORITY_SHIFT) |
18800 + priv->dma_poll_mask);
18801 + break;
18802 +
18803 + }
18804 +*/
18805 + write_nic_byte(dev, TX_DMA_POLLING,
18806 + (1 << (priority + 1)) | priv->dma_poll_mask);
18807 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
18808 +
18809 + force_pci_posting(dev);
18810 +}
18811 +
18812 +#if 0
18813 +void rtl8180_tx_queues_stop(struct net_device *dev)
18814 +{
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);
18820 +
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);
18824 +}
18825 +#endif
18826 +
18827 +void rtl8180_data_hard_stop(struct net_device *dev)
18828 +{
18829 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
18830 +
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);
18835 +#else
18836 + priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
18837 + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
18838 +#endif
18839 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
18840 +}
18841 +
18842 +
18843 +void rtl8180_data_hard_resume(struct net_device *dev)
18844 +{
18845 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
18846 +
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);
18851 +#else
18852 + priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
18853 + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
18854 +#endif
18855 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
18856 +}
18857 +
18858 +
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
18861 + */
18862 +void rtl8180_hard_data_xmit(struct sk_buff *skb,struct net_device *dev, int
18863 +rate)
18864 +{
18865 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
18866 + int mode;
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;
18870 + int priority;
18871 + //static int count = 0;
18872 +
18873 + mode = priv->ieee80211->iw_mode;
18874 +
18875 + rate = ieeerate2rtlrate(rate);
18876 + /*
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.
18882 + */
18883 +#ifdef CONFIG_RTL8185B
18884 + priority = AC2Q(skb->priority);
18885 +#else
18886 + priority = LOW_PRIORITY;
18887 +#endif
18888 + spin_lock_irqsave(&priv->tx_lock,flags);
18889 +
18890 + if(priv->ieee80211->bHwRadioOff)
18891 + {
18892 + spin_unlock_irqrestore(&priv->tx_lock,flags);
18893 +
18894 + return;
18895 + }
18896 +
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);
18905 + }
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);
18909 +
18910 + //dev_kfree_skb_any(skb);
18911 + spin_unlock_irqrestore(&priv->tx_lock,flags);
18912 +
18913 +}
18914 +
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)
18924 + */
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)
18927 +{
18928 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
18929 +
18930 + unsigned long flags;
18931 +
18932 + int priority;
18933 +
18934 +#ifdef CONFIG_RTL8185B
18935 + priority = MANAGE_PRIORITY;
18936 +#else
18937 + priority = NORM_PRIORITY;
18938 +#endif
18939 +
18940 + spin_lock_irqsave(&priv->tx_lock,flags);
18941 +
18942 + if(priv->ieee80211->bHwRadioOff)
18943 + {
18944 + spin_unlock_irqrestore(&priv->tx_lock,flags);
18945 +
18946 + dev_kfree_skb_any(skb);
18947 + return 0;
18948 + }
18949 +
18950 + rtl8180_tx(dev, skb->data, skb->len, priority,
18951 + 0, 0,ieeerate2rtlrate(priv->ieee80211->basic_rate));
18952 +
18953 + priv->ieee80211->stats.tx_bytes+=skb->len;
18954 + priv->ieee80211->stats.tx_packets++;
18955 + spin_unlock_irqrestore(&priv->tx_lock,flags);
18956 +
18957 + dev_kfree_skb_any(skb);
18958 + return 0;
18959 +}
18960 +
18961 +// longpre 144+48 shortpre 72+24
18962 +u16 rtl8180_len2duration(u32 len, short rate,short* ext)
18963 +{
18964 + u16 duration;
18965 + u16 drift;
18966 + *ext=0;
18967 +
18968 + switch(rate){
18969 + case 0://1mbps
18970 + *ext=0;
18971 + duration = ((len+4)<<4) /0x2;
18972 + drift = ((len+4)<<4) % 0x2;
18973 + if(drift ==0 ) break;
18974 + duration++;
18975 + break;
18976 +
18977 + case 1://2mbps
18978 + *ext=0;
18979 + duration = ((len+4)<<4) /0x4;
18980 + drift = ((len+4)<<4) % 0x4;
18981 + if(drift ==0 ) break;
18982 + duration++;
18983 + break;
18984 +
18985 + case 2: //5.5mbps
18986 + *ext=0;
18987 + duration = ((len+4)<<4) /0xb;
18988 + drift = ((len+4)<<4) % 0xb;
18989 + if(drift ==0 )
18990 + break;
18991 + duration++;
18992 + break;
18993 +
18994 + default:
18995 + case 3://11mbps
18996 + *ext=0;
18997 + duration = ((len+4)<<4) /0x16;
18998 + drift = ((len+4)<<4) % 0x16;
18999 + if(drift ==0 )
19000 + break;
19001 + duration++;
19002 + if(drift > 6)
19003 + break;
19004 + *ext=1;
19005 + break;
19006 + }
19007 +
19008 + return duration;
19009 +}
19010 +
19011 +
19012 +void rtl8180_prepare_beacon(struct net_device *dev)
19013 +{
19014 +
19015 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
19016 +
19017 + struct sk_buff *skb;
19018 +
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);
19023 +
19024 +
19025 + skb = ieee80211_get_beacon(priv->ieee80211);
19026 + if(skb){
19027 + rtl8180_tx(dev,skb->data,skb->len,BEACON_PRIORITY,
19028 + 0,0,ieeerate2rtlrate(priv->ieee80211->basic_rate));
19029 + dev_kfree_skb_any(skb);
19030 + }
19031 + #if 0
19032 + //DMESG("size %x",len);
19033 + if(*tail & (1<<31)){
19034 +
19035 + //DMESG("No more beacon TX desc");
19036 + return ;
19037 +
19038 + }
19039 + //while(! *tail & (1<<31)){
19040 + *tail= 0; // zeroes header
19041 +
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
19049 + *(tail+1)= 0;
19050 + *tail = *tail | (rate << 24);
19051 +
19052 + duration = rtl8180_len2duration(len,rate,&ext);
19053 +
19054 + *(tail+1) = *(tail+1) | ((duration & 0x7fff)<<16);
19055 +
19056 + *tail = *tail | (1<<31);
19057 + //^ descriptor ready to be txed
19058 + if((tail - begin)/8 == priv->txbeaconcount-1)
19059 + tail=begin;
19060 + else
19061 + tail=tail+8;
19062 + //}
19063 +#endif
19064 +}
19065 +
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.
19069 + */
19070 +short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
19071 + short morefrag, short descfrag, int rate)
19072 +{
19073 + struct r8180_priv *priv = ieee80211_priv(dev);
19074 + u32 *tail,*temp_tail;
19075 + u32 *begin;
19076 + u32 *buf;
19077 + int i;
19078 + int remain;
19079 + int buflen;
19080 + int count;
19081 + //u16 AckCtsTime;
19082 + //u16 FrameTime;
19083 + u16 duration;
19084 + short ext;
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;
19096 + u16 RtsDur = 0;
19097 + u16 ThisFrameTime = 0;
19098 + u16 TxDescDuration = 0;
19099 + u8 ownbit_flag = false; //added by david woo for sync Tx, 2007.12.14
19100 +#endif
19101 +
19102 + switch(priority) {
19103 + case MANAGE_PRIORITY:
19104 + tail=priv->txmapringtail;
19105 + begin=priv->txmapring;
19106 + buflist = priv->txmapbufstail;
19107 + count = priv->txringcount;
19108 + break;
19109 +
19110 + case BK_PRIORITY:
19111 + tail=priv->txbkpringtail;
19112 + begin=priv->txbkpring;
19113 + buflist = priv->txbkpbufstail;
19114 + count = priv->txringcount;
19115 + break;
19116 +
19117 + case BE_PRIORITY:
19118 + tail=priv->txbepringtail;
19119 + begin=priv->txbepring;
19120 + buflist = priv->txbepbufstail;
19121 + count = priv->txringcount;
19122 + break;
19123 +
19124 + case VI_PRIORITY:
19125 + tail=priv->txvipringtail;
19126 + begin=priv->txvipring;
19127 + buflist = priv->txvipbufstail;
19128 + count = priv->txringcount;
19129 + break;
19130 +
19131 + case VO_PRIORITY:
19132 + tail=priv->txvopringtail;
19133 + begin=priv->txvopring;
19134 + buflist = priv->txvopbufstail;
19135 + count = priv->txringcount;
19136 + break;
19137 +
19138 + case HI_PRIORITY:
19139 + tail=priv->txhpringtail;
19140 + begin=priv->txhpring;
19141 + buflist = priv->txhpbufstail;
19142 + count = priv->txringcount;
19143 + break;
19144 +
19145 + case BEACON_PRIORITY:
19146 + tail=priv->txbeaconringtail;
19147 + begin=priv->txbeaconring;
19148 + buflist = priv->txbeaconbufstail;
19149 + count = priv->txbeaconcount;
19150 + break;
19151 +
19152 + default:
19153 + return -1;
19154 + break;
19155 + }
19156 +
19157 + //printk("in rtl8180_tx(): rate is %d\n",priv->ieee80211->rate);
19158 +#if 1
19159 + memcpy(&dest, frag_hdr->addr1, ETH_ALEN);
19160 + if (is_multicast_ether_addr(dest) ||
19161 + is_broadcast_ether_addr(dest))
19162 + {
19163 + Duration = 0;
19164 + RtsDur = 0;
19165 + bRTSEnable = 0;
19166 + bCTSEnable = 0;
19167 +
19168 + ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), 0, bUseShortPreamble);
19169 + TxDescDuration = ThisFrameTime;
19170 + } else {// Unicast packet
19171 + //u8 AckRate;
19172 + u16 AckTime;
19173 +
19174 + //YJ,add,080828,for Keep alive
19175 + priv->NumTxUnicast++;
19176 +
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
19185 +
19186 + if ( ((len + sCrcLng) > priv->rts) && priv->rts )
19187 + { // RTS/CTS.
19188 + u16 RtsTime, CtsTime;
19189 + //u16 CtsRate;
19190 + bRTSEnable = 1;
19191 + bCTSEnable = 0;
19192 +
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
19197 +
19198 + // Figure out time required to transmit this frame.
19199 + ThisFrameTime = ComputeTxTime(len + sCrcLng,
19200 + rtl8180_rate2rate(rate),
19201 + 0,
19202 + bUseShortPreamble);
19203 +
19204 + // RTS-CTS-ThisFrame-ACK.
19205 + RtsDur = CtsTime + ThisFrameTime + AckTime + 3*aSifsTime;
19206 +
19207 + TxDescDuration = RtsTime + RtsDur;
19208 + }
19209 + else {// Normal case.
19210 + bCTSEnable = 0;
19211 + bRTSEnable = 0;
19212 + RtsDur = 0;
19213 +
19214 + ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), 0, bUseShortPreamble);
19215 + TxDescDuration = ThisFrameTime + aSifsTime + AckTime;
19216 + }
19217 +
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),
19225 + 0,
19226 + bUseShortPreamble );
19227 +
19228 + //ThisFrag-ACk-NextFrag-ACK.
19229 + Duration = NextFragTime + 3*aSifsTime + 2*AckTime;
19230 + }
19231 +
19232 + } // End of Unicast packet
19233 +
19234 + frag_hdr->duration_id = Duration;
19235 +#endif
19236 +
19237 + buflen=priv->txbuffsize;
19238 + remain=len;
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");
19244 +#endif
19245 +#ifdef DEBUG_TX
19246 + DMESG("TX: filling descriptor %x",(u32)tail);
19247 +#endif
19248 + mb();
19249 + if(!buflist){
19250 + DMESGE("TX buffer error, cannot TX frames. pri %d.", priority);
19251 + //spin_unlock_irqrestore(&priv->tx_lock,flags);
19252 + return -1;
19253 + }
19254 + buf=buflist->buf;
19255 +
19256 + if( (*tail & (1<<31)) && (priority != BEACON_PRIORITY)){
19257 +
19258 + DMESGW("No more TX desc, returning %x of %x",
19259 + remain,len);
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);
19265 +#endif
19266 + // spin_unlock_irqrestore(&priv->tx_lock,flags);
19267 +
19268 + return remain;
19269 +
19270 + }
19271 +
19272 + *tail= 0; // zeroes header
19273 + *(tail+1) = 0;
19274 + *(tail+3) = 0;
19275 + *(tail+5) = 0;
19276 + *(tail+6) = 0;
19277 + *(tail+7) = 0;
19278 +
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
19283 + }
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");
19289 +#endif
19290 + *tail = *tail| (1<<29) ; //fist segment of the packet
19291 + *tail = *tail |(len);
19292 + } else {
19293 + ownbit_flag = true;
19294 + }
19295 +
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 */
19300 +
19301 + }
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.
19309 +
19310 +#ifdef CONFIG_RTL8185B
19311 + if(bCTSEnable) {
19312 + *tail |= (1<<18);
19313 + }
19314 +
19315 + if(bRTSEnable) //rts enable
19316 + {
19317 + *tail |= ((ieeerate2rtlrate(priv->ieee80211->basic_rate))<<19);//RTS RATE
19318 + *tail |= (1<<23);//rts enable
19319 + *(tail+1) |=(RtsDur&0xffff);//RTS Duration
19320 + }
19321 + *(tail+3) |= ((TxDescDuration&0xffff)<<16); //DURATION
19322 +// *(tail+3) |= (0xe6<<16);
19323 + *(tail+5) |= (11<<8);//(priv->retry_data<<8); //retry lim ;
19324 +#else
19325 + //Use RTS or not
19326 +#ifdef CONFIG_RTL8187B
19327 + if ( (len>priv->rts) && priv->rts && priority!=MANAGE_PRIORITY){
19328 +#else
19329 + if ( (len>priv->rts) && priv->rts && priority==LOW_PRIORITY){
19330 +#endif
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
19338 + }else{
19339 + *(tail+1)= 0; // zeroes the second 32-bits dword of the descriptor
19340 + }
19341 +#endif
19342 +
19343 + *tail = *tail | ((rate&0xf) << 24);
19344 + //DMESG("rate %d",rate);
19345 +
19346 + if(priv->card_8185){
19347 +
19348 + #if 0
19349 + *(tail+5)&= ~(1<<24); /* tx ant 0 */
19350 +
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);
19353 +
19354 + *(tail+5) &=
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
19357 +
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
19361 + #endif
19362 + // *(tail+5) = 0;
19363 + }
19364 +
19365 + /* hw_plcp_len is not used for rtl8180 chip */
19366 + /* FIXME */
19367 + if(priv->card_8185 == 0 || !priv->hw_plcp_len){
19368 +
19369 + duration = rtl8180_len2duration(len,
19370 + rate,&ext);
19371 +
19372 +
19373 +#ifdef DEBUG_TX
19374 + DMESG("PLCP duration %d",duration );
19375 + //DMESG("drift %d",drift);
19376 + DMESG("extension %s", (ext==1) ? "on":"off");
19377 +#endif
19378 + *(tail+1) = *(tail+1) | ((duration & 0x7fff)<<16);
19379 + if(ext) *(tail+1) = *(tail+1) |(1<<31); //plcp length extension
19380 + }
19381 +
19382 + if(morefrag) *tail = (*tail) | (1<<17); // more fragment
19383 + if(!remain) *tail = (*tail) | (1<<28); // last segment of frame
19384 +
19385 +#ifdef DEBUG_TX_FRAG
19386 + if(!remain)DMESG("Last descriptor");
19387 + if(morefrag)DMESG("More frag");
19388 +#endif
19389 + *(tail+5) = *(tail+5)|(2<<27);
19390 + *(tail+7) = *(tail+7)|(1<<4);
19391 +
19392 + wmb();
19393 + if(ownbit_flag)
19394 + {
19395 + *tail = *tail | (1<<31); // descriptor ready to be txed
19396 + }
19397 +
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]);
19402 +#endif
19403 +
19404 + if((tail - begin)/8 == count-1)
19405 + tail=begin;
19406 +
19407 + else
19408 + tail=tail+8;
19409 +
19410 + buflist=buflist->next;
19411 +
19412 + mb();
19413 +
19414 + switch(priority) {
19415 + case MANAGE_PRIORITY:
19416 + priv->txmapringtail=tail;
19417 + priv->txmapbufstail=buflist;
19418 + break;
19419 +
19420 + case BK_PRIORITY:
19421 + priv->txbkpringtail=tail;
19422 + priv->txbkpbufstail=buflist;
19423 + break;
19424 +
19425 + case BE_PRIORITY:
19426 + priv->txbepringtail=tail;
19427 + priv->txbepbufstail=buflist;
19428 + break;
19429 +
19430 + case VI_PRIORITY:
19431 + priv->txvipringtail=tail;
19432 + priv->txvipbufstail=buflist;
19433 + break;
19434 +
19435 + case VO_PRIORITY:
19436 + priv->txvopringtail=tail;
19437 + priv->txvopbufstail=buflist;
19438 + break;
19439 +
19440 + case HI_PRIORITY:
19441 + priv->txhpringtail=tail;
19442 + priv->txhpbufstail = buflist;
19443 + break;
19444 +
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
19449 + * touch 2nd
19450 + */
19451 + // priv->txbeaconringtail=tail;
19452 + // priv->txbeaconbufstail=buflist;
19453 +
19454 + break;
19455 +
19456 + }
19457 +
19458 + //rtl8180_dma_kick(dev,priority);
19459 + }
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);
19463 +
19464 + return 0;
19465 +
19466 +}
19467 +
19468 +
19469 +void rtl8180_irq_rx_tasklet(struct r8180_priv * priv);
19470 +
19471 +
19472 +void rtl8180_link_change(struct net_device *dev)
19473 +{
19474 + struct r8180_priv *priv = ieee80211_priv(dev);
19475 + u16 beacon_interval;
19476 +
19477 + struct ieee80211_network *net = &priv->ieee80211->current_network;
19478 +// rtl8180_adapter_start(dev);
19479 + rtl8180_update_msr(dev);
19480 +
19481 +
19482 + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
19483 +
19484 + write_nic_dword(dev,BSSID,((u32*)net->bssid)[0]);
19485 + write_nic_word(dev,BSSID+4,((u16*)net->bssid)[2]);
19486 +
19487 +
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);
19492 +
19493 + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
19494 +
19495 +
19496 + /*
19497 + u16 atim = read_nic_dword(dev,ATIM);
19498 + u16 = u16 &~ ATIM_MASK;
19499 + u16 = u16 | beacon->atim;
19500 + */
19501 +#if 0
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;
19508 + }
19509 +#ifndef CONFIG_IEEE80211_NOWEP
19510 + else {
19511 + priv->ieee80211->host_encrypt=1;
19512 + priv->ieee80211->host_decrypt=1;
19513 + }
19514 +#endif
19515 + }
19516 +#ifndef CONFIG_IEEE80211_NOWEP
19517 + else{
19518 + priv->ieee80211->host_encrypt=0;
19519 + priv->ieee80211->host_decrypt=0;
19520 + }
19521 +#endif
19522 +#endif
19523 +
19524 +
19525 + if(priv->card_8185)
19526 + rtl8180_set_chan(dev, priv->chan);
19527 +
19528 +
19529 +}
19530 +
19531 +void rtl8180_rq_tx_ack(struct net_device *dev){
19532 +
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;
19537 +}
19538 +
19539 +short rtl8180_is_tx_queue_empty(struct net_device *dev){
19540 +
19541 + struct r8180_priv *priv = ieee80211_priv(dev);
19542 + u32* d;
19543 +
19544 + for (d = priv->txmapring;
19545 + d < priv->txmapring + priv->txringcount;d+=8)
19546 + if(*d & (1<<31)) return 0;
19547 +
19548 + for (d = priv->txbkpring;
19549 + d < priv->txbkpring + priv->txringcount;d+=8)
19550 + if(*d & (1<<31)) return 0;
19551 +
19552 + for (d = priv->txbepring;
19553 + d < priv->txbepring + priv->txringcount;d+=8)
19554 + if(*d & (1<<31)) return 0;
19555 +
19556 + for (d = priv->txvipring;
19557 + d < priv->txvipring + priv->txringcount;d+=8)
19558 + if(*d & (1<<31)) return 0;
19559 +
19560 + for (d = priv->txvopring;
19561 + d < priv->txvopring + priv->txringcount;d+=8)
19562 + if(*d & (1<<31)) return 0;
19563 +
19564 + for (d = priv->txhpring;
19565 + d < priv->txhpring + priv->txringcount;d+=8)
19566 + if(*d & (1<<31)) return 0;
19567 + return 1;
19568 +}
19569 +/* FIXME FIXME 5msecs is random */
19570 +#define HW_WAKE_DELAY 5
19571 +
19572 +void rtl8180_hw_wakeup(struct net_device *dev)
19573 +{
19574 + unsigned long flags;
19575 +
19576 + struct r8180_priv *priv = ieee80211_priv(dev);
19577 +
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);
19581 +
19582 + if(priv->rf_wakeup)
19583 + priv->rf_wakeup(dev);
19584 +// mdelay(HW_WAKE_DELAY);
19585 + spin_unlock_irqrestore(&priv->ps_lock,flags);
19586 +}
19587 +
19588 +void rtl8180_hw_sleep_down(struct net_device *dev)
19589 +{
19590 + unsigned long flags;
19591 +
19592 + struct r8180_priv *priv = ieee80211_priv(dev);
19593 +
19594 + spin_lock_irqsave(&priv->ps_lock,flags);
19595 + //DMESG("Sleep!");
19596 +
19597 + if(priv->rf_sleep)
19598 + priv->rf_sleep(dev);
19599 + spin_unlock_irqrestore(&priv->ps_lock,flags);
19600 +}
19601 +
19602 +
19603 +void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl)
19604 +{
19605 +
19606 + struct r8180_priv *priv = ieee80211_priv(dev);
19607 +
19608 + u32 rb = jiffies;
19609 + unsigned long flags;
19610 +
19611 + spin_lock_irqsave(&priv->ps_lock,flags);
19612 +
19613 + /* Writing HW register with 0 equals to disable
19614 + * the timer, that is not really what we want
19615 + */
19616 + tl -= MSECS(4+16+7);
19617 +
19618 + //if(tl == 0) tl = 1;
19619 +
19620 + /* FIXME HACK FIXME HACK */
19621 +// force_pci_posting(dev);
19622 + //mdelay(1);
19623 +
19624 +// rb = read_nic_dword(dev, TSFTR);
19625 +
19626 + /* If the interval in witch we are requested to sleep is too
19627 + * short then give up and remain awake
19628 + */
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");
19633 + return;
19634 + }
19635 +
19636 +// write_nic_dword(dev, TimerInt, tl);
19637 +// rb = read_nic_dword(dev, TSFTR);
19638 + {
19639 + u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
19640 + // if (tl<rb)
19641 +
19642 + //lzm,add,080828
19643 + priv->DozePeriodInPast2Sec += jiffies_to_msecs(tmp);
19644 +
19645 + queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
19646 + }
19647 + /* if we suspect the TimerInt is gone beyond tl
19648 + * while setting it, then give up
19649 + */
19650 +#if 1
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);
19654 + return;
19655 + }
19656 +#endif
19657 +// if(priv->rf_sleep)
19658 +// priv->rf_sleep(dev);
19659 +
19660 + queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq);
19661 + spin_unlock_irqrestore(&priv->ps_lock,flags);
19662 +}
19663 +
19664 +
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)
19668 +{
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;
19672 +#else
19673 +void rtl8180_wmm_param_update(struct ieee80211_device *ieee)
19674 +{
19675 + struct net_device *dev = ieee->dev;
19676 + struct r8180_priv *priv = ieee80211_priv(dev);
19677 +#endif
19678 + u8 *ac_param = (u8 *)(ieee->current_network.wmm_param);
19679 + u8 mode = ieee->current_network.mode;
19680 + AC_CODING eACI;
19681 + AC_PARAM AcParam;
19682 + PAC_PARAM pAcParam;
19683 + u8 i;
19684 +
19685 +#ifndef CONFIG_RTL8185B
19686 + //for legacy 8185 keep the PARAM unchange.
19687 + return;
19688 +#else
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;
19699 + {
19700 + u8 u1bAIFS;
19701 + u32 u4bAcParam;
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));
19709 + switch(eACI){
19710 + case AC1_BK:
19711 + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
19712 + break;
19713 +
19714 + case AC0_BE:
19715 + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
19716 + break;
19717 +
19718 + case AC2_VI:
19719 + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
19720 + break;
19721 +
19722 + case AC3_VO:
19723 + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
19724 + break;
19725 +
19726 + default:
19727 + printk(KERN_WARNING "SetHwReg8185():invalid ACI: %d!\n", eACI);
19728 + break;
19729 + }
19730 + }
19731 + }
19732 + return;
19733 + }
19734 +
19735 + for(i = 0; i < AC_MAX; i++){
19736 + //AcParam.longData = 0;
19737 + pAcParam = (AC_PARAM * )ac_param;
19738 + {
19739 + AC_CODING eACI;
19740 + u8 u1bAIFS;
19741 + u32 u4bAcParam;
19742 +
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));
19751 +
19752 + switch(eACI){
19753 + case AC1_BK:
19754 + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
19755 + break;
19756 +
19757 + case AC0_BE:
19758 + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
19759 + break;
19760 +
19761 + case AC2_VI:
19762 + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
19763 + break;
19764 +
19765 + case AC3_VO:
19766 + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
19767 + break;
19768 +
19769 + default:
19770 + printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
19771 + break;
19772 + }
19773 + }
19774 + ac_param += (sizeof(AC_PARAM));
19775 + }
19776 +#endif
19777 +}
19778 +
19779 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
19780 +void rtl8180_tx_irq_wq(struct work_struct *work);
19781 +#else
19782 +void rtl8180_tx_irq_wq(struct net_device *dev);
19783 +#endif
19784 +
19785 +
19786 +
19787 +
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);
19791 +#else
19792 + void rtl8180_restart_wq(struct net_device *dev);
19793 +//void rtl8180_rq_tx_ack(struct net_device *dev);
19794 +#endif
19795 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
19796 +void rtl8180_watch_dog_wq(struct work_struct *work);
19797 +#else
19798 +void rtl8180_watch_dog_wq(struct net_device *dev);
19799 +#endif
19800 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
19801 +void rtl8180_hw_wakeup_wq(struct work_struct *work);
19802 +#else
19803 +void rtl8180_hw_wakeup_wq(struct net_device *dev);
19804 +#endif
19805 +
19806 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
19807 +void rtl8180_hw_sleep_wq(struct work_struct *work);
19808 +#else
19809 +void rtl8180_hw_sleep_wq(struct net_device *dev);
19810 +#endif
19811 +
19812 +
19813 +
19814 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
19815 +void rtl8180_sw_antenna_wq(struct work_struct *work);
19816 +#else
19817 +void rtl8180_sw_antenna_wq(struct net_device *dev);
19818 +#endif
19819 + void rtl8180_watch_dog(struct net_device *dev);
19820 +void watch_dog_adaptive(unsigned long data)
19821 +{
19822 + struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
19823 +// DMESG("---->watch_dog_adaptive()\n");
19824 + if(!priv->up)
19825 + {
19826 + DMESG("<----watch_dog_adaptive():driver is not up!\n");
19827 + return;
19828 + }
19829 +
19830 + // queue_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq);
19831 +//{by amy 080312
19832 +#if 1
19833 + // Tx High Power Mechanism.
19834 +#ifdef HIGH_POWER
19835 + if(CheckHighPower((struct net_device *)data))
19836 + {
19837 + queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->tx_pw_wq);
19838 + }
19839 +#endif
19840 +
19841 +#ifdef CONFIG_RTL818X_S
19842 + // Tx Power Tracking on 87SE.
19843 +#ifdef TX_TRACK
19844 + //if( priv->bTxPowerTrack ) //lzm mod 080826
19845 + if( CheckTxPwrTracking((struct net_device *)data));
19846 + TxPwrTracking87SE((struct net_device *)data);
19847 +#endif
19848 +#endif
19849 +
19850 + // Perform DIG immediately.
19851 +#ifdef SW_DIG
19852 + if(CheckDig((struct net_device *)data) == true)
19853 + {
19854 + queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_dig_wq);
19855 + }
19856 +#endif
19857 +#endif
19858 +//by amy 080312}
19859 + rtl8180_watch_dog((struct net_device *)data);
19860 +
19861 +
19862 + queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->GPIOChangeRFWorkItem);
19863 +
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");
19867 +}
19868 +
19869 +#ifdef ENABLE_DOT11D
19870 +
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
19883 +};
19884 +
19885 +static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ieee)
19886 +{
19887 + int i;
19888 +
19889 + //lzm add 080826
19890 + ieee->MinPassiveChnlNum=MAX_CHANNEL_NUMBER+1;
19891 + ieee->IbssStartChnl=0;
19892 +
19893 + switch (channel_plan)
19894 + {
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:
19904 + {
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++)
19912 + {
19913 + if(ChannelPlan[channel_plan].Channel[i] <= 14)
19914 + GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
19915 + }
19916 + }
19917 + break;
19918 + }
19919 + case COUNTRY_CODE_GLOBAL_DOMAIN:
19920 + {
19921 + GET_DOT11D_INFO(ieee)->bEnabled = 0;
19922 + Dot11d_Reset(ieee);
19923 + ieee->bGlobalDomain = true;
19924 + break;
19925 + }
19926 + case COUNTRY_CODE_WORLD_WIDE_13_INDEX://lzm add 080826
19927 + {
19928 + ieee->MinPassiveChnlNum=12;
19929 + ieee->IbssStartChnl= 10;
19930 + break;
19931 + }
19932 + default:
19933 + {
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++)
19938 + {
19939 + GET_DOT11D_INFO(ieee)->channel_map[i] = 1;
19940 + }
19941 + break;
19942 + }
19943 + }
19944 +}
19945 +#endif
19946 +
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);
19950 +#else
19951 +void GPIOChangeRFWorkItemCallBack(struct ieee80211_device *ieee);
19952 +#endif
19953 +
19954 +//YJ,add,080828
19955 +static void rtl8180_statistics_init(struct Stats *pstats)
19956 +{
19957 + memset(pstats, 0, sizeof(struct Stats));
19958 +}
19959 +static void rtl8180_link_detect_init(plink_detect_t plink_detect)
19960 +{
19961 + memset(plink_detect, 0, sizeof(link_detect_t));
19962 + plink_detect->SlotNum = DEFAULT_SLOT_NUM;
19963 +}
19964 +//YJ,add,080828,end
19965 +
19966 +short rtl8180_init(struct net_device *dev)
19967 +{
19968 + struct r8180_priv *priv = ieee80211_priv(dev);
19969 + u16 word;
19970 + u16 version;
19971 + u8 hw_version;
19972 + //u8 config3;
19973 + u32 usValue;
19974 + u16 tmpu16;
19975 + int i, j;
19976 +
19977 +#ifdef ENABLE_DOT11D
19978 +#if 0
19979 + for(i=0;i<0xFF;i++) {
19980 + if(i%16 == 0)
19981 + printk("\n[%x]: ", i/16);
19982 + printk("\t%4.4x", eprom_read(dev,i));
19983 + }
19984 +#endif
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;
19989 + }
19990 + //priv->channel_plan = 9; //Global Domain
19991 +
19992 + DMESG("Channel plan is %d\n",priv->channel_plan);
19993 + rtl8180_set_channel_map(priv->channel_plan, priv->ieee80211);
19994 +#else
19995 + int ch;
19996 + //Set Default Channel Plan
19997 + if(!channels){
19998 + DMESG("No channels, aborting");
19999 + return -1;
20000 + }
20001 + ch=channels;
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);
20006 + ch >>= 1;
20007 + }
20008 +#endif
20009 +
20010 + //memcpy(priv->stats,0,sizeof(struct Stats));
20011 +
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)
20022 + */
20023 +
20024 +#ifdef CONFIG_RTL8185B
20025 +#ifdef CONFIG_RTL818X_S
20026 + priv->RegThreeWireMode = HW_THREE_WIRE_SI;
20027 +#else
20028 + priv->RegThreeWireMode = SW_THREE_WIRE;
20029 +#endif
20030 +#endif
20031 +
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;
20037 +
20038 + priv->irq_enabled=0;
20039 +
20040 +//YJ,modified,080828
20041 +#if 0
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;
20070 +#else
20071 + rtl8180_statistics_init(&priv->stats);
20072 + rtl8180_link_detect_init(&priv->link_detect);
20073 +#endif
20074 +//YJ,modified,080828,end
20075 +
20076 +
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;
20092 +
20093 + priv->hw_wep = hwwep;
20094 + priv->prism_hdr=0;
20095 + priv->dev=dev;
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
20132 +//{by amy 080312
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;
20164 + priv->RSSI = 0;
20165 + //YJ,add,080828
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;
20191 +
20192 +//by amy for rate adaptive
20193 +//by amy 080312}
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
20213 +
20214 + //add for RF power on power off by lizhaoming 080512
20215 + INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,(void*) GPIOChangeRFWorkItemCallBack);
20216 +#else
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
20227 +
20228 + //add for RF power on power off by lizhaoming 080512
20229 + INIT_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,(void*) GPIOChangeRFWorkItemCallBack, priv->ieee80211);
20230 +#endif
20231 + //INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart_wq,dev);
20232 +
20233 + tasklet_init(&priv->irq_rx_tasklet,
20234 + (void(*)(unsigned long)) rtl8180_irq_rx_tasklet,
20235 + (unsigned long)priv);
20236 +//by amy
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;
20240 +//by amy
20241 +
20242 +//{by amy 080312
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
20250 +//by amy 080312}
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));
20255 +
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;
20262 +
20263 + priv->ieee80211->init_wmmparam_flag = 0;
20264 +
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;
20268 +
20269 +#ifdef CONFIG_RTL8185B
20270 + priv->MWIEnable = 0;
20271 +
20272 + priv->ShortRetryLimit = 7;
20273 + priv->LongRetryLimit = 7;
20274 + priv->EarlyRxThreshold = 7;
20275 +
20276 + priv->CSMethod = (0x01 << 29);
20277 +
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
20284 +
20285 + priv->ReceiveConfig =
20286 +#ifdef CONFIG_RTL818X_S
20287 +#else
20288 + priv->CSMethod |
20289 +#endif
20290 +// RCR_ENMARP |
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);
20298 +
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.
20308 +
20309 + priv->InitialGain = 6;
20310 +#endif
20311 +
20312 + hw_version =( read_nic_dword(dev, TCR) & TCR_HWVERID_MASK)>>TCR_HWVERID_SHIFT;
20313 +
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;
20321 + break;
20322 +#else
20323 + DMESG("MAC controller is a RTL8185B b/g");
20324 + priv->card_8185 = 3;
20325 + priv->phy_ver = 2;
20326 + break;
20327 +#endif
20328 +#endif
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;
20334 + break;
20335 +
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;
20341 + break;
20342 +
20343 + case HW_VERID_R8180_ABCD:
20344 + DMESG("MAC controller is a RTL8180");
20345 + priv->card_8185 = 0;
20346 + break;
20347 +
20348 + case HW_VERID_R8180_F:
20349 + DMESG("MAC controller is a RTL8180 (v. F)");
20350 + priv->card_8185 = 0;
20351 + break;
20352 +
20353 + default:
20354 + DMESGW("MAC chip not recognized: version %x. Assuming RTL8180",hw_version);
20355 + priv->card_8185 = 0;
20356 + break;
20357 + }
20358 +
20359 + if(priv->card_8185){
20360 + priv->ieee80211->modulation |= IEEE80211_OFDM_MODULATION;
20361 + priv->ieee80211->short_slot = 1;
20362 + }
20363 + /* you should not found any 8185 Ver B Card */
20364 + priv->card_8185_Bversion = 0;
20365 +
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");
20371 +#else
20372 + config3 = read_nic_byte(dev, CONFIG3);
20373 + if(config3 & 0x8){
20374 + priv->card_type = CARDBUS;
20375 + DMESG("This is a CARDBUS NIC");
20376 + }
20377 + else if( config3 & 0x4){
20378 + priv->card_type = MINIPCI;
20379 + DMESG("This is a MINI-PCI NIC");
20380 + }else{
20381 + priv->card_type = PCI;
20382 + DMESG("This is a PCI NIC");
20383 + }
20384 +#endif
20385 +#endif
20386 + priv->enable_gpio0 = 0;
20387 +
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 )
20396 + {
20397 + priv->EEPROMSwAntennaDiversity = false;
20398 + //printk("EEPROM Disable SW Antenna Diversity\n");
20399 + }
20400 + else
20401 + {
20402 + priv->EEPROMSwAntennaDiversity = true;
20403 + //printk("EEPROM Enable SW Antenna Diversity\n");
20404 + }
20405 + // Default Antenna to use.
20406 + if( (usValue & EEPROM_DEF_ANT_MASK) != EEPROM_DEF_ANT_1 )
20407 + {
20408 + priv->EEPROMDefaultAntenna1 = false;
20409 + //printk("EEPROM Default Antenna 0\n");
20410 + }
20411 + else
20412 + {
20413 + priv->EEPROMDefaultAntenna1 = true;
20414 + //printk("EEPROM Default Antenna 1\n");
20415 + }
20416 +
20417 + //
20418 + // Antenna diversity mechanism. Added by Roger, 2007.11.05.
20419 + //
20420 + if( priv->RegSwAntennaDiversityMechanism == 0 ) // Auto
20421 + {// 0: default from EEPROM.
20422 + priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity;
20423 + }
20424 + else
20425 + {// 1:disable antenna diversity, 2: enable antenna diversity.
20426 + priv->bSwAntennaDiverity = ((priv->RegSwAntennaDiversityMechanism == 1)? false : true);
20427 + }
20428 + //printk("bSwAntennaDiverity = %d\n", priv->bSwAntennaDiverity);
20429 +
20430 +
20431 + //
20432 + // Default antenna settings. Added by Roger, 2007.11.05.
20433 + //
20434 + if( priv->RegDefaultAntenna == 0)
20435 + {// 0: default from EEPROM.
20436 + priv->bDefaultAntenna1 = priv->EEPROMDefaultAntenna1;
20437 + }
20438 + else
20439 + {// 1: main, 2: aux.
20440 + priv->bDefaultAntenna1 = ((priv->RegDefaultAntenna== 2) ? true : false);
20441 + }
20442 + //printk("bDefaultAntenna1 = %d\n", priv->bDefaultAntenna1);
20443 +#endif
20444 +#endif
20445 +//by amy for antenna
20446 + /* rtl8185 can calc plcp len in HW.*/
20447 + priv->hw_plcp_len = 1;
20448 +
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)");
20454 + }else{
20455 + priv->epromtype=EPROM_93c46;
20456 + //DMESG("Reported EEPROM chip is a 93c46 (1Kbit)");
20457 + }
20458 +
20459 + dev->get_stats = rtl8180_stats;
20460 +
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));
20468 +
20469 +
20470 + for(i=1,j=0; i<14; i+=2,j++){
20471 +
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]);
20479 +#endif
20480 + }
20481 + if(priv->card_8185){
20482 + for(i=1,j=0; i<14; i+=2,j++){
20483 +
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]);
20491 +#endif
20492 + }
20493 + }
20494 +//{by amy 080312
20495 + //3Read crystal calibtration and thermal meter indication on 87SE.
20496 +
20497 + // By SD3 SY's request. Added by Roger, 2007.12.11.
20498 +
20499 + tmpu16 = eprom_read(dev, EEPROM_RSV>>1);
20500 +
20501 + //printk("ReadAdapterInfo8185(): EEPROM_RSV(%04x)\n", tmpu16);
20502 +
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;
20508 +
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;
20513 +
20514 +//by amy 080312}
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;
20519 +#endif
20520 +
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");
20527 + priv->digphy=1;
20528 + priv->antb=0;
20529 + priv->diversity=1;
20530 + priv->cs_treshold=0xc;
20531 + priv->rcr_csense=1;
20532 + priv->rf_chip=RFCHIPID_PHILIPS;
20533 + }else{
20534 + if(!priv->card_8185){
20535 + u8 rfparam = eprom_read(dev,RF_PARAM);
20536 + DMESG("RfParam: %x",rfparam);
20537 +
20538 + priv->digphy = rfparam & (1<<RF_PARAM_DIGPHY_SHIFT) ? 0:1;
20539 + priv->antb = rfparam & (1<<RF_PARAM_ANTBDEFAULT_SHIFT) ? 1:0;
20540 +
20541 + priv->rcr_csense = (rfparam & RF_PARAM_CARRIERSENSE_MASK) >>
20542 + RF_PARAM_CARRIERSENSE_SHIFT;
20543 +
20544 + priv->diversity =
20545 + (read_nic_byte(dev,CONFIG2)&(1<<CONFIG2_ANTENNA_SHIFT)) ? 1:0;
20546 + }else{
20547 + priv->rcr_csense = 3;
20548 + }
20549 +
20550 + priv->cs_treshold = (eprom_read(dev,ENERGY_TRESHOLD)&0xff00) >>8;
20551 +
20552 + priv->rf_chip = 0xff & eprom_read(dev,RFCHIPID);
20553 + }
20554 +
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;
20560 +#else
20561 + priv->rf_chip = RF_ZEBRA2;
20562 +#endif
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!");
20567 +
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;
20574 +
20575 +#else
20576 + /* check RF frontend chipset */
20577 + switch (priv->rf_chip) {
20578 +
20579 + case RFCHIPID_RTL8225:
20580 +
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");
20586 +
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;
20593 +
20594 + }else{
20595 + DMESGW("Detected RTL8225 radio on a card recognized as RTL8180");
20596 + DMESGW("This could not be... something went wrong....");
20597 + return -ENODEV;
20598 + }
20599 + break;
20600 +
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");
20607 +
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;
20614 +
20615 + }else{
20616 + DMESGW("Detected RTL8255 radio on a card recognized as RTL8180");
20617 + DMESGW("This could not be... something went wrong....");
20618 + return -ENODEV;
20619 + }
20620 + break;
20621 +
20622 +
20623 + case RFCHIPID_INTERSIL:
20624 + DMESGW("Card reports RF frontend by Intersil.");
20625 + DMESGW("This driver has NO support for this chipset.");
20626 + return -ENODEV;
20627 + break;
20628 +
20629 + case RFCHIPID_RFMD:
20630 + DMESGW("Card reports RF frontend by RFMD.");
20631 + DMESGW("This driver has NO support for this chipset.");
20632 + return -ENODEV;
20633 + break;
20634 +
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;
20646 + break;
20647 +
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;
20659 + break;
20660 +
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;
20672 +
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>");
20677 + }else{
20678 + DMESG ("Analog PHY found");
20679 + }
20680 +
20681 + break;
20682 +
20683 + default:
20684 + DMESGW("Unknown RF module %x",priv->rf_chip);
20685 + DMESGW("Exiting...");
20686 + return -1;
20687 +
20688 + }
20689 +#endif
20690 +
20691 +
20692 + if(!priv->card_8185){
20693 + if(priv->antb)
20694 + DMESG ("Antenna B is default antenna");
20695 + else
20696 + DMESG ("Antenna A is default antenna");
20697 +
20698 + if(priv->diversity)
20699 + DMESG ("Antenna diversity is enabled");
20700 + else
20701 + DMESG("Antenna diversity is disabled");
20702 +
20703 + DMESG("Carrier sense %d",priv->rcr_csense);
20704 + }
20705 +
20706 + if (0!=alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount))
20707 + return -ENOMEM;
20708 +
20709 + if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
20710 + TX_MANAGEPRIORITY_RING_ADDR))
20711 + return -ENOMEM;
20712 +
20713 + if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
20714 + TX_BKPRIORITY_RING_ADDR))
20715 + return -ENOMEM;
20716 +
20717 + if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
20718 + TX_BEPRIORITY_RING_ADDR))
20719 + return -ENOMEM;
20720 +
20721 + if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
20722 + TX_VIPRIORITY_RING_ADDR))
20723 + return -ENOMEM;
20724 +
20725 + if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
20726 + TX_VOPRIORITY_RING_ADDR))
20727 + return -ENOMEM;
20728 +
20729 + if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
20730 + TX_HIGHPRIORITY_RING_ADDR))
20731 + return -ENOMEM;
20732 +
20733 + if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txbeaconcount,
20734 + TX_BEACON_RING_ADDR))
20735 + return -ENOMEM;
20736 +
20737 +
20738 + //priv->beacon_buf=NULL;
20739 +
20740 + if(!priv->card_8185){
20741 +
20742 + if(read_nic_byte(dev, CONFIG0) & (1<<CONFIG0_WEP40_SHIFT))
20743 + DMESG ("40-bit WEP is supported in hardware");
20744 + else
20745 + DMESG ("40-bit WEP is NOT supported in hardware");
20746 +
20747 + if(read_nic_byte(dev,CONFIG0) & (1<<CONFIG0_WEP104_SHIFT))
20748 + DMESG ("104-bit WEP is supported in hardware");
20749 + else
20750 + DMESG ("104-bit WEP is NOT supported in hardware");
20751 + }
20752 +#if !defined(SA_SHIRQ)
20753 + if(request_irq(dev->irq, (void *)rtl8180_interrupt, IRQF_SHARED, dev->name, dev)){
20754 +#else
20755 + if(request_irq(dev->irq, (void *)rtl8180_interrupt, SA_SHIRQ, dev->name, dev)){
20756 +#endif
20757 + DMESGE("Error allocating IRQ %d",dev->irq);
20758 + return -1;
20759 + }else{
20760 + priv->irq=dev->irq;
20761 + DMESG("IRQ %d",dev->irq);
20762 + }
20763 +
20764 +#ifdef DEBUG_EPROM
20765 + dump_eprom(dev);
20766 +#endif
20767 +
20768 + return 0;
20769 +
20770 +}
20771 +
20772 +
20773 +void rtl8180_no_hw_wep(struct net_device *dev)
20774 +{
20775 + struct r8180_priv *priv = ieee80211_priv(dev);
20776 +
20777 + if(!priv->card_8185)
20778 + {
20779 + u8 security;
20780 +
20781 + security = read_nic_byte(dev, SECURITY);
20782 + security &=~(1<<SECURITY_WEP_TX_ENABLE_SHIFT);
20783 + security &=~(1<<SECURITY_WEP_RX_ENABLE_SHIFT);
20784 +
20785 + write_nic_byte(dev, SECURITY, security);
20786 +
20787 + }else{
20788 +
20789 + //FIXME!!!
20790 + }
20791 + /*
20792 + write_nic_dword(dev,TX_CONF,read_nic_dword(dev,TX_CONF) |
20793 + (1<<TX_NOICV_SHIFT) );
20794 + */
20795 +// priv->ieee80211->hw_wep=0;
20796 +}
20797 +
20798 +
20799 +void rtl8180_set_hw_wep(struct net_device *dev)
20800 +{
20801 + struct r8180_priv *priv = ieee80211_priv(dev);
20802 + u8 pgreg;
20803 + u8 security;
20804 + u32 key0_word4;
20805 +
20806 + pgreg=read_nic_byte(dev, PGSELECT);
20807 + write_nic_byte(dev, PGSELECT, pgreg &~ (1<<PGSELECT_PG_SHIFT));
20808 +
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));
20816 +
20817 + /*
20818 + TX_CONF,read_nic_dword(dev,TX_CONF) &~(1<<TX_NOICV_SHIFT));
20819 + */
20820 +
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);
20826 +
20827 + write_nic_byte(dev, SECURITY, security);
20828 +
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));
20832 +
20833 + //priv->ieee80211->hw_wep=1;
20834 +}
20835 +
20836 +
20837 +void rtl8185_rf_pins_enable(struct net_device *dev)
20838 +{
20839 +// u16 tmp;
20840 +// tmp = read_nic_word(dev, RFPinsEnable);
20841 + write_nic_word(dev, RFPinsEnable, 0x1fff);// | tmp);
20842 +// write_nic_word(dev, RFPinsEnable,7 | tmp);
20843 +}
20844 +
20845 +
20846 +void rtl8185_set_anaparam2(struct net_device *dev, u32 a)
20847 +{
20848 + u8 conf3;
20849 +
20850 + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
20851 +
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);
20855 +
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);
20859 +
20860 +}
20861 +
20862 +
20863 +void rtl8180_set_anaparam(struct net_device *dev, u32 a)
20864 +{
20865 + u8 conf3;
20866 +
20867 + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
20868 +
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);
20872 +
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);
20876 +}
20877 +
20878 +
20879 +void rtl8185_tx_antenna(struct net_device *dev, u8 ant)
20880 +{
20881 + write_nic_byte(dev, TX_ANTENNA, ant);
20882 + force_pci_posting(dev);
20883 + mdelay(1);
20884 +}
20885 +
20886 +
20887 +void rtl8185_write_phy(struct net_device *dev, u8 adr, u32 data)
20888 +{
20889 + //u8 phyr;
20890 + u32 phyw;
20891 + //int i;
20892 +
20893 + adr |= 0x80;
20894 +
20895 + phyw= ((data<<8) | adr);
20896 +#if 0
20897 +
20898 + write_nic_dword(dev, PHY_ADR, phyw);
20899 +
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;
20905 +
20906 + }
20907 +#else
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) ));
20913 +#endif
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
20916 + */
20917 + //if(phyr != (data&0xff)) DMESGW("Phy write timeout %x %x %x", phyr, data,adr);
20918 +}
20919 +
20920 +
20921 +inline void write_phy_ofdm (struct net_device *dev, u8 adr, u32 data)
20922 +{
20923 + data = data & 0xff;
20924 + rtl8185_write_phy(dev, adr, data);
20925 +}
20926 +
20927 +
20928 +void write_phy_cck (struct net_device *dev, u8 adr, u32 data)
20929 +{
20930 + data = data & 0xff;
20931 + rtl8185_write_phy(dev, adr, data | 0x10000);
20932 +}
20933 +
20934 +
20935 +/* 70*3 = 210 ms
20936 + * I hope this is enougth
20937 + */
20938 +#define MAX_PHY 70
20939 +void write_phy(struct net_device *dev, u8 adr, u8 data)
20940 +{
20941 + u32 phy;
20942 + int i;
20943 +
20944 + phy = 0xff0000;
20945 + phy |= adr;
20946 + phy |= 0x80; /* this should enable writing */
20947 + phy |= (data<<8);
20948 +
20949 + //PHY_ADR, PHY_R and PHY_W are contig and treated as one dword
20950 + write_nic_dword(dev,PHY_ADR, phy);
20951 +
20952 + phy= 0xffff00;
20953 + phy |= adr;
20954 +
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;
20959 + phy= phy >> 16;
20960 + if(phy == data){ //SUCCESS!
20961 + force_pci_posting(dev);
20962 + mdelay(3); //random value
20963 +#ifdef DEBUG_BB
20964 + DMESG("Phy wr %x,%x",adr,data);
20965 +#endif
20966 + return;
20967 + }else{
20968 + force_pci_posting(dev);
20969 + mdelay(3); //random value
20970 + }
20971 + }
20972 + DMESGW ("Phy writing %x %x failed!", adr,data);
20973 +}
20974 +
20975 +void rtl8185_set_rate(struct net_device *dev)
20976 +{
20977 + int i;
20978 + u16 word;
20979 + int basic_rate,min_rr_rate,max_rr_rate;
20980 +
20981 +// struct r8180_priv *priv = ieee80211_priv(dev);
20982 +
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);
20988 +
20989 +//
20990 +// }else{
20991 +// basic_rate = ieeerate2rtlrate(20);
20992 +// min_rr_rate = ieeerate2rtlrate(10);
20993 +// max_rr_rate = ieeerate2rtlrate(110);
20994 +// }
20995 +
20996 + write_nic_byte(dev, RESP_RATE,
20997 + max_rr_rate<<MAX_RESP_RATE_SHIFT| min_rr_rate<<MIN_RESP_RATE_SHIFT);
20998 +
20999 + word = read_nic_word(dev, BRSR);
21000 + word &= ~BRSR_MBR_8185;
21001 +
21002 +
21003 + for(i=0;i<=basic_rate;i++)
21004 + word |= (1<<i);
21005 +
21006 + write_nic_word(dev, BRSR, word);
21007 + //DMESG("RR:%x BRSR: %x", read_nic_byte(dev,RESP_RATE),read_nic_word(dev,BRSR));
21008 +}
21009 +
21010 +
21011 +
21012 +void rtl8180_adapter_start(struct net_device *dev)
21013 +{
21014 + struct r8180_priv *priv = ieee80211_priv(dev);
21015 + u32 anaparam;
21016 + u16 word;
21017 + u8 config3;
21018 +// int i;
21019 +
21020 + rtl8180_rtx_disable(dev);
21021 + rtl8180_reset(dev);
21022 +
21023 + /* seems that 0xffff or 0xafff will cause
21024 + * HW interrupt line crash
21025 + */
21026 +
21027 + //priv->irq_mask = 0xafff;
21028 +// priv->irq_mask = 0x4fcf;
21029 +
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;
21034 +
21035 + priv->dma_poll_mask = 0;
21036 +
21037 + rtl8180_beacon_tx_disable(dev);
21038 +
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));
21044 + }
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);
21049 +
21050 + rtl8180_update_msr(dev);
21051 +
21052 + if(!priv->card_8185){
21053 + anaparam = eprom_read(dev,EPROM_ANAPARAM_ADDRLWORD);
21054 + anaparam |= eprom_read(dev,EPROM_ANAPARAM_ADDRHWORD)<<16;
21055 +
21056 + rtl8180_set_anaparam(dev,anaparam);
21057 + }
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);*/
21063 +
21064 + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
21065 +
21066 + /*
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
21070 + */
21071 +
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));
21079 +
21080 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
21081 +
21082 + write_nic_dword(dev,INT_TIMEOUT,0);
21083 +#ifdef DEBUG_REGISTERS
21084 + rtl8180_dump_reg(dev);
21085 +#endif
21086 +
21087 + if(!priv->card_8185)
21088 + {
21089 + /*
21090 + experimental - this might be needed to calibrate AGC,
21091 + anyway it shouldn't hurt
21092 + */
21093 + write_nic_byte(dev, CONFIG5,
21094 + read_nic_byte(dev, CONFIG5) | (1<<AGCRESET_SHIFT));
21095 + read_nic_byte(dev, CONFIG5);
21096 + udelay(15);
21097 + write_nic_byte(dev, CONFIG5,
21098 + read_nic_byte(dev, CONFIG5) &~ (1<<AGCRESET_SHIFT));
21099 + }else{
21100 +
21101 + write_nic_byte(dev, WPA_CONFIG, 0);
21102 + //write_nic_byte(dev, TESTR, 0xd);
21103 + }
21104 +
21105 + rtl8180_no_hw_wep(dev);
21106 +
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);
21111 + }else{
21112 + word = read_nic_word(dev, BRSR);
21113 + word &= ~BRSR_MBR;
21114 + word &= ~BRSR_BPLCP;
21115 + word |= ieeerate2rtlrate(priv->ieee80211->basic_rate);
21116 +//by amy
21117 + word |= 0x0f;
21118 +//by amy
21119 + write_nic_word(dev, BRSR, word);
21120 + }
21121 +
21122 +
21123 + if(priv->card_8185){
21124 + write_nic_byte(dev, GP_ENABLE,read_nic_byte(dev, GP_ENABLE) & ~(1<<6));
21125 +
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);
21131 +
21132 + }
21133 +
21134 + priv->rf_init(dev);
21135 +
21136 + if(priv->rf_set_sens != NULL)
21137 + priv->rf_set_sens(dev,priv->sens);
21138 + rtl8180_irq_enable(dev);
21139 +
21140 + netif_start_queue(dev);
21141 + /*DMESG ("lfree %d",get_curr_tx_free_desc(dev,LOW_PRIORITY));
21142 +
21143 + DMESG ("nfree %d",get_curr_tx_free_desc(dev,NORM_PRIORITY));
21144 +
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");*/
21149 +}
21150 +
21151 +
21152 +
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
21156 + */
21157 +void rtl8180_start_tx_beacon(struct net_device *dev)
21158 +{
21159 +// struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
21160 + u16 word;
21161 +// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
21162 +
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);
21170 +#if 0
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);
21175 +
21176 +#if 0
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);
21181 +#endif
21182 +#endif
21183 + word = read_nic_word(dev, AtimWnd) &~ AtimWnd_AtimWnd;
21184 + write_nic_word(dev, AtimWnd,word);// word |=
21185 +//priv->ieee80211->current_network.atim_window);
21186 +
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;
21192 + */
21193 + write_nic_word(dev, BintrItv, word);
21194 +
21195 +
21196 + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
21197 +
21198 +// rtl8180_beacon_tx_enable(dev);
21199 +#ifdef CONFIG_RTL8185B
21200 + rtl8185b_irq_enable(dev);
21201 +#else
21202 + rtl8180_irq_enable(dev);
21203 +#endif
21204 + /* VV !!!!!!!!!! VV*/
21205 + /*
21206 + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
21207 + write_nic_byte(dev,0x9d,0x00);
21208 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
21209 +*/
21210 +// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
21211 +
21212 +}
21213 +
21214 +
21215 +
21216 +/***************************************************************************
21217 + -------------------------------NET STUFF---------------------------
21218 +***************************************************************************/
21219 +static struct net_device_stats *rtl8180_stats(struct net_device *dev)
21220 +{
21221 + struct r8180_priv *priv = ieee80211_priv(dev);
21222 +
21223 + return &priv->ieee80211->stats;
21224 +}
21225 +//
21226 +// Change current and default preamble mode.
21227 +// 2005.01.06, by rcnjko.
21228 +//
21229 +bool
21230 +MgntActSet_802_11_PowerSaveMode(
21231 + struct r8180_priv *priv,
21232 + RT_PS_MODE rtPsMode
21233 +)
21234 +{
21235 +
21236 + // Currently, we do not change power save mode on IBSS mode.
21237 + if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
21238 + {
21239 + return false;
21240 + }
21241 +
21242 + //
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.
21247 + //
21248 +// // Change device's power save mode.
21249 +// Adapter->HalFunc.SetPSModeHandler( Adapter, rtPsMode );
21250 +
21251 + // Update power save mode configured.
21252 +// priv->dot11PowerSaveMode = rtPsMode;
21253 + priv->ieee80211->ps = rtPsMode;
21254 + // Determine ListenInterval.
21255 +#if 0
21256 + if(priv->dot11PowerSaveMode == eMaxPs)
21257 + {
21258 + priv->ieee80211->ListenInterval = 10;
21259 + }
21260 + else
21261 + {
21262 + priv->ieee80211->ListenInterval = 2;
21263 + }
21264 +#endif
21265 + return true;
21266 +}
21267 +
21268 +//================================================================================
21269 +// Leisure Power Save in linked state.
21270 +//================================================================================
21271 +
21272 +//
21273 +// Description:
21274 +// Enter the leisure power save mode.
21275 +//
21276 +void
21277 +LeisurePSEnter(
21278 + struct r8180_priv *priv
21279 + )
21280 +{
21281 + if (priv->bLeisurePs)
21282 + {
21283 + if (priv->ieee80211->ps == IEEE80211_PS_DISABLED)
21284 + {
21285 + //printk("----Enter PS\n");
21286 + MgntActSet_802_11_PowerSaveMode(priv, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST);//IEEE80211_PS_ENABLE
21287 + }
21288 + }
21289 +}
21290 +
21291 +
21292 +//
21293 +// Description:
21294 +// Leave the leisure power save mode.
21295 +//
21296 +void
21297 +LeisurePSLeave(
21298 + struct r8180_priv *priv
21299 + )
21300 +{
21301 + if (priv->bLeisurePs)
21302 + {
21303 + if (priv->ieee80211->ps != IEEE80211_PS_DISABLED)
21304 + {
21305 + //printk("----Leave PS\n");
21306 + MgntActSet_802_11_PowerSaveMode(priv, IEEE80211_PS_DISABLED);
21307 + }
21308 + }
21309 +}
21310 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
21311 +void rtl8180_hw_wakeup_wq (struct work_struct *work)
21312 +{
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;
21319 +#else
21320 +void rtl8180_hw_wakeup_wq(struct net_device *dev)
21321 +{
21322 + struct r8180_priv *priv = ieee80211_priv(dev);
21323 +#endif
21324 +
21325 +// printk("dev is %d\n",dev);
21326 +// printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
21327 + rtl8180_hw_wakeup(dev);
21328 +
21329 +}
21330 +
21331 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
21332 +void rtl8180_hw_sleep_wq (struct work_struct *work)
21333 +{
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;
21340 +#else
21341 +void rtl8180_hw_sleep_wq(struct net_device *dev)
21342 +{
21343 + struct r8180_priv *priv = ieee80211_priv(dev);
21344 +#endif
21345 +
21346 + rtl8180_hw_sleep_down(dev);
21347 +}
21348 +
21349 +//YJ,add,080828,for KeepAlive
21350 +static void MgntLinkKeepAlive(struct r8180_priv *priv )
21351 +{
21352 + if (priv->keepAliveLevel == 0)
21353 + return;
21354 +
21355 + if(priv->ieee80211->state == IEEE80211_LINKED)
21356 + {
21357 + //
21358 + // Keep-Alive.
21359 + //
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);
21361 +
21362 + if ( (priv->keepAliveLevel== 2) ||
21363 + (priv->link_detect.LastNumTxUnicast == priv->NumTxUnicast &&
21364 + priv->link_detect.LastNumRxUnicast == priv->ieee80211->NumRxUnicast )
21365 + )
21366 + {
21367 + priv->link_detect.IdleCount++;
21368 +
21369 + //
21370 + // Send a Keep-Alive packet packet to AP if we had been idle for a while.
21371 + //
21372 + if(priv->link_detect.IdleCount >= ((KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)-1) )
21373 + {
21374 + priv->link_detect.IdleCount = 0;
21375 + ieee80211_sta_ps_send_null_frame(priv->ieee80211, false);
21376 + }
21377 + }
21378 + else
21379 + {
21380 + priv->link_detect.IdleCount = 0;
21381 + }
21382 + priv->link_detect.LastNumTxUnicast = priv->NumTxUnicast;
21383 + priv->link_detect.LastNumRxUnicast = priv->ieee80211->NumRxUnicast;
21384 + }
21385 +}
21386 +//YJ,add,080828,for KeepAlive,end
21387 +
21388 +static u8 read_acadapter_file(char *filename);
21389 +void rtl8180_watch_dog(struct net_device *dev)
21390 +{
21391 + struct r8180_priv *priv = ieee80211_priv(dev);
21392 + bool bEnterPS = false;
21393 + bool bBusyTraffic = false;
21394 + u32 TotalRxNum = 0;
21395 + u16 SlotIndex = 0;
21396 + u16 i = 0;
21397 +#ifdef ENABLE_IPS
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)){
21400 + IPSEnter(dev);
21401 + }
21402 + }
21403 +#endif
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);
21414 + }
21415 + }
21416 +
21417 + //YJ,add,080828,for KeepAlive
21418 + MgntLinkKeepAlive(priv);
21419 +
21420 + //YJ,add,080828,for LPS
21421 +#ifdef ENABLE_LPS
21422 + if(priv->PowerProfile == POWER_PROFILE_BATTERY )
21423 + {
21424 + //Turn on LeisurePS on battery power
21425 + //printk("!!!!!On battery power\n");
21426 + priv->bLeisurePs = true;
21427 + }
21428 + else if(priv->PowerProfile == POWER_PROFILE_AC )
21429 + {
21430 + // Turn off LeisurePS on AC power
21431 + //printk("----On AC power\n");
21432 + LeisurePSLeave(priv);
21433 + priv->bLeisurePs= false;
21434 + }
21435 +#endif
21436 +
21437 +#if 0
21438 +#ifndef ENABLE_LPS
21439 + if(priv->ieee80211->state == IEEE80211_LINKED){
21440 + if( priv->NumRxOkInPeriod> 666 ||
21441 + priv->NumTxOkInPeriod > 666 ) {
21442 + bBusyTraffic = true;
21443 + }
21444 + if((priv->ieee80211->NumRxData + priv->NumTxOkInPeriod)<8) {
21445 + bEnterPS= true;
21446 + }
21447 + if(bEnterPS) {
21448 + LeisurePSEnter(priv);
21449 + }
21450 + else {
21451 + LeisurePSLeave(priv);
21452 + }
21453 + }
21454 + else {
21455 + LeisurePSLeave(priv);
21456 + }
21457 +#endif
21458 + priv->NumRxOkInPeriod = 0;
21459 + priv->NumTxOkInPeriod = 0;
21460 + priv->ieee80211->NumRxData = 0;
21461 +#else
21462 +#ifdef ENABLE_LPS
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;
21469 + }
21470 + if(((priv->link_detect.NumRxOkInPeriod + priv->link_detect.NumTxOkInPeriod) > 8)
21471 + || (priv->link_detect.NumRxOkInPeriod > 2)) {
21472 + bEnterPS= false;
21473 + }
21474 + else {
21475 + bEnterPS= true;
21476 + }
21477 +
21478 + if(bEnterPS) {
21479 + LeisurePSEnter(priv);
21480 + }
21481 + else {
21482 + LeisurePSLeave(priv);
21483 + }
21484 + }
21485 + else{
21486 + LeisurePSLeave(priv);
21487 + }
21488 +#endif
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;
21494 +#endif
21495 +}
21496 +int _rtl8180_up(struct net_device *dev)
21497 +{
21498 + struct r8180_priv *priv = ieee80211_priv(dev);
21499 + //int i;
21500 +
21501 + priv->up=1;
21502 +
21503 + DMESG("Bringing up iface");
21504 +#ifdef CONFIG_RTL8185B
21505 + rtl8185b_adapter_start(dev);
21506 + rtl8185b_rx_enable(dev);
21507 + rtl8185b_tx_enable(dev);
21508 +#else
21509 + rtl8180_adapter_start(dev);
21510 + rtl8180_rx_enable(dev);
21511 + rtl8180_tx_enable(dev);
21512 +#endif
21513 +#ifdef ENABLE_IPS
21514 + if(priv->bInactivePs){
21515 + if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
21516 + IPSLeave(dev);
21517 + }
21518 +#endif
21519 +//by amy 080312
21520 +#ifdef RATE_ADAPT
21521 + timer_rate_adaptive((unsigned long)dev);
21522 +#endif
21523 +//by amy 080312
21524 + watch_dog_adaptive((unsigned long)dev);
21525 +#ifdef SW_ANTE
21526 + if(priv->bSwAntennaDiverity)
21527 + SwAntennaDiversityTimerCallback(dev);
21528 +#endif
21529 +// IPSEnter(dev);
21530 + ieee80211_softmac_start_protocol(priv->ieee80211);
21531 +
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);
21536 +
21537 + return 0;
21538 +}
21539 +
21540 +
21541 +int rtl8180_open(struct net_device *dev)
21542 +{
21543 + struct r8180_priv *priv = ieee80211_priv(dev);
21544 + int ret;
21545 +
21546 + down(&priv->wx_sem);
21547 + ret = rtl8180_up(dev);
21548 + up(&priv->wx_sem);
21549 + return ret;
21550 +
21551 +}
21552 +
21553 +
21554 +int rtl8180_up(struct net_device *dev)
21555 +{
21556 + struct r8180_priv *priv = ieee80211_priv(dev);
21557 +
21558 + if (priv->up == 1) return -1;
21559 +
21560 + return _rtl8180_up(dev);
21561 +}
21562 +
21563 +
21564 +int rtl8180_close(struct net_device *dev)
21565 +{
21566 + struct r8180_priv *priv = ieee80211_priv(dev);
21567 + int ret;
21568 +
21569 + down(&priv->wx_sem);
21570 + ret = rtl8180_down(dev);
21571 + up(&priv->wx_sem);
21572 +
21573 + return ret;
21574 +
21575 +}
21576 +
21577 +int rtl8180_down(struct net_device *dev)
21578 +{
21579 + struct r8180_priv *priv = ieee80211_priv(dev);
21580 +
21581 + if (priv->up == 0) return -1;
21582 +
21583 + priv->up=0;
21584 +
21585 + ieee80211_softmac_stop_protocol(priv->ieee80211);
21586 + /* FIXME */
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);
21593 +//{by amy 080312
21594 + del_timer_sync(&priv->rateadapter_timer);
21595 + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
21596 +//by amy 080312}
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;
21606 + return 0;
21607 +}
21608 +
21609 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
21610 +void rtl8180_restart_wq(struct work_struct *work)
21611 +{
21612 + struct r8180_priv *priv = container_of(work, struct r8180_priv, reset_wq);
21613 + struct net_device *dev = priv->dev;
21614 +#else
21615 +void rtl8180_restart_wq(struct net_device *dev)
21616 +{
21617 + struct r8180_priv *priv = ieee80211_priv(dev);
21618 +#endif
21619 + down(&priv->wx_sem);
21620 +
21621 + rtl8180_commit(dev);
21622 +
21623 + up(&priv->wx_sem);
21624 +}
21625 +
21626 +void rtl8180_restart(struct net_device *dev)
21627 +{
21628 + struct r8180_priv *priv = ieee80211_priv(dev);
21629 + //rtl8180_commit(dev);
21630 + schedule_work(&priv->reset_wq);
21631 + //DMESG("TXTIMEOUT");
21632 +}
21633 +
21634 +
21635 +void rtl8180_commit(struct net_device *dev)
21636 +{
21637 + struct r8180_priv *priv = ieee80211_priv(dev);
21638 +
21639 + if (priv->up == 0) return ;
21640 +//+by amy 080312
21641 + del_timer_sync(&priv->watch_dog_timer);
21642 + //cancel_delayed_work(&priv->ieee80211->watch_dog_wq);
21643 +//{by amy 080312
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
21648 +//by amy 080312}
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);
21658 +}
21659 +
21660 +
21661 +static void r8180_set_multicast(struct net_device *dev)
21662 +{
21663 + struct r8180_priv *priv = ieee80211_priv(dev);
21664 + short promisc;
21665 +
21666 + //down(&priv->wx_sem);
21667 +
21668 + promisc = (dev->flags & IFF_PROMISC) ? 1:0;
21669 +
21670 + if (promisc != priv->promisc)
21671 + rtl8180_restart(dev);
21672 +
21673 + priv->promisc = promisc;
21674 +
21675 + //up(&priv->wx_sem);
21676 +}
21677 +
21678 +#if 0
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)
21681 +{
21682 + struct r8180_priv *priv = ieee80211_priv(dev);
21683 + int ret;
21684 + unsigned long flags;
21685 +
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);
21689 + return ret;
21690 +}
21691 +#endif
21692 +
21693 +int r8180_set_mac_adr(struct net_device *dev, void *mac)
21694 +{
21695 + struct r8180_priv *priv = ieee80211_priv(dev);
21696 + struct sockaddr *addr = mac;
21697 +
21698 + down(&priv->wx_sem);
21699 +
21700 + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
21701 +
21702 + if(priv->ieee80211->iw_mode == IW_MODE_MASTER)
21703 + memcpy(priv->ieee80211->current_network.bssid, dev->dev_addr, ETH_ALEN);
21704 +
21705 + if (priv->up) {
21706 + rtl8180_down(dev);
21707 + rtl8180_up(dev);
21708 + }
21709 +
21710 + up(&priv->wx_sem);
21711 +
21712 + return 0;
21713 +}
21714 +
21715 +/* based on ipw2200 driver */
21716 +int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
21717 +{
21718 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
21719 +
21720 + struct iwreq *wrq = (struct iwreq *) rq;
21721 + int ret=-1;
21722 + switch (cmd) {
21723 + case RTL_IOCTL_WPA_SUPPLICANT:
21724 + ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
21725 + return ret;
21726 +
21727 + default:
21728 + return -EOPNOTSUPP;
21729 + }
21730 +
21731 + return -EOPNOTSUPP;
21732 +}
21733 +
21734 +
21735 +
21736 +/****************************************************************************
21737 + -----------------------------PCI STUFF---------------------------
21738 +*****************************************************************************/
21739 +
21740 +
21741 +static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
21742 + const struct pci_device_id *id)
21743 +{
21744 + unsigned long ioaddr = 0;
21745 + struct net_device *dev = NULL;
21746 + struct r8180_priv *priv= NULL;
21747 + //u8 *ptr;
21748 + u8 unit = 0;
21749 +
21750 +#ifdef CONFIG_RTL8180_IO_MAP
21751 + unsigned long pio_start, pio_len, pio_flags;
21752 +#else
21753 + unsigned long pmem_start, pmem_len, pmem_flags;
21754 +#endif //end #ifdef RTL_IO_MAP
21755 +
21756 + DMESG("Configuring chip resources");
21757 +
21758 + if( pci_enable_device (pdev) ){
21759 + DMESG("Failed to enable PCI device");
21760 + return -EIO;
21761 + }
21762 +
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));
21768 + if (!dev)
21769 + return -ENOMEM;
21770 + priv = ieee80211_priv(dev);
21771 + priv->ieee80211 = netdev_priv(dev);
21772 +
21773 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
21774 + SET_MODULE_OWNER(dev);
21775 +#endif
21776 + pci_set_drvdata(pdev, dev);
21777 + SET_NETDEV_DEV(dev, &pdev->dev);
21778 +
21779 + priv = ieee80211_priv(dev);
21780 +// memset(priv,0,sizeof(struct r8180_priv));
21781 + priv->pdev=pdev;
21782 +
21783 +
21784 +#ifdef CONFIG_RTL8180_IO_MAP
21785 +
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);
21789 +
21790 + if (!(pio_flags & IORESOURCE_IO)) {
21791 + DMESG("region #0 not a PIO resource, aborting");
21792 + goto fail;
21793 + }
21794 +
21795 + //DMESG("IO space @ 0x%08lx", pio_start );
21796 + if( ! request_region( pio_start, pio_len, RTL8180_MODULE_NAME ) ){
21797 + DMESG("request_region failed!");
21798 + goto fail;
21799 + }
21800 +
21801 + ioaddr = pio_start;
21802 + dev->base_addr = ioaddr; // device I/O address
21803 +
21804 +#else
21805 +
21806 + pmem_start = pci_resource_start(pdev, 1);
21807 + pmem_len = pci_resource_len(pdev, 1);
21808 + pmem_flags = pci_resource_flags (pdev, 1);
21809 +
21810 + if (!(pmem_flags & IORESOURCE_MEM)) {
21811 + DMESG("region #1 not a MMIO resource, aborting");
21812 + goto fail;
21813 + }
21814 +
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!");
21818 + goto fail;
21819 + }
21820 +
21821 +
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 );
21826 + goto fail1;
21827 + }
21828 +
21829 + dev->mem_start = ioaddr; // shared mem start
21830 + dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end
21831 +
21832 +#endif //end #ifdef RTL_IO_MAP
21833 +
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));
21839 +#endif
21840 +
21841 + dev->irq = pdev->irq;
21842 + priv->irq = 0;
21843 +
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;
21852 +
21853 +#if WIRELESS_EXT >= 12
21854 +#if WIRELESS_EXT < 17
21855 + dev->get_wireless_stats = r8180_get_wireless_stats;
21856 +#endif
21857 + dev->wireless_handlers = (struct iw_handler_def *) &r8180_wx_handlers_def;
21858 +#endif
21859 +
21860 + dev->type=ARPHRD_ETHER;
21861 + dev->watchdog_timeo = HZ*3; //added by david woo, 2007.12.13
21862 +
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);
21868 + }
21869 +
21870 +
21871 + if(rtl8180_init(dev)!=0){
21872 + DMESG("Initialization failed");
21873 + goto fail1;
21874 + }
21875 +
21876 + netif_carrier_off(dev);
21877 +
21878 + register_netdev(dev);
21879 +
21880 + rtl8180_proc_init_one(dev);
21881 +
21882 + DMESG("Driver probe completed\n");
21883 + return 0;
21884 +
21885 +fail1:
21886 +
21887 +#ifdef CONFIG_RTL8180_IO_MAP
21888 +
21889 + if( dev->base_addr != 0 ){
21890 +
21891 + release_region(dev->base_addr,
21892 + pci_resource_len(pdev, 0) );
21893 + }
21894 +#else
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) );
21899 + }
21900 +#endif //end #ifdef RTL_IO_MAP
21901 +
21902 +
21903 +fail:
21904 + if(dev){
21905 +
21906 + if (priv->irq) {
21907 + free_irq(dev->irq, dev);
21908 + dev->irq=0;
21909 + }
21910 + free_ieee80211(dev);
21911 + }
21912 +
21913 + pci_disable_device(pdev);
21914 +
21915 + DMESG("wlan driver load failed\n");
21916 + pci_set_drvdata(pdev, NULL);
21917 + return -ENODEV;
21918 +
21919 +}
21920 +
21921 +
21922 +static void __devexit rtl8180_pci_remove(struct pci_dev *pdev)
21923 +{
21924 + struct r8180_priv *priv;
21925 + struct net_device *dev = pci_get_drvdata(pdev);
21926 + if(dev){
21927 +
21928 + unregister_netdev(dev);
21929 +
21930 + priv=ieee80211_priv(dev);
21931 +
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);
21938 + mdelay(10);
21939 + //write_nic_word(dev,INTA,read_nic_word(dev,INTA));
21940 + //force_pci_posting(dev);
21941 + //mdelay(10);
21942 +
21943 + if(priv->irq){
21944 +
21945 + DMESG("Freeing irq %d",dev->irq);
21946 + free_irq(dev->irq, dev);
21947 + priv->irq=0;
21948 +
21949 + }
21950 +
21951 + free_rx_desc_ring(dev);
21952 + free_tx_desc_rings(dev);
21953 + // free_beacon_desc_ring(dev,priv->txbeaconcount);
21954 +
21955 +#ifdef CONFIG_RTL8180_IO_MAP
21956 +
21957 + if( dev->base_addr != 0 ){
21958 +
21959 + release_region(dev->base_addr,
21960 + pci_resource_len(pdev, 0) );
21961 + }
21962 +#else
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) );
21967 + }
21968 +#endif /*end #ifdef RTL_IO_MAP*/
21969 +
21970 + free_ieee80211(dev);
21971 + }
21972 + pci_disable_device(pdev);
21973 +
21974 + DMESG("wlan driver removed\n");
21975 +}
21976 +
21977 +
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);
21987 +
21988 +static int __init rtl8180_pci_module_init(void)
21989 +{
21990 + int ret;
21991 +
21992 + ret = ieee80211_crypto_init();
21993 + if (ret) {
21994 + printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
21995 + return ret;
21996 + }
21997 + ret = ieee80211_crypto_tkip_init();
21998 + if (ret) {
21999 + printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n", ret);
22000 + return ret;
22001 + }
22002 + ret = ieee80211_crypto_ccmp_init();
22003 + if (ret) {
22004 + printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n", ret);
22005 + return ret;
22006 + }
22007 + ret = ieee80211_crypto_wep_init();
22008 + if (ret) {
22009 + printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
22010 + return ret;
22011 + }
22012 +
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();
22019 +
22020 +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
22021 + if(0!=pci_module_init(&rtl8180_pci_driver))
22022 +#else
22023 + if(0!=pci_register_driver(&rtl8180_pci_driver))
22024 +#endif
22025 + //if(0!=pci_module_init(&rtl8180_pci_driver))
22026 + {
22027 + DMESG("No device found");
22028 + /*pci_unregister_driver (&rtl8180_pci_driver);*/
22029 + return -ENODEV;
22030 + }
22031 + return 0;
22032 +}
22033 +
22034 +
22035 +static void __exit rtl8180_pci_module_exit(void)
22036 +{
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");
22044 +}
22045 +
22046 +
22047 +void rtl8180_try_wake_queue(struct net_device *dev, int pri)
22048 +{
22049 + unsigned long flags;
22050 + short enough_desc;
22051 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
22052 +
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);
22056 +
22057 + if(enough_desc)
22058 + ieee80211_wake_queue(priv->ieee80211);
22059 +}
22060 +
22061 +/*****************************************************************************
22062 + -----------------------------IRQ STUFF---------------------------
22063 +******************************************************************************/
22064 +
22065 +void rtl8180_tx_isr(struct net_device *dev, int pri,short error)
22066 +{
22067 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
22068 +
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
22076 +// short txed;
22077 + unsigned long flag;
22078 + /* physical addr are ok on 32 bits since we set DMA mask*/
22079 +
22080 + int offs;
22081 + int j,i;
22082 + int hd;
22083 + if (error) priv->stats.txretry++; //tony 20060601
22084 + spin_lock_irqsave(&priv->tx_lock,flag);
22085 + switch(pri) {
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;
22092 + break;
22093 +
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;
22100 + break;
22101 +
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;
22108 + break;
22109 +
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;
22116 + break;
22117 +
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;
22124 + break;
22125 +
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;
22132 + break;
22133 +
22134 + default:
22135 + spin_unlock_irqrestore(&priv->tx_lock,flag);
22136 + return ;
22137 + }
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);
22142 +*/
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))){
22147 +
22148 + DMESGW("nic has lost pointer");
22149 +#ifdef DEBUG_TX_DESC
22150 + //check_tx_ring(dev,NORM_PRIORITY);
22151 + check_tx_ring(dev,pri);
22152 +#endif
22153 + spin_unlock_irqrestore(&priv->tx_lock,flag);
22154 + rtl8180_restart(dev);
22155 + return;
22156 + }
22157 +
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 ??)
22161 + */
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);
22166 +
22167 + offs = offs / 8 /4;
22168 +
22169 + hd = (head - begin) /8;
22170 +
22171 + if(offs >= hd)
22172 + j = offs - hd;
22173 + else
22174 + j = offs + (priv->txringcount -1 -hd);
22175 + // j= priv->txringcount -1- (hd - offs);
22176 +
22177 + j-=2;
22178 + if(j<0) j=0;
22179 +
22180 +
22181 + for(i=0;i<j;i++)
22182 + {
22183 +// printk("+++++++++++++check status desc\n");
22184 + if((*head) & (1<<31))
22185 + break;
22186 + if(((*head)&(0x10000000)) != 0){
22187 +// printk("++++++++++++++last desc,retry count is %d\n",((*head) & (0x000000ff)));
22188 + priv->CurrRetryCnt += (u16)((*head) & (0x000000ff));
22189 +#if 1
22190 + if(!error)
22191 + {
22192 + priv->NumTxOkTotal++;
22193 +// printk("NumTxOkTotal is %d\n",priv->NumTxOkTotal++);
22194 + }
22195 +#endif
22196 + // printk("in function %s:curr_retry_count is %d\n",__FUNCTION__,((*head) & (0x000000ff)));
22197 + }
22198 + if(!error){
22199 + priv->NumTxOkBytesTotal += (*(head+3)) & (0x00000fff);
22200 + }
22201 +// printk("in function %s:curr_txokbyte_count is %d\n",__FUNCTION__,(*(head+3)) & (0x00000fff));
22202 + *head = *head &~ (1<<31);
22203 +
22204 + if((head - begin)/8 == priv->txringcount-1)
22205 + head=begin;
22206 +
22207 + else
22208 + head+=8;
22209 + }
22210 +#if 0
22211 + if(nicv == begin)
22212 + txdv = begin + (priv->txringcount -1)*8;
22213 + else
22214 + txdv = nicv - 8;
22215 +
22216 + txed = !(txdv[0] &(1<<31));
22217 +
22218 + if(txed){
22219 + if(!(txdv[0] & (1<<15))) error = 1;
22220 + //if(!(txdv[0] & (1<<30))) error = 1;
22221 + if(error)DMESG("%x",txdv[0]);
22222 + }
22223 +#endif
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.
22232 + */
22233 +
22234 + switch(pri) {
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");
22241 +#if 1
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);
22246 + }
22247 +#endif
22248 + }
22249 + break;
22250 +
22251 + case BK_PRIORITY:
22252 + priv->txbkpringhead = head;
22253 + break;
22254 +
22255 + case BE_PRIORITY:
22256 + priv->txbepringhead = head;
22257 + break;
22258 +
22259 + case VI_PRIORITY:
22260 + priv->txvipringhead = head;
22261 + break;
22262 +
22263 + case VO_PRIORITY:
22264 + priv->txvopringhead = head;
22265 + break;
22266 +
22267 + case HI_PRIORITY:
22268 + priv->txhpringhead = head;
22269 + break;
22270 + }
22271 +
22272 + /*DMESG("%x %x %x", (priv->txnpringhead - priv->txnpring) /8 ,
22273 + (priv->txnpringtail - priv->txnpring) /8,
22274 + offs );
22275 + */
22276 +
22277 + spin_unlock_irqrestore(&priv->tx_lock,flag);
22278 +
22279 +}
22280 +
22281 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
22282 +void rtl8180_tx_irq_wq(struct work_struct *work)
22283 +{
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;
22289 +#else
22290 +void rtl8180_tx_irq_wq(struct net_device *dev)
22291 +{
22292 + //struct r8180_priv *priv = ieee80211_priv(dev);
22293 +#endif
22294 + rtl8180_tx_isr(dev,MANAGE_PRIORITY,0);
22295 +}
22296 +irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs)
22297 +{
22298 + struct net_device *dev = (struct net_device *) netdev;
22299 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
22300 + unsigned long flags;
22301 + u32 inta;
22302 +
22303 + /* We should return IRQ_NONE, but for now let me keep this */
22304 + if(priv->irq_enabled == 0) return IRQ_HANDLED;
22305 +
22306 + spin_lock_irqsave(&priv->irq_th_lock,flags);
22307 +
22308 +#ifdef CONFIG_RTL8185B
22309 + //ISR: 4bytes
22310 + inta = read_nic_dword(dev, ISR);// & priv->IntrMask;
22311 + write_nic_dword(dev,ISR,inta); // reset int situation
22312 +#else
22313 + inta = read_nic_word(dev,INTA) & priv->irq_mask;
22314 + write_nic_word(dev,INTA,inta); // reset int situation
22315 +#endif
22316 +
22317 + priv->stats.shints++;
22318 +
22319 + //DMESG("Enter interrupt, ISR value = 0x%08x", inta);
22320 +
22321 + if(!inta){
22322 + spin_unlock_irqrestore(&priv->irq_th_lock,flags);
22323 + return IRQ_HANDLED;
22324 + /*
22325 + most probably we can safely return IRQ_NONE,
22326 + but for now is better to avoid problems
22327 + */
22328 + }
22329 +
22330 + if(inta == 0xffff){
22331 + /* HW disappared */
22332 + spin_unlock_irqrestore(&priv->irq_th_lock,flags);
22333 + return IRQ_HANDLED;
22334 + }
22335 +
22336 + priv->stats.ints++;
22337 +#ifdef DEBUG_IRQ
22338 + DMESG("NIC irq %x",inta);
22339 +#endif
22340 + //priv->irqpending = inta;
22341 +
22342 +
22343 + if(!netif_running(dev)) {
22344 + spin_unlock_irqrestore(&priv->irq_th_lock,flags);
22345 + return IRQ_HANDLED;
22346 + }
22347 +
22348 + if(inta & ISR_TimeOut){
22349 + write_nic_dword(dev, TimerInt, 0);
22350 + //DMESG("=================>waking up");
22351 +// rtl8180_hw_wakeup(dev);
22352 + }
22353 +
22354 + if(inta & ISR_TBDOK){
22355 + priv->stats.txbeacon++;
22356 + }
22357 +
22358 + if(inta & ISR_TBDER){
22359 + priv->stats.txbeaconerr++;
22360 + }
22361 +
22362 + if(inta & IMR_TMGDOK ) {
22363 +// priv->NumTxOkTotal++;
22364 + rtl8180_tx_isr(dev,MANAGE_PRIORITY,0);
22365 +// schedule_work(&priv->tx_irq_wq);
22366 +
22367 + }
22368 +
22369 + if(inta & ISR_THPDER){
22370 +#ifdef DEBUG_TX
22371 + DMESG ("TX high priority ERR");
22372 +#endif
22373 + priv->stats.txhperr++;
22374 + rtl8180_tx_isr(dev,HI_PRIORITY,1);
22375 + priv->ieee80211->stats.tx_errors++;
22376 + }
22377 +
22378 + if(inta & ISR_THPDOK){ //High priority tx ok
22379 +#ifdef DEBUG_TX
22380 + DMESG ("TX high priority OK");
22381 +#endif
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);
22387 + }
22388 +
22389 + if(inta & ISR_RER) {
22390 + priv->stats.rxerr++;
22391 +#ifdef DEBUG_RX
22392 + DMESGW("RX error int");
22393 +#endif
22394 + }
22395 +#ifdef CONFIG_RTL8185B
22396 + if(inta & ISR_TBKDER){ //corresponding to BK_PRIORITY
22397 + priv->stats.txbkperr++;
22398 + priv->ieee80211->stats.tx_errors++;
22399 +#ifdef DEBUG_TX
22400 + DMESGW("TX bkp error int");
22401 +#endif
22402 + //tasklet_schedule(&priv->irq_tx_tasklet);
22403 + rtl8180_tx_isr(dev,BK_PRIORITY,1);
22404 + rtl8180_try_wake_queue(dev, BE_PRIORITY);
22405 + }
22406 +
22407 + if(inta & ISR_TBEDER){ //corresponding to BE_PRIORITY
22408 + priv->stats.txbeperr++;
22409 + priv->ieee80211->stats.tx_errors++;
22410 +#ifdef DEBUG_TX
22411 + DMESGW("TX bep error int");
22412 +#endif
22413 + rtl8180_tx_isr(dev,BE_PRIORITY,1);
22414 + //tasklet_schedule(&priv->irq_tx_tasklet);
22415 + rtl8180_try_wake_queue(dev, BE_PRIORITY);
22416 + }
22417 +#endif
22418 + if(inta & ISR_TNPDER){ //corresponding to VO_PRIORITY
22419 + priv->stats.txnperr++;
22420 + priv->ieee80211->stats.tx_errors++;
22421 +#ifdef DEBUG_TX
22422 + DMESGW("TX np error int");
22423 +#endif
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);
22428 +#endif
22429 + }
22430 +
22431 + if(inta & ISR_TLPDER){ //corresponding to VI_PRIORITY
22432 + priv->stats.txlperr++;
22433 + priv->ieee80211->stats.tx_errors++;
22434 +#ifdef DEBUG_TX
22435 + DMESGW("TX lp error int");
22436 +#endif
22437 + rtl8180_tx_isr(dev,LOW_PRIORITY,1);
22438 + //tasklet_schedule(&priv->irq_tx_tasklet);
22439 + rtl8180_try_wake_queue(dev, LOW_PRIORITY);
22440 + }
22441 +
22442 + if(inta & ISR_ROK){
22443 +#ifdef DEBUG_RX
22444 + DMESG("Frame arrived !");
22445 +#endif
22446 + //priv->NumRxOkInPeriod++; //YJ,del,080828
22447 + priv->stats.rxint++;
22448 + tasklet_schedule(&priv->irq_rx_tasklet);
22449 + }
22450 +
22451 + if(inta & ISR_RQoSOK ){
22452 +#ifdef DEBUG_RX
22453 + DMESG("QoS Frame arrived !");
22454 +#endif
22455 + //priv->NumRxOkInPeriod++; //YJ,del,080828
22456 + priv->stats.rxint++;
22457 + tasklet_schedule(&priv->irq_rx_tasklet);
22458 + }
22459 + if(inta & ISR_BcnInt) {
22460 + //DMESG("Preparing Beacons");
22461 + rtl8180_prepare_beacon(dev);
22462 + }
22463 +
22464 + if(inta & ISR_RDU){
22465 +//#ifdef DEBUG_RX
22466 + DMESGW("No RX descriptor available");
22467 + priv->stats.rxrdu++;
22468 +//#endif
22469 + tasklet_schedule(&priv->irq_rx_tasklet);
22470 + /*queue_work(priv->workqueue ,&priv->restart_work);*/
22471 +
22472 + }
22473 + if(inta & ISR_RXFOVW){
22474 +#ifdef DEBUG_RX
22475 + DMESGW("RX fifo overflow");
22476 +#endif
22477 + priv->stats.rxoverflow++;
22478 + tasklet_schedule(&priv->irq_rx_tasklet);
22479 + //queue_work(priv->workqueue ,&priv->restart_work);
22480 + }
22481 +
22482 + if(inta & ISR_TXFOVW) priv->stats.txoverflow++;
22483 +
22484 + if(inta & ISR_TNPDOK){ //Normal priority tx ok
22485 +#ifdef DEBUG_TX
22486 + DMESG ("TX normal priority OK");
22487 +#endif
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);
22494 + }
22495 +
22496 + if(inta & ISR_TLPDOK){ //Low priority tx ok
22497 +#ifdef DEBUG_TX
22498 + DMESG ("TX low priority OK");
22499 +#endif
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);
22507 + }
22508 +
22509 +#ifdef CONFIG_RTL8185B
22510 + if(inta & ISR_TBKDOK){ //corresponding to BK_PRIORITY
22511 + priv->stats.txbkpokint++;
22512 +#ifdef DEBUG_TX
22513 + DMESGW("TX bk priority ok");
22514 +#endif
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);
22520 + }
22521 +
22522 + if(inta & ISR_TBEDOK){ //corresponding to BE_PRIORITY
22523 + priv->stats.txbeperr++;
22524 +#ifdef DEBUG_TX
22525 + DMESGW("TX be priority ok");
22526 +#endif
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);
22532 + }
22533 +#endif
22534 + force_pci_posting(dev);
22535 + spin_unlock_irqrestore(&priv->irq_th_lock,flags);
22536 +
22537 + return IRQ_HANDLED;
22538 +}
22539 +
22540 +
22541 +void rtl8180_irq_rx_tasklet(struct r8180_priv* priv)
22542 +{
22543 +// unsigned long flags;
22544 +
22545 +/* spin_lock_irqsave(&priv->irq_lock, flags);
22546 + priv->irq_mask &=~IMR_ROK;
22547 + priv->irq_mask &=~IMR_RDU;
22548 +
22549 + rtl8180_irq_enable(priv->dev);
22550 + spin_unlock_irqrestore(&priv->irq_lock, flags);
22551 +*/
22552 + rtl8180_rx(priv->dev);
22553 +
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);
22559 +*/
22560 +}
22561 +
22562 +/****************************************************************************
22563 +lizhaoming--------------------------- RF power on/power off -----------------
22564 +*****************************************************************************/
22565 +
22566 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
22567 +void GPIOChangeRFWorkItemCallBack(struct work_struct *work)
22568 +{
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);
22573 +#else
22574 +void GPIOChangeRFWorkItemCallBack(struct ieee80211_device *ieee)
22575 +{
22576 + struct net_device *dev = ieee->dev;
22577 + struct r8180_priv *priv = ieee80211_priv(dev);
22578 +#endif
22579 +
22580 + //u16 tmp2byte;
22581 + u8 btPSR;
22582 + u8 btConfig0;
22583 + RT_RF_POWER_STATE eRfPowerStateToSet;
22584 + bool bActuallySet=false;
22585 +
22586 + char *argv[3];
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__);
22591 +
22592 +#ifdef ENABLE_LPS
22593 + if(readf_count % 10 == 0)
22594 + priv->PowerProfile = read_acadapter_file("/proc/acpi/ac_adapter/AC0/state");
22595 +
22596 + readf_count = (readf_count+1)%0xffff;
22597 +#endif
22598 +#if 0
22599 + if(priv->up == 0)//driver stopped
22600 + {
22601 + printk("\nDo nothing...");
22602 + goto out;
22603 + }
22604 + else
22605 +#endif
22606 + {
22607 + // We should turn off LED before polling FF51[4].
22608 +
22609 + //Turn off LED.
22610 + btPSR = read_nic_byte(dev, PSR);
22611 + write_nic_byte(dev, PSR, (btPSR & ~BIT3));
22612 +
22613 + //It need to delay 4us suggested by Jong, 2008-01-16
22614 + udelay(4);
22615 +
22616 + //HW radio On/Off according to the value of FF51[4](config0)
22617 + btConfig0 = btPSR = read_nic_byte(dev, CONFIG0);
22618 +
22619 + //Turn on LED.
22620 + write_nic_byte(dev, PSR, btPSR| BIT3);
22621 +
22622 + eRfPowerStateToSet = (btConfig0 & BIT4) ? eRfOn : eRfOff;
22623 +
22624 + if((priv->ieee80211->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn))
22625 + {
22626 + priv->ieee80211->bHwRadioOff = false;
22627 + bActuallySet = true;
22628 + }
22629 + else if((priv->ieee80211->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff))
22630 + {
22631 + priv->ieee80211->bHwRadioOff = true;
22632 + bActuallySet = true;
22633 + }
22634 +
22635 + if(bActuallySet)
22636 + {
22637 + MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
22638 +
22639 + /* To update the UI status for Power status changed */
22640 + if(priv->ieee80211->bHwRadioOff == true)
22641 + argv[1] = "RFOFF";
22642 + else{
22643 + //if(!priv->RfOffReason)
22644 + argv[1] = "RFON";
22645 + //else
22646 + // argv[1] = "RFOFF";
22647 + }
22648 + argv[0] = RadioPowerPath;
22649 + argv[2] = NULL;
22650 +
22651 + call_usermodehelper(RadioPowerPath,argv,envp,1);
22652 + }
22653 +
22654 + }
22655 +
22656 +}
22657 +
22658 +static u8 read_acadapter_file(char *filename)
22659 +{
22660 +//#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
22661 +#if 0
22662 + int fd;
22663 + char buf[1];
22664 + char ret[50];
22665 + int i = 0;
22666 + int n = 0;
22667 + mm_segment_t old_fs = get_fs();
22668 + set_fs(KERNEL_DS);
22669 +
22670 + fd = sys_open(filename, O_RDONLY, 0);
22671 + if (fd >= 0) {
22672 + while (sys_read(fd, buf, 1) == 1)
22673 + {
22674 + i++;
22675 + if(i>10)
22676 + {
22677 + if(buf[0]!=' ')
22678 + {
22679 + ret[n]=buf[0];
22680 + n++;
22681 + }
22682 + }
22683 + }
22684 + sys_close(fd);
22685 + }
22686 + ret[n]='\0';
22687 +// printk("%s \n", ret);
22688 + set_fs(old_fs);
22689 +
22690 + if(strncmp(ret, "off-line",8) == 0)
22691 + {
22692 + return 1;
22693 + }
22694 +#endif
22695 + return 0;
22696 +}
22697 +
22698 +/***************************************************************************
22699 + ------------------- module init / exit stubs ----------------
22700 +****************************************************************************/
22701 +module_init(rtl8180_pci_module_init);
22702 +module_exit(rtl8180_pci_module_exit);
22703 +
22704 --- /dev/null
22705 +++ b/drivers/staging/rtl8187se/r8180_dm.c
22706 @@ -0,0 +1,1725 @@
22707 +//#include "r8180.h"
22708 +#include "r8180_dm.h"
22709 +#include "r8180_hw.h"
22710 +#include "r8180_93cx6.h"
22711 +//{by amy 080312
22712 +
22713 +//
22714 +// Description:
22715 +// Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise.
22716 +//
22717 +//+by amy 080312
22718 +#define RATE_ADAPTIVE_TIMER_PERIOD 300
22719 +
22720 +bool CheckHighPower(struct net_device *dev)
22721 +{
22722 + struct r8180_priv *priv = ieee80211_priv(dev);
22723 + struct ieee80211_device *ieee = priv->ieee80211;
22724 +
22725 + if(!priv->bRegHighPowerMechanism)
22726 + {
22727 + return false;
22728 + }
22729 +
22730 + if(ieee->state == IEEE80211_LINKED_SCANNING)
22731 + {
22732 + return false;
22733 + }
22734 +
22735 + return true;
22736 +}
22737 +
22738 +//
22739 +// Description:
22740 +// Update Tx power level if necessary.
22741 +// See also DoRxHighPower() and SetTxPowerLevel8185() for reference.
22742 +//
22743 +// Note:
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.
22748 +//
22749 +void
22750 +DoTxHighPower(
22751 + struct net_device *dev
22752 + )
22753 +{
22754 + struct r8180_priv *priv = ieee80211_priv(dev);
22755 + u16 HiPwrUpperTh = 0;
22756 + u16 HiPwrLowerTh = 0;
22757 + u8 RSSIHiPwrUpperTh;
22758 + u8 RSSIHiPwrLowerTh;
22759 + u8 u1bTmp;
22760 + char OfdmTxPwrIdx, CckTxPwrIdx;
22761 +
22762 + //printk("----> DoTxHighPower()\n");
22763 +
22764 + HiPwrUpperTh = priv->RegHiPwrUpperTh;
22765 + HiPwrLowerTh = priv->RegHiPwrLowerTh;
22766 +
22767 + HiPwrUpperTh = HiPwrUpperTh * 10;
22768 + HiPwrLowerTh = HiPwrLowerTh * 10;
22769 + RSSIHiPwrUpperTh = priv->RegRSSIHiPwrUpperTh;
22770 + RSSIHiPwrLowerTh = priv->RegRSSIHiPwrLowerTh;
22771 +
22772 + //lzm add 080826
22773 + OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
22774 + CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
22775 +
22776 + // printk("DoTxHighPower() - UndecoratedSmoothedSS:%d, CurCCKRSSI = %d , bCurCCKPkt= %d \n", priv->UndecoratedSmoothedSS, priv->CurCCKRSSI, priv->bCurCCKPkt );
22777 +
22778 + if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
22779 + (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh)))
22780 + {
22781 + // Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah
22782 +
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);
22786 +
22787 + // If it never enter High Power.
22788 + if( CckTxPwrIdx == u1bTmp)
22789 + {
22790 + u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm
22791 + write_nic_byte(dev, CCK_TXAGC, u1bTmp);
22792 +
22793 + u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
22794 + u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm
22795 + write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
22796 + }
22797 +
22798 + }
22799 + else if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&
22800 + (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh))
22801 + {
22802 + // printk("DoTxHighPower() - lower Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrLowerTh );
22803 + if(priv->bToUpdateTxPwr)
22804 + {
22805 + priv->bToUpdateTxPwr = false;
22806 + //SD3 required.
22807 + u1bTmp= read_nic_byte(dev, CCK_TXAGC);
22808 + if(u1bTmp < CckTxPwrIdx)
22809 + {
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);
22813 + }
22814 +
22815 + u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
22816 + if(u1bTmp < OfdmTxPwrIdx)
22817 + {
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);
22821 + }
22822 + }
22823 + }
22824 +
22825 + //printk("<---- DoTxHighPower()\n");
22826 +}
22827 +
22828 +
22829 +//
22830 +// Description:
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.
22834 +//
22835 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
22836 +void rtl8180_tx_pw_wq (struct work_struct *work)
22837 +{
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;
22844 +#else
22845 +void rtl8180_tx_pw_wq(struct net_device *dev)
22846 +{
22847 + // struct r8180_priv *priv = ieee80211_priv(dev);
22848 +#endif
22849 +
22850 +// printk("----> UpdateTxPowerWorkItemCallback()\n");
22851 +
22852 + DoTxHighPower(dev);
22853 +
22854 +// printk("<---- UpdateTxPowerWorkItemCallback()\n");
22855 +}
22856 +
22857 +
22858 +//
22859 +// Description:
22860 +// Return TRUE if we shall perform DIG Mecahnism, FALSE otherwise.
22861 +//
22862 +bool
22863 +CheckDig(
22864 + struct net_device *dev
22865 + )
22866 +{
22867 + struct r8180_priv *priv = ieee80211_priv(dev);
22868 + struct ieee80211_device *ieee = priv->ieee80211;
22869 +
22870 + if(!priv->bDigMechanism)
22871 + return false;
22872 +
22873 + if(ieee->state != IEEE80211_LINKED)
22874 + return false;
22875 +
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.
22878 + return false;
22879 + return true;
22880 +}
22881 +//
22882 +// Description:
22883 +// Implementation of DIG for Zebra and Zebra2.
22884 +//
22885 +void
22886 +DIG_Zebra(
22887 + struct net_device *dev
22888 + )
22889 +{
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;
22896 +
22897 + //printk("---------> DIG_Zebra()\n");
22898 +
22899 + CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);
22900 + OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);
22901 + OfdmFA1 = 0x15;
22902 + OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;
22903 +
22904 +// printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm);
22905 +// printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm);
22906 +
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)
22911 + }
22912 + //if(pHalData->VersionID != VERSION_8187B_B)
22913 + { // Advised from SD3 DZ
22914 + OfdmFA1 = 0x20;
22915 + }
22916 +
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;
22921 +
22922 + if(AwakePeriodIn2Sec)
22923 + {
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));
22929 + }
22930 + else
22931 + {
22932 + ;//RT_TRACE(COMP_DIG, DBG_WARNING, ("ERROR!! AwakePeriodIn2Sec should not be ZERO!!\n"));
22933 + }
22934 +#endif
22935 +
22936 + InitialGainStep = 8;
22937 + LowestGainStage = priv->RegBModeGainStage; // Lowest gain stage.
22938 +
22939 + if (OFDMFalseAlarm > OfdmFA1)
22940 + {
22941 + if (OFDMFalseAlarm > OfdmFA2)
22942 + {
22943 + priv->DIG_NumberFallbackVote++;
22944 + if (priv->DIG_NumberFallbackVote >1)
22945 + {
22946 + //serious OFDM False Alarm, need fallback
22947 + if (priv->InitialGain < InitialGainStep)
22948 + {
22949 + priv->InitialGainBackUp= priv->InitialGain;
22950 +
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);
22955 + }
22956 + priv->DIG_NumberFallbackVote = 0;
22957 + priv->DIG_NumberUpgradeVote=0;
22958 + }
22959 + }
22960 + else
22961 + {
22962 + if (priv->DIG_NumberFallbackVote)
22963 + priv->DIG_NumberFallbackVote--;
22964 + }
22965 + priv->DIG_NumberUpgradeVote=0;
22966 + }
22967 + else
22968 + {
22969 + if (priv->DIG_NumberFallbackVote)
22970 + priv->DIG_NumberFallbackVote--;
22971 + priv->DIG_NumberUpgradeVote++;
22972 +
22973 + if (priv->DIG_NumberUpgradeVote>9)
22974 + {
22975 + if (priv->InitialGain > LowestGainStage) // In 87B, m78dBm means State 4 (m864dBm)
22976 + {
22977 + priv->InitialGainBackUp= priv->InitialGain;
22978 +
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);
22983 + }
22984 + priv->DIG_NumberFallbackVote = 0;
22985 + priv->DIG_NumberUpgradeVote=0;
22986 + }
22987 + }
22988 +
22989 +// printk("DIG+++++++ OFDM:%d\n", priv->InitialGain);
22990 + //printk("<--------- DIG_Zebra()\n");
22991 +}
22992 +
22993 +//
22994 +// Description:
22995 +// Dispatch DIG implementation according to RF.
22996 +//
22997 +void
22998 +DynamicInitGain(
22999 + struct net_device *dev
23000 + )
23001 +{
23002 + struct r8180_priv *priv = ieee80211_priv(dev);
23003 +
23004 + switch(priv->rf_chip)
23005 + {
23006 + case RF_ZEBRA2: // [AnnieWorkaround] For Zebra2, 2005-08-01.
23007 + case RF_ZEBRA4:
23008 + DIG_Zebra( dev );
23009 + break;
23010 +
23011 + default:
23012 + printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip);
23013 + break;
23014 + }
23015 +}
23016 +
23017 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
23018 +void rtl8180_hw_dig_wq (struct work_struct *work)
23019 +{
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;
23026 +#else
23027 +void rtl8180_hw_dig_wq(struct net_device *dev)
23028 +{
23029 +
23030 +#endif
23031 + struct r8180_priv *priv = ieee80211_priv(dev);
23032 +
23033 + // Read CCK and OFDM False Alarm.
23034 + priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
23035 +
23036 +
23037 + // Adjust Initial Gain dynamically.
23038 + DynamicInitGain(dev);
23039 +
23040 +}
23041 +
23042 +int
23043 +IncludedInSupportedRates(
23044 + struct r8180_priv *priv,
23045 + u8 TxRate )
23046 +{
23047 + u8 rate_len;
23048 + u8 rate_ex_len;
23049 + u8 RateMask = 0x7F;
23050 + u8 idx;
23051 + unsigned short Found = 0;
23052 + u8 NaiveTxRate = TxRate&RateMask;
23053 +
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++ )
23057 + {
23058 + if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate )
23059 + {
23060 + Found = 1;
23061 + goto found_rate;
23062 + }
23063 + }
23064 + for( idx=0; idx< rate_ex_len; idx++ )
23065 + {
23066 + if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate )
23067 + {
23068 + Found = 1;
23069 + goto found_rate;
23070 + }
23071 + }
23072 + return Found;
23073 + found_rate:
23074 + return Found;
23075 +}
23076 +
23077 +//
23078 +// Description:
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.
23082 +//
23083 +u8
23084 +GetUpgradeTxRate(
23085 + struct net_device *dev,
23086 + u8 rate
23087 + )
23088 +{
23089 + struct r8180_priv *priv = ieee80211_priv(dev);
23090 + u8 UpRate;
23091 +
23092 + // Upgrade 1 degree.
23093 + switch(rate)
23094 + {
23095 + case 108: // Up to 54Mbps.
23096 + UpRate = 108;
23097 + break;
23098 +
23099 + case 96: // Up to 54Mbps.
23100 + UpRate = 108;
23101 + break;
23102 +
23103 + case 72: // Up to 48Mbps.
23104 + UpRate = 96;
23105 + break;
23106 +
23107 + case 48: // Up to 36Mbps.
23108 + UpRate = 72;
23109 + break;
23110 +
23111 + case 36: // Up to 24Mbps.
23112 + UpRate = 48;
23113 + break;
23114 +
23115 + case 22: // Up to 18Mbps.
23116 + UpRate = 36;
23117 + break;
23118 +
23119 + case 11: // Up to 11Mbps.
23120 + UpRate = 22;
23121 + break;
23122 +
23123 + case 4: // Up to 5.5Mbps.
23124 + UpRate = 11;
23125 + break;
23126 +
23127 + case 2: // Up to 2Mbps.
23128 + UpRate = 4;
23129 + break;
23130 +
23131 + default:
23132 + printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
23133 + return rate;
23134 + }
23135 + // Check if the rate is valid.
23136 + if(IncludedInSupportedRates(priv, UpRate))
23137 + {
23138 +// printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate);
23139 + return UpRate;
23140 + }
23141 + else
23142 + {
23143 + //printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate);
23144 + return rate;
23145 + }
23146 + return rate;
23147 +}
23148 +//
23149 +// Description:
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.
23153 +//
23154 +u8
23155 +GetDegradeTxRate(
23156 + struct net_device *dev,
23157 + u8 rate
23158 + )
23159 +{
23160 + struct r8180_priv *priv = ieee80211_priv(dev);
23161 + u8 DownRate;
23162 +
23163 + // Upgrade 1 degree.
23164 + switch(rate)
23165 + {
23166 + case 108: // Down to 48Mbps.
23167 + DownRate = 96;
23168 + break;
23169 +
23170 + case 96: // Down to 36Mbps.
23171 + DownRate = 72;
23172 + break;
23173 +
23174 + case 72: // Down to 24Mbps.
23175 + DownRate = 48;
23176 + break;
23177 +
23178 + case 48: // Down to 18Mbps.
23179 + DownRate = 36;
23180 + break;
23181 +
23182 + case 36: // Down to 11Mbps.
23183 + DownRate = 22;
23184 + break;
23185 +
23186 + case 22: // Down to 5.5Mbps.
23187 + DownRate = 11;
23188 + break;
23189 +
23190 + case 11: // Down to 2Mbps.
23191 + DownRate = 4;
23192 + break;
23193 +
23194 + case 4: // Down to 1Mbps.
23195 + DownRate = 2;
23196 + break;
23197 +
23198 + case 2: // Down to 1Mbps.
23199 + DownRate = 2;
23200 + break;
23201 +
23202 + default:
23203 + printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
23204 + return rate;
23205 + }
23206 + // Check if the rate is valid.
23207 + if(IncludedInSupportedRates(priv, DownRate))
23208 + {
23209 +// printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate);
23210 + return DownRate;
23211 + }
23212 + else
23213 + {
23214 + //printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate);
23215 + return rate;
23216 + }
23217 + return rate;
23218 +}
23219 +//
23220 +// Helper function to determine if specified data rate is
23221 +// CCK rate.
23222 +// 2005.01.25, by rcnjko.
23223 +//
23224 +bool
23225 +MgntIsCckRate(
23226 + u16 rate
23227 + )
23228 +{
23229 + bool bReturn = false;
23230 +
23231 + if((rate <= 22) && (rate != 12) && (rate != 18))
23232 + {
23233 + bReturn = true;
23234 + }
23235 +
23236 + return bReturn;
23237 +}
23238 +#ifdef CONFIG_RTL818X_S
23239 +//
23240 +// Description:
23241 +// Tx Power tracking mechanism routine on 87SE.
23242 +// Created by Roger, 2007.12.11.
23243 +//
23244 +void
23245 +TxPwrTracking87SE(
23246 + struct net_device *dev
23247 +)
23248 +{
23249 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
23250 + u8 tmpu1Byte, CurrentThermal, Idx;
23251 + char CckTxPwrIdx, OfdmTxPwrIdx;
23252 + //u32 u4bRfReg;
23253 +
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
23257 +
23258 + //printk("TxPwrTracking87SE(): CurrentThermal(%d)\n", CurrentThermal);
23259 +
23260 + if( CurrentThermal != priv->ThermalMeter)
23261 + {
23262 +// printk("TxPwrTracking87SE(): Thermal meter changed!!!\n");
23263 +
23264 + // Update Tx Power level on each channel.
23265 + for(Idx = 1; Idx<15; Idx++)
23266 + {
23267 + CckTxPwrIdx = priv->chtxpwr[Idx];
23268 + OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];
23269 +
23270 + if( CurrentThermal > priv->ThermalMeter )
23271 + { // higher thermal meter.
23272 + CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
23273 + OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
23274 +
23275 + if(CckTxPwrIdx >35)
23276 + CckTxPwrIdx = 35; // Force TxPower to maximal index.
23277 + if(OfdmTxPwrIdx >35)
23278 + OfdmTxPwrIdx = 35;
23279 + }
23280 + else
23281 + { // lower thermal meter.
23282 + CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
23283 + OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
23284 +
23285 + if(CckTxPwrIdx <0)
23286 + CckTxPwrIdx = 0;
23287 + if(OfdmTxPwrIdx <0)
23288 + OfdmTxPwrIdx = 0;
23289 + }
23290 +
23291 + // Update TxPower level on CCK and OFDM resp.
23292 + priv->chtxpwr[Idx] = CckTxPwrIdx;
23293 + priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;
23294 + }
23295 +
23296 + // Update TxPower level immediately.
23297 + rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);
23298 + }
23299 + priv->ThermalMeter = CurrentThermal;
23300 +}
23301 +void
23302 +StaRateAdaptive87SE(
23303 + struct net_device *dev
23304 + )
23305 +{
23306 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
23307 + unsigned long CurrTxokCnt;
23308 + u16 CurrRetryCnt;
23309 + u16 CurrRetryRate;
23310 + //u16 i,idx;
23311 + unsigned long CurrRxokCnt;
23312 + bool bTryUp = false;
23313 + bool bTryDown = false;
23314 + u8 TryUpTh = 1;
23315 + u8 TryDownTh = 2;
23316 + u32 TxThroughput;
23317 + long CurrSignalStrength;
23318 + bool bUpdateInitialGain = false;
23319 + u8 u1bOfdm=0, u1bCck = 0;
23320 + char OfdmTxPwrIdx, CckTxPwrIdx;
23321 +
23322 + priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD;
23323 +
23324 +
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)
23335 + {
23336 + CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt);
23337 + }
23338 + else
23339 + { // It may be serious retry. To distinguish serious retry or no packets modified by Bruce
23340 + CurrRetryRate = (u16)(CurrRetryCnt*100/1);
23341 + }
23342 +
23343 +
23344 + //
23345 + // Added by Roger, 2007.01.02.
23346 + // For debug information.
23347 + //
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);
23355 +
23356 + priv->LastRetryCnt = priv->CurrRetryCnt;
23357 + priv->LastTxokCnt = priv->NumTxOkTotal;
23358 + priv->LastRxokCnt = priv->ieee80211->NumRxOkTotal;
23359 + priv->CurrRetryCnt = 0;
23360 +
23361 + //2No Tx packets, return to init_rate or not?
23362 + if (CurrRetryRate==0 && CurrTxokCnt == 0)
23363 + {
23364 + //
23365 + //After 9 (30*300ms) seconds in this condition, we try to raise rate.
23366 + //
23367 + priv->TryupingCountNoData++;
23368 +
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)
23372 + {
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;
23379 + }
23380 + goto SetInitialGain;
23381 + }
23382 + else
23383 + {
23384 + priv->TryupingCountNoData=0; //Reset trying up times.
23385 + }
23386 +
23387 +
23388 + //
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.
23392 + //
23393 +
23394 + //
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.
23404 + //
23405 + //
23406 +
23407 + // 11Mbps or 36Mbps
23408 + // Check more times in these rate(key rates).
23409 + //
23410 + if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
23411 + {
23412 + TryUpTh += 9;
23413 + }
23414 + //
23415 + // Let these rates down more difficult.
23416 + //
23417 + if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
23418 + {
23419 + TryDownTh += 1;
23420 + }
23421 +
23422 + //1 Adjust Rate.
23423 + if (priv->bTryuping == true)
23424 + {
23425 + //2 For Test Upgrading mechanism
23426 + // Note:
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.
23430 +
23431 + // Upgrading rate did not improve the retry rate, fallback to the original rate.
23432 + if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput)
23433 + {
23434 + //Not necessary raising rate, fall back rate.
23435 + bTryDown = true;
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);
23439 + }
23440 + else
23441 + {
23442 + priv->bTryuping = false;
23443 + }
23444 + }
23445 + else if (CurrSignalStrength > -47 && (CurrRetryRate < 50))
23446 + {
23447 + //2For High Power
23448 + //
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.
23453 + //
23454 + // Also need to check retry rate for safety, by Bruce, 2007-06-05.
23455 + if(priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate )
23456 + {
23457 + bTryUp = true;
23458 + // Upgrade Tx Rate directly.
23459 + priv->TryupingCount += TryUpTh;
23460 + }
23461 +// printk("case2: StaRateAdaptive87SE: Power(%d) is high enough!!. \n", CurrSignalStrength);
23462 +
23463 + }
23464 + else if(CurrTxokCnt > 9 && CurrTxokCnt< 100 && CurrRetryRate >= 600)
23465 + {
23466 + //2 For Serious Retry
23467 + //
23468 + // Traffic is not busy but our Tx retry is serious.
23469 + //
23470 + bTryDown = true;
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);
23474 + }
23475 + else if ( priv->CurrentOperaRate == 108 )
23476 + {
23477 + //2For 54Mbps
23478 + // Air Link
23479 + if ( (CurrRetryRate>26)&&(priv->LastRetryRate>25))
23480 +// if ( (CurrRetryRate>40)&&(priv->LastRetryRate>39))
23481 + {
23482 + //Down to rate 48Mbps.
23483 + bTryDown = true;
23484 + }
23485 + // Cable Link
23486 + else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
23487 +// else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
23488 + {
23489 + //Down to rate 48Mbps.
23490 + bTryDown = true;
23491 + }
23492 +
23493 + if(bTryDown && (CurrSignalStrength < -75)) //cable link
23494 + {
23495 + priv->TryDownCountLowData += TryDownTh;
23496 + }
23497 + //printk("case4---54M \n");
23498 +
23499 + }
23500 + else if ( priv->CurrentOperaRate == 96 )
23501 + {
23502 + //2For 48Mbps
23503 + //Air Link
23504 + if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47)))
23505 +// if ( ((CurrRetryRate>65) && (priv->LastRetryRate>64)))
23506 +
23507 + {
23508 + //Down to rate 36Mbps.
23509 + bTryDown = true;
23510 + }
23511 + //Cable Link
23512 + else if ( ((CurrRetryRate>21) && (priv->LastRetryRate>20)) && (CurrSignalStrength > -74))
23513 + {
23514 + //Down to rate 36Mbps.
23515 + bTryDown = true;
23516 + }
23517 + else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
23518 +// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
23519 + {
23520 + bTryDown = true;
23521 + priv->TryDownCountLowData += TryDownTh;
23522 + }
23523 + else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) ) //TO DO: need to consider (RSSI)
23524 +// else if ( (CurrRetryRate<28) && (priv->LastRetryRate<8) )
23525 + {
23526 + bTryUp = true;
23527 + }
23528 +
23529 + if(bTryDown && (CurrSignalStrength < -75))
23530 + {
23531 + priv->TryDownCountLowData += TryDownTh;
23532 + }
23533 + //printk("case5---48M \n");
23534 + }
23535 + else if ( priv->CurrentOperaRate == 72 )
23536 + {
23537 + //2For 36Mbps
23538 + if ( (CurrRetryRate>43) && (priv->LastRetryRate>41))
23539 +// if ( (CurrRetryRate>60) && (priv->LastRetryRate>59))
23540 + {
23541 + //Down to rate 24Mbps.
23542 + bTryDown = true;
23543 + }
23544 + else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
23545 +// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
23546 + {
23547 + bTryDown = true;
23548 + priv->TryDownCountLowData += TryDownTh;
23549 + }
23550 + else if ( (CurrRetryRate<15) && (priv->LastRetryRate<16)) //TO DO: need to consider (RSSI)
23551 +// else if ( (CurrRetryRate<35) && (priv->LastRetryRate<36))
23552 + {
23553 + bTryUp = true;
23554 + }
23555 +
23556 + if(bTryDown && (CurrSignalStrength < -80))
23557 + {
23558 + priv->TryDownCountLowData += TryDownTh;
23559 + }
23560 + //printk("case6---36M \n");
23561 + }
23562 + else if ( priv->CurrentOperaRate == 48 )
23563 + {
23564 + //2For 24Mbps
23565 + // Air Link
23566 + if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62)))
23567 +// if ( ((CurrRetryRate>83) && (priv->LastRetryRate>82)))
23568 + {
23569 + //Down to rate 18Mbps.
23570 + bTryDown = true;
23571 + }
23572 + //Cable Link
23573 + else if ( ((CurrRetryRate>33) && (priv->LastRetryRate>32)) && (CurrSignalStrength > -82) )
23574 +// else if ( ((CurrRetryRate>50) && (priv->LastRetryRate>49)) && (CurrSignalStrength > -82) )
23575 + {
23576 + //Down to rate 18Mbps.
23577 + bTryDown = true;
23578 + }
23579 + else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
23580 +// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
23581 +
23582 + {
23583 + bTryDown = true;
23584 + priv->TryDownCountLowData += TryDownTh;
23585 + }
23586 + else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21)) //TO DO: need to consider (RSSI)
23587 +// else if ( (CurrRetryRate<40) && (priv->LastRetryRate<41))
23588 + {
23589 + bTryUp = true;
23590 + }
23591 +
23592 + if(bTryDown && (CurrSignalStrength < -82))
23593 + {
23594 + priv->TryDownCountLowData += TryDownTh;
23595 + }
23596 + //printk("case7---24M \n");
23597 + }
23598 + else if ( priv->CurrentOperaRate == 36 )
23599 + {
23600 + //2For 18Mbps
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)))
23606 + {
23607 + //Down to rate 11Mbps.
23608 + bTryDown = true;
23609 + }
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 ))
23613 + {
23614 + bTryDown = true;
23615 + priv->TryDownCountLowData += TryDownTh;
23616 + }
23617 + else if ( (CurrRetryRate<22) && (priv->LastRetryRate<23)) //TO DO: need to consider (RSSI)
23618 +// else if ( (CurrRetryRate<42) && (priv->LastRetryRate<43))
23619 + {
23620 + bTryUp = true;
23621 + }
23622 + //printk("case8---18M \n");
23623 + }
23624 + else if ( priv->CurrentOperaRate == 22 )
23625 + {
23626 + //2For 11Mbps
23627 + if (CurrRetryRate>95)
23628 +// if (CurrRetryRate>155)
23629 + {
23630 + bTryDown = true;
23631 + }
23632 + else if ( (CurrRetryRate<29) && (priv->LastRetryRate <30) )//TO DO: need to consider (RSSI)
23633 +// else if ( (CurrRetryRate<49) && (priv->LastRetryRate <50) )
23634 + {
23635 + bTryUp = true;
23636 + }
23637 + //printk("case9---11M \n");
23638 + }
23639 + else if ( priv->CurrentOperaRate == 11 )
23640 + {
23641 + //2For 5.5Mbps
23642 + if (CurrRetryRate>149)
23643 +// if (CurrRetryRate>189)
23644 + {
23645 + bTryDown = true;
23646 + }
23647 + else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65))
23648 +// else if ( (CurrRetryRate<80) && (priv->LastRetryRate < 85))
23649 +
23650 + {
23651 + bTryUp = true;
23652 + }
23653 + //printk("case10---5.5M \n");
23654 + }
23655 + else if ( priv->CurrentOperaRate == 4 )
23656 + {
23657 + //2For 2 Mbps
23658 + if((CurrRetryRate>99) && (priv->LastRetryRate>99))
23659 +// if((CurrRetryRate>199) && (priv->LastRetryRate>199))
23660 + {
23661 + bTryDown = true;
23662 + }
23663 + else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70))
23664 +// else if ( (CurrRetryRate < 85) && (priv->LastRetryRate < 90))
23665 + {
23666 + bTryUp = true;
23667 + }
23668 + //printk("case11---2M \n");
23669 + }
23670 + else if ( priv->CurrentOperaRate == 2 )
23671 + {
23672 + //2For 1 Mbps
23673 + if( (CurrRetryRate<70) && (priv->LastRetryRate<75))
23674 +// if( (CurrRetryRate<90) && (priv->LastRetryRate<95))
23675 + {
23676 + bTryUp = true;
23677 + }
23678 + //printk("case12---1M \n");
23679 + }
23680 +
23681 + if(bTryUp && bTryDown)
23682 + printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
23683 +
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)
23689 + {
23690 + if(jiffies% (CurrRetryRate + 101) == 0)
23691 + {
23692 + bTryUp = true;
23693 + priv->bTryuping = true;
23694 + //printk("StaRateAdaptive87SE(): Randomly try upgrading...\n");
23695 + }
23696 + }
23697 +
23698 + //1 Rate Mechanism
23699 + if(bTryUp)
23700 + {
23701 + priv->TryupingCount++;
23702 + priv->TryDownCountLowData = 0;
23703 +
23704 + {
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);
23709 +
23710 + }
23711 +
23712 + //
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.
23717 + //
23718 +
23719 + if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
23720 + (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping)
23721 + {
23722 + priv->TryupingCount = 0;
23723 + //
23724 + // When transfering from CCK to OFDM, DIG is an important issue.
23725 + //
23726 + if(priv->CurrentOperaRate == 22)
23727 + bUpdateInitialGain = true;
23728 +
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.
23731 + //
23732 + if( ((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) &&
23733 + (priv->FailTxRateCount > 2) )
23734 + priv->RateAdaptivePeriod= (RATE_ADAPTIVE_TIMER_PERIOD/2);
23735 +
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.
23738 +
23739 + priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
23740 +// printk("StaRateAdaptive87SE(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate);
23741 +
23742 + //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
23743 + if(priv->CurrentOperaRate ==36)
23744 + {
23745 + priv->bUpdateARFR=true;
23746 + write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
23747 +// printk("UP: ARFR=0xF8F\n");
23748 + }
23749 + else if(priv->bUpdateARFR)
23750 + {
23751 + priv->bUpdateARFR=false;
23752 + write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
23753 +// printk("UP: ARFR=0xFFF\n");
23754 + }
23755 +
23756 + // Update Fail Tx rate and count.
23757 + if(priv->LastFailTxRate != priv->CurrentOperaRate)
23758 + {
23759 + priv->LastFailTxRate = priv->CurrentOperaRate;
23760 + priv->FailTxRateCount = 0;
23761 + priv->LastFailTxRateSS = -200; // Set lowest power.
23762 + }
23763 + }
23764 + }
23765 + else
23766 + {
23767 + if(priv->TryupingCount > 0)
23768 + priv->TryupingCount --;
23769 + }
23770 +
23771 + if(bTryDown)
23772 + {
23773 + priv->TryDownCountLowData++;
23774 + priv->TryupingCount = 0;
23775 + {
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);
23779 + }
23780 +
23781 + //Check if Tx rate can be degraded or Test trying upgrading should fallback.
23782 + if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping)
23783 + {
23784 + priv->TryDownCountLowData = 0;
23785 + priv->bTryuping = false;
23786 + // Update fail information.
23787 + if(priv->LastFailTxRate == priv->CurrentOperaRate)
23788 + {
23789 + priv->FailTxRateCount ++;
23790 + // Record the Tx fail rate signal strength.
23791 + if(CurrSignalStrength > priv->LastFailTxRateSS)
23792 + {
23793 + priv->LastFailTxRateSS = CurrSignalStrength;
23794 + }
23795 + }
23796 + else
23797 + {
23798 + priv->LastFailTxRate = priv->CurrentOperaRate;
23799 + priv->FailTxRateCount = 1;
23800 + priv->LastFailTxRateSS = CurrSignalStrength;
23801 + }
23802 + priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
23803 +
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 ))
23807 + {
23808 + priv->CurrentOperaRate = 72;
23809 +// printk("DN: weak signal strength (%d), degrade to 36Mbps\n", CurrSignalStrength);
23810 + }
23811 +
23812 + //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
23813 + if(priv->CurrentOperaRate ==36)
23814 + {
23815 + priv->bUpdateARFR=true;
23816 + write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
23817 +// printk("DN: ARFR=0xF8F\n");
23818 + }
23819 + else if(priv->bUpdateARFR)
23820 + {
23821 + priv->bUpdateARFR=false;
23822 + write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
23823 +// printk("DN: ARFR=0xFFF\n");
23824 + }
23825 +
23826 + //
23827 + // When it is CCK rate, it may need to update initial gain to receive lower power packets.
23828 + //
23829 + if(MgntIsCckRate(priv->CurrentOperaRate))
23830 + {
23831 + bUpdateInitialGain = true;
23832 + }
23833 +// printk("StaRateAdaptive87SE(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate);
23834 + }
23835 + }
23836 + else
23837 + {
23838 + if(priv->TryDownCountLowData > 0)
23839 + priv->TryDownCountLowData --;
23840 + }
23841 +
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))
23846 + {
23847 + priv->FailTxRateCount --;
23848 + }
23849 +
23850 +
23851 + OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
23852 + CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
23853 +
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))
23856 + {
23857 + u1bCck = read_nic_byte(dev, CCK_TXAGC);
23858 + u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
23859 +
23860 + // case 1: Never enter High power
23861 + if(u1bCck == CckTxPwrIdx )
23862 + {
23863 + if(u1bOfdm != (OfdmTxPwrIdx+2) )
23864 + {
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);
23869 + }
23870 + }
23871 + // case 2: enter high power
23872 + else if(u1bCck < CckTxPwrIdx)
23873 + {
23874 + if(!priv->bEnhanceTxPwr)
23875 + {
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));
23880 + }
23881 + }
23882 + }
23883 + else if(priv->bEnhanceTxPwr) //54/48/11/5.5/2/1
23884 + {
23885 + u1bCck = read_nic_byte(dev, CCK_TXAGC);
23886 + u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
23887 +
23888 + // case 1: Never enter High power
23889 + if(u1bCck == CckTxPwrIdx )
23890 + {
23891 + priv->bEnhanceTxPwr= false;
23892 + write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
23893 + //printk("Recover OFDM_TXAGC : ===== u1bOfdm= 0x%x\n", OfdmTxPwrIdx);
23894 + }
23895 + // case 2: enter high power
23896 + else if(u1bCck < CckTxPwrIdx)
23897 + {
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));
23902 +
23903 + }
23904 + }
23905 +
23906 + //
23907 + // We need update initial gain when we set tx rate "from OFDM to CCK" or
23908 + // "from CCK to OFDM".
23909 + //
23910 +SetInitialGain:
23911 + if(bUpdateInitialGain)
23912 + {
23913 + if(MgntIsCckRate(priv->CurrentOperaRate)) // CCK
23914 + {
23915 + if(priv->InitialGain > priv->RegBModeGainStage)
23916 + {
23917 + priv->InitialGainBackUp= priv->InitialGain;
23918 +
23919 + if(CurrSignalStrength < -85) // Low power, OFDM [0x17] = 26.
23920 + {
23921 + //SD3 SYs suggest that CurrSignalStrength < -65, ofdm 0x17=26.
23922 + priv->InitialGain = priv->RegBModeGainStage;
23923 + }
23924 + else if(priv->InitialGain > priv->RegBModeGainStage + 1)
23925 + {
23926 + priv->InitialGain -= 2;
23927 + }
23928 + else
23929 + {
23930 + priv->InitialGain --;
23931 + }
23932 + printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
23933 + UpdateInitialGain(dev);
23934 + }
23935 + }
23936 + else // OFDM
23937 + {
23938 + if(priv->InitialGain < 4)
23939 + {
23940 + priv->InitialGainBackUp= priv->InitialGain;
23941 +
23942 + priv->InitialGain ++;
23943 + printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
23944 + UpdateInitialGain(dev);
23945 + }
23946 + }
23947 + }
23948 +
23949 + //Record the related info
23950 + priv->LastRetryRate = CurrRetryRate;
23951 + priv->LastTxThroughput = TxThroughput;
23952 + priv->ieee80211->rate = priv->CurrentOperaRate * 5;
23953 +}
23954 +
23955 +#endif
23956 +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
23957 +void rtl8180_rate_adapter(struct work_struct * work)
23958 +{
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;
23962 +#else
23963 +void rtl8180_rate_adapter(struct net_device *dev)
23964 +{
23965 +
23966 +#endif
23967 + //struct r8180_priv *priv = ieee80211_priv(dev);
23968 +// DMESG("---->rtl8180_rate_adapter");
23969 + StaRateAdaptive87SE(dev);
23970 +// DMESG("<----rtl8180_rate_adapter");
23971 +}
23972 +void timer_rate_adaptive(unsigned long data)
23973 +{
23974 + struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
23975 + //DMESG("---->timer_rate_adaptive()\n");
23976 + if(!priv->up)
23977 + {
23978 +// DMESG("<----timer_rate_adaptive():driver is not up!\n");
23979 + return;
23980 + }
23981 + if((priv->ieee80211->iw_mode != IW_MODE_MASTER)
23982 + && (priv->ieee80211->state == IEEE80211_LINKED) &&
23983 + (priv->ForcedDataRate == 0) )
23984 + {
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);
23989 +#endif
23990 + }
23991 + priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod);
23992 + add_timer(&priv->rateadapter_timer);
23993 + //DMESG("<----timer_rate_adaptive()\n");
23994 +}
23995 +//by amy 080312}
23996 +void
23997 +SwAntennaDiversityRxOk8185(
23998 + struct net_device *dev,
23999 + u8 SignalStrength
24000 + )
24001 +{
24002 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
24003 +
24004 +// printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength);
24005 +
24006 + priv->AdRxOkCnt++;
24007 +
24008 + if( priv->AdRxSignalStrength != -1)
24009 + {
24010 + priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10;
24011 + }
24012 + else
24013 + { // Initialization case.
24014 + priv->AdRxSignalStrength = SignalStrength;
24015 + }
24016 +//{+by amy 080312
24017 + if( priv->LastRxPktAntenna ) //Main antenna.
24018 + priv->AdMainAntennaRxOkCnt++;
24019 + else // Aux antenna.
24020 + priv->AdAuxAntennaRxOkCnt++;
24021 +//+by amy 080312
24022 +// printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength);
24023 +}
24024 +//
24025 +// Description:
24026 +// Change Antenna Switch.
24027 +//
24028 +bool
24029 +SetAntenna8185(
24030 + struct net_device *dev,
24031 + u8 u1bAntennaIndex
24032 + )
24033 +{
24034 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
24035 + bool bAntennaSwitched = false;
24036 +
24037 +// printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex);
24038 +
24039 + switch(u1bAntennaIndex)
24040 + {
24041 + case 0:
24042 + switch(priv->rf_chip)
24043 + {
24044 + case RF_ZEBRA2:
24045 + case RF_ZEBRA4:
24046 +#ifdef CONFIG_RTL8185B
24047 +#ifdef CONFIG_RTL818X_S
24048 + // Mac register, main antenna
24049 + write_nic_byte(dev, ANTSEL, 0x03);
24050 + //base band
24051 + write_phy_cck(dev,0x11, 0x9b); // Config CCK RX antenna.
24052 + write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
24053 +
24054 +#else
24055 + // Mac register, main antenna
24056 + write_nic_byte(dev, ANTSEL, 0x03);
24057 + //base band
24058 + write_phy_cck(dev, 0x10, 0x9b); // Config CCK RX antenna.
24059 + write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
24060 +#endif
24061 +#endif
24062 +
24063 + bAntennaSwitched = true;
24064 + break;
24065 +
24066 + default:
24067 + printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
24068 + break;
24069 + }
24070 + break;
24071 +
24072 + case 1:
24073 + switch(priv->rf_chip)
24074 + {
24075 + case RF_ZEBRA2:
24076 + case RF_ZEBRA4:
24077 +#ifdef CONFIG_RTL8185B
24078 +#ifdef CONFIG_RTL818X_S
24079 + // Mac register, aux antenna
24080 + write_nic_byte(dev, ANTSEL, 0x00);
24081 + //base band
24082 + write_phy_cck(dev, 0x11, 0xbb); // Config CCK RX antenna.
24083 + write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
24084 +#else
24085 + // Mac register, aux antenna
24086 + write_nic_byte(dev, ANTSEL, 0x00);
24087 + //base band
24088 + write_phy_cck(dev, 0x10, 0xbb); // Config CCK RX antenna.
24089 + write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
24090 +#endif
24091 +#endif
24092 +
24093 + bAntennaSwitched = true;
24094 + break;
24095 +
24096 + default:
24097 + printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
24098 + break;
24099 + }
24100 + break;
24101 +
24102 + default:
24103 + printk("SetAntenna8185: unkown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
24104 + break;
24105 + }
24106 +
24107 + if(bAntennaSwitched)
24108 + {
24109 + priv->CurrAntennaIndex = u1bAntennaIndex;
24110 + }
24111 +
24112 +// printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched);
24113 +
24114 + return bAntennaSwitched;
24115 +}
24116 +//
24117 +// Description:
24118 +// Toggle Antenna switch.
24119 +//
24120 +bool
24121 +SwitchAntenna(
24122 + struct net_device *dev
24123 + )
24124 +{
24125 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
24126 +
24127 + bool bResult;
24128 +
24129 + if(priv->CurrAntennaIndex == 0)
24130 + {
24131 +#if 0//lzm del 080826
24132 +//by amy 080312
24133 +#ifdef CONFIG_RTL818X_S
24134 + if(priv->bSwAntennaDiverity)
24135 + bResult = SetAntennaConfig87SE(dev, 1, true);
24136 + else
24137 +#endif
24138 +#endif
24139 + bResult = SetAntenna8185(dev, 1);
24140 +//by amy 080312
24141 +// printk("SwitchAntenna(): switching to antenna 1 ......\n");
24142 +// bResult = SetAntenna8185(dev, 1);//-by amy 080312
24143 + }
24144 + else
24145 + {
24146 +#if 0//lzm del 080826
24147 +//by amy 080312
24148 +#ifdef CONFIG_RTL818X_S
24149 + if(priv->bSwAntennaDiverity)
24150 + bResult = SetAntennaConfig87SE(dev, 0, true);
24151 + else
24152 +#endif
24153 +#endif
24154 + bResult = SetAntenna8185(dev, 0);
24155 +//by amy 080312
24156 +// printk("SwitchAntenna(): switching to antenna 0 ......\n");
24157 +// bResult = SetAntenna8185(dev, 0);//-by amy 080312
24158 + }
24159 +
24160 + return bResult;
24161 +}
24162 +//
24163 +// Description:
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.
24167 +//
24168 +// 2006.04.17, by rcnjko.
24169 +//
24170 +void
24171 +SwAntennaDiversity(
24172 + struct net_device *dev
24173 + )
24174 +{
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);
24179 +//by amy 080312
24180 + if(bSwCheckSS)
24181 + {
24182 + priv->AdTickCount++;
24183 +
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);
24188 + }
24189 +// priv->AdTickCount++;//-by amy 080312
24190 +
24191 + // Case 1. No Link.
24192 + if(priv->ieee80211->state != IEEE80211_LINKED)
24193 + {
24194 + // printk("SwAntennaDiversity(): Case 1. No Link.\n");
24195 +
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);
24199 + }
24200 + // Case 2. Linked but no packet received.
24201 + else if(priv->AdRxOkCnt == 0)
24202 + {
24203 + // printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n");
24204 +
24205 + priv->bAdSwitchedChecking = false;
24206 + SwitchAntenna(dev);
24207 + }
24208 + // Case 3. Evaluate last antenna switch action and undo it if necessary.
24209 + else if(priv->bAdSwitchedChecking == true)
24210 + {
24211 + // printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n");
24212 +
24213 + priv->bAdSwitchedChecking = false;
24214 +
24215 + // Adjust Rx signal strength threashold.
24216 + priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
24217 +
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);
24224 +//by amy 080312
24225 + // Increase Antenna Diversity checking period due to bad decision.
24226 + priv->AdCheckPeriod *= 2;
24227 +//by amy 080312
24228 + // Increase Antenna Diversity checking period.
24229 + if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
24230 + priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
24231 +
24232 + // Wrong deceision => switch back.
24233 + SwitchAntenna(dev);
24234 + }
24235 + else
24236 + { // Rx Signal Strength is improved.
24237 +// printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %d, LastRxSs: %d\n",
24238 +// priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
24239 +
24240 + // Reset Antenna Diversity checking period to its min value.
24241 + priv->AdCheckPeriod = priv->AdMinCheckPeriod;
24242 + }
24243 +
24244 +// printk("SwAntennaDiversity(): AdRxSsThreshold: %d, AdCheckPeriod: %d\n",
24245 +// priv->AdRxSsThreshold, priv->AdCheckPeriod);
24246 + }
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
24250 + {
24251 +// printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n");
24252 +
24253 + priv->AdTickCount = 0;
24254 +
24255 + //
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.
24260 + // 2008.01.30.
24261 + //
24262 +
24263 + //
24264 + // Evaluate RxOk count from each antenna if we shall switch default antenna now.
24265 + // Added by Roger, 2008.02.21.
24266 +//{by amy 080312
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.
24270 +
24271 + // printk("SwAntennaDiversity(): Main antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
24272 + // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
24273 +
24274 + // Switch to Aux antenna.
24275 + SwitchAntenna(dev);
24276 + priv->bHWAdSwitched = true;
24277 + }
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.
24281 +
24282 + // printk("SwAntennaDiversity(): Aux antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
24283 + // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
24284 +
24285 + // Switch to Main antenna.
24286 + SwitchAntenna(dev);
24287 + priv->bHWAdSwitched = true;
24288 + }
24289 + else
24290 + {// Default antenna is better.
24291 +
24292 + // printk("SwAntennaDiversity(): Default antenna is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
24293 + // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
24294 +
24295 + // Still need to check current signal strength.
24296 + priv->bHWAdSwitched = false;
24297 + }
24298 + //
24299 + // <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
24300 + // didn't changed by HW evaluation.
24301 + // 2008.02.27.
24302 + //
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.
24308 + //
24309 + if( (!priv->bHWAdSwitched) && (bSwCheckSS))
24310 + {
24311 +//by amy 080312}
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);
24317 +
24318 + priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
24319 + priv->bAdSwitchedChecking = true;
24320 +
24321 + SwitchAntenna(dev);
24322 + }
24323 + else
24324 + { // Rx signal strength is OK.
24325 +// printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %d, RxSsThreshold: %d\n",
24326 +// priv->AdRxSignalStrength, priv->AdRxSsThreshold);
24327 +
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.
24332 + {
24333 + priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
24334 + priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
24335 + priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312
24336 + }
24337 +
24338 + // Reduce Antenna Diversity checking period if possible.
24339 + if( priv->AdCheckPeriod > priv->AdMinCheckPeriod )
24340 + {
24341 + priv->AdCheckPeriod /= 2;
24342 + }
24343 + }
24344 + }
24345 + }
24346 +//by amy 080312
24347 + // Reset antenna diversity Rx related statistics.
24348 + priv->AdRxOkCnt = 0;
24349 + priv->AdMainAntennaRxOkCnt = 0;
24350 + priv->AdAuxAntennaRxOkCnt = 0;
24351 +//by amy 080312
24352 +
24353 +// priv->AdRxOkCnt = 0;//-by amy 080312
24354 +
24355 +// printk("-SwAntennaDiversity()\n");
24356 +}
24357 +
24358 +//
24359 +// Description:
24360 +// Return TRUE if we shall perform Tx Power Tracking Mecahnism, FALSE otherwise.
24361 +//
24362 +bool
24363 +CheckTxPwrTracking( struct net_device *dev)
24364 +{
24365 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
24366 +
24367 + if(!priv->bTxPowerTrack)
24368 + {
24369 + return false;
24370 + }
24371 +
24372 +//lzm reserved 080826
24373 + //if(priv->bScanInProgress)
24374 + //{
24375 + // return false;
24376 + //}
24377 +
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)
24380 + {
24381 + return false;
24382 + }
24383 +
24384 + return true;
24385 +}
24386 +
24387 +
24388 +//
24389 +// Description:
24390 +// Timer callback function of SW Antenna Diversity.
24391 +//
24392 +void
24393 +SwAntennaDiversityTimerCallback(
24394 + struct net_device *dev
24395 + )
24396 +{
24397 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
24398 + RT_RF_POWER_STATE rtState;
24399 +
24400 + //printk("+SwAntennaDiversityTimerCallback()\n");
24401 +
24402 + //
24403 + // We do NOT need to switch antenna while RF is off.
24404 + // 2007.05.09, added by Roger.
24405 + //
24406 + rtState = priv->eRFPowerState;
24407 + do{
24408 + if (rtState == eRfOff)
24409 + {
24410 +// printk("SwAntennaDiversityTimer - RF is OFF.\n");
24411 + break;
24412 + }
24413 + else if (rtState == eRfSleep)
24414 + {
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"));
24417 + break;
24418 + }
24419 + SwAntennaDiversity(dev);
24420 +
24421 + }while(false);
24422 +
24423 + if(priv->up)
24424 + {
24425 + priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
24426 + add_timer(&priv->SwAntennaDiversityTimer);
24427 + }
24428 +
24429 + //printk("-SwAntennaDiversityTimerCallback()\n");
24430 +}
24431 +
24432 --- /dev/null
24433 +++ b/drivers/staging/rtl8187se/r8180_dm.h
24434 @@ -0,0 +1,41 @@
24435 +#ifndef R8180_DM_H
24436 +#define R8180_DM_H
24437 +
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);
24450 +#else
24451 +void rtl8180_hw_dig_wq(struct net_device *dev);
24452 +#endif
24453 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
24454 +void rtl8180_tx_pw_wq (struct work_struct *work);
24455 +#else
24456 +void rtl8180_tx_pw_wq(struct net_device *dev);
24457 +#endif
24458 +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
24459 +void rtl8180_rate_adapter(struct work_struct * work);
24460 +
24461 +#else
24462 +void rtl8180_rate_adapter(struct net_device *dev);
24463 +
24464 +#endif
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);
24469 +#else
24470 +void rtl8180_rate_adapter(struct net_device *dev);
24471 +#endif
24472 +void timer_rate_adaptive(unsigned long data);
24473 +
24474 +
24475 +#endif
24476 --- /dev/null
24477 +++ b/drivers/staging/rtl8187se/r8180_gct.c
24478 @@ -0,0 +1,296 @@
24479 +/*
24480 + This files contains GCT radio frontend programming routines.
24481 +
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)
24485 +
24486 + Parts of this driver are based on the GPL part of the
24487 + official realtek driver
24488 +
24489 + Parts of this driver are based on the rtl8180 driver skeleton
24490 + from Patric Schenke & Andres Salomon
24491 +
24492 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
24493 +
24494 + Code from Rtw8180 NetBSD driver by David Young has been really useful to
24495 + understand some things and gets some ideas
24496 +
24497 + Code from rtl8181 project has been useful to me to understand some things.
24498 +
24499 + Some code from 'Deuce' work
24500 +
24501 + We want to tanks the Authors of such projects and the Ndiswrapper
24502 + project Authors.
24503 +*/
24504 +
24505 +
24506 +#include "r8180.h"
24507 +#include "r8180_hw.h"
24508 +#include "r8180_gct.h"
24509 +
24510 +
24511 +//#define DEBUG_GCT
24512 +
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
24518 + */
24519 +
24520 +//#define GCT_EXPERIMENT1 //improve RX sensivity
24521 +
24522 +//#define GCT_EXPERIMENT2
24523 +
24524 +//#define GCT_EXPERIMENT3 //iprove a bit RX signal quality ?
24525 +
24526 +//#define GCT_EXPERIMENT4 //maybe solve some brokeness with experiment1 ?
24527 +
24528 +//#define GCT_EXPERIMENT5
24529 +
24530 +//#define GCT_EXPERIMENT6 //not good
24531 +
24532 +
24533 +u32 gct_chan[] = {
24534 + 0x0, //dummy channel 0
24535 + 0x0, //1
24536 + 0x1, //2
24537 + 0x2, //3
24538 + 0x3, //4
24539 + 0x4, //5
24540 + 0x5, //6
24541 + 0x6, //7
24542 + 0x7, //8
24543 + 0x8, //9
24544 + 0x9, //10
24545 + 0xa, //11
24546 + 0xb, //12
24547 + 0xc, //13
24548 + 0xd, //14
24549 +};
24550 +
24551 +int gct_encode[16] = {
24552 + 0, 8, 4, 0xC,
24553 + 2, 0xA, 6, 0xE,
24554 + 1, 9, 5, 0xD,
24555 + 3, 0xB, 7, 0xF
24556 +};
24557 +
24558 +void gct_rf_stabilize(struct net_device *dev)
24559 +{
24560 + force_pci_posting(dev);
24561 + mdelay(3); //for now use a great value.. we may optimize in future
24562 +}
24563 +
24564 +
24565 +void write_gct(struct net_device *dev, u8 adr, u32 data)
24566 +{
24567 +// struct r8180_priv *priv = ieee80211_priv(dev);
24568 + u32 phy_config;
24569 +
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;
24576 +
24577 + phy_config |= 0x90000000; // MAC will bang bits to the chip
24578 +
24579 +
24580 + write_nic_dword(dev,PHY_CONFIG,phy_config);
24581 +#ifdef DEBUG_GCT
24582 + DMESG("Writing GCT: %x (adr %x)",phy_config,adr);
24583 +#endif
24584 + gct_rf_stabilize(dev);
24585 +}
24586 +
24587 +
24588 +
24589 +void gct_write_phy_antenna(struct net_device *dev,short ch)
24590 +{
24591 + struct r8180_priv *priv = ieee80211_priv(dev);
24592 + u8 ant;
24593 +
24594 + ant = GCT_ANTENNA;
24595 + if(priv->antb) /*default antenna is antenna B */
24596 + ant |= BB_ANTENNA_B;
24597 + if(ch == 14)
24598 + ant |= BB_ANTATTEN_CHAN14;
24599 + write_phy(dev,0x10,ant);
24600 + //DMESG("BB antenna %x ",ant);
24601 +}
24602 +
24603 +
24604 +void gct_rf_set_chan(struct net_device *dev, short ch)
24605 +{
24606 + struct r8180_priv *priv = ieee80211_priv(dev);
24607 + u32 txpw = 0xff & priv->chtxpwr[ch];
24608 + u32 chan = gct_chan[ch];
24609 +
24610 + //write_phy(dev,3,txpw);
24611 +#ifdef DEBUG_GCT
24612 + DMESG("Gct set channel");
24613 +#endif
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);
24619 +
24620 + /*set frequency*/
24621 + write_gct(dev,7, 0);
24622 + write_gct(dev,0xB, chan);
24623 + write_gct(dev,7, 0x1000);
24624 +
24625 +#ifdef DEBUG_GCT
24626 + DMESG("Gct set channel > write phy antenna");
24627 +#endif
24628 +
24629 +
24630 + gct_write_phy_antenna(dev,ch);
24631 +
24632 +}
24633 +
24634 +
24635 +void gct_rf_close(struct net_device *dev)
24636 +{
24637 + u32 anaparam;
24638 +
24639 + anaparam = read_nic_dword(dev,ANAPARAM);
24640 + anaparam &= 0x000fffff;
24641 + anaparam |= 0x3f900000;
24642 + rtl8180_set_anaparam(dev, anaparam);
24643 +
24644 + write_gct(dev, 0x7, 0);
24645 + write_gct(dev, 0x1f, 0x45);
24646 + write_gct(dev, 0x1f, 0x5);
24647 + write_gct(dev, 0x0, 0x8e4);
24648 +}
24649 +
24650 +
24651 +void gct_rf_init(struct net_device *dev)
24652 +{
24653 + struct r8180_priv *priv = ieee80211_priv(dev);
24654 + //u32 anaparam;
24655 +
24656 +
24657 + write_nic_byte(dev,PHY_DELAY,0x6); //this is general
24658 + write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general
24659 +
24660 + //DMESG("%x", read_nic_dword(dev,ANAPARAM));
24661 + /* we should set anaparm here*/
24662 + //rtl8180_set_anaparam(dev,anaparam);
24663 +
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
24694 +#else
24695 + write_gct(dev,0x5,0x61ff); //best performance but weak sensitivity
24696 +#endif
24697 +#ifdef GCT_EXPERIMENT2
24698 + write_gct(dev,0x6,0xe);
24699 +#else
24700 + write_gct(dev,0x6,0x0);
24701 +#endif
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);
24712 +#else
24713 + write_gct(dev,0x11,0x248);
24714 +#endif
24715 + write_gct(dev,0x12,0x0);
24716 + write_gct(dev,0x13,0x20c4);
24717 +#ifdef GCT_EXPERIMENT4
24718 + write_gct(dev,0x14,0xf488);
24719 +#else
24720 + write_gct(dev,0x14,0xf4fc);
24721 +#endif
24722 +#ifdef GCT_EXPERIMENT5
24723 + write_gct(dev,0x15,0xb152);
24724 +#else
24725 + write_gct(dev,0x15,0x0);
24726 +#endif
24727 +#ifdef GCT_EXPERIMENT6
24728 + write_gct(dev,0x1e,0x1);
24729 +#endif
24730 + write_gct(dev,0x16,0x1500);
24731 +
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);
24737 +*/
24738 + write_phy(dev,0,0xa8);
24739 +
24740 +/* write_gct(dev,0x15,0x0);
24741 + write_gct(dev,0x6,0x12);
24742 + write_gct(dev,0x15,0x8);
24743 + write_gct(dev,0x15,0x0);
24744 +*/
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);
24750 +
24751 +#ifdef DEBUG_GCT
24752 + DMESG("Gct init> write phy antenna");
24753 +#endif
24754 +
24755 + gct_write_phy_antenna(dev,priv->chan);
24756 +
24757 + write_phy(dev,0x11,0x88);
24758 + if(!priv->diversity)
24759 + write_phy(dev,0x12,0xc0);
24760 + else
24761 + write_phy(dev,0x12,0x40);
24762 +
24763 + write_phy(dev,0x13,0x90 | priv->cs_treshold );
24764 +
24765 + write_phy(dev,0x19,0x0);
24766 + write_phy(dev,0x1a,0xa0);
24767 + write_phy(dev,0x1b,0x44);
24768 +
24769 +#ifdef DEBUG_GCT
24770 + DMESG("Gct init > set channel2");
24771 +#endif
24772 +
24773 + gct_rf_set_chan(dev,priv->chan);
24774 +}
24775 --- /dev/null
24776 +++ b/drivers/staging/rtl8187se/r8180_gct.h
24777 @@ -0,0 +1,25 @@
24778 +/*
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)
24782 +
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
24786 +
24787 + We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
24788 +*/
24789 +
24790 +#define GCT_ANTENNA 0xA3
24791 +
24792 +
24793 +// we use the untouched eeprom value- cross your finger ;-)
24794 +#define GCT_ANAPARAM_PWR1_ON ??
24795 +#define GCT_ANAPARAM_PWR0_ON ??
24796 +
24797 +
24798 +
24799 +void gct_rf_init(struct net_device *dev);
24800 +void gct_rf_set_chan(struct net_device *dev,short ch);
24801 +
24802 +void gct_rf_close(struct net_device *dev);
24803 --- /dev/null
24804 +++ b/drivers/staging/rtl8187se/r8180.h
24805 @@ -0,0 +1,761 @@
24806 +/*
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)
24810 +
24811 + Parts of this driver are based on the GPL part of the
24812 + official realtek driver
24813 +
24814 + Parts of this driver are based on the rtl8180 driver skeleton
24815 + from Patric Schenke & Andres Salomon
24816 +
24817 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
24818 +
24819 + We want to tanks the Authors of those projects and the Ndiswrapper
24820 + project Authors.
24821 +*/
24822 +
24823 +#ifndef R8180H
24824 +#define R8180H
24825 +
24826 +
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)
24831 +
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>
24852 +
24853 +#define EPROM_93c46 0
24854 +#define EPROM_93c56 1
24855 +
24856 +#define RTL_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
24857 +
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"
24866 +
24867 +#define DEFAULT_SSID ""
24868 +#define DEFAULT_RETRY_RTS 7
24869 +#define DEFAULT_RETRY_DATA 7
24870 +#define PRISM_HDR_SIZE 64
24871 +
24872 +#ifdef CONFIG_RTL8185B
24873 +
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
24881 +
24882 +#define LOW_QUEUE BE_QUEUE
24883 +#define NORMAL_QUEUE MGNT_QUEUE
24884 +
24885 +#define aSifsTime 10
24886 +
24887 +#define sCrcLng 4
24888 +#define sAckCtsLng 112 // bits in ACK and CTS frames
24889 +//+by amy 080312
24890 +#define RATE_ADAPTIVE_TIMER_PERIOD 300
24891 +
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,
24898 +} WIRELESS_MODE;
24899 +
24900 +typedef enum _VERSION_8185{
24901 + // RTL8185
24902 + VERSION_8185_UNKNOWN,
24903 + VERSION_8185_C, // C-cut
24904 + VERSION_8185_D, // D-cut
24905 + // RTL8185B
24906 + VERSION_8185B_B, // B-cut
24907 + VERSION_8185B_D, // D-cut
24908 + VERSION_8185B_E, // E-cut
24909 + //RTL8187S-PCIE
24910 + VERSION_8187S_B, // B-cut
24911 + VERSION_8187S_C, // C-cut
24912 + VERSION_8187S_D, // D-cut
24913 +
24914 +}VERSION_8185,*PVERSION_8185;
24915 +typedef struct ChnlAccessSetting {
24916 + u16 SIFS_Timer;
24917 + u16 DIFS_Timer;
24918 + u16 SlotTimeTimer;
24919 + u16 EIFS_Timer;
24920 + u16 CWminIndex;
24921 + u16 CWmaxIndex;
24922 +}*PCHANNEL_ACCESS_SETTING,CHANNEL_ACCESS_SETTING;
24923 +
24924 +typedef enum{
24925 + NIC_8185 = 1,
24926 + NIC_8185B
24927 + } nic_t;
24928 +
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.
24935 +
24936 +//
24937 +// ECWmin/ECWmax field.
24938 +// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
24939 +//
24940 +typedef union _ECW{
24941 + u8 charData;
24942 + struct
24943 + {
24944 + u8 ECWmin:4;
24945 + u8 ECWmax:4;
24946 + }f; // Field
24947 +}ECW, *PECW;
24948 +
24949 +//
24950 +// ACI/AIFSN Field.
24951 +// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
24952 +//
24953 +typedef union _ACI_AIFSN{
24954 + u8 charData;
24955 +
24956 + struct
24957 + {
24958 + u8 AIFSN:4;
24959 + u8 ACM:1;
24960 + u8 ACI:2;
24961 + u8 Reserved:1;
24962 + }f; // Field
24963 +}ACI_AIFSN, *PACI_AIFSN;
24964 +
24965 +//
24966 +// AC Parameters Record Format.
24967 +// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
24968 +//
24969 +typedef union _AC_PARAM{
24970 + u32 longData;
24971 + u8 charData[4];
24972 +
24973 + struct
24974 + {
24975 + ACI_AIFSN AciAifsn;
24976 + ECW Ecw;
24977 + u16 TXOPLimit;
24978 + }f; // Field
24979 +}AC_PARAM, *PAC_PARAM;
24980 +
24981 +/* it is a wrong definition. -xiong-2006-11-17
24982 +typedef struct ThreeWireReg {
24983 + u16 longData;
24984 + struct {
24985 + u8 enableB;
24986 + u8 data;
24987 + u8 clk;
24988 + u8 read_write;
24989 + } struc;
24990 +} ThreeWireReg;
24991 +*/
24992 +
24993 +typedef union _ThreeWire{
24994 + struct _ThreeWireStruc{
24995 + u16 data:1;
24996 + u16 clk:1;
24997 + u16 enableB:1;
24998 + u16 read_write:1;
24999 + u16 resv1:12;
25000 +// u2Byte resv2:14;
25001 +// u2Byte ThreeWireEnable:1;
25002 +// u2Byte resv3:1;
25003 + }struc;
25004 + u16 longData;
25005 +}ThreeWireReg;
25006 +
25007 +#endif
25008 +
25009 +typedef struct buffer
25010 +{
25011 + struct buffer *next;
25012 + u32 *buf;
25013 + dma_addr_t dma;
25014 +} buffer;
25015 +
25016 +//YJ,modified,080828
25017 +typedef struct Stats
25018 +{
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
25051 +} Stats;
25052 +
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
25060 +
25061 +typedef struct _link_detect_t
25062 +{
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
25065 + u16 SlotIndex;
25066 +
25067 + u32 NumTxOkInPeriod; //number of packet transmitted during CheckForHang
25068 + u32 NumRxOkInPeriod; //number of packet received during CheckForHang
25069 +
25070 + u8 IdleCount; // (KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)
25071 + u32 LastNumTxUnicast;
25072 + u32 LastNumRxUnicast;
25073 +
25074 + bool bBusyTraffic; //when it is set to 1, UI cann't scan at will.
25075 +}link_detect_t, *plink_detect_t;
25076 +
25077 +//YJ,modified,080828,end
25078 +
25079 +//by amy for led
25080 +//================================================================================
25081 +// LED customization.
25082 +//================================================================================
25083 +
25084 +typedef enum _LED_STRATEGY_8185{
25085 + SW_LED_MODE0, //
25086 + SW_LED_MODE1, //
25087 + HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes)
25088 +}LED_STRATEGY_8185, *PLED_STRATEGY_8185;
25089 +//by amy for led
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,
25095 + LED_CTL_TX = 4,
25096 + LED_CTL_RX = 5,
25097 + LED_CTL_SITE_SURVEY = 6,
25098 + LED_CTL_POWER_OFF = 7
25099 +}LED_CTL_MODE;
25100 +
25101 +typedef enum _RT_RF_POWER_STATE
25102 +{
25103 + eRfOn,
25104 + eRfSleep,
25105 + eRfOff
25106 +}RT_RF_POWER_STATE;
25107 +
25108 +enum _ReasonCode{
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,
25118 +
25119 + //----MIC_CHECK
25120 + mic_failure = 0xe,
25121 + //----END MIC_CHECK
25122 +
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,
25135 +
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
25149 +};
25150 +typedef enum _RT_PS_MODE
25151 +{
25152 + eActive, // Active/Continuous access.
25153 + eMaxPs, // Max power save mode.
25154 + eFastPs // Fast power save mode.
25155 +}RT_PS_MODE;
25156 +//by amy for power save
25157 +typedef struct r8180_priv
25158 +{
25159 + struct pci_dev *pdev;
25160 +
25161 + short epromtype;
25162 + int irq;
25163 + struct ieee80211_device *ieee80211;
25164 +
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
25172 +
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;
25178 +
25179 + u16 irq_mask;
25180 + short irq_enabled;
25181 + struct net_device *dev;
25182 + short chan;
25183 + short sens;
25184 + short max_sens;
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
25189 + short up;
25190 + short crcmon; //if 1 allow bad crc frame reception in monitor mode
25191 + short prism_hdr;
25192 +
25193 + struct timer_list scan_timer;
25194 + /*short scanpending;
25195 + short stopscan;*/
25196 + spinlock_t scan_lock;
25197 + u8 active_probe;
25198 + //u8 active_scan_num;
25199 + struct semaphore wx_sem;
25200 + struct semaphore rf_state;
25201 + short hw_wep;
25202 +
25203 + short digphy;
25204 + short antb;
25205 + short diversity;
25206 + u8 cs_treshold;
25207 + short rcr_csense;
25208 + short rf_chip;
25209 + u32 key0[4];
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);
25216 + //short rate;
25217 + short promisc;
25218 + /*stats*/
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;
25223 +
25224 + /*RX stuff*/
25225 + u32 *rxring;
25226 + u32 *rxringtail;
25227 + dma_addr_t rxringdma;
25228 + struct buffer *rxbuffer;
25229 + struct buffer *rxbufferhead;
25230 + int rxringcount;
25231 + u16 rxbuffersize;
25232 +
25233 + struct sk_buff *rx_skb;
25234 +
25235 + short rx_skb_complete;
25236 +
25237 + u32 rx_prevlen;
25238 +
25239 + /*TX stuff*/
25240 +/*
25241 + u32 *txlpring;
25242 + u32 *txhpring;
25243 + u32 *txnpring;
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;
25259 +*/
25260 + u32 *txmapring;
25261 + u32 *txbkpring;
25262 + u32 *txbepring;
25263 + u32 *txvipring;
25264 + u32 *txvopring;
25265 + u32 *txhpring;
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;
25296 +
25297 + int txringcount;
25298 + int txbuffsize;
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;
25304 +
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;
25316 +
25317 + u8 retry_data;
25318 + u8 retry_rts;
25319 + u16 rts;
25320 +
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.
25323 +
25324 +//by amy for led
25325 + LED_STRATEGY_8185 LedStrategy;
25326 +//by amy for led
25327 +
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;
25334 + u32 RfOffReason;
25335 + bool RFChangeInProgress;
25336 + bool bInHctTest;
25337 + bool SetRFPowerStateInProgress;
25338 + u8 RFProgType;
25339 + bool bLeisurePs;
25340 + RT_PS_MODE dot11PowerSaveMode;
25341 + //u32 NumRxOkInPeriod; //YJ,del,080828
25342 + //u32 NumTxOkInPeriod; //YJ,del,080828
25343 + u8 TxPollingTimes;
25344 +
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;
25348 +
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.
25365 + u32 AdRxOkCnt;
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
25378 +//{by amy 080312
25379 +//
25380 + // Crystal calibration.
25381 + // Added by Roger, 2007.12.11.
25382 + //
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
25386 + //
25387 + // Tx power tracking with thermal meter indication.
25388 + // Added by Roger, 2007.12.11.
25389 + //
25390 + bool bTxPowerTrack; // Tx Power tracking.
25391 + u8 ThermalMeter; // Thermal meter reference indication.
25392 + //
25393 + // Dynamic Initial Gain Adjustment Mechanism. Added by Bruce, 2007-02-14.
25394 + //
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.
25412 + u8 CurCCKRSSI;
25413 + bool bCurCCKPkt;
25414 + //
25415 + // High Power Mechanism. Added by amy, 080312.
25416 + //
25417 + bool bToUpdateTxPwr;
25418 + long UndecoratedSmoothedSS;
25419 + long UndercorateSmoothedRxPower;
25420 + u8 RSSI;
25421 + char RxPower;
25422 + u8 InitialGain;
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;
25448 + //for up rate
25449 + unsigned short bTryuping;
25450 + u8 CurrTxRate; //the rate before up
25451 + u16 CurrRetryRate;
25452 + u16 TryupingCount;
25453 + u8 TryDownCountLowData;
25454 + u8 TryupingCountNoData;
25455 +
25456 + u8 CurrentOperaRate;
25457 +//by amy for rate adaptive
25458 +//by amy 080312}
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;
25465 +
25466 + u8 PowerProfile;
25467 +#ifdef CONFIG_RTL8185B
25468 + u32 CSMethod;
25469 + u8 cck_txpwr_base;
25470 + u8 ofdm_txpwr_base;
25471 + u8 dma_poll_stop_mask;
25472 +
25473 + //u8 RegThreeWireMode;
25474 + u8 MWIEnable;
25475 + u16 ShortRetryLimit;
25476 + u16 LongRetryLimit;
25477 + u16 EarlyRxThreshold;
25478 + u32 TransmitConfig;
25479 + u32 ReceiveConfig;
25480 + u32 IntrMask;
25481 +
25482 + struct ChnlAccessSetting ChannelAccessSetting;
25483 +#endif
25484 +}r8180_priv;
25485 +
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
25493 +
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 : \
25500 + BE_PRIORITY)
25501 +
25502 +short rtl8180_tx(struct net_device *dev,u8* skbuf, int len,int priority,
25503 + short morefrag,short fragdesc,int rate);
25504 +
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);
25512 +
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);
25548 +
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);
25560 +#else
25561 +void rtl8180_rate_adapter(struct net_device *dev);
25562 +#endif
25563 +//#endif
25564 +bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u32 ChangeSource);
25565 +
25566 +#endif
25567 --- /dev/null
25568 +++ b/drivers/staging/rtl8187se/r8180_hw.h
25569 @@ -0,0 +1,956 @@
25570 +/*
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)
25574 +
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
25580 + 2100 GPL driver.
25581 +
25582 + We want to tanks the Authors of those projects
25583 + and the Ndiswrapper project Authors.
25584 +*/
25585 +
25586 +/* Mariusz Matuszek added full registers definition with Realtek's name */
25587 +
25588 +/* this file contains register definitions for the rtl8180 MAC controller */
25589 +#ifndef R8180_HW
25590 +#define R8180_HW
25591 +
25592 +#define CONFIG_RTL8185B //support for rtl8185B, xiong-2006-11-15
25593 +#define CONFIG_RTL818X_S
25594 +
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
25627 +
25628 +#define MAX_SLEEP_TIME (10000)
25629 +#define MIN_SLEEP_TIME (50)
25630 +
25631 +#define BB_ANTATTEN_CHAN14 0x0c
25632 +#define BB_ANTENNA_B 0x40
25633 +
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
25638 +
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
25644 +
25645 +#define MAC0 0
25646 +#define MAC1 1
25647 +#define MAC2 2
25648 +#define MAC3 3
25649 +#define MAC4 4
25650 +#define MAC5 5
25651 +#define CMD 0x37
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
25656 +
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
25670 +#define INTA 0x3e
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
25746 +
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)| \
25759 +(1<<8)|(1<<9))
25760 +#define ATIM 0x72
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
25780 +
25781 +
25782 +
25783 +/*
25784 + * Operational registers offsets in PCI (I/O) space.
25785 + * RealTek names are used.
25786 + */
25787 +
25788 +#define IDR0 0x0000
25789 +#define IDR1 0x0001
25790 +#define IDR2 0x0002
25791 +#define IDR3 0x0003
25792 +#define IDR4 0x0004
25793 +#define IDR5 0x0005
25794 +
25795 +/* 0x0006 - 0x0007 - reserved */
25796 +
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
25805 +
25806 +/* 0x0010 - 0x0017 - reserved */
25807 +
25808 +#define TSFTR 0x0018
25809 +#define TSFTR_END 0x001F
25810 +
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
25817 +
25818 +#define BSSID 0x002E
25819 +#define BSSID_END 0x0033
25820 +
25821 +#define CR 0x0037
25822 +
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.
25828 +
25829 +#define BRSR 0x34 // Basic rate set
25830 +
25831 +#define IMR 0x006C
25832 +#define ISR 0x003C
25833 +#else
25834 +#define BRSR 0x002C
25835 +#define BRSR_END 0x002D
25836 +
25837 +/* 0x0034 - 0x0034 - reserved */
25838 +#define EIFS 0x0035
25839 +
25840 +#define IMR 0x003C
25841 +#define IMR_END 0x003D
25842 +#define ISR 0x003E
25843 +#define ISR_END 0x003F
25844 +#endif
25845 +
25846 +#define TCR 0x0040
25847 +#define TCR_END 0x0043
25848 +
25849 +#define RCR 0x0044
25850 +#define RCR_END 0x0047
25851 +
25852 +#define TimerInt 0x0048
25853 +#define TimerInt_END 0x004B
25854 +
25855 +#define TBDA 0x004C
25856 +#define TBDA_END 0x004F
25857 +
25858 +#define CR9346 0x0050
25859 +
25860 +#define CONFIG0 0x0051
25861 +#define CONFIG1 0x0052
25862 +#define CONFIG2 0x0053
25863 +
25864 +#define ANA_PARM 0x0054
25865 +#define ANA_PARM_END 0x0x0057
25866 +
25867 +#define MSR 0x0058
25868 +
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
25877 +
25878 + #define ANAPARM_ON ANAPARM_ASIC_ON
25879 + #define ANAPARM2_ON ANAPARM2_ASIC_ON
25880 +#else
25881 + // SD3 CMLin:
25882 + #define ANAPARM_ASIC_ON 0x45090658
25883 + #define ANAPARM2_ASIC_ON 0x727f3f52
25884 +
25885 + #define ANAPARM_ON ANAPARM_ASIC_ON
25886 + #define ANAPARM2_ON ANAPARM2_ASIC_ON
25887 +#endif
25888 +#endif
25889 +
25890 +#define TESTR 0x005B
25891 +
25892 +/* 0x005C - 0x005D - reserved */
25893 +
25894 +#define PSR 0x005E
25895 +
25896 +/* 0x0060 - 0x006F - reserved */
25897 +
25898 +#define BcnItv 0x0070
25899 +#define BcnItv_END 0x0071
25900 +
25901 +#define AtimWnd 0x0072
25902 +#define AtimWnd_END 0x0073
25903 +
25904 +#define BintrItv 0x0074
25905 +#define BintrItv_END 0x0075
25906 +
25907 +#define AtimtrItv 0x0076
25908 +#define AtimtrItv_END 0x0077
25909 +
25910 +#define PhyDelay 0x0078
25911 +
25912 +#define CRCount 0x0079
25913 +
25914 +/* 0x007A - 0x007B - reserved */
25915 +
25916 +#define PhyAddr 0x007C
25917 +#define PhyDataW 0x007D
25918 +#define PhyDataR 0x007E
25919 +
25920 +#define PhyCFG 0x0080
25921 +#define PhyCFG_END 0x0083
25922 +
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
25932 +#define GPIO 0x91
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
25943 +#define SIFS 0xb4
25944 +#define DIFS 0xb5
25945 +
25946 +#define SLOT 0xb6
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
25954 +/*
25955 + * 0x0084 - 0x00D3 is selected to page 1 when PSEn bit (bit0, PSR)
25956 + * is set to 1
25957 + */
25958 +
25959 +#define Wakeup0 0x0084
25960 +#define Wakeup0_END 0x008B
25961 +
25962 +#define Wakeup1 0x008C
25963 +#define Wakeup1_END 0x0093
25964 +
25965 +#define Wakeup2LD 0x0094
25966 +#define Wakeup2LD_END 0x009B
25967 +#define Wakeup2HD 0x009C
25968 +#define Wakeup2HD_END 0x00A3
25969 +
25970 +#define Wakeup3LD 0x00A4
25971 +#define Wakeup3LD_END 0x00AB
25972 +#define Wakeup3HD 0x00AC
25973 +#define Wakeup3HD_END 0x00B3
25974 +
25975 +#define Wakeup4LD 0x00B4
25976 +#define Wakeup4LD_END 0x00BB
25977 +#define Wakeup4HD 0x00BC
25978 +#define Wakeup4HD_END 0x00C3
25979 +
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
25990 +
25991 +/* 0x00CE - 0x00D3 - reserved */
25992 +
25993 +
25994 +
25995 +/*
25996 + * 0x0084 - 0x00D3 is selected to page 0 when PSEn bit (bit0, PSR)
25997 + * is set to 0
25998 + */
25999 +
26000 +/* 0x0084 - 0x008F - reserved */
26001 +
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
26010 +
26011 +/* 0x00D0 - 0x00D3 - reserved */
26012 +
26013 +
26014 +
26015 +
26016 +
26017 +/* 0x00D4 - 0x00D7 - reserved */
26018 +
26019 +#define CONFIG5 0x00D8
26020 +
26021 +#define TPPoll 0x00D9
26022 +
26023 +/* 0x00DA - 0x00DB - reserved */
26024 +
26025 +#ifdef CONFIG_RTL818X_S
26026 +#define PHYPR 0xDA //0xDA - 0x0B PHY Parameter Register.
26027 +#endif
26028 +
26029 +#define CWR 0x00DC
26030 +#define CWR_END 0x00DD
26031 +
26032 +#define RetryCTR 0x00DE
26033 +
26034 +/* 0x00DF - 0x00E3 - reserved */
26035 +
26036 +#define RDSAR 0x00E4
26037 +#define RDSAR_END 0x00E7
26038 +
26039 +/* 0x00E8 - 0x00EF - reserved */
26040 +#ifdef CONFIG_RTL818X_S
26041 +#define LED_CONTROL 0xED
26042 +#endif
26043 +
26044 +#define FER 0x00F0
26045 +#define FER_END 0x00F3
26046 +
26047 +#ifdef CONFIG_RTL8185B
26048 +#define FEMR 0x1D4 // Function Event Mask register
26049 +#else
26050 +#define FEMR 0x00F4
26051 +#define FEMR_END 0x00F7
26052 +#endif
26053 +
26054 +#define FPSR 0x00F8
26055 +#define FPSR_END 0x00FB
26056 +
26057 +#define FFER 0x00FC
26058 +#define FFER_END 0x00FF
26059 +
26060 +
26061 +
26062 +/*
26063 + * Bitmasks for specific register functions.
26064 + * Names are derived from the register name and function name.
26065 + *
26066 + * <REGISTER>_<FUNCTION>[<bit>]
26067 + *
26068 + * this leads to some awkward names...
26069 + */
26070 +
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))
26076 +
26077 +#define CR_RST ((1<< 4))
26078 +#define CR_RE ((1<< 3))
26079 +#define CR_TE ((1<< 2))
26080 +#define CR_MulRW ((1<< 0))
26081 +
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
26136 +
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
26144 +
26145 +#else
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))
26162 +
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))
26179 +#endif
26180 +
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
26187 +#endif
26188 +
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
26208 +
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))
26234 +
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))
26242 +
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))
26249 +
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))
26258 +
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))
26266 +
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))
26274 +
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))
26283 +
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))
26290 +
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
26297 +
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))
26304 +
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))
26310 +
26311 +#define BcnItv_BcnItv (0x01FF)
26312 +
26313 +#define AtimWnd_AtimWnd (0x01FF)
26314 +
26315 +#define BintrItv_BintrItv (0x01FF)
26316 +
26317 +#define AtimtrItv_AtimtrItv (0x01FF)
26318 +
26319 +#define PhyDelay_PhyDelay ((1<<2)|(1<<1)|(1<<0))
26320 +
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))
26329 +
26330 +#define CWR_CW (0x01FF)
26331 +
26332 +#define FER_INTR ((1<<15))
26333 +#define FER_GWAKE ((1<< 4))
26334 +
26335 +#define FEMR_INTR ((1<<15))
26336 +#define FEMR_WKUP ((1<<14))
26337 +#define FEMR_GWAKE ((1<< 4))
26338 +
26339 +#define FPSR_INTR ((1<<15))
26340 +#define FPSR_GWAKE ((1<< 4))
26341 +
26342 +#define FFER_INTR ((1<<15))
26343 +#define FFER_GWAKE ((1<< 4))
26344 +
26345 +#ifdef CONFIG_RTL8185B
26346 +// Three wire mode.
26347 +#define SW_THREE_WIRE 0
26348 +#define HW_THREE_WIRE 2
26349 +//RTL8187S by amy
26350 +#define HW_THREE_WIRE_PI 5
26351 +#define HW_THREE_WIRE_SI 6
26352 +//by amy
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
26358 +
26359 +#define RCR_MXDMA_OFFSET 8
26360 +#define RCR_FIFO_OFFSET 13
26361 +
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
26368 +
26369 +#define TBDS 0x4c // Beacon descriptor queue start address
26370 +
26371 +#define RDSA 0xE4 // Receive descriptor queue start address
26372 +
26373 +#define AckTimeOutReg 0x79 // ACK timeout register, in unit of 4 us.
26374 +
26375 +#define RFTiming 0x8C
26376 +
26377 +#define TPPollStop 0x93
26378 +
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
26383 +
26384 +#define ACM_CONTROL 0x00BF // ACM Control Registe
26385 +
26386 +#define RTL8185B_VER_REG 0xE1
26387 +
26388 +#define IntMig 0xE2 // Interrupt Migration (0xE2 ~ 0xE3)
26389 +
26390 +#define TID_AC_MAP 0xE8 // TID to AC Mapping Register
26391 +
26392 +#define ANAPARAM3 0xEE // <RJ_TODO_8185B> How to use it?
26393 +
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
26398 +
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.
26403 +#endif
26404 +#define ARFR 0x1E0 // Auto Rate Fallback Register (0x1e0 ~ 0x1e2)
26405 +
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.
26411 +
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.
26415 +#endif
26416 +
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)
26427 +
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)
26438 +
26439 +
26440 +#define MSR_LINK_ENEDCA (1<<4)
26441 +
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
26449 +
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
26461 +
26462 +
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
26470 +
26471 +#define BB_HOST_BANG_RW (1<<3)
26472 +
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
26483 +
26484 +
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
26498 +
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
26503 +//{by amy 080312
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
26518 +//by amy 080312}
26519 +
26520 +//YJ,add for Country IE, 080630
26521 +#define EEPROM_COUNTRY_CODE 0x2E
26522 +//YJ,add,080630,end
26523 +#endif
26524 +
26525 +#endif
26526 --- /dev/null
26527 +++ b/drivers/staging/rtl8187se/r8180_max2820.c
26528 @@ -0,0 +1,240 @@
26529 +/*
26530 + This files contains MAXIM MAX2820 radio frontend programming routines.
26531 +
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)
26535 +
26536 + Parts of this driver are based on the GPL part of the
26537 + official realtek driver
26538 +
26539 + Parts of this driver are based on the rtl8180 driver skeleton
26540 + from Patric Schenke & Andres Salomon
26541 +
26542 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
26543 +
26544 + NetBSD rtl8180 driver from Dave Young has been really useful to
26545 + understand how to program the MAXIM radio. Thanks a lot!!!
26546 +
26547 + 'The Deuce' tested this and fixed some bugs.
26548 +
26549 + Code from rtl8181 project has been useful to me to understand some things.
26550 +
26551 + We want to tanks the Authors of such projects and the Ndiswrapper
26552 + project Authors.
26553 +*/
26554 +
26555 +
26556 +#include "r8180.h"
26557 +#include "r8180_hw.h"
26558 +#include "r8180_max2820.h"
26559 +
26560 +
26561 +//#define DEBUG_MAXIM
26562 +
26563 +u32 maxim_chan[] = {
26564 + 0, //dummy channel 0
26565 + 12, //1
26566 + 17, //2
26567 + 22, //3
26568 + 27, //4
26569 + 32, //5
26570 + 37, //6
26571 + 42, //7
26572 + 47, //8
26573 + 52, //9
26574 + 57, //10
26575 + 62, //11
26576 + 67, //12
26577 + 72, //13
26578 + 84, //14
26579 +};
26580 +
26581 +#if 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)
26584 +{
26585 +
26586 + int shift;
26587 + short bit;
26588 + u16 word;
26589 +
26590 + adr = adr &0xf;
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);
26595 + mdelay(1);
26596 +
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);
26599 + mdelay(1);
26600 + */
26601 +
26602 + /* MAX2820 will sample data on rising edge of clock */
26603 + for(shift = 15;shift >=0; shift--){
26604 + bit = word>>shift & 1;
26605 +
26606 + write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA));
26607 +
26608 + read_nic_dword(dev,PHY_CONFIG);
26609 + mdelay(2);
26610 +
26611 + write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG |
26612 + (bit<<BB_HOST_BANG_DATA) | BB_HOST_BANG_CLK); /* sample data */
26613 +
26614 + read_nic_dword(dev,PHY_CONFIG);
26615 + mdelay(1);
26616 +
26617 + write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG |
26618 + (bit<<BB_HOST_BANG_DATA));
26619 +
26620 + read_nic_dword(dev,PHY_CONFIG);
26621 + mdelay(2);
26622 +
26623 + }
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);
26627 + mdelay(2);
26628 +
26629 + /* The shift register fill flush to the requested register the
26630 + * last 12 bits data shifted in
26631 + */
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);
26635 + mdelay(2);
26636 +
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);
26640 + mdelay(2);
26641 +
26642 +
26643 +#ifdef DEBUG_MAXIM
26644 + DMESG("Writing maxim: %x (adr %x)",phy_config,adr);
26645 +#endif
26646 +
26647 +}
26648 +#endif
26649 +
26650 +void write_maxim(struct net_device *dev,u8 adr, u32 data) {
26651 + u32 temp;
26652 + temp = 0x90 + (data & 0xf);
26653 + temp <<= 16;
26654 + temp += adr;
26655 + temp <<= 8;
26656 + temp += (data >> 4) & 0xff;
26657 +#ifdef DEBUG_MAXIM
26658 + DMESG("write_maxim: %08x", temp);
26659 +#endif
26660 + write_nic_dword(dev, PHY_CONFIG, temp);
26661 + force_pci_posting(dev);
26662 + mdelay(1);
26663 +}
26664 +
26665 +
26666 +void maxim_write_phy_antenna(struct net_device *dev,short ch)
26667 +{
26668 + struct r8180_priv *priv = ieee80211_priv(dev);
26669 + u8 ant;
26670 +
26671 + ant = MAXIM_ANTENNA;
26672 + if(priv->antb) /*default antenna is antenna B */
26673 + ant |= BB_ANTENNA_B;
26674 + if(ch == 14)
26675 + ant |= BB_ANTATTEN_CHAN14;
26676 + write_phy(dev,0x10,ant);
26677 + //DMESG("BB antenna %x ",ant);
26678 +}
26679 +
26680 +
26681 +void maxim_rf_set_chan(struct net_device *dev, short ch)
26682 +{
26683 + struct r8180_priv *priv = ieee80211_priv(dev);
26684 + u32 txpw = 0xff & priv->chtxpwr[ch];
26685 + u32 chan = maxim_chan[ch];
26686 +
26687 + /*While philips SA2400 drive the PA bias
26688 + *seems that for MAXIM we delegate this
26689 + *to the BB
26690 + */
26691 +
26692 + //write_maxim(dev,5,txpw);
26693 + write_phy(dev,3,txpw);
26694 +
26695 + maxim_write_phy_antenna(dev,ch);
26696 + write_maxim(dev,3,chan);
26697 +}
26698 +
26699 +
26700 +void maxim_rf_close(struct net_device *dev)
26701 +{
26702 + write_phy(dev, 3, 0x8);
26703 + write_maxim(dev, 1, 0);
26704 +}
26705 +
26706 +
26707 +void maxim_rf_init(struct net_device *dev)
26708 +{
26709 + struct r8180_priv *priv = ieee80211_priv(dev);
26710 + u32 anaparam;
26711 +
26712 + write_nic_byte(dev,PHY_DELAY,0x6); //this is general
26713 + write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general
26714 +
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);
26722 +
26723 + //rtl8180_set_anaparam(dev,anaparam);
26724 +
26725 + /* MAXIM from netbsd driver */
26726 +
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 */
26730 +
26731 +
26732 + maxim_rf_set_chan(dev,priv->chan);
26733 +
26734 + write_maxim(dev,4, 0x313); /* rx register*/
26735 +
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..
26739 + */
26740 +
26741 + write_maxim(dev,5, 0xf);
26742 +
26743 +
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
26751 +
26752 + /*Should be done something more here??*/
26753 +
26754 + maxim_write_phy_antenna(dev,priv->chan);
26755 +
26756 + write_phy(dev,0x11,0x88); //trl
26757 + if(priv->diversity)
26758 + write_phy(dev,0x12,0xc7);
26759 + else
26760 + write_phy(dev,0x12,0x47);
26761 +
26762 + write_phy(dev,0x13,0x9b);
26763 +
26764 + write_phy(dev,0x19,0x0); //CHESTLIM
26765 + write_phy(dev,0x1a,0x9f); //CHSQLIM
26766 +
26767 + maxim_rf_set_chan(dev,priv->chan);
26768 +}
26769 --- /dev/null
26770 +++ b/drivers/staging/rtl8187se/r8180_max2820.h
26771 @@ -0,0 +1,21 @@
26772 +/*
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)
26776 +
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
26780 +
26781 + We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
26782 +*/
26783 +
26784 +#define MAXIM_ANTENNA 0xb3
26785 +#define MAXIM_ANAPARAM_PWR1_ON 0x8
26786 +#define MAXIM_ANAPARAM_PWR0_ON 0x0
26787 +
26788 +
26789 +void maxim_rf_init(struct net_device *dev);
26790 +void maxim_rf_set_chan(struct net_device *dev,short ch);
26791 +
26792 +void maxim_rf_close(struct net_device *dev);
26793 --- /dev/null
26794 +++ b/drivers/staging/rtl8187se/r8180_pm.c
26795 @@ -0,0 +1,90 @@
26796 +/*
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.
26801 +
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)
26805 +*/
26806 +
26807 +#ifdef CONFIG_RTL8180_PM
26808 +
26809 +
26810 +#include "r8180_hw.h"
26811 +#include "r8180_pm.h"
26812 +#include "r8180.h"
26813 +
26814 +int rtl8180_save_state (struct pci_dev *dev, u32 state)
26815 +{
26816 + printk(KERN_NOTICE "r8180 save state call (state %u).\n", state);
26817 + return(-EAGAIN);
26818 +}
26819 +
26820 +int rtl8180_suspend (struct pci_dev *pdev, pm_message_t state)
26821 +{
26822 + struct net_device *dev = pci_get_drvdata(pdev);
26823 +// struct r8180_priv *priv = ieee80211_priv(dev);
26824 +
26825 + if (!netif_running(dev))
26826 + goto out_pci_suspend;
26827 +
26828 + dev->stop(dev);
26829 +
26830 + netif_device_detach(dev);
26831 +
26832 +out_pci_suspend:
26833 + pci_save_state(pdev);
26834 + pci_disable_device(pdev);
26835 + pci_set_power_state(pdev,pci_choose_state(pdev,state));
26836 + return 0;
26837 +}
26838 +
26839 +int rtl8180_resume (struct pci_dev *pdev)
26840 +{
26841 + struct net_device *dev = pci_get_drvdata(pdev);
26842 +// struct r8180_priv *priv = ieee80211_priv(dev);
26843 + int err;
26844 + u32 val;
26845 +
26846 + pci_set_power_state(pdev, PCI_D0);
26847 +
26848 + err = pci_enable_device(pdev);
26849 + if(err) {
26850 + printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
26851 + dev->name);
26852 +
26853 + return err;
26854 + }
26855 + pci_restore_state(pdev);
26856 + /*
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.
26861 + */
26862 + pci_read_config_dword(pdev, 0x40, &val);
26863 + if ((val & 0x0000ff00) != 0)
26864 + pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
26865 +
26866 + if(!netif_running(dev))
26867 + goto out;
26868 +
26869 + dev->open(dev);
26870 + netif_device_attach(dev);
26871 +out:
26872 + return 0;
26873 +}
26874 +
26875 +
26876 +int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable)
26877 +{
26878 + printk(KERN_NOTICE "r8180 enable wake call (state %u, enable %d).\n",
26879 + state, enable);
26880 + return(-EAGAIN);
26881 +}
26882 +
26883 +
26884 +
26885 +#endif //CONFIG_RTL8180_PM
26886 --- /dev/null
26887 +++ b/drivers/staging/rtl8187se/r8180_pm.h
26888 @@ -0,0 +1,28 @@
26889 +/*
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.
26894 +
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)
26898 +
26899 +*/
26900 +
26901 +#ifdef CONFIG_RTL8180_PM
26902 +
26903 +#ifndef R8180_PM_H
26904 +#define R8180_PM_H
26905 +
26906 +#include <linux/types.h>
26907 +#include <linux/pci.h>
26908 +
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);
26913 +
26914 +#endif //R8180_PM_H
26915 +
26916 +#endif // CONFIG_RTL8180_PM
26917 --- /dev/null
26918 +++ b/drivers/staging/rtl8187se/r8180_rtl8225.c
26919 @@ -0,0 +1,933 @@
26920 +/*
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>
26924 +
26925 + This files contains programming code for the rtl8225
26926 + radio frontend.
26927 +
26928 + *Many* thanks to Realtek Corp. for their great support!
26929 +
26930 +*/
26931 +
26932 +
26933 +
26934 +#include "r8180_hw.h"
26935 +#include "r8180_rtl8225.h"
26936 +
26937 +
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
26946 +};
26947 +
26948 +#if 0
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
26958 +};
26959 +#endif
26960 +#ifdef CONFIG_RTL818X_S
26961 +u32 rtl8225_chan[] ={
26962 + 0,
26963 + 0x0080, //ch1
26964 + 0x0100, //ch2
26965 + 0x0180, //ch3
26966 + 0x0200, //ch4
26967 + 0x0280,
26968 + 0x0300,
26969 + 0x0380,
26970 + 0x0400,
26971 + 0x0480,
26972 + 0x0500,
26973 + 0x0580,
26974 + 0x0600,
26975 + 0x0680,
26976 + 0x074A, //ch14
26977 +};
26978 +#else
26979 +u32 rtl8225_chan[] = {
26980 + 0, //dummy channel 0
26981 + 0x085c, //1
26982 + 0x08dc, //2
26983 + 0x095c, //3
26984 + 0x09dc, //4
26985 + 0x0a5c, //5
26986 + 0x0adc, //6
26987 + 0x0b5c, //7
26988 + 0x0bdc, //8
26989 + 0x0c5c, //9
26990 + 0x0cdc, //10
26991 + 0x0d5c, //11
26992 + 0x0ddc, //12
26993 + 0x0e5c, //13
26994 + //0x0f5c, //14
26995 + 0x0f72, // 14
26996 +};
26997 +#endif
26998 +
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
27012 +
27013 +};
27014 +
27015 +
27016 +#if 0
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
27030 +
27031 +};
27032 +
27033 +
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
27047 +};
27048 +#endif
27049 +
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,
27059 +};
27060 +
27061 +
27062 +u8 rtl8225_tx_gain_cck_ofdm[]={
27063 + 0x02,0x06,0x0e,0x1e,0x3e,0x7e
27064 +};
27065 +
27066 +
27067 +u8 rtl8225_tx_power_ofdm[]={
27068 + 0x80,0x90,0xa2,0xb5,0xcb,0xe4
27069 +};
27070 +
27071 +
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
27079 +};
27080 +
27081 +
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
27089 +};
27090 +
27091 +
27092 +void rtl8225_set_gain(struct net_device *dev, short gain)
27093 +{
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]);
27098 +}
27099 +#if 0
27100 +
27101 +void rtl8225_set_gain(struct net_device *dev, short gain)
27102 +{
27103 + struct r8180_priv *priv = ieee80211_priv(dev);
27104 +
27105 + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
27106 +
27107 + if(priv->card_8185 == 2)
27108 + write_phy_ofdm(dev, 0x21, 0x27);
27109 + else
27110 + write_phy_ofdm(dev, 0x21, 0x37);
27111 +
27112 + write_phy_ofdm(dev, 0x25, 0x20);
27113 + write_phy_ofdm(dev, 0x11, 0x6);
27114 +
27115 + if(priv->card_8185 == 1 && priv->card_8185_Bversion)
27116 + write_phy_ofdm(dev, 0x27, 0x8);
27117 + else
27118 + write_phy_ofdm(dev, 0x27, 0x88);
27119 +
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);
27124 +
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);
27130 +}
27131 +#endif
27132 +
27133 +
27134 +void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
27135 +{
27136 + int i;
27137 + u16 out,select;
27138 + u8 bit;
27139 + u32 bangdata = (data << 4) | (adr & 0xf);
27140 + struct r8180_priv *priv = ieee80211_priv(dev);
27141 +
27142 + out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
27143 +
27144 + write_nic_word(dev,RFPinsEnable,
27145 + (read_nic_word(dev,RFPinsEnable) | 0x7));
27146 +
27147 + select = read_nic_word(dev, RFPinsSelect);
27148 +
27149 + write_nic_word(dev, RFPinsSelect, select | 0x7 |
27150 + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
27151 +
27152 + force_pci_posting(dev);
27153 + udelay(10);
27154 +
27155 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
27156 +
27157 + force_pci_posting(dev);
27158 + udelay(2);
27159 +
27160 + write_nic_word(dev, RFPinsOutput, out);
27161 +
27162 + force_pci_posting(dev);
27163 + udelay(10);
27164 +
27165 +
27166 + for(i=15; i>=0;i--){
27167 +
27168 + bit = (bangdata & (1<<i)) >> i;
27169 +
27170 + write_nic_word(dev, RFPinsOutput, bit | out);
27171 +
27172 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
27173 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
27174 +
27175 + i--;
27176 + bit = (bangdata & (1<<i)) >> i;
27177 +
27178 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
27179 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
27180 +
27181 + write_nic_word(dev, RFPinsOutput, bit | out);
27182 +
27183 + }
27184 +
27185 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
27186 +
27187 + force_pci_posting(dev);
27188 + udelay(10);
27189 +
27190 + write_nic_word(dev, RFPinsOutput, out |
27191 + ((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
27192 +
27193 + write_nic_word(dev, RFPinsSelect, select |
27194 + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
27195 +
27196 + if(priv->card_type == USB)
27197 + mdelay(2);
27198 + else
27199 + rtl8185_rf_pins_enable(dev);
27200 +}
27201 +
27202 +void rtl8225_rf_close(struct net_device *dev)
27203 +{
27204 + write_rtl8225(dev, 0x4, 0x1f);
27205 +
27206 + force_pci_posting(dev);
27207 + mdelay(1);
27208 +
27209 + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF);
27210 + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF);
27211 +}
27212 +
27213 +void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch)
27214 +{
27215 + struct r8180_priv *priv = ieee80211_priv(dev);
27216 +
27217 + int GainIdx;
27218 + int GainSetting;
27219 + int i;
27220 + u8 power;
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];
27227 +
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;
27232 + }else{
27233 + max_cck_power_level = 35;
27234 + max_ofdm_power_level = 35;
27235 + min_ofdm_power_level = 0;
27236 + }
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;
27242 +
27243 + if(ch == 14)
27244 + cck_power_table = rtl8225_tx_power_cck_ch14;
27245 + else
27246 + cck_power_table = rtl8225_tx_power_cck;
27247 +
27248 +// if(priv->card_8185 == 1 && priv->card_8185_Bversion ){
27249 + /*Ver B*/
27250 +// write_nic_byte(dev, TX_GAIN_CCK, rtl8225_tx_gain_cck_ofdm[GainSetting]);
27251 +// }else{
27252 + /*Ver C - D */
27253 + write_nic_byte(dev, TX_GAIN_CCK, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1);
27254 +// }
27255 +
27256 + for(i=0;i<8;i++){
27257 +
27258 + power = cck_power_table[GainIdx * 8 + i];
27259 + write_phy_cck(dev, 0x44 + i, power);
27260 + }
27261 +
27262 + /* FIXME Is this delay really needeed ? */
27263 + force_pci_posting(dev);
27264 + mdelay(1);
27265 +
27266 + /* OFDM power setting */
27267 +// Old:
27268 +// if(ofdm_power_level > max_ofdm_power_level)
27269 +// ofdm_power_level = 35;
27270 +// ofdm_power_level += min_ofdm_power_level;
27271 +// Latest:
27272 + if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
27273 + ofdm_power_level = max_ofdm_power_level;
27274 + else
27275 + ofdm_power_level += min_ofdm_power_level;
27276 + if(ofdm_power_level > 35)
27277 + ofdm_power_level = 35;
27278 +//
27279 +
27280 + GainIdx=ofdm_power_level % 6;
27281 + GainSetting=ofdm_power_level / 6;
27282 +#if 1
27283 +// if(priv->card_type == USB){
27284 + rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON);
27285 +
27286 + write_phy_ofdm(dev,2,0x42);
27287 + write_phy_ofdm(dev,6,0);
27288 + write_phy_ofdm(dev,8,0);
27289 +// }
27290 +#endif
27291 +// if(priv->card_8185 == 1 && priv->card_8185_Bversion){
27292 +// /*Ver B*/
27293 +// write_nic_byte(dev, TX_GAIN_OFDM, rtl8225_tx_gain_cck_ofdm[GainSetting]);
27294 +// }else{
27295 + /*Ver C - D */
27296 + write_nic_byte(dev, TX_GAIN_OFDM, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1);
27297 +// }
27298 +
27299 +
27300 + power = rtl8225_tx_power_ofdm[GainIdx];
27301 +
27302 + write_phy_ofdm(dev, 0x5, power);
27303 + write_phy_ofdm(dev, 0x7, power);
27304 +
27305 + force_pci_posting(dev);
27306 + mdelay(1);
27307 + //write_nic_byte(dev, TX_AGC_CONTROL,4);
27308 +}
27309 +#if 0
27310 +/* switch between mode B and G */
27311 +void rtl8225_set_mode(struct net_device *dev, short modeb)
27312 +{
27313 + write_phy_ofdm(dev, 0x15, (modeb ? 0x0 : 0x40));
27314 + write_phy_ofdm(dev, 0x17, (modeb ? 0x0 : 0x40));
27315 +}
27316 +#endif
27317 +void rtl8225_rf_set_chan(struct net_device *dev, short ch)
27318 +{
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;
27323 +
27324 + rtl8225_SetTXPowerLevel(dev, ch);
27325 +
27326 + write_rtl8225(dev, 0x7, rtl8225_chan[ch]);
27327 +
27328 + force_pci_posting(dev);
27329 + mdelay(10);
27330 +
27331 + // A mode sifs 0x44, difs 34-14, slot 9, eifs 23, cwm 3, cwM 7, ctstoself 0x10
27332 + if(gset){
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
27336 + }else{
27337 + write_nic_byte(dev,SIFS,0x44);// SIFS: 0x22
27338 + write_nic_byte(dev,DIFS,50 - 14); //DIFS: 36
27339 + }
27340 + if(priv->ieee80211->state == IEEE80211_LINKED &&
27341 + ieee80211_is_shortslot(priv->ieee80211->current_network))
27342 + write_nic_byte(dev,SLOT,0x9); //SLOT: 9
27343 +
27344 + else
27345 + write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
27346 +
27347 +
27348 + if(gset){
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");
27352 + }else{
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");
27356 + }
27357 +
27358 +
27359 +}
27360 +
27361 +void rtl8225_host_pci_init(struct net_device *dev)
27362 +{
27363 + write_nic_word(dev, RFPinsOutput, 0x480);
27364 +
27365 + rtl8185_rf_pins_enable(dev);
27366 +
27367 + //if(priv->card_8185 == 2 && priv->enable_gpio0 ) /* version D */
27368 + //write_nic_word(dev, RFPinsSelect, 0x88);
27369 + //else
27370 + write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO); /* 0x488 | SW_CONTROL_GPIO */
27371 +
27372 + write_nic_byte(dev, GP_ENABLE, 0);
27373 +
27374 + force_pci_posting(dev);
27375 + mdelay(200);
27376 +
27377 + write_nic_word(dev, GP_ENABLE, 0xff & (~(1<<6))); /* bit 6 is for RF on/off detection */
27378 +
27379 +
27380 +}
27381 +
27382 +void rtl8225_host_usb_init(struct net_device *dev)
27383 +{
27384 + #if 0
27385 + write_nic_byte(dev,RFPinsSelect+1,0);
27386 +
27387 + write_nic_byte(dev,GPIO,0);
27388 +
27389 + write_nic_byte_E(dev,0x53,read_nic_byte_E(dev,0x53) | (1<<7));
27390 +
27391 + write_nic_byte(dev,RFPinsSelect+1,4);
27392 +
27393 + write_nic_byte(dev,GPIO,0x20);
27394 +
27395 + write_nic_byte(dev,GP_ENABLE,0);
27396 +
27397 +
27398 + /* Config BB & RF */
27399 + write_nic_word(dev, RFPinsOutput, 0x80);
27400 +
27401 + write_nic_word(dev, RFPinsSelect, 0x80);
27402 +
27403 + write_nic_word(dev, RFPinsEnable, 0x80);
27404 +
27405 +
27406 + mdelay(100);
27407 +
27408 + mdelay(1000);
27409 +#endif
27410 +
27411 +}
27412 +
27413 +void rtl8225_rf_sleep(struct net_device *dev)
27414 +{
27415 + write_rtl8225(dev,0x4,0xdff);
27416 + force_pci_posting(dev);
27417 + mdelay(1);
27418 + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_SLEEP);
27419 + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_SLEEP);
27420 + force_pci_posting(dev);
27421 +}
27422 +
27423 +void rtl8225_rf_wakeup(struct net_device *dev)
27424 +{
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);
27429 +}
27430 +
27431 +void rtl8225_rf_init(struct net_device *dev)
27432 +{
27433 + struct r8180_priv *priv = ieee80211_priv(dev);
27434 + int i;
27435 + short channel = 1;
27436 + u16 brsr;
27437 +
27438 + priv->chan = channel;
27439 +
27440 + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
27441 +
27442 +
27443 + if(priv->card_type == USB)
27444 + rtl8225_host_usb_init(dev);
27445 + else
27446 + rtl8225_host_pci_init(dev);
27447 +
27448 + write_nic_dword(dev, RF_TIMING, 0x000a8008);
27449 +
27450 + brsr = read_nic_word(dev, BRSR);
27451 +
27452 + write_nic_word(dev, BRSR, 0xffff);
27453 +
27454 + #if 0
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);
27465 + }
27466 + #endif
27467 +
27468 + write_nic_dword(dev, RF_PARA, 0x100044);
27469 +
27470 + #if 1 //0->1
27471 + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
27472 + write_nic_byte(dev, CONFIG3, 0x44);
27473 + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
27474 + #endif
27475 +
27476 + if(priv->card_type == USB){
27477 + rtl8185_rf_pins_enable(dev);
27478 +
27479 + mdelay(1000);
27480 + }
27481 +
27482 + write_rtl8225(dev, 0x0, 0x67); mdelay(1);
27483 +
27484 +
27485 + write_rtl8225(dev, 0x1, 0xfe0); mdelay(1);
27486 +
27487 + write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
27488 +
27489 + write_rtl8225(dev, 0x3, 0x441); mdelay(1);
27490 +
27491 + if(priv->card_type == USB)
27492 + write_rtl8225(dev, 0x4, 0x486);
27493 + else
27494 + write_rtl8225(dev, 0x4, 0x8be);
27495 +
27496 + mdelay(1);
27497 +
27498 +
27499 + #if 0
27500 + }else if(priv->phy_ver == 1){
27501 + /* version A */
27502 + write_rtl8225(dev, 0x5, 0xbc0 + 2);
27503 + }else{
27504 + #endif
27505 + /* version B & C */
27506 +
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));
27511 + else
27512 + write_rtl8225(dev, 0x5, 0xbc0 + (6<<3));
27513 +
27514 + mdelay(1);
27515 +// }
27516 +
27517 + write_rtl8225(dev, 0x6, 0xae6); mdelay(1);
27518 +
27519 + write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel])); mdelay(1);
27520 +
27521 + write_rtl8225(dev, 0x8, 0x1f); mdelay(1);
27522 +
27523 + write_rtl8225(dev, 0x9, 0x334); mdelay(1);
27524 +
27525 + write_rtl8225(dev, 0xa, 0xfd4); mdelay(1);
27526 +
27527 + write_rtl8225(dev, 0xb, 0x391); mdelay(1);
27528 +
27529 + write_rtl8225(dev, 0xc, 0x50); mdelay(1);
27530 +
27531 +
27532 + write_rtl8225(dev, 0xd, 0x6db); mdelay(1);
27533 +
27534 + write_rtl8225(dev, 0xe, 0x29); mdelay(1);
27535 +
27536 + write_rtl8225(dev, 0xf, 0x914);
27537 +
27538 + if(priv->card_type == USB){
27539 + //force_pci_posting(dev);
27540 + mdelay(100);
27541 + }
27542 +
27543 + write_rtl8225(dev, 0x2, 0xc4d);
27544 +
27545 + if(priv->card_type == USB){
27546 + // force_pci_posting(dev);
27547 + mdelay(200);
27548 +
27549 + write_rtl8225(dev, 0x2, 0x44d);
27550 +
27551 + // force_pci_posting(dev);
27552 + mdelay(100);
27553 +
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)
27558 + */
27559 + force_pci_posting(dev);
27560 +
27561 + mdelay(100); //200 for 8187
27562 +
27563 + //if(priv->card_type != USB) /* maybe not needed even for 8185 */
27564 +// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
27565 +
27566 + write_rtl8225(dev, 0x0, 0x127);
27567 +
27568 + for(i=0;i<95;i++){
27569 + write_rtl8225(dev, 0x1, (u8)(i+1));
27570 +
27571 + #if 0
27572 + if(priv->phy_ver == 1)
27573 + /* version A */
27574 + write_rtl8225(dev, 0x2, rtl8225a_rxgain[i]);
27575 + else
27576 + #endif
27577 + /* version B & C & D*/
27578 +
27579 + write_rtl8225(dev, 0x2, rtl8225bcd_rxgain[i]);
27580 + }
27581 +
27582 + write_rtl8225(dev, 0x0, 0x27);
27583 +
27584 +
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);
27589 +//
27590 +// force_pci_posting(dev);
27591 +// mdelay(100);
27592 +//
27593 +// write_rtl8225(dev, 0x2, 0x44d);
27594 +// //}
27595 +
27596 + write_rtl8225(dev, 0x0, 0x22f);
27597 +
27598 + if(priv->card_type != USB)
27599 + rtl8185_rf_pins_enable(dev);
27600 +
27601 + for(i=0;i<128;i++){
27602 + write_phy_ofdm(dev, 0xb, rtl8225_agc[i]);
27603 +
27604 + mdelay(1);
27605 + write_phy_ofdm(dev, 0xa, (u8)i+ 0x80);
27606 +
27607 + mdelay(1);
27608 + }
27609 +
27610 + force_pci_posting(dev);
27611 + mdelay(1);
27612 +
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);
27623 +
27624 + #if 0
27625 + if(priv->card_type == USB){
27626 + write_phy_ofdm(dev, 0xa, 0x9);
27627 + }else{
27628 + if(priv->card_8185 == 1 && priv->card_8185_Bversion){
27629 + /* Ver B
27630 + * maybe later version can accept this also?
27631 + */
27632 + write_phy_ofdm(dev, 0xa, 0x6);
27633 + write_phy_ofdm(dev, 0x18, 0x6f);
27634 + }else{
27635 + #endif
27636 + /* ver C & D */
27637 + write_phy_ofdm(dev, 0xa, 0x9); mdelay(1);
27638 +
27639 + //write_phy_ofdm(dev, 0x18, 0xef);
27640 + // }
27641 + //}
27642 + write_phy_ofdm(dev, 0xb, 0x80); mdelay(1);
27643 +
27644 + write_phy_ofdm(dev, 0xc, 0x1);mdelay(1);
27645 +
27646 +
27647 + //if(priv->card_type != USB)
27648 + //write_phy_ofdm(dev, 0xd, 0x33); // <>
27649 +
27650 + write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1);
27651 +
27652 +
27653 + #if 0
27654 + if(priv->card_8185 == 1){
27655 + if(priv->card_8185_Bversion)
27656 + write_phy_ofdm(dev, 0xf, 0x20);/*ver B*/
27657 + else
27658 + write_phy_ofdm(dev, 0xf, 0x28);/*ver C*/
27659 + }else{
27660 + #endif
27661 + write_phy_ofdm(dev, 0xf, 0x38);mdelay(1);
27662 +/*ver D & 8187*/
27663 +// }
27664 +
27665 +// if(priv->card_8185 == 1 && priv->card_8185_Bversion)
27666 +// write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/
27667 +// else
27668 + write_phy_ofdm(dev, 0x10, 0x84);mdelay(1);
27669 +/*ver C & D & 8187*/
27670 +
27671 + write_phy_ofdm(dev, 0x11, 0x06);mdelay(1);
27672 +/*agc resp time 700*/
27673 +
27674 +
27675 +// if(priv->card_8185 == 2){
27676 + /* Ver D & 8187*/
27677 + write_phy_ofdm(dev, 0x12, 0x20);mdelay(1);
27678 +
27679 + write_phy_ofdm(dev, 0x13, 0x20);mdelay(1);
27680 +
27681 +#if 0
27682 + }else{
27683 + /* Ver B & C*/
27684 + write_phy_ofdm(dev, 0x12, 0x0);
27685 + write_phy_ofdm(dev, 0x13, 0x0);
27686 + }
27687 +#endif
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);
27692 +
27693 +// if (priv->card_type == USB)
27694 +// write_phy_ofdm(dev, 0x18, 0xef);
27695 +
27696 + write_phy_ofdm(dev, 0x18, 0xef);mdelay(1);
27697 +
27698 +
27699 + write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
27700 + write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
27701 +
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 */
27705 +// else
27706 + write_phy_ofdm(dev, 0x1b, 0x76);mdelay(1);
27707 + /* Ver C & D */ //FIXME:MAYBE not needed
27708 +// }
27709 +
27710 + write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1);
27711 +
27712 +#if 0
27713 + if(priv->card_8185 == 1){
27714 + if(priv->card_8185_Bversion){
27715 + /*ver B*/
27716 + write_phy_ofdm(dev, 0x1e, 0x95);
27717 + write_phy_ofdm(dev, 0x1f, 0x55);
27718 + }else{
27719 + /*ver C*/
27720 + write_phy_ofdm(dev, 0x1e, 0x90);
27721 + write_phy_ofdm(dev, 0x1f, 0x34);
27722 +
27723 + }
27724 + }else{
27725 +#endif
27726 + /*ver D & 8187*/
27727 + write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1);
27728 +
27729 + write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
27730 +
27731 +// }
27732 +
27733 + write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1);
27734 +
27735 + write_phy_ofdm(dev, 0x21, 0x27);mdelay(1);
27736 +
27737 + write_phy_ofdm(dev, 0x22, 0x16);mdelay(1);
27738 +
27739 +// if(priv->card_type != USB)
27740 + //write_phy_ofdm(dev, 0x23, 0x43); //FIXME maybe not needed // <>
27741 +
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);
27745 +#if 0
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 ?*/
27748 + else
27749 +#endif
27750 + write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
27751 +/* Ver C & D & 8187*/
27752 +
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);
27758 +
27759 + //if(priv->card_type == USB);
27760 + // rtl8225_set_gain_usb(dev, 1); /* FIXME this '2' is random */
27761 +
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);
27767 +#if 0
27768 + if(priv->card_8185 == 1 && priv->card_8185_Bversion)
27769 + write_phy_cck(dev, 0x7, 0xd8); /* Ver B */
27770 + else
27771 +#endif
27772 + write_phy_cck(dev, 0x7, 0x78);mdelay(1);
27773 + /* Ver C & D & 8187*/
27774 +
27775 + write_phy_cck(dev, 0x8, 0x2e);mdelay(1);
27776 +
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);
27780 +#if 0
27781 + if(priv->card_8185 == 1 && priv->card_8185_Bversion)
27782 + write_phy_cck(dev, 0x13, 0x98); /* Ver B */
27783 + else
27784 +#endif
27785 + write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
27786 +
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 */
27791 +
27792 + write_phy_cck(dev, 0x41, 0x8d);mdelay(1);
27793 +
27794 +
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);
27806 +
27807 +
27808 + write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
27809 +
27810 +
27811 +
27812 +// <>
27813 +// // TESTR 0xb 8187
27814 +// write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
27815 +//
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);
27820 +// //}
27821 +
27822 + rtl8225_SetTXPowerLevel(dev, channel);
27823 +
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 */
27826 +
27827 + rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */
27828 +
27829 + /* switch to high-speed 3-wire
27830 + * last digit. 2 for both cck and ofdm
27831 + */
27832 + if(priv->card_type == USB)
27833 + write_nic_dword(dev, 0x94, 0x3dc00002);
27834 + else{
27835 + write_nic_dword(dev, 0x94, 0x15c00002);
27836 + rtl8185_rf_pins_enable(dev);
27837 + }
27838 +
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 */ // <>
27842 +//
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);
27847 +
27848 + rtl8225_rf_set_chan(dev, priv->chan);
27849 +
27850 + write_nic_word(dev,BRSR,brsr);
27851 +
27852 +}
27853 --- /dev/null
27854 +++ b/drivers/staging/rtl8187se/r8180_rtl8225.h
27855 @@ -0,0 +1,44 @@
27856 +/*
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>
27860 +
27861 + This files contains programming code for the rtl8225
27862 + radio frontend.
27863 +
27864 + *Many* thanks to Realtek Corp. for their great support!
27865 +
27866 +*/
27867 +
27868 +#include "r8180.h"
27869 +
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
27876 +
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);
27881 +
27882 +void rtl8225_host_pci_init(struct net_device *dev);
27883 +void rtl8225_host_usb_init(struct net_device *dev);
27884 +
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);
27888 +#endif
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);
27899 +
27900 --- /dev/null
27901 +++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c
27902 @@ -0,0 +1,1587 @@
27903 +/*
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>
27907 +
27908 + This files contains programming code for the rtl8225
27909 + radio frontend.
27910 +
27911 + *Many* thanks to Realtek Corp. for their great support!
27912 +
27913 +*/
27914 +
27915 +#include "r8180_hw.h"
27916 +#include "r8180_rtl8225.h"
27917 +#include "r8180_93cx6.h"
27918 +
27919 +#ifdef ENABLE_DOT11D
27920 +#include "dot11d.h"
27921 +#endif
27922 +
27923 +#ifdef CONFIG_RTL8185B
27924 +
27925 +extern u8 rtl8225_agc[];
27926 +
27927 +extern u32 rtl8225_chan[];
27928 +
27929 +//2005.11.16
27930 +u8 rtl8225z2_threshold[]={
27931 + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
27932 +};
27933 +
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
27943 +};
27944 +
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
27953 +};
27954 +#if 0
27955 +u32 rtl8225_chan[] = {
27956 + 0, //dummy channel 0
27957 + 0x085c, //1
27958 + 0x08dc, //2
27959 + 0x095c, //3
27960 + 0x09dc, //4
27961 + 0x0a5c, //5
27962 + 0x0adc, //6
27963 + 0x0b5c, //7
27964 + 0x0bdc, //8
27965 + 0x0c5c, //9
27966 + 0x0cdc, //10
27967 + 0x0d5c, //11
27968 + 0x0ddc, //12
27969 + 0x0e5c, //13
27970 + //0x0f5c, //14
27971 + 0x0f72, // 14
27972 +};
27973 +#endif
27974 +
27975 +//-
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
27989 +
27990 +};
27991 +
27992 +//2005.11.16,
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,
28000 +};
28001 +
28002 +#if 0
28003 +//-
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,
28013 +};
28014 +#endif
28015 +/*
28016 + from 0 to 0x23
28017 +u8 rtl8225_tx_gain_cck_ofdm[]={
28018 + 0x02,0x06,0x0e,0x1e,0x3e,0x7e
28019 +};
28020 +*/
28021 +
28022 +//-
28023 +u8 rtl8225z2_tx_power_ofdm[]={
28024 + 0x42,0x00,0x40,0x00,0x40
28025 +};
28026 +
28027 +
28028 +//-
28029 +u8 rtl8225z2_tx_power_cck_ch14[]={
28030 + 0x36,0x35,0x2e,0x1b,0x00,0x00,0x00,0x00
28031 +};
28032 +
28033 +
28034 +//-
28035 +u8 rtl8225z2_tx_power_cck[]={
28036 + 0x36,0x35,0x2e,0x25,0x1c,0x12,0x09,0x04
28037 +};
28038 +
28039 +
28040 +void rtl8225z2_set_gain(struct net_device *dev, short gain)
28041 +{
28042 + u8* rtl8225_gain;
28043 + struct r8180_priv *priv = ieee80211_priv(dev);
28044 +
28045 + u8 mode = priv->ieee80211->mode;
28046 +
28047 + if(mode == IEEE_B || mode == IEEE_G)
28048 + rtl8225_gain = rtl8225z2_gain_bg;
28049 + else
28050 + rtl8225_gain = rtl8225z2_gain_a;
28051 +
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);
28060 +
28061 +}
28062 +
28063 +#if 0
28064 +
28065 +void rtl8225_set_gain(struct net_device *dev, short gain)
28066 +{
28067 + struct r8180_priv *priv = ieee80211_priv(dev);
28068 +
28069 + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
28070 +
28071 + if(priv->card_8185 == 2)
28072 + write_phy_ofdm(dev, 0x21, 0x27);
28073 + else
28074 + write_phy_ofdm(dev, 0x21, 0x37);
28075 +
28076 + write_phy_ofdm(dev, 0x25, 0x20);
28077 + write_phy_ofdm(dev, 0x11, 0x6);
28078 +
28079 + if(priv->card_8185 == 1 && priv->card_8185_Bversion)
28080 + write_phy_ofdm(dev, 0x27, 0x8);
28081 + else
28082 + write_phy_ofdm(dev, 0x27, 0x88);
28083 +
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);
28088 +
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);
28094 +}
28095 +#endif
28096 +
28097 +u32 read_rtl8225(struct net_device *dev, u8 adr)
28098 +{
28099 + u32 data2Write = ((u32)(adr & 0x1f)) << 27;
28100 + u32 dataRead;
28101 + u32 mask;
28102 + u16 oval,oval2,oval3,tmp;
28103 +// ThreeWireReg twreg;
28104 +// ThreeWireReg tdata;
28105 + int i;
28106 + short bit, rw;
28107 +
28108 + u8 wLength = 6;
28109 + u8 rLength = 12;
28110 + u8 low2high = 0;
28111 +
28112 + oval = read_nic_word(dev, RFPinsOutput);
28113 + oval2 = read_nic_word(dev, RFPinsEnable);
28114 + oval3 = read_nic_word(dev, RFPinsSelect);
28115 +
28116 + write_nic_word(dev, RFPinsEnable, (oval2|0xf));
28117 + write_nic_word(dev, RFPinsSelect, (oval3|0xf));
28118 +
28119 + dataRead = 0;
28120 +
28121 + oval &= ~0xf;
28122 +
28123 + write_nic_word(dev, RFPinsOutput, oval | BB_HOST_BANG_EN ); udelay(4);
28124 +
28125 + write_nic_word(dev, RFPinsOutput, oval ); udelay(5);
28126 +
28127 + rw = 0;
28128 +
28129 + mask = (low2high) ? 0x01 : (((u32)0x01)<<(32-1));
28130 + for(i = 0; i < wLength/2; i++)
28131 + {
28132 + bit = ((data2Write&mask) != 0) ? 1 : 0;
28133 + write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(1);
28134 +
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);
28137 +
28138 + mask = (low2high) ? (mask<<1): (mask>>1);
28139 +
28140 + if(i == 2)
28141 + {
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);
28145 + break;
28146 + }
28147 +
28148 + bit = ((data2Write&mask) != 0) ? 1: 0;
28149 +
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);
28152 +
28153 + write_nic_word(dev, RFPinsOutput, oval| bit |rw); udelay(1);
28154 +
28155 + mask = (low2high) ? (mask<<1) : (mask>>1);
28156 + }
28157 +
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));
28162 +
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)));
28166 +
28167 + for(i = 0; i < rLength; i++)
28168 + {
28169 + write_nic_word(dev, RFPinsOutput, rw|oval); udelay(1);
28170 +
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);
28175 +
28176 + dataRead |= (tmp & BB_HOST_BANG_CLK ? mask : 0);
28177 +
28178 + write_nic_word(dev, RFPinsOutput, (rw|oval)); udelay(2);
28179 +
28180 + mask = (low2high) ? (mask<<1) : (mask>>1);
28181 + }
28182 +
28183 + write_nic_word(dev, RFPinsOutput, BB_HOST_BANG_EN|BB_HOST_BANG_RW|oval); udelay(2);
28184 +
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);
28188 +
28189 + return dataRead;
28190 +
28191 +}
28192 +#if 0
28193 +void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
28194 +{
28195 + int i;
28196 + u16 out,select;
28197 + u8 bit;
28198 + u32 bangdata = (data << 4) | (adr & 0xf);
28199 + struct r8180_priv *priv = ieee80211_priv(dev);
28200 +
28201 + out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
28202 +
28203 + write_nic_word(dev,RFPinsEnable,
28204 + (read_nic_word(dev,RFPinsEnable) | 0x7));
28205 +
28206 + select = read_nic_word(dev, RFPinsSelect);
28207 +
28208 + write_nic_word(dev, RFPinsSelect, select | 0x7 |
28209 + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
28210 +
28211 + force_pci_posting(dev);
28212 + udelay(10);
28213 +
28214 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
28215 +
28216 + force_pci_posting(dev);
28217 + udelay(2);
28218 +
28219 + write_nic_word(dev, RFPinsOutput, out);
28220 +
28221 + force_pci_posting(dev);
28222 + udelay(10);
28223 +
28224 +
28225 + for(i=15; i>=0;i--){
28226 +
28227 + bit = (bangdata & (1<<i)) >> i;
28228 +
28229 + write_nic_word(dev, RFPinsOutput, bit | out);
28230 +
28231 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
28232 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
28233 +
28234 + i--;
28235 + bit = (bangdata & (1<<i)) >> i;
28236 +
28237 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
28238 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
28239 +
28240 + write_nic_word(dev, RFPinsOutput, bit | out);
28241 +
28242 + }
28243 +
28244 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
28245 +
28246 + force_pci_posting(dev);
28247 + udelay(10);
28248 +
28249 + write_nic_word(dev, RFPinsOutput, out |
28250 + ((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
28251 +
28252 + write_nic_word(dev, RFPinsSelect, select |
28253 + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
28254 +
28255 + if(priv->card_type == USB)
28256 + mdelay(2);
28257 + else
28258 + rtl8185_rf_pins_enable(dev);
28259 +}
28260 +
28261 +#endif
28262 +short rtl8225_is_V_z2(struct net_device *dev)
28263 +{
28264 + short vz2 = 1;
28265 + //int i;
28266 + /* sw to reg pg 1 */
28267 + //write_rtl8225(dev, 0, 0x1b7);
28268 + //write_rtl8225(dev, 0, 0x0b7);
28269 +
28270 + /* reg 8 pg 1 = 23*/
28271 + //printk(KERN_WARNING "RF Rigisters:\n");
28272 +#if 0
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));
28276 +
28277 +// printk(KERN_WARNING "RF:\n");
28278 +#endif
28279 + if( read_rtl8225(dev, 8) != 0x588)
28280 + vz2 = 0;
28281 +
28282 + else /* reg 9 pg 1 = 24 */
28283 + if( read_rtl8225(dev, 9) != 0x700)
28284 + vz2 = 0;
28285 +
28286 + /* sw back to pg 0 */
28287 + write_rtl8225(dev, 0, 0xb7);
28288 +
28289 + return vz2;
28290 +
28291 +}
28292 +
28293 +#if 0
28294 +void rtl8225_rf_close(struct net_device *dev)
28295 +{
28296 + write_rtl8225(dev, 0x4, 0x1f);
28297 +
28298 + force_pci_posting(dev);
28299 + mdelay(1);
28300 +
28301 + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF);
28302 + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF);
28303 +}
28304 +#endif
28305 +#if 0
28306 +short rtl8225_rf_set_sens(struct net_device *dev, short sens)
28307 +{
28308 + if (sens <0 || sens > 6) return -1;
28309 +
28310 + if(sens > 4)
28311 + write_rtl8225(dev, 0x0c, 0x850);
28312 + else
28313 + write_rtl8225(dev, 0x0c, 0x50);
28314 +
28315 + sens= 6-sens;
28316 + rtl8225_set_gain(dev, sens);
28317 +
28318 + write_phy_cck(dev, 0x41, rtl8225_threshold[sens]);
28319 + return 0;
28320 +
28321 +}
28322 +#endif
28323 +
28324 +
28325 +void rtl8225z2_rf_close(struct net_device *dev)
28326 +{
28327 + RF_WriteReg(dev, 0x4, 0x1f);
28328 +
28329 + force_pci_posting(dev);
28330 + mdelay(1);
28331 +
28332 + rtl8180_set_anaparam(dev, RTL8225z2_ANAPARAM_OFF);
28333 + rtl8185_set_anaparam2(dev, RTL8225z2_ANAPARAM2_OFF);
28334 +}
28335 +
28336 +#ifdef ENABLE_DOT11D
28337 +//
28338 +// Description:
28339 +// Map dBm into Tx power index according to
28340 +// current HW model, for example, RF and PA, and
28341 +// current wireless mode.
28342 +//
28343 +s8
28344 +DbmToTxPwrIdx(
28345 + struct r8180_priv *priv,
28346 + WIRELESS_MODE WirelessMode,
28347 + s32 PowerInDbm
28348 + )
28349 +{
28350 + bool bUseDefault = true;
28351 + s8 TxPwrIdx = 0;
28352 +
28353 +#ifdef CONFIG_RTL818X_S
28354 + //
28355 + // 071011, SD3 SY:
28356 + // OFDM Power in dBm = Index * 0.5 + 0
28357 + // CCK Power in dBm = Index * 0.25 + 13
28358 + //
28359 + if(priv->card_8185 >= VERSION_8187S_B)
28360 + {
28361 + s32 tmp = 0;
28362 +
28363 + if(WirelessMode == WIRELESS_MODE_G)
28364 + {
28365 + bUseDefault = false;
28366 + tmp = (2 * PowerInDbm);
28367 +
28368 + if(tmp < 0)
28369 + TxPwrIdx = 0;
28370 + else if(tmp > 40) // 40 means 20 dBm.
28371 + TxPwrIdx = 40;
28372 + else
28373 + TxPwrIdx = (s8)tmp;
28374 + }
28375 + else if(WirelessMode == WIRELESS_MODE_B)
28376 + {
28377 + bUseDefault = false;
28378 + tmp = (4 * PowerInDbm) - 52;
28379 +
28380 + if(tmp < 0)
28381 + TxPwrIdx = 0;
28382 + else if(tmp > 28) // 28 means 20 dBm.
28383 + TxPwrIdx = 28;
28384 + else
28385 + TxPwrIdx = (s8)tmp;
28386 + }
28387 + }
28388 +#endif
28389 +
28390 + //
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.
28394 + //
28395 + if(bUseDefault)
28396 + {
28397 + if(PowerInDbm < 0)
28398 + TxPwrIdx = 0;
28399 + else if(PowerInDbm > 35)
28400 + TxPwrIdx = 35;
28401 + else
28402 + TxPwrIdx = (u8)PowerInDbm;
28403 + }
28404 +
28405 + return TxPwrIdx;
28406 +}
28407 +#endif
28408 +
28409 +void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch)
28410 +{
28411 + struct r8180_priv *priv = ieee80211_priv(dev);
28412 +
28413 +// int GainIdx;
28414 +// int GainSetting;
28415 + //int i;
28416 + //u8 power;
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
28426 +#if 0
28427 + //
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.
28432 + //
28433 + // TODO:
28434 + // 1. 802.11h power contraint
28435 + //
28436 + // 071011, by rcnjko.
28437 + //
28438 + if( priv->OpMode == RT_OP_MODE_INFRASTRUCTURE &&
28439 + priv->bWithCcxCellPwr &&
28440 + ch == priv->dot11CurrentChannelNumber)
28441 + {
28442 + u8 CckCellPwrIdx = DbmToTxPwrIdx(dev, WIRELESS_MODE_B, pMgntInfo->CcxCellPwr);
28443 + u8 OfdmCellPwrIdx = DbmToTxPwrIdx(dev, WIRELESS_MODE_G, pMgntInfo->CcxCellPwr);
28444 +
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);
28449 +
28450 + if(cck_power_level > CckCellPwrIdx)
28451 + cck_power_level = CckCellPwrIdx;
28452 + if(ofdm_power_level > OfdmCellPwrIdx)
28453 + ofdm_power_level = OfdmCellPwrIdx;
28454 +
28455 + printk("Altered CCK Tx power index : %d, OFDM Tx power index: %d\n",
28456 + CckTxPwrIdx, OfdmTxPwrIdx);
28457 + }
28458 +#endif
28459 +#ifdef ENABLE_DOT11D
28460 + if(IS_DOT11D_ENABLE(priv->ieee80211) &&
28461 + IS_DOT11D_STATE_DONE(priv->ieee80211) )
28462 + {
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);
28467 +
28468 + //printk("Max Tx Power dBm (%d) => CCK Tx power index : %d, OFDM Tx power index: %d\n", MaxTxPwrInDbm, CckMaxPwrIdx, OfdmMaxPwrIdx);
28469 +
28470 + //printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n",
28471 + // ch, cck_power_level, ofdm_power_level);
28472 +
28473 + if(cck_power_level > CckMaxPwrIdx)
28474 + cck_power_level = CckMaxPwrIdx;
28475 + if(ofdm_power_level > OfdmMaxPwrIdx)
28476 + ofdm_power_level = OfdmMaxPwrIdx;
28477 + }
28478 +
28479 + //priv->CurrentCckTxPwrIdx = cck_power_level;
28480 + //priv->CurrentOfdmTxPwrIdx = ofdm_power_level;
28481 +#endif
28482 +
28483 + max_cck_power_level = 15;
28484 + max_ofdm_power_level = 25; // 12 -> 25
28485 + min_ofdm_power_level = 10;
28486 +
28487 +#ifdef CONFIG_RTL8185B
28488 +#ifdef CONFIG_RTL818X_S
28489 +
28490 + if(cck_power_level > 35)
28491 + {
28492 + cck_power_level = 35;
28493 + }
28494 + //
28495 + // Set up CCK TXAGC. suggested by SD3 SY.
28496 + //
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);
28500 + mdelay(1);
28501 +#else
28502 +
28503 + /* CCK power setting */
28504 + if(cck_power_level > max_cck_power_level)
28505 + cck_power_level = max_cck_power_level;
28506 +
28507 + cck_power_level += priv->cck_txpwr_base;
28508 +
28509 + if(cck_power_level > 35)
28510 + cck_power_level = 35;
28511 +
28512 + if(ch == 14)
28513 + cck_power_table = rtl8225z2_tx_power_cck_ch14;
28514 + else
28515 + cck_power_table = rtl8225z2_tx_power_cck;
28516 +
28517 +
28518 + for(i=0;i<8;i++){
28519 +
28520 + power = cck_power_table[i];
28521 + write_phy_cck(dev, 0x44 + i, power);
28522 + }
28523 +
28524 + //write_nic_byte(dev, TX_GAIN_CCK, power);
28525 + //2005.11.17,
28526 + write_nic_byte(dev, CCK_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)cck_power_level]);
28527 +
28528 + force_pci_posting(dev);
28529 + mdelay(1);
28530 +#endif
28531 +#endif
28532 + /* OFDM power setting */
28533 +// Old:
28534 +// if(ofdm_power_level > max_ofdm_power_level)
28535 +// ofdm_power_level = 35;
28536 +// ofdm_power_level += min_ofdm_power_level;
28537 +// Latest:
28538 +/* if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
28539 + ofdm_power_level = max_ofdm_power_level;
28540 + else
28541 + ofdm_power_level += min_ofdm_power_level;
28542 +
28543 + ofdm_power_level += priv->ofdm_txpwr_base;
28544 +*/
28545 + if(ofdm_power_level > 35)
28546 + ofdm_power_level = 35;
28547 +
28548 +// rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON);
28549 +
28550 + //rtl8185_set_anaparam2(dev, ANAPARM2_ASIC_ON);
28551 +
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);
28559 + }
28560 +
28561 + //write_nic_byte(dev, TX_GAIN_OFDM, ofdm_power_level);
28562 + //2005.11.17,
28563 +#ifdef CONFIG_RTL818X_S
28564 + write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)ofdm_power_level]);
28565 +#else
28566 + write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)ofdm_power_level]*2);
28567 +#endif
28568 + if(ofdm_power_level<=11)
28569 + {
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);
28574 + }
28575 + if(ofdm_power_level<=17)
28576 + {
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);
28581 + }
28582 + else
28583 + {
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);
28588 + }
28589 + force_pci_posting(dev);
28590 + mdelay(1);
28591 +
28592 +}
28593 +#if 0
28594 +/* switch between mode B and G */
28595 +void rtl8225_set_mode(struct net_device *dev, short modeb)
28596 +{
28597 + write_phy_ofdm(dev, 0x15, (modeb ? 0x0 : 0x40));
28598 + write_phy_ofdm(dev, 0x17, (modeb ? 0x0 : 0x40));
28599 +}
28600 +#endif
28601 +
28602 +void rtl8225z2_rf_set_chan(struct net_device *dev, short ch)
28603 +{
28604 +/*
28605 + short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
28606 + ieee80211_is_54g(priv->ieee80211->current_network)) ||
28607 + priv->ieee80211->iw_mode == IW_MODE_MONITOR;
28608 +*/
28609 + rtl8225z2_SetTXPowerLevel(dev, ch);
28610 +
28611 + RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);
28612 +
28613 + //YJ,add,080828, if set channel failed, write again
28614 + if((RF_ReadReg(dev, 0x7) & 0x0F80) != rtl8225_chan[ch])
28615 + {
28616 + RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);
28617 + }
28618 +
28619 + mdelay(1);
28620 +
28621 + force_pci_posting(dev);
28622 + mdelay(10);
28623 +//deleted by David : 2006/8/9
28624 +#if 0
28625 + write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
28626 +
28627 + if(gset)
28628 + write_nic_byte(dev,DIFS,20); //DIFS: 20
28629 + else
28630 + write_nic_byte(dev,DIFS,0x24); //DIFS: 36
28631 +
28632 + if(priv->ieee80211->state == IEEE80211_LINKED &&
28633 + ieee80211_is_shortslot(priv->ieee80211->current_network))
28634 + write_nic_byte(dev,SLOT,0x9); //SLOT: 9
28635 +
28636 + else
28637 + write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
28638 +
28639 +
28640 + if(gset){
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");
28644 + }else{
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");
28648 + }
28649 +#endif
28650 +
28651 +}
28652 +#if 0
28653 +void rtl8225_host_pci_init(struct net_device *dev)
28654 +{
28655 + write_nic_word(dev, RFPinsOutput, 0x480);
28656 +
28657 + rtl8185_rf_pins_enable(dev);
28658 +
28659 + //if(priv->card_8185 == 2 && priv->enable_gpio0 ) /* version D */
28660 + //write_nic_word(dev, RFPinsSelect, 0x88);
28661 + //else
28662 + write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO); /* 0x488 | SW_CONTROL_GPIO */
28663 +
28664 + write_nic_byte(dev, GP_ENABLE, 0);
28665 +
28666 + force_pci_posting(dev);
28667 + mdelay(200);
28668 +
28669 + write_nic_word(dev, GP_ENABLE, 0xff & (~(1<<6))); /* bit 6 is for RF on/off detection */
28670 +
28671 +
28672 +}
28673 +
28674 +void rtl8225_host_usb_init(struct net_device *dev)
28675 +{
28676 + write_nic_byte(dev,RFPinsSelect+1,0);
28677 +
28678 + write_nic_byte(dev,GPIO,0);
28679 +
28680 + write_nic_byte_E(dev,0x53,read_nic_byte_E(dev,0x53) | (1<<7));
28681 +
28682 + write_nic_byte(dev,RFPinsSelect+1,4);
28683 +
28684 + write_nic_byte(dev,GPIO,0x20);
28685 +
28686 + write_nic_byte(dev,GP_ENABLE,0);
28687 +
28688 +
28689 + /* Config BB & RF */
28690 + write_nic_word(dev, RFPinsOutput, 0x80);
28691 +
28692 + write_nic_word(dev, RFPinsSelect, 0x80);
28693 +
28694 + write_nic_word(dev, RFPinsEnable, 0x80);
28695 +
28696 +
28697 + mdelay(100);
28698 +
28699 + mdelay(1000);
28700 +
28701 +}
28702 +#endif
28703 +void rtl8225z2_rf_init(struct net_device *dev)
28704 +{
28705 + struct r8180_priv *priv = ieee80211_priv(dev);
28706 + int i;
28707 + short channel = 1;
28708 + u16 brsr;
28709 + u32 data,addr;
28710 +
28711 + priv->chan = channel;
28712 +
28713 +// rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
28714 +
28715 +
28716 + if(priv->card_type == USB)
28717 + rtl8225_host_usb_init(dev);
28718 + else
28719 + rtl8225_host_pci_init(dev);
28720 +
28721 + write_nic_dword(dev, RF_TIMING, 0x000a8008);
28722 +
28723 + brsr = read_nic_word(dev, BRSR);
28724 +
28725 + write_nic_word(dev, BRSR, 0xffff);
28726 +
28727 +
28728 + write_nic_dword(dev, RF_PARA, 0x100044);
28729 +
28730 + #if 1 //0->1
28731 + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
28732 + write_nic_byte(dev, CONFIG3, 0x44);
28733 + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
28734 + #endif
28735 +
28736 +
28737 + rtl8185_rf_pins_enable(dev);
28738 +
28739 +// mdelay(1000);
28740 +
28741 + write_rtl8225(dev, 0x0, 0x2bf); mdelay(1);
28742 +
28743 +
28744 + write_rtl8225(dev, 0x1, 0xee0); mdelay(1);
28745 +
28746 + write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
28747 +
28748 + write_rtl8225(dev, 0x3, 0x441); mdelay(1);
28749 +
28750 +
28751 + write_rtl8225(dev, 0x4, 0x8c3);mdelay(1);
28752 +
28753 +
28754 +
28755 + write_rtl8225(dev, 0x5, 0xc72);mdelay(1);
28756 +// }
28757 +
28758 + write_rtl8225(dev, 0x6, 0xe6); mdelay(1);
28759 +
28760 + write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel])); mdelay(1);
28761 +
28762 + write_rtl8225(dev, 0x8, 0x3f); mdelay(1);
28763 +
28764 + write_rtl8225(dev, 0x9, 0x335); mdelay(1);
28765 +
28766 + write_rtl8225(dev, 0xa, 0x9d4); mdelay(1);
28767 +
28768 + write_rtl8225(dev, 0xb, 0x7bb); mdelay(1);
28769 +
28770 + write_rtl8225(dev, 0xc, 0x850); mdelay(1);
28771 +
28772 +
28773 + write_rtl8225(dev, 0xd, 0xcdf); mdelay(1);
28774 +
28775 + write_rtl8225(dev, 0xe, 0x2b); mdelay(1);
28776 +
28777 + write_rtl8225(dev, 0xf, 0x114);
28778 +
28779 +
28780 + mdelay(100);
28781 +
28782 +
28783 + //if(priv->card_type != USB) /* maybe not needed even for 8185 */
28784 +// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
28785 +
28786 + write_rtl8225(dev, 0x0, 0x1b7);
28787 +
28788 + for(i=0;i<95;i++){
28789 + write_rtl8225(dev, 0x1, (u8)(i+1));
28790 +
28791 + #if 0
28792 + if(priv->phy_ver == 1)
28793 + /* version A */
28794 + write_rtl8225(dev, 0x2, rtl8225a_rxgain[i]);
28795 + else
28796 + #endif
28797 + /* version B & C & D*/
28798 +
28799 + write_rtl8225(dev, 0x2, rtl8225z2_rxgain[i]);
28800 + }
28801 + write_rtl8225(dev, 0x3, 0x80);
28802 + write_rtl8225(dev, 0x5, 0x4);
28803 +
28804 + write_rtl8225(dev, 0x0, 0xb7);
28805 +
28806 + write_rtl8225(dev, 0x2, 0xc4d);
28807 +
28808 + if(priv->card_type == USB){
28809 + // force_pci_posting(dev);
28810 + mdelay(200);
28811 +
28812 + write_rtl8225(dev, 0x2, 0x44d);
28813 +
28814 + // force_pci_posting(dev);
28815 + mdelay(100);
28816 +
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)
28821 + */
28822 + // Check for calibration status, 2005.11.17,
28823 + data = read_rtl8225(dev, 6);
28824 + if (!(data&0x00000080))
28825 + {
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))
28832 + {
28833 + DMESGW("RF Calibration Failed!!!!\n");
28834 + }
28835 + }
28836 + //force_pci_posting(dev);
28837 +
28838 + mdelay(200); //200 for 8187
28839 +
28840 +
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);
28845 +//
28846 +// force_pci_posting(dev);
28847 +// mdelay(100);
28848 +//
28849 +// write_rtl8225(dev, 0x2, 0x44d);
28850 +// //}
28851 +
28852 + write_rtl8225(dev, 0x0, 0x2bf);
28853 +
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];
28859 +
28860 + addr = i + 0x80; //enable writing AGC table
28861 + write_phy_ofdm(dev, 0xb, data);
28862 +
28863 + mdelay(1);
28864 + write_phy_ofdm(dev, 0xa, addr);
28865 +
28866 + mdelay(1);
28867 + }
28868 +#if 0
28869 + for(i=0;i<128;i++){
28870 + write_phy_ofdm(dev, 0xb, rtl8225_agc[i]);
28871 +
28872 + mdelay(1);
28873 + write_phy_ofdm(dev, 0xa, (u8)i+ 0x80);
28874 +
28875 + mdelay(1);
28876 + }
28877 +#endif
28878 +
28879 + force_pci_posting(dev);
28880 + mdelay(1);
28881 +
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);
28892 +
28893 + write_phy_ofdm(dev, 0xa, 0x8); mdelay(1);
28894 +
28895 + //write_phy_ofdm(dev, 0x18, 0xef);
28896 + // }
28897 + //}
28898 + write_phy_ofdm(dev, 0xb, 0x80); mdelay(1);
28899 +
28900 + write_phy_ofdm(dev, 0xc, 0x1);mdelay(1);
28901 +
28902 +
28903 + //if(priv->card_type != USB)
28904 + write_phy_ofdm(dev, 0xd, 0x43);
28905 +
28906 + write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1);
28907 +
28908 +
28909 + #if 0
28910 + if(priv->card_8185 == 1){
28911 + if(priv->card_8185_Bversion)
28912 + write_phy_ofdm(dev, 0xf, 0x20);/*ver B*/
28913 + else
28914 + write_phy_ofdm(dev, 0xf, 0x28);/*ver C*/
28915 + }else{
28916 + #endif
28917 + write_phy_ofdm(dev, 0xf, 0x38);mdelay(1);
28918 +/*ver D & 8187*/
28919 +// }
28920 +
28921 +// if(priv->card_8185 == 1 && priv->card_8185_Bversion)
28922 +// write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/
28923 +// else
28924 + write_phy_ofdm(dev, 0x10, 0x84);mdelay(1);
28925 +/*ver C & D & 8187*/
28926 +
28927 + write_phy_ofdm(dev, 0x11, 0x07);mdelay(1);
28928 +/*agc resp time 700*/
28929 +
28930 +
28931 +// if(priv->card_8185 == 2){
28932 + /* Ver D & 8187*/
28933 + write_phy_ofdm(dev, 0x12, 0x20);mdelay(1);
28934 +
28935 + write_phy_ofdm(dev, 0x13, 0x20);mdelay(1);
28936 +
28937 +#if 0
28938 + }else{
28939 + /* Ver B & C*/
28940 + write_phy_ofdm(dev, 0x12, 0x0);
28941 + write_phy_ofdm(dev, 0x13, 0x0);
28942 + }
28943 +#endif
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);
28948 +
28949 +// if (priv->card_type == USB)
28950 +// write_phy_ofdm(dev, 0x18, 0xef);
28951 +
28952 + write_phy_ofdm(dev, 0x18, 0xef);mdelay(1);
28953 +
28954 +
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);
28958 +
28959 + write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1);
28960 +
28961 + write_phy_ofdm(dev, 0x1d, 0xc5);mdelay(1); //2005.11.17,
28962 +
28963 + write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1);
28964 +
28965 + write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
28966 +
28967 +// }
28968 +
28969 + write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1);
28970 +
28971 + write_phy_ofdm(dev, 0x21, 0x17);mdelay(1);
28972 +
28973 + write_phy_ofdm(dev, 0x22, 0x16);mdelay(1);
28974 +
28975 +// if(priv->card_type != USB)
28976 + write_phy_ofdm(dev, 0x23, 0x80);mdelay(1); //FIXME maybe not needed // <>
28977 +
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);
28981 +
28982 + write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
28983 +
28984 +
28985 + // <> Set init. gain to m74dBm.
28986 +
28987 + rtl8225z2_set_gain(dev,4);
28988 +
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);
28994 +
28995 + write_phy_cck(dev, 0x7, 0x78);mdelay(1);
28996 + /* Ver C & D & 8187*/
28997 +
28998 + write_phy_cck(dev, 0x8, 0x2e);mdelay(1);
28999 +
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);
29003 +#if 0
29004 + if(priv->card_8185 == 1 && priv->card_8185_Bversion)
29005 + write_phy_cck(dev, 0x13, 0x98); /* Ver B */
29006 + else
29007 +#endif
29008 + write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
29009 +
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 */
29014 +
29015 + write_phy_cck(dev, 0x41, 0x8d);mdelay(1);
29016 +
29017 +
29018 + write_phy_cck(dev, 0x42, 0x15); mdelay(1);
29019 + write_phy_cck(dev, 0x43, 0x18); mdelay(1);
29020 +
29021 +
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);
29031 +
29032 +
29033 + write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
29034 +
29035 +
29036 +
29037 +// <>
29038 +// // TESTR 0xb 8187
29039 +// write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
29040 +//
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);
29045 +// //}
29046 +
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 */
29050 +#else
29051 + write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
29052 +#endif
29053 + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */
29054 +
29055 + rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */
29056 +
29057 + /* switch to high-speed 3-wire
29058 + * last digit. 2 for both cck and ofdm
29059 + */
29060 + if(priv->card_type == USB)
29061 + write_nic_dword(dev, 0x94, 0x3dc00002);
29062 + else{
29063 + write_nic_dword(dev, 0x94, 0x15c00002);
29064 + rtl8185_rf_pins_enable(dev);
29065 + }
29066 +
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 */ // <>
29070 +//
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);
29075 +
29076 + rtl8225_rf_set_chan(dev, priv->chan);
29077 +
29078 + //write_nic_word(dev,BRSR,brsr);
29079 +
29080 + //rtl8225z2_rf_set_mode(dev);
29081 +}
29082 +
29083 +void rtl8225z2_rf_set_mode(struct net_device *dev)
29084 +{
29085 + struct r8180_priv *priv = ieee80211_priv(dev);
29086 +
29087 + if(priv->ieee80211->mode == IEEE_A)
29088 + {
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);
29097 +
29098 + rtl8225z2_set_gain(dev,4);
29099 +
29100 + write_phy_ofdm(dev,0x15, 0x40);
29101 + write_phy_ofdm(dev,0x17, 0x40);
29102 +
29103 + write_nic_dword(dev, 0x94,0x10000000);
29104 + }else{
29105 +
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);
29114 +
29115 + rtl8225z2_set_gain(dev,4);
29116 +
29117 + write_phy_ofdm(dev,0x15, 0x40);
29118 + write_phy_ofdm(dev,0x17, 0x40);
29119 +
29120 + write_nic_dword(dev, 0x94,0x04000002);
29121 + }
29122 +}
29123 +
29124 +//lzm mod 080826
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
29130 +
29131 +bool
29132 +SetZebraRFPowerState8185(
29133 + struct net_device *dev,
29134 + RT_RF_POWER_STATE eRFPowerState
29135 + )
29136 +{
29137 + struct r8180_priv *priv = ieee80211_priv(dev);
29138 + u8 btCR9346, btConfig3;
29139 + bool bActionAllowed= true, bTurnOffBB = true;//lzm mod 080826
29140 + //u32 DWordContent;
29141 + u8 u1bTmp;
29142 + int i;
29143 + //u16 u2bTFPC = 0;
29144 + bool bResult = true;
29145 + u8 QueueID;
29146 +
29147 + if(priv->SetRFPowerStateInProgress == true)
29148 + return false;
29149 +
29150 + priv->SetRFPowerStateInProgress = true;
29151 +
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) );
29158 +
29159 + switch( priv->rf_chip )
29160 + {
29161 + case RF_ZEBRA2:
29162 + switch( eRFPowerState )
29163 + {
29164 + case eRfOn:
29165 + RF_WriteReg(dev,0x4,0x9FF);
29166 +
29167 + write_nic_dword(dev, ANAPARAM, ANAPARM_ON);
29168 + write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON);
29169 +
29170 + write_nic_byte(dev, CONFIG4, priv->RFProgType);
29171 +
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.
29175 + break;
29176 +
29177 + case eRfSleep:
29178 + break;
29179 +
29180 + case eRfOff:
29181 + break;
29182 +
29183 + default:
29184 + bResult = false;
29185 + break;
29186 + }
29187 + break;
29188 +
29189 + case RF_ZEBRA4:
29190 + switch( eRFPowerState )
29191 + {
29192 + case eRfOn:
29193 + //printk("===================================power on@jiffies:%d\n",jiffies);
29194 + write_nic_word(dev, 0x37C, 0x00EC);
29195 +
29196 + //turn on AFE
29197 + write_nic_byte(dev, 0x54, 0x00);
29198 + write_nic_byte(dev, 0x62, 0x00);
29199 +
29200 + //lzm mod 080826
29201 + //turn on RF
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);
29209 +
29210 + //turn on BB
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);
29217 +
29218 + u1bTmp = read_nic_byte(dev, 0x24E);
29219 + write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );
29220 +
29221 + break;
29222 +
29223 + case eRfSleep:
29224 + // Make sure BusyQueue is empty befor turn off RFE pwoer.
29225 + //printk("===================================power sleep@jiffies:%d\n",jiffies);
29226 +
29227 + for(QueueID = 0, i = 0; QueueID < 6; )
29228 + {
29229 + if(get_curr_tx_free_desc(dev,QueueID) == priv->txringcount)
29230 + {
29231 + QueueID++;
29232 + continue;
29233 + }
29234 +#if 0 //reserved amy
29235 + else if(priv->NdisAdapter.CurrentPowerState != NdisDeviceStateD0)
29236 + {
29237 + RT_TRACE(COMP_POWER, DBG_LOUD, ("eRfSleep: %d times TcbBusyQueue[%d] !=0 but lower power state!\n", (pMgntInfo->TxPollingTimes+1), QueueID));
29238 + break;
29239 + }
29240 +#endif
29241 + else//lzm mod 080826
29242 + {
29243 + priv->TxPollingTimes ++;
29244 + if(priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE)
29245 + {
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;
29248 + break;
29249 + }
29250 + else
29251 + {
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));
29254 + }
29255 + }
29256 +
29257 + //lzm del 080826
29258 + //if(i >= MAX_DOZE_WAITING_TIMES_85B)
29259 + //{
29260 + //printk("\n\n\n SetZebraRFPowerState8185B(): %d times BusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_85B, QueueID);
29261 + //break;
29262 + //}
29263 + }
29264 +
29265 + if(bActionAllowed)//lzm add 080826
29266 + {
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);
29272 + //turn off RF
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);
29278 +// mdelay(10);
29279 +
29280 +#if 1
29281 + mdelay(1);
29282 + {
29283 + int i = 0;
29284 + while (true)
29285 + {
29286 + u8 tmp24F = read_nic_byte(dev, 0x24f);
29287 + if ((tmp24F == 0x01) || (tmp24F == 0x09))
29288 + {
29289 + bTurnOffBB = true;
29290 + break;
29291 + }
29292 + else//lzm mod 080826
29293 + {
29294 + udelay(10);
29295 + i++;
29296 + priv->TxPollingTimes++;
29297 +
29298 + if(priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE)
29299 + {
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;
29302 + break;
29303 + }
29304 + else
29305 + {
29306 + udelay(10);// Windows may delay 3~16ms actually.
29307 + //RT_TRACE(COMP_POWER, DBG_LOUD,("(%d)eRfSleep- u1bTmp24F= 0x%X\n", i, u1bTmp24F));
29308 +
29309 + }
29310 + }
29311 +
29312 + //lzm del 080826
29313 + //if (i > MAX_POLLING_24F_TIMES_87SE)
29314 + // break;
29315 + }
29316 + }
29317 +#endif
29318 + if (bTurnOffBB)//lzm mod 080826
29319 + {
29320 + //turn off BB
29321 + u1bTmp = read_nic_byte(dev, 0x24E);
29322 + write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));
29323 +
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
29329 + }
29330 + }
29331 + break;
29332 +
29333 + case eRfOff:
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; )
29337 + {
29338 + if(get_curr_tx_free_desc(dev,QueueID) == priv->txringcount)
29339 + {
29340 + QueueID++;
29341 + continue;
29342 + }
29343 +#if 0
29344 + else if(Adapter->NdisAdapter.CurrentPowerState != NdisDeviceStateD0)
29345 + {
29346 + RT_TRACE(COMP_POWER, DBG_LOUD, ("%d times TcbBusyQueue[%d] !=0 but lower power state!\n", (i+1), QueueID));
29347 + break;
29348 + }
29349 +#endif
29350 + else
29351 + {
29352 + udelay(10);
29353 + i++;
29354 + }
29355 +
29356 + if(i >= MAX_DOZE_WAITING_TIMES_85B)
29357 + {
29358 + //printk("\n\n\n SetZebraRFPowerState8185B(): %d times BusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_85B, QueueID);
29359 + break;
29360 + }
29361 + }
29362 +
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);
29368 + //turn off RF
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);
29374 +// mdelay(10);
29375 +#if 1
29376 + mdelay(1);
29377 + {
29378 + int i = 0;
29379 + while (true)
29380 + {
29381 + u8 tmp24F = read_nic_byte(dev, 0x24f);
29382 + if ((tmp24F == 0x01) || (tmp24F == 0x09))
29383 + {
29384 + bTurnOffBB = true;
29385 + break;
29386 + }
29387 + else
29388 + {
29389 + bTurnOffBB = false;
29390 + udelay(10);
29391 + i++;
29392 + }
29393 + if (i > MAX_POLLING_24F_TIMES_87SE)
29394 + break;
29395 + }
29396 + }
29397 +#endif
29398 + if (bTurnOffBB)//lzm mod 080826
29399 + {
29400 +
29401 + //turn off BB
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
29409 + }
29410 +
29411 + break;
29412 +
29413 + default:
29414 + bResult = false;
29415 + printk("SetZebraRFPowerState8185(): unknow state to set: 0x%X!!!\n", eRFPowerState);
29416 + break;
29417 + }
29418 + break;
29419 + }
29420 +
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);
29427 +
29428 + if(bResult && bActionAllowed)//lzm mod 080826
29429 + {
29430 + // Update current RF state variable.
29431 + priv->eRFPowerState = eRFPowerState;
29432 +#if 0
29433 + switch(priv->eRFPowerState)
29434 + {
29435 + case eRfOff:
29436 + //
29437 + //If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015
29438 + //
29439 + if(priv->RfOffReason==RF_CHANGE_BY_IPS )
29440 + {
29441 + Adapter->HalFunc.LedControlHandler(Adapter,LED_CTL_NO_LINK);
29442 + }
29443 + else
29444 + {
29445 + // Turn off LED if RF is not ON.
29446 + Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF);
29447 + }
29448 + break;
29449 +
29450 + case eRfOn:
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 )
29454 + {
29455 + Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK);
29456 + }
29457 + break;
29458 +
29459 + default:
29460 + // do nothing.
29461 + break;
29462 + }
29463 +#endif
29464 +
29465 + }
29466 +
29467 + priv->SetRFPowerStateInProgress = false;
29468 +
29469 + return (bResult && bActionAllowed) ;
29470 +}
29471 +void rtl8225z4_rf_sleep(struct net_device *dev)
29472 +{
29473 + //
29474 + // Turn off RF power.
29475 + //
29476 + //printk("=========>%s()\n", __FUNCTION__);
29477 + MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
29478 + //mdelay(2); //FIXME
29479 +}
29480 +void rtl8225z4_rf_wakeup(struct net_device *dev)
29481 +{
29482 + //
29483 + // Turn on RF power.
29484 + //
29485 + //printk("=========>%s()\n", __FUNCTION__);
29486 + MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
29487 +}
29488 +#endif
29489 +
29490 --- /dev/null
29491 +++ b/drivers/staging/rtl8187se/r8180_rtl8255.c
29492 @@ -0,0 +1,1838 @@
29493 +/*
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>
29497 +
29498 + This files contains programming code for the rtl8255
29499 + radio frontend.
29500 +
29501 + *Many* thanks to Realtek Corp. for their great support!
29502 +
29503 +*/
29504 +
29505 +#define BAND_A 1
29506 +#define BAND_BG 2
29507 +
29508 +#include "r8180.h"
29509 +#include "r8180_hw.h"
29510 +#include "r8180_rtl8255.h"
29511 +
29512 +u32 rtl8255_chan[] = {
29513 + 0, //dummy channel 0
29514 + 0x13, //1
29515 + 0x115, //2
29516 + 0x217, //3
29517 + 0x219, //4
29518 + 0x31b, //5
29519 + 0x41d, //6
29520 + 0x41f, //7
29521 + 0x621, //8
29522 + 0x623, //9
29523 + 0x625, //10
29524 + 0x627, //11
29525 + 0x829, //12
29526 + 0x82b, //13
29527 + 0x92f, // 14
29528 +};
29529 +
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
29535 +};
29536 +
29537 +
29538 +static short rtl8255_agc[]={
29539 + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
29540 +
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,
29544 +
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,
29548 + 0x1f, 0x1f,
29549 +
29550 + 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24,
29551 + 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29,
29552 + 0x2a, 0x2a,
29553 +
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
29558 +
29559 +};
29560 +
29561 +void rtl8255_set_gain(struct net_device *dev, short gain)
29562 +{
29563 +
29564 +// struct r8180_priv *priv = ieee80211_priv(dev);
29565 +
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);
29571 +}
29572 +
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)
29575 +{
29576 + int i,j;
29577 + u16 out,select;
29578 + u8 bit;
29579 + u32 bangdata;
29580 +// struct r8180_priv *priv = ieee80211_priv(dev);
29581 +
29582 + write_nic_word(dev,RFPinsEnable,
29583 + (read_nic_word(dev,RFPinsEnable) | 0x7));
29584 +
29585 + select = read_nic_word(dev, RFPinsSelect);
29586 +
29587 + write_nic_word(dev, RFPinsSelect, select | 0x7 | SW_CONTROL_GPIO);
29588 +
29589 + out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
29590 +
29591 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
29592 +
29593 + force_pci_posting(dev);
29594 + udelay(2);
29595 +
29596 + write_nic_word(dev, RFPinsOutput, out);
29597 +
29598 + force_pci_posting(dev);
29599 + udelay(2);
29600 +
29601 + for(j=0;j<10;j++)
29602 + {
29603 + switch(j)
29604 + {
29605 + case 9:
29606 + bangdata = d10 | 0x0c;
29607 + break;
29608 + case 8:
29609 + bangdata = d9;
29610 + break;
29611 + case 7:
29612 + bangdata = d8;
29613 + break;
29614 + case 6:
29615 + bangdata = d7;
29616 + break;
29617 + case 5:
29618 + bangdata = d6;
29619 + break;
29620 + case 4:
29621 + bangdata = d5;
29622 + break;
29623 + case 3:
29624 + bangdata = d4;
29625 + break;
29626 + case 2:
29627 + bangdata = d3;
29628 + break;
29629 + case 1:
29630 + bangdata = d2;
29631 + break;
29632 + case 0:
29633 + bangdata = d1;
29634 + break;
29635 + default:
29636 + bangdata=0xbadc0de; /* avoid gcc complaints */
29637 + break;
29638 + }
29639 +
29640 + for(i=31; i>=0;i--){
29641 +
29642 + bit = (bangdata & (1<<i)) >> i;
29643 +
29644 + write_nic_word(dev, RFPinsOutput, bit | out);
29645 + force_pci_posting(dev);
29646 + udelay(1);
29647 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
29648 + force_pci_posting(dev);
29649 + udelay(1);
29650 + // write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
29651 + i--;
29652 + bit = (bangdata & (1<<i)) >> i;
29653 +
29654 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
29655 + force_pci_posting(dev);
29656 + udelay(1);
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);
29660 + udelay(1);
29661 + }
29662 + }
29663 +
29664 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
29665 + force_pci_posting(dev);
29666 + udelay(10);
29667 +
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);
29671 +
29672 +}
29673 +
29674 +void write_rtl8255(struct net_device *dev, u8 adr, u16 data)
29675 +{
29676 + int i;
29677 + u16 out,select;
29678 + u8 bit;
29679 + u32 bangdata = (data << 4) | (adr & 0xf);
29680 +// struct r8180_priv *priv = ieee80211_priv(dev);
29681 +
29682 + out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
29683 +
29684 + write_nic_word(dev,RFPinsEnable,
29685 + (read_nic_word(dev,RFPinsEnable) | 0x7));
29686 +
29687 + select = read_nic_word(dev, RFPinsSelect);
29688 +
29689 + write_nic_word(dev, RFPinsSelect, select | 0x7 | SW_CONTROL_GPIO);
29690 +
29691 + force_pci_posting(dev);
29692 + udelay(10);
29693 +
29694 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
29695 +
29696 + force_pci_posting(dev);
29697 + udelay(2);
29698 +
29699 + write_nic_word(dev, RFPinsOutput, out);
29700 +
29701 + force_pci_posting(dev);
29702 + udelay(10);
29703 +
29704 +
29705 + for(i=15; i>=0;i--){
29706 +
29707 + bit = (bangdata & (1<<i)) >> i;
29708 +
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);
29712 + i--;
29713 + bit = (bangdata & (1<<i)) >> i;
29714 +
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);
29718 + }
29719 +
29720 +
29721 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
29722 +
29723 + force_pci_posting(dev);
29724 + udelay(10);
29725 +
29726 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
29727 + write_nic_word(dev, RFPinsSelect, select | SW_CONTROL_GPIO);
29728 +
29729 + rtl8185_rf_pins_enable(dev);
29730 +}
29731 +
29732 +void rtl8255_rf_close(struct net_device *dev)
29733 +{
29734 +
29735 +// rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF);
29736 +// rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF);
29737 +}
29738 +
29739 +void rtl8255_SetTXPowerLevel(struct net_device *dev, short ch)
29740 +{
29741 + struct r8180_priv *priv = ieee80211_priv(dev);
29742 +
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);
29748 + mdelay(1);
29749 + //write_nic_byte(dev, TX_AGC_CONTROL,4);
29750 +}
29751 +#if 0
29752 +/* switch between mode B and G */
29753 +void rtl8255_set_mode(struct net_device *dev, short modeb)
29754 +{
29755 + write_phy_ofdm(dev, 0x15, (modeb ? 0x0 : 0x40));
29756 + write_phy_ofdm(dev, 0x17, (modeb ? 0x0 : 0x40));
29757 +}
29758 +#endif
29759 +
29760 +void rtl8255_rf_set_chan(struct net_device *dev, short ch)
29761 +{
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);
29767 +
29768 +
29769 + force_pci_posting(dev);
29770 + set_current_state(TASK_INTERRUPTIBLE);
29771 + schedule_timeout(HZ);
29772 +// rtl8225_set_mode_B(dev);
29773 +
29774 + rtl8255_SetTXPowerLevel(dev, ch);
29775 + /* FIXME FIXME FIXME */
29776 +
29777 + #if 0
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);
29792 + */
29793 + //mdelay(100);
29794 + #endif
29795 +}
29796 +
29797 +void rtl8255_init_BGband(struct net_device *dev)
29798 +{
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);
31166 + mdelay(20);
31167 + write_rtl8255(dev, 0xd, 0xd7e);
31168 +
31169 +}
31170 +
31171 +
31172 +void rtl8255_set_band_param(struct net_device *dev, short band)
31173 +{
31174 + if(band != BAND_A){
31175 + write_nic_dword(dev, 0x94, 0x3dc00002);
31176 + write_nic_dword(dev, 0x88, 0x00100040);
31177 +
31178 + write_phy_cck(dev, 0x13, 0xd0);
31179 +
31180 + write_phy_cck(dev, 0x41, 0x9d);
31181 + write_nic_dword(dev, 0x8c, 0x00082205);
31182 + write_nic_byte(dev, 0xb4, 0x66);
31183 + }
31184 +}
31185 +
31186 +void rtl8255_rf_init(struct net_device *dev)
31187 +{
31188 + struct r8180_priv *priv = ieee80211_priv(dev);
31189 + int i;
31190 + u16 brsr;
31191 +// short channel /*= priv->chan*/ = 1;
31192 + priv->chan = 1;
31193 +
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);
31198 +
31199 + write_nic_dword(dev, RF_TIMING, 0x000f800f);
31200 +
31201 + brsr = read_nic_word(dev, BRSR);
31202 +
31203 + write_nic_word(dev, 0x2c, 0xffff);
31204 +
31205 +
31206 + rtl8180_set_anaparam(dev, RTL8255_ANAPARAM_ON);
31207 + rtl8185_set_anaparam2(dev, RTL8255_ANAPARAM2_ON);
31208 +
31209 + write_nic_dword(dev, 0x94, 0x11c00002);
31210 +
31211 + write_nic_dword(dev, RF_PARA, 0x100040);
31212 +
31213 + rtl8185_rf_pins_enable(dev);
31214 +
31215 + rtl8255_init_BGband(dev);
31216 + rtl8255_set_band_param(dev,BAND_BG);
31217 +
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*/
31229 +
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);
31237 +
31238 + write_nic_byte(dev, TESTR,0x8);
31239 +
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);
31243 + }
31244 +
31245 +
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);
31285 +
31286 +
31287 + write_nic_dword(dev, 0x94, 0x3dc00002); //BAND DEPEND.
31288 +// write_nic_dword(dev, 0x94, 0x15c00002); //BAND DEPEND.
31289 +
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);
31302 +#if 0
31303 + write_phy_cck(dev, 0x41, 0x9d); /* Energy Threshold */
31304 + // TESTR 0xb 8187
31305 + write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
31306 +#endif
31307 + //rtl8255_set_gain(dev, 1); /* FIXME this '1' is random */
31308 +
31309 + rtl8255_SetTXPowerLevel(dev, priv->chan);
31310 +
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 */
31313 +
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);
31318 +
31319 + rtl8255_set_band_param(dev,BAND_BG);
31320 +
31321 + write_phy_cck(dev, 0x41, 0x9d);
31322 +
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);
31327 +
31328 + write_nic_word(dev, BRSR, brsr);
31329 +}
31330 +
31331 --- /dev/null
31332 +++ b/drivers/staging/rtl8187se/r8180_rtl8255.h
31333 @@ -0,0 +1,19 @@
31334 +/*
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>
31338 +
31339 + This files contains programming code for the rtl8255
31340 + radio frontend.
31341 +
31342 + *Many* thanks to Realtek Corp. for their great support!
31343 +
31344 +*/
31345 +
31346 +#define RTL8255_ANAPARAM_ON 0xa0000b59
31347 +#define RTL8255_ANAPARAM2_ON 0x840cf311
31348 +
31349 +
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);
31353 --- /dev/null
31354 +++ b/drivers/staging/rtl8187se/r8180_sa2400.c
31355 @@ -0,0 +1,233 @@
31356 +/*
31357 + This files contains PHILIPS SA2400 radio frontend programming routines.
31358 +
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)
31362 +
31363 + Parts of this driver are based on the GPL part of the
31364 + official realtek driver
31365 +
31366 + Parts of this driver are based on the rtl8180 driver skeleton
31367 + from Patric Schenke & Andres Salomon
31368 +
31369 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
31370 +
31371 + Code at http://che.ojctech.com/~dyoung/rtw/ has been useful to me to
31372 + understand some things.
31373 +
31374 + Code from rtl8181 project has been useful to me to understand some things.
31375 +
31376 + We want to tanks the Authors of such projects and the Ndiswrapper
31377 + project Authors.
31378 +*/
31379 +
31380 +
31381 +#include "r8180.h"
31382 +#include "r8180_hw.h"
31383 +#include "r8180_sa2400.h"
31384 +
31385 +
31386 +//#define DEBUG_SA2400
31387 +
31388 +u32 sa2400_chan[] = {
31389 + 0x0, //dummy channel 0
31390 + 0x00096c, //1
31391 + 0x080970, //2
31392 + 0x100974, //3
31393 + 0x180978, //4
31394 + 0x000980, //5
31395 + 0x080984, //6
31396 + 0x100988, //7
31397 + 0x18098c, //8
31398 + 0x000994, //9
31399 + 0x080998, //10
31400 + 0x10099c, //11
31401 + 0x1809a0, //12
31402 + 0x0009a8, //13
31403 + 0x0009b4, //14
31404 +};
31405 +
31406 +
31407 +void rf_stabilize(struct net_device *dev)
31408 +{
31409 + force_pci_posting(dev);
31410 + mdelay(3); //for now use a great value.. we may optimize in future
31411 +}
31412 +
31413 +
31414 +void write_sa2400(struct net_device *dev,u8 adr, u32 data)
31415 +{
31416 +// struct r8180_priv *priv = ieee80211_priv(dev);
31417 + u32 phy_config;
31418 +
31419 + // philips sa2400 expects 24 bits data
31420 +
31421 + /*if(adr == 4 && priv->digphy){
31422 + phy_config=0x60000000;
31423 + }else{
31424 + phy_config=0xb0000000;
31425 + }*/
31426 +
31427 + phy_config = 0xb0000000; // MAC will bang bits to the sa2400
31428 +
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);
31434 +#endif
31435 + rf_stabilize(dev);
31436 +}
31437 +
31438 +
31439 +
31440 +void sa2400_write_phy_antenna(struct net_device *dev,short ch)
31441 +{
31442 + struct r8180_priv *priv = ieee80211_priv(dev);
31443 + u8 ant;
31444 +
31445 + ant = SA2400_ANTENNA;
31446 + if(priv->antb) /*default antenna is antenna B */
31447 + ant |= BB_ANTENNA_B;
31448 + if(ch == 14)
31449 + ant |= BB_ANTATTEN_CHAN14;
31450 + write_phy(dev,0x10,ant);
31451 + //DMESG("BB antenna %x ",ant);
31452 +}
31453 +
31454 +
31455 +/* from the rtl8181 embedded driver */
31456 +short sa2400_rf_set_sens(struct net_device *dev, short sens)
31457 +{
31458 + u8 finetune = 0;
31459 + if ((sens > 85) || (sens < 54)) return -1;
31460 +
31461 + write_sa2400(dev,5,0x1dfb | (sens-54) << 15 |(finetune<<20)); // AGC 0xc9dfb
31462 +
31463 + return 0;
31464 +}
31465 +
31466 +
31467 +void sa2400_rf_set_chan(struct net_device *dev, short ch)
31468 +{
31469 + struct r8180_priv *priv = ieee80211_priv(dev);
31470 + u32 txpw = 0xff & priv->chtxpwr[ch];
31471 + u32 chan = sa2400_chan[ch];
31472 +
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);
31480 +}
31481 +
31482 +
31483 +void sa2400_rf_close(struct net_device *dev)
31484 +{
31485 + write_sa2400(dev, 4, 0);
31486 +}
31487 +
31488 +
31489 +void sa2400_rf_init(struct net_device *dev)
31490 +{
31491 + struct r8180_priv *priv = ieee80211_priv(dev);
31492 + u32 anaparam;
31493 + u8 firdac;
31494 +
31495 + write_nic_byte(dev,PHY_DELAY,0x6); //this is general
31496 + write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general
31497 +
31498 + /*these are philips sa2400 specific*/
31499 + anaparam = read_nic_dword(dev,ANAPARAM);
31500 + anaparam = anaparam &~ (1<<ANAPARAM_TXDACOFF_SHIFT);
31501 +
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);
31507 + }else{
31508 + anaparam |= (SA2400_ANA_ANAPARAM_PWR1_ON<<ANAPARAM_PWR1_SHIFT);
31509 + }
31510 +
31511 + rtl8180_set_anaparam(dev,anaparam);
31512 +
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
31521 +
31522 + if(priv->digphy)
31523 + write_sa2400(dev,4,0x1938c); /*???*/
31524 +
31525 + write_sa2400(dev,4,0x19340 | firdac);
31526 +
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
31532 +
31533 + /* new from rtl8180 embedded driver (rtl8181 project) */
31534 + write_sa2400(dev,6,0x13ff | (1<<23)); // MANRX
31535 + write_sa2400(dev,8,0); //VCO
31536 +
31537 + if(!priv->digphy)
31538 + {
31539 + rtl8180_set_anaparam(dev, anaparam | \
31540 + (1<<ANAPARAM_TXDACOFF_SHIFT));
31541 +
31542 + rtl8180_conttx_enable(dev);
31543 +
31544 + write_sa2400(dev, 4, 0x19341); // calibrates DC
31545 +
31546 + /* a 5us sleep is required here,
31547 + we rely on the 3ms delay introduced in write_sa2400
31548 + */
31549 + write_sa2400(dev, 4, 0x19345);
31550 + /* a 20us sleep is required here,
31551 + we rely on the 3ms delay introduced in write_sa2400
31552 + */
31553 + rtl8180_conttx_disable(dev);
31554 +
31555 + rtl8180_set_anaparam(dev, anaparam);
31556 + }
31557 + /* end new */
31558 +
31559 + write_sa2400(dev,4,0x19341 | firdac ); //RTX MODE
31560 +
31561 + // Set tx power level !?
31562 +
31563 +
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);
31571 +
31572 + /*Should be done something more here??*/
31573 +
31574 + sa2400_write_phy_antenna(dev,priv->chan);
31575 +
31576 + write_phy(dev,0x11,0x80);
31577 + if(priv->diversity)
31578 + write_phy(dev,0x12,0xc7);
31579 + else
31580 + write_phy(dev,0x12,0x47);
31581 +
31582 + write_phy(dev,0x13,0x90 | priv->cs_treshold );
31583 +
31584 + write_phy(dev,0x19,0x0);
31585 + write_phy(dev,0x1a,0xa0);
31586 +
31587 + sa2400_rf_set_chan(dev,priv->chan);
31588 +}
31589 --- /dev/null
31590 +++ b/drivers/staging/rtl8187se/r8180_sa2400.h
31591 @@ -0,0 +1,26 @@
31592 +/*
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)
31596 +
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
31600 +
31601 + We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
31602 +*/
31603 +
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
31608 +
31609 +#define SA2400_RF_MAX_SENS 85
31610 +#define SA2400_RF_DEF_SENS 80
31611 +
31612 +#define SA2400_REG4_FIRDAC_SHIFT 7
31613 +
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);
31618 --- /dev/null
31619 +++ b/drivers/staging/rtl8187se/r8180_wx.c
31620 @@ -0,0 +1,1644 @@
31621 +/*
31622 + This file contains wireless extension handlers.
31623 +
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)
31627 +
31628 + Parts of this driver are based on the GPL part
31629 + of the official realtek driver.
31630 +
31631 + Parts of this driver are based on the rtl8180 driver skeleton
31632 + from Patric Schenke & Andres Salomon.
31633 +
31634 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
31635 +
31636 + We want to tanks the Authors of those projects and the Ndiswrapper
31637 + project Authors.
31638 +*/
31639 +
31640 +
31641 +#include "r8180.h"
31642 +#include "r8180_hw.h"
31643 +#include "r8180_sa2400.h"
31644 +
31645 +#ifdef ENABLE_DOT11D
31646 +#include "dot11d.h"
31647 +#endif
31648 +
31649 +//#define RATE_COUNT 4
31650 +u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
31651 + 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
31652 +
31653 +#define RATE_COUNT (sizeof(rtl8180_rates)/sizeof(rtl8180_rates[0]))
31654 +
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
31667 +};
31668 +static int r8180_wx_get_freq(struct net_device *dev,
31669 + struct iw_request_info *a,
31670 + union iwreq_data *wrqu, char *b)
31671 +{
31672 + struct r8180_priv *priv = ieee80211_priv(dev);
31673 +
31674 + return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
31675 +}
31676 +
31677 +
31678 +int r8180_wx_set_key(struct net_device *dev, struct iw_request_info *info,
31679 + union iwreq_data *wrqu, char *key)
31680 +{
31681 + struct r8180_priv *priv = ieee80211_priv(dev);
31682 + struct iw_point *erq = &(wrqu->encoding);
31683 +
31684 + if(priv->ieee80211->bHwRadioOff)
31685 + return 0;
31686 +
31687 + if (erq->flags & IW_ENCODE_DISABLED) {
31688 + }
31689 +
31690 +
31691 +/* i = erq->flags & IW_ENCODE_INDEX;
31692 + if (i < 1 || i > 4)
31693 +*/
31694 +
31695 + if (erq->length > 0) {
31696 +
31697 + //int len = erq->length <= 5 ? 5 : 13;
31698 +
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);
31707 + }
31708 + return 0;
31709 +}
31710 +
31711 +
31712 +static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
31713 + union iwreq_data *wrqu, char *b)
31714 +{
31715 + int *parms = (int *)b;
31716 + int bi = parms[0];
31717 +
31718 + struct r8180_priv *priv = ieee80211_priv(dev);
31719 +
31720 + if(priv->ieee80211->bHwRadioOff)
31721 + return 0;
31722 +
31723 + down(&priv->wx_sem);
31724 + DMESG("setting beacon interval to %x",bi);
31725 +
31726 + priv->ieee80211->current_network.beacon_interval=bi;
31727 + rtl8180_commit(dev);
31728 + up(&priv->wx_sem);
31729 +
31730 + return 0;
31731 +}
31732 +
31733 +
31734 +
31735 +static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
31736 + union iwreq_data *wrqu, char *b)
31737 +{
31738 + struct r8180_priv *priv = ieee80211_priv(dev);
31739 + return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
31740 +}
31741 +
31742 +
31743 +
31744 +static int r8180_wx_get_rate(struct net_device *dev,
31745 + struct iw_request_info *info,
31746 + union iwreq_data *wrqu, char *extra)
31747 +{
31748 + struct r8180_priv *priv = ieee80211_priv(dev);
31749 + return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
31750 +}
31751 +
31752 +
31753 +
31754 +static int r8180_wx_set_rate(struct net_device *dev,
31755 + struct iw_request_info *info,
31756 + union iwreq_data *wrqu, char *extra)
31757 +{
31758 + int ret;
31759 + struct r8180_priv *priv = ieee80211_priv(dev);
31760 +
31761 +
31762 + if(priv->ieee80211->bHwRadioOff)
31763 + return 0;
31764 +
31765 + down(&priv->wx_sem);
31766 +
31767 + ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
31768 +
31769 + up(&priv->wx_sem);
31770 +
31771 + return ret;
31772 +}
31773 +
31774 +
31775 +static int r8180_wx_set_crcmon(struct net_device *dev,
31776 + struct iw_request_info *info,
31777 + union iwreq_data *wrqu, char *extra)
31778 +{
31779 + struct r8180_priv *priv = ieee80211_priv(dev);
31780 + int *parms = (int *)extra;
31781 + int enable = (parms[0] > 0);
31782 + short prev = priv->crcmon;
31783 +
31784 +
31785 + if(priv->ieee80211->bHwRadioOff)
31786 + return 0;
31787 +
31788 + down(&priv->wx_sem);
31789 +
31790 + if(enable)
31791 + priv->crcmon=1;
31792 + else
31793 + priv->crcmon=0;
31794 +
31795 + DMESG("bad CRC in monitor mode are %s",
31796 + priv->crcmon ? "accepted" : "rejected");
31797 +
31798 + if(prev != priv->crcmon && priv->up){
31799 + rtl8180_down(dev);
31800 + rtl8180_up(dev);
31801 + }
31802 +
31803 + up(&priv->wx_sem);
31804 +
31805 + return 0;
31806 +}
31807 +
31808 +
31809 +static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
31810 + union iwreq_data *wrqu, char *b)
31811 +{
31812 + struct r8180_priv *priv = ieee80211_priv(dev);
31813 + int ret;
31814 +
31815 +
31816 + if(priv->ieee80211->bHwRadioOff)
31817 + return 0;
31818 +
31819 + down(&priv->wx_sem);
31820 +#ifdef ENABLE_IPS
31821 +// printk("set mode ENABLE_IPS\n");
31822 + if(priv->bInactivePs){
31823 + if(wrqu->mode == IW_MODE_ADHOC)
31824 + IPSLeave(dev);
31825 + }
31826 +#endif
31827 + ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
31828 +
31829 + //rtl8180_commit(dev);
31830 +
31831 + up(&priv->wx_sem);
31832 + return ret;
31833 +}
31834 +
31835 +//YJ,add,080819,for hidden ap
31836 +struct iw_range_with_scan_capa
31837 +{
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...
31845 + */
31846 +
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 */
31850 +
31851 + /* Old Frequency (backward compat - moved lower ) */
31852 + __u16 old_num_channels;
31853 + __u8 old_num_frequency;
31854 +
31855 + /* Scan capabilities */
31856 + __u8 scan_capa;
31857 +};
31858 +//YJ,add,080819,for hidden ap
31859 +
31860 +
31861 +static int rtl8180_wx_get_range(struct net_device *dev,
31862 + struct iw_request_info *info,
31863 + union iwreq_data *wrqu, char *extra)
31864 +{
31865 + struct iw_range *range = (struct iw_range *)extra;
31866 + struct r8180_priv *priv = ieee80211_priv(dev);
31867 + u16 val;
31868 + int i;
31869 + //struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range; //YJ,add,080819,for hidden ap
31870 +
31871 + wrqu->data.length = sizeof(*range);
31872 + memset(range, 0, sizeof(*range));
31873 +
31874 + /* Let's try to keep this struct in the same order as in
31875 + * linux/include/wireless.h
31876 + */
31877 +
31878 + /* TODO: See what values we can set, and remove the ones we can't
31879 + * set, or fill them with some default data.
31880 + */
31881 +
31882 + /* ~5 Mb/s real (802.11b) */
31883 + range->throughput = 5 * 1000 * 1000;
31884 +
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 */
31889 +
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 */
31896 +
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 */
31902 +
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 */
31908 +
31909 + range->num_bitrates = RATE_COUNT;
31910 +
31911 + for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
31912 + range->bitrate[i] = rtl8180_rates[i];
31913 + }
31914 +
31915 + range->min_frag = MIN_FRAG_THRESHOLD;
31916 + range->max_frag = MAX_FRAG_THRESHOLD;
31917 +
31918 + range->pm_capa = 0;
31919 +
31920 + range->we_version_compiled = WIRELESS_EXT;
31921 + range->we_version_source = 16;
31922 +
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 */
31930 +
31931 + range->num_channels = 14;
31932 +
31933 + for (i = 0, val = 0; i < 14; i++) {
31934 +
31935 + // Include only legal frequencies for some countries
31936 +#ifdef ENABLE_DOT11D
31937 + if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
31938 +#else
31939 + if ((priv->ieee80211->channel_map)[i+1]) {
31940 +#endif
31941 + range->freq[val].i = i + 1;
31942 + range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
31943 + range->freq[val].e = 1;
31944 + val++;
31945 + } else {
31946 + // FIXME: do we need to set anything for channels
31947 + // we don't use ?
31948 + }
31949 +
31950 + if (val == IW_MAX_FREQUENCIES)
31951 + break;
31952 + }
31953 +
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;
31957 +
31958 + //tmp->scan_capa = 0x01; //YJ,add,080819,for hidden ap
31959 +
31960 + return 0;
31961 +}
31962 +
31963 +
31964 +static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
31965 + union iwreq_data *wrqu, char *b)
31966 +{
31967 + struct r8180_priv *priv = ieee80211_priv(dev);
31968 + int ret;
31969 + struct ieee80211_device* ieee = priv->ieee80211;
31970 +
31971 +
31972 + if(priv->ieee80211->bHwRadioOff)
31973 + return 0;
31974 +
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)
31979 + {
31980 + struct iw_scan_req* req = (struct iw_scan_req*)b;
31981 + if (req->essid_len)
31982 + {
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);
31987 + }
31988 + }
31989 +//YJ,add,080819, for hidden ap, end
31990 +
31991 + down(&priv->wx_sem);
31992 + if(priv->up){
31993 +#ifdef ENABLE_IPS
31994 +// printk("set scan ENABLE_IPS\n");
31995 + priv->ieee80211->actscanning = true;
31996 + if(priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED)){
31997 + IPSLeave(dev);
31998 +// down(&priv->ieee80211->wx_sem);
31999 +
32000 +// if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || !(priv->ieee80211->proto_started)){
32001 +// ret = -1;
32002 +// up(&priv->ieee80211->wx_sem);
32003 +// up(&priv->wx_sem);
32004 +// return ret;
32005 +// }
32006 +
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);
32013 + ret = 0;
32014 + }
32015 + else
32016 +#endif
32017 + {
32018 + //YJ,add,080828, prevent scan in BusyTraffic
32019 + //FIXME: Need to consider last scan time
32020 + if ((priv->link_detect.bBusyTraffic) && (true))
32021 + {
32022 + ret = 0;
32023 + printk("Now traffic is busy, please try later!\n");
32024 + }
32025 + else
32026 + //YJ,add,080828, prevent scan in BusyTraffic,end
32027 + ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
32028 + }
32029 + }
32030 + else
32031 + ret = -1;
32032 +
32033 + up(&priv->wx_sem);
32034 +
32035 + return ret;
32036 +}
32037 +
32038 +
32039 +static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
32040 + union iwreq_data *wrqu, char *b)
32041 +{
32042 +
32043 + int ret;
32044 + struct r8180_priv *priv = ieee80211_priv(dev);
32045 +
32046 + down(&priv->wx_sem);
32047 + if(priv->up)
32048 + ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
32049 + else
32050 + ret = -1;
32051 +
32052 + up(&priv->wx_sem);
32053 + return ret;
32054 +}
32055 +
32056 +
32057 +static int r8180_wx_set_essid(struct net_device *dev,
32058 + struct iw_request_info *a,
32059 + union iwreq_data *wrqu, char *b)
32060 +{
32061 + struct r8180_priv *priv = ieee80211_priv(dev);
32062 +
32063 + int ret;
32064 +
32065 + if(priv->ieee80211->bHwRadioOff)
32066 + return 0;
32067 +
32068 + down(&priv->wx_sem);
32069 +#ifdef ENABLE_IPS
32070 + //printk("set essid ENABLE_IPS\n");
32071 + if(priv->bInactivePs)
32072 + IPSLeave(dev);
32073 +#endif
32074 +// printk("haha:set essid %s essid_len = %d essid_flgs = %d\n",b, wrqu->essid.length, wrqu->essid.flags);
32075 +
32076 + ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
32077 +
32078 + up(&priv->wx_sem);
32079 + return ret;
32080 +}
32081 +
32082 +
32083 +static int r8180_wx_get_essid(struct net_device *dev,
32084 + struct iw_request_info *a,
32085 + union iwreq_data *wrqu, char *b)
32086 +{
32087 + int ret;
32088 + struct r8180_priv *priv = ieee80211_priv(dev);
32089 +
32090 + down(&priv->wx_sem);
32091 +
32092 + ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
32093 +
32094 + up(&priv->wx_sem);
32095 +
32096 + return ret;
32097 +}
32098 +
32099 +
32100 +static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
32101 + union iwreq_data *wrqu, char *b)
32102 +{
32103 + int ret;
32104 + struct r8180_priv *priv = ieee80211_priv(dev);
32105 +
32106 +
32107 + if(priv->ieee80211->bHwRadioOff)
32108 + return 0;
32109 +
32110 + down(&priv->wx_sem);
32111 +
32112 + ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
32113 +
32114 + up(&priv->wx_sem);
32115 + return ret;
32116 +}
32117 +
32118 +
32119 +static int r8180_wx_get_name(struct net_device *dev,
32120 + struct iw_request_info *info,
32121 + union iwreq_data *wrqu, char *extra)
32122 +{
32123 + struct r8180_priv *priv = ieee80211_priv(dev);
32124 + return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
32125 +}
32126 +
32127 +static int r8180_wx_set_frag(struct net_device *dev,
32128 + struct iw_request_info *info,
32129 + union iwreq_data *wrqu, char *extra)
32130 +{
32131 + struct r8180_priv *priv = ieee80211_priv(dev);
32132 +
32133 + if(priv->ieee80211->bHwRadioOff)
32134 + return 0;
32135 +
32136 + if (wrqu->frag.disabled)
32137 + priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
32138 + else {
32139 + if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
32140 + wrqu->frag.value > MAX_FRAG_THRESHOLD)
32141 + return -EINVAL;
32142 +
32143 + priv->ieee80211->fts = wrqu->frag.value & ~0x1;
32144 + }
32145 +
32146 + return 0;
32147 +}
32148 +
32149 +
32150 +static int r8180_wx_get_frag(struct net_device *dev,
32151 + struct iw_request_info *info,
32152 + union iwreq_data *wrqu, char *extra)
32153 +{
32154 + struct r8180_priv *priv = ieee80211_priv(dev);
32155 +
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);
32159 +
32160 + return 0;
32161 +}
32162 +
32163 +
32164 +static int r8180_wx_set_wap(struct net_device *dev,
32165 + struct iw_request_info *info,
32166 + union iwreq_data *awrq,
32167 + char *extra)
32168 +{
32169 + int ret;
32170 + struct r8180_priv *priv = ieee80211_priv(dev);
32171 +
32172 + if(priv->ieee80211->bHwRadioOff)
32173 + return 0;
32174 +
32175 + down(&priv->wx_sem);
32176 +
32177 + ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
32178 +
32179 + up(&priv->wx_sem);
32180 + return ret;
32181 +
32182 +}
32183 +
32184 +
32185 +static int r8180_wx_get_wap(struct net_device *dev,
32186 + struct iw_request_info *info,
32187 + union iwreq_data *wrqu, char *extra)
32188 +{
32189 + struct r8180_priv *priv = ieee80211_priv(dev);
32190 +
32191 + return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
32192 +}
32193 +
32194 +
32195 +static int r8180_wx_set_enc(struct net_device *dev,
32196 + struct iw_request_info *info,
32197 + union iwreq_data *wrqu, char *key)
32198 +{
32199 + struct r8180_priv *priv = ieee80211_priv(dev);
32200 + int ret;
32201 +
32202 + if(priv->ieee80211->bHwRadioOff)
32203 + return 0;
32204 +
32205 +
32206 + down(&priv->wx_sem);
32207 +
32208 + if(priv->hw_wep) ret = r8180_wx_set_key(dev,info,wrqu,key);
32209 + else{
32210 + DMESG("Setting SW wep key");
32211 + ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
32212 + }
32213 +
32214 + up(&priv->wx_sem);
32215 + return ret;
32216 +}
32217 +
32218 +
32219 +static int r8180_wx_get_enc(struct net_device *dev,
32220 + struct iw_request_info *info,
32221 + union iwreq_data *wrqu, char *key)
32222 +{
32223 + struct r8180_priv *priv = ieee80211_priv(dev);
32224 +
32225 + return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
32226 +}
32227 +
32228 +
32229 +static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
32230 + iwreq_data *wrqu, char *p){
32231 +
32232 + struct r8180_priv *priv = ieee80211_priv(dev);
32233 + int *parms=(int*)p;
32234 + int mode=parms[0];
32235 +
32236 + if(priv->ieee80211->bHwRadioOff)
32237 + return 0;
32238 +
32239 + priv->ieee80211->active_scan = mode;
32240 +
32241 + return 1;
32242 +}
32243 +
32244 +
32245 +/* added by christian */
32246 +/*
32247 +static int r8180_wx_set_monitor_type(struct net_device *dev, struct iw_request_info *aa, union
32248 + iwreq_data *wrqu, char *p){
32249 +
32250 + struct r8180_priv *priv = ieee80211_priv(dev);
32251 + int *parms=(int*)p;
32252 + int mode=parms[0];
32253 +
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");
32259 + return 0;
32260 +
32261 +}
32262 +*/
32263 +//of r8180_wx_set_monitor_type
32264 +/* end added christian */
32265 +
32266 +static int r8180_wx_set_retry(struct net_device *dev,
32267 + struct iw_request_info *info,
32268 + union iwreq_data *wrqu, char *extra)
32269 +{
32270 + struct r8180_priv *priv = ieee80211_priv(dev);
32271 + int err = 0;
32272 +
32273 + if(priv->ieee80211->bHwRadioOff)
32274 + return 0;
32275 +
32276 + down(&priv->wx_sem);
32277 +
32278 + if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
32279 + wrqu->retry.disabled){
32280 + err = -EINVAL;
32281 + goto exit;
32282 + }
32283 + if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
32284 + err = -EINVAL;
32285 + goto exit;
32286 + }
32287 +
32288 + if(wrqu->retry.value > R8180_MAX_RETRY){
32289 + err= -EINVAL;
32290 + goto exit;
32291 + }
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);
32295 +
32296 + }else {
32297 + priv->retry_data = wrqu->retry.value;
32298 + DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
32299 + }
32300 +
32301 + /* FIXME !
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
32305 + */
32306 +
32307 + rtl8180_commit(dev);
32308 + /*
32309 + if(priv->up){
32310 + rtl8180_rtx_disable(dev);
32311 + rtl8180_rx_enable(dev);
32312 + rtl8180_tx_enable(dev);
32313 +
32314 + }
32315 + */
32316 +exit:
32317 + up(&priv->wx_sem);
32318 +
32319 + return err;
32320 +}
32321 +
32322 +static int r8180_wx_get_retry(struct net_device *dev,
32323 + struct iw_request_info *info,
32324 + union iwreq_data *wrqu, char *extra)
32325 +{
32326 + struct r8180_priv *priv = ieee80211_priv(dev);
32327 +
32328 +
32329 + wrqu->retry.disabled = 0; /* can't be disabled */
32330 +
32331 + if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
32332 + IW_RETRY_LIFETIME)
32333 + return -EINVAL;
32334 +
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;
32338 + } else {
32339 + wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
32340 + wrqu->retry.value = priv->retry_data;
32341 + }
32342 + //DMESG("returning %d",wrqu->retry.value);
32343 +
32344 +
32345 + return 0;
32346 +}
32347 +
32348 +static int r8180_wx_get_sens(struct net_device *dev,
32349 + struct iw_request_info *info,
32350 + union iwreq_data *wrqu, char *extra)
32351 +{
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;
32356 + return 0;
32357 +}
32358 +
32359 +
32360 +static int r8180_wx_set_sens(struct net_device *dev,
32361 + struct iw_request_info *info,
32362 + union iwreq_data *wrqu, char *extra)
32363 +{
32364 +
32365 + struct r8180_priv *priv = ieee80211_priv(dev);
32366 +
32367 + short err = 0;
32368 +
32369 + if(priv->ieee80211->bHwRadioOff)
32370 + return 0;
32371 +
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 */
32376 + goto exit;
32377 + }
32378 + if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
32379 + priv->sens = wrqu->sens.value;
32380 + else
32381 + err= -EINVAL;
32382 +
32383 +exit:
32384 + up(&priv->wx_sem);
32385 +
32386 + return err;
32387 +}
32388 +
32389 +
32390 +static int r8180_wx_set_rawtx(struct net_device *dev,
32391 + struct iw_request_info *info,
32392 + union iwreq_data *wrqu, char *extra)
32393 +{
32394 + struct r8180_priv *priv = ieee80211_priv(dev);
32395 + int ret;
32396 +
32397 + if(priv->ieee80211->bHwRadioOff)
32398 + return 0;
32399 +
32400 + down(&priv->wx_sem);
32401 +
32402 + ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
32403 +
32404 + up(&priv->wx_sem);
32405 +
32406 + return ret;
32407 +
32408 +}
32409 +
32410 +static int r8180_wx_get_power(struct net_device *dev,
32411 + struct iw_request_info *info,
32412 + union iwreq_data *wrqu, char *extra)
32413 +{
32414 + int ret;
32415 + struct r8180_priv *priv = ieee80211_priv(dev);
32416 +
32417 + down(&priv->wx_sem);
32418 +
32419 + ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
32420 +
32421 + up(&priv->wx_sem);
32422 +
32423 + return ret;
32424 +}
32425 +
32426 +static int r8180_wx_set_power(struct net_device *dev,
32427 + struct iw_request_info *info,
32428 + union iwreq_data *wrqu, char *extra)
32429 +{
32430 + int ret;
32431 + struct r8180_priv *priv = ieee80211_priv(dev);
32432 +
32433 +
32434 + if(priv->ieee80211->bHwRadioOff)
32435 + return 0;
32436 +
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;
32443 + }
32444 +
32445 + ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
32446 +
32447 + up(&priv->wx_sem);
32448 +
32449 + return ret;
32450 +}
32451 +
32452 +static int r8180_wx_set_rts(struct net_device *dev,
32453 + struct iw_request_info *info,
32454 + union iwreq_data *wrqu, char *extra)
32455 +{
32456 + struct r8180_priv *priv = ieee80211_priv(dev);
32457 +
32458 +
32459 + if(priv->ieee80211->bHwRadioOff)
32460 + return 0;
32461 +
32462 + if (wrqu->rts.disabled)
32463 + priv->rts = DEFAULT_RTS_THRESHOLD;
32464 + else {
32465 + if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
32466 + wrqu->rts.value > MAX_RTS_THRESHOLD)
32467 + return -EINVAL;
32468 +
32469 + priv->rts = wrqu->rts.value;
32470 + }
32471 +
32472 + return 0;
32473 +}
32474 +static int r8180_wx_get_rts(struct net_device *dev,
32475 + struct iw_request_info *info,
32476 + union iwreq_data *wrqu, char *extra)
32477 +{
32478 + struct r8180_priv *priv = ieee80211_priv(dev);
32479 +
32480 +
32481 +
32482 + wrqu->rts.value = priv->rts;
32483 + wrqu->rts.fixed = 0; /* no auto select */
32484 + wrqu->rts.disabled = (wrqu->rts.value == 0);
32485 +
32486 + return 0;
32487 +}
32488 +static int dummy(struct net_device *dev, struct iw_request_info *a,
32489 + union iwreq_data *wrqu,char *b)
32490 +{
32491 + return -1;
32492 +}
32493 +
32494 +/*
32495 +static int r8180_wx_get_psmode(struct net_device *dev,
32496 + struct iw_request_info *info,
32497 + union iwreq_data *wrqu, char *extra)
32498 +{
32499 + struct r8180_priv *priv = ieee80211_priv(dev);
32500 + struct ieee80211_device *ieee;
32501 + int ret = 0;
32502 +
32503 +
32504 +
32505 + down(&priv->wx_sem);
32506 +
32507 + if(priv) {
32508 + ieee = priv->ieee80211;
32509 + if(ieee->ps == IEEE80211_PS_DISABLED) {
32510 + *((unsigned int *)extra) = IEEE80211_PS_DISABLED;
32511 + goto exit;
32512 + }
32513 + *((unsigned int *)extra) = IW_POWER_TIMEOUT;
32514 + if (ieee->ps & IEEE80211_PS_MBCAST)
32515 + *((unsigned int *)extra) |= IW_POWER_ALL_R;
32516 + else
32517 + *((unsigned int *)extra) |= IW_POWER_UNICAST_R;
32518 + } else
32519 + ret = -1;
32520 +exit:
32521 + up(&priv->wx_sem);
32522 +
32523 + return ret;
32524 +}
32525 +static int r8180_wx_set_psmode(struct net_device *dev,
32526 + struct iw_request_info *info,
32527 + union iwreq_data *wrqu, char *extra)
32528 +{
32529 + struct r8180_priv *priv = ieee80211_priv(dev);
32530 + //struct ieee80211_device *ieee;
32531 + int ret = 0;
32532 +
32533 +
32534 +
32535 + down(&priv->wx_sem);
32536 +
32537 + ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
32538 +
32539 + up(&priv->wx_sem);
32540 +
32541 + return ret;
32542 +
32543 +}
32544 +*/
32545 +
32546 +static int r8180_wx_get_iwmode(struct net_device *dev,
32547 + struct iw_request_info *info,
32548 + union iwreq_data *wrqu, char *extra)
32549 +{
32550 + struct r8180_priv *priv = ieee80211_priv(dev);
32551 + struct ieee80211_device *ieee;
32552 + int ret = 0;
32553 +
32554 +
32555 +
32556 + down(&priv->wx_sem);
32557 +
32558 + ieee = priv->ieee80211;
32559 +
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");
32567 +
32568 + up(&priv->wx_sem);
32569 +
32570 + return ret;
32571 +}
32572 +static int r8180_wx_set_iwmode(struct net_device *dev,
32573 + struct iw_request_info *info,
32574 + union iwreq_data *wrqu, char *extra)
32575 +{
32576 + struct r8180_priv *priv = ieee80211_priv(dev);
32577 + struct ieee80211_device *ieee = priv->ieee80211;
32578 + int *param = (int *)extra;
32579 + int ret = 0;
32580 + int modulation = 0, mode = 0;
32581 +
32582 +
32583 + if(priv->ieee80211->bHwRadioOff)
32584 + return 0;
32585 +
32586 + down(&priv->wx_sem);
32587 +
32588 + if (*param == 1) {
32589 + modulation |= IEEE80211_CCK_MODULATION;
32590 + mode = IEEE_B;
32591 + printk(KERN_INFO "B mode!\n");
32592 + } else if (*param == 2) {
32593 + modulation |= IEEE80211_OFDM_MODULATION;
32594 + mode = IEEE_G;
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");
32601 + }
32602 +
32603 + if(ieee->proto_started) {
32604 + ieee80211_stop_protocol(ieee);
32605 + ieee->mode = mode;
32606 + ieee->modulation = modulation;
32607 + ieee80211_start_protocol(ieee);
32608 + } else {
32609 + ieee->mode = mode;
32610 + ieee->modulation = modulation;
32611 +// ieee80211_start_protocol(ieee);
32612 + }
32613 +
32614 + up(&priv->wx_sem);
32615 +
32616 + return ret;
32617 +}
32618 +static int r8180_wx_get_preamble(struct net_device *dev,
32619 + struct iw_request_info *info,
32620 + union iwreq_data *wrqu, char *extra)
32621 +{
32622 + struct r8180_priv *priv = ieee80211_priv(dev);
32623 +
32624 +
32625 +
32626 + down(&priv->wx_sem);
32627 +
32628 +
32629 +
32630 + *extra = (char) priv->plcp_preamble_mode; // 0:auto 1:short 2:long
32631 + up(&priv->wx_sem);
32632 +
32633 + return 0;
32634 +}
32635 +static int r8180_wx_set_preamble(struct net_device *dev,
32636 + struct iw_request_info *info,
32637 + union iwreq_data *wrqu, char *extra)
32638 +{
32639 + struct r8180_priv *priv = ieee80211_priv(dev);
32640 + int ret = 0;
32641 +
32642 +
32643 + if(priv->ieee80211->bHwRadioOff)
32644 + return 0;
32645 +
32646 + down(&priv->wx_sem);
32647 + if (*extra<0||*extra>2)
32648 + ret = -1;
32649 + else
32650 + priv->plcp_preamble_mode = *((short *)extra) ;
32651 +
32652 +
32653 +
32654 + up(&priv->wx_sem);
32655 +
32656 + return ret;
32657 +}
32658 +static int r8180_wx_get_siglevel(struct net_device *dev,
32659 + struct iw_request_info *info,
32660 + union iwreq_data *wrqu, char *extra)
32661 +{
32662 + struct r8180_priv *priv = ieee80211_priv(dev);
32663 + //struct ieee80211_network *network = &(priv->ieee80211->current_network);
32664 + int ret = 0;
32665 +
32666 +
32667 +
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;
32671 +
32672 +
32673 +
32674 + up(&priv->wx_sem);
32675 +
32676 + return ret;
32677 +}
32678 +static int r8180_wx_get_sigqual(struct net_device *dev,
32679 + struct iw_request_info *info,
32680 + union iwreq_data *wrqu, char *extra)
32681 +{
32682 + struct r8180_priv *priv = ieee80211_priv(dev);
32683 + //struct ieee80211_network *network = &(priv->ieee80211->current_network);
32684 + int ret = 0;
32685 +
32686 +
32687 +
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;
32691 +
32692 +
32693 +
32694 + up(&priv->wx_sem);
32695 +
32696 + return ret;
32697 +}
32698 +static int r8180_wx_reset_stats(struct net_device *dev,
32699 + struct iw_request_info *info,
32700 + union iwreq_data *wrqu, char *extra)
32701 +{
32702 + struct r8180_priv *priv =ieee80211_priv(dev);
32703 + down(&priv->wx_sem);
32704 +
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;
32715 +
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;
32732 +
32733 + up(&priv->wx_sem);
32734 +
32735 + return 0;
32736 +
32737 +}
32738 +static int r8180_wx_radio_on(struct net_device *dev,
32739 + struct iw_request_info *info,
32740 + union iwreq_data *wrqu, char *extra)
32741 +{
32742 + struct r8180_priv *priv =ieee80211_priv(dev);
32743 +
32744 + if(priv->ieee80211->bHwRadioOff)
32745 + return 0;
32746 +
32747 +
32748 + down(&priv->wx_sem);
32749 + priv->rf_wakeup(dev);
32750 +
32751 + up(&priv->wx_sem);
32752 +
32753 + return 0;
32754 +
32755 +}
32756 +
32757 +static int r8180_wx_radio_off(struct net_device *dev,
32758 + struct iw_request_info *info,
32759 + union iwreq_data *wrqu, char *extra)
32760 +{
32761 + struct r8180_priv *priv =ieee80211_priv(dev);
32762 +
32763 + if(priv->ieee80211->bHwRadioOff)
32764 + return 0;
32765 +
32766 +
32767 + down(&priv->wx_sem);
32768 + priv->rf_sleep(dev);
32769 +
32770 + up(&priv->wx_sem);
32771 +
32772 + return 0;
32773 +
32774 +}
32775 +static int r8180_wx_get_channelplan(struct net_device *dev,
32776 + struct iw_request_info *info,
32777 + union iwreq_data *wrqu, char *extra)
32778 +{
32779 + struct r8180_priv *priv = ieee80211_priv(dev);
32780 +
32781 +
32782 +
32783 + down(&priv->wx_sem);
32784 + *extra = priv->channel_plan;
32785 +
32786 +
32787 +
32788 + up(&priv->wx_sem);
32789 +
32790 + return 0;
32791 +}
32792 +static int r8180_wx_set_channelplan(struct net_device *dev,
32793 + struct iw_request_info *info,
32794 + union iwreq_data *wrqu, char *extra)
32795 +{
32796 + struct r8180_priv *priv = ieee80211_priv(dev);
32797 + //struct ieee80211_device *ieee = netdev_priv(dev);
32798 + int *val = (int *)extra;
32799 + int i;
32800 + printk("-----in fun %s\n", __FUNCTION__);
32801 +
32802 + if(priv->ieee80211->bHwRadioOff)
32803 + return 0;
32804 +
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++)
32811 + {
32812 +#ifdef ENABLE_DOT11D
32813 + GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
32814 +#else
32815 + priv->ieee80211->channel_map[i] = 0;
32816 +#endif
32817 + }
32818 + // Set new channel map
32819 + for (i=1;i<=DefaultChannelPlan[*val].Len;i++)
32820 + {
32821 +#ifdef ENABLE_DOT11D
32822 + GET_DOT11D_INFO(priv->ieee80211)->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
32823 +#else
32824 + priv->ieee80211->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
32825 +#endif
32826 + }
32827 + }
32828 + up(&priv->wx_sem);
32829 +
32830 + return 0;
32831 +}
32832 +
32833 +static int r8180_wx_get_version(struct net_device *dev,
32834 + struct iw_request_info *info,
32835 + union iwreq_data *wrqu, char *extra)
32836 +{
32837 + struct r8180_priv *priv = ieee80211_priv(dev);
32838 + //struct ieee80211_device *ieee;
32839 +
32840 + down(&priv->wx_sem);
32841 + strcpy(extra, "1020.0808");
32842 + up(&priv->wx_sem);
32843 +
32844 + return 0;
32845 +}
32846 +
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)
32852 +{
32853 + struct r8180_priv *priv = ieee80211_priv(dev);
32854 + u8 forcerate = *extra;
32855 +
32856 + down(&priv->wx_sem);
32857 +
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))
32862 + {
32863 + priv->ForcedDataRate = 1;
32864 + priv->ieee80211->rate = forcerate * 5;
32865 + }
32866 + else if(forcerate == 0)
32867 + {
32868 + priv->ForcedDataRate = 0;
32869 + printk("OK! return rate adaptive\n");
32870 + }
32871 + else
32872 + printk("ERR: wrong rate\n");
32873 + up(&priv->wx_sem);
32874 + return 0;
32875 +}
32876 +
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)
32880 +{
32881 +
32882 + struct r8180_priv *priv = ieee80211_priv(dev);
32883 + //printk("===>%s()\n", __FUNCTION__);
32884 +
32885 + int ret=0;
32886 +
32887 + if(priv->ieee80211->bHwRadioOff)
32888 + return 0;
32889 +
32890 + down(&priv->wx_sem);
32891 + ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
32892 + up(&priv->wx_sem);
32893 + return ret;
32894 +
32895 +}
32896 +static int r8180_wx_set_auth(struct net_device *dev,
32897 + struct iw_request_info *info,
32898 + struct iw_param *data, char *extra)
32899 +{
32900 + //printk("====>%s()\n", __FUNCTION__);
32901 + struct r8180_priv *priv = ieee80211_priv(dev);
32902 + int ret=0;
32903 +
32904 + if(priv->ieee80211->bHwRadioOff)
32905 + return 0;
32906 +
32907 + down(&priv->wx_sem);
32908 + ret = ieee80211_wx_set_auth(priv->ieee80211, info, data, extra);
32909 + up(&priv->wx_sem);
32910 + return ret;
32911 +}
32912 +
32913 +static int r8180_wx_set_mlme(struct net_device *dev,
32914 + struct iw_request_info *info,
32915 + union iwreq_data *wrqu, char *extra)
32916 +{
32917 + //printk("====>%s()\n", __FUNCTION__);
32918 +
32919 + int ret=0;
32920 + struct r8180_priv *priv = ieee80211_priv(dev);
32921 +
32922 +
32923 + if(priv->ieee80211->bHwRadioOff)
32924 + return 0;
32925 +
32926 +
32927 + down(&priv->wx_sem);
32928 +#if 1
32929 + ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
32930 +#endif
32931 + up(&priv->wx_sem);
32932 + return ret;
32933 +}
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)
32937 +{
32938 +// printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
32939 + int ret=0;
32940 + struct r8180_priv *priv = ieee80211_priv(dev);
32941 +
32942 +
32943 + if(priv->ieee80211->bHwRadioOff)
32944 + return 0;
32945 +
32946 + down(&priv->wx_sem);
32947 +#if 1
32948 + ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->length);
32949 +#endif
32950 + up(&priv->wx_sem);
32951 + //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
32952 + return ret;
32953 +
32954 +
32955 +}
32956 +static iw_handler r8180_wx_handlers[] =
32957 +{
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---*/
33014 +};
33015 +
33016 +
33017 +static const struct iw_priv_args r8180_private_args[] = {
33018 + {
33019 + SIOCIWFIRSTPRIV + 0x0,
33020 + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
33021 + },
33022 + { SIOCIWFIRSTPRIV + 0x1,
33023 + 0, 0, "dummy"
33024 +
33025 + },
33026 + {
33027 + SIOCIWFIRSTPRIV + 0x2,
33028 + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint"
33029 + },
33030 + { SIOCIWFIRSTPRIV + 0x3,
33031 + 0, 0, "dummy"
33032 +
33033 + },
33034 + /* added by christian */
33035 + //{
33036 + // SIOCIWFIRSTPRIV + 0x2,
33037 + // IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "prismhdr"
33038 + //},
33039 + /* end added by christian */
33040 + {
33041 + SIOCIWFIRSTPRIV + 0x4,
33042 + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
33043 +
33044 + },
33045 + { SIOCIWFIRSTPRIV + 0x5,
33046 + 0, 0, "dummy"
33047 +
33048 + },
33049 + {
33050 + SIOCIWFIRSTPRIV + 0x6,
33051 + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
33052 +
33053 + },
33054 + { SIOCIWFIRSTPRIV + 0x7,
33055 + 0, 0, "dummy"
33056 +
33057 + },
33058 +// {
33059 +// SIOCIWFIRSTPRIV + 0x5,
33060 +// 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpsmode"
33061 +// },
33062 +// {
33063 +// SIOCIWFIRSTPRIV + 0x6,
33064 +// IW_PRIV_SIZE_FIXED, 0, "setpsmode"
33065 +// },
33066 +//set/get mode have been realized in public handlers
33067 +
33068 + {
33069 + SIOCIWFIRSTPRIV + 0x8,
33070 + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode"
33071 + },
33072 + {
33073 + SIOCIWFIRSTPRIV + 0x9,
33074 + 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode"
33075 + },
33076 + {
33077 + SIOCIWFIRSTPRIV + 0xA,
33078 + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble"
33079 + },
33080 + {
33081 + SIOCIWFIRSTPRIV + 0xB,
33082 + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble"
33083 + },
33084 + { SIOCIWFIRSTPRIV + 0xC,
33085 + 0, 0, "dummy"
33086 + },
33087 + {
33088 + SIOCIWFIRSTPRIV + 0xD,
33089 + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi"
33090 + },
33091 + { SIOCIWFIRSTPRIV + 0xE,
33092 + 0, 0, "dummy"
33093 + },
33094 + {
33095 + SIOCIWFIRSTPRIV + 0xF,
33096 + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual"
33097 + },
33098 + {
33099 + SIOCIWFIRSTPRIV + 0x10,
33100 + 0, 0, "resetstats"
33101 + },
33102 + {
33103 + SIOCIWFIRSTPRIV + 0x11,
33104 + 0,0, "dummy"
33105 + },
33106 + {
33107 + SIOCIWFIRSTPRIV + 0x12,
33108 + 0, 0, "radioon"
33109 + },
33110 + {
33111 + SIOCIWFIRSTPRIV + 0x13,
33112 + 0, 0, "radiooff"
33113 + },
33114 + {
33115 + SIOCIWFIRSTPRIV + 0x14,
33116 + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel"
33117 + },
33118 + {
33119 + SIOCIWFIRSTPRIV + 0x15,
33120 + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
33121 + },
33122 + {
33123 + SIOCIWFIRSTPRIV + 0x16,
33124 + 0,0, "dummy"
33125 + },
33126 + {
33127 + SIOCIWFIRSTPRIV + 0x17,
33128 + 0,IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion"
33129 + },
33130 + {
33131 + SIOCIWFIRSTPRIV + 0x18,
33132 + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate"
33133 + },
33134 +};
33135 +
33136 +
33137 +static iw_handler r8180_private_handler[] = {
33138 + r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
33139 + dummy,
33140 + r8180_wx_set_beaconinterval,
33141 + dummy,
33142 + //r8180_wx_set_monitor_type,
33143 + r8180_wx_set_scan_type,
33144 + dummy,
33145 + r8180_wx_set_rawtx,
33146 + dummy,
33147 + r8180_wx_set_iwmode,
33148 + r8180_wx_get_iwmode,
33149 + r8180_wx_set_preamble,
33150 + r8180_wx_get_preamble,
33151 + dummy,
33152 + r8180_wx_get_siglevel,
33153 + dummy,
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,
33161 + dummy,
33162 + r8180_wx_get_version,
33163 + r8180_wx_set_forcerate,
33164 +};
33165 +
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)
33170 +{
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)));
33185 +}
33186 +
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)
33189 +{
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;
33198 +
33199 + if (ieee->state < IEEE80211_LINKED)
33200 + {
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;
33205 + return wstats;
33206 + }
33207 +#if 0
33208 + spin_lock_irqsave(&ieee->lock, flag);
33209 + list_for_each_entry(target, &ieee->network_list, list)
33210 + {
33211 + if (is_same_network(target, &ieee->current_network, ieee))
33212 + {
33213 + printk("it's same network:%s\n", target->ssid);
33214 +#if 0
33215 + if (!tmp_level)
33216 + {
33217 + tmp_level = target->stats.signalstrength;
33218 + tmp_qual = target->stats.signal;
33219 + }
33220 + else
33221 + {
33222 +
33223 + tmp_level = (15*tmp_level + target->stats.signalstrength)/16;
33224 + tmp_qual = (15*tmp_qual + target->stats.signal)/16;
33225 + }
33226 +#else
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);
33231 +#endif
33232 + break;
33233 + }
33234 + }
33235 + spin_unlock_irqrestore(&ieee->lock, flag);
33236 +#endif
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);
33241 +
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;
33247 + return wstats;
33248 +}
33249 +#endif
33250 +
33251 +
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,
33260 +#endif
33261 + .private_args = (struct iw_priv_args *)r8180_private_args,
33262 +};
33263 +
33264 +
33265 --- /dev/null
33266 +++ b/drivers/staging/rtl8187se/r8180_wx.h
33267 @@ -0,0 +1,21 @@
33268 +/*
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)
33272 +
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
33276 +
33277 + We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
33278 +*/
33279 +
33280 +/* this file (will) contains wireless extension handlers*/
33281 +
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;
33287 +
33288 +#endif
33289 --- /dev/null
33290 +++ b/drivers/staging/rtl8187se/r8185b_init.c
33291 @@ -0,0 +1,3342 @@
33292 +/*++
33293 +Copyright (c) Realtek Semiconductor Corp. All rights reserved.
33294 +
33295 +Module Name:
33296 + r8185b_init.c
33297 +
33298 +Abstract:
33299 + Hardware Initialization and Hardware IO for RTL8185B
33300 +
33301 +Major Change History:
33302 + When Who What
33303 + ---------- --------------- -------------------------------
33304 + 2006-11-15 Xiong Created
33305 +
33306 +Notes:
33307 + This file is ported from RTL8185B Windows driver.
33308 +
33309 +
33310 +--*/
33311 +
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"
33323 +
33324 +#ifdef CONFIG_RTL8180_PM
33325 +#include "r8180_pm.h"
33326 +#endif
33327 +
33328 +#ifdef ENABLE_DOT11D
33329 +#include "dot11d.h"
33330 +#endif
33331 +
33332 +#ifdef CONFIG_RTL8185B
33333 +
33334 +//#define CONFIG_RTL8180_IO_MAP
33335 +
33336 +#define TC_3W_POLL_MAX_TRY_CNT 5
33337 +#ifdef CONFIG_RTL818X_S
33338 +static u8 MAC_REG_TABLE[][2]={
33339 + //PAGA 0:
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},
33351 + {0xff, 0x00},
33352 +
33353 + //PAGE 1:
33354 + // For Flextronics system Logo PCIHCT failure:
33355 + // 0x1C4~0x1CD set no-zero value to avoid PCI configuration space 0x45[7]=1
33356 + {0x5e, 0x01},
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
33362 + {0xe2, 0x00},
33363 +
33364 +
33365 + //PAGE 2:
33366 + {0x5e, 0x02},
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},
33374 +
33375 + //PAGA 0:
33376 + {0x5e, 0x00},{0x9f, 0x03}
33377 + };
33378 +
33379 +
33380 +static u8 ZEBRA_AGC[]={
33381 + 0,
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
33390 + };
33391 +
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
33398 + };
33399 +
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
33404 +
33405 + // 0x00
33406 + 0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50,
33407 + 0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00,
33408 + // 0x10
33409 + 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26,
33410 + 0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB,
33411 + // 0x20
33412 + 0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00,
33413 + 0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00,
33414 + // 0x30
33415 + 0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e,
33416 + 0xD8, 0x3C, 0x7B, 0x10, 0x10
33417 + };
33418 +#else
33419 + static u8 MAC_REG_TABLE[][2]={
33420 + //PAGA 0:
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},
33424 + {0xff, 0x00},
33425 +
33426 + //PAGE 1:
33427 + {0x5e, 0x01},
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},
33433 +
33434 +
33435 + //PAGE 2:
33436 + {0x5e, 0x02},
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},
33443 +
33444 + //PAGA 0:
33445 + {0x5e, 0x00},
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},
33450 + {0x91, 0x03},
33451 +
33452 + //PAGE 2:
33453 + {0x5e, 0x02},
33454 + {0x4c, 0x03},
33455 +
33456 + //PAGE 0:
33457 + {0x5e, 0x00},
33458 +
33459 + //PAGE 3:
33460 + {0x5e, 0x03},
33461 + {0x9f, 0x00},
33462 +
33463 + //PAGE 0:
33464 + {0x5e, 0x00},
33465 + {0x8c, 0x01}, {0x8d, 0x10},{0x8e, 0x08}, {0x8f, 0x00}
33466 + };
33467 +
33468 +
33469 +static u8 ZEBRA_AGC[]={
33470 + 0,
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
33479 + };
33480 +
33481 +static u32 ZEBRA_RF_RX_GAIN_TABLE[]={
33482 + 0,
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
33495 +};
33496 +
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
33507 +};
33508 +#endif
33509 +
33510 +/*---------------------------------------------------------------
33511 + * Hardware IO
33512 + * the code is ported from Windows source code
33513 + ----------------------------------------------------------------*/
33514 +
33515 +void
33516 +PlatformIOWrite1Byte(
33517 + struct net_device *dev,
33518 + u32 offset,
33519 + u8 data
33520 + )
33521 +{
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.
33525 +
33526 +#else // Port IO
33527 + u32 Page = (offset >> 8);
33528 +
33529 + switch(Page)
33530 + {
33531 + case 0: // Page 0
33532 + write_nic_byte(dev, offset, data);
33533 + break;
33534 +
33535 + case 1: // Page 1
33536 + case 2: // Page 2
33537 + case 3: // Page 3
33538 + {
33539 + u8 psr = read_nic_byte(dev, PSR);
33540 +
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.
33544 + }
33545 + break;
33546 +
33547 + default:
33548 + // Illegal page number.
33549 + DMESGE("PlatformIOWrite1Byte(): illegal page number: %d, offset: %#X", Page, offset);
33550 + break;
33551 + }
33552 +#endif
33553 +}
33554 +
33555 +void
33556 +PlatformIOWrite2Byte(
33557 + struct net_device *dev,
33558 + u32 offset,
33559 + u16 data
33560 + )
33561 +{
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.
33565 +
33566 +
33567 +#else // Port IO
33568 + u32 Page = (offset >> 8);
33569 +
33570 + switch(Page)
33571 + {
33572 + case 0: // Page 0
33573 + write_nic_word(dev, offset, data);
33574 + break;
33575 +
33576 + case 1: // Page 1
33577 + case 2: // Page 2
33578 + case 3: // Page 3
33579 + {
33580 + u8 psr = read_nic_byte(dev, PSR);
33581 +
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.
33585 + }
33586 + break;
33587 +
33588 + default:
33589 + // Illegal page number.
33590 + DMESGE("PlatformIOWrite2Byte(): illegal page number: %d, offset: %#X", Page, offset);
33591 + break;
33592 + }
33593 +#endif
33594 +}
33595 +u8 PlatformIORead1Byte(struct net_device *dev, u32 offset);
33596 +
33597 +void
33598 +PlatformIOWrite4Byte(
33599 + struct net_device *dev,
33600 + u32 offset,
33601 + u32 data
33602 + )
33603 +{
33604 +#ifndef CONFIG_RTL8180_IO_MAP
33605 +//{by amy 080312
33606 +if (offset == PhyAddr)
33607 + {//For Base Band configuration.
33608 + unsigned char cmdByte;
33609 + unsigned long dataBytes;
33610 + unsigned char idx;
33611 + u8 u1bTmp;
33612 +
33613 + cmdByte = (u8)(data & 0x000000ff);
33614 + dataBytes = data>>8;
33615 +
33616 + //
33617 + // 071010, rcnjko:
33618 + // The critical section is only BB read/write race condition.
33619 + // Assumption:
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.
33623 + //
33624 +// NdisAcquireSpinLock( &(pDevice->IoSpinLock) );
33625 +
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)
33630 + break;
33631 + else
33632 + mdelay(10);
33633 + }
33634 +
33635 + for(idx=0; idx < 3; idx++)
33636 + {
33637 + PlatformIOWrite1Byte(dev,offset+1+idx,((u8*)&dataBytes)[idx] );
33638 + }
33639 + write_nic_byte(dev, offset, cmdByte);
33640 +
33641 +// NdisReleaseSpinLock( &(pDevice->IoSpinLock) );
33642 + }
33643 +//by amy 080312}
33644 + else{
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.
33647 + }
33648 +#else // Port IO
33649 + u32 Page = (offset >> 8);
33650 +
33651 + switch(Page)
33652 + {
33653 + case 0: // Page 0
33654 + write_nic_word(dev, offset, data);
33655 + break;
33656 +
33657 + case 1: // Page 1
33658 + case 2: // Page 2
33659 + case 3: // Page 3
33660 + {
33661 + u8 psr = read_nic_byte(dev, PSR);
33662 +
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.
33666 + }
33667 + break;
33668 +
33669 + default:
33670 + // Illegal page number.
33671 + DMESGE("PlatformIOWrite4Byte(): illegal page number: %d, offset: %#X", Page, offset);
33672 + break;
33673 + }
33674 +#endif
33675 +}
33676 +
33677 +u8
33678 +PlatformIORead1Byte(
33679 + struct net_device *dev,
33680 + u32 offset
33681 + )
33682 +{
33683 + u8 data = 0;
33684 +
33685 +#ifndef CONFIG_RTL8180_IO_MAP
33686 + data = read_nic_byte(dev, offset);
33687 +
33688 +#else // Port IO
33689 + u32 Page = (offset >> 8);
33690 +
33691 + switch(Page)
33692 + {
33693 + case 0: // Page 0
33694 + data = read_nic_byte(dev, offset);
33695 + break;
33696 +
33697 + case 1: // Page 1
33698 + case 2: // Page 2
33699 + case 3: // Page 3
33700 + {
33701 + u8 psr = read_nic_byte(dev, PSR);
33702 +
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.
33706 + }
33707 + break;
33708 +
33709 + default:
33710 + // Illegal page number.
33711 + DMESGE("PlatformIORead1Byte(): illegal page number: %d, offset: %#X", Page, offset);
33712 + break;
33713 + }
33714 +#endif
33715 +
33716 + return data;
33717 +}
33718 +
33719 +u16
33720 +PlatformIORead2Byte(
33721 + struct net_device *dev,
33722 + u32 offset
33723 + )
33724 +{
33725 + u16 data = 0;
33726 +
33727 +#ifndef CONFIG_RTL8180_IO_MAP
33728 + data = read_nic_word(dev, offset);
33729 +
33730 +#else // Port IO
33731 + u32 Page = (offset >> 8);
33732 +
33733 + switch(Page)
33734 + {
33735 + case 0: // Page 0
33736 + data = read_nic_word(dev, offset);
33737 + break;
33738 +
33739 + case 1: // Page 1
33740 + case 2: // Page 2
33741 + case 3: // Page 3
33742 + {
33743 + u8 psr = read_nic_byte(dev, PSR);
33744 +
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.
33748 + }
33749 + break;
33750 +
33751 + default:
33752 + // Illegal page number.
33753 + DMESGE("PlatformIORead2Byte(): illegal page number: %d, offset: %#X", Page, offset);
33754 + break;
33755 + }
33756 +#endif
33757 +
33758 + return data;
33759 +}
33760 +
33761 +u32
33762 +PlatformIORead4Byte(
33763 + struct net_device *dev,
33764 + u32 offset
33765 + )
33766 +{
33767 + u32 data = 0;
33768 +
33769 +#ifndef CONFIG_RTL8180_IO_MAP
33770 + data = read_nic_dword(dev, offset);
33771 +
33772 +#else // Port IO
33773 + u32 Page = (offset >> 8);
33774 +
33775 + switch(Page)
33776 + {
33777 + case 0: // Page 0
33778 + data = read_nic_dword(dev, offset);
33779 + break;
33780 +
33781 + case 1: // Page 1
33782 + case 2: // Page 2
33783 + case 3: // Page 3
33784 + {
33785 + u8 psr = read_nic_byte(dev, PSR);
33786 +
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.
33790 + }
33791 + break;
33792 +
33793 + default:
33794 + // Illegal page number.
33795 + DMESGE("PlatformIORead4Byte(): illegal page number: %d, offset: %#X\n", Page, offset);
33796 + break;
33797 + }
33798 +#endif
33799 +
33800 + return data;
33801 +}
33802 +
33803 +void
33804 +SetOutputEnableOfRfPins(
33805 + struct net_device *dev
33806 + )
33807 +{
33808 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
33809 +
33810 + switch(priv->rf_chip)
33811 + {
33812 + case RFCHIPID_RTL8225:
33813 + case RF_ZEBRA2:
33814 + case RF_ZEBRA4:
33815 + write_nic_word(dev, RFPinsEnable, 0x1bff);
33816 + //write_nic_word(dev, RFPinsEnable, 0x1fff);
33817 + break;
33818 + }
33819 +}
33820 +
33821 +void
33822 +ZEBRA_RFSerialWrite(
33823 + struct net_device *dev,
33824 + u32 data2Write,
33825 + u8 totalLength,
33826 + u8 low2high
33827 + )
33828 +{
33829 + ThreeWireReg twreg;
33830 + int i;
33831 + u16 oval,oval2,oval3;
33832 + u32 mask;
33833 + u16 UshortBuffer;
33834 +
33835 + u8 u1bTmp;
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);
33841 +#endif
33842 + UshortBuffer = read_nic_word(dev, RFPinsOutput);
33843 + oval = UshortBuffer & 0xfff8; // We shall clear bit0, 1, 2 first, 2005.10.28, by rcnjko.
33844 +
33845 + oval2 = read_nic_word(dev, RFPinsEnable);
33846 + oval3 = read_nic_word(dev, RFPinsSelect);
33847 +
33848 + // <RJ_NOTE> 3-wire should be controled by HW when we finish SW 3-wire programming. 2005.08.10, by rcnjko.
33849 + oval3 &= 0xfff8;
33850 +
33851 + write_nic_word(dev, RFPinsEnable, (oval2|0x0007)); // Set To Output Enable
33852 + write_nic_word(dev, RFPinsSelect, (oval3|0x0007)); // Set To SW Switch
33853 + udelay(10);
33854 +
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)
33860 + udelay(2);
33861 + twreg.struc.enableB = 0;
33862 + write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); // Clear SI_EN (RFLE)
33863 + udelay(10);
33864 +
33865 + mask = (low2high)?0x01:((u32)0x01<<(totalLength-1));
33866 +
33867 + for(i=0; i<totalLength/2; i++)
33868 + {
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));
33874 +
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);
33882 + }
33883 +
33884 + twreg.struc.enableB = 1;
33885 + twreg.struc.clk = 0;
33886 + twreg.struc.data = 0;
33887 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval);
33888 + udelay(10);
33889 +
33890 + write_nic_word(dev, RFPinsOutput, oval|0x0004);
33891 + write_nic_word(dev, RFPinsSelect, oval3|0x0000);
33892 +
33893 + SetOutputEnableOfRfPins(dev);
33894 +}
33895 +//by amy
33896 +
33897 +
33898 +int
33899 +HwHSSIThreeWire(
33900 + struct net_device *dev,
33901 + u8 *pDataBuf,
33902 + u8 nDataBufBitCnt,
33903 + int bSI,
33904 + int bWrite
33905 + )
33906 +{
33907 + int bResult = 1;
33908 + u8 TryCnt;
33909 + u8 u1bTmp;
33910 +
33911 + do
33912 + {
33913 + // Check if WE and RE are cleared.
33914 + for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
33915 + {
33916 + u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
33917 + if( (u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0 )
33918 + {
33919 + break;
33920 + }
33921 + udelay(10);
33922 + }
33923 + if (TryCnt == TC_3W_POLL_MAX_TRY_CNT)
33924 + panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp);
33925 +
33926 + // RTL8187S HSSI Read/Write Function
33927 + u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
33928 +
33929 + if(bSI)
33930 + {
33931 + u1bTmp |= RF_SW_CFG_SI; //reg08[1]=1 Serial Interface(SI)
33932 + }else
33933 + {
33934 + u1bTmp &= ~RF_SW_CFG_SI; //reg08[1]=0 Parallel Interface(PI)
33935 + }
33936 +
33937 + write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
33938 +
33939 + if(bSI)
33940 + {
33941 + // jong: HW SI read must set reg84[3]=0.
33942 + u1bTmp = read_nic_byte(dev, RFPinsSelect);
33943 + u1bTmp &= ~BIT3;
33944 + write_nic_byte(dev, RFPinsSelect, u1bTmp );
33945 + }
33946 + // Fill up data buffer for write operation.
33947 +
33948 + if(bWrite)
33949 + {
33950 + if(nDataBufBitCnt == 16)
33951 + {
33952 + write_nic_word(dev, SW_3W_DB0, *((u16*)pDataBuf));
33953 + }
33954 + else if(nDataBufBitCnt == 64) // RTL8187S shouldn't enter this case
33955 + {
33956 + write_nic_dword(dev, SW_3W_DB0, *((u32*)pDataBuf));
33957 + write_nic_dword(dev, SW_3W_DB1, *((u32*)(pDataBuf + 4)));
33958 + }
33959 + else
33960 + {
33961 + int idx;
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",
33966 + nDataBufBitCnt);
33967 +
33968 + if (nDataBufBitCnt > 64)
33969 + panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
33970 + nDataBufBitCnt);
33971 +
33972 + for(idx = 0; idx < ByteCnt; idx++)
33973 + {
33974 + write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
33975 + }
33976 + }
33977 + }
33978 + else //read
33979 + {
33980 + if(bSI)
33981 + {
33982 + // SI - reg274[3:0] : RF register's Address
33983 + write_nic_word(dev, SW_3W_DB0, *((u16*)pDataBuf) );
33984 + }
33985 + else
33986 + {
33987 + // PI - reg274[15:12] : RF register's Address
33988 + write_nic_word(dev, SW_3W_DB0, (*((u16*)pDataBuf)) << 12);
33989 + }
33990 + }
33991 +
33992 + // Set up command: WE or RE.
33993 + if(bWrite)
33994 + {
33995 + write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
33996 + }
33997 + else
33998 + {
33999 + write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
34000 + }
34001 +
34002 + // Check if DONE is set.
34003 + for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
34004 + {
34005 + u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
34006 + if( (u1bTmp & SW_3W_CMD1_DONE) != 0 )
34007 + {
34008 + break;
34009 + }
34010 + udelay(10);
34011 + }
34012 +
34013 + write_nic_byte(dev, SW_3W_CMD1, 0);
34014 +
34015 + // Read back data for read operation.
34016 + if(bWrite == 0)
34017 + {
34018 + if(bSI)
34019 + {
34020 + //Serial Interface : reg363_362[11:0]
34021 + *((u16*)pDataBuf) = read_nic_word(dev, SI_DATA_READ) ;
34022 + }
34023 + else
34024 + {
34025 + //Parallel Interface : reg361_360[11:0]
34026 + *((u16*)pDataBuf) = read_nic_word(dev, PI_DATA_READ);
34027 + }
34028 +
34029 + *((u16*)pDataBuf) &= 0x0FFF;
34030 + }
34031 +
34032 + }while(0);
34033 +
34034 + return bResult;
34035 +}
34036 +//by amy
34037 +
34038 +int
34039 +HwThreeWire(
34040 + struct net_device *dev,
34041 + u8 *pDataBuf,
34042 + u8 nDataBufBitCnt,
34043 + int bHold,
34044 + int bWrite
34045 + )
34046 +{
34047 + int bResult = 1;
34048 + u8 TryCnt;
34049 + u8 u1bTmp;
34050 +
34051 + do
34052 + {
34053 + // Check if WE and RE are cleared.
34054 + for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
34055 + {
34056 + u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
34057 + if( (u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0 )
34058 + {
34059 + break;
34060 + }
34061 + udelay(10);
34062 + }
34063 + if (TryCnt == TC_3W_POLL_MAX_TRY_CNT)
34064 + panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp);
34065 +
34066 + // Fill up data buffer for write operation.
34067 + if(nDataBufBitCnt == 16)
34068 + {
34069 + write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
34070 + }
34071 + else if(nDataBufBitCnt == 64)
34072 + {
34073 + write_nic_dword(dev, SW_3W_DB0, *((u32 *)pDataBuf));
34074 + write_nic_dword(dev, SW_3W_DB1, *((u32 *)(pDataBuf + 4)));
34075 + }
34076 + else
34077 + {
34078 + int idx;
34079 + int ByteCnt = nDataBufBitCnt / 8;
34080 +
34081 + if ((nDataBufBitCnt % 8) != 0)
34082 + panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
34083 + nDataBufBitCnt);
34084 +
34085 + if (nDataBufBitCnt > 64)
34086 + panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
34087 + nDataBufBitCnt);
34088 +
34089 + for(idx = 0; idx < ByteCnt; idx++)
34090 + {
34091 + write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
34092 + }
34093 + }
34094 +
34095 + // Fill up length field.
34096 + u1bTmp = (u8)(nDataBufBitCnt - 1); // Number of bits - 1.
34097 + if(bHold)
34098 + u1bTmp |= SW_3W_CMD0_HOLD;
34099 + write_nic_byte(dev, SW_3W_CMD0, u1bTmp);
34100 +
34101 + // Set up command: WE or RE.
34102 + if(bWrite)
34103 + {
34104 + write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
34105 + }
34106 + else
34107 + {
34108 + write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
34109 + }
34110 +
34111 + // Check if WE and RE are cleared and DONE is set.
34112 + for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
34113 + {
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 )
34117 + {
34118 + break;
34119 + }
34120 + udelay(10);
34121 + }
34122 + if(TryCnt == TC_3W_POLL_MAX_TRY_CNT)
34123 + {
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);
34128 + }
34129 +
34130 + // Read back data for read operation.
34131 + // <RJ_TODO> I am not sure if this is correct output format of a read operation.
34132 + if(bWrite == 0)
34133 + {
34134 + if(nDataBufBitCnt == 16)
34135 + {
34136 + *((u16 *)pDataBuf) = read_nic_word(dev, SW_3W_DB0);
34137 + }
34138 + else if(nDataBufBitCnt == 64)
34139 + {
34140 + *((u32 *)pDataBuf) = read_nic_dword(dev, SW_3W_DB0);
34141 + *((u32 *)(pDataBuf + 4)) = read_nic_dword(dev, SW_3W_DB1);
34142 + }
34143 + else
34144 + {
34145 + int idx;
34146 + int ByteCnt = nDataBufBitCnt / 8;
34147 +
34148 + if ((nDataBufBitCnt % 8) != 0)
34149 + panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
34150 + nDataBufBitCnt);
34151 +
34152 + if (nDataBufBitCnt > 64)
34153 + panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
34154 + nDataBufBitCnt);
34155 +
34156 + for(idx = 0; idx < ByteCnt; idx++)
34157 + {
34158 + *(pDataBuf+idx) = read_nic_byte(dev, (SW_3W_DB0+idx));
34159 + }
34160 + }
34161 + }
34162 +
34163 + }while(0);
34164 +
34165 + return bResult;
34166 +}
34167 +
34168 +
34169 +void
34170 +RF_WriteReg(
34171 + struct net_device *dev,
34172 + u8 offset,
34173 + u32 data
34174 + )
34175 +{
34176 + //RFReg reg;
34177 + u32 data2Write;
34178 + u8 len;
34179 + u8 low2high;
34180 + //u32 RF_Read = 0;
34181 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
34182 +
34183 +
34184 + switch(priv->rf_chip)
34185 + {
34186 + case RFCHIPID_RTL8225:
34187 + case RF_ZEBRA2: // Annie 2006-05-12.
34188 + case RF_ZEBRA4: //by amy
34189 + switch(priv->RegThreeWireMode)
34190 + {
34191 + case SW_THREE_WIRE:
34192 + { // Perform SW 3-wire programming by driver.
34193 + data2Write = (data << 4) | (u32)(offset & 0x0f);
34194 + len = 16;
34195 + low2high = 0;
34196 + ZEBRA_RFSerialWrite(dev, data2Write, len, low2high);
34197 + }
34198 + break;
34199 +
34200 + case HW_THREE_WIRE:
34201 + { // Pure HW 3-wire.
34202 + data2Write = (data << 4) | (u32)(offset & 0x0f);
34203 + len = 16;
34204 + HwThreeWire(
34205 + dev,
34206 + (u8 *)(&data2Write), // pDataBuf,
34207 + len, // nDataBufBitCnt,
34208 + 0, // bHold,
34209 + 1); // bWrite
34210 + }
34211 + break;
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);
34216 + len = 16;
34217 + HwHSSIThreeWire(
34218 + dev,
34219 + (u8*)(&data2Write), // pDataBuf,
34220 + len, // nDataBufBitCnt,
34221 + 0, // bSI
34222 + 1); // bWrite
34223 +
34224 + //printk("33333\n");
34225 + }
34226 + break;
34227 +
34228 + case HW_THREE_WIRE_SI: //Serial Interface
34229 + { // Pure HW 3-wire.
34230 + data2Write = (data << 4) | (u32)(offset & 0x0f);
34231 + len = 16;
34232 +// printk(" enter ZEBRA_RFSerialWrite\n ");
34233 +// low2high = 0;
34234 +// ZEBRA_RFSerialWrite(dev, data2Write, len, low2high);
34235 +
34236 + HwHSSIThreeWire(
34237 + dev,
34238 + (u8*)(&data2Write), // pDataBuf,
34239 + len, // nDataBufBitCnt,
34240 + 1, // bSI
34241 + 1); // bWrite
34242 +
34243 +// printk(" exit ZEBRA_RFSerialWrite\n ");
34244 + }
34245 + break;
34246 + #endif
34247 +
34248 +
34249 + default:
34250 + DMESGE("RF_WriteReg(): invalid RegThreeWireMode(%d) !!!", priv->RegThreeWireMode);
34251 + break;
34252 + }
34253 + break;
34254 +
34255 + default:
34256 + DMESGE("RF_WriteReg(): unknown RFChipID: %#X", priv->rf_chip);
34257 + break;
34258 + }
34259 +}
34260 +
34261 +
34262 +void
34263 +ZEBRA_RFSerialRead(
34264 + struct net_device *dev,
34265 + u32 data2Write,
34266 + u8 wLength,
34267 + u32 *data2Read,
34268 + u8 rLength,
34269 + u8 low2high
34270 + )
34271 +{
34272 + ThreeWireReg twreg;
34273 + int i;
34274 + u16 oval,oval2,oval3,tmp, wReg80;
34275 + u32 mask;
34276 + u8 u1bTmp;
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);
34284 + }
34285 +#endif
34286 +
34287 + wReg80 = oval = read_nic_word(dev, RFPinsOutput);
34288 + oval2 = read_nic_word(dev, RFPinsEnable);
34289 + oval3 = read_nic_word(dev, RFPinsSelect);
34290 +
34291 + write_nic_word(dev, RFPinsEnable, oval2|0xf);
34292 + write_nic_word(dev, RFPinsSelect, oval3|0xf);
34293 +
34294 + *data2Read = 0;
34295 +
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.
34299 + oval &= ~0xf;
34300 +
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);
34305 +
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);
34311 +
34312 + mask = (low2high) ? 0x01 : ((u32)0x01<<(32-1));
34313 + for(i = 0; i < wLength/2; i++)
34314 + {
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);
34320 +
34321 + mask = (low2high) ? (mask<<1): (mask>>1);
34322 +
34323 + if(i == 2)
34324 + {
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);
34328 +
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);
34333 + break;
34334 + }
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);
34338 +
34339 + twreg.struc.clk = 0;
34340 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1);
34341 +
34342 + mask = (low2high) ? (mask<<1) : (mask>>1);
34343 + }
34344 +
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));
34349 +
34350 + //
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.
34354 + //
34355 + write_nic_word(dev, RFPinsEnable, ( ((oval2|0x0E) & (~0x01))) );
34356 +
34357 + for(i = 0; i < rLength; i++)
34358 + {
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;
34367 +
34368 + twreg.struc.clk = 0;
34369 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
34370 +
34371 + mask = (low2high) ? (mask<<1) : (mask>>1);
34372 + }
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);
34378 +
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);
34386 +}
34387 +
34388 +
34389 +u32
34390 +RF_ReadReg(
34391 + struct net_device *dev,
34392 + u8 offset
34393 + )
34394 +{
34395 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
34396 + u32 data2Write;
34397 + u8 wlen;
34398 + u8 rlen;
34399 + u8 low2high;
34400 + u32 dataRead;
34401 +
34402 + switch(priv->rf_chip)
34403 + {
34404 + case RFCHIPID_RTL8225:
34405 + case RF_ZEBRA2:
34406 + case RF_ZEBRA4:
34407 + switch(priv->RegThreeWireMode)
34408 + {
34409 +#ifdef CONFIG_RTL818X_S
34410 + case HW_THREE_WIRE_PI: // For 87S Parallel Interface.
34411 + {
34412 + data2Write = ((u32)(offset&0x0f));
34413 + wlen=16;
34414 + HwHSSIThreeWire(
34415 + dev,
34416 + (u8*)(&data2Write), // pDataBuf,
34417 + wlen, // nDataBufBitCnt,
34418 + 0, // bSI
34419 + 0); // bWrite
34420 + dataRead= data2Write;
34421 + }
34422 + break;
34423 +
34424 + case HW_THREE_WIRE_SI: // For 87S Serial Interface.
34425 + {
34426 + data2Write = ((u32)(offset&0x0f)) ;
34427 + wlen=16;
34428 + HwHSSIThreeWire(
34429 + dev,
34430 + (u8*)(&data2Write), // pDataBuf,
34431 + wlen, // nDataBufBitCnt,
34432 + 1, // bSI
34433 + 0 // bWrite
34434 + );
34435 + dataRead= data2Write;
34436 + }
34437 + break;
34438 +
34439 +#endif
34440 + // Perform SW 3-wire programming by driver.
34441 + default:
34442 + {
34443 + data2Write = ((u32)(offset&0x1f)) << 27; // For Zebra E-cut. 2005.04.11, by rcnjko.
34444 + wlen = 6;
34445 + rlen = 12;
34446 + low2high = 0;
34447 + ZEBRA_RFSerialRead(dev, data2Write, wlen,&dataRead,rlen, low2high);
34448 + }
34449 + break;
34450 + }
34451 + break;
34452 + default:
34453 + dataRead = 0;
34454 + break;
34455 + }
34456 +
34457 + return dataRead;
34458 +}
34459 +
34460 +
34461 +// by Owen on 04/07/14 for writing BB register successfully
34462 +void
34463 +WriteBBPortUchar(
34464 + struct net_device *dev,
34465 + u32 Data
34466 + )
34467 +{
34468 + //u8 TimeoutCounter;
34469 + u8 RegisterContent;
34470 + u8 UCharData;
34471 +
34472 + UCharData = (u8)((Data & 0x0000ff00) >> 8);
34473 + PlatformIOWrite4Byte(dev, PhyAddr, Data);
34474 + //for(TimeoutCounter = 10; TimeoutCounter > 0; TimeoutCounter--)
34475 + {
34476 + PlatformIOWrite4Byte(dev, PhyAddr, Data & 0xffffff7f);
34477 + RegisterContent = PlatformIORead1Byte(dev, PhyDataR);
34478 + //if(UCharData == RegisterContent)
34479 + // break;
34480 + }
34481 +}
34482 +
34483 +u8
34484 +ReadBBPortUchar(
34485 + struct net_device *dev,
34486 + u32 addr
34487 + )
34488 +{
34489 + //u8 TimeoutCounter;
34490 + u8 RegisterContent;
34491 +
34492 + PlatformIOWrite4Byte(dev, PhyAddr, addr & 0xffffff7f);
34493 + RegisterContent = PlatformIORead1Byte(dev, PhyDataR);
34494 +
34495 + return RegisterContent;
34496 +}
34497 +//{by amy 080312
34498 +#ifdef CONFIG_RTL818X_S
34499 +//
34500 +// Description:
34501 +// Perform Antenna settings with antenna diversity on 87SE.
34502 +// Created by Roger, 2008.01.25.
34503 +//
34504 +bool
34505 +SetAntennaConfig87SE(
34506 + struct net_device *dev,
34507 + u8 DefaultAnt, // 0: Main, 1: Aux.
34508 + bool bAntDiversity // 1:Enable, 0: Disable.
34509 +)
34510 +{
34511 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
34512 + bool bAntennaSwitched = true;
34513 +
34514 + //printk("SetAntennaConfig87SE(): DefaultAnt(%d), bAntDiversity(%d)\n", DefaultAnt, bAntDiversity);
34515 +
34516 + // Threshold for antenna diversity.
34517 + write_phy_cck(dev, 0x0c, 0x09); // Reg0c : 09
34518 +
34519 + if( bAntDiversity ) // Enable Antenna Diversity.
34520 + {
34521 + if( DefaultAnt == 1 ) // aux antenna
34522 + {
34523 + // Mac register, aux antenna
34524 + write_nic_byte(dev, ANTSEL, 0x00);
34525 +
34526 + // Config CCK RX antenna.
34527 + write_phy_cck(dev, 0x11, 0xbb); // Reg11 : bb
34528 + write_phy_cck(dev, 0x01, 0xc7); // Reg01 : c7
34529 +
34530 + // Config OFDM RX antenna.
34531 + write_phy_ofdm(dev, 0x0D, 0x54); // Reg0d : 54
34532 + write_phy_ofdm(dev, 0x18, 0xb2); // Reg18 : b2
34533 + }
34534 + else // use main antenna
34535 + {
34536 + // Mac register, main antenna
34537 + write_nic_byte(dev, ANTSEL, 0x03);
34538 + //base band
34539 + // Config CCK RX antenna.
34540 + write_phy_cck(dev, 0x11, 0x9b); // Reg11 : 9b
34541 + write_phy_cck(dev, 0x01, 0xc7); // Reg01 : c7
34542 +
34543 + // Config OFDM RX antenna.
34544 + write_phy_ofdm(dev, 0x0d, 0x5c); // Reg0d : 5c
34545 + write_phy_ofdm(dev, 0x18, 0xb2); // Reg18 : b2
34546 + }
34547 + }
34548 + else // Disable Antenna Diversity.
34549 + {
34550 + if( DefaultAnt == 1 ) // aux Antenna
34551 + {
34552 + // Mac register, aux antenna
34553 + write_nic_byte(dev, ANTSEL, 0x00);
34554 +
34555 + // Config CCK RX antenna.
34556 + write_phy_cck(dev, 0x11, 0xbb); // Reg11 : bb
34557 + write_phy_cck(dev, 0x01, 0x47); // Reg01 : 47
34558 +
34559 + // Config OFDM RX antenna.
34560 + write_phy_ofdm(dev, 0x0D, 0x54); // Reg0d : 54
34561 + write_phy_ofdm(dev, 0x18, 0x32); // Reg18 : 32
34562 + }
34563 + else // main Antenna
34564 + {
34565 + // Mac register, main antenna
34566 + write_nic_byte(dev, ANTSEL, 0x03);
34567 +
34568 + // Config CCK RX antenna.
34569 + write_phy_cck(dev, 0x11, 0x9b); // Reg11 : 9b
34570 + write_phy_cck(dev, 0x01, 0x47); // Reg01 : 47
34571 +
34572 + // Config OFDM RX antenna.
34573 + write_phy_ofdm(dev, 0x0D, 0x5c); // Reg0d : 5c
34574 + write_phy_ofdm(dev, 0x18, 0x32); // Reg18 : 32
34575 + }
34576 + }
34577 + priv->CurrAntennaIndex = DefaultAnt; // Update default settings.
34578 + return bAntennaSwitched;
34579 +}
34580 +#endif
34581 +//by amy 080312
34582 +/*---------------------------------------------------------------
34583 + * Hardware Initialization.
34584 + * the code is ported from Windows source code
34585 + ----------------------------------------------------------------*/
34586 +
34587 +void
34588 +ZEBRA_Config_85BASIC_HardCode(
34589 + struct net_device *dev
34590 + )
34591 +{
34592 +
34593 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
34594 + u32 i;
34595 + u32 addr,data;
34596 + u32 u4bRegOffset, u4bRegValue, u4bRF23, u4bRF24;
34597 + u8 u1b24E;
34598 +
34599 +#ifdef CONFIG_RTL818X_S
34600 +
34601 + //=============================================================================
34602 + // 87S_PCIE :: RADIOCFG.TXT
34603 + //=============================================================================
34604 +
34605 +
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);
34610 +
34611 + if (u4bRF23==0x818 && u4bRF24==0x70C && priv->card_8185 == VERSION_8187S_C)
34612 + priv->card_8185 = VERSION_8187S_D;
34613 +
34614 + // Page0 : reg0-reg15
34615 +
34616 +// RF_WriteReg(dev, 0x00, 0x003f); mdelay(1);//1
34617 + RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);// 1
34618 +
34619 + RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1);
34620 +
34621 +// RF_WriteReg(dev, 0x02, 0x004c); mdelay(1);//2
34622 + RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);// 2
34623 +
34624 +// RF_WriteReg(dev, 0x03, 0x0000); mdelay(1);//3
34625 + RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);// 3
34626 +
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);
34639 +
34640 +
34641 + // Page1 : reg16-reg30
34642 + RF_WriteReg(dev, 0x00, 0x013f); mdelay(1);
34643 +
34644 + RF_WriteReg(dev, 0x03, 0x0806); mdelay(1);
34645 +
34646 + if(priv->card_8185 < VERSION_8187S_C)
34647 + {
34648 + RF_WriteReg(dev, 0x04, 0x03f7); mdelay(1);
34649 + RF_WriteReg(dev, 0x05, 0x05ab); mdelay(1);
34650 + RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1);
34651 + }
34652 + else
34653 + {
34654 + RF_WriteReg(dev, 0x04, 0x03a7); mdelay(1);
34655 + RF_WriteReg(dev, 0x05, 0x059b); mdelay(1);
34656 + RF_WriteReg(dev, 0x06, 0x0081); mdelay(1);
34657 + }
34658 +
34659 +
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);
34666 +
34667 + if(priv->card_8185 == VERSION_8187S_D)
34668 + {
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
34672 + }
34673 + else
34674 + {
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
34678 + }
34679 +
34680 + RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
34681 +
34682 +// RF_WriteReg(dev, 0x00, 0x017f); mdelay(1);//6
34683 + RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1);// 6
34684 +
34685 + RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1);
34686 + RF_WriteReg(dev, 0x04, 0x0e50); mdelay(1);
34687 + for(i=0;i<=36;i++)
34688 + {
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]);
34692 + }
34693 +
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
34697 +
34698 + RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); // switch to reg16-reg30, and HSSI disable 137
34699 + mdelay(10); // Deay 10 ms. //0xfd
34700 +
34701 +// RF_WriteReg(dev, 0x0c, 0x09be); mdelay(1); // 7
34702 + //RF_WriteReg(dev, 0x0c, 0x07be); mdelay(1);
34703 + //mdelay(10); // Deay 10 ms. //0xfd
34704 +
34705 + RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); // Z4 synthesizer loop filter setting, 392
34706 + mdelay(10); // Deay 10 ms. //0xfd
34707 +
34708 + RF_WriteReg(dev, 0x00, 0x0037); mdelay(1); // switch to reg0-reg15, and HSSI disable
34709 + mdelay(10); // Deay 10 ms. //0xfd
34710 +
34711 + RF_WriteReg(dev, 0x04, 0x0160); mdelay(1); // CBC on, Tx Rx disable, High gain
34712 + mdelay(10); // Deay 10 ms. //0xfd
34713 +
34714 + RF_WriteReg(dev, 0x07, 0x0080); mdelay(1); // Z4 setted channel 1
34715 + mdelay(10); // Deay 10 ms. //0xfd
34716 +
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
34721 +
34722 + RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); // switch to reg16-reg30 137, and HSSI disable 137
34723 + mdelay(10); // Deay 10 ms. //0xfd
34724 +
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);
34729 +
34730 + // DAC calibration off 20070702
34731 + RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1);
34732 + RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
34733 +//{by amy 080312
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);
34744 + }
34745 + else
34746 + { // using default value. Xin=6, Xout=6.
34747 + RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
34748 + }
34749 +//by amy 080312
34750 +// RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); //-by amy 080312
34751 +
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
34763 +
34764 +#if 0//-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);
34768 +#endif
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))));
34774 +
34775 + //=============================================================================
34776 +
34777 + //=============================================================================
34778 + // CCKCONF.TXT
34779 + //=============================================================================
34780 +
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
34787 + */
34788 +#if 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);
34795 +#endif
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);
34802 +
34803 + // power control
34804 + write_nic_byte(dev, CCK_TXAGC, 0x10);
34805 + write_nic_byte(dev, OFDM_TXAGC, 0x1B);
34806 + write_nic_byte(dev, ANTSEL, 0x03);
34807 +#else
34808 + //=============================================================================
34809 + // RADIOCFG.TXT
34810 + //=============================================================================
34811 +
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);
34828 +
34829 + RF_WriteReg(dev, 0x00, 0x01b7); mdelay(1);
34830 +
34831 +
34832 + for(i=1;i<=95;i++)
34833 + {
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]);
34837 + }
34838 +
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
34842 + //0xfd
34843 + //0xfd
34844 + //0xfd
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
34850 +
34851 + //=============================================================================
34852 +
34853 + //=============================================================================
34854 + // CCKCONF.TXT
34855 + //=============================================================================
34856 +
34857 + //=============================================================================
34858 +
34859 + //=============================================================================
34860 + // Follow WMAC RTL8225_Config()
34861 + //=============================================================================
34862 +
34863 + // power control
34864 + write_nic_byte(dev, CCK_TXAGC, 0x03);
34865 + write_nic_byte(dev, OFDM_TXAGC, 0x07);
34866 + write_nic_byte(dev, ANTSEL, 0x03);
34867 +
34868 + //=============================================================================
34869 +
34870 + // OFDM BBP setup
34871 +// SetOutputEnableOfRfPins(dev);//by amy
34872 +#endif
34873 +
34874 +
34875 +
34876 + //=============================================================================
34877 + // AGC.txt
34878 + //=============================================================================
34879 +
34880 +// PlatformIOWrite4Byte( dev, PhyAddr, 0x00001280); // Annie, 2006-05-05
34881 + write_phy_ofdm(dev, 0x00, 0x12);
34882 + //WriteBBPortUchar(dev, 0x00001280);
34883 +
34884 + for (i=0; i<128; i++)
34885 + {
34886 + //DbgPrint("AGC - [%x+1] = 0x%x\n", i, ZEBRA_AGC[i+1]);
34887 +
34888 + data = ZEBRA_AGC[i+1];
34889 + data = data << 8;
34890 + data = data | 0x0000008F;
34891 +
34892 + addr = i + 0x80; //enable writing AGC table
34893 + addr = addr << 8;
34894 + addr = addr | 0x0000008E;
34895 +
34896 + WriteBBPortUchar(dev, data);
34897 + WriteBBPortUchar(dev, addr);
34898 + WriteBBPortUchar(dev, 0x0000008E);
34899 + }
34900 +
34901 + PlatformIOWrite4Byte( dev, PhyAddr, 0x00001080); // Annie, 2006-05-05
34902 + //WriteBBPortUchar(dev, 0x00001080);
34903 +
34904 + //=============================================================================
34905 +
34906 + //=============================================================================
34907 + // OFDMCONF.TXT
34908 + //=============================================================================
34909 +
34910 + for(i=0; i<60; i++)
34911 + {
34912 + u4bRegOffset=i;
34913 + u4bRegValue=OFDM_CONFIG[i];
34914 +
34915 + //DbgPrint("OFDM - 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue);
34916 +
34917 + WriteBBPortUchar(dev,
34918 + (0x00000080 |
34919 + (u4bRegOffset & 0x7f) |
34920 + ((u4bRegValue & 0xff) << 8)));
34921 + }
34922 +
34923 + //=============================================================================
34924 +//by amy for antenna
34925 + //=============================================================================
34926 +//{by amy 080312
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);
34930 +#endif
34931 +//by amy 080312}
34932 +#if 0
34933 + // Config Sw/Hw Antenna Diversity
34934 + if( priv->bSwAntennaDiverity ) // Use SW+Hw Antenna Diversity
34935 + {
34936 + if( priv->bDefaultAntenna1 == true ) // aux antenna
34937 + {
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
34947 + }
34948 + else // main antenna
34949 + {
34950 + // Mac register, main antenna
34951 + write_nic_byte(dev, ANTSEL, 0x03);
34952 + //base band
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
34960 + }
34961 + }
34962 + else // Disable Antenna Diversity
34963 + {
34964 + if( priv->bDefaultAntenna1 == true ) // aux Antenna
34965 + {
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
34975 + }
34976 + else // main Antenna
34977 + {
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
34987 + }
34988 + }
34989 +#endif
34990 +//by amy for antenna
34991 +}
34992 +
34993 +
34994 +void
34995 +UpdateInitialGain(
34996 + struct net_device *dev
34997 + )
34998 +{
34999 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35000 + //unsigned char* IGTable;
35001 + //u8 DIG_CurrentInitialGain = 4;
35002 + //unsigned char u1Tmp;
35003 +
35004 + //lzm add 080826
35005 + if(priv->eRFPowerState != eRfOn)
35006 + {
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;
35011 + return;
35012 + }
35013 +
35014 + switch(priv->rf_chip)
35015 + {
35016 +#if 0
35017 + case RF_ZEBRA2:
35018 + // Dynamic set initial gain, by shien chang, 2006.07.14
35019 + switch(priv->InitialGain)
35020 + {
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);
35026 + break;
35027 +
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);
35033 + break;
35034 +
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);
35040 + break;
35041 +
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);
35047 + break;
35048 +
35049 + case 5: //m82dBm
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);
35054 + break;
35055 +
35056 + case 6: //m78dBm
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);
35061 + break;
35062 +
35063 + case 7: //m74dBm
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);
35068 + break;
35069 +
35070 + default: //MP
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);
35075 + break;
35076 + }
35077 + break;
35078 +#endif
35079 + case RF_ZEBRA4:
35080 + // Dynamic set initial gain, follow 87B
35081 + switch(priv->InitialGain)
35082 + {
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);
35088 + break;
35089 +
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);
35095 + break;
35096 +
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);
35102 + break;
35103 +
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);
35109 + break;
35110 +
35111 + case 5: //m82dBm
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);
35116 + break;
35117 +
35118 + case 6: //m78dBm
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);
35123 + break;
35124 +
35125 + case 7: //m74dBm
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);
35130 + break;
35131 +
35132 + case 8:
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);
35137 + break;
35138 +
35139 +
35140 + default: //MP
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);
35145 + break;
35146 + }
35147 + break;
35148 +
35149 +
35150 + default:
35151 + DMESG("UpdateInitialGain(): unknown RFChipID: %#X\n", priv->rf_chip);
35152 + break;
35153 + }
35154 +}
35155 +#ifdef CONFIG_RTL818X_S
35156 +//
35157 +// Description:
35158 +// Tx Power tracking mechanism routine on 87SE.
35159 +// Created by Roger, 2007.12.11.
35160 +//
35161 +void
35162 +InitTxPwrTracking87SE(
35163 + struct net_device *dev
35164 +)
35165 +{
35166 + //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35167 + u32 u4bRfReg;
35168 +
35169 + u4bRfReg = RF_ReadReg(dev, 0x02);
35170 +
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);
35174 +}
35175 +
35176 +#endif
35177 +void
35178 +PhyConfig8185(
35179 + struct net_device *dev
35180 + )
35181 +{
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;
35185 + // RF config
35186 + switch(priv->rf_chip)
35187 + {
35188 + case RF_ZEBRA2:
35189 + case RF_ZEBRA4:
35190 + ZEBRA_Config_85BASIC_HardCode( dev);
35191 + break;
35192 + }
35193 +//{by amy 080312
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)
35197 + {
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);
35201 + }
35202 +
35203 + //
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.
35207 + //
35208 + if(priv->bTxPowerTrack)
35209 + InitTxPwrTracking87SE(dev);
35210 +
35211 +#endif
35212 +//by amy 080312}
35213 + priv->InitialGainBackUp= priv->InitialGain;
35214 + UpdateInitialGain(dev);
35215 +
35216 + return;
35217 +}
35218 +
35219 +
35220 +
35221 +
35222 +void
35223 +HwConfigureRTL8185(
35224 + struct net_device *dev
35225 + )
35226 +{
35227 + //RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control.
35228 +// u8 bUNIVERSAL_CONTROL_RL = 1;
35229 + u8 bUNIVERSAL_CONTROL_RL = 0;
35230 +
35231 + u8 bUNIVERSAL_CONTROL_AGC = 1;
35232 + u8 bUNIVERSAL_CONTROL_ANT = 1;
35233 + u8 bAUTO_RATE_FALLBACK_CTL = 1;
35234 + u8 val8;
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))
35239 +// {
35240 +// write_nic_word(dev, BRSR, 0xffff);
35241 +// }
35242 +// else
35243 +// {
35244 +// write_nic_word(dev, BRSR, 0x000f);
35245 +// }
35246 +//by amy 080312}
35247 + write_nic_word(dev, BRSR, 0x0fff);
35248 + // Retry limit
35249 + val8 = read_nic_byte(dev, CW_CONF);
35250 +
35251 + if(bUNIVERSAL_CONTROL_RL)
35252 + val8 = val8 & 0xfd;
35253 + else
35254 + val8 = val8 | 0x02;
35255 +
35256 + write_nic_byte(dev, CW_CONF, val8);
35257 +
35258 + // Tx AGC
35259 + val8 = read_nic_byte(dev, TXAGC_CTL);
35260 + if(bUNIVERSAL_CONTROL_AGC)
35261 + {
35262 + write_nic_byte(dev, CCK_TXAGC, 128);
35263 + write_nic_byte(dev, OFDM_TXAGC, 128);
35264 + val8 = val8 & 0xfe;
35265 + }
35266 + else
35267 + {
35268 + val8 = val8 | 0x01 ;
35269 + }
35270 +
35271 +
35272 + write_nic_byte(dev, TXAGC_CTL, val8);
35273 +
35274 + // Tx Antenna including Feedback control
35275 + val8 = read_nic_byte(dev, TXAGC_CTL );
35276 +
35277 + if(bUNIVERSAL_CONTROL_ANT)
35278 + {
35279 + write_nic_byte(dev, ANTSEL, 0x00);
35280 + val8 = val8 & 0xfd;
35281 + }
35282 + else
35283 + {
35284 + val8 = val8 & (val8|0x02); //xiong-2006-11-15
35285 + }
35286 +
35287 + write_nic_byte(dev, TXAGC_CTL, val8);
35288 +
35289 + // Auto Rate fallback control
35290 + val8 = read_nic_byte(dev, RATE_FALLBACK);
35291 + val8 &= 0x7c;
35292 + if( bAUTO_RATE_FALLBACK_CTL )
35293 + {
35294 + val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1;
35295 +
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
35298 +//by amy
35299 +#if 0
35300 + PlatformIOWrite2Byte(dev, ARFR, 0x0fff); // set 1M ~ 54M
35301 +#endif
35302 +#ifdef CONFIG_RTL818X_S
35303 + // Aadded by Roger, 2007.11.15.
35304 + PlatformIOWrite2Byte(dev, ARFR, 0x0fff); //set 1M ~ 54Mbps.
35305 +#else
35306 + PlatformIOWrite2Byte(dev, ARFR, 0x0c00); //set 48Mbps, 54Mbps.
35307 + // By SD3 szuyi's request. by Roger, 2007.03.26.
35308 +#endif
35309 +//by amy
35310 + }
35311 + else
35312 + {
35313 + }
35314 + write_nic_byte(dev, RATE_FALLBACK, val8);
35315 +}
35316 +
35317 +
35318 +
35319 +static void
35320 +MacConfig_85BASIC_HardCode(
35321 + struct net_device *dev)
35322 +{
35323 + //============================================================================
35324 + // MACREG.TXT
35325 + //============================================================================
35326 + int nLinesRead = 0;
35327 +
35328 + u32 u4bRegOffset, u4bRegValue,u4bPageIndex = 0;
35329 + int i;
35330 +
35331 + nLinesRead=sizeof(MAC_REG_TABLE)/2;
35332 +
35333 + for(i = 0; i < nLinesRead; i++) //nLinesRead=101
35334 + {
35335 + u4bRegOffset=MAC_REG_TABLE[i][0];
35336 + u4bRegValue=MAC_REG_TABLE[i][1];
35337 +
35338 + if(u4bRegOffset == 0x5e)
35339 + {
35340 + u4bPageIndex = u4bRegValue;
35341 + }
35342 + else
35343 + {
35344 + u4bRegOffset |= (u4bPageIndex << 8);
35345 + }
35346 + //DbgPrint("MAC - 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue);
35347 + write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
35348 + }
35349 + //============================================================================
35350 +}
35351 +
35352 +
35353 +
35354 +static void
35355 +MacConfig_85BASIC(
35356 + struct net_device *dev)
35357 +{
35358 +
35359 + u8 u1DA;
35360 + MacConfig_85BASIC_HardCode(dev);
35361 +
35362 + //============================================================================
35363 +
35364 + // Follow TID_AC_MAP of WMac.
35365 + write_nic_word(dev, TID_AC_MAP, 0xfa50);
35366 +
35367 + // Interrupt Migration, Jong suggested we use set 0x0000 first, 2005.12.14, by rcnjko.
35368 + write_nic_word(dev, IntMig, 0x0000);
35369 +
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);
35374 +
35375 + // Asked for by SD3 CM Lin, 2006.06.27, by rcnjko.
35376 + //PlatformIOWrite4Byte(dev, RFTiming, 0x00004001);
35377 +//by amy
35378 +#if 0
35379 + write_nic_dword(dev, RFTiming, 0x00004001);
35380 +#endif
35381 +#ifdef CONFIG_RTL818X_S
35382 + // power save parameter based on "87SE power save parameters 20071127.doc", as follow.
35383 +
35384 + //Enable DA10 TX power saving
35385 + u1DA = read_nic_byte(dev, PHYPR);
35386 + write_nic_byte(dev, PHYPR, (u1DA | BIT2) );
35387 +
35388 + //POWER:
35389 + write_nic_word(dev, 0x360, 0x1000);
35390 + write_nic_word(dev, 0x362, 0x1000);
35391 +
35392 + // AFE.
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
35402 +#else
35403 + write_nic_dword(dev, RFTiming, 0x00004003);
35404 +#endif
35405 + write_nic_byte(dev, 0x24E,0x01);
35406 +//by amy
35407 +
35408 +}
35409 +
35410 +
35411 +
35412 +
35413 +u8
35414 +GetSupportedWirelessMode8185(
35415 + struct net_device *dev
35416 +)
35417 +{
35418 + u8 btSupportedWirelessMode = 0;
35419 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35420 +
35421 + switch(priv->rf_chip)
35422 + {
35423 + case RF_ZEBRA2:
35424 + case RF_ZEBRA4:
35425 + btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
35426 + break;
35427 + default:
35428 + btSupportedWirelessMode = WIRELESS_MODE_B;
35429 + break;
35430 + }
35431 +
35432 + return btSupportedWirelessMode;
35433 +}
35434 +
35435 +void
35436 +ActUpdateChannelAccessSetting(
35437 + struct net_device *dev,
35438 + WIRELESS_MODE WirelessMode,
35439 + PCHANNEL_ACCESS_SETTING ChnlAccessSetting
35440 + )
35441 +{
35442 + struct r8180_priv *priv = ieee80211_priv(dev);
35443 + struct ieee80211_device *ieee = priv->ieee80211;
35444 + AC_CODING eACI;
35445 + AC_PARAM AcParam;
35446 + //PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos;
35447 + u8 bFollowLegacySetting = 0;
35448 + u8 u1bAIFS;
35449 +
35450 + //
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.
35454 + //
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.
35459 + //
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.
35466 +
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.
35470 +
35471 + u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer );
35472 +
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);
35477 +
35478 + write_nic_byte(dev, EIFS, ChnlAccessSetting->EIFS_Timer);
35479 +
35480 + write_nic_byte(dev, AckTimeOutReg, 0x5B); // <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS register, 2005.12.08.
35481 +
35482 +#ifdef TODO
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 )
35485 + { // QoS mode.
35486 + if(pStaQos->QBssWirelessMode == WirelessMode)
35487 + {
35488 + // Follow AC Parameters of the QBSS.
35489 + for(eACI = 0; eACI < AC_MAX; eACI++)
35490 + {
35491 + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) );
35492 + }
35493 + }
35494 + else
35495 + {
35496 + // Follow Default WMM AC Parameters.
35497 + bFollowLegacySetting = 1;
35498 + }
35499 + }
35500 + else
35501 +#endif
35502 + { // Legacy 802.11.
35503 + bFollowLegacySetting = 1;
35504 +
35505 + }
35506 +
35507 + // this setting is copied from rtl8187B. xiong-2006-11-13
35508 + if(bFollowLegacySetting)
35509 + {
35510 +
35511 +
35512 + //
35513 + // Follow 802.11 seeting to AC parameter, all AC shall use the same parameter.
35514 + // 2005.12.01, by rcnjko.
35515 + //
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;
35522 +
35523 + //lzm reserved 080826
35524 +#if 1
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;
35529 +#endif
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;
35533 +#endif
35534 +
35535 + for(eACI = 0; eACI < AC_MAX; eACI++)
35536 + {
35537 + AcParam.f.AciAifsn.f.ACI = (u8)eACI;
35538 + {
35539 + PAC_PARAM pAcParam = (PAC_PARAM)(&AcParam);
35540 + AC_CODING eACI;
35541 + u8 u1bAIFS;
35542 + u32 u4bAcParam;
35543 +
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));
35551 +
35552 + switch(eACI)
35553 + {
35554 + case AC1_BK:
35555 + //write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
35556 + break;
35557 +
35558 + case AC0_BE:
35559 + //write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
35560 + break;
35561 +
35562 + case AC2_VI:
35563 + //write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
35564 + break;
35565 +
35566 + case AC3_VO:
35567 + //write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
35568 + break;
35569 +
35570 + default:
35571 + DMESGW( "SetHwReg8185(): invalid ACI: %d !\n", eACI);
35572 + break;
35573 + }
35574 +
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);
35578 + {
35579 + PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn);
35580 + AC_CODING eACI = pAciAifsn->f.ACI;
35581 +
35582 + //modified Joseph
35583 + //for 8187B AsynIORead issue
35584 +#ifdef TODO
35585 + u8 AcmCtrl = pHalData->AcmControl;
35586 +#else
35587 + u8 AcmCtrl = 0;
35588 +#endif
35589 + if( pAciAifsn->f.ACM )
35590 + { // ACM bit is 1.
35591 + switch(eACI)
35592 + {
35593 + case AC0_BE:
35594 + AcmCtrl |= (BEQ_ACM_EN|BEQ_ACM_CTL|ACM_HW_EN); // or 0x21
35595 + break;
35596 +
35597 + case AC2_VI:
35598 + AcmCtrl |= (VIQ_ACM_EN|VIQ_ACM_CTL|ACM_HW_EN); // or 0x42
35599 + break;
35600 +
35601 + case AC3_VO:
35602 + AcmCtrl |= (VOQ_ACM_EN|VOQ_ACM_CTL|ACM_HW_EN); // or 0x84
35603 + break;
35604 +
35605 + default:
35606 + DMESGW("SetHwReg8185(): [HW_VAR_ACM_CTRL] ACM set failed: eACI is %d\n", eACI );
35607 + break;
35608 + }
35609 + }
35610 + else
35611 + { // ACM bit is 0.
35612 + switch(eACI)
35613 + {
35614 + case AC0_BE:
35615 + AcmCtrl &= ( (~BEQ_ACM_EN) & (~BEQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0xDE
35616 + break;
35617 +
35618 + case AC2_VI:
35619 + AcmCtrl &= ( (~VIQ_ACM_EN) & (~VIQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0xBD
35620 + break;
35621 +
35622 + case AC3_VO:
35623 + AcmCtrl &= ( (~VOQ_ACM_EN) & (~VOQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0x7B
35624 + break;
35625 +
35626 + default:
35627 + break;
35628 + }
35629 + }
35630 +
35631 + //printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
35632 +
35633 +#ifdef TO_DO
35634 + pHalData->AcmControl = AcmCtrl;
35635 +#endif
35636 + //write_nic_byte(dev, ACM_CONTROL, AcmCtrl);
35637 + write_nic_byte(dev, ACM_CONTROL, 0);
35638 + }
35639 + }
35640 + }
35641 +
35642 +
35643 + }
35644 +}
35645 +
35646 +void
35647 +ActSetWirelessMode8185(
35648 + struct net_device *dev,
35649 + u8 btWirelessMode
35650 + )
35651 +{
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);
35656 +
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);
35661 + return;
35662 + }
35663 +
35664 + // 1. Assign wireless mode to swtich if necessary.
35665 + if (btWirelessMode == WIRELESS_MODE_AUTO)
35666 + {
35667 + if((btSupportedWirelessMode & WIRELESS_MODE_A))
35668 + {
35669 + btWirelessMode = WIRELESS_MODE_A;
35670 + }
35671 + else if((btSupportedWirelessMode & WIRELESS_MODE_G))
35672 + {
35673 + btWirelessMode = WIRELESS_MODE_G;
35674 + }
35675 + else if((btSupportedWirelessMode & WIRELESS_MODE_B))
35676 + {
35677 + btWirelessMode = WIRELESS_MODE_B;
35678 + }
35679 + else
35680 + {
35681 + DMESGW("ActSetWirelessMode8185(): No valid wireless mode supported, btSupportedWirelessMode(%x)!!!\n",
35682 + btSupportedWirelessMode);
35683 + btWirelessMode = WIRELESS_MODE_B;
35684 + }
35685 + }
35686 +
35687 +
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)
35691 + {
35692 + case RF_ZEBRA2:
35693 + case RF_ZEBRA4:
35694 + {
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;
35698 + }
35699 + break;
35700 +
35701 + default:
35702 + DMESGW("ActSetWirelessMode8185(): unsupported RF: 0x%X !!!\n", priv->rf_chip);
35703 + break;
35704 + }
35705 +
35706 + // 3. Change related setting.
35707 + if( ieee->mode == WIRELESS_MODE_A ){
35708 + DMESG("WIRELESS_MODE_A\n");
35709 + }
35710 + else if( ieee->mode == WIRELESS_MODE_B ){
35711 + DMESG("WIRELESS_MODE_B\n");
35712 + }
35713 + else if( ieee->mode == WIRELESS_MODE_G ){
35714 + DMESG("WIRELESS_MODE_G\n");
35715 + }
35716 +
35717 + ActUpdateChannelAccessSetting( dev, ieee->mode, &priv->ChannelAccessSetting);
35718 +}
35719 +
35720 +void rtl8185b_irq_enable(struct net_device *dev)
35721 +{
35722 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35723 +
35724 + priv->irq_enabled = 1;
35725 + write_nic_dword(dev, IMR, priv->IntrMask);
35726 +}
35727 +//by amy for power save
35728 +void
35729 +DrvIFIndicateDisassociation(
35730 + struct net_device *dev,
35731 + u16 reason
35732 + )
35733 +{
35734 + //printk("==> DrvIFIndicateDisassociation()\n");
35735 +
35736 + // nothing is needed after disassociation request.
35737 +
35738 + //printk("<== DrvIFIndicateDisassociation()\n");
35739 +}
35740 +void
35741 +MgntDisconnectIBSS(
35742 + struct net_device *dev
35743 +)
35744 +{
35745 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35746 + u8 i;
35747 +
35748 + //printk("XXXXXXXXXX MgntDisconnect IBSS\n");
35749 +
35750 + DrvIFIndicateDisassociation(dev, unspec_reason);
35751 +
35752 +// PlatformZeroMemory( pMgntInfo->Bssid, 6 );
35753 + for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x55;
35754 +
35755 + priv->ieee80211->state = IEEE80211_NOLINK;
35756 +
35757 + //Stop Beacon.
35758 +
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.
35762 +
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);
35766 +
35767 + priv->ieee80211->link_change(dev);
35768 + notify_wx_assoc_event(priv->ieee80211);
35769 +
35770 + // Stop SW Beacon.Use hw beacon so do not need to do so.by amy
35771 +#if 0
35772 + if(pMgntInfo->bEnableSwBeaconTimer)
35773 + {
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);
35778 +//#endif
35779 + }
35780 +#endif
35781 +
35782 +// MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE );
35783 +
35784 +}
35785 +void
35786 +MlmeDisassociateRequest(
35787 + struct net_device *dev,
35788 + u8* asSta,
35789 + u8 asRsn
35790 + )
35791 +{
35792 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35793 + u8 i;
35794 +
35795 + SendDisassociation(priv->ieee80211, asSta, asRsn );
35796 +
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);
35801 +
35802 +
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) );
35807 +
35808 + ieee80211_disassociate(priv->ieee80211);
35809 +
35810 +
35811 + }
35812 +
35813 +}
35814 +
35815 +void
35816 +MgntDisconnectAP(
35817 + struct net_device *dev,
35818 + u8 asRsn
35819 +)
35820 +{
35821 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35822 +
35823 +//
35824 +// Commented out by rcnjko, 2005.01.27:
35825 +// I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE().
35826 +//
35827 +// //2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success
35828 +// SecClearAllKeys(Adapter);
35829 +
35830 + // In WPA WPA2 need to Clear all key ... because new key will set after new handshaking.
35831 +#ifdef TODO
35832 + if( pMgntInfo->SecurityInfo.AuthMode > RT_802_11AuthModeAutoSwitch ||
35833 + (pMgntInfo->bAPSuportCCKM && pMgntInfo->bCCX8021xenable) ) // In CCKM mode will Clear key
35834 + {
35835 + SecClearAllKeys(Adapter);
35836 + RT_TRACE(COMP_SEC, DBG_LOUD,("======>CCKM clear key..."))
35837 + }
35838 +#endif
35839 + // 2004.10.11, by rcnjko.
35840 + //MlmeDisassociateRequest( Adapter, pMgntInfo->Bssid, disas_lv_ss );
35841 + MlmeDisassociateRequest( dev, priv->ieee80211->current_network.bssid, asRsn );
35842 +
35843 + priv->ieee80211->state = IEEE80211_NOLINK;
35844 +// pMgntInfo->AsocTimestamp = 0;
35845 +}
35846 +bool
35847 +MgntDisconnect(
35848 + struct net_device *dev,
35849 + u8 asRsn
35850 +)
35851 +{
35852 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35853 + //
35854 + // Schedule an workitem to wake up for ps mode, 070109, by rcnjko.
35855 + //
35856 +#ifdef TODO
35857 + if(pMgntInfo->mPss != eAwake)
35858 + {
35859 + //
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.
35862 + //
35863 + // PlatformScheduleWorkItem( &(pMgntInfo->AwakeWorkItem) );
35864 + PlatformSetTimer( Adapter, &(pMgntInfo->AwakeTimer), 0 );
35865 + }
35866 +#endif
35867 +
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);
35873 +#endif
35874 + // In adhoc mode, update beacon frame.
35875 + if( priv->ieee80211->state == IEEE80211_LINKED )
35876 + {
35877 + if( priv->ieee80211->iw_mode == IW_MODE_ADHOC )
35878 + {
35879 +// RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> MgntDisconnectIBSS\n"));
35880 + //printk("MgntDisconnect() ===> MgntDisconnectIBSS\n");
35881 + MgntDisconnectIBSS(dev);
35882 + }
35883 + if( priv->ieee80211->iw_mode == IW_MODE_INFRA )
35884 + {
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);
35891 +
35892 +// RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> MgntDisconnectAP\n"));
35893 + //printk("MgntDisconnect() ===> MgntDisconnectAP\n");
35894 + MgntDisconnectAP(dev, asRsn);
35895 + }
35896 +
35897 + // Inidicate Disconnect, 2005.02.23, by rcnjko.
35898 +// MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE);
35899 + }
35900 +
35901 + return true;
35902 +}
35903 +//
35904 +// Description:
35905 +// Chang RF Power State.
35906 +// Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE.
35907 +//
35908 +// Assumption:
35909 +// PASSIVE LEVEL.
35910 +//
35911 +bool
35912 +SetRFPowerState(
35913 + struct net_device *dev,
35914 + RT_RF_POWER_STATE eRFPowerState
35915 + )
35916 +{
35917 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35918 + bool bResult = false;
35919 +
35920 +// printk("---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState);
35921 + if(eRFPowerState == priv->eRFPowerState)
35922 + {
35923 +// printk("<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState);
35924 + return bResult;
35925 + }
35926 +
35927 + switch(priv->rf_chip)
35928 + {
35929 + case RF_ZEBRA2:
35930 + case RF_ZEBRA4:
35931 + bResult = SetZebraRFPowerState8185(dev, eRFPowerState);
35932 + break;
35933 +
35934 + default:
35935 + printk("SetRFPowerState8185(): unknown RFChipID: 0x%X!!!\n", priv->rf_chip);
35936 + break;;
35937 +}
35938 +// printk("<--------- SetRFPowerState(): bResult(%d)\n", bResult);
35939 +
35940 + return bResult;
35941 +}
35942 +void
35943 +HalEnableRx8185Dummy(
35944 + struct net_device *dev
35945 + )
35946 +{
35947 +}
35948 +void
35949 +HalDisableRx8185Dummy(
35950 + struct net_device *dev
35951 + )
35952 +{
35953 +}
35954 +
35955 +bool
35956 +MgntActSet_RF_State(
35957 + struct net_device *dev,
35958 + RT_RF_POWER_STATE StateToSet,
35959 + u32 ChangeSource
35960 + )
35961 +{
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);
35969 + //
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.
35972 + //
35973 +#if 1
35974 + while(true)
35975 + {
35976 +// down(&priv->rf_state);
35977 + spin_lock_irqsave(&priv->rf_ps_lock,flag);
35978 + if(priv->RFChangeInProgress)
35979 + {
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)
35986 + {
35987 + RFWaitCounter ++;
35988 +// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter));
35989 + udelay(1000); // 1 ms
35990 +
35991 + // Wait too long, return FALSE to avoid to be stuck here.
35992 + if(RFWaitCounter > 1000) // 1sec
35993 + {
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?
35997 + return false;
35998 + }
35999 + }
36000 + }
36001 + else
36002 + {
36003 +// printk("========================>haha2\n");
36004 + priv->RFChangeInProgress = true;
36005 +// up(&priv->rf_state);
36006 + spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
36007 + break;
36008 + }
36009 + }
36010 +#endif
36011 + rtState = priv->eRFPowerState;
36012 +
36013 +
36014 + switch(StateToSet)
36015 + {
36016 + case eRfOn:
36017 + //
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.
36020 + //
36021 + priv->RfOffReason &= (~ChangeSource);
36022 +
36023 + if(! priv->RfOffReason)
36024 + {
36025 + priv->RfOffReason = 0;
36026 + bActionAllowed = true;
36027 +
36028 + if(rtState == eRfOff && ChangeSource >=RF_CHANGE_BY_HW && !priv->bInHctTest)
36029 + {
36030 + bConnectBySSID = true;
36031 + }
36032 + }
36033 + else
36034 +// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", pMgntInfo->RfOffReason, ChangeSource));
36035 + ;
36036 + break;
36037 +
36038 + case eRfOff:
36039 + // 070125, rcnjko: we always keep connected in AP mode.
36040 +
36041 + if (priv->RfOffReason > RF_CHANGE_BY_IPS)
36042 + {
36043 + //
36044 + // 060808, Annie:
36045 + // Disconnect to current BSS when radio off. Asked by QuanTa.
36046 + //
36047 +
36048 + //
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.
36052 + //
36053 + MgntDisconnect( dev, disas_lv_ss );
36054 +
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;
36061 + }
36062 +
36063 +
36064 +
36065 + priv->RfOffReason |= ChangeSource;
36066 + bActionAllowed = true;
36067 + break;
36068 +
36069 + case eRfSleep:
36070 + priv->RfOffReason |= ChangeSource;
36071 + bActionAllowed = true;
36072 + break;
36073 +
36074 + default:
36075 + break;
36076 + }
36077 +
36078 + if(bActionAllowed)
36079 + {
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);
36084 +
36085 + // Turn on RF.
36086 + if(StateToSet == eRfOn)
36087 + {
36088 + HalEnableRx8185Dummy(dev);
36089 + if(bConnectBySSID)
36090 + {
36091 + // by amy not supported
36092 +// MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE );
36093 + }
36094 + }
36095 + // Turn off RF.
36096 + else if(StateToSet == eRfOff)
36097 + {
36098 + HalDisableRx8185Dummy(dev);
36099 + }
36100 + }
36101 + else
36102 + {
36103 + // printk("MgntActSet_RF_State(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, priv->RfOffReason);
36104 + }
36105 +
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;
36114 +}
36115 +void
36116 +InactivePowerSave(
36117 + struct net_device *dev
36118 + )
36119 +{
36120 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
36121 + //u8 index = 0;
36122 +
36123 + //
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.
36130 + //
36131 + priv->bSwRfProcessing = true;
36132 +
36133 + MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
36134 +
36135 + //
36136 + // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
36137 + //
36138 +#if 0
36139 + while( index < 4 )
36140 + {
36141 + if( ( pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP104_Encryption ) ||
36142 + (pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP40_Encryption) )
36143 + {
36144 + if( pMgntInfo->SecurityInfo.KeyLen[index] != 0)
36145 + pAdapter->HalFunc.SetKeyHandler(pAdapter, index, 0, FALSE, pMgntInfo->SecurityInfo.PairwiseEncAlgorithm, TRUE, FALSE);
36146 +
36147 + }
36148 + index++;
36149 + }
36150 +#endif
36151 + priv->bSwRfProcessing = false;
36152 +}
36153 +
36154 +//
36155 +// Description:
36156 +// Enter the inactive power save mode. RF will be off
36157 +// 2007.08.17, by shien chang.
36158 +//
36159 +void
36160 +IPSEnter(
36161 + struct net_device *dev
36162 + )
36163 +{
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)
36168 + {
36169 + rtState = priv->eRFPowerState;
36170 +
36171 + //
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)
36179 + //
36180 + if (rtState == eRfOn && !priv->bSwRfProcessing
36181 + && (priv->ieee80211->state != IEEE80211_LINKED ))
36182 + {
36183 + // printk("IPSEnter(): Turn off RF.\n");
36184 + priv->eInactivePowerState = eRfOff;
36185 + InactivePowerSave(dev);
36186 + }
36187 + }
36188 +// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
36189 +}
36190 +void
36191 +IPSLeave(
36192 + struct net_device *dev
36193 + )
36194 +{
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)
36199 + {
36200 + rtState = priv->eRFPowerState;
36201 + if ((rtState == eRfOff || rtState == eRfSleep) && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS)
36202 + {
36203 +// printk("IPSLeave(): Turn on RF.\n");
36204 + priv->eInactivePowerState = eRfOn;
36205 + InactivePowerSave(dev);
36206 + }
36207 + }
36208 +// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
36209 +}
36210 +//by amy for power save
36211 +void rtl8185b_adapter_start(struct net_device *dev)
36212 +{
36213 + struct r8180_priv *priv = ieee80211_priv(dev);
36214 + struct ieee80211_device *ieee = priv->ieee80211;
36215 +
36216 + u8 SupportedWirelessMode;
36217 + u8 InitWirelessMode;
36218 + u8 bInvalidWirelessMode = 0;
36219 + //int i;
36220 + u8 tmpu8;
36221 + //u8 u1tmp,u2tmp;
36222 + u8 btCR9346;
36223 + u8 TmpU1b;
36224 + u8 btPSR;
36225 +
36226 + //rtl8180_rtx_disable(dev);
36227 +//{by amy 080312
36228 + write_nic_byte(dev,0x24e, (BIT5|BIT6|BIT0));
36229 +//by amy 080312}
36230 + rtl8180_reset(dev);
36231 +
36232 + priv->dma_poll_mask = 0;
36233 + priv->dma_poll_stop_mask = 0;
36234 +
36235 + //rtl8180_beacon_tx_disable(dev);
36236 +
36237 + HwConfigureRTL8185(dev);
36238 +
36239 + write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
36240 + write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
36241 +
36242 + write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3); // default network type to 'No Link'
36243 +
36244 + //write_nic_byte(dev, BRSR, 0x0); // Set BRSR= 1M
36245 +
36246 + write_nic_word(dev, BcnItv, 100);
36247 + write_nic_word(dev, AtimWnd, 2);
36248 +
36249 + //PlatformEFIOWrite2Byte(dev, FEMR, 0xFFFF);
36250 + PlatformIOWrite2Byte(dev, FEMR, 0xFFFF);
36251 +
36252 + write_nic_byte(dev, WPA_CONFIG, 0);
36253 +
36254 + MacConfig_85BASIC(dev);
36255 +
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);
36259 +//by amy
36260 +//#ifdef CONFIG_RTL818X_S
36261 + // for jong required
36262 +// PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x9a56);
36263 +//#endif
36264 +//by amy
36265 + //BT_QA_BOARD
36266 + //PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x9a56);
36267 +
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
36273 +//by amy
36274 + tmpu8 = read_nic_byte(dev, CONFIG3);
36275 +#ifdef CONFIG_RTL818X_S
36276 + write_nic_byte(dev, CONFIG3, (tmpu8 |CONFIG3_PARM_En) );
36277 +#else
36278 + write_nic_byte(dev, CONFIG3, (tmpu8 |CONFIG3_PARM_En | CONFIG3_CLKRUN_En) );
36279 +#endif
36280 +//by amy
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);
36285 +//by amy
36286 +#ifdef CONFIG_RTL818X_S
36287 + write_nic_word(dev, ANAPARAM3, 0x0010);
36288 +#else
36289 + write_nic_byte(dev, ANAPARAM3, 0x00);
36290 +#endif
36291 +//by amy
36292 +
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) );
36299 +
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);
36304 +
36305 + // disable EEM0 and EEM1 in 9346CR
36306 + btCR9346 &= ~(0xC0);
36307 + write_nic_byte(dev, CR9346, btCR9346);
36308 +
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);
36318 +
36319 + // PHY config.
36320 + PhyConfig8185(dev);
36321 +
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;
36332 + }
36333 + else
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 )
36338 + {
36339 + bInvalidWirelessMode = 1;
36340 + }
36341 + }
36342 +
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))
36347 + {
36348 + InitWirelessMode = WIRELESS_MODE_A;
36349 + }
36350 + else if((SupportedWirelessMode & WIRELESS_MODE_G))
36351 + {
36352 + InitWirelessMode = WIRELESS_MODE_G;
36353 + }
36354 + else if((SupportedWirelessMode & WIRELESS_MODE_B))
36355 + {
36356 + InitWirelessMode = WIRELESS_MODE_B;
36357 + }
36358 + else
36359 + {
36360 + DMESGW("InitializeAdapter8185(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n",
36361 + SupportedWirelessMode);
36362 + InitWirelessMode = WIRELESS_MODE_B;
36363 + }
36364 +
36365 + // Initialize RegWirelessMode if it is not a valid one.
36366 + if(bInvalidWirelessMode)
36367 + {
36368 + ieee->mode = (WIRELESS_MODE)InitWirelessMode;
36369 + }
36370 + }
36371 + else
36372 + { // One of B, G, A.
36373 + InitWirelessMode = ieee->mode;
36374 + }
36375 +//by amy for power save
36376 +#ifdef ENABLE_IPS
36377 +// printk("initialize ENABLE_IPS\n");
36378 + priv->eRFPowerState = eRfOff;
36379 + priv->RfOffReason = 0;
36380 + {
36381 + // u32 tmp2;
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);
36386 + }
36387 +// DrvIFIndicateCurrentPhyStatus(priv);
36388 + //
36389 + // If inactive power mode is enabled, disable rf while in disconnected state.
36390 + // 2007.07.16, by shien chang.
36391 + //
36392 + if (priv->bInactivePs)
36393 + {
36394 + // u32 tmp2;
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);
36399 +
36400 + }
36401 +#endif
36402 +// IPSEnter(dev);
36403 +//by amy for power save
36404 +#ifdef TODO
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)
36409 + {
36410 + SetRFPowerState8185(Adapter, RF_OFF);
36411 + }
36412 + else
36413 + {
36414 + SetRFPowerState8185(Adapter, RF_ON);
36415 + }
36416 +#endif
36417 +
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);
36426 +*/
36427 +
36428 + ActSetWirelessMode8185(dev, (u8)(InitWirelessMode));
36429 +
36430 + //-----------------------------------------------------------------------------
36431 +
36432 + rtl8185b_irq_enable(dev);
36433 +
36434 + netif_start_queue(dev);
36435 +
36436 + }
36437 +
36438 +
36439 +void rtl8185b_rx_enable(struct net_device *dev)
36440 +{
36441 + u8 cmd;
36442 + //u32 rxconf;
36443 + /* for now we accept data, management & ctl frame*/
36444 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
36445 +#if 0
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");
36454 +
36455 + if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
36456 + dev->flags & IFF_PROMISC){
36457 + rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
36458 + }else{
36459 + rxconf = rxconf | (1<<ACCEPT_NICMAC_FRAME_SHIFT);
36460 + if(priv->card_8185 == 0)
36461 + rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
36462 + }
36463 +
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);
36467 + }*/
36468 +
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);
36473 + }
36474 +
36475 + if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
36476 + rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
36477 +
36478 + //if(!priv->card_8185){
36479 + rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
36480 + rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
36481 + //}
36482 +
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);
36486 +
36487 + //if(!priv->card_8185)
36488 + rxconf = rxconf | RCR_ONLYERLPKT;
36489 +
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);
36496 +#endif
36497 +
36498 + if (dev->flags & IFF_PROMISC) DMESG ("NIC in promisc mode");
36499 +
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;
36504 + }
36505 +
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);
36509 + }*/
36510 +
36511 + if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
36512 + priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF | RCR_APWRMGT | RCR_AICV;
36513 + }
36514 +
36515 + if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
36516 + priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACRC32;
36517 +
36518 + write_nic_dword(dev, RCR, priv->ReceiveConfig);
36519 +
36520 + fix_rx_fifo(dev);
36521 +
36522 +#ifdef DEBUG_RX
36523 + DMESG("rxconf: %x %x",priv->ReceiveConfig ,read_nic_dword(dev,RCR));
36524 +#endif
36525 + cmd=read_nic_byte(dev,CMD);
36526 + write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
36527 +
36528 +}
36529 +
36530 +void rtl8185b_tx_enable(struct net_device *dev)
36531 +{
36532 + u8 cmd;
36533 + //u8 tx_agc_ctl;
36534 + u8 byte;
36535 + //u32 txconf;
36536 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
36537 +
36538 +#if 0
36539 + txconf= read_nic_dword(dev,TX_CONF);
36540 + if(priv->card_8185){
36541 +
36542 +
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);
36547 +
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);
36553 + /*
36554 + write_nic_word(dev, 0x5e, 0x01);
36555 + force_pci_posting(dev);
36556 + mdelay(1);
36557 + write_nic_word(dev, 0xfe, 0x10);
36558 + force_pci_posting(dev);
36559 + mdelay(1);
36560 + write_nic_word(dev, 0x5e, 0x00);
36561 + force_pci_posting(dev);
36562 + mdelay(1);
36563 + */
36564 + write_nic_byte(dev, 0xec, 0x3f); /* Disable early TX */
36565 + }
36566 +
36567 + if(priv->card_8185){
36568 +
36569 + txconf = txconf &~ (1<<TCR_PROBE_NOTIMESTAMP_SHIFT);
36570 +
36571 + }else{
36572 +
36573 + if(hwseqnum)
36574 + txconf= txconf &~ (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
36575 + else
36576 + txconf= txconf | (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
36577 + }
36578 +
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);
36586 +
36587 + if(priv->card_8185){
36588 + if(priv->hw_plcp_len)
36589 + txconf = txconf &~ TCR_PLCP_LEN;
36590 + else
36591 + txconf = txconf | TCR_PLCP_LEN;
36592 + }else{
36593 + txconf = txconf &~ TCR_SAT;
36594 + }
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;
36599 +
36600 +// if(priv->ieee80211->hw_wep)
36601 +// txconf=txconf &~ (1<<TX_NOICV_SHIFT);
36602 +// else
36603 + txconf=txconf | (1<<TX_NOICV_SHIFT);
36604 +
36605 + write_nic_dword(dev,TX_CONF,txconf);
36606 +#endif
36607 +
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);
36612 +
36613 + fix_tx_fifo(dev);
36614 +
36615 +#ifdef DEBUG_TX
36616 + DMESG("txconf: %x %x",priv->TransmitConfig,read_nic_dword(dev,TCR));
36617 +#endif
36618 +
36619 + cmd=read_nic_byte(dev,CMD);
36620 + write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
36621 +
36622 + //write_nic_dword(dev,TX_CONF,txconf);
36623 +
36624 +
36625 +/*
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);
36629 + */
36630 +}
36631 +
36632 +
36633 +#endif