Staging: rtl8192su: buffer overflow in r8192U_core.c
[deliverable/linux.git] / drivers / staging / rtl8192su / r8192U_core.c
CommitLineData
5f53d8ca
JC
1/******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 * Linux device driver for RTL8192U
4 *
5 * Based on the r8187 driver, which is:
6 * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 *
20 * The full GNU General Public License is included in this distribution in the
21 * file called LICENSE.
22 *
23 * Contact Information:
24 * Jerry chuang <wlanfae@realtek.com>
25 */
26
d1aed899 27#include <linux/vmalloc.h>
5f53d8ca
JC
28
29#undef LOOP_TEST
30#undef DUMP_RX
31#undef DUMP_TX
32#undef DEBUG_TX_DESC2
33#undef RX_DONT_PASS_UL
34#undef DEBUG_EPROM
35#undef DEBUG_RX_VERBOSE
36#undef DUMMY_RX
37#undef DEBUG_ZERO_RX
38#undef DEBUG_RX_SKB
39#undef DEBUG_TX_FRAG
40#undef DEBUG_RX_FRAG
41#undef DEBUG_TX_FILLDESC
42#undef DEBUG_TX
43#undef DEBUG_IRQ
44#undef DEBUG_RX
45#undef DEBUG_RXALLOC
46#undef DEBUG_REGISTERS
47#undef DEBUG_RING
48#undef DEBUG_IRQ_TASKLET
49#undef DEBUG_TX_ALLOC
50#undef DEBUG_TX_DESC
51
52#define CONFIG_RTL8192_IO_MAP
53
5f53d8ca
JC
54#include <asm/uaccess.h>
55#include "r8192U.h"
5f53d8ca
JC
56#include "r8180_93cx6.h" /* Card EEPROM */
57#include "r8192U_wx.h"
58
59#include "r8192S_rtl8225.h"
60#include "r8192S_hw.h"
61#include "r8192S_phy.h"
62#include "r8192S_phyreg.h"
63#include "r8192S_Efuse.h"
64
65#include "r819xU_cmdpkt.h"
66#include "r8192U_dm.h"
67//#include "r8192xU_phyreg.h"
68#include <linux/usb.h>
5f53d8ca 69
5f53d8ca 70#include "r8192U_pm.h"
5f53d8ca 71
2a7d71ad 72#include "ieee80211/dot11d.h"
5f53d8ca 73
5f53d8ca
JC
74
75
5f53d8ca
JC
76u32 rt_global_debug_component = \
77// COMP_TRACE |
78// COMP_DBG |
79// COMP_INIT |
80// COMP_RECV |
81// COMP_SEND |
82// COMP_IO |
83 COMP_POWER |
84// COMP_EPROM |
85 COMP_SWBW |
86 COMP_POWER_TRACKING |
87 COMP_TURBO |
88 COMP_QOS |
89// COMP_RATE |
90// COMP_RM |
91 COMP_DIG |
92// COMP_EFUSE |
93// COMP_CH |
94// COMP_TXAGC |
95 COMP_HIPWR |
96// COMP_HALDM |
97 COMP_SEC |
98 COMP_LED |
99// COMP_RF |
100// COMP_RXDESC |
101 COMP_FIRMWARE |
102 COMP_HT |
103 COMP_AMSDU |
104 COMP_SCAN |
105// COMP_CMD |
106 COMP_DOWN |
107 COMP_RESET |
108 COMP_ERR; //always open err flags on
5f53d8ca
JC
109
110#define TOTAL_CAM_ENTRY 32
111#define CAM_CONTENT_COUNT 8
112
113static struct usb_device_id rtl8192_usb_id_tbl[] = {
114 /* Realtek */
115 {USB_DEVICE(0x0bda, 0x8192)},
116 {USB_DEVICE(0x0bda, 0x8709)},
117 /* Corega */
118 {USB_DEVICE(0x07aa, 0x0043)},
119 /* Belkin */
120 {USB_DEVICE(0x050d, 0x805E)},
121 /* Sitecom */
122 {USB_DEVICE(0x0df6, 0x0031)},
123 /* EnGenius */
124 {USB_DEVICE(0x1740, 0x9201)},
125 /* Dlink */
126 {USB_DEVICE(0x2001, 0x3301)},
127 /* Zinwell */
128 {USB_DEVICE(0x5a57, 0x0290)},
488d3749
SG
129 /* Guillemot */
130 {USB_DEVICE(0x06f8, 0xe031)},
5f53d8ca
JC
131 //92SU
132 {USB_DEVICE(0x0bda, 0x8172)},
133 {}
134};
135
136MODULE_LICENSE("GPL");
5f53d8ca 137MODULE_VERSION("V 1.1");
5f53d8ca
JC
138MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
139MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
140
141static char* ifname = "wlan%d";
5f53d8ca
JC
142static int hwwep = 1; //default use hw. set 0 to use software security
143static int channels = 0x3fff;
144
145
146
5f53d8ca
JC
147module_param(ifname, charp, S_IRUGO|S_IWUSR );
148//module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
149module_param(hwwep,int, S_IRUGO|S_IWUSR);
150module_param(channels,int, S_IRUGO|S_IWUSR);
5f53d8ca
JC
151
152MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
153//MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
154MODULE_PARM_DESC(hwwep," Try to use hardware security support. ");
155MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
156
5f53d8ca
JC
157static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
158 const struct usb_device_id *id);
159static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
5f53d8ca
JC
160
161static struct usb_driver rtl8192_usb_driver = {
5f53d8ca
JC
162 .name = RTL819xU_MODULE_NAME, /* Driver name */
163 .id_table = rtl8192_usb_id_tbl, /* PCI_ID table */
164 .probe = rtl8192_usb_probe, /* probe fn */
165 .disconnect = rtl8192_usb_disconnect, /* remove fn */
5f53d8ca
JC
166 .suspend = rtl8192U_suspend, /* PM suspend fn */
167 .resume = rtl8192U_resume, /* PM resume fn */
5f53d8ca 168 .reset_resume = rtl8192U_resume, /* PM reset resume fn */
5f53d8ca
JC
169};
170
171
5f53d8ca
JC
172static void rtl8192SU_read_eeprom_info(struct net_device *dev);
173short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb);
174void rtl8192SU_rx_nomal(struct sk_buff* skb);
175void rtl8192SU_rx_cmd(struct sk_buff *skb);
176bool rtl8192SU_adapter_start(struct net_device *dev);
177short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
178void rtl8192SU_link_change(struct net_device *dev);
179void InitialGain8192S(struct net_device *dev,u8 Operation);
180void rtl8192SU_query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe);
181
182struct rtl819x_ops rtl8192su_ops = {
183 .nic_type = NIC_8192SU,
184 .rtl819x_read_eeprom_info = rtl8192SU_read_eeprom_info,
185 .rtl819x_tx = rtl8192SU_tx,
186 .rtl819x_tx_cmd = rtl8192SU_tx_cmd,
187 .rtl819x_rx_nomal = rtl8192SU_rx_nomal,
188 .rtl819x_rx_cmd = rtl8192SU_rx_cmd,
189 .rtl819x_adapter_start = rtl8192SU_adapter_start,
190 .rtl819x_link_change = rtl8192SU_link_change,
191 .rtl819x_initial_gain = InitialGain8192S,
192 .rtl819x_query_rxdesc_status = rtl8192SU_query_rxdesc_status,
193};
5f53d8ca 194
5f53d8ca
JC
195
196typedef struct _CHANNEL_LIST
197{
198 u8 Channel[32];
199 u8 Len;
200}CHANNEL_LIST, *PCHANNEL_LIST;
201
202static CHANNEL_LIST ChannelPlan[] = {
203 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24}, //FCC
204 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
205 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
206 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
207 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
208 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, //MKK //MKK
209 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
210 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
211 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, // For 11a , TELEC
212 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
213 {{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
214};
215
216static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
217{
218 int i, max_chan=-1, min_chan=-1;
219 struct ieee80211_device* ieee = priv->ieee80211;
220 switch (channel_plan)
221 {
222 case COUNTRY_CODE_FCC:
223 case COUNTRY_CODE_IC:
224 case COUNTRY_CODE_ETSI:
225 case COUNTRY_CODE_SPAIN:
226 case COUNTRY_CODE_FRANCE:
227 case COUNTRY_CODE_MKK:
228 case COUNTRY_CODE_MKK1:
229 case COUNTRY_CODE_ISRAEL:
230 case COUNTRY_CODE_TELEC:
231 case COUNTRY_CODE_MIC:
232 {
233 Dot11d_Init(ieee);
234 ieee->bGlobalDomain = false;
235 //acturally 8225 & 8256 rf chip only support B,G,24N mode
236 if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256) || (priv->rf_chip == RF_6052))
237 {
238 min_chan = 1;
239 max_chan = 14;
240 }
241 else
242 {
243 RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
244 }
245 if (ChannelPlan[channel_plan].Len != 0){
246 // Clear old channel map
247 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
248 // Set new channel map
249 for (i=0;i<ChannelPlan[channel_plan].Len;i++)
250 {
251 if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
252 break;
253 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
254 }
255 }
256 break;
257 }
258 case COUNTRY_CODE_GLOBAL_DOMAIN:
259 {
260 GET_DOT11D_INFO(ieee)->bEnabled = 0;//this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain settings.
261 Dot11d_Reset(ieee);
262 ieee->bGlobalDomain = true;
263 break;
264 }
265 default:
266 break;
267 }
268 return;
269}
5f53d8ca
JC
270
271#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 )
272
5f53d8ca
JC
273#define rx_hal_is_cck_rate(_pDesc)\
274 ((_pDesc->RxMCS == DESC92S_RATE1M ||\
275 _pDesc->RxMCS == DESC92S_RATE2M ||\
276 _pDesc->RxMCS == DESC92S_RATE5_5M ||\
277 _pDesc->RxMCS == DESC92S_RATE11M) &&\
278 !_pDesc->RxHT)
279
280#define tx_hal_is_cck_rate(_DataRate)\
281 ( _DataRate == MGN_1M ||\
282 _DataRate == MGN_2M ||\
283 _DataRate == MGN_5_5M ||\
284 _DataRate == MGN_11M )
285
5f53d8ca
JC
286
287
288
289void CamResetAllEntry(struct net_device *dev)
290{
291#if 1
292 u32 ulcommand = 0;
293 //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
294 // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
295 // In this condition, Cam can not be reset because upper layer will not set this static key again.
296 //if(Adapter->EncAlgorithm == WEP_Encryption)
297 // return;
298//debug
299 //DbgPrint("========================================\n");
300 //DbgPrint(" Call ResetAllEntry \n");
301 //DbgPrint("========================================\n\n");
302 ulcommand |= BIT31|BIT30;
303 write_nic_dword(dev, RWCAM, ulcommand);
304#else
305 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
306 CAM_mark_invalid(dev, ucIndex);
307 for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
308 CAM_empty_entry(dev, ucIndex);
309#endif
310
311}
312
313
314void write_cam(struct net_device *dev, u8 addr, u32 data)
315{
316 write_nic_dword(dev, WCAMI, data);
317 write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
318}
319
320u32 read_cam(struct net_device *dev, u8 addr)
321{
322 write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
323 return read_nic_dword(dev, 0xa8);
324}
325
326void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
327{
328 int status;
329 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
330 struct usb_device *udev = priv->udev;
331
332 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
333 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
334 indx|0xfe00, 0, &data, 1, HZ / 2);
335
336 if (status < 0)
337 {
338 printk("write_nic_byte_E TimeOut! status:%d\n", status);
339 }
340}
341
342u8 read_nic_byte_E(struct net_device *dev, int indx)
343{
344 int status;
345 u8 data;
346 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
347 struct usb_device *udev = priv->udev;
348
349 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
350 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
351 indx|0xfe00, 0, &data, 1, HZ / 2);
352
353 if (status < 0)
354 {
355 printk("read_nic_byte_E TimeOut! status:%d\n", status);
356 }
357
358 return data;
359}
360//as 92U has extend page from 4 to 16, so modify functions below.
361void write_nic_byte(struct net_device *dev, int indx, u8 data)
362{
363 int status;
364
365 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
366 struct usb_device *udev = priv->udev;
367
368 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
369 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
5f53d8ca 370 indx, 0, &data, 1, HZ / 2);
5f53d8ca
JC
371
372 if (status < 0)
373 {
374 printk("write_nic_byte TimeOut! status:%d\n", status);
375 }
376
377
378}
379
380
381void write_nic_word(struct net_device *dev, int indx, u16 data)
382{
383
384 int status;
385
386 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
387 struct usb_device *udev = priv->udev;
388
389 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
390 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
5f53d8ca 391 indx, 0, &data, 2, HZ / 2);
5f53d8ca
JC
392
393 if (status < 0)
394 {
395 printk("write_nic_word TimeOut! status:%d\n", status);
396 }
397
398}
399
400
401void write_nic_dword(struct net_device *dev, int indx, u32 data)
402{
403
404 int status;
405
406 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
407 struct usb_device *udev = priv->udev;
408
409 status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
410 RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
5f53d8ca 411 indx, 0, &data, 4, HZ / 2);
5f53d8ca
JC
412
413
414 if (status < 0)
415 {
416 printk("write_nic_dword TimeOut! status:%d\n", status);
417 }
418
419}
420
421
422
423u8 read_nic_byte(struct net_device *dev, int indx)
424{
425 u8 data;
426 int status;
427 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
428 struct usb_device *udev = priv->udev;
429
430 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
431 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
5f53d8ca 432 indx, 0, &data, 1, HZ / 2);
5f53d8ca
JC
433
434 if (status < 0)
435 {
436 printk("read_nic_byte TimeOut! status:%d\n", status);
437 }
438
439 return data;
440}
441
442
443
444u16 read_nic_word(struct net_device *dev, int indx)
445{
446 u16 data;
447 int status;
448 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
449 struct usb_device *udev = priv->udev;
450
451 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
452 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
5f53d8ca 453 indx, 0, &data, 2, HZ / 2);
5f53d8ca
JC
454
455 if (status < 0)
456 {
457 printk("read_nic_word TimeOut! status:%d\n", status);
458 }
459
460
461 return data;
462}
463
464u16 read_nic_word_E(struct net_device *dev, int indx)
465{
466 u16 data;
467 int status;
468 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
469 struct usb_device *udev = priv->udev;
470
471 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
472 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
473 indx|0xfe00, 0, &data, 2, HZ / 2);
474
475 if (status < 0)
476 {
477 printk("read_nic_word TimeOut! status:%d\n", status);
478 }
479
480
481 return data;
482}
483
484u32 read_nic_dword(struct net_device *dev, int indx)
485{
486 u32 data;
487 int status;
488// int result;
489
490 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
491 struct usb_device *udev = priv->udev;
492
493 status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
494 RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
5f53d8ca 495 indx, 0, &data, 4, HZ / 2);
5f53d8ca
JC
496// if(0 != result) {
497// printk(KERN_WARNING "read size of data = %d\, date = %d\n", result, data);
498// }
499
500 if (status < 0)
501 {
502 printk("read_nic_dword TimeOut! status:%d\n", status);
503 if(status == -ENODEV) {
504 priv->usb_error = true;
505 }
506 }
507
508
509
510 return data;
511}
512
513
514//u8 read_phy_cck(struct net_device *dev, u8 adr);
515//u8 read_phy_ofdm(struct net_device *dev, u8 adr);
516/* this might still called in what was the PHY rtl8185/rtl8192 common code
517 * plans are to possibilty turn it again in one common code...
518 */
519inline void force_pci_posting(struct net_device *dev)
520{
521}
522
523
524static struct net_device_stats *rtl8192_stats(struct net_device *dev);
525void rtl8192_commit(struct net_device *dev);
526//void rtl8192_restart(struct net_device *dev);
5f53d8ca
JC
527void rtl8192_restart(struct work_struct *work);
528//void rtl8192_rq_tx_ack(struct work_struct *work);
5f53d8ca
JC
529
530void watch_dog_timer_callback(unsigned long data);
531
532/****************************************************************************
533 -----------------------------PROCFS STUFF-------------------------
534*****************************************************************************/
535
536static struct proc_dir_entry *rtl8192_proc = NULL;
537
538
539
540static int proc_get_stats_ap(char *page, char **start,
541 off_t offset, int count,
542 int *eof, void *data)
543{
544 struct net_device *dev = data;
545 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
546 struct ieee80211_device *ieee = priv->ieee80211;
547 struct ieee80211_network *target;
548
549 int len = 0;
550
551 list_for_each_entry(target, &ieee->network_list, list) {
552
553 len += snprintf(page + len, count - len,
554 "%s ", target->ssid);
555
556 if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
557 len += snprintf(page + len, count - len,
558 "WPA\n");
559 }
560 else{
561 len += snprintf(page + len, count - len,
562 "non_WPA\n");
563 }
564
565 }
566
567 *eof = 1;
568 return len;
569}
570
5f53d8ca
JC
571static int proc_get_registers(char *page, char **start,
572 off_t offset, int count,
573 int *eof, void *data)
574{
575 struct net_device *dev = data;
576// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
577
578 int len = 0;
579 int i,n,page0,page1,page2;
580
581 int max=0xff;
582 page0 = 0x000;
583 page1 = 0x100;
584 page2 = 0x800;
585
586 /* This dump the current register page */
587 if(!IS_BB_REG_OFFSET_92S(page0)){
588 len += snprintf(page + len, count - len,
589 "\n####################page %x##################\n ", (page0>>8));
590 for(n=0;n<=max;)
591 {
592 len += snprintf(page + len, count - len,
593 "\nD: %2x > ",n);
594 for(i=0;i<16 && n<=max;i++,n++)
595 len += snprintf(page + len, count - len,
596 "%2.2x ",read_nic_byte(dev,(page0|n)));
597 }
598 }else{
599 len += snprintf(page + len, count - len,
600 "\n####################page %x##################\n ", (page0>>8));
601 for(n=0;n<=max;)
602 {
603 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
604 for(i=0;i<4 && n<=max;n+=4,i++)
605 len += snprintf(page + len, count - len,
606 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
607 }
608 }
609 len += snprintf(page + len, count - len,"\n");
610 *eof = 1;
611 return len;
612
613}
614static int proc_get_registers_1(char *page, char **start,
615 off_t offset, int count,
616 int *eof, void *data)
617{
618 struct net_device *dev = data;
619// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
620
621 int len = 0;
622 int i,n,page0;
623
624 int max=0xff;
625 page0 = 0x100;
626
627 /* This dump the current register page */
628 len += snprintf(page + len, count - len,
629 "\n####################page %x##################\n ", (page0>>8));
630 for(n=0;n<=max;)
631 {
632 len += snprintf(page + len, count - len,
633 "\nD: %2x > ",n);
634 for(i=0;i<16 && n<=max;i++,n++)
635 len += snprintf(page + len, count - len,
636 "%2.2x ",read_nic_byte(dev,(page0|n)));
637 }
638 len += snprintf(page + len, count - len,"\n");
639 *eof = 1;
640 return len;
641
642}
643static int proc_get_registers_2(char *page, char **start,
644 off_t offset, int count,
645 int *eof, void *data)
646{
647 struct net_device *dev = data;
648// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
649
650 int len = 0;
651 int i,n,page0;
652
653 int max=0xff;
654 page0 = 0x200;
655
656 /* This dump the current register page */
657 len += snprintf(page + len, count - len,
658 "\n####################page %x##################\n ", (page0>>8));
659 for(n=0;n<=max;)
660 {
661 len += snprintf(page + len, count - len,
662 "\nD: %2x > ",n);
663 for(i=0;i<16 && n<=max;i++,n++)
664 len += snprintf(page + len, count - len,
665 "%2.2x ",read_nic_byte(dev,(page0|n)));
666 }
667 len += snprintf(page + len, count - len,"\n");
668 *eof = 1;
669 return len;
670
671}
672static int proc_get_registers_8(char *page, char **start,
673 off_t offset, int count,
674 int *eof, void *data)
675{
676 struct net_device *dev = data;
677
678 int len = 0;
679 int i,n,page0;
680
681 int max=0xff;
682 page0 = 0x800;
683
684 /* This dump the current register page */
685 len += snprintf(page + len, count - len,
686 "\n####################page %x##################\n ", (page0>>8));
687 for(n=0;n<=max;)
688 {
689 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
690 for(i=0;i<4 && n<=max;n+=4,i++)
691 len += snprintf(page + len, count - len,
692 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
693 }
694 len += snprintf(page + len, count - len,"\n");
695 *eof = 1;
696 return len;
697
698 }
699static int proc_get_registers_9(char *page, char **start,
700 off_t offset, int count,
701 int *eof, void *data)
702{
703 struct net_device *dev = data;
704// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
705
706 int len = 0;
707 int i,n,page0;
708
709 int max=0xff;
710 page0 = 0x900;
711
712 /* This dump the current register page */
713 len += snprintf(page + len, count - len,
714 "\n####################page %x##################\n ", (page0>>8));
715 for(n=0;n<=max;)
716 {
717 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
718 for(i=0;i<4 && n<=max;n+=4,i++)
719 len += snprintf(page + len, count - len,
720 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
721 }
722 len += snprintf(page + len, count - len,"\n");
723 *eof = 1;
724 return len;
725}
726static int proc_get_registers_a(char *page, char **start,
727 off_t offset, int count,
728 int *eof, void *data)
729{
730 struct net_device *dev = data;
731// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
732
733 int len = 0;
734 int i,n,page0;
735
736 int max=0xff;
737 page0 = 0xa00;
738
739 /* This dump the current register page */
740 len += snprintf(page + len, count - len,
741 "\n####################page %x##################\n ", (page0>>8));
742 for(n=0;n<=max;)
743 {
744 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
745 for(i=0;i<4 && n<=max;n+=4,i++)
746 len += snprintf(page + len, count - len,
747 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
748 }
749 len += snprintf(page + len, count - len,"\n");
750 *eof = 1;
751 return len;
752}
753static int proc_get_registers_b(char *page, char **start,
754 off_t offset, int count,
755 int *eof, void *data)
756{
757 struct net_device *dev = data;
758// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
759
760 int len = 0;
761 int i,n,page0;
762
763 int max=0xff;
764 page0 = 0xb00;
765
766 /* This dump the current register page */
767 len += snprintf(page + len, count - len,
768 "\n####################page %x##################\n ", (page0>>8));
769 for(n=0;n<=max;)
770 {
771 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
772 for(i=0;i<4 && n<=max;n+=4,i++)
773 len += snprintf(page + len, count - len,
774 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
775 }
776 len += snprintf(page + len, count - len,"\n");
777 *eof = 1;
778 return len;
779 }
780static int proc_get_registers_c(char *page, char **start,
781 off_t offset, int count,
782 int *eof, void *data)
783{
784 struct net_device *dev = data;
785// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
786
787 int len = 0;
788 int i,n,page0;
789
790 int max=0xff;
791 page0 = 0xc00;
792
793 /* This dump the current register page */
794 len += snprintf(page + len, count - len,
795 "\n####################page %x##################\n ", (page0>>8));
796 for(n=0;n<=max;)
797 {
798 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
799 for(i=0;i<4 && n<=max;n+=4,i++)
800 len += snprintf(page + len, count - len,
801 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
802 }
803 len += snprintf(page + len, count - len,"\n");
804 *eof = 1;
805 return len;
806}
807static int proc_get_registers_d(char *page, char **start,
808 off_t offset, int count,
809 int *eof, void *data)
810{
811 struct net_device *dev = data;
812// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
813
814 int len = 0;
815 int i,n,page0;
816
817 int max=0xff;
818 page0 = 0xd00;
819
820 /* This dump the current register page */
821 len += snprintf(page + len, count - len,
822 "\n####################page %x##################\n ", (page0>>8));
823 for(n=0;n<=max;)
824 {
825 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
826 for(i=0;i<4 && n<=max;n+=4,i++)
827 len += snprintf(page + len, count - len,
828 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
829 }
830 len += snprintf(page + len, count - len,"\n");
831 *eof = 1;
832 return len;
833}
834static int proc_get_registers_e(char *page, char **start,
835 off_t offset, int count,
836 int *eof, void *data)
837{
838 struct net_device *dev = data;
839// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
840
841 int len = 0;
842 int i,n,page0;
843
844 int max=0xff;
845 page0 = 0xe00;
846
847 /* This dump the current register page */
848 len += snprintf(page + len, count - len,
849 "\n####################page %x##################\n ", (page0>>8));
850 for(n=0;n<=max;)
851 {
852 len += snprintf(page + len, count - len, "\nD: %2x > ",n);
853 for(i=0;i<4 && n<=max;n+=4,i++)
854 len += snprintf(page + len, count - len,
855 "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
856 }
857 len += snprintf(page + len, count - len,"\n");
858 *eof = 1;
859 return len;
860}
5f53d8ca 861
5f53d8ca
JC
862static int proc_get_stats_tx(char *page, char **start,
863 off_t offset, int count,
864 int *eof, void *data)
865{
866 struct net_device *dev = data;
867 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
868
869 int len = 0;
870
871 len += snprintf(page + len, count - len,
872 "TX VI priority ok int: %lu\n"
873 "TX VI priority error int: %lu\n"
874 "TX VO priority ok int: %lu\n"
875 "TX VO priority error int: %lu\n"
876 "TX BE priority ok int: %lu\n"
877 "TX BE priority error int: %lu\n"
878 "TX BK priority ok int: %lu\n"
879 "TX BK priority error int: %lu\n"
880 "TX MANAGE priority ok int: %lu\n"
881 "TX MANAGE priority error int: %lu\n"
882 "TX BEACON priority ok int: %lu\n"
883 "TX BEACON priority error int: %lu\n"
884// "TX high priority ok int: %lu\n"
885// "TX high priority failed error int: %lu\n"
886 "TX queue resume: %lu\n"
887 "TX queue stopped?: %d\n"
888 "TX fifo overflow: %lu\n"
889// "TX beacon: %lu\n"
890 "TX VI queue: %d\n"
891 "TX VO queue: %d\n"
892 "TX BE queue: %d\n"
893 "TX BK queue: %d\n"
894// "TX HW queue: %d\n"
895 "TX VI dropped: %lu\n"
896 "TX VO dropped: %lu\n"
897 "TX BE dropped: %lu\n"
898 "TX BK dropped: %lu\n"
899 "TX total data packets %lu\n",
900// "TX beacon aborted: %lu\n",
901 priv->stats.txviokint,
902 priv->stats.txvierr,
903 priv->stats.txvookint,
904 priv->stats.txvoerr,
905 priv->stats.txbeokint,
906 priv->stats.txbeerr,
907 priv->stats.txbkokint,
908 priv->stats.txbkerr,
909 priv->stats.txmanageokint,
910 priv->stats.txmanageerr,
911 priv->stats.txbeaconokint,
912 priv->stats.txbeaconerr,
913// priv->stats.txhpokint,
914// priv->stats.txhperr,
915 priv->stats.txresumed,
916 netif_queue_stopped(dev),
917 priv->stats.txoverflow,
918// priv->stats.txbeacon,
919 atomic_read(&(priv->tx_pending[VI_PRIORITY])),
920 atomic_read(&(priv->tx_pending[VO_PRIORITY])),
921 atomic_read(&(priv->tx_pending[BE_PRIORITY])),
922 atomic_read(&(priv->tx_pending[BK_PRIORITY])),
923// read_nic_byte(dev, TXFIFOCOUNT),
924 priv->stats.txvidrop,
925 priv->stats.txvodrop,
926 priv->stats.txbedrop,
927 priv->stats.txbkdrop,
928 priv->stats.txdatapkt
929// priv->stats.txbeaconerr
930 );
931
932 *eof = 1;
933 return len;
934}
935
936
937
938static int proc_get_stats_rx(char *page, char **start,
939 off_t offset, int count,
940 int *eof, void *data)
941{
942 struct net_device *dev = data;
943 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
944
945 int len = 0;
946
947 len += snprintf(page + len, count - len,
948 "RX packets: %lu\n"
949 "RX urb status error: %lu\n"
950 "RX invalid urb error: %lu\n",
951 priv->stats.rxoktotal,
952 priv->stats.rxstaterr,
953 priv->stats.rxurberr);
954
955 *eof = 1;
956 return len;
957}
5f53d8ca 958
5f53d8ca
JC
959void rtl8192_proc_module_init(void)
960{
961 RT_TRACE(COMP_INIT, "Initializing proc filesystem");
5f53d8ca 962 rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net);
5f53d8ca
JC
963}
964
965
966void rtl8192_proc_module_remove(void)
967{
5f53d8ca 968 remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
5f53d8ca
JC
969}
970
971
972void rtl8192_proc_remove_one(struct net_device *dev)
973{
974 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
975
976
977 if (priv->dir_dev) {
978 // remove_proc_entry("stats-hw", priv->dir_dev);
979 remove_proc_entry("stats-tx", priv->dir_dev);
980 remove_proc_entry("stats-rx", priv->dir_dev);
981 // remove_proc_entry("stats-ieee", priv->dir_dev);
982 remove_proc_entry("stats-ap", priv->dir_dev);
983 remove_proc_entry("registers", priv->dir_dev);
984 remove_proc_entry("registers-1", priv->dir_dev);
985 remove_proc_entry("registers-2", priv->dir_dev);
986 remove_proc_entry("registers-8", priv->dir_dev);
987 remove_proc_entry("registers-9", priv->dir_dev);
988 remove_proc_entry("registers-a", priv->dir_dev);
989 remove_proc_entry("registers-b", priv->dir_dev);
990 remove_proc_entry("registers-c", priv->dir_dev);
991 remove_proc_entry("registers-d", priv->dir_dev);
992 remove_proc_entry("registers-e", priv->dir_dev);
993 // remove_proc_entry("cck-registers",priv->dir_dev);
994 // remove_proc_entry("ofdm-registers",priv->dir_dev);
995 //remove_proc_entry(dev->name, rtl8192_proc);
996 remove_proc_entry("wlan0", rtl8192_proc);
997 priv->dir_dev = NULL;
998 }
999}
1000
1001
1002void rtl8192_proc_init_one(struct net_device *dev)
1003{
1004 struct proc_dir_entry *e;
1005 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1006 priv->dir_dev = create_proc_entry(dev->name,
1007 S_IFDIR | S_IRUGO | S_IXUGO,
1008 rtl8192_proc);
1009 if (!priv->dir_dev) {
1010 RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
1011 dev->name);
1012 return;
1013 }
5f53d8ca
JC
1014 e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
1015 priv->dir_dev, proc_get_stats_rx, dev);
1016
1017 if (!e) {
1018 RT_TRACE(COMP_ERR,"Unable to initialize "
1019 "/proc/net/rtl8192/%s/stats-rx\n",
1020 dev->name);
1021 }
1022
1023
1024 e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
1025 priv->dir_dev, proc_get_stats_tx, dev);
1026
1027 if (!e) {
1028 RT_TRACE(COMP_ERR, "Unable to initialize "
1029 "/proc/net/rtl8192/%s/stats-tx\n",
1030 dev->name);
1031 }
5f53d8ca
JC
1032
1033 e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
1034 priv->dir_dev, proc_get_stats_ap, dev);
1035
1036 if (!e) {
1037 RT_TRACE(COMP_ERR, "Unable to initialize "
1038 "/proc/net/rtl8192/%s/stats-ap\n",
1039 dev->name);
1040 }
1041
1042 e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
1043 priv->dir_dev, proc_get_registers, dev);
1044 if (!e) {
1045 RT_TRACE(COMP_ERR, "Unable to initialize "
1046 "/proc/net/rtl8192/%s/registers\n",
1047 dev->name);
1048 }
5f53d8ca
JC
1049 e = create_proc_read_entry("registers-1", S_IFREG | S_IRUGO,
1050 priv->dir_dev, proc_get_registers_1, dev);
1051 if (!e) {
1052 RT_TRACE(COMP_ERR, "Unable to initialize "
1053 "/proc/net/rtl8192/%s/registers-1\n",
1054 dev->name);
1055 }
1056 e = create_proc_read_entry("registers-2", S_IFREG | S_IRUGO,
1057 priv->dir_dev, proc_get_registers_2, dev);
1058 if (!e) {
1059 RT_TRACE(COMP_ERR, "Unable to initialize "
1060 "/proc/net/rtl8192/%s/registers-2\n",
1061 dev->name);
1062 }
1063 e = create_proc_read_entry("registers-8", S_IFREG | S_IRUGO,
1064 priv->dir_dev, proc_get_registers_8, dev);
1065 if (!e) {
1066 RT_TRACE(COMP_ERR, "Unable to initialize "
1067 "/proc/net/rtl8192/%s/registers-8\n",
1068 dev->name);
1069 }
1070 e = create_proc_read_entry("registers-9", S_IFREG | S_IRUGO,
1071 priv->dir_dev, proc_get_registers_9, dev);
1072 if (!e) {
1073 RT_TRACE(COMP_ERR, "Unable to initialize "
1074 "/proc/net/rtl8192/%s/registers-9\n",
1075 dev->name);
1076 }
1077 e = create_proc_read_entry("registers-a", S_IFREG | S_IRUGO,
1078 priv->dir_dev, proc_get_registers_a, dev);
1079 if (!e) {
1080 RT_TRACE(COMP_ERR, "Unable to initialize "
1081 "/proc/net/rtl8192/%s/registers-a\n",
1082 dev->name);
1083 }
1084 e = create_proc_read_entry("registers-b", S_IFREG | S_IRUGO,
1085 priv->dir_dev, proc_get_registers_b, dev);
1086 if (!e) {
1087 RT_TRACE(COMP_ERR, "Unable to initialize "
1088 "/proc/net/rtl8192/%s/registers-b\n",
1089 dev->name);
1090 }
1091 e = create_proc_read_entry("registers-c", S_IFREG | S_IRUGO,
1092 priv->dir_dev, proc_get_registers_c, dev);
1093 if (!e) {
1094 RT_TRACE(COMP_ERR, "Unable to initialize "
1095 "/proc/net/rtl8192/%s/registers-c\n",
1096 dev->name);
1097 }
1098 e = create_proc_read_entry("registers-d", S_IFREG | S_IRUGO,
1099 priv->dir_dev, proc_get_registers_d, dev);
1100 if (!e) {
1101 RT_TRACE(COMP_ERR, "Unable to initialize "
1102 "/proc/net/rtl8192/%s/registers-d\n",
1103 dev->name);
1104 }
1105 e = create_proc_read_entry("registers-e", S_IFREG | S_IRUGO,
1106 priv->dir_dev, proc_get_registers_e, dev);
1107 if (!e) {
1108 RT_TRACE(COMP_ERR, "Unable to initialize "
1109 "/proc/net/rtl8192/%s/registers-e\n",
1110 dev->name);
1111 }
5f53d8ca
JC
1112}
1113/****************************************************************************
1114 -----------------------------MISC STUFF-------------------------
1115*****************************************************************************/
1116
1117/* this is only for debugging */
1118void print_buffer(u32 *buffer, int len)
1119{
1120 int i;
1121 u8 *buf =(u8*)buffer;
1122
1123 printk("ASCII BUFFER DUMP (len: %x):\n",len);
1124
1125 for(i=0;i<len;i++)
1126 printk("%c",buf[i]);
1127
1128 printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
1129
1130 for(i=0;i<len;i++)
1131 printk("%x",buf[i]);
1132
1133 printk("\n");
1134}
1135
1136//short check_nic_enough_desc(struct net_device *dev, priority_t priority)
1137short check_nic_enough_desc(struct net_device *dev,int queue_index)
1138{
1139 struct r8192_priv *priv = ieee80211_priv(dev);
1140 int used = atomic_read(&priv->tx_pending[queue_index]);
1141
1142 return (used < MAX_TX_URB);
1143}
1144
1145void tx_timeout(struct net_device *dev)
1146{
1147 struct r8192_priv *priv = ieee80211_priv(dev);
1148 //rtl8192_commit(dev);
1149
5f53d8ca 1150 schedule_work(&priv->reset_wq);
5f53d8ca
JC
1151 //DMESG("TXTIMEOUT");
1152}
1153
1154
1155/* this is only for debug */
1156void dump_eprom(struct net_device *dev)
1157{
1158 int i;
1159 for(i=0; i<63; i++)
1160 RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev,i));
1161}
1162
1163/* this is only for debug */
1164void rtl8192_dump_reg(struct net_device *dev)
1165{
1166 int i;
1167 int n;
1168 int max=0x1ff;
1169
1170 RT_TRACE(COMP_PHY, "Dumping NIC register map");
1171
1172 for(n=0;n<=max;)
1173 {
1174 printk( "\nD: %2x> ", n);
1175 for(i=0;i<16 && n<=max;i++,n++)
1176 printk("%2x ",read_nic_byte(dev,n));
1177 }
1178 printk("\n");
1179}
1180
1181/****************************************************************************
1182 ------------------------------HW STUFF---------------------------
1183*****************************************************************************/
1184
5f53d8ca
JC
1185void rtl8192_set_mode(struct net_device *dev,int mode)
1186{
1187 u8 ecmd;
1188 ecmd=read_nic_byte(dev, EPROM_CMD);
1189 ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
1190 ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
1191 ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
1192 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
1193 write_nic_byte(dev, EPROM_CMD, ecmd);
1194}
1195
1196
1197void rtl8192_update_msr(struct net_device *dev)
1198{
1199 struct r8192_priv *priv = ieee80211_priv(dev);
1200 u8 msr;
1201
1202 msr = read_nic_byte(dev, MSR);
1203 msr &= ~ MSR_LINK_MASK;
1204
1205 /* do not change in link_state != WLAN_LINK_ASSOCIATED.
1206 * msr must be updated if the state is ASSOCIATING.
1207 * this is intentional and make sense for ad-hoc and
1208 * master (see the create BSS/IBSS func)
1209 */
1210 if (priv->ieee80211->state == IEEE80211_LINKED){
1211
1212 if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
1213 msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
1214 else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1215 msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
1216 else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
1217 msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
1218
1219 }else
1220 msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
1221
1222 write_nic_byte(dev, MSR, msr);
1223}
1224
1225void rtl8192_set_chan(struct net_device *dev,short ch)
1226{
1227 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1228// u32 tx;
1229 RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
1230 //printk("=====>%s()====ch:%d\n", __FUNCTION__, ch);
1231 priv->chan=ch;
5f53d8ca
JC
1232
1233 /* this hack should avoid frame TX during channel setting*/
1234
1235
1236// tx = read_nic_dword(dev,TX_CONF);
1237// tx &= ~TX_LOOPBACK_MASK;
1238
1239#ifndef LOOP_TEST
1240// write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
1241
1242 //need to implement rf set channel here WB
1243
1244 if (priv->rf_set_chan)
1245 priv->rf_set_chan(dev,priv->chan);
1246 mdelay(10);
1247// write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
1248#endif
1249}
1250
5f53d8ca 1251static void rtl8192_rx_isr(struct urb *urb);
5f53d8ca
JC
1252
1253u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
1254{
1255
5f53d8ca
JC
1256 return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
1257 + pstats->RxBufShift);
1258
1259}
1260static int rtl8192_rx_initiate(struct net_device*dev)
1261{
1262 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1263 struct urb *entry;
1264 struct sk_buff *skb;
1265 struct rtl8192_rx_info *info;
1266
1267 /* nomal packet rx procedure */
1268 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
1269 skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
1270 if (!skb)
1271 break;
5f53d8ca 1272 entry = usb_alloc_urb(0, GFP_KERNEL);
5f53d8ca
JC
1273 if (!entry) {
1274 kfree_skb(skb);
1275 break;
1276 }
1277// printk("nomal packet IN request!\n");
1278 usb_fill_bulk_urb(entry, priv->udev,
8109c2fd 1279 usb_rcvbulkpipe(priv->udev, 3), skb_tail_pointer(skb),
5f53d8ca
JC
1280 RX_URB_SIZE, rtl8192_rx_isr, skb);
1281 info = (struct rtl8192_rx_info *) skb->cb;
1282 info->urb = entry;
1283 info->dev = dev;
1284 info->out_pipe = 3; //denote rx normal packet queue
1285 skb_queue_tail(&priv->rx_queue, skb);
5f53d8ca 1286 usb_submit_urb(entry, GFP_KERNEL);
5f53d8ca
JC
1287 }
1288
1289 /* command packet rx procedure */
1290 while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
1291// printk("command packet IN request!\n");
1292 skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL);
1293 if (!skb)
1294 break;
5f53d8ca 1295 entry = usb_alloc_urb(0, GFP_KERNEL);
5f53d8ca
JC
1296 if (!entry) {
1297 kfree_skb(skb);
1298 break;
1299 }
1300 usb_fill_bulk_urb(entry, priv->udev,
8109c2fd 1301 usb_rcvbulkpipe(priv->udev, 9), skb_tail_pointer(skb),
5f53d8ca
JC
1302 RX_URB_SIZE, rtl8192_rx_isr, skb);
1303 info = (struct rtl8192_rx_info *) skb->cb;
1304 info->urb = entry;
1305 info->dev = dev;
1306 info->out_pipe = 9; //denote rx cmd packet queue
1307 skb_queue_tail(&priv->rx_queue, skb);
5f53d8ca 1308 usb_submit_urb(entry, GFP_KERNEL);
5f53d8ca
JC
1309 }
1310
1311 return 0;
1312}
1313
1314void rtl8192_set_rxconf(struct net_device *dev)
1315{
1316 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1317 u32 rxconf;
1318
1319 rxconf=read_nic_dword(dev,RCR);
1320 rxconf = rxconf &~ MAC_FILTER_MASK;
1321 rxconf = rxconf | RCR_AMF;
1322 rxconf = rxconf | RCR_ADF;
1323 rxconf = rxconf | RCR_AB;
1324 rxconf = rxconf | RCR_AM;
1325 //rxconf = rxconf | RCR_ACF;
1326
1327 if (dev->flags & IFF_PROMISC) {DMESG ("NIC in promisc mode");}
1328
1329 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
1330 dev->flags & IFF_PROMISC){
1331 rxconf = rxconf | RCR_AAP;
1332 } /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
1333 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
1334 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
1335 }*/else{
1336 rxconf = rxconf | RCR_APM;
1337 rxconf = rxconf | RCR_CBSSID;
1338 }
1339
1340
1341 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
1342 rxconf = rxconf | RCR_AICV;
1343 rxconf = rxconf | RCR_APWRMGT;
1344 }
1345
1346 if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
1347 rxconf = rxconf | RCR_ACRC32;
1348
1349
1350 rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
1351 rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
1352 rxconf = rxconf &~ MAX_RX_DMA_MASK;
1353 rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
1354
1355// rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
1356 rxconf = rxconf | RCR_ONLYERLPKT;
1357
1358// rxconf = rxconf &~ RCR_CS_MASK;
1359// rxconf = rxconf | (1<<RCR_CS_SHIFT);
1360
1361 write_nic_dword(dev, RCR, rxconf);
1362
1363 #ifdef DEBUG_RX
1364 DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RCR));
1365 #endif
1366}
1367//wait to be removed
1368void rtl8192_rx_enable(struct net_device *dev)
1369{
1370 //u8 cmd;
1371
1372 //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1373
1374 rtl8192_rx_initiate(dev);
1375
1376// rtl8192_set_rxconf(dev);
5f53d8ca
JC
1377}
1378
1379
1380void rtl8192_tx_enable(struct net_device *dev)
1381{
5f53d8ca
JC
1382}
1383
5f53d8ca
JC
1384void rtl8192_rtx_disable(struct net_device *dev)
1385{
1386 u8 cmd;
1387 struct r8192_priv *priv = ieee80211_priv(dev);
1388 struct sk_buff *skb;
1389 struct rtl8192_rx_info *info;
1390
1391 cmd=read_nic_byte(dev,CMDR);
1392 write_nic_byte(dev, CMDR, cmd &~ \
1393 (CR_TE|CR_RE));
1394 force_pci_posting(dev);
1395 mdelay(10);
1396
1397 while ((skb = __skb_dequeue(&priv->rx_queue))) {
1398 info = (struct rtl8192_rx_info *) skb->cb;
1399 if (!info->urb)
1400 continue;
1401
1402 usb_kill_urb(info->urb);
1403 kfree_skb(skb);
1404 }
1405
1406 if (skb_queue_len(&priv->skb_queue)) {
1407 printk(KERN_WARNING "skb_queue not empty\n");
1408 }
1409
1410 skb_queue_purge(&priv->skb_queue);
1411 return;
1412}
1413
1414
1415int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
1416{
5f53d8ca
JC
1417 return 0;
1418}
1419
5f53d8ca
JC
1420inline u16 ieeerate2rtlrate(int rate)
1421{
1422 switch(rate){
1423 case 10:
1424 return 0;
1425 case 20:
1426 return 1;
1427 case 55:
1428 return 2;
1429 case 110:
1430 return 3;
1431 case 60:
1432 return 4;
1433 case 90:
1434 return 5;
1435 case 120:
1436 return 6;
1437 case 180:
1438 return 7;
1439 case 240:
1440 return 8;
1441 case 360:
1442 return 9;
1443 case 480:
1444 return 10;
1445 case 540:
1446 return 11;
1447 default:
1448 return 3;
1449
1450 }
1451}
1452static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
1453inline u16 rtl8192_rate2rate(short rate)
1454{
1455 if (rate >11) return 0;
1456 return rtl_rate[rate];
1457}
1458
5f53d8ca 1459static void rtl8192_rx_isr(struct urb *urb)
5f53d8ca
JC
1460{
1461 struct sk_buff *skb = (struct sk_buff *) urb->context;
1462 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
1463 struct net_device *dev = info->dev;
1464 struct r8192_priv *priv = ieee80211_priv(dev);
1465 int out_pipe = info->out_pipe;
1466 int err;
1467 if(!priv->up)
1468 return;
1469 if (unlikely(urb->status)) {
1470 info->urb = NULL;
1471 priv->stats.rxstaterr++;
1472 priv->ieee80211->stats.rx_errors++;
1473 usb_free_urb(urb);
1474 // printk("%s():rx status err\n",__FUNCTION__);
1475 return;
1476 }
1ec9e48d 1477
5f53d8ca 1478 skb_unlink(skb, &priv->rx_queue);
5f53d8ca
JC
1479 skb_put(skb, urb->actual_length);
1480
1481 skb_queue_tail(&priv->skb_queue, skb);
1482 tasklet_schedule(&priv->irq_rx_tasklet);
1483
1484 skb = dev_alloc_skb(RX_URB_SIZE);
1485 if (unlikely(!skb)) {
1486 usb_free_urb(urb);
1487 printk("%s():can,t alloc skb\n",__FUNCTION__);
1488 /* TODO check rx queue length and refill *somewhere* */
1489 return;
1490 }
1491
1492 usb_fill_bulk_urb(urb, priv->udev,
8109c2fd
JM
1493 usb_rcvbulkpipe(priv->udev, out_pipe),
1494 skb_tail_pointer(skb),
5f53d8ca
JC
1495 RX_URB_SIZE, rtl8192_rx_isr, skb);
1496
1497 info = (struct rtl8192_rx_info *) skb->cb;
1498 info->urb = urb;
1499 info->dev = dev;
1500 info->out_pipe = out_pipe;
1501
8109c2fd 1502 urb->transfer_buffer = skb_tail_pointer(skb);
5f53d8ca
JC
1503 urb->context = skb;
1504 skb_queue_tail(&priv->rx_queue, skb);
5f53d8ca 1505 err = usb_submit_urb(urb, GFP_ATOMIC);
aad445f8 1506 if(err && err != -EPERM)
5f53d8ca
JC
1507 printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);
1508}
1509
1510u32
1511rtl819xusb_rx_command_packet(
1512 struct net_device *dev,
1513 struct ieee80211_rx_stats *pstats
1514 )
1515{
1516 u32 status;
1517
1518 //RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
1519
1520 status = cmpk_message_handle_rx(dev, pstats);
1521 if (status)
1522 {
1523 DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
1524 }
1525 else
1526 {
1527 //RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
1528 }
1529
1530 //RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
1531 return status;
1532}
1533
5f53d8ca
JC
1534void rtl8192_data_hard_stop(struct net_device *dev)
1535{
1536 //FIXME !!
5f53d8ca
JC
1537}
1538
1539
1540void rtl8192_data_hard_resume(struct net_device *dev)
1541{
1542 // FIXME !!
5f53d8ca
JC
1543}
1544
1545/* this function TX data frames when the ieee80211 stack requires this.
1546 * It checks also if we need to stop the ieee tx queue, eventually do it
1547 */
1548void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
1549{
1550 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1551 int ret;
1552 unsigned long flags;
1553 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1554 u8 queue_index = tcb_desc->queue_index;
1555
1556 /* shall not be referred by command packet */
1557 assert(queue_index != TXCMD_QUEUE);
1558
1559 spin_lock_irqsave(&priv->tx_lock,flags);
1560
1561 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1562// tcb_desc->RATRIndex = 7;
1563// tcb_desc->bTxDisableRateFallBack = 1;
1564// tcb_desc->bTxUseDriverAssingedRate = 1;
1565 tcb_desc->bTxEnableFwCalcDur = 1;
1566 skb_push(skb, priv->ieee80211->tx_headroom);
1567 ret = priv->ops->rtl819x_tx(dev, skb);
1568
1569 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1570 //priv->ieee80211->stats.tx_packets++;
1571
1572 spin_unlock_irqrestore(&priv->tx_lock,flags);
1573
1574// return ret;
1575 return;
1576}
1577
1578/* This is a rough attempt to TX a frame
1579 * This is called by the ieee 80211 stack to TX management frames.
1580 * If the ring is full packet are dropped (for data frame the queue
1581 * is stopped before this can happen).
1582 */
1583int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
1584{
1585 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1586 int ret;
1587 unsigned long flags;
1588 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1589 u8 queue_index = tcb_desc->queue_index;
1590
1591
1592 spin_lock_irqsave(&priv->tx_lock,flags);
1593
1594 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1595 if(queue_index == TXCMD_QUEUE) {
1596 skb_push(skb, USB_HWDESC_HEADER_LEN);
1597 priv->ops->rtl819x_tx_cmd(dev, skb);
1598 ret = 1;
1599 spin_unlock_irqrestore(&priv->tx_lock,flags);
1600 return ret;
1601 } else {
1602 skb_push(skb, priv->ieee80211->tx_headroom);
1603 ret = priv->ops->rtl819x_tx(dev, skb);
1604 }
1605
1606 spin_unlock_irqrestore(&priv->tx_lock,flags);
1607
1608 return ret;
1609}
1610
1611
1612void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1613
5f53d8ca 1614
5f53d8ca 1615static void rtl8192_tx_isr(struct urb *tx_urb)
5f53d8ca
JC
1616{
1617 struct sk_buff *skb = (struct sk_buff*)tx_urb->context;
1618 struct net_device *dev = NULL;
1619 struct r8192_priv *priv = NULL;
1620 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1621 u8 queue_index = tcb_desc->queue_index;
1622// bool bToSend0Byte;
1623// u16 BufLen = skb->len;
1624
1625 memcpy(&dev,(struct net_device*)(skb->cb),sizeof(struct net_device*));
1626 priv = ieee80211_priv(dev);
1627
1628 if(tcb_desc->queue_index != TXCMD_QUEUE) {
1629 if(tx_urb->status == 0) {
1630 // dev->trans_start = jiffies;
1631 // As act as station mode, destion shall be unicast address.
1632 //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
1633 //priv->ieee80211->stats.tx_packets++;
1634 priv->stats.txoktotal++;
1635 priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
1636 priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
1637 } else {
1638 priv->ieee80211->stats.tx_errors++;
1639 //priv->stats.txmanageerr++;
1640 /* TODO */
1641 }
1642 }
1643
1644 /* free skb and tx_urb */
1645 if(skb != NULL) {
1646 dev_kfree_skb_any(skb);
1647 usb_free_urb(tx_urb);
1648 atomic_dec(&priv->tx_pending[queue_index]);
1649 }
1650
5f53d8ca
JC
1651 {
1652 //
1653 // Handle HW Beacon:
1654 // We had transfer our beacon frame to host controler at this moment.
1655 //
5f53d8ca
JC
1656 //
1657 // Caution:
1658 // Handling the wait queue of command packets.
1659 // For Tx command packets, we must not do TCB fragment because it is not handled right now.
1660 // We must cut the packets to match the size of TX_CMD_PKT before we send it.
1661 //
1662 if (queue_index == MGNT_QUEUE){
1663 if (priv->ieee80211->ack_tx_to_ieee){
1664 if (rtl8192_is_tx_queue_empty(dev)){
1665 priv->ieee80211->ack_tx_to_ieee = 0;
1666 ieee80211_ps_tx_ack(priv->ieee80211, 1);
1667 }
1668 }
1669 }
1670 /* Handle MPDU in wait queue. */
1671 if(queue_index != BEACON_QUEUE) {
1672 /* Don't send data frame during scanning.*/
1673 if((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0)&&\
1674 (!(priv->ieee80211->queue_stop))) {
1675 if(NULL != (skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]))))
1676 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
1677
1678 return; //modified by david to avoid further processing AMSDU
1679 }
5f53d8ca
JC
1680 }
1681 }
5f53d8ca
JC
1682}
1683
1684void rtl8192_beacon_stop(struct net_device *dev)
1685{
1686 u8 msr, msrm, msr2;
1687 struct r8192_priv *priv = ieee80211_priv(dev);
1688
1689 msr = read_nic_byte(dev, MSR);
1690 msrm = msr & MSR_LINK_MASK;
1691 msr2 = msr & ~MSR_LINK_MASK;
1692
1693 if(NIC_8192U == priv->card_8192) {
1694 usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
1695 }
1696 if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
1697 (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
1698 write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
1699 write_nic_byte(dev, MSR, msr);
1700 }
1701}
1702
1703void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1704{
1705 struct r8192_priv *priv = ieee80211_priv(dev);
1706 struct ieee80211_network *net;
1707 u8 i=0, basic_rate = 0;
1708 net = & priv->ieee80211->current_network;
1709
1710 for (i=0; i<net->rates_len; i++)
1711 {
1712 basic_rate = net->rates[i]&0x7f;
1713 switch(basic_rate)
1714 {
1715 case MGN_1M: *rate_config |= RRSR_1M; break;
1716 case MGN_2M: *rate_config |= RRSR_2M; break;
1717 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1718 case MGN_11M: *rate_config |= RRSR_11M; break;
1719 case MGN_6M: *rate_config |= RRSR_6M; break;
1720 case MGN_9M: *rate_config |= RRSR_9M; break;
1721 case MGN_12M: *rate_config |= RRSR_12M; break;
1722 case MGN_18M: *rate_config |= RRSR_18M; break;
1723 case MGN_24M: *rate_config |= RRSR_24M; break;
1724 case MGN_36M: *rate_config |= RRSR_36M; break;
1725 case MGN_48M: *rate_config |= RRSR_48M; break;
1726 case MGN_54M: *rate_config |= RRSR_54M; break;
1727 }
1728 }
1729 for (i=0; i<net->rates_ex_len; i++)
1730 {
1731 basic_rate = net->rates_ex[i]&0x7f;
1732 switch(basic_rate)
1733 {
1734 case MGN_1M: *rate_config |= RRSR_1M; break;
1735 case MGN_2M: *rate_config |= RRSR_2M; break;
1736 case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
1737 case MGN_11M: *rate_config |= RRSR_11M; break;
1738 case MGN_6M: *rate_config |= RRSR_6M; break;
1739 case MGN_9M: *rate_config |= RRSR_9M; break;
1740 case MGN_12M: *rate_config |= RRSR_12M; break;
1741 case MGN_18M: *rate_config |= RRSR_18M; break;
1742 case MGN_24M: *rate_config |= RRSR_24M; break;
1743 case MGN_36M: *rate_config |= RRSR_36M; break;
1744 case MGN_48M: *rate_config |= RRSR_48M; break;
1745 case MGN_54M: *rate_config |= RRSR_54M; break;
1746 }
1747 }
1748}
1749
1750
1751#define SHORT_SLOT_TIME 9
1752#define NON_SHORT_SLOT_TIME 20
1753
1754void rtl8192_update_cap(struct net_device* dev, u16 cap)
1755{
1756 //u32 tmp = 0;
1757 struct r8192_priv *priv = ieee80211_priv(dev);
1758 struct ieee80211_network *net = &priv->ieee80211->current_network;
1759 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1760
1761 //LZM MOD 090303 HW_VAR_ACK_PREAMBLE
5f53d8ca
JC
1762 if(0)
1763 {
1764 u8 tmp = 0;
1765 tmp = ((priv->nCur40MhzPrimeSC) << 5);
1766 if (priv->short_preamble)
1767 tmp |= 0x80;
1768 write_nic_byte(dev, RRSR+2, tmp);
1769 }
5f53d8ca
JC
1770
1771 if (net->mode & (IEEE_G|IEEE_N_24G))
1772 {
1773 u8 slot_time = 0;
1774 if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1775 {//short slot time
1776 slot_time = SHORT_SLOT_TIME;
1777 }
1778 else //long slot time
1779 slot_time = NON_SHORT_SLOT_TIME;
1780 priv->slot_time = slot_time;
1781 write_nic_byte(dev, SLOT_TIME, slot_time);
1782 }
1783
1784}
1785void rtl8192_net_update(struct net_device *dev)
1786{
1787
1788 struct r8192_priv *priv = ieee80211_priv(dev);
1789 struct ieee80211_network *net;
1790 u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1791 u16 rate_config = 0;
1792 net = & priv->ieee80211->current_network;
1793
1794 rtl8192_config_rate(dev, &rate_config);
1795 priv->basic_rate = rate_config &= 0x15f;
1796
1797 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1798 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1799 //for(i=0;i<ETH_ALEN;i++)
1800 // write_nic_byte(dev,BSSID+i,net->bssid[i]);
1801
1802 rtl8192_update_msr(dev);
1803// rtl8192_update_cap(dev, net->capability);
1804 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1805 {
1806 write_nic_word(dev, ATIMWND, 2);
1807 write_nic_word(dev, BCN_DMATIME, 1023);
1808 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1809// write_nic_word(dev, BcnIntTime, 100);
1810 write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
1811 write_nic_byte(dev, BCN_ERR_THRESH, 100);
1812 BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1813 // TODO: BcnIFS may required to be changed on ASIC
1814 BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1815
1816 write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1817 }
1818
1819
1820
1821}
1822
1823//temporary hw beacon is not used any more.
1824//open it when necessary
1825#if 1
1826void rtl819xusb_beacon_tx(struct net_device *dev,u16 tx_rate)
1827{
5f53d8ca
JC
1828}
1829#endif
1830inline u8 rtl8192_IsWirelessBMode(u16 rate)
1831{
1832 if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
1833 return 1;
1834 else return 0;
1835}
1836
1837u16 N_DBPSOfRate(u16 DataRate);
1838
1839u16 ComputeTxTime(
1840 u16 FrameLength,
1841 u16 DataRate,
1842 u8 bManagementFrame,
1843 u8 bShortPreamble
1844)
1845{
1846 u16 FrameTime;
1847 u16 N_DBPS;
1848 u16 Ceiling;
1849
1850 if( rtl8192_IsWirelessBMode(DataRate) )
1851 {
1852 if( bManagementFrame || !bShortPreamble || DataRate == 10 )
1853 { // long preamble
1854 FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
1855 }
1856 else
1857 { // Short preamble
1858 FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
1859 }
1860 if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
1861 FrameTime ++;
1862 } else { //802.11g DSSS-OFDM PLCP length field calculation.
1863 N_DBPS = N_DBPSOfRate(DataRate);
1864 Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
1865 + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
1866 FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
1867 }
1868 return FrameTime;
1869}
1870
1871u16 N_DBPSOfRate(u16 DataRate)
1872{
1873 u16 N_DBPS = 24;
1874
1875 switch(DataRate)
1876 {
1877 case 60:
1878 N_DBPS = 24;
1879 break;
1880
1881 case 90:
1882 N_DBPS = 36;
1883 break;
1884
1885 case 120:
1886 N_DBPS = 48;
1887 break;
1888
1889 case 180:
1890 N_DBPS = 72;
1891 break;
1892
1893 case 240:
1894 N_DBPS = 96;
1895 break;
1896
1897 case 360:
1898 N_DBPS = 144;
1899 break;
1900
1901 case 480:
1902 N_DBPS = 192;
1903 break;
1904
1905 case 540:
1906 N_DBPS = 216;
1907 break;
1908
1909 default:
1910 break;
1911 }
1912
1913 return N_DBPS;
1914}
1915
1916void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
1917{
5f53d8ca
JC
1918 usb_free_urb(tx_cmd_urb);
1919}
1920
1921unsigned int txqueue2outpipe(struct r8192_priv* priv,unsigned int tx_queue) {
1922
1923 if(tx_queue >= 9)
1924 {
1925 RT_TRACE(COMP_ERR,"%s():Unknown queue ID!!!\n",__FUNCTION__);
1926 return 0x04;
1927 }
1928 return priv->txqueue_to_outpipemap[tx_queue];
1929}
1930
5f53d8ca
JC
1931short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1932{
1933 struct r8192_priv *priv = ieee80211_priv(dev);
1934 int status;
1935 struct urb *tx_urb;
1936 unsigned int idx_pipe;
1937 tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
1938 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1939 u8 queue_index = tcb_desc->queue_index;
1940 u32 PktSize = 0;
1941
1942 //printk("\n %s::::::::::::::::::::::queue_index = %d\n",__FUNCTION__, queue_index);
1943 atomic_inc(&priv->tx_pending[queue_index]);
1944
5f53d8ca 1945 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
5f53d8ca
JC
1946 if(!tx_urb){
1947 dev_kfree_skb(skb);
1948 return -ENOMEM;
1949 }
1950
1951 memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
1952
1953 /* Tx descriptor ought to be set according to the skb->cb */
1954 pdesc->LINIP = tcb_desc->bLastIniPkt;
1955 PktSize = (u16)(skb->len - USB_HWDESC_HEADER_LEN);
1956 pdesc->PktSize = PktSize;
1957 //printk("PKTSize = %d %x\n",pdesc->PktSize,pdesc->PktSize);
1958 //----------------------------------------------------------------------------
1959 // Fill up USB_OUT_CONTEXT.
1960 //----------------------------------------------------------------------------
1961 // Get index to out pipe from specified QueueID.
1962 idx_pipe = txqueue2outpipe(priv,queue_index);
1963 //printk("=============>%s queue_index:%d, outpipe:%d\n", __func__,queue_index,priv->RtOutPipes[idx_pipe]);
1964
5f53d8ca
JC
1965 usb_fill_bulk_urb(tx_urb,
1966 priv->udev,
1967 usb_sndbulkpipe(priv->udev,priv->RtOutPipes[idx_pipe]),
1968 skb->data,
1969 skb->len,
1970 rtl8192_tx_isr,
1971 skb);
1972
5f53d8ca 1973 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
5f53d8ca
JC
1974 if (!status){
1975 return 0;
1976 }else{
1977 printk("Error TX CMD URB, error %d",
1978 status);
1979 return -1;
1980 }
1981}
5f53d8ca
JC
1982
1983/*
1984 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1985 * in TxFwInfo data structure
1986 * 2006.10.30 by Emily
1987 *
1988 * \param QUEUEID Software Queue
1989*/
1990u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1991{
1992 u8 QueueSelect = 0x0; //defualt set to
1993
1994 switch(QueueID) {
1995 case BE_QUEUE:
1996 QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
1997 break;
1998
1999 case BK_QUEUE:
2000 QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
2001 break;
2002
2003 case VO_QUEUE:
2004 QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
2005 break;
2006
2007 case VI_QUEUE:
2008 QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
2009 break;
2010 case MGNT_QUEUE:
2011 QueueSelect = QSLT_MGNT;
2012 break;
2013
2014 case BEACON_QUEUE:
2015 QueueSelect = QSLT_BEACON;
2016 break;
2017
2018 // TODO: 2006.10.30 mark other queue selection until we verify it is OK
2019 // TODO: Remove Assertions
2020//#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
2021 case TXCMD_QUEUE:
2022 QueueSelect = QSLT_CMD;
2023 break;
2024//#endif
2025 case HIGH_QUEUE:
2026 QueueSelect = QSLT_HIGH;
2027 break;
2028
2029 default:
2030 RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
2031 break;
2032 }
2033 return QueueSelect;
2034}
2035
5f53d8ca
JC
2036u8 MRateToHwRate8190Pci(u8 rate)
2037{
2038 u8 ret = DESC92S_RATE1M;
2039
2040 switch(rate)
2041 {
2042 // CCK and OFDM non-HT rates
2043 case MGN_1M: ret = DESC92S_RATE1M; break;
2044 case MGN_2M: ret = DESC92S_RATE2M; break;
2045 case MGN_5_5M: ret = DESC92S_RATE5_5M; break;
2046 case MGN_11M: ret = DESC92S_RATE11M; break;
2047 case MGN_6M: ret = DESC92S_RATE6M; break;
2048 case MGN_9M: ret = DESC92S_RATE9M; break;
2049 case MGN_12M: ret = DESC92S_RATE12M; break;
2050 case MGN_18M: ret = DESC92S_RATE18M; break;
2051 case MGN_24M: ret = DESC92S_RATE24M; break;
2052 case MGN_36M: ret = DESC92S_RATE36M; break;
2053 case MGN_48M: ret = DESC92S_RATE48M; break;
2054 case MGN_54M: ret = DESC92S_RATE54M; break;
2055
2056 // HT rates since here
2057 case MGN_MCS0: ret = DESC92S_RATEMCS0; break;
2058 case MGN_MCS1: ret = DESC92S_RATEMCS1; break;
2059 case MGN_MCS2: ret = DESC92S_RATEMCS2; break;
2060 case MGN_MCS3: ret = DESC92S_RATEMCS3; break;
2061 case MGN_MCS4: ret = DESC92S_RATEMCS4; break;
2062 case MGN_MCS5: ret = DESC92S_RATEMCS5; break;
2063 case MGN_MCS6: ret = DESC92S_RATEMCS6; break;
2064 case MGN_MCS7: ret = DESC92S_RATEMCS7; break;
2065 case MGN_MCS8: ret = DESC92S_RATEMCS8; break;
2066 case MGN_MCS9: ret = DESC92S_RATEMCS9; break;
2067 case MGN_MCS10: ret = DESC92S_RATEMCS10; break;
2068 case MGN_MCS11: ret = DESC92S_RATEMCS11; break;
2069 case MGN_MCS12: ret = DESC92S_RATEMCS12; break;
2070 case MGN_MCS13: ret = DESC92S_RATEMCS13; break;
2071 case MGN_MCS14: ret = DESC92S_RATEMCS14; break;
2072 case MGN_MCS15: ret = DESC92S_RATEMCS15; break;
2073
2074 // Set the highest SG rate
2075 case MGN_MCS0_SG:
2076 case MGN_MCS1_SG:
2077 case MGN_MCS2_SG:
2078 case MGN_MCS3_SG:
2079 case MGN_MCS4_SG:
2080 case MGN_MCS5_SG:
2081 case MGN_MCS6_SG:
2082 case MGN_MCS7_SG:
2083 case MGN_MCS8_SG:
2084 case MGN_MCS9_SG:
2085 case MGN_MCS10_SG:
2086 case MGN_MCS11_SG:
2087 case MGN_MCS12_SG:
2088 case MGN_MCS13_SG:
2089 case MGN_MCS14_SG:
2090 case MGN_MCS15_SG:
2091 {
2092 ret = DESC92S_RATEMCS15_SG;
2093 break;
2094 }
2095
2096 default: break;
2097 }
2098 return ret;
2099}
5f53d8ca
JC
2100
2101u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
2102{
2103 u8 tmp_Short;
2104
2105 tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
2106
2107 if(TxHT==1 && TxRate != DESC90_RATEMCS15)
2108 tmp_Short = 0;
2109
2110 return tmp_Short;
2111}
2112
5f53d8ca 2113static void tx_zero_isr(struct urb *tx_urb)
5f53d8ca
JC
2114{
2115 return;
2116}
2117
2118
5f53d8ca
JC
2119/*
2120 * The tx procedure is just as following, skb->cb will contain all the following
2121 *information: * priority, morefrag, rate, &dev.
2122 * */
2123 // <Note> Buffer format for 8192S Usb bulk out:
2124//
2125// --------------------------------------------------
2126// | 8192S Usb Tx Desc | 802_11_MAC_header | data |
2127// --------------------------------------------------
2128// | 32 bytes | 24 bytes |0-2318 bytes|
2129// --------------------------------------------------
2130// |<------------ BufferLen ------------------------->|
2131
2132short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
2133{
2134 struct r8192_priv *priv = ieee80211_priv(dev);
2135 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
2136 tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
2137 //tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);//92su del
2138 struct usb_device *udev = priv->udev;
2139 int pend;
2140 int status;
2141 struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
2142 //int urb_len;
2143 unsigned int idx_pipe;
2144 u16 MPDUOverhead = 0;
2145 //RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
2146
5f53d8ca
JC
2147 pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
2148 /* we are locked here so the two atomic_read and inc are executed
2149 * without interleaves * !!! For debug purpose */
2150 if( pend > MAX_TX_URB){
2151 switch (tcb_desc->queue_index) {
2152 case VO_PRIORITY:
2153 priv->stats.txvodrop++;
2154 break;
2155 case VI_PRIORITY:
2156 priv->stats.txvidrop++;
2157 break;
2158 case BE_PRIORITY:
2159 priv->stats.txbedrop++;
2160 break;
2161 default://BK_PRIORITY
2162 priv->stats.txbkdrop++;
2163 break;
2164 }
2165 printk("To discard skb packet!\n");
2166 dev_kfree_skb_any(skb);
2167 return -1;
2168 }
2169
5f53d8ca 2170 tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
5f53d8ca
JC
2171 if(!tx_urb){
2172 dev_kfree_skb_any(skb);
2173 return -ENOMEM;
2174 }
2175
2176 memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
2177
2178
5f53d8ca 2179 tx_desc->NonQos = (IsQoSDataFrame(skb->data)==TRUE)? 0:1;
5f53d8ca
JC
2180
2181 /* Fill Tx descriptor */
2182 //memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
2183
2184 // This part can just fill to the first descriptor of the frame.
2185 /* DWORD 0 */
2186 tx_desc->TxHT = (tcb_desc->data_rate&0x80)?1:0;
2187
5f53d8ca
JC
2188
2189 tx_desc->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
2190 //tx_desc->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
2191 tx_desc->TxShort = QueryIsShort(tx_desc->TxHT, tx_desc->TxRate, tcb_desc);
2192
2193
2194 // Aggregation related
2195 if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
2196 tx_desc->AllowAggregation = 1;
2197 /* DWORD 1 */
2198 //tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
2199 //tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
2200 } else {
2201 tx_desc->AllowAggregation = 0;
2202 /* DWORD 1 */
2203 //tx_fwinfo->RxMF = 0;
2204 //tx_fwinfo->RxAMD = 0;
2205 }
2206
2207 //
2208 // <Roger_Notes> For AMPDU case, we must insert SSN into TX_DESC,
2209 // FW according as this SSN to do necessary packet retry.
2210 // 2008.06.06.
2211 //
2212 {
2213 u8 *pSeq;
2214 u16 Temp;
2215 //pSeq = (u8 *)(VirtualAddress+USB_HWDESC_HEADER_LEN + FRAME_OFFSET_SEQUENCE);
2216 pSeq = (u8 *)(skb->data+USB_HWDESC_HEADER_LEN + 22);
2217 Temp = pSeq[0];
2218 Temp <<= 12;
2219 Temp |= (*(u16 *)pSeq)>>4;
2220 tx_desc->Seq = Temp;
2221 }
2222
2223 /* Protection mode related */
2224 tx_desc->RTSEn = (tcb_desc->bRTSEnable)?1:0;
2225 tx_desc->CTS2Self = (tcb_desc->bCTSEnable)?1:0;
2226 tx_desc->RTSSTBC = (tcb_desc->bRTSSTBC)?1:0;
2227 tx_desc->RTSHT = (tcb_desc->rts_rate&0x80)?1:0;
2228 tx_desc->RTSRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
2229 tx_desc->RTSSubcarrier = (tx_desc->RTSHT==0)?(tcb_desc->RTSSC):0;
2230 tx_desc->RTSBW = (tx_desc->RTSHT==1)?((tcb_desc->bRTSBW)?1:0):0;
2231 tx_desc->RTSShort = (tx_desc->RTSHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
2232 (tcb_desc->bRTSUseShortGI?1:0);
2233 //LZM 090219
2234 tx_desc->DisRTSFB = 0;
2235 tx_desc->RTSRateFBLmt = 0xf;
2236
2237 // <Roger_EXP> 2008.09.22. We disable RTS rate fallback temporarily.
2238 //tx_desc->DisRTSFB = 0x01;
2239
2240 /* Set Bandwidth and sub-channel settings. */
2241 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
2242 {
2243 if(tcb_desc->bPacketBW) {
2244 tx_desc->TxBandwidth = 1;
2245 tx_desc->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
2246 } else {
2247 tx_desc->TxBandwidth = 0;
2248 tx_desc->TxSubCarrier = priv->nCur40MhzPrimeSC;
2249 }
2250 } else {
2251 tx_desc->TxBandwidth = 0;
2252 tx_desc->TxSubCarrier = 0;
2253 }
2254
5f53d8ca
JC
2255
2256 //memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
2257 /* DWORD 0 */
2258 tx_desc->LINIP = 0;
2259 //tx_desc->CmdInit = 1; //92su del
2260 tx_desc->Offset = USB_HWDESC_HEADER_LEN;
2261
5f53d8ca
JC
2262 {
2263 tx_desc->PktSize = (skb->len - USB_HWDESC_HEADER_LEN) & 0xffff;
2264 }
2265
2266 /*DWORD 1*/
2267 //tx_desc->SecCAMID= 0;//92su del
2268 tx_desc->RaBRSRID= tcb_desc->RATRIndex;
2269//#ifdef RTL8192S_PREPARE_FOR_NORMAL_RELEASE
5f53d8ca 2270
5f53d8ca
JC
2271 {
2272 MPDUOverhead = 0;
2273 //tx_desc->NoEnc = 1;//92su del
2274 }
35c1b462 2275
5f53d8ca 2276 tx_desc->SecType = 0x0;
35c1b462 2277
5f53d8ca
JC
2278 if (tcb_desc->bHwSec)
2279 {
2280 switch (priv->ieee80211->pairwise_key_type)
2281 {
2282 case KEY_TYPE_WEP40:
2283 case KEY_TYPE_WEP104:
2284 tx_desc->SecType = 0x1;
2285 //tx_desc->NoEnc = 0;//92su del
2286 break;
2287 case KEY_TYPE_TKIP:
2288 tx_desc->SecType = 0x2;
2289 //tx_desc->NoEnc = 0;//92su del
2290 break;
2291 case KEY_TYPE_CCMP:
2292 tx_desc->SecType = 0x3;
2293 //tx_desc->NoEnc = 0;//92su del
2294 break;
2295 case KEY_TYPE_NA:
2296 tx_desc->SecType = 0x0;
2297 //tx_desc->NoEnc = 1;//92su del
2298 break;
2299 default:
2300 tx_desc->SecType = 0x0;
2301 //tx_desc->NoEnc = 1;//92su del
2302 break;
2303 }
2304 }
2305
2306 //tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);//92su del
2307
2308
2309 tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
2310 tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
2311 tx_desc->DataRateFBLmt = 0x1F;// Alwasy enable all rate fallback range
2312
2313 tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
2314
2315
2316 /* Fill fields that are required to be initialized in all of the descriptors */
2317 //DWORD 0
5f53d8ca
JC
2318 tx_desc->FirstSeg = 1;
2319 tx_desc->LastSeg = 1;
5f53d8ca
JC
2320 tx_desc->OWN = 1;
2321
5f53d8ca
JC
2322 {
2323 //DWORD 2
2324 //tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
2325 tx_desc->TxBufferSize = (u32)(skb->len);//92su mod FIXLZM
2326 }
2327
5f53d8ca
JC
2328 /* Get index to out pipe from specified QueueID */
2329 idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
2330 //printk("=============>%s queue_index:%d, outpipe:%d\n", __func__,tcb_desc->queue_index,priv->RtOutPipes[idx_pipe]);
2331
2332 //RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
2333 //RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
2334
2335 /* To submit bulk urb */
2336 usb_fill_bulk_urb(tx_urb,
2337 udev,
2338 usb_sndbulkpipe(udev,priv->RtOutPipes[idx_pipe]),
2339 skb->data,
2340 skb->len, rtl8192_tx_isr, skb);
2341
5f53d8ca 2342 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
5f53d8ca
JC
2343 if (!status){
2344//we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted. Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
2345 bool bSend0Byte = false;
2346 u8 zero = 0;
2347 if(udev->speed == USB_SPEED_HIGH)
2348 {
2349 if (skb->len > 0 && skb->len % 512 == 0)
2350 bSend0Byte = true;
2351 }
2352 else
2353 {
2354 if (skb->len > 0 && skb->len % 64 == 0)
2355 bSend0Byte = true;
2356 }
2357 if (bSend0Byte)
2358 {
2359#if 1
5f53d8ca 2360 tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
5f53d8ca
JC
2361 if(!tx_urb_zero){
2362 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
2363 return -ENOMEM;
2364 }
2365 usb_fill_bulk_urb(tx_urb_zero,udev,
2366 usb_sndbulkpipe(udev,idx_pipe), &zero,
2367 0, tx_zero_isr, dev);
5f53d8ca 2368 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
5f53d8ca
JC
2369 if (status){
2370 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
2371 return -1;
2372 }
2373#endif
2374 }
2375 dev->trans_start = jiffies;
2376 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
2377 return 0;
2378 }else{
2379 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
2380 status);
2381 return -1;
2382 }
2383}
5f53d8ca 2384
35c1b462 2385void rtl8192SU_net_update(struct net_device *dev)
5f53d8ca
JC
2386{
2387
2388 struct r8192_priv *priv = ieee80211_priv(dev);
2389 struct ieee80211_device* ieee = priv->ieee80211;
2390 struct ieee80211_network *net = &priv->ieee80211->current_network;
2391 //u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
2392 u16 rate_config = 0;
2393 u32 regTmp = 0;
2394 u8 rateIndex = 0;
2395 u8 retrylimit = 0x30;
2396 u16 cap = net->capability;
2397
2398 priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
2399
2400//HW_VAR_BASIC_RATE
2401 //update Basic rate: RR, BRSR
2402 rtl8192_config_rate(dev, &rate_config); //HalSetBrateCfg
2403
5f53d8ca 2404 priv->basic_rate = rate_config = rate_config & 0x15f;
5f53d8ca
JC
2405
2406 // Set RRSR rate table.
2407 write_nic_byte(dev, RRSR, rate_config&0xff);
2408 write_nic_byte(dev, RRSR+1, (rate_config>>8)&0xff);
2409
2410 // Set RTS initial rate
2411 while(rate_config > 0x1)
2412 {
2413 rate_config = (rate_config>> 1);
2414 rateIndex++;
2415 }
2416 write_nic_byte(dev, INIRTSMCS_SEL, rateIndex);
2417//HW_VAR_BASIC_RATE
2418
2419 //set ack preample
2420 regTmp = (priv->nCur40MhzPrimeSC) << 5;
2421 if (priv->short_preamble)
2422 regTmp |= 0x80;
2423 write_nic_byte(dev, RRSR+2, regTmp);
2424
2425 write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
2426 write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
2427
2428 write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
2429 //2008.10.24 added by tynli for beacon changed.
2430 PHY_SetBeaconHwReg( dev, net->beacon_interval);
2431
2432 rtl8192_update_cap(dev, cap);
2433
2434 if (ieee->iw_mode == IW_MODE_ADHOC){
2435 retrylimit = 7;
2436 //we should enable ibss interrupt here, but disable it temporarily
2437 if (0){
2438 priv->irq_mask |= (IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
2439 //rtl8192_irq_disable(dev);
2440 //rtl8192_irq_enable(dev);
2441 }
2442 }
2443 else{
2444 if (0){
2445 priv->irq_mask &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
2446 //rtl8192_irq_disable(dev);
2447 //rtl8192_irq_enable(dev);
2448 }
2449 }
2450
2451 priv->ShortRetryLimit = priv->LongRetryLimit = retrylimit;
2452
2453 write_nic_word(dev, RETRY_LIMIT,
2454 retrylimit << RETRY_LIMIT_SHORT_SHIFT | \
2455 retrylimit << RETRY_LIMIT_LONG_SHIFT);
2456}
2457
2458void rtl8192SU_update_ratr_table(struct net_device* dev)
2459{
2460 struct r8192_priv* priv = ieee80211_priv(dev);
2461 struct ieee80211_device* ieee = priv->ieee80211;
2462 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2463 //struct ieee80211_network *net = &ieee->current_network;
2464 u32 ratr_value = 0;
2465
2466 u8 rate_index = 0;
2467 int WirelessMode = ieee->mode;
2468 u8 MimoPs = ieee->pHTInfo->PeerMimoPs;
2469
2470 u8 bNMode = 0;
2471
2472 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2473 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2474
2475 //switch (ieee->mode)
2476 switch (WirelessMode)
2477 {
2478 case IEEE_A:
2479 ratr_value &= 0x00000FF0;
2480 break;
2481 case IEEE_B:
2482 ratr_value &= 0x0000000D;
2483 break;
2484 case IEEE_G:
2485 ratr_value &= 0x00000FF5;
2486 break;
2487 case IEEE_N_24G:
2488 case IEEE_N_5G:
2489 {
2490 bNMode = 1;
2491
2492 if (MimoPs == 0) //MIMO_PS_STATIC
2493 {
2494 ratr_value &= 0x0007F005;
2495 }
2496 else
2497 { // MCS rate only => for 11N mode.
2498 u32 ratr_mask;
2499
2500 // 1T2R or 1T1R, Spatial Stream 2 should be disabled
2501 if ( priv->rf_type == RF_1T2R ||
2502 priv->rf_type == RF_1T1R ||
2503 (ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_TX_2SS) )
2504 ratr_mask = 0x000ff005;
2505 else
2506 ratr_mask = 0x0f0ff005;
2507
2508 if((ieee->pHTInfo->bCurTxBW40MHz) &&
2509 !(ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_TX_40_MHZ))
2510 ratr_mask |= 0x00000010; // Set 6MBps
2511
2512 // Select rates for rate adaptive mechanism.
2513 ratr_value &= ratr_mask;
2514 }
2515 }
2516 break;
2517 default:
2518 if(0)
2519 {
2520 if(priv->rf_type == RF_1T2R) // 1T2R, Spatial Stream 2 should be disabled
2521 {
2522 ratr_value &= 0x000ff0f5;
2523 }
2524 else
2525 {
2526 ratr_value &= 0x0f0ff0f5;
2527 }
2528 }
2529 //printk("====>%s(), mode is not correct:%x\n", __FUNCTION__, ieee->mode);
2530 break;
2531 }
2532
5f53d8ca 2533 ratr_value &= 0x0FFFFFFF;
5f53d8ca
JC
2534
2535 // Get MAX MCS available.
2536 if ( (bNMode && ((ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_SHORT_GI)==0)) &&
2537 ((ieee->pHTInfo->bCurBW40MHz && ieee->pHTInfo->bCurShortGI40MHz) ||
2538 (!ieee->pHTInfo->bCurBW40MHz && ieee->pHTInfo->bCurShortGI20MHz)))
2539 {
2540 u8 shortGI_rate = 0;
2541 u32 tmp_ratr_value = 0;
2542 ratr_value |= 0x10000000;//???
2543 tmp_ratr_value = (ratr_value>>12);
2544 for(shortGI_rate=15; shortGI_rate>0; shortGI_rate--)
2545 {
2546 if((1<<shortGI_rate) & tmp_ratr_value)
2547 break;
2548 }
2549 shortGI_rate = (shortGI_rate<<12)|(shortGI_rate<<8)|(shortGI_rate<<4)|(shortGI_rate);
2550 write_nic_byte(dev, SG_RATE, shortGI_rate);
2551 //printk("==>SG_RATE:%x\n", read_nic_byte(dev, SG_RATE));
2552 }
2553 write_nic_dword(dev, ARFR0+rate_index*4, ratr_value);
2554 printk("=============>ARFR0+rate_index*4:%#x\n", ratr_value);
2555
2556 //2 UFWP
2557 if (ratr_value & 0xfffff000){
2558 //printk("===>set to N mode\n");
2559 HalSetFwCmd8192S(dev, FW_CMD_RA_REFRESH_N);
2560 }
2561 else {
2562 //printk("===>set to B/G mode\n");
2563 HalSetFwCmd8192S(dev, FW_CMD_RA_REFRESH_BG);
2564 }
2565}
2566
2567void rtl8192SU_link_change(struct net_device *dev)
2568{
2569 struct r8192_priv *priv = ieee80211_priv(dev);
2570 struct ieee80211_device* ieee = priv->ieee80211;
2571 //unsigned long flags;
2572 u32 reg = 0;
2573
2574 printk("=====>%s 1\n", __func__);
2575 reg = read_nic_dword(dev, RCR);
2576
2577 if (ieee->state == IEEE80211_LINKED)
2578 {
2579
2580 rtl8192SU_net_update(dev);
2581 rtl8192SU_update_ratr_table(dev);
2582 ieee->SetFwCmdHandler(dev, FW_CMD_HIGH_PWR_ENABLE);
2583 priv->ReceiveConfig = reg |= RCR_CBSSID;
2584
2585 }else{
2586 priv->ReceiveConfig = reg &= ~RCR_CBSSID;
2587
2588 }
2589
2590 write_nic_dword(dev, RCR, reg);
2591 rtl8192_update_msr(dev);
2592
2593 printk("<=====%s 2\n", __func__);
2594}
5f53d8ca
JC
2595
2596static struct ieee80211_qos_parameters def_qos_parameters = {
2597 {3,3,3,3},/* cw_min */
2598 {7,7,7,7},/* cw_max */
2599 {2,2,2,2},/* aifs */
2600 {0,0,0,0},/* flags */
2601 {0,0,0,0} /* tx_op_limit */
2602};
2603
2604
5f53d8ca
JC
2605void rtl8192_update_beacon(struct work_struct * work)
2606{
2607 struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
2608 struct net_device *dev = priv->ieee80211->dev;
5f53d8ca
JC
2609 struct ieee80211_device* ieee = priv->ieee80211;
2610 struct ieee80211_network* net = &ieee->current_network;
2611
2612 if (ieee->pHTInfo->bCurrentHTSupport)
2613 HTUpdateSelfAndPeerSetting(ieee, net);
2614 ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
2615 // Joseph test for turbo mode with AP
2616 ieee->pHTInfo->RT2RT_HT_Mode = net->bssht.RT2RT_HT_Mode;
2617 rtl8192_update_cap(dev, net->capability);
2618}
2619/*
2620* background support to run QoS activate functionality
2621*/
2622int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
1ec9e48d 2623
5f53d8ca
JC
2624void rtl8192_qos_activate(struct work_struct * work)
2625{
2626 struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
2627 struct net_device *dev = priv->ieee80211->dev;
5f53d8ca
JC
2628 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2629 u8 mode = priv->ieee80211->current_network.mode;
2630 //u32 size = sizeof(struct ieee80211_qos_parameters);
2631 u8 u1bAIFS;
2632 u32 u4bAcParam;
2633 int i;
2634
2635 if (priv == NULL)
2636 return;
2637
5f53d8ca 2638 mutex_lock(&priv->mutex);
1ec9e48d 2639
5f53d8ca
JC
2640 if(priv->ieee80211->state != IEEE80211_LINKED)
2641 goto success;
2642 RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
2643 /* It better set slot time at first */
2644 /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2645 /* update the ac parameter to related registers */
2646 for(i = 0; i < QOS_QUEUE_NUM; i++) {
2647 //Mode G/A: slotTimeTimer = 9; Mode B: 20
2648 u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2649 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2650 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2651 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2652 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2653
2654 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2655 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4322);
2656 }
2657
2658success:
5f53d8ca 2659 mutex_unlock(&priv->mutex);
5f53d8ca
JC
2660}
2661
2662static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2663 int active_network,
2664 struct ieee80211_network *network)
2665{
2666 int ret = 0;
2667 u32 size = sizeof(struct ieee80211_qos_parameters);
2668
2669 if(priv->ieee80211->state !=IEEE80211_LINKED)
2670 return ret;
2671
2672 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2673 return ret;
2674
2675 if (network->flags & NETWORK_HAS_QOS_MASK) {
2676 if (active_network &&
2677 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2678 network->qos_data.active = network->qos_data.supported;
2679
2680 if ((network->qos_data.active == 1) && (active_network == 1) &&
2681 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2682 (network->qos_data.old_param_count !=
2683 network->qos_data.param_count)) {
2684 network->qos_data.old_param_count =
2685 network->qos_data.param_count;
5f53d8ca 2686 queue_work(priv->priv_wq, &priv->qos_activate);
5f53d8ca
JC
2687 RT_TRACE (COMP_QOS, "QoS parameters change call "
2688 "qos_activate\n");
2689 }
2690 } else {
2691 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2692 &def_qos_parameters, size);
2693
2694 if ((network->qos_data.active == 1) && (active_network == 1)) {
5f53d8ca 2695 queue_work(priv->priv_wq, &priv->qos_activate);
5f53d8ca
JC
2696 RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2697 }
2698 network->qos_data.active = 0;
2699 network->qos_data.supported = 0;
2700 }
2701
2702 return 0;
2703}
2704
2705/* handle manage frame frame beacon and probe response */
2706static int rtl8192_handle_beacon(struct net_device * dev,
f59d0127
BZ
2707 struct ieee80211_probe_response *beacon,
2708 struct ieee80211_network *network)
5f53d8ca
JC
2709{
2710 struct r8192_priv *priv = ieee80211_priv(dev);
2711
2712 rtl8192_qos_handle_probe_response(priv,1,network);
5f53d8ca 2713 queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
5f53d8ca 2714
5f53d8ca
JC
2715 return 0;
2716
2717}
2718
2719/*
2720* handling the beaconing responses. if we get different QoS setting
2721* off the network from the associated setting, adjust the QoS
2722* setting
2723*/
2724static int rtl8192_qos_association_resp(struct r8192_priv *priv,
2725 struct ieee80211_network *network)
2726{
2727 int ret = 0;
2728 unsigned long flags;
2729 u32 size = sizeof(struct ieee80211_qos_parameters);
2730 int set_qos_param = 0;
2731
2732 if ((priv == NULL) || (network == NULL))
2733 return ret;
2734
2735 if(priv->ieee80211->state !=IEEE80211_LINKED)
2736 return ret;
2737
2738 if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2739 return ret;
2740
2741 spin_lock_irqsave(&priv->ieee80211->lock, flags);
2742 if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2743 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2744 &network->qos_data.parameters,\
2745 sizeof(struct ieee80211_qos_parameters));
2746 priv->ieee80211->current_network.qos_data.active = 1;
5f53d8ca
JC
2747 {
2748 set_qos_param = 1;
2749 /* update qos parameter for current network */
2750 priv->ieee80211->current_network.qos_data.old_param_count = \
2751 priv->ieee80211->current_network.qos_data.param_count;
2752 priv->ieee80211->current_network.qos_data.param_count = \
2753 network->qos_data.param_count;
2754 }
2755 } else {
2756 memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2757 &def_qos_parameters, size);
2758 priv->ieee80211->current_network.qos_data.active = 0;
2759 priv->ieee80211->current_network.qos_data.supported = 0;
2760 set_qos_param = 1;
2761 }
2762
2763 spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2764
2765 RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
2766 if (set_qos_param == 1)
5f53d8ca 2767 queue_work(priv->priv_wq, &priv->qos_activate);
5f53d8ca
JC
2768
2769 return ret;
2770}
2771
2772
2773static int rtl8192_handle_assoc_response(struct net_device *dev,
2774 struct ieee80211_assoc_response_frame *resp,
2775 struct ieee80211_network *network)
2776{
2777 struct r8192_priv *priv = ieee80211_priv(dev);
2778 rtl8192_qos_association_resp(priv, network);
2779 return 0;
2780}
2781
2782
2783void rtl8192_update_ratr_table(struct net_device* dev)
2784 // POCTET_STRING posLegacyRate,
2785 // u8* pMcsRate)
2786 // PRT_WLAN_STA pEntry)
2787{
2788 struct r8192_priv* priv = ieee80211_priv(dev);
2789 struct ieee80211_device* ieee = priv->ieee80211;
2790 u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2791 //struct ieee80211_network *net = &ieee->current_network;
2792 u32 ratr_value = 0;
2793 u8 rate_index = 0;
2794 rtl8192_config_rate(dev, (u16*)(&ratr_value));
2795 ratr_value |= (*(u16*)(pMcsRate)) << 12;
2796// switch (net->mode)
2797 switch (ieee->mode)
2798 {
2799 case IEEE_A:
2800 ratr_value &= 0x00000FF0;
2801 break;
2802 case IEEE_B:
2803 ratr_value &= 0x0000000F;
2804 break;
2805 case IEEE_G:
2806 ratr_value &= 0x00000FF7;
2807 break;
2808 case IEEE_N_24G:
2809 case IEEE_N_5G:
2810 if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2811 ratr_value &= 0x0007F007;
2812 else{
2813 if (priv->rf_type == RF_1T2R)
2814 ratr_value &= 0x000FF007;
2815 else
2816 ratr_value &= 0x0F81F007;
2817 }
2818 break;
2819 default:
2820 break;
2821 }
2822 ratr_value &= 0x0FFFFFFF;
2823 if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2824 ratr_value |= 0x80000000;
2825 }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2826 ratr_value |= 0x80000000;
2827 }
2828 write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2829 write_nic_byte(dev, UFWP, 1);
2830}
2831
2832static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
2833static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2834bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
2835{
2836#if 1
2837 struct r8192_priv* priv = ieee80211_priv(dev);
2838 struct ieee80211_device* ieee = priv->ieee80211;
2839 struct ieee80211_network * network = &ieee->current_network;
2840 int wpa_ie_len= ieee->wpa_ie_len;
2841 struct ieee80211_crypt_data* crypt;
2842 int encrypt;
5f53d8ca 2843 return TRUE;
5f53d8ca
JC
2844
2845 crypt = ieee->crypt[ieee->tx_keyidx];
2846 //we use connecting AP's capability instead of only security config on our driver to distinguish whether it should use N mode or G mode
2847 encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2848
2849 /* simply judge */
2850 if(encrypt && (wpa_ie_len == 0)) {
2851 /* wep encryption, no N mode setting */
2852 return false;
2853// } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2854 } else if((wpa_ie_len != 0)) {
2855 /* parse pairwise key type */
2856 //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2857 if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) || ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
2858 return true;
2859 else
2860 return false;
2861 } else {
2862 return true;
2863 }
2864
5f53d8ca
JC
2865 return true;
2866#endif
2867}
2868
2869bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
2870{
2871 bool Reval;
2872 struct r8192_priv* priv = ieee80211_priv(dev);
2873 struct ieee80211_device* ieee = priv->ieee80211;
2874
2875// Added by Roger, 2008.08.29.
5f53d8ca 2876 return false;
5f53d8ca
JC
2877
2878 if(ieee->bHalfWirelessN24GMode == true)
2879 Reval = true;
2880 else
2881 Reval = false;
2882
2883 return Reval;
2884}
2885
2886void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2887{
2888 struct ieee80211_device* ieee = priv->ieee80211;
2889 //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2890 if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2891 {
2892 memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2893 //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2894 //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2895 }
2896 else
2897 memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2898 return;
2899}
2900
2901u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2902{
2903 struct r8192_priv *priv = ieee80211_priv(dev);
2904 u8 ret = 0;
2905 switch(priv->rf_chip)
2906 {
2907 case RF_8225:
2908 case RF_8256:
2909 case RF_PSEUDO_11N:
2910 case RF_6052:
2911 ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2912 break;
2913 case RF_8258:
2914 ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2915 break;
2916 default:
2917 ret = WIRELESS_MODE_B;
2918 break;
2919 }
2920 return ret;
2921}
2922void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2923{
2924 struct r8192_priv *priv = ieee80211_priv(dev);
2925 u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2926
2927#if 1
2928 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2929 {
2930 if(bSupportMode & WIRELESS_MODE_N_24G)
2931 {
2932 wireless_mode = WIRELESS_MODE_N_24G;
2933 }
2934 else if(bSupportMode & WIRELESS_MODE_N_5G)
2935 {
2936 wireless_mode = WIRELESS_MODE_N_5G;
2937 }
2938 else if((bSupportMode & WIRELESS_MODE_A))
2939 {
2940 wireless_mode = WIRELESS_MODE_A;
2941 }
2942 else if((bSupportMode & WIRELESS_MODE_G))
2943 {
2944 wireless_mode = WIRELESS_MODE_G;
2945 }
2946 else if((bSupportMode & WIRELESS_MODE_B))
2947 {
2948 wireless_mode = WIRELESS_MODE_B;
2949 }
2950 else{
2951 RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2952 wireless_mode = WIRELESS_MODE_B;
2953 }
2954 }
39cfb97b 2955#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
5f53d8ca
JC
2956 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2957#endif
5f53d8ca
JC
2958 //LZM 090306 usb crash here, mark it temp
2959 //write_nic_word(dev, SIFS_OFDM, 0x0e0e);
5f53d8ca
JC
2960 priv->ieee80211->mode = wireless_mode;
2961
2962 if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
2963 priv->ieee80211->pHTInfo->bEnableHT = 1;
2964 else
2965 priv->ieee80211->pHTInfo->bEnableHT = 0;
2966 RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2967 rtl8192_refresh_supportrate(priv);
2968#endif
2969
2970}
2971
2972
2973short rtl8192_is_tx_queue_empty(struct net_device *dev)
2974{
2975 int i=0;
2976 struct r8192_priv *priv = ieee80211_priv(dev);
2977 //struct ieee80211_device* ieee = priv->ieee80211;
2978 for (i=0; i<=MGNT_QUEUE; i++)
2979 {
2980 if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
2981 continue;
2982 if (atomic_read(&priv->tx_pending[i]))
2983 {
2984 printk("===>tx queue is not empty:%d, %d\n", i, atomic_read(&priv->tx_pending[i]));
2985 return 0;
2986 }
2987 }
2988 return 1;
2989}
35c1b462 2990
5f53d8ca
JC
2991void rtl8192_hw_sleep_down(struct net_device *dev)
2992{
2993 RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__);
2994#ifdef TODO
2995// MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
2996#endif
2997}
1ec9e48d 2998
5f53d8ca
JC
2999void rtl8192_hw_sleep_wq (struct work_struct *work)
3000{
3001// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
3002// struct ieee80211_device * ieee = (struct ieee80211_device*)
3003// container_of(work, struct ieee80211_device, watch_dog_wq);
3004 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
3005 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
3006 struct net_device *dev = ieee->dev;
1ec9e48d 3007
5f53d8ca
JC
3008 //printk("=========>%s()\n", __FUNCTION__);
3009 rtl8192_hw_sleep_down(dev);
3010}
3011// printk("dev is %d\n",dev);
3012// printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
3013void rtl8192_hw_wakeup(struct net_device* dev)
3014{
3015// u32 flags = 0;
3016
3017// spin_lock_irqsave(&priv->ps_lock,flags);
3018 RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__);
3019#ifdef TODO
3020// MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
3021#endif
3022 //FIXME: will we send package stored while nic is sleep?
3023// spin_unlock_irqrestore(&priv->ps_lock,flags);
3024}
1ec9e48d 3025
5f53d8ca
JC
3026void rtl8192_hw_wakeup_wq (struct work_struct *work)
3027{
3028// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
3029// struct ieee80211_device * ieee = (struct ieee80211_device*)
3030// container_of(work, struct ieee80211_device, watch_dog_wq);
3031 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
3032 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
3033 struct net_device *dev = ieee->dev;
5f53d8ca 3034
1ec9e48d 3035 rtl8192_hw_wakeup(dev);
5f53d8ca
JC
3036}
3037
3038#define MIN_SLEEP_TIME 50
3039#define MAX_SLEEP_TIME 10000
3040void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
3041{
3042
3043 struct r8192_priv *priv = ieee80211_priv(dev);
3044
3045 u32 rb = jiffies;
3046 unsigned long flags;
3047
3048 spin_lock_irqsave(&priv->ps_lock,flags);
3049
3050 /* Writing HW register with 0 equals to disable
3051 * the timer, that is not really what we want
3052 */
3053 tl -= MSECS(4+16+7);
3054
3055 //if(tl == 0) tl = 1;
3056
3057 /* FIXME HACK FIXME HACK */
3058// force_pci_posting(dev);
3059 //mdelay(1);
3060
3061// rb = read_nic_dword(dev, TSFTR);
3062
3063 /* If the interval in witch we are requested to sleep is too
3064 * short then give up and remain awake
3065 */
3066 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
3067 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
3068 spin_unlock_irqrestore(&priv->ps_lock,flags);
3069 printk("too short to sleep\n");
3070 return;
3071 }
3072
3073// write_nic_dword(dev, TimerInt, tl);
3074// rb = read_nic_dword(dev, TSFTR);
3075 {
3076 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
3077 // if (tl<rb)
3078
5f53d8ca 3079 queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
5f53d8ca
JC
3080 }
3081 /* if we suspect the TimerInt is gone beyond tl
3082 * while setting it, then give up
3083 */
3084#if 1
3085 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
3086 ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
3087 printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
3088 spin_unlock_irqrestore(&priv->ps_lock,flags);
3089 return;
3090 }
3091#endif
3092// if(priv->rf_sleep)
3093// priv->rf_sleep(dev);
3094
3095 //printk("<=========%s()\n", __FUNCTION__);
5f53d8ca 3096 queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0);
1ec9e48d 3097
5f53d8ca
JC
3098 spin_unlock_irqrestore(&priv->ps_lock,flags);
3099}
3100//init priv variables here. only non_zero value should be initialized here.
3101static void rtl8192_init_priv_variable(struct net_device* dev)
3102{
3103 struct r8192_priv *priv = ieee80211_priv(dev);
3104 u8 i;
3105 priv->card_8192 = NIC_8192U;
3106 priv->chan = 1; //set to channel 1
3107 priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
3108 priv->ieee80211->iw_mode = IW_MODE_INFRA;
3109 priv->ieee80211->ieee_up=0;
3110 priv->retry_rts = DEFAULT_RETRY_RTS;
3111 priv->retry_data = DEFAULT_RETRY_DATA;
3112 priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
3113 priv->ieee80211->rate = 110; //11 mbps
3114 priv->ieee80211->short_slot = 1;
3115 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
3116 priv->CckPwEnl = 6;
3117 //for silent reset
3118 priv->IrpPendingCount = 1;
3119 priv->ResetProgress = RESET_TYPE_NORESET;
3120 priv->bForcedSilentReset = 0;
3121 priv->bDisableNormalResetCheck = false;
3122 priv->force_reset = false;
3123
3124 priv->ieee80211->FwRWRF = 0; //we don't use FW read/write RF until stable firmware is available.
3125 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
3126 priv->ieee80211->iw_mode = IW_MODE_INFRA;
3127 priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
3128 IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
3129 IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
3130 IEEE_SOFTMAC_BEACONS;//added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
3131
3132 priv->ieee80211->active_scan = 1;
3133 priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
3134 priv->ieee80211->host_encrypt = 1;
3135 priv->ieee80211->host_decrypt = 1;
3136 priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
3137 priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
3138 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
3139 priv->ieee80211->set_chan = rtl8192_set_chan;
3140 priv->ieee80211->link_change = priv->ops->rtl819x_link_change;
3141 priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
3142 priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
3143 priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
3144 priv->ieee80211->init_wmmparam_flag = 0;
3145 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
3146 priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
3147 priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
3148 priv->ieee80211->qos_support = 1;
3149
3150 //added by WB
3151// priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
3152 priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
3153 priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
3154 priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
3155 //for LPS
3156 priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
3157// priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
3158 priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
3159 priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
3160 //added by david
3161 priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
3162 priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
3163 priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
3164 //added by amy
3165 priv->ieee80211->InitialGainHandler = priv->ops->rtl819x_initial_gain;
3166 priv->card_type = USB;
3167
5f53d8ca
JC
3168//1 RTL8192SU/
3169 priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
3170 priv->ieee80211->SetFwCmdHandler = HalSetFwCmd8192S;
3171 priv->bRFSiOrPi = 0;//o=si,1=pi;
3172 //lzm add
3173 priv->bInHctTest = false;
3174
3175 priv->MidHighPwrTHR_L1 = 0x3B;
3176 priv->MidHighPwrTHR_L2 = 0x40;
3177
3178 if(priv->bInHctTest)
3179 {
3180 priv->ShortRetryLimit = HAL_RETRY_LIMIT_AP_ADHOC;
3181 priv->LongRetryLimit = HAL_RETRY_LIMIT_AP_ADHOC;
3182 }
3183 else
3184 {
3185 priv->ShortRetryLimit = HAL_RETRY_LIMIT_INFRA;
3186 priv->LongRetryLimit = HAL_RETRY_LIMIT_INFRA;
3187 }
3188
3189 priv->SetFwCmdInProgress = false; //is set FW CMD in Progress? 92S only
3190 priv->CurrentFwCmdIO = 0;
3191
3192 priv->MinSpaceCfg = 0;
3193
3194 priv->EarlyRxThreshold = 7;
3195 priv->enable_gpio0 = 0;
3196 priv->TransmitConfig =
3197 ((u32)TCR_MXDMA_2048<<TCR_MXDMA_OFFSET) | // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
3198 (priv->ShortRetryLimit<<TCR_SRL_OFFSET) | // Short retry limit
3199 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
3200 (false ? TCR_SAT : 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
3201 if(priv->bInHctTest)
3202 priv->ReceiveConfig = //priv->CSMethod |
3203 RCR_AMF | RCR_ADF | //RCR_AAP | //accept management/data
3204 RCR_ACF |RCR_APPFCS| //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
3205 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
3206 RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
3207 RCR_APP_PHYST_STAFF | RCR_APP_PHYST_RXFF | // Accept PHY status
3208 ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
3209 (priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
3210 (priv->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
3211 else
3212 priv->ReceiveConfig = //priv->CSMethod |
3213 RCR_AMF | RCR_ADF | RCR_AB |
3214 RCR_AM | RCR_APM |RCR_AAP |RCR_ADD3|RCR_APP_ICV|
3215 RCR_APP_PHYST_STAFF | RCR_APP_PHYST_RXFF | // Accept PHY status
3216 RCR_APP_MIC | RCR_APPFCS;
3217
3218 // <Roger_EXP> 2008.06.16.
3219 priv->IntrMask = (u16)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK | \
3220 IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK | \
3221 IMR_BDOK | IMR_RXCMDOK | /*IMR_TIMEOUT0 |*/ IMR_RDU | IMR_RXFOVW | \
3222 IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
3223
3224//1 End
3225
5f53d8ca
JC
3226
3227 priv->AcmControl = 0;
3228 priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
3229 if (priv->pFirmware)
3230 memset(priv->pFirmware, 0, sizeof(rt_firmware));
3231
3232 /* rx related queue */
3233 skb_queue_head_init(&priv->rx_queue);
3234 skb_queue_head_init(&priv->skb_queue);
3235
3236 /* Tx related queue */
3237 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
3238 skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
3239 }
3240 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
3241 skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
3242 }
3243 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
3244 skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ [i]);
3245 }
3246 priv->rf_set_chan = rtl8192_phy_SwChnl;
3247}
3248
3249//init lock here
3250static void rtl8192_init_priv_lock(struct r8192_priv* priv)
3251{
3252 spin_lock_init(&priv->tx_lock);
3253 spin_lock_init(&priv->irq_lock);//added by thomas
3254 //spin_lock_init(&priv->rf_lock);//use rf_sem, or will crash in some OS.
3255 sema_init(&priv->wx_sem,1);
3256 sema_init(&priv->rf_sem,1);
3257 spin_lock_init(&priv->ps_lock);
5f53d8ca 3258 mutex_init(&priv->mutex);
5f53d8ca
JC
3259}
3260
5f53d8ca 3261extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
5f53d8ca
JC
3262
3263void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
3264//init tasklet and wait_queue here. only 2.6 above kernel is considered
3265#define DRV_NAME "wlan0"
3266static void rtl8192_init_priv_task(struct net_device* dev)
3267{
3268 struct r8192_priv *priv = ieee80211_priv(dev);
3269
5f53d8ca
JC
3270#ifdef PF_SYNCTHREAD
3271 priv->priv_wq = create_workqueue(DRV_NAME,0);
3272#else
3273 priv->priv_wq = create_workqueue(DRV_NAME);
3274#endif
5f53d8ca 3275
5f53d8ca
JC
3276 INIT_WORK(&priv->reset_wq, rtl8192_restart);
3277
3278 //INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
3279 INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
3280 INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
3281// INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback);
3282 INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
3283 INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
3284 INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
3285 //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
3286 //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
3287 INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
3288 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
3289 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
3290
5f53d8ca
JC
3291 tasklet_init(&priv->irq_rx_tasklet,
3292 (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
3293 (unsigned long)priv);
3294}
3295
3296static void rtl8192_get_eeprom_size(struct net_device* dev)
3297{
3298 u16 curCR = 0;
3299 struct r8192_priv *priv = ieee80211_priv(dev);
3300 RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
3301 curCR = read_nic_word_E(dev,EPROM_CMD);
3302 RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
3303 //whether need I consider BIT5?
3304 priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
3305 RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
3306}
3307
3308//used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
3309static inline u16 endian_swap(u16* data)
3310{
3311 u16 tmp = *data;
3312 *data = (tmp >> 8) | (tmp << 8);
3313 return *data;
3314}
3315
5f53d8ca
JC
3316u8 rtl8192SU_UsbOptionToEndPointNumber(u8 UsbOption)
3317{
3318 u8 nEndPoint = 0;
3319 switch(UsbOption)
3320 {
3321 case 0:
3322 nEndPoint = 6;
3323 break;
3324 case 1:
3325 nEndPoint = 11;
3326 break;
3327 case 2:
3328 nEndPoint = 4;
3329 break;
3330 default:
3331 RT_TRACE(COMP_INIT, "UsbOptionToEndPointNumber(): Invalid UsbOption(%#x)\n", UsbOption);
3332 break;
3333 }
3334 return nEndPoint;
3335}
3336
3337u8 rtl8192SU_BoardTypeToRFtype(struct net_device* dev, u8 Boardtype)
3338{
3339 u8 RFtype = RF_1T2R;
3340
3341 switch(Boardtype)
3342 {
3343 case 0:
3344 RFtype = RF_1T1R;
3345 break;
3346 case 1:
3347 RFtype = RF_1T2R;
3348 break;
3349 case 2:
3350 RFtype = RF_2T2R;
3351 break;
3352 case 3:
3353 RFtype = RF_2T2R_GREEN;
3354 break;
3355 default:
3356 break;
3357 }
3358
3359 return RFtype;
3360}
3361
88e05d85
DC
3362void update_hal_variables(struct r8192_priv *priv)
3363{
3364 int rf_path;
3365 int i;
3366 u8 index;
3367
3368 for (rf_path = 0; rf_path < 2; rf_path++) {
3369 for (i = 0; i < 3; i++) {
3370 RT_TRACE((COMP_INIT), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfCckChnlAreaTxPwr[rf_path][i]);
3371 RT_TRACE((COMP_INIT), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
3372 RT_TRACE((COMP_INIT), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
3373 }
3374 /* Assign dedicated channel tx power */
3375 for(i = 0; i < 14; i++) {
3376 /* channel 1-3 use the same Tx Power Level. */
3377 if (i < 3) /* Channel 1-3 */
3378 index = 0;
3379 else if (i < 9) /* Channel 4-9 */
3380 index = 1;
3381 else /* Channel 10-14 */
3382 index = 2;
3383 /* Record A & B CCK /OFDM - 1T/2T Channel area tx power */
3384 priv->RfTxPwrLevelCck[rf_path][i] = priv->RfCckChnlAreaTxPwr[rf_path][index];
3385 priv->RfTxPwrLevelOfdm1T[rf_path][i] = priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
3386 priv->RfTxPwrLevelOfdm2T[rf_path][i] = priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
3387 if (rf_path == 0) {
3388 priv->TxPowerLevelOFDM24G[i] = priv->RfTxPwrLevelOfdm1T[rf_path][i] ;
3389 priv->TxPowerLevelCCK[i] = priv->RfTxPwrLevelCck[rf_path][i];
3390 }
3391 }
3392 for(i = 0; i < 14; i++) {
3393 RT_TRACE((COMP_INIT),
3394 "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
3395 rf_path, i, priv->RfTxPwrLevelCck[rf_path][i],
3396 priv->RfTxPwrLevelOfdm1T[rf_path][i] ,
3397 priv->RfTxPwrLevelOfdm2T[rf_path][i] );
3398 }
3399 }
3400}
3401
5f53d8ca
JC
3402//
3403// Description:
3404// Config HW adapter information into initial value.
3405//
3406// Assumption:
3407// 1. After Auto load fail(i.e, check CR9346 fail)
3408//
3409// Created by Roger, 2008.10.21.
3410//
3411void
3412rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev)
3413{
3414 struct r8192_priv *priv = ieee80211_priv(dev);
3415 //u16 i,usValue;
3416 //u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
88e05d85 3417 u8 rf_path; // For EEPROM/EFUSE After V0.6_1117
5f53d8ca
JC
3418 int i;
3419
3420 RT_TRACE(COMP_INIT, "====> ConfigAdapterInfo8192SForAutoLoadFail\n");
3421
3422 write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
3423 //PlatformStallExecution(10000);
3424 mdelay(10);
3425 write_nic_byte(dev, PMC_FSM, 0x02); // Enable Loader Data Keep
3426
3427 //RT_ASSERT(priv->AutoloadFailFlag==TRUE, ("ReadAdapterInfo8192SEEPROM(): AutoloadFailFlag !=TRUE\n"));
3428
3429 // Initialize IC Version && Channel Plan
3430 priv->eeprom_vid = 0;
3431 priv->eeprom_pid = 0;
3432 priv->card_8192_version = 0;
3433 priv->eeprom_ChannelPlan = 0;
3434 priv->eeprom_CustomerID = 0;
3435 priv->eeprom_SubCustomerID = 0;
3436 priv->bIgnoreDiffRateTxPowerOffset = false;
3437
3438 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
3439 RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
3440 RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
3441 RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID);
3442 RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan);
3443 RT_TRACE(COMP_INIT, "IgnoreDiffRateTxPowerOffset = %d\n", priv->bIgnoreDiffRateTxPowerOffset);
3444
3445
3446
3447 priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
3448 RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
3449
35c1b462
BZ
3450 for(i=0; i<5; i++)
3451 priv->EEPROMUsbPhyParam[i] = EEPROM_USB_Default_PHY_PARAM;
5f53d8ca 3452
35c1b462 3453 //RT_PRINT_DATA(COMP_INIT|COMP_EFUSE, DBG_LOUD, ("EFUSE USB PHY Param: \n"), priv->EEPROMUsbPhyParam, 5);
5f53d8ca 3454
35c1b462
BZ
3455 {
3456 //<Roger_Notes> In this case, we random assigh MAC address here. 2008.10.15.
5f53d8ca
JC
3457 static u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
3458 u8 i;
3459
35c1b462 3460 //sMacAddr[5] = (u8)GetRandomNumber(1, 254);
5f53d8ca
JC
3461
3462 for(i = 0; i < 6; i++)
3463 dev->dev_addr[i] = sMacAddr[i];
3464 }
5f53d8ca
JC
3465 //NicIFSetMacAddress(Adapter, Adapter->PermanentAddress);
3466 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
3467 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
3468
6756993b
HS
3469 RT_TRACE(COMP_INIT,
3470 "ReadAdapterInfo8192SEFuse(), Permanent Address = %pM\n",
3471 dev->dev_addr);
5f53d8ca 3472
35c1b462
BZ
3473 priv->EEPROMBoardType = EEPROM_Default_BoardType;
3474 priv->rf_type = RF_1T2R; //RF_2T2R
3475 priv->EEPROMTxPowerDiff = EEPROM_Default_PwDiff;
3476 priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
3477 priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
3478 priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
3479 priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
3480 priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
3481 priv->EEPROMTxPwrTkMode = EEPROM_Default_TxPwrTkMode;
5f53d8ca 3482
5f53d8ca 3483
5f53d8ca 3484
35c1b462
BZ
3485 for (rf_path = 0; rf_path < 2; rf_path++)
3486 {
3487 for (i = 0; i < 3; i++)
5f53d8ca 3488 {
35c1b462
BZ
3489 // Read CCK RF A & B Tx power
3490 priv->RfCckChnlAreaTxPwr[rf_path][i] =
3491 priv->RfOfdmChnlAreaTxPwr1T[rf_path][i] =
3492 priv->RfOfdmChnlAreaTxPwr2T[rf_path][i] =
3493 (u8)(EEPROM_Default_TxPower & 0xff);
5f53d8ca 3494 }
35c1b462 3495 }
5f53d8ca 3496
88e05d85 3497 update_hal_variables(priv);
5f53d8ca 3498
35c1b462
BZ
3499 //
3500 // Update remained HAL variables.
3501 //
3502 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
3503 priv->LegacyHTTxPowerDiff = priv->EEPROMTxPowerDiff;//new
3504 priv->TxPowerDiff = priv->EEPROMTxPowerDiff;
3505 //priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);// Antenna B gain offset to antenna A, bit0~3
3506 //priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);// Antenna C gain offset to antenna A, bit4~7
3507 priv->CrystalCap = priv->EEPROMCrystalCap; // CrystalCap, bit12~15
3508 priv->ThermalMeter[0] = priv->EEPROMThermalMeter;// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
5f53d8ca
JC
3509 priv->LedStrategy = SW_LED_MODE0;
3510
3511 init_rate_adaptive(dev);
3512
35c1b462 3513 RT_TRACE(COMP_INIT, "<==== ConfigAdapterInfo8192SForAutoLoadFail\n");
5f53d8ca
JC
3514
3515}
5f53d8ca
JC
3516
3517//
3518// Description:
3519// Read HW adapter information by E-Fuse or EEPROM according CR9346 reported.
3520//
3521// Assumption:
3522// 1. CR9346 regiser has verified.
3523// 2. PASSIVE_LEVEL (USB interface)
3524//
3525// Created by Roger, 2008.10.21.
3526//
3527void
3528rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev)
3529{
3530 struct r8192_priv *priv = ieee80211_priv(dev);
3531 u16 i,usValue;
3532 u8 tmpU1b, tempval;
3533 u16 EEPROMId;
3534 u8 hwinfo[HWSET_MAX_SIZE_92S];
3535 u8 rf_path, index; // For EEPROM/EFUSE After V0.6_1117
3536
3537
3538 RT_TRACE(COMP_INIT, "====> ReadAdapterInfo8192SUsb\n");
3539
3540 //
3541 // <Roger_Note> The following operation are prevent Efuse leakage by turn on 2.5V.
3542 // 2008.11.25.
3543 //
3544 tmpU1b = read_nic_byte(dev, EFUSE_TEST+3);
3545 write_nic_byte(dev, EFUSE_TEST+3, tmpU1b|0x80);
3546 //PlatformStallExecution(1000);
3547 mdelay(10);
3548 write_nic_byte(dev, EFUSE_TEST+3, (tmpU1b&(~BIT7)));
3549
3550 // Retrieve Chip version.
3551 priv->card_8192_version = (VERSION_8192S)((read_nic_dword(dev, PMC_FSM)>>16)&0xF);
3552 RT_TRACE(COMP_INIT, "Chip Version ID: 0x%2x\n", priv->card_8192_version);
3553
3554 switch(priv->card_8192_version)
3555 {
3556 case 0:
3557 RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_ACUT.\n");
3558 break;
3559 case 1:
3560 RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_BCUT.\n");
3561 break;
3562 case 2:
3563 RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_CCUT.\n");
3564 break;
3565 default:
3566 RT_TRACE(COMP_INIT, "Unknown Chip Version!!\n");
3567 priv->card_8192_version = VERSION_8192S_BCUT;
3568 break;
3569 }
3570
3571 //if (IS_BOOT_FROM_EEPROM(Adapter))
3572 if(priv->EepromOrEfuse)
3573 { // Read frin EEPROM
3574 write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
3575 //PlatformStallExecution(10000);
3576 mdelay(10);
3577 write_nic_byte(dev, PMC_FSM, 0x02); // Enable Loader Data Keep
3578 // Read all Content from EEPROM or EFUSE.
3579 for(i = 0; i < HWSET_MAX_SIZE_92S; i += 2)
3580 {
3581 usValue = eprom_read(dev, (u16) (i>>1));
3582 *((u16*)(&hwinfo[i])) = usValue;
3583 }
3584 }
3585 else if (!(priv->EepromOrEfuse))
3586 { // Read from EFUSE
3587
3588 //
3589 // <Roger_Notes> We set Isolation signals from Loader and reset EEPROM after system resuming
3590 // from suspend mode.
3591 // 2008.10.21.
3592 //
3593 //PlatformEFIOWrite1Byte(Adapter, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
3594 //PlatformStallExecution(10000);
3595 //PlatformEFIOWrite1Byte(Adapter, SYS_FUNC_EN+1, 0x40);
3596 //PlatformEFIOWrite1Byte(Adapter, SYS_FUNC_EN+1, 0x50);
3597
3598 //tmpU1b = PlatformEFIORead1Byte(Adapter, EFUSE_TEST+3);
3599 //PlatformEFIOWrite1Byte(Adapter, EFUSE_TEST+3, (tmpU1b | 0x80));
3600 //PlatformEFIOWrite1Byte(Adapter, EFUSE_TEST+3, 0x72);
3601 //PlatformEFIOWrite1Byte(Adapter, EFUSE_CLK, 0x03);
3602
3603 // Read EFUSE real map to shadow.
3604 EFUSE_ShadowMapUpdate(dev);
3605 memcpy(hwinfo, &priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
3606 }
3607 else
3608 {
3609 RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SUsb(): Invalid boot type!!\n");
3610 }
3611
3612 //YJ,test,090106
3613 //dump_buf(hwinfo,HWSET_MAX_SIZE_92S);
3614 //
3615 // <Roger_Notes> The following are EFUSE/EEPROM independent operations!!
3616 //
3617 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("MAP: \n"), hwinfo, HWSET_MAX_SIZE_92S);
3618
3619 //
3620 // <Roger_Notes> Event though CR9346 regiser can verify whether Autoload is success or not, but we still
3621 // double check ID codes for 92S here(e.g., due to HW GPIO polling fail issue).
3622 // 2008.10.21.
3623 //
3624 EEPROMId = *((u16 *)&hwinfo[0]);
3625
3626 if( EEPROMId != RTL8190_EEPROM_ID )
3627 {
3628 RT_TRACE(COMP_INIT, "ID(%#x) is invalid!!\n", EEPROMId);
3629 priv->bTXPowerDataReadFromEEPORM = FALSE;
3630 priv->AutoloadFailFlag=TRUE;
3631 }
3632 else
3633 {
3634 priv->AutoloadFailFlag=FALSE;
5f53d8ca 3635 priv->bTXPowerDataReadFromEEPORM = TRUE;
5f53d8ca
JC
3636 }
3637 // Read IC Version && Channel Plan
3638 if(!priv->AutoloadFailFlag)
3639 {
3640 // VID, PID
3641 priv->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
3642 priv->eeprom_pid = *(u16 *)&hwinfo[EEPROM_PID];
3643 priv->bIgnoreDiffRateTxPowerOffset = false; //cosa for test
3644
3645
3646 // EEPROM Version ID, Channel plan
3647 priv->EEPROMVersion = *(u8 *)&hwinfo[EEPROM_Version];
3648 priv->eeprom_ChannelPlan = *(u8 *)&hwinfo[EEPROM_ChannelPlan];
3649
3650 // Customer ID, 0x00 and 0xff are reserved for Realtek.
3651 priv->eeprom_CustomerID = *(u8 *)&hwinfo[EEPROM_CustomID];
3652 priv->eeprom_SubCustomerID = *(u8 *)&hwinfo[EEPROM_SubCustomID];
3653 }
3654 else
3655 {
3656 //priv->eeprom_vid = 0;
3657 //priv->eeprom_pid = 0;
3658 //priv->EEPROMVersion = 0;
3659 //priv->eeprom_ChannelPlan = 0;
3660 //priv->eeprom_CustomerID = 0;
3661 //priv->eeprom_SubCustomerID = 0;
3662
3663 rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(dev);
3664 return;
3665 }
3666
3667
3668 RT_TRACE(COMP_INIT, "EEPROM Id = 0x%4x\n", EEPROMId);
3669 RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
3670 RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
3671 RT_TRACE(COMP_INIT, "EEPROM Version ID: 0x%2x\n", priv->EEPROMVersion);
3672 RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
3673 RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID);
3674 RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan);
3675 RT_TRACE(COMP_INIT, "bIgnoreDiffRateTxPowerOffset = %d\n", priv->bIgnoreDiffRateTxPowerOffset);
3676
3677
3678 // Read USB optional function.
3679 if(!priv->AutoloadFailFlag)
3680 {
3681 priv->EEPROMUsbOption = *(u8 *)&hwinfo[EEPROM_USB_OPTIONAL];
3682 }
3683 else
3684 {
3685 priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
3686 }
3687
3688
3689 priv->EEPROMUsbEndPointNumber = rtl8192SU_UsbOptionToEndPointNumber((priv->EEPROMUsbOption&EEPROM_EP_NUMBER)>>3);
3690
3691 RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
3692 RT_TRACE(COMP_INIT, "EndPoint Number = %#x\n", priv->EEPROMUsbEndPointNumber);
3693
3694#ifdef TO_DO_LIST
3695 //
3696 // Decide CustomerID according to VID/DID or EEPROM
3697 //
3698 switch(pHalData->EEPROMCustomerID)
3699 {
3700 case EEPROM_CID_ALPHA:
3701 pMgntInfo->CustomerID = RT_CID_819x_ALPHA;
3702 break;
3703
3704 case EEPROM_CID_CAMEO:
3705 pMgntInfo->CustomerID = RT_CID_819x_CAMEO;
3706 break;
3707
3708 case EEPROM_CID_SITECOM:
3709 pMgntInfo->CustomerID = RT_CID_819x_Sitecom;
3710 RT_TRACE(COMP_INIT, DBG_LOUD, ("CustomerID = 0x%4x\n", pMgntInfo->CustomerID));
3711
3712 break;
3713
3714 case EEPROM_CID_WHQL:
3715 Adapter->bInHctTest = TRUE;
3716
3717 pMgntInfo->bSupportTurboMode = FALSE;
3718 pMgntInfo->bAutoTurboBy8186 = FALSE;
3719
3720 pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
3721 pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
3722 pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
3723 pMgntInfo->keepAliveLevel = 0;
3724 break;
3725
3726 default:
3727 pMgntInfo->CustomerID = RT_CID_DEFAULT;
3728 break;
3729
3730 }
3731
3732 //
3733 // Led mode
3734 //
3735 switch(pMgntInfo->CustomerID)
3736 {
3737 case RT_CID_DEFAULT:
3738 case RT_CID_819x_ALPHA:
3739 pHalData->LedStrategy = SW_LED_MODE1;
3740 pHalData->bRegUseLed = TRUE;
3741 pHalData->SwLed1.bLedOn = TRUE;
3742 break;
3743 case RT_CID_819x_CAMEO:
3744 pHalData->LedStrategy = SW_LED_MODE1;
3745 pHalData->bRegUseLed = TRUE;
3746 break;
3747
3748 case RT_CID_819x_Sitecom:
3749 pHalData->LedStrategy = SW_LED_MODE2;
3750 pHalData->bRegUseLed = TRUE;
3751 break;
3752
3753 default:
3754 pHalData->LedStrategy = SW_LED_MODE0;
3755 break;
3756 }
3757#endif
3758
3759 // Read USB PHY parameters.
3760 for(i=0; i<5; i++)
3761 priv->EEPROMUsbPhyParam[i] = *(u8 *)&hwinfo[EEPROM_USB_PHY_PARA1+i];
3762
3763 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("USB PHY Param: \n"), pHalData->EEPROMUsbPhyParam, 5);
3764
3765
3766 //Read Permanent MAC address
3767 for(i=0; i<6; i++)
3768 dev->dev_addr[i] = *(u8 *)&hwinfo[EEPROM_NODE_ADDRESS_BYTE_0+i];
3769
3770 //NicIFSetMacAddress(Adapter, Adapter->PermanentAddress);
3771 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
3772 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
3773
6756993b
HS
3774 RT_TRACE(COMP_INIT,
3775 "ReadAdapterInfo8192SEFuse(), Permanent Address = %pM\n",
3776 dev->dev_addr);
5f53d8ca
JC
3777
3778 //
3779 // Get CustomerID(Boad Type)
3780 // i.e., 0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU.
3781 // Others: Reserved. Default is 0x2: RTL8192SU.
3782 //
3783 //if(!priv->AutoloadFailFlag)
3784 //{
3785 priv->EEPROMBoardType = *(u8 *)&hwinfo[EEPROM_BoardType];
3786 priv->rf_type = rtl8192SU_BoardTypeToRFtype(dev, priv->EEPROMBoardType);
3787 //}
3788 //else
3789 //{
3790 // priv->EEPROMBoardType = EEPROM_Default_BoardType;
3791 // priv->rf_type = RF_1T2R;
3792 //}
3793
5f53d8ca 3794 priv->rf_chip = RF_6052;
5f53d8ca
JC
3795
3796 priv->rf_chip = RF_6052;//lzm test
3797 RT_TRACE(COMP_INIT, "BoardType = 0x%2x\n", priv->EEPROMBoardType);
3798 RT_TRACE(COMP_INIT, "RF_Type = 0x%2x\n", priv->rf_type);
3799
3800 //
3801 // Read antenna tx power offset of B/C/D to A from EEPROM
3802 // and read ThermalMeter from EEPROM
3803 //
3804 //if(!priv->AutoloadFailFlag)
3805 {
3806 priv->EEPROMTxPowerDiff = *(u8 *)&hwinfo[EEPROM_PwDiff];
3807 priv->EEPROMThermalMeter = *(u8 *)&hwinfo[EEPROM_ThermalMeter];
3808 }
3809 //else
3810 //{
3811 // priv->EEPROMTxPowerDiff = EEPROM_Default_PwDiff;
3812 // priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
3813 //}
3814
3815 RT_TRACE(COMP_INIT, "PwDiff = %#x\n", priv->EEPROMTxPowerDiff);
3816 RT_TRACE(COMP_INIT, "ThermalMeter = %#x\n", priv->EEPROMThermalMeter);
3817
3818 //
3819 // Read Tx Power gain offset of legacy OFDM to HT rate.
3820 // Read CrystalCap from EEPROM
3821 //
3822 //if(!priv->AutoloadFailFlag)
3823 {
3824 priv->EEPROMCrystalCap = *(u8 *)&hwinfo[EEPROM_CrystalCap];
3825 }
3826 //else
3827 //{
3828 // priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
3829 //}
3830
3831 RT_TRACE(COMP_INIT, "CrystalCap = %#x\n", priv->EEPROMCrystalCap);
3832
3833 //
3834 // Get Tx Power Base.
3835 //
3836 //if(!priv->AutoloadFailFlag)
3837 {
3838 priv->EEPROMTxPwrBase = *(u8 *)&hwinfo[EEPROM_TxPowerBase];
3839 }
3840 //else
3841 //{
3842 // priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
3843 //}
3844
3845 RT_TRACE(COMP_INIT, "TxPwrBase = %#x\n", priv->EEPROMTxPwrBase);
3846
3847
3848 //
3849 // Get TSSI value for each path.
3850 //
3851 //if(!priv->AutoloadFailFlag)
3852 {
3853 priv->EEPROMTSSI_A = *(u8 *)&hwinfo[EEPROM_TSSI_A];
3854 priv->EEPROMTSSI_B = *(u8 *)&hwinfo[EEPROM_TSSI_B];
3855 }
3856 //else
3857 //{ // Default setting for Empty EEPROM
3858 // priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
3859 // priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
3860 //}
3861
3862 RT_TRACE(COMP_INIT, "TSSI_A = %#x, TSSI_B = %#x\n", priv->EEPROMTSSI_A, priv->EEPROMTSSI_B);
3863
3864 //
3865 // Get Tx Power tracking mode.
3866 //
3867 //if(!priv->AutoloadFailFlag)
3868 {
3869 priv->EEPROMTxPwrTkMode = *(u8 *)&hwinfo[EEPROM_TxPwTkMode];
3870 }
3871
3872 RT_TRACE(COMP_INIT, "TxPwrTkMod = %#x\n", priv->EEPROMTxPwrTkMode);
3873
3874
5f53d8ca
JC
3875 {
3876 //
3877 // Buffer TxPwIdx(i.e., from offset 0x55~0x66, total 18Bytes)
3878 // Update CCK, OFDM (1T/2T)Tx Power Index from above buffer.
3879 //
3880
3881 //
3882 // Get Tx Power Level by Channel
3883 //
3884 //if(!priv->AutoloadFailFlag)
3885 {
3886 // Read Tx power of Channel 1 ~ 14 from EFUSE.
3887 // 92S suupport RF A & B
3888 for (rf_path = 0; rf_path < 2; rf_path++)
3889 {
3890 for (i = 0; i < 3; i++)
3891 {
3892 // Read CCK RF A & B Tx power
3893 priv->RfCckChnlAreaTxPwr[rf_path][i] =
3894 hwinfo[EEPROM_TxPwIndex+rf_path*3+i];
3895
3896 // Read OFDM RF A & B Tx power for 1T
3897 priv->RfOfdmChnlAreaTxPwr1T[rf_path][i] =
3898 hwinfo[EEPROM_TxPwIndex+6+rf_path*3+i];
3899
3900 // Read OFDM RF A & B Tx power for 2T
3901 priv->RfOfdmChnlAreaTxPwr2T[rf_path][i] =
3902 hwinfo[EEPROM_TxPwIndex+12+rf_path*3+i];
3903 }
3904 }
3905
3906 }
88e05d85 3907 update_hal_variables(priv);
5f53d8ca
JC
3908 }
3909
3910 //
3911 // 2009/02/09 Cosa add for new EEPROM format
3912 //
3913 for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level.
3914 {
3915 // Read tx power difference between HT OFDM 20/40 MHZ
3916 if (i < 3) // Cjanel 1-3
3917 index = 0;
3918 else if (i < 9) // Channel 4-9
3919 index = 1;
3920 else // Channel 10-14
3921 index = 2;
3922
3923 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_HT20_DIFF+index])&0xff;
3924 priv->TxPwrHt20Diff[RF90_PATH_A][i] = (tempval&0xF);
3925 priv->TxPwrHt20Diff[RF90_PATH_B][i] = ((tempval>>4)&0xF);
3926
3927 // Read OFDM<->HT tx power diff
3928 if (i < 3) // Cjanel 1-3
3929 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF])&0xff;
3930 else if (i < 9) // Channel 4-9
3931 tempval = (*(u8 *)&hwinfo[EEPROM_PwDiff])&0xff;
3932 else // Channel 10-14
3933 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF+1])&0xff;
3934
3935 //cosa tempval = (*(u1Byte *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF+index])&0xff;
3936 priv->TxPwrLegacyHtDiff[RF90_PATH_A][i] = (tempval&0xF);
3937 priv->TxPwrLegacyHtDiff[RF90_PATH_B][i] = ((tempval>>4)&0xF);
3938
3939 //
3940 // Read Band Edge tx power offset and check if user enable the ability
3941 //
3942 // HT 40 band edge channel
3943 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE])&0xff;
3944 priv->TxPwrbandEdgeHt40[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
3945 priv->TxPwrbandEdgeHt40[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
3946 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+1])&0xff;
3947 priv->TxPwrbandEdgeHt40[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
3948 priv->TxPwrbandEdgeHt40[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
3949 // HT 20 band edge channel
3950 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+2])&0xff;
3951 priv->TxPwrbandEdgeHt20[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
3952 priv->TxPwrbandEdgeHt20[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
3953 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+3])&0xff;
3954 priv->TxPwrbandEdgeHt20[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
3955 priv->TxPwrbandEdgeHt20[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
3956 // OFDM band edge channel
3957 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+4])&0xff;
3958 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
3959 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
3960 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+5])&0xff;
3961 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
3962 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
3963
3964 priv->TxPwrbandEdgeFlag = (*(u8 *)&hwinfo[TX_PWR_BAND_EDGE_CHK]);
3965 }
3966
3967 for(i=0; i<14; i++)
3968 RT_TRACE(COMP_INIT, "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrHt20Diff[RF90_PATH_A][i]);
3969 for(i=0; i<14; i++)
3970 RT_TRACE(COMP_INIT, "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, priv->TxPwrLegacyHtDiff[RF90_PATH_A][i]);
3971 for(i=0; i<14; i++)
3972 RT_TRACE(COMP_INIT, "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrHt20Diff[RF90_PATH_B][i]);
3973 for(i=0; i<14; i++)
3974 RT_TRACE(COMP_INIT, "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrLegacyHtDiff[RF90_PATH_B][i]);
3975 RT_TRACE(COMP_INIT, "RF-A HT40 band-edge low/high power diff = 0x%x/0x%x\n",
3976 priv->TxPwrbandEdgeHt40[RF90_PATH_A][0],
3977 priv->TxPwrbandEdgeHt40[RF90_PATH_A][1]);
3978 RT_TRACE((COMP_INIT&COMP_DBG), "RF-B HT40 band-edge low/high power diff = 0x%x/0x%x\n",
3979 priv->TxPwrbandEdgeHt40[RF90_PATH_B][0],
3980 priv->TxPwrbandEdgeHt40[RF90_PATH_B][1]);
3981
3982 RT_TRACE((COMP_INIT&COMP_DBG), "RF-A HT20 band-edge low/high power diff = 0x%x/0x%x\n",
3983 priv->TxPwrbandEdgeHt20[RF90_PATH_A][0],
3984 priv->TxPwrbandEdgeHt20[RF90_PATH_A][1]);
3985 RT_TRACE((COMP_INIT&COMP_DBG), "RF-B HT20 band-edge low/high power diff = 0x%x/0x%x\n",
3986 priv->TxPwrbandEdgeHt20[RF90_PATH_B][0],
3987 priv->TxPwrbandEdgeHt20[RF90_PATH_B][1]);
3988
3989 RT_TRACE((COMP_INIT&COMP_DBG), "RF-A OFDM band-edge low/high power diff = 0x%x/0x%x\n",
3990 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][0],
3991 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][1]);
3992 RT_TRACE((COMP_INIT&COMP_DBG), "RF-B OFDM band-edge low/high power diff = 0x%x/0x%x\n",
3993 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][0],
3994 priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][1]);
3995 RT_TRACE((COMP_INIT&COMP_DBG), "Band-edge enable flag = %d\n", priv->TxPwrbandEdgeFlag);
5f53d8ca
JC
3996
3997 //
3998 // Update remained HAL variables.
3999 //
4000 priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
4001 priv->LegacyHTTxPowerDiff = priv->EEPROMTxPowerDiff;
4002 priv->TxPowerDiff = priv->EEPROMTxPowerDiff;
4003 //priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);// Antenna B gain offset to antenna A, bit[3:0]
4004 //priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);// Antenna C gain offset to antenna A, bit[7:4]
4005 priv->CrystalCap = priv->EEPROMCrystalCap; // CrystalCap, bit[15:12]
4006 priv->ThermalMeter[0] = (priv->EEPROMThermalMeter&0x1f);// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
4007 priv->LedStrategy = SW_LED_MODE0;
4008
4009 init_rate_adaptive(dev);
4010
4011 RT_TRACE(COMP_INIT, "<==== ReadAdapterInfo8192SUsb\n");
4012
4013 //return RT_STATUS_SUCCESS;
4014}
4015
4016
4017//
4018// Description:
4019// Read HW adapter information by E-Fuse or EEPROM according CR9346 reported.
4020//
4021// Assumption:
4022// 1. CR9346 regiser has verified.
4023// 2. PASSIVE_LEVEL (USB interface)
4024//
4025// Created by Roger, 2008.10.21.
4026//
4027static void rtl8192SU_read_eeprom_info(struct net_device *dev)
4028{
4029 struct r8192_priv *priv = ieee80211_priv(dev);
4030 u8 tmpU1b;
4031
4032 RT_TRACE(COMP_INIT, "====> ReadAdapterInfo8192SUsb\n");
4033
4034 // Retrieve Chip version.
4035 priv->card_8192_version = (VERSION_8192S)((read_nic_dword(dev, PMC_FSM)>>16)&0xF);
4036 RT_TRACE(COMP_INIT, "Chip Version ID: 0x%2x\n", priv->card_8192_version);
4037
4038 tmpU1b = read_nic_byte(dev, EPROM_CMD);//CR9346
4039
4040 // To check system boot selection.
4041 if (tmpU1b & CmdEERPOMSEL)
4042 {
4043 RT_TRACE(COMP_INIT, "Boot from EEPROM\n");
4044 priv->EepromOrEfuse = TRUE;
4045 }
4046 else
4047 {
4048 RT_TRACE(COMP_INIT, "Boot from EFUSE\n");
4049 priv->EepromOrEfuse = FALSE;
4050 }
4051
4052 // To check autoload success or not.
4053 if (tmpU1b & CmdEEPROM_En)
4054 {
4055 RT_TRACE(COMP_INIT, "Autoload OK!!\n");
4056 priv->AutoloadFailFlag=FALSE;
4057 rtl8192SU_ReadAdapterInfo8192SUsb(dev);//eeprom or e-fuse
4058 }
4059 else
4060 { // Auto load fail.
4061 RT_TRACE(COMP_INIT, "AutoLoad Fail reported from CR9346!!\n");
4062 priv->AutoloadFailFlag=TRUE;
4063 rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(dev);
4064
4065 //if (IS_BOOT_FROM_EFUSE(Adapter))
4066 if(!priv->EepromOrEfuse)
4067 {
4068 RT_TRACE(COMP_INIT, "Update shadow map for EFuse future use!!\n");
4069 EFUSE_ShadowMapUpdate(dev);
4070 }
4071 }
4072#ifdef TO_DO_LIST
4073 if((priv->RegChannelPlan >= RT_CHANNEL_DOMAIN_MAX) || (pHalData->EEPROMChannelPlan & EEPROM_CHANNEL_PLAN_BY_HW_MASK))
4074 {
4075 pMgntInfo->ChannelPlan = HalMapChannelPlan8192S(Adapter, (pHalData->EEPROMChannelPlan & (~(EEPROM_CHANNEL_PLAN_BY_HW_MASK))));
4076 pMgntInfo->bChnlPlanFromHW = (pHalData->EEPROMChannelPlan & EEPROM_CHANNEL_PLAN_BY_HW_MASK) ? TRUE : FALSE; // User cannot change channel plan.
4077 }
4078 else
4079 {
4080 pMgntInfo->ChannelPlan = (RT_CHANNEL_DOMAIN)pMgntInfo->RegChannelPlan;
4081 }
4082
4083 switch(pMgntInfo->ChannelPlan)
4084 {
4085 case RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN:
4086 {
4087 PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(pMgntInfo);
4088
4089 pDot11dInfo->bEnabled = TRUE;
4090 }
4091 RT_TRACE(COMP_INIT, DBG_LOUD, ("ReadAdapterInfo8187(): Enable dot11d when RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN!\n"));
4092 break;
4093 }
4094
4095 RT_TRACE(COMP_INIT, DBG_LOUD, ("RegChannelPlan(%d) EEPROMChannelPlan(%d)", pMgntInfo->RegChannelPlan, pHalData->EEPROMChannelPlan));
4096 RT_TRACE(COMP_INIT, DBG_LOUD, ("ChannelPlan = %d\n" , pMgntInfo->ChannelPlan));
4097
4098 RT_TRACE(COMP_INIT, DBG_LOUD, ("<==== ReadAdapterInfo8192S\n"));
4099#endif
4100
4101 RT_TRACE(COMP_INIT, "<==== ReadAdapterInfo8192SUsb\n");
4102
4103 //return RT_STATUS_SUCCESS;
4104}
0f29f587
BZ
4105
4106short rtl8192_get_channel_map(struct net_device * dev)
5f53d8ca 4107{
5f53d8ca 4108 struct r8192_priv *priv = ieee80211_priv(dev);
0f29f587
BZ
4109 if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
4110 printk("rtl8180_init:Error channel plan! Set to default.\n");
4111 priv->ChannelPlan= 0;
5f53d8ca 4112 }
0f29f587 4113 RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
5f53d8ca 4114
0f29f587
BZ
4115 rtl819x_set_channel_map(priv->ChannelPlan, priv);
4116 return 0;
4117}
5f53d8ca
JC
4118
4119short rtl8192_init(struct net_device *dev)
4120{
4121
4122 struct r8192_priv *priv = ieee80211_priv(dev);
4123
5f53d8ca
JC
4124 rtl8192_init_priv_variable(dev);
4125 rtl8192_init_priv_lock(priv);
4126 rtl8192_init_priv_task(dev);
4127 rtl8192_get_eeprom_size(dev);
4128 priv->ops->rtl819x_read_eeprom_info(dev);
4129 rtl8192_get_channel_map(dev);
4130 init_hal_dm(dev);
4131 init_timer(&priv->watch_dog_timer);
4132 priv->watch_dog_timer.data = (unsigned long)dev;
4133 priv->watch_dog_timer.function = watch_dog_timer_callback;
4134
4135 //rtl8192_adapter_start(dev);
4136#ifdef DEBUG_EPROM
4137 dump_eprom(dev);
4138#endif
4139 return 0;
4140}
4141
4142/******************************************************************************
4143 *function: This function actually only set RRSR, RATR and BW_OPMODE registers
4144 * not to do all the hw config as its name says
4145 * input: net_device dev
4146 * output: none
4147 * return: none
4148 * notice: This part need to modified according to the rate set we filtered
4149 * ****************************************************************************/
4150void rtl8192_hwconfig(struct net_device* dev)
4151{
4152 u32 regRATR = 0, regRRSR = 0;
4153 u8 regBwOpMode = 0, regTmp = 0;
4154 struct r8192_priv *priv = ieee80211_priv(dev);
4155
4156// Set RRSR, RATR, and BW_OPMODE registers
4157 //
4158 switch(priv->ieee80211->mode)
4159 {
4160 case WIRELESS_MODE_B:
4161 regBwOpMode = BW_OPMODE_20MHZ;
4162 regRATR = RATE_ALL_CCK;
4163 regRRSR = RATE_ALL_CCK;
4164 break;
4165 case WIRELESS_MODE_A:
4166 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
4167 regRATR = RATE_ALL_OFDM_AG;
4168 regRRSR = RATE_ALL_OFDM_AG;
4169 break;
4170 case WIRELESS_MODE_G:
4171 regBwOpMode = BW_OPMODE_20MHZ;
4172 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4173 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4174 break;
4175 case WIRELESS_MODE_AUTO:
4176#ifdef TO_DO_LIST
4177 if (Adapter->bInHctTest)
4178 {
4179 regBwOpMode = BW_OPMODE_20MHZ;
4180 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4181 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4182 }
4183 else
4184#endif
4185 {
4186 regBwOpMode = BW_OPMODE_20MHZ;
4187 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4188 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4189 }
4190 break;
4191 case WIRELESS_MODE_N_24G:
4192 // It support CCK rate by default.
4193 // CCK rate will be filtered out only when associated AP does not support it.
4194 regBwOpMode = BW_OPMODE_20MHZ;
4195 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4196 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4197 break;
4198 case WIRELESS_MODE_N_5G:
4199 regBwOpMode = BW_OPMODE_5G;
4200 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4201 regRRSR = RATE_ALL_OFDM_AG;
4202 break;
4203 }
4204
4205 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
4206 {
4207 u32 ratr_value = 0;
4208 ratr_value = regRATR;
4209 if (priv->rf_type == RF_1T2R)
4210 {
4211 ratr_value &= ~(RATE_ALL_OFDM_2SS);
4212 }
4213 write_nic_dword(dev, RATR0, ratr_value);
4214 write_nic_byte(dev, UFWP, 1);
4215 }
4216 regTmp = read_nic_byte(dev, 0x313);
4217 regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
4218 write_nic_dword(dev, RRSR, regRRSR);
4219
4220 //
4221 // Set Retry Limit here
4222 //
4223 write_nic_word(dev, RETRY_LIMIT,
4224 priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
4225 priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
4226 // Set Contention Window here
4227
4228 // Set Tx AGC
4229
4230 // Set Tx Antenna including Feedback control
4231
4232 // Set Auto Rate fallback control
4233
4234
4235}
4236
5f53d8ca
JC
4237
4238//
4239// Description:
4240// Initial HW relted registers.
4241//
4242// Assumption:
4243// Config RTL8192S USB MAC, we should config MAC before download FW.
4244//
4245// 2008.09.03, Added by Roger.
4246//
4247static void rtl8192SU_MacConfigBeforeFwDownloadASIC(struct net_device *dev)
4248{
4249 u8 tmpU1b;// i;
4250// u16 tmpU2b;
4251// u32 tmpU4b;
4252 u8 PollingCnt = 20;
4253
4254 RT_TRACE(COMP_INIT, "--->MacConfigBeforeFwDownloadASIC()\n");
4255
4256 //2MAC Initialization for power on sequence, Revised by Roger. 2008.09.03.
4257
4258 //
4259 //<Roger_Notes> Set control path switch to HW control and reset Digital Core, CPU Core and
4260 // MAC I/O to solve FW download fail when system from resume sate.
4261 // 2008.11.04.
4262 //
4263 tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
4264 if(tmpU1b & 0x80)
4265 {
4266 tmpU1b &= 0x3f;
4267 write_nic_byte(dev, SYS_CLKR+1, tmpU1b);
4268 }
4269 // Clear FW RPWM for FW control LPS. by tynli. 2009.02.23
4270 write_nic_byte(dev, RPWM, 0x0);
4271
4272 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
4273 tmpU1b &= 0x73;
4274 write_nic_byte(dev, SYS_FUNC_EN+1, tmpU1b);
4275 udelay(1000);
4276
4277 //Revised POS, suggested by SD1 Alex, 2008.09.27.
4278 write_nic_byte(dev, SPS0_CTRL+1, 0x53);
4279 write_nic_byte(dev, SPS0_CTRL, 0x57);
4280
4281 //Enable AFE Macro Block's Bandgap adn Enable AFE Macro Block's Mbias
4282 tmpU1b = read_nic_byte(dev, AFE_MISC);
4283 write_nic_byte(dev, AFE_MISC, (tmpU1b|AFE_BGEN|AFE_MBEN));
4284
4285 //Enable PLL Power (LDOA15V)
4286 tmpU1b = read_nic_byte(dev, LDOA15_CTRL);
4287 write_nic_byte(dev, LDOA15_CTRL, (tmpU1b|LDA15_EN));
4288
4289 //Enable LDOV12D block
4290 tmpU1b = read_nic_byte(dev, LDOV12D_CTRL);
4291 write_nic_byte(dev, LDOV12D_CTRL, (tmpU1b|LDV12_EN));
4292
4293 //mpU1b = read_nic_byte(Adapter, SPS1_CTRL);
4294 //write_nic_byte(dev, SPS1_CTRL, (tmpU1b|SPS1_LDEN));
4295
4296 //PlatformSleepUs(2000);
4297
4298 //Enable Switch Regulator Block
4299 //tmpU1b = read_nic_byte(Adapter, SPS1_CTRL);
4300 //write_nic_byte(dev, SPS1_CTRL, (tmpU1b|SPS1_SWEN));
4301
4302 //write_nic_dword(Adapter, SPS1_CTRL, 0x00a7b267);
4303
4304 tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL+1);
4305 write_nic_byte(dev, SYS_ISO_CTRL+1, (tmpU1b|0x08));
4306
4307 //Engineer Packet CP test Enable
4308 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
4309 write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x20));
4310
4311 //Support 64k IMEM, suggested by SD1 Alex.
4312 tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL+1);
4313 write_nic_byte(dev, SYS_ISO_CTRL+1, (tmpU1b& 0x68));
4314
4315 //Enable AFE clock
4316 tmpU1b = read_nic_byte(dev, AFE_XTAL_CTRL+1);
4317 write_nic_byte(dev, AFE_XTAL_CTRL+1, (tmpU1b& 0xfb));
4318
4319 //Enable AFE PLL Macro Block
4320 tmpU1b = read_nic_byte(dev, AFE_PLL_CTRL);
4321 write_nic_byte(dev, AFE_PLL_CTRL, (tmpU1b|0x11));
4322
4323 //Attatch AFE PLL to MACTOP/BB/PCIe Digital
4324 tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL);
4325 write_nic_byte(dev, SYS_ISO_CTRL, (tmpU1b&0xEE));
4326
4327 // Switch to 40M clock
4328 write_nic_byte(dev, SYS_CLKR, 0x00);
4329
4330 //SSC Disable
4331 tmpU1b = read_nic_byte(dev, SYS_CLKR);
4332 //write_nic_byte(dev, SYS_CLKR, (tmpU1b&0x5f));
4333 write_nic_byte(dev, SYS_CLKR, (tmpU1b|0xa0));
4334
4335 //Enable MAC clock
4336 tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
4337 write_nic_byte(dev, SYS_CLKR+1, (tmpU1b|0x18));
4338
4339 //Revised POS, suggested by SD1 Alex, 2008.09.27.
4340 write_nic_byte(dev, PMC_FSM, 0x02);
4341
4342 //Enable Core digital and enable IOREG R/W
4343 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
4344 write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x08));
4345
4346 //Enable REG_EN
4347 tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
4348 write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x80));
4349
4350 //Switch the control path to FW
4351 tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
4352 write_nic_byte(dev, SYS_CLKR+1, (tmpU1b|0x80)& 0xBF);
4353
4354 write_nic_byte(dev, CMDR, 0xFC);
4355 write_nic_byte(dev, CMDR+1, 0x37);
4356
4357 //Fix the RX FIFO issue(usb error), 970410
4358 tmpU1b = read_nic_byte_E(dev, 0x5c);
4359 write_nic_byte_E(dev, 0x5c, (tmpU1b|BIT7));
4360
4361 //For power save, used this in the bit file after 970621
4362 tmpU1b = read_nic_byte(dev, SYS_CLKR);
4363 write_nic_byte(dev, SYS_CLKR, tmpU1b&(~SYS_CPU_CLKSEL));
4364
4365 // Revised for 8051 ROM code wrong operation. Added by Roger. 2008.10.16.
4366 write_nic_byte_E(dev, 0x1c, 0x80);
4367
4368 //
4369 // <Roger_EXP> To make sure that TxDMA can ready to download FW.
4370 // We should reset TxDMA if IMEM RPT was not ready.
4371 // Suggested by SD1 Alex. 2008.10.23.
4372 //
4373 do
4374 {
4375 tmpU1b = read_nic_byte(dev, TCR);
4376 if((tmpU1b & TXDMA_INIT_VALUE) == TXDMA_INIT_VALUE)
4377 break;
4378 //PlatformStallExecution(5);
4379 udelay(5);
4380 }while(PollingCnt--); // Delay 1ms
4381
4382 if(PollingCnt <= 0 )
4383 {
4384 RT_TRACE(COMP_INIT, "MacConfigBeforeFwDownloadASIC(): Polling TXDMA_INIT_VALUE timeout!! Current TCR(%#x)\n", tmpU1b);
4385 tmpU1b = read_nic_byte(dev, CMDR);
4386 write_nic_byte(dev, CMDR, tmpU1b&(~TXDMA_EN));
4387 udelay(2);
4388 write_nic_byte(dev, CMDR, tmpU1b|TXDMA_EN);// Reset TxDMA
4389 }
4390
4391
4392 RT_TRACE(COMP_INIT, "<---MacConfigBeforeFwDownloadASIC()\n");
4393}
5f53d8ca 4394
5f53d8ca
JC
4395//
4396// Description:
4397// Initial HW relted registers.
4398//
4399// Assumption:
4400// 1. This function is only invoked at driver intialization once.
4401// 2. PASSIVE LEVEL.
4402//
4403// 2008.06.10, Added by Roger.
4404//
4405static void rtl8192SU_MacConfigAfterFwDownload(struct net_device *dev)
4406{
4407 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
4408 //PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
4409 //u8 tmpU1b, RxPageCfg, i;
4410 u16 tmpU2b;
4411 u8 tmpU1b;//, i;
4412
4413
4414 RT_TRACE(COMP_INIT, "--->MacConfigAfterFwDownload()\n");
4415
4416 // Enable Tx/Rx
4417 tmpU2b = (BBRSTn|BB_GLB_RSTn|SCHEDULE_EN|MACRXEN|MACTXEN|DDMA_EN|
4418 FW2HW_EN|RXDMA_EN|TXDMA_EN|HCI_RXDMA_EN|HCI_TXDMA_EN); //3
4419 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_COMMAND, &tmpU1b );
4420 write_nic_word(dev, CMDR, tmpU2b); //LZM REGISTER COM 090305
4421
4422 // Loopback mode or not
4423 priv->LoopbackMode = RTL8192SU_NO_LOOPBACK; // Set no loopback as default.
4424 if(priv->LoopbackMode == RTL8192SU_NO_LOOPBACK)
4425 tmpU1b = LBK_NORMAL;
4426 else if (priv->LoopbackMode == RTL8192SU_MAC_LOOPBACK )
4427 tmpU1b = LBK_MAC_DLB;
4428 else
4429 RT_TRACE(COMP_INIT, "Serious error: wrong loopback mode setting\n");
4430
4431 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_LBK_MODE, &tmpU1b);
4432 write_nic_byte(dev, LBKMD_SEL, tmpU1b);
4433
4434 // Set RCR
4435 write_nic_dword(dev, RCR, priv->ReceiveConfig);
4436 RT_TRACE(COMP_INIT, "MacConfigAfterFwDownload(): Current RCR settings(%#x)\n", priv->ReceiveConfig);
4437
4438
4439 // Set RQPN
4440 //
4441 // <Roger_Notes> 2008.08.18.
4442 // 6 endpoints:
4443 // (1) Page number on CMDQ is 0x03.
4444 // (2) Page number on BCNQ, HQ and MGTQ is 0.
4445 // (3) Page number on BKQ, BEQ, VIQ and VOQ are 0x07.
4446 // (4) Page number on PUBQ is 0xdd
4447 //
4448 // 11 endpoints:
4449 // (1) Page number on CMDQ is 0x00.
4450 // (2) Page number on BCNQ is 0x02, HQ and MGTQ are 0x03.
4451 // (3) Page number on BKQ, BEQ, VIQ and VOQ are 0x07.
4452 // (4) Page number on PUBQ is 0xd8
4453 //
4454 //write_nic_dword(Adapter, 0xa0, 0x07070707); //BKQ, BEQ, VIQ and VOQ
4455 //write_nic_byte(dev, 0xa4, 0x00); // HCCAQ
5f53d8ca
JC
4456
4457 // Fix the RX FIFO issue(USB error), Rivesed by Roger, 2008-06-14
4458 tmpU1b = read_nic_byte_E(dev, 0x5C);
4459 write_nic_byte_E(dev, 0x5C, tmpU1b|BIT7);
4460
5f53d8ca
JC
4461 // For EFUSE init configuration.
4462 //if (IS_BOOT_FROM_EFUSE(Adapter)) // We may R/W EFUSE in EFUSE mode
4463 if (priv->bBootFromEfuse)
4464 {
4465 u8 tempval;
4466
4467 tempval = read_nic_byte(dev, SYS_ISO_CTRL+1);
4468 tempval &= 0xFE;
4469 write_nic_byte(dev, SYS_ISO_CTRL+1, tempval);
4470
4471 // Enable LDO 2.5V for write action
4472 //tempval = read_nic_byte(Adapter, EFUSE_TEST+3);
4473 //write_nic_byte(Adapter, EFUSE_TEST+3, (tempval | 0x80));
4474
4475 // Change Efuse Clock for write action
4476 //write_nic_byte(Adapter, EFUSE_CLK, 0x03);
4477
4478 // Change Program timing
4479 write_nic_byte(dev, EFUSE_CTRL+3, 0x72);
4480 //printk("!!!!!!!!!!!!!!!!!!!!!%s: write 0x33 with 0x72\n",__FUNCTION__);
4481 RT_TRACE(COMP_INIT, "EFUSE CONFIG OK\n");
4482 }
4483
4484
4485 RT_TRACE(COMP_INIT, "<---MacConfigAfterFwDownload()\n");
4486}
4487
4488void rtl8192SU_HwConfigureRTL8192SUsb(struct net_device *dev)
4489{
4490
4491 struct r8192_priv *priv = ieee80211_priv(dev);
4492 u8 regBwOpMode = 0;
4493 u32 regRATR = 0, regRRSR = 0;
4494 u8 regTmp = 0;
4495 u32 i = 0;
4496
4497 //1 This part need to modified according to the rate set we filtered!!
4498 //
4499 // Set RRSR, RATR, and BW_OPMODE registers
4500 //
4501 switch(priv->ieee80211->mode)
4502 {
4503 case WIRELESS_MODE_B:
4504 regBwOpMode = BW_OPMODE_20MHZ;
4505 regRATR = RATE_ALL_CCK;
4506 regRRSR = RATE_ALL_CCK;
4507 break;
4508 case WIRELESS_MODE_A:
4509 regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
4510 regRATR = RATE_ALL_OFDM_AG;
4511 regRRSR = RATE_ALL_OFDM_AG;
4512 break;
4513 case WIRELESS_MODE_G:
4514 regBwOpMode = BW_OPMODE_20MHZ;
4515 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4516 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4517 break;
4518 case WIRELESS_MODE_AUTO:
4519 if (priv->bInHctTest)
4520 {
4521 regBwOpMode = BW_OPMODE_20MHZ;
4522 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4523 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4524 }
4525 else
4526 {
4527 regBwOpMode = BW_OPMODE_20MHZ;
4528 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4529 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4530 }
4531 break;
4532 case WIRELESS_MODE_N_24G:
4533 // It support CCK rate by default.
4534 // CCK rate will be filtered out only when associated AP does not support it.
4535 regBwOpMode = BW_OPMODE_20MHZ;
4536 regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4537 regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
4538 break;
4539 case WIRELESS_MODE_N_5G:
4540 regBwOpMode = BW_OPMODE_5G;
4541 regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
4542 regRRSR = RATE_ALL_OFDM_AG;
4543 break;
4544 }
4545
4546 //
4547 // <Roger_Notes> We disable CCK response rate until FIB CCK rate IC's back.
4548 // 2008.09.23.
4549 //
4550 regTmp = read_nic_byte(dev, INIRTSMCS_SEL);
5f53d8ca 4551 regRRSR = ((regRRSR & 0x000fffff)<<8) | regTmp;
5f53d8ca
JC
4552
4553 //
4554 // Update SIFS timing.
4555 //
4556 //priv->SifsTime = 0x0e0e0a0a;
4557 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_SIFS, (pu1Byte)&pHalData->SifsTime);
4558 { u8 val[4] = {0x0e, 0x0e, 0x0a, 0x0a};
4559 // SIFS for CCK Data ACK
4560 write_nic_byte(dev, SIFS_CCK, val[0]);
4561 // SIFS for CCK consecutive tx like CTS data!
4562 write_nic_byte(dev, SIFS_CCK+1, val[1]);
4563
4564 // SIFS for OFDM Data ACK
4565 write_nic_byte(dev, SIFS_OFDM, val[2]);
4566 // SIFS for OFDM consecutive tx like CTS data!
4567 write_nic_byte(dev, SIFS_OFDM+1, val[3]);
4568 }
4569
4570 write_nic_dword(dev, INIRTSMCS_SEL, regRRSR);
4571 write_nic_byte(dev, BW_OPMODE, regBwOpMode);
4572
4573 //
4574 // Suggested by SD1 Alex, 2008-06-14.
4575 //
4576 //PlatformEFIOWrite1Byte(Adapter, TXOP_STALL_CTRL, 0x80);//NAV to protect all TXOP.
4577
4578 //
4579 // Set Data Auto Rate Fallback Retry Count register.
4580 //
4581 write_nic_dword(dev, DARFRC, 0x02010000);
4582 write_nic_dword(dev, DARFRC+4, 0x06050403);
4583 write_nic_dword(dev, RARFRC, 0x02010000);
4584 write_nic_dword(dev, RARFRC+4, 0x06050403);
4585
4586 // Set Data Auto Rate Fallback Reg. Added by Roger, 2008.09.22.
4587 for (i = 0; i < 8; i++)
5f53d8ca 4588 write_nic_dword(dev, ARFR0+i*4, 0x1f0ffff0);
5f53d8ca
JC
4589
4590 //
4591 // Aggregation length limit. Revised by Roger. 2008.09.22.
4592 //
4593 write_nic_byte(dev, AGGLEN_LMT_H, 0x0f); // Set AMPDU length to 12Kbytes for ShortGI case.
4594 write_nic_dword(dev, AGGLEN_LMT_L, 0xddd77442); // Long GI
4595 write_nic_dword(dev, AGGLEN_LMT_L+4, 0xfffdd772);
4596
4597 // Set NAV protection length
4598 write_nic_word(dev, NAV_PROT_LEN, 0x0080);
4599
4600 // Set TXOP stall control for several queue/HI/BCN/MGT/
4601 write_nic_byte(dev, TXOP_STALL_CTRL, 0x00); // NAV Protect next packet.
4602
4603 // Set MSDU lifetime.
4604 write_nic_byte(dev, MLT, 0x8f);
4605
4606 // Set CCK/OFDM SIFS
4607 write_nic_word(dev, SIFS_CCK, 0x0a0a); // CCK SIFS shall always be 10us.
4608 write_nic_word(dev, SIFS_OFDM, 0x0e0e);
4609
4610 write_nic_byte(dev, ACK_TIMEOUT, 0x40);
4611
4612 // CF-END Threshold
4613 write_nic_byte(dev, CFEND_TH, 0xFF);
4614
4615 //
4616 // For Min Spacing configuration.
4617 //
4618 switch(priv->rf_type)
4619 {
4620 case RF_1T2R:
4621 case RF_1T1R:
4622 RT_TRACE(COMP_INIT, "Initializeadapter: RF_Type%s\n", (priv->rf_type==RF_1T1R? "(1T1R)":"(1T2R)"));
4623 priv->MinSpaceCfg = (MAX_MSS_DENSITY_1T<<3);
4624 break;
4625 case RF_2T2R:
4626 case RF_2T2R_GREEN:
4627 RT_TRACE(COMP_INIT, "Initializeadapter:RF_Type(2T2R)\n");
4628 priv->MinSpaceCfg = (MAX_MSS_DENSITY_2T<<3);
4629 break;
4630 }
4631 write_nic_byte(dev, AMPDU_MIN_SPACE, priv->MinSpaceCfg);
4632
4633 //LZM 090219
4634 //
4635 // For Min Spacing configuration.
4636 //
4637 //priv->MinSpaceCfg = 0x00;
4638 //rtl8192SU_SetHwRegAmpduMinSpace(dev, priv->MinSpaceCfg);
4639}
4640
5f53d8ca 4641
5f53d8ca
JC
4642// Description: Initial HW relted registers.
4643//
4644// Assumption: This function is only invoked at driver intialization once.
4645//
4646// 2008.06.10, Added by Roger.
4647bool rtl8192SU_adapter_start(struct net_device *dev)
4648{
4649 struct r8192_priv *priv = ieee80211_priv(dev);
4650 //u32 dwRegRead = 0;
4651 //bool init_status = true;
4652 //u32 ulRegRead;
4653 bool rtStatus = true;
4654 //u8 PipeIndex;
4655 //u8 eRFPath, tmpU1b;
4656 u8 fw_download_times = 1;
4657
4658
4659 RT_TRACE(COMP_INIT, "--->InitializeAdapter8192SUsb()\n");
4660
4661 //pHalData->bGPIOChangeRF = FALSE;
4662
4663
4664 //
4665 // <Roger_Notes> 2008.06.15.
4666 //
4667 // Initialization Steps on RTL8192SU:
4668 // a. MAC initialization prior to sending down firmware code.
4669 // b. Download firmware code step by step(i.e., IMEM, EMEM, DMEM).
4670 // c. MAC configuration after firmware has been download successfully.
4671 // d. Initialize BB related configurations.
4672 // e. Initialize RF related configurations.
4673 // f. Start to BulkIn transfer.
4674 //
4675
4676 //
4677 //a. MAC initialization prior to send down firmware code.
4678 //
4679start:
4680 rtl8192SU_MacConfigBeforeFwDownloadASIC(dev);
4681
4682 //
4683 //b. Download firmware code step by step(i.e., IMEM, EMEM, DMEM).
4684 //
4685 rtStatus = FirmwareDownload92S(dev);
4686 if(rtStatus != true)
4687 {
4688 if(fw_download_times == 1){
4689 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Download Firmware failed once, Download again!!\n");
4690 fw_download_times = fw_download_times + 1;
4691 goto start;
4692 }else{
4693 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Download Firmware failed twice, end!!\n");
4694 goto end;
4695 }
4696 }
4697 //
4698 //c. MAC configuration after firmware has been download successfully.
4699 //
4700 rtl8192SU_MacConfigAfterFwDownload(dev);
4701
5f53d8ca
JC
4702 //priv->bLbusEnable = TRUE;
4703 //if(priv->RegRfOff == TRUE)
4704 // priv->eRFPowerState = eRfOff;
4705
4706 // Save target channel
4707 // <Roger_Notes> Current Channel will be updated again later.
4708 //priv->CurrentChannel = Channel;
4709 rtStatus = PHY_MACConfig8192S(dev);//===>ok
4710 if(rtStatus != true)
4711 {
4712 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure MAC!!\n");
4713 goto end;
4714 }
4715 if (1){
4716 int i;
4717 for (i=0; i<4; i++)
4718 write_nic_dword(dev,WDCAPARA_ADD[i], 0x5e4322);
4719 write_nic_byte(dev,AcmHwCtrl, 0x01);
4720 }
4721
4722
4723 //
4724 //d. Initialize BB related configurations.
4725 //
4726
4727 rtStatus = PHY_BBConfig8192S(dev);//===>ok
4728 if(rtStatus != true)
4729 {
4730 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure BB!!\n");
4731 goto end;
4732 }
4733
4734 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x58);//===>ok
4735
4736 //
4737 // e. Initialize RF related configurations.
4738 //
4739 // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
4740 priv->Rf_Mode = RF_OP_By_SW_3wire;
4741
4742 // For RF test only from Scott's suggestion
4743 //write_nic_byte(dev, 0x27, 0xDB);
4744 //write_nic_byte(dev, 0x1B, 0x07);
4745
4746
4747 write_nic_byte(dev, AFE_XTAL_CTRL+1, 0xDB);
4748
4749 // <Roger_Notes> The following IOs are configured for each RF modules.
4750 // Enable RF module and reset RF and SDM module. 2008.11.17.
4751 if(priv->card_8192_version == VERSION_8192S_ACUT)
4752 write_nic_byte(dev, SPS1_CTRL+3, (u8)(RF_EN|RF_RSTB|RF_SDMRSTB)); // Fix A-Cut bug.
4753 else
4754 write_nic_byte(dev, RF_CTRL, (u8)(RF_EN|RF_RSTB|RF_SDMRSTB));
4755
4756 rtStatus = PHY_RFConfig8192S(dev);//===>ok
4757 if(rtStatus != true)
4758 {
4759 RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure RF!!\n");
4760 goto end;
4761 }
4762
4763
4764 // Set CCK and OFDM Block "ON"
4765 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
4766 rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
4767
4768 //
4769 // Turn off Radio B while RF type is 1T1R by SD3 Wilsion's request.
4770 // Revised by Roger, 2008.12.18.
4771 //
4772 if(priv->rf_type == RF_1T1R)
4773 {
4774 // This is needed for PHY_REG after 20081219
4775 rtl8192_setBBreg(dev, rFPGA0_RFMOD, 0xff000000, 0x03);
4776 // This is needed for PHY_REG before 20081219
4777 //PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, bMaskByte0, 0x11);
4778 }
4779
5f53d8ca
JC
4780
4781 //LZM 090219
4782 // Set CCK and OFDM Block "ON"
4783 //rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
4784 //rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
4785
4786
4787 //3//Get hardware version, do it in read eeprom?
4788 //GetHardwareVersion819xUsb(Adapter);
4789
4790 //3//
4791 //3 //Set Hardware
4792 //3//
4793 rtl8192SU_HwConfigureRTL8192SUsb(dev);//==>ok
4794
4795 //
4796 // <Roger_Notes> We set MAC address here if autoload was failed before,
4797 // otherwise IDR0 will NOT contain any value.
4798 //
4799 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
4800 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
4801 if(!priv->bInHctTest)
4802 {
4803 if(priv->ResetProgress == RESET_TYPE_NORESET)
4804 {
4805 //RT_TRACE(COMP_MLME, DBG_LOUD, ("Initializeadapter8192SUsb():RegWirelessMode(%#x) \n", Adapter->RegWirelessMode));
4806 //Adapter->HalFunc.SetWirelessModeHandler(Adapter, Adapter->RegWirelessMode);
4807 rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);//===>ok
4808 }
4809 }
4810 else
4811 {
4812 priv->ieee80211->mode = WIRELESS_MODE_G;
4813 rtl8192_SetWirelessMode(dev, WIRELESS_MODE_G);
4814 }
4815
4816 //Security related.
4817 //-----------------------------------------------------------------------------
4818 // Set up security related. 070106, by rcnjko:
4819 // 1. Clear all H/W keys.
4820 // 2. Enable H/W encryption/decryption.
4821 //-----------------------------------------------------------------------------
4822 //CamResetAllEntry(Adapter);
4823 //Adapter->HalFunc.EnableHWSecCfgHandler(Adapter);
4824
4825 //SecClearAllKeys(Adapter);
4826 CamResetAllEntry(dev);
4827 //SecInit(Adapter);
4828 {
4829 u8 SECR_value = 0x0;
4830 SECR_value |= SCR_TxEncEnable;
4831 SECR_value |= SCR_RxDecEnable;
4832 SECR_value |= SCR_NoSKMC;
4833 write_nic_byte(dev, SECR, SECR_value);
4834 }
4835
5f53d8ca
JC
4836#ifdef TO_DO_LIST
4837
4838 //PHY_UpdateInitialGain(dev);
4839
4840 if(priv->RegRfOff == true)
4841 { // User disable RF via registry.
4842 u8 eRFPath = 0;
4843
4844 RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): Turn off RF for RegRfOff ----------\n");
4845 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
4846 // Those action will be discard in MgntActSet_RF_State because off the same state
4847 for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
4848 rtl8192_setBBreg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
4849 }
4850 else if(priv->RfOffReason > RF_CHANGE_BY_PS)
4851 { // H/W or S/W RF OFF before sleep.
4852 RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): Turn off RF for RfOffReason(%d) ----------\n", priv->RfOffReason);
4853 MgntActSet_RF_State(dev, eRfOff, priv->RfOffReason);
4854 }
4855 else
4856 {
4857 priv->eRFPowerState = eRfOn;
4858 priv->RfOffReason = 0;
4859 RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): RF is on ----------\n");
4860 }
4861
4862#endif
4863
4864
4865//
4866// f. Start to BulkIn transfer.
4867//
4868#ifdef TO_DO_LIST
4869
4870#ifndef UNDER_VISTA
4871 {
4872 u8 i;
4873 PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
4874
4875 for(PipeIndex=0; PipeIndex < MAX_RX_QUEUE; PipeIndex++)
4876 {
4877 if (PipeIndex == 0)
4878 {
4879 for(i=0; i<32; i++)
4880 HalUsbInMpdu(Adapter, PipeIndex);
4881 }
4882 else
4883 {
4884 //HalUsbInMpdu(Adapter, PipeIndex);
4885 //HalUsbInMpdu(Adapter, PipeIndex);
4886 //HalUsbInMpdu(Adapter, PipeIndex);
4887 }
4888 }
4889 PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
4890 }
4891#else
4892 // Joseph add to 819X code base for Vista USB platform.
4893 // This part may need to be add to Hal819xU code base. too.
4894 PlatformUsbEnableInPipes(Adapter);
4895#endif
4896
4897 RT_TRACE(COMP_INIT, "HighestOperaRate = %x\n", Adapter->MgntInfo.HighestOperaRate);
4898
4899 PlatformStartWorkItem( &(pHalData->RtUsbCheckForHangWorkItem) );
4900
4901 //
4902 // <Roger_EXP> The following configurations are for ASIC verification temporally.
4903 // 2008.07.10.
4904 //
4905
4906#endif
4907
4908 //
4909 // Read EEPROM TX power index and PHY_REG_PG.txt to capture correct
4910 // TX power index for different rate set.
4911 //
4912 //if(priv->card_8192_version >= VERSION_8192S_ACUT)
4913 {
4914 // Get original hw reg values
4915 PHY_GetHWRegOriginalValue(dev);
4916
4917 // Write correct tx power index//FIXLZM
4918 PHY_SetTxPowerLevel8192S(dev, priv->chan);
4919 }
4920
4921 {
4922 u8 tmpU1b = 0;
4923 // EEPROM R/W workaround
4924 tmpU1b = read_nic_byte(dev, MAC_PINMUX_CFG);
4925 write_nic_byte(dev, MAC_PINMUX_CFG, tmpU1b&(~GPIOMUX_EN));
4926 }
4927
4928//
4929//<Roger_Notes> 2008.08.19.
4930// We return status here for temporal FPGA verification, 2008.08.19.
4931
4932#ifdef RTL8192SU_FW_IQK
4933 write_nic_dword(dev, WFM5, FW_IQK_ENABLE);
4934 ChkFwCmdIoDone(dev);
4935#endif
4936
4937 //
4938 // <Roger_Notes> We enable high power mechanism after NIC initialized.
4939 // 2008.11.27.
4940 //
4941 write_nic_dword(dev, WFM5, FW_RA_RESET);
4942 ChkFwCmdIoDone(dev);
4943 write_nic_dword(dev, WFM5, FW_RA_ACTIVE);
4944 ChkFwCmdIoDone(dev);
4945 write_nic_dword(dev, WFM5, FW_RA_REFRESH);
4946 ChkFwCmdIoDone(dev);
4947 write_nic_dword(dev, WFM5, FW_BB_RESET_ENABLE);
4948
4949// <Roger_Notes> We return status here for temporal FPGA verification. 2008.05.12.
4950//
5f53d8ca 4951
5f53d8ca
JC
4952end:
4953return rtStatus;
4954}
4955
5f53d8ca
JC
4956/***************************************************************************
4957 -------------------------------NET STUFF---------------------------
4958***************************************************************************/
4959
4960static struct net_device_stats *rtl8192_stats(struct net_device *dev)
4961{
4962 struct r8192_priv *priv = ieee80211_priv(dev);
4963
4964 return &priv->ieee80211->stats;
4965}
4966
4967bool
4968HalTxCheckStuck819xUsb(
4969 struct net_device *dev
4970 )
4971{
4972 struct r8192_priv *priv = ieee80211_priv(dev);
4973 u16 RegTxCounter = read_nic_word(dev, 0x128);
4974 bool bStuck = FALSE;
4975 RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
4976 if(priv->TxCounter==RegTxCounter)
4977 bStuck = TRUE;
4978
4979 priv->TxCounter = RegTxCounter;
4980
4981 return bStuck;
4982}
4983
4984/*
4985* <Assumption: RT_TX_SPINLOCK is acquired.>
4986* First added: 2006.11.19 by emily
4987*/
4988RESET_TYPE
4989TxCheckStuck(struct net_device *dev)
4990{
4991 struct r8192_priv *priv = ieee80211_priv(dev);
4992 u8 QueueID;
4993// PRT_TCB pTcb;
4994// u8 ResetThreshold;
4995 bool bCheckFwTxCnt = false;
4996 //unsigned long flags;
4997
4998 //
4999 // Decide Stuch threshold according to current power save mode
5000 //
5001
5002// RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n");
5003// PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
5004// spin_lock_irqsave(&priv->ieee80211->lock,flags);
5005 for (QueueID = 0; QueueID<=BEACON_QUEUE;QueueID ++)
5006 {
5007 if(QueueID == TXCMD_QUEUE)
5008 continue;
5009#if 1
5f53d8ca 5010 if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
5f53d8ca
JC
5011 continue;
5012#endif
5013
5014 bCheckFwTxCnt = true;
5015 }
5016// PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
5017// spin_unlock_irqrestore(&priv->ieee80211->lock,flags);
5018// RT_TRACE(COMP_RESET,"bCheckFwTxCnt is %d\n",bCheckFwTxCnt);
5019#if 1
5020 if(bCheckFwTxCnt)
5021 {
5022 if(HalTxCheckStuck819xUsb(dev))
5023 {
5024 RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
5025 return RESET_TYPE_SILENT;
5026 }
5027 }
5028#endif
5029 return RESET_TYPE_NORESET;
5030}
5031
5032bool
5033HalRxCheckStuck819xUsb(struct net_device *dev)
5034{
5035 u16 RegRxCounter = read_nic_word(dev, 0x130);
5036 struct r8192_priv *priv = ieee80211_priv(dev);
5037 bool bStuck = FALSE;
5038//#ifdef RTL8192SU
5039
5040//#else
5041 static u8 rx_chk_cnt = 0;
5042 RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
5043 // If rssi is small, we should check rx for long time because of bad rx.
5044 // or maybe it will continuous silent reset every 2 seconds.
5045 rx_chk_cnt++;
5046 if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
5047 {
5048 rx_chk_cnt = 0; //high rssi, check rx stuck right now.
5049 }
5050 else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
5051 ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
5052 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
5053 {
5054 if(rx_chk_cnt < 2)
5055 {
5056 return bStuck;
5057 }
5058 else
5059 {
5060 rx_chk_cnt = 0;
5061 }
5062 }
5063 else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
5064 (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
5065 priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
5066 {
5067 if(rx_chk_cnt < 4)
5068 {
5069 //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
5070 return bStuck;
5071 }
5072 else
5073 {
5074 rx_chk_cnt = 0;
5075 //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
5076 }
5077 }
5078 else
5079 {
5080 if(rx_chk_cnt < 8)
5081 {
5082 //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
5083 return bStuck;
5084 }
5085 else
5086 {
5087 rx_chk_cnt = 0;
5088 //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
5089 }
5090 }
5091//#endif
5092
5093 if(priv->RxCounter==RegRxCounter)
5094 bStuck = TRUE;
5095
5096 priv->RxCounter = RegRxCounter;
5097
5098 return bStuck;
5099}
5100
5101RESET_TYPE
5102RxCheckStuck(struct net_device *dev)
5103{
5104 struct r8192_priv *priv = ieee80211_priv(dev);
5105 //int i;
5106 bool bRxCheck = FALSE;
5107
5108// RT_TRACE(COMP_RESET," ==> RxCheckStuck()\n");
5109 //PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
5110
5111 if(priv->IrpPendingCount > 1)
5112 bRxCheck = TRUE;
5113 //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
5114
5115// RT_TRACE(COMP_RESET,"bRxCheck is %d \n",bRxCheck);
5116 if(bRxCheck)
5117 {
5118 if(HalRxCheckStuck819xUsb(dev))
5119 {
5120 RT_TRACE(COMP_RESET, "RxStuck Condition\n");
5121 return RESET_TYPE_SILENT;
5122 }
5123 }
5124 return RESET_TYPE_NORESET;
5125}
5126
5127
5128/**
5129* This function is called by Checkforhang to check whether we should ask OS to reset driver
5130*
5131* \param pAdapter The adapter context for this miniport
5132*
5133* Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
5134* to judge whether there is tx stuck.
5135* Note: This function may be required to be rewrite for Vista OS.
5136* <<<Assumption: Tx spinlock has been acquired >>>
5137*
5138* 8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
5139*/
5140RESET_TYPE
5141rtl819x_ifcheck_resetornot(struct net_device *dev)
5142{
5143 struct r8192_priv *priv = ieee80211_priv(dev);
5144 RESET_TYPE TxResetType = RESET_TYPE_NORESET;
5145 RESET_TYPE RxResetType = RESET_TYPE_NORESET;
5146 RT_RF_POWER_STATE rfState;
5147
5f53d8ca 5148 return RESET_TYPE_NORESET;
5f53d8ca
JC
5149
5150 rfState = priv->ieee80211->eRFPowerState;
5151
5152 TxResetType = TxCheckStuck(dev);
5153#if 1
5154 if( rfState != eRfOff ||
5155 /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
5156 (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
5157 {
5158 // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
5159 // in turned off state. Driver should check whether Rx stuck and do silent reset. And
5160 // if driver is in firmware download failure status, driver should initialize RF in the following
5161 // silent reset procedure Emily, 2008.01.21
5162
5163 // Driver should not check RX stuck in IBSS mode because it is required to
5164 // set Check BSSID in order to send beacon, however, if check BSSID is
5165 // set, STA cannot hear any packet a all. Emily, 2008.04.12
5166 RxResetType = RxCheckStuck(dev);
5167 }
5168#endif
5169 if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
5170 return RESET_TYPE_NORMAL;
5171 else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT){
5172 RT_TRACE(COMP_RESET,"%s():silent reset\n",__FUNCTION__);
5173 return RESET_TYPE_SILENT;
5174 }
5175 else
5176 return RESET_TYPE_NORESET;
5177
5178}
5179
5180void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
5181int _rtl8192_up(struct net_device *dev);
5182int rtl8192_close(struct net_device *dev);
5183
5184
5185
5186void
5187CamRestoreAllEntry( struct net_device *dev)
5188{
5189 u8 EntryId = 0;
5190 struct r8192_priv *priv = ieee80211_priv(dev);
5191 u8* MacAddr = priv->ieee80211->current_network.bssid;
5192
5193 static u8 CAM_CONST_ADDR[4][6] = {
5194 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
5195 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
5196 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
5197 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
5198 static u8 CAM_CONST_BROAD[] =
5199 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
5200
5201 RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
5202
5203
5204 if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
5205 (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
5206 {
5207
5208 for(EntryId=0; EntryId<4; EntryId++)
5209 {
5210 {
5211 MacAddr = CAM_CONST_ADDR[EntryId];
5212 setKey(dev,
5213 EntryId ,
5214 EntryId,
5215 priv->ieee80211->pairwise_key_type,
5216 MacAddr,
5217 0,
5218 NULL);
5219 }
5220 }
5221
5222 }
5223 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
5224 {
5225
5226 {
5227 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
5228 setKey(dev,
5229 4,
5230 0,
5231 priv->ieee80211->pairwise_key_type,
5232 (u8*)dev->dev_addr,
5233 0,
5234 NULL);
5235 else
5236 setKey(dev,
5237 4,
5238 0,
5239 priv->ieee80211->pairwise_key_type,
5240 MacAddr,
5241 0,
5242 NULL);
5243 }
5244 }
5245 else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
5246 {
5247
5248 {
5249 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
5250 setKey(dev,
5251 4,
5252 0,
5253 priv->ieee80211->pairwise_key_type,
5254 (u8*)dev->dev_addr,
5255 0,
5256 NULL);
5257 else
5258 setKey(dev,
5259 4,
5260 0,
5261 priv->ieee80211->pairwise_key_type,
5262 MacAddr,
5263 0,
5264 NULL);
5265 }
5266 }
5267
5268
5269
5270 if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
5271 {
5272 MacAddr = CAM_CONST_BROAD;
5273 for(EntryId=1 ; EntryId<4 ; EntryId++)
5274 {
5275 {
5276 setKey(dev,
5277 EntryId,
5278 EntryId,
5279 priv->ieee80211->group_key_type,
5280 MacAddr,
5281 0,
5282 NULL);
5283 }
5284 }
5285 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
5286 setKey(dev,
5287 0,
5288 0,
5289 priv->ieee80211->group_key_type,
5290 CAM_CONST_ADDR[0],
5291 0,
5292 NULL);
5293 }
5294 else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
5295 {
5296 MacAddr = CAM_CONST_BROAD;
5297 for(EntryId=1; EntryId<4 ; EntryId++)
5298 {
5299 {
5300 setKey(dev,
5301 EntryId ,
5302 EntryId,
5303 priv->ieee80211->group_key_type,
5304 MacAddr,
5305 0,
5306 NULL);
5307 }
5308 }
5309
5310 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
5311 setKey(dev,
5312 0 ,
5313 0,
5314 priv->ieee80211->group_key_type,
5315 CAM_CONST_ADDR[0],
5316 0,
5317 NULL);
5318 }
5319}
5320//////////////////////////////////////////////////////////////
5321// This function is used to fix Tx/Rx stop bug temporarily.
5322// This function will do "system reset" to NIC when Tx or Rx is stuck.
5323// The method checking Tx/Rx stuck of this function is supported by FW,
5324// which reports Tx and Rx counter to register 0x128 and 0x130.
5325//////////////////////////////////////////////////////////////
5326void
5327rtl819x_ifsilentreset(struct net_device *dev)
5328{
5329 //OCTET_STRING asocpdu;
5330 struct r8192_priv *priv = ieee80211_priv(dev);
5331 u8 reset_times = 0;
5332 int reset_status = 0;
5333 struct ieee80211_device *ieee = priv->ieee80211;
5334
5335
5336 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
5337 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
5338
5339 if(priv->ResetProgress==RESET_TYPE_NORESET)
5340 {
5341RESET_START:
5342
5343 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
5344
5345 // Set the variable for reset.
5346 priv->ResetProgress = RESET_TYPE_SILENT;
5347// rtl8192_close(dev);
5348#if 1
5349 down(&priv->wx_sem);
5350 if(priv->up == 0)
5351 {
5352 RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
5353 up(&priv->wx_sem);
5354 return ;
5355 }
5356 priv->up = 0;
5357 RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
5358// if(!netif_queue_stopped(dev))
5359// netif_stop_queue(dev);
5360
5361 rtl8192_rtx_disable(dev);
5362 rtl8192_cancel_deferred_work(priv);
5363 deinit_hal_dm(dev);
5364 del_timer_sync(&priv->watch_dog_timer);
5365
5366 ieee->sync_scan_hurryup = 1;
5367 if(ieee->state == IEEE80211_LINKED)
5368 {
5369 down(&ieee->wx_sem);
5370 printk("ieee->state is IEEE80211_LINKED\n");
5371 ieee80211_stop_send_beacons(priv->ieee80211);
5372 del_timer_sync(&ieee->associate_timer);
5f53d8ca 5373 cancel_delayed_work(&ieee->associate_retry_wq);
5f53d8ca
JC
5374 ieee80211_stop_scan(ieee);
5375 netif_carrier_off(dev);
5376 up(&ieee->wx_sem);
5377 }
5378 else{
5379 printk("ieee->state is NOT LINKED\n");
5380 ieee80211_softmac_stop_protocol(priv->ieee80211); }
5381 up(&priv->wx_sem);
5382 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
5383 //rtl8192_irq_disable(dev);
5384 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
5385 reset_status = _rtl8192_up(dev);
5386
5387 RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
5388 if(reset_status == -EAGAIN)
5389 {
5390 if(reset_times < 3)
5391 {
5392 reset_times++;
5393 goto RESET_START;
5394 }
5395 else
5396 {
5397 RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n", __FUNCTION__);
5398 }
5399 }
5400#endif
5401 ieee->is_silent_reset = 1;
5402#if 1
5403 EnableHWSecurityConfig8192(dev);
5404#if 1
5405 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
5406 {
5407 ieee->set_chan(ieee->dev, ieee->current_network.channel);
5408
5409#if 1
5f53d8ca 5410 queue_work(ieee->wq, &ieee->associate_complete_wq);
5f53d8ca
JC
5411#endif
5412
5413 }
5414 else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
5415 {
5416 ieee->set_chan(ieee->dev, ieee->current_network.channel);
5417 ieee->link_change(ieee->dev);
5418
5419 // notify_wx_assoc_event(ieee);
5420
5421 ieee80211_start_send_beacons(ieee);
5422
5423 if (ieee->data_hard_resume)
5424 ieee->data_hard_resume(ieee->dev);
5425 netif_carrier_on(ieee->dev);
5426 }
5427#endif
5428
5429 CamRestoreAllEntry(dev);
5430
5431 priv->ResetProgress = RESET_TYPE_NORESET;
5432 priv->reset_count++;
5433
5434 priv->bForcedSilentReset =false;
5435 priv->bResetInProgress = false;
5436
5437 // For test --> force write UFWP.
5438 write_nic_byte(dev, UFWP, 1);
5439 RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
5440#endif
5441 }
5442}
5443
5444void CAM_read_entry(
5445 struct net_device *dev,
5446 u32 iIndex
5447)
5448{
5449 u32 target_command=0;
5450 u32 target_content=0;
5451 u8 entry_i=0;
5452 u32 ulStatus;
5453 s32 i=100;
5454// printk("=======>start read CAM\n");
5455 for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
5456 {
5457 // polling bit, and No Write enable, and address
5458 target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
5459 target_command= target_command | BIT31;
5460
5461 //Check polling bit is clear
5462// mdelay(1);
5463#if 1
5464 while((i--)>=0)
5465 {
5466 ulStatus = read_nic_dword(dev, RWCAM);
5467 if(ulStatus & BIT31){
5468 continue;
5469 }
5470 else{
5471 break;
5472 }
5473 }
5474#endif
5475 write_nic_dword(dev, RWCAM, target_command);
5476 RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
5477 // printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
5478 target_content = read_nic_dword(dev, RCAMO);
5479 RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
5480 // printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
5481 }
5482 printk("\n");
5483}
5484
5485void rtl819x_update_rxcounts(
5486 struct r8192_priv *priv,
5487 u32* TotalRxBcnNum,
5488 u32* TotalRxDataNum
5489)
5490{
5491 u16 SlotIndex;
5492 u8 i;
5493
5494 *TotalRxBcnNum = 0;
5495 *TotalRxDataNum = 0;
5496
5497 SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
5498 priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
5499 priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
5500 for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
5501 *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
5502 *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
5503 }
5504}
5505
5f53d8ca
JC
5506extern void rtl819x_watchdog_wqcallback(struct work_struct *work)
5507{
5508 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
5509 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
5510 struct net_device *dev = priv->ieee80211->dev;
5f53d8ca
JC
5511 struct ieee80211_device* ieee = priv->ieee80211;
5512 RESET_TYPE ResetType = RESET_TYPE_NORESET;
5513 static u8 check_reset_cnt=0;
5514 bool bBusyTraffic = false;
5515
5516 if(!priv->up)
5517 return;
5518 hal_dm_watchdog(dev);
5519
5520 {//to get busy traffic condition
5521 if(ieee->state == IEEE80211_LINKED)
5522 {
5523 //windows mod 666 to 100.
5524 //if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
5525 // ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
5526 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 100 ||
5527 ieee->LinkDetectInfo.NumTxOkInPeriod> 100 ) {
5528 bBusyTraffic = true;
5529 }
5530 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
5531 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
5532 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
5533 }
5534 }
5535 //added by amy for AP roaming
5536 {
5537 if(priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA)
5538 {
5539 u32 TotalRxBcnNum = 0;
5540 u32 TotalRxDataNum = 0;
5541
5542 rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
5543 if((TotalRxBcnNum+TotalRxDataNum) == 0)
5544 {
5545 #ifdef TODO
5546 if(rfState == eRfOff)
5547 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
5548 #endif
5549 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
5550 // Dot11d_Reset(dev);
5551 priv->ieee80211->state = IEEE80211_ASSOCIATING;
5552 notify_wx_assoc_event(priv->ieee80211);
5553 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
5554 ieee->is_roaming = true;
5555 priv->ieee80211->link_change(dev);
5f53d8ca 5556 queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
5f53d8ca
JC
5557 }
5558 }
5559 priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod=0;
5560 priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod=0;
5561 }
5562// CAM_read_entry(dev,4);
5563 //check if reset the driver
5564 if(check_reset_cnt++ >= 3 && !ieee->is_roaming)
5565 {
5566 ResetType = rtl819x_ifcheck_resetornot(dev);
5567 check_reset_cnt = 3;
5568 //DbgPrint("Start to check silent reset\n");
5569 }
5570 // RT_TRACE(COMP_RESET,"%s():priv->force_reset is %d,priv->ResetProgress is %d, priv->bForcedSilentReset is %d,priv->bDisableNormalResetCheck is %d,ResetType is %d\n",__FUNCTION__,priv->force_reset,priv->ResetProgress,priv->bForcedSilentReset,priv->bDisableNormalResetCheck,ResetType);
5571#if 1
5572 if( (priv->force_reset) || (priv->ResetProgress==RESET_TYPE_NORESET &&
5573 (priv->bForcedSilentReset ||
5574 (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT)))) // This is control by OID set in Pomelo
5575 {
5576 RT_TRACE(COMP_RESET,"%s():priv->force_reset is %d,priv->ResetProgress is %d, priv->bForcedSilentReset is %d,priv->bDisableNormalResetCheck is %d,ResetType is %d\n",__FUNCTION__,priv->force_reset,priv->ResetProgress,priv->bForcedSilentReset,priv->bDisableNormalResetCheck,ResetType);
5577 rtl819x_ifsilentreset(dev);
5578 }
5579#endif
5580 priv->force_reset = false;
5581 priv->bForcedSilentReset = false;
5582 priv->bResetInProgress = false;
5583 RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
5584
5585}
5586
5587void watch_dog_timer_callback(unsigned long data)
5588{
5589 struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
5590 //printk("===============>watch_dog timer\n");
5f53d8ca 5591 queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0);
5f53d8ca 5592 mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
5f53d8ca
JC
5593}
5594int _rtl8192_up(struct net_device *dev)
5595{
5596 struct r8192_priv *priv = ieee80211_priv(dev);
5597 //int i;
5598 int init_status = 0;
5599 priv->up=1;
5600 priv->ieee80211->ieee_up=1;
5601 RT_TRACE(COMP_INIT, "Bringing up iface");
5602 init_status = priv->ops->rtl819x_adapter_start(dev);
5603 if(!init_status)
5604 {
5605 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n", __FUNCTION__);
5606 priv->up=priv->ieee80211->ieee_up = 0;
5607 return -EAGAIN;
5608 }
5609 RT_TRACE(COMP_INIT, "start adapter finished\n");
5610 rtl8192_rx_enable(dev);
5611// rtl8192_tx_enable(dev);
5612 if(priv->ieee80211->state != IEEE80211_LINKED)
5613 ieee80211_softmac_start_protocol(priv->ieee80211);
5614 ieee80211_reset_queue(priv->ieee80211);
5615 watch_dog_timer_callback((unsigned long) dev);
5616 if(!netif_queue_stopped(dev))
5617 netif_start_queue(dev);
5618 else
5619 netif_wake_queue(dev);
5620
5621 /*
5622 * Make sure that drop_unencrypted is initialized as "0"
5623 * No packets will be sent in non-security mode if we had set drop_unencrypted.
5624 * ex, After kill wpa_supplicant process, make the driver up again.
5625 * drop_unencrypted remains as "1", which is set by wpa_supplicant. 2008/12/04.john
5626 */
5627 priv->ieee80211->drop_unencrypted = 0;
5628
5629 return 0;
5630}
5631
5632
5633int rtl8192_open(struct net_device *dev)
5634{
5635 struct r8192_priv *priv = ieee80211_priv(dev);
5636 int ret;
5637 down(&priv->wx_sem);
5638 ret = rtl8192_up(dev);
5639 up(&priv->wx_sem);
5640 return ret;
5641
5642}
5643
5644
5645int rtl8192_up(struct net_device *dev)
5646{
5647 struct r8192_priv *priv = ieee80211_priv(dev);
5648
5649 if (priv->up == 1) return -1;
5650
5651 return _rtl8192_up(dev);
5652}
5653
5654
5655int rtl8192_close(struct net_device *dev)
5656{
5657 struct r8192_priv *priv = ieee80211_priv(dev);
5658 int ret;
5659
5660 down(&priv->wx_sem);
5661
5662 ret = rtl8192_down(dev);
5663
5664 up(&priv->wx_sem);
5665
5666 return ret;
5667
5668}
5669
5670int rtl8192_down(struct net_device *dev)
5671{
5672 struct r8192_priv *priv = ieee80211_priv(dev);
5673 int i;
5674
5675 if (priv->up == 0) return -1;
5676
5677 priv->up=0;
5678 priv->ieee80211->ieee_up = 0;
5679 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
5680/* FIXME */
5681 if (!netif_queue_stopped(dev))
5682 netif_stop_queue(dev);
5683
5684 rtl8192_rtx_disable(dev);
5685 //rtl8192_irq_disable(dev);
5686
5687 /* Tx related queue release */
5688 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
5689 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
5690 }
5691 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
5692 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
5693 }
5694
5695 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
5696 skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]);
5697 }
5698
5699 //as cancel_delayed_work will del work->timer, so if work is not definedas struct delayed_work, it will corrupt
5700// flush_scheduled_work();
5701 rtl8192_cancel_deferred_work(priv);
5702 deinit_hal_dm(dev);
5703 del_timer_sync(&priv->watch_dog_timer);
5704
5705
5706 ieee80211_softmac_stop_protocol(priv->ieee80211);
5707 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
5708 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
5709
5710 return 0;
5711}
5712
5713
5714void rtl8192_commit(struct net_device *dev)
5715{
5716 struct r8192_priv *priv = ieee80211_priv(dev);
5717 int reset_status = 0;
5718 //u8 reset_times = 0;
5719 if (priv->up == 0) return ;
5720 priv->up = 0;
5721
5722 rtl8192_cancel_deferred_work(priv);
5723 del_timer_sync(&priv->watch_dog_timer);
5724 //cancel_delayed_work(&priv->SwChnlWorkItem);
5725
5726 ieee80211_softmac_stop_protocol(priv->ieee80211);
5727
5728 //rtl8192_irq_disable(dev);
5729 rtl8192_rtx_disable(dev);
5730 reset_status = _rtl8192_up(dev);
5731
5732}
5733
5734/*
5735void rtl8192_restart(struct net_device *dev)
5736{
5737 struct r8192_priv *priv = ieee80211_priv(dev);
5738*/
5f53d8ca
JC
5739void rtl8192_restart(struct work_struct *work)
5740{
5741 struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
5742 struct net_device *dev = priv->ieee80211->dev;
5f53d8ca
JC
5743
5744 down(&priv->wx_sem);
5745
5746 rtl8192_commit(dev);
5747
5748 up(&priv->wx_sem);
5749}
5750
5751static void r8192_set_multicast(struct net_device *dev)
5752{
5753 struct r8192_priv *priv = ieee80211_priv(dev);
5754 short promisc;
5755
5756 //down(&priv->wx_sem);
5757
5758 /* FIXME FIXME */
5759
5760 promisc = (dev->flags & IFF_PROMISC) ? 1:0;
5761
5762 if (promisc != priv->promisc)
5763 // rtl8192_commit(dev);
5764
5765 priv->promisc = promisc;
5766
5767 //schedule_work(&priv->reset_wq);
5768 //up(&priv->wx_sem);
5769}
5770
5771
5772int r8192_set_mac_adr(struct net_device *dev, void *mac)
5773{
5774 struct r8192_priv *priv = ieee80211_priv(dev);
5775 struct sockaddr *addr = mac;
5776
5777 down(&priv->wx_sem);
5778
5779 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
5780
5f53d8ca 5781 schedule_work(&priv->reset_wq);
1ec9e48d 5782
5f53d8ca
JC
5783 up(&priv->wx_sem);
5784
5785 return 0;
5786}
5787
5788/* based on ipw2200 driver */
5789int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5790{
5791 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5792 struct iwreq *wrq = (struct iwreq *)rq;
5793 int ret=-1;
5794 struct ieee80211_device *ieee = priv->ieee80211;
5795 u32 key[4];
5796 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
5797 u8 zero_addr[6] = {0};
5798 struct iw_point *p = &wrq->u.data;
5799 struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
5800
5801 down(&priv->wx_sem);
5802
5803
5804 if (p->length < sizeof(struct ieee_param) || !p->pointer){
5805 ret = -EINVAL;
5806 goto out;
5807 }
5808
5809 ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
5810 if (ipw == NULL){
5811 ret = -ENOMEM;
5812 goto out;
5813 }
5814 if (copy_from_user(ipw, p->pointer, p->length)) {
5815 kfree(ipw);
5816 ret = -EFAULT;
5817 goto out;
5818 }
5819
5820 switch (cmd) {
5821 case RTL_IOCTL_WPA_SUPPLICANT:
5822 //parse here for HW security
5823 if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
5824 {
5825 if (ipw->u.crypt.set_tx)
5826 {
5827 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
5828 ieee->pairwise_key_type = KEY_TYPE_CCMP;
5829 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
5830 ieee->pairwise_key_type = KEY_TYPE_TKIP;
5831 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
5832 {
5833 if (ipw->u.crypt.key_len == 13)
5834 ieee->pairwise_key_type = KEY_TYPE_WEP104;
5835 else if (ipw->u.crypt.key_len == 5)
5836 ieee->pairwise_key_type = KEY_TYPE_WEP40;
5837 }
5838 else
5839 ieee->pairwise_key_type = KEY_TYPE_NA;
5840
5841 if (ieee->pairwise_key_type)
5842 {
5843 // FIXME:these two lines below just to fix ipw interface bug, that is, it will never set mode down to driver. So treat it as ADHOC mode, if no association procedure. WB. 2009.02.04
5844 if (memcmp(ieee->ap_mac_addr, zero_addr, 6) == 0)
5845 ieee->iw_mode = IW_MODE_ADHOC;
5846 memcpy((u8*)key, ipw->u.crypt.key, 16);
5847 EnableHWSecurityConfig8192(dev);
5848 //we fill both index entry and 4th entry for pairwise key as in IPW interface, adhoc will only get here, so we need index entry for its default key serching!
5849 //added by WB.
5850 setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
5851 if (ieee->iw_mode == IW_MODE_ADHOC)
5852 setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
5853 }
5854 }
5855 else //if (ipw->u.crypt.idx) //group key use idx > 0
5856 {
5857 memcpy((u8*)key, ipw->u.crypt.key, 16);
5858 if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
5859 ieee->group_key_type= KEY_TYPE_CCMP;
5860 else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
5861 ieee->group_key_type = KEY_TYPE_TKIP;
5862 else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
5863 {
5864 if (ipw->u.crypt.key_len == 13)
5865 ieee->group_key_type = KEY_TYPE_WEP104;
5866 else if (ipw->u.crypt.key_len == 5)
5867 ieee->group_key_type = KEY_TYPE_WEP40;
5868 }
5869 else
5870 ieee->group_key_type = KEY_TYPE_NA;
5871
5872 if (ieee->group_key_type)
5873 {
5874 setKey( dev,
5875 ipw->u.crypt.idx,
5876 ipw->u.crypt.idx, //KeyIndex
5877 ieee->group_key_type, //KeyType
5878 broadcast_addr, //MacAddr
5879 0, //DefaultKey
5880 key); //KeyContent
5881 }
5882 }
5883 }
5884#ifdef JOHN_HWSEC_DEBUG
5885 //john's test 0711
5886 printk("@@ wrq->u pointer = ");
5887 for(i=0;i<wrq->u.data.length;i++){
5888 if(i%10==0) printk("\n");
5889 printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
5890 }
5891 printk("\n");
5892#endif /*JOHN_HWSEC_DEBUG*/
5893 ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
5894 break;
5895
5896 default:
5897 ret = -EOPNOTSUPP;
5898 break;
5899 }
5900 kfree(ipw);
5901 ipw = NULL;
5902out:
5903 up(&priv->wx_sem);
5904 return ret;
5905}
5906
5f53d8ca
JC
5907u8 rtl8192SU_HwRateToMRate(bool bIsHT, u8 rate,bool bFirstAMPDU)
5908{
5909
5910 u8 ret_rate = 0x02;
5911
5912 if( bFirstAMPDU )
5913 {
5914 if(!bIsHT)
5915 {
5916 switch(rate)
5917 {
5918
5919 case DESC92S_RATE1M: ret_rate = MGN_1M; break;
5920 case DESC92S_RATE2M: ret_rate = MGN_2M; break;
5921 case DESC92S_RATE5_5M: ret_rate = MGN_5_5M; break;
5922 case DESC92S_RATE11M: ret_rate = MGN_11M; break;
5923 case DESC92S_RATE6M: ret_rate = MGN_6M; break;
5924 case DESC92S_RATE9M: ret_rate = MGN_9M; break;
5925 case DESC92S_RATE12M: ret_rate = MGN_12M; break;
5926 case DESC92S_RATE18M: ret_rate = MGN_18M; break;
5927 case DESC92S_RATE24M: ret_rate = MGN_24M; break;
5928 case DESC92S_RATE36M: ret_rate = MGN_36M; break;
5929 case DESC92S_RATE48M: ret_rate = MGN_48M; break;
5930 case DESC92S_RATE54M: ret_rate = MGN_54M; break;
5931
5932 default:
5933 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
5934 break;
5935 }
5936 }
5937 else
5938 {
5939 switch(rate)
5940 {
5941
5942 case DESC92S_RATEMCS0: ret_rate = MGN_MCS0; break;
5943 case DESC92S_RATEMCS1: ret_rate = MGN_MCS1; break;
5944 case DESC92S_RATEMCS2: ret_rate = MGN_MCS2; break;
5945 case DESC92S_RATEMCS3: ret_rate = MGN_MCS3; break;
5946 case DESC92S_RATEMCS4: ret_rate = MGN_MCS4; break;
5947 case DESC92S_RATEMCS5: ret_rate = MGN_MCS5; break;
5948 case DESC92S_RATEMCS6: ret_rate = MGN_MCS6; break;
5949 case DESC92S_RATEMCS7: ret_rate = MGN_MCS7; break;
5950 case DESC92S_RATEMCS8: ret_rate = MGN_MCS8; break;
5951 case DESC92S_RATEMCS9: ret_rate = MGN_MCS9; break;
5952 case DESC92S_RATEMCS10: ret_rate = MGN_MCS10; break;
5953 case DESC92S_RATEMCS11: ret_rate = MGN_MCS11; break;
5954 case DESC92S_RATEMCS12: ret_rate = MGN_MCS12; break;
5955 case DESC92S_RATEMCS13: ret_rate = MGN_MCS13; break;
5956 case DESC92S_RATEMCS14: ret_rate = MGN_MCS14; break;
5957 case DESC92S_RATEMCS15: ret_rate = MGN_MCS15; break;
5958 case DESC92S_RATEMCS32: ret_rate = (0x80|0x20); break;
5959
5960 default:
5961 RT_TRACE(COMP_RECV, "HwRateToMRate92S(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT );
5962 break;
5963 }
5964
5965 }
5966 }
5967 else
5968 {
5969 switch(rate)
5970 {
5971
5972 case DESC92S_RATE1M: ret_rate = MGN_1M; break;
5973 case DESC92S_RATE2M: ret_rate = MGN_2M; break;
5974 case DESC92S_RATE5_5M: ret_rate = MGN_5_5M; break;
5975 case DESC92S_RATE11M: ret_rate = MGN_11M; break;
5976 case DESC92S_RATE6M: ret_rate = MGN_6M; break;
5977 case DESC92S_RATE9M: ret_rate = MGN_9M; break;
5978 case DESC92S_RATE12M: ret_rate = MGN_12M; break;
5979 case DESC92S_RATE18M: ret_rate = MGN_18M; break;
5980 case DESC92S_RATE24M: ret_rate = MGN_24M; break;
5981 case DESC92S_RATE36M: ret_rate = MGN_36M; break;
5982 case DESC92S_RATE48M: ret_rate = MGN_48M; break;
5983 case DESC92S_RATE54M: ret_rate = MGN_54M; break;
5984 case DESC92S_RATEMCS0: ret_rate = MGN_MCS0; break;
5985 case DESC92S_RATEMCS1: ret_rate = MGN_MCS1; break;
5986 case DESC92S_RATEMCS2: ret_rate = MGN_MCS2; break;
5987 case DESC92S_RATEMCS3: ret_rate = MGN_MCS3; break;
5988 case DESC92S_RATEMCS4: ret_rate = MGN_MCS4; break;
5989 case DESC92S_RATEMCS5: ret_rate = MGN_MCS5; break;
5990 case DESC92S_RATEMCS6: ret_rate = MGN_MCS6; break;
5991 case DESC92S_RATEMCS7: ret_rate = MGN_MCS7; break;
5992 case DESC92S_RATEMCS8: ret_rate = MGN_MCS8; break;
5993 case DESC92S_RATEMCS9: ret_rate = MGN_MCS9; break;
5994 case DESC92S_RATEMCS10: ret_rate = MGN_MCS10; break;
5995 case DESC92S_RATEMCS11: ret_rate = MGN_MCS11; break;
5996 case DESC92S_RATEMCS12: ret_rate = MGN_MCS12; break;
5997 case DESC92S_RATEMCS13: ret_rate = MGN_MCS13; break;
5998 case DESC92S_RATEMCS14: ret_rate = MGN_MCS14; break;
5999 case DESC92S_RATEMCS15: ret_rate = MGN_MCS15; break;
6000 case DESC92S_RATEMCS32: ret_rate = (0x80|0x20); break;
6001
6002 default:
6003 RT_TRACE(COMP_RECV, "HwRateToMRate92S(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT );
6004 break;
6005 }
6006 }
6007 return ret_rate;
6008}
5f53d8ca
JC
6009
6010u8 HwRateToMRate90(bool bIsHT, u8 rate)
6011{
6012 u8 ret_rate = 0xff;
6013
6014 if(!bIsHT) {
6015 switch(rate) {
6016 case DESC90_RATE1M: ret_rate = MGN_1M; break;
6017 case DESC90_RATE2M: ret_rate = MGN_2M; break;
6018 case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
6019 case DESC90_RATE11M: ret_rate = MGN_11M; break;
6020 case DESC90_RATE6M: ret_rate = MGN_6M; break;
6021 case DESC90_RATE9M: ret_rate = MGN_9M; break;
6022 case DESC90_RATE12M: ret_rate = MGN_12M; break;
6023 case DESC90_RATE18M: ret_rate = MGN_18M; break;
6024 case DESC90_RATE24M: ret_rate = MGN_24M; break;
6025 case DESC90_RATE36M: ret_rate = MGN_36M; break;
6026 case DESC90_RATE48M: ret_rate = MGN_48M; break;
6027 case DESC90_RATE54M: ret_rate = MGN_54M; break;
6028
6029 default:
6030 ret_rate = 0xff;
6031 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
6032 break;
6033 }
6034
6035 } else {
6036 switch(rate) {
6037 case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
6038 case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
6039 case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
6040 case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
6041 case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
6042 case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
6043 case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
6044 case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
6045 case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
6046 case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
6047 case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
6048 case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
6049 case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
6050 case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
6051 case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
6052 case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
6053 case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
6054
6055 default:
6056 ret_rate = 0xff;
6057 RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
6058 break;
6059 }
6060 }
6061
6062 return ret_rate;
6063}
6064
6065/**
6066 * Function: UpdateRxPktTimeStamp
6067 * Overview: Recored down the TSF time stamp when receiving a packet
6068 *
6069 * Input:
6070 * PADAPTER Adapter
6071 * PRT_RFD pRfd,
6072 *
6073 * Output:
6074 * PRT_RFD pRfd
6075 * (pRfd->Status.TimeStampHigh is updated)
6076 * (pRfd->Status.TimeStampLow is updated)
6077 * Return:
6078 * None
6079 */
6080void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
6081{
6082 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6083
6084 if(stats->bIsAMPDU && !stats->bFirstMPDU) {
6085 stats->mac_time[0] = priv->LastRxDescTSFLow;
6086 stats->mac_time[1] = priv->LastRxDescTSFHigh;
6087 } else {
6088 priv->LastRxDescTSFLow = stats->mac_time[0];
6089 priv->LastRxDescTSFHigh = stats->mac_time[1];
6090 }
6091}
6092
6093//by amy 080606
6094
6095long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index.
6096{
6097 long signal_power; // in dBm.
6098
6099 // Translate to dBm (x=0.5y-95).
6100 signal_power = (long)((signal_strength_index + 1) >> 1);
6101 signal_power -= 95;
6102
6103 return signal_power;
6104}
6105
6106
6107/* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
6108 be a local static. Otherwise, it may increase when we return from S3/S4. The
6109 value will be kept in memory or disk. We must delcare the value in adapter
6110 and it will be reinitialized when return from S3/S4. */
6111void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
6112{
6113 bool bcheck = false;
6114 u8 rfpath;
6115 u32 nspatial_stream, tmp_val;
6116 //u8 i;
6117 static u32 slide_rssi_index=0, slide_rssi_statistics=0;
6118 static u32 slide_evm_index=0, slide_evm_statistics=0;
6119 static u32 last_rssi=0, last_evm=0;
6120
6121 static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
6122 static u32 last_beacon_adc_pwdb=0;
6123
6124 struct ieee80211_hdr_3addr *hdr;
6125 u16 sc ;
6126 unsigned int frag,seq;
6127 hdr = (struct ieee80211_hdr_3addr *)buffer;
6128 sc = le16_to_cpu(hdr->seq_ctl);
6129 frag = WLAN_GET_SEQ_FRAG(sc);
6130 seq = WLAN_GET_SEQ_SEQ(sc);
6131 //cosa add 04292008 to record the sequence number
6132 pcurrent_stats->Seq_Num = seq;
6133 //
6134 // Check whether we should take the previous packet into accounting
6135 //
6136 if(!pprevious_stats->bIsAMPDU)
6137 {
6138 // if previous packet is not aggregated packet
6139 bcheck = true;
6140 }else
6141 {
5f53d8ca
JC
6142 }
6143
6144
6145 if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
6146 {
6147 slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
6148 last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
6149 priv->stats.slide_rssi_total -= last_rssi;
6150 }
6151 priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
6152
6153 priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
6154 if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
6155 slide_rssi_index = 0;
6156
6157 // <1> Showed on UI for user, in dbm
6158 tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
6159 priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
6160 pcurrent_stats->rssi = priv->stats.signal_strength;
6161 //
6162 // If the previous packet does not match the criteria, neglect it
6163 //
6164 if(!pprevious_stats->bPacketMatchBSSID)
6165 {
6166 if(!pprevious_stats->bToSelfBA)
6167 return;
6168 }
6169
6170 if(!bcheck)
6171 return;
6172
6173
6174 //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
6175
6176 //
6177 // Check RSSI
6178 //
6179 priv->stats.num_process_phyinfo++;
6180
6181 /* record the general signal strength to the sliding window. */
6182
6183
6184 // <2> Showed on UI for engineering
6185 // hardware does not provide rssi information for each rf path in CCK
6186 if(!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA))
6187 {
6188 for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++)
6189 {
6190 if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
6191 continue;
6192
6193 //Fixed by Jacken 2008-03-20
6194 if(priv->stats.rx_rssi_percentage[rfpath] == 0)
6195 {
6196 priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
6197 //DbgPrint("MIMO RSSI initialize \n");
6198 }
6199 if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
6200 {
6201 priv->stats.rx_rssi_percentage[rfpath] =
6202 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
6203 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
6204 priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
6205 }
6206 else
6207 {
6208 priv->stats.rx_rssi_percentage[rfpath] =
6209 ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
6210 (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
6211 }
6212 RT_TRACE(COMP_DBG,"priv->stats.rx_rssi_percentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
6213 }
6214 }
6215
6216
6217 //
6218 // Check PWDB.
6219 //
6220 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
6221 pprevious_stats->bIsCCK? "CCK": "OFDM",
6222 pprevious_stats->RxPWDBAll);
6223
6224 if(pprevious_stats->bPacketBeacon)
6225 {
6226/* record the beacon pwdb to the sliding window. */
6227 if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
6228 {
6229 slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
6230 last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
6231 priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
6232 //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
6233 // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
6234 }
6235 priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
6236 priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
6237 //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
6238 slide_beacon_adc_pwdb_index++;
6239 if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
6240 slide_beacon_adc_pwdb_index = 0;
6241 pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
6242 if(pprevious_stats->RxPWDBAll >= 3)
6243 pprevious_stats->RxPWDBAll -= 3;
6244 }
6245
6246 RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
6247 pprevious_stats->bIsCCK? "CCK": "OFDM",
6248 pprevious_stats->RxPWDBAll);
6249
6250
6251 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
6252 {
6253 if(priv->undecorated_smoothed_pwdb < 0) // initialize
6254 {
6255 priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
6256 //DbgPrint("First pwdb initialize \n");
6257 }
6258#if 1
6259 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
6260 {
6261 priv->undecorated_smoothed_pwdb =
6262 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
6263 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
6264 priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
6265 }
6266 else
6267 {
6268 priv->undecorated_smoothed_pwdb =
6269 ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
6270 (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
6271 }
6272#else
6273 //Fixed by Jacken 2008-03-20
6274 if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
6275 {
6276 pHalData->UndecoratedSmoothedPWDB =
6277 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
6278 pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
6279 }
6280 else
6281 {
6282 pHalData->UndecoratedSmoothedPWDB =
6283 ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
6284 }
6285#endif
6286
6287 }
6288
6289 //
6290 // Check EVM
6291 //
6292 /* record the general EVM to the sliding window. */
6293 if(pprevious_stats->SignalQuality == 0)
6294 {
6295 }
6296 else
6297 {
6298 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
6299 if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
6300 slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
6301 last_evm = priv->stats.slide_evm[slide_evm_index];
6302 priv->stats.slide_evm_total -= last_evm;
6303 }
6304
6305 priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
6306
6307 priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
6308 if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
6309 slide_evm_index = 0;
6310
6311 // <1> Showed on UI for user, in percentage.
6312 tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
6313 priv->stats.signal_quality = tmp_val;
6314 //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
6315 priv->stats.last_signal_strength_inpercent = tmp_val;
6316 }
6317
6318 // <2> Showed on UI for engineering
6319 if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
6320 {
6321 for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
6322 {
6323 if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
6324 {
6325 if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
6326 {
6327 priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
6328 }
6329 priv->stats.rx_evm_percentage[nspatial_stream] =
6330 ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
6331 (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
6332 }
6333 }
6334 }
6335 }
6336
6337
6338}
6339
6340/*-----------------------------------------------------------------------------
6341 * Function: rtl819x_query_rxpwrpercentage()
6342 *
6343 * Overview:
6344 *
6345 * Input: char antpower
6346 *
6347 * Output: NONE
6348 *
6349 * Return: 0-100 percentage
6350 *
6351 * Revised History:
6352 * When Who Remark
6353 * 05/26/2008 amy Create Version 0 porting from windows code.
6354 *
6355 *---------------------------------------------------------------------------*/
6356static u8 rtl819x_query_rxpwrpercentage(
6357 char antpower
6358 )
6359{
6360 if ((antpower <= -100) || (antpower >= 20))
6361 {
6362 return 0;
6363 }
6364 else if (antpower >= 0)
6365 {
6366 return 100;
6367 }
6368 else
6369 {
6370 return (100+antpower);
6371 }
6372
6373} /* QueryRxPwrPercentage */
6374
6375static u8
6376rtl819x_evm_dbtopercentage(
6377 char value
6378 )
6379{
6380 char ret_val;
6381
6382 ret_val = value;
6383
6384 if(ret_val >= 0)
6385 ret_val = 0;
6386 if(ret_val <= -33)
6387 ret_val = -33;
6388 ret_val = 0 - ret_val;
6389 ret_val*=3;
6390 if(ret_val == 99)
6391 ret_val = 100;
6392 return(ret_val);
6393}
6394//
6395// Description:
6396// We want good-looking for signal strength/quality
6397// 2007/7/19 01:09, by cosa.
6398//
6399long
6400rtl819x_signal_scale_mapping(
6401 long currsig
6402 )
6403{
6404 long retsig;
6405
6406 // Step 1. Scale mapping.
6407 if(currsig >= 61 && currsig <= 100)
6408 {
6409 retsig = 90 + ((currsig - 60) / 4);
6410 }
6411 else if(currsig >= 41 && currsig <= 60)
6412 {
6413 retsig = 78 + ((currsig - 40) / 2);
6414 }
6415 else if(currsig >= 31 && currsig <= 40)
6416 {
6417 retsig = 66 + (currsig - 30);
6418 }
6419 else if(currsig >= 21 && currsig <= 30)
6420 {
6421 retsig = 54 + (currsig - 20);
6422 }
6423 else if(currsig >= 5 && currsig <= 20)
6424 {
6425 retsig = 42 + (((currsig - 5) * 2) / 3);
6426 }
6427 else if(currsig == 4)
6428 {
6429 retsig = 36;
6430 }
6431 else if(currsig == 3)
6432 {
6433 retsig = 27;
6434 }
6435 else if(currsig == 2)
6436 {
6437 retsig = 18;
6438 }
6439 else if(currsig == 1)
6440 {
6441 retsig = 9;
6442 }
6443 else
6444 {
6445 retsig = currsig;
6446 }
6447
6448 return retsig;
6449}
6450
5f53d8ca
JC
6451/*-----------------------------------------------------------------------------
6452 * Function: QueryRxPhyStatus8192S()
6453 *
6454 * Overview:
6455 *
6456 * Input: NONE
6457 *
6458 * Output: NONE
6459 *
6460 * Return: NONE
6461 *
6462 * Revised History:
6463 * When Who Remark
6464 * 06/01/2007 MHC Create Version 0.
6465 * 06/05/2007 MHC Accordign to HW's new data sheet, we add CCK and OFDM
6466 * descriptor definition.
6467 * 07/04/2007 MHC According to Jerry and Bryant's document. We read
6468 * ir_isolation and ext_lna for RF's init value and use
6469 * to compensate RSSI after receiving packets.
6470 * 09/10/2008 MHC Modify name and PHY status field for 92SE.
6471 * 09/19/2008 MHC Add CCK/OFDM SS/SQ for 92S series.
6472 *
6473 *---------------------------------------------------------------------------*/
6474static void rtl8192SU_query_rxphystatus(
6475 struct r8192_priv * priv,
6476 struct ieee80211_rx_stats * pstats,
6477 rx_desc_819x_usb *pDesc,
6478 rx_drvinfo_819x_usb * pdrvinfo,
6479 struct ieee80211_rx_stats * precord_stats,
6480 bool bpacket_match_bssid,
6481 bool bpacket_toself,
6482 bool bPacketBeacon,
6483 bool bToSelfBA
6484 )
6485{
6486 //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
6487 //PHY_STS_CCK_8192S_T *pCck_buf;
6488 phy_sts_cck_819xusb_t * pcck_buf;
6489 phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
6490 //u8 *prxpkt;
6491 //u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
6492 u8 i, max_spatial_stream, rxsc_sgien_exflg;
6493 char rx_pwr[4], rx_pwr_all=0;
6494 //long rx_avg_pwr = 0;
6495 //char rx_snrX, rx_evmX;
6496 u8 evm, pwdb_all;
6497 u32 RSSI, total_rssi=0;//, total_evm=0;
6498// long signal_strength_index = 0;
6499 u8 is_cck_rate=0;
6500 u8 rf_rx_num = 0;
6501
6502
6503
6504 priv->stats.numqry_phystatus++;
6505
6506 is_cck_rate = rx_hal_is_cck_rate(pDesc);
6507
6508 // Record it for next packet processing
6509 memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
6510 pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
6511 pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
6512 pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
6513 pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
6514 pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
6515
5f53d8ca
JC
6516
6517 pstats->RxMIMOSignalQuality[0] = -1;
6518 pstats->RxMIMOSignalQuality[1] = -1;
6519 precord_stats->RxMIMOSignalQuality[0] = -1;
6520 precord_stats->RxMIMOSignalQuality[1] = -1;
6521
6522 if(is_cck_rate)
6523 {
6524 u8 report;//, tmp_pwdb;
6525 //char cck_adc_pwdb[4];
6526
6527 // CCK Driver info Structure is not the same as OFDM packet.
6528 pcck_buf = (phy_sts_cck_819xusb_t *)pdrvinfo;
6529
6530 //
6531 // (1)Hardware does not provide RSSI for CCK
6532 //
6533
6534 //
6535 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
6536 //
6537
6538 priv->stats.numqry_phystatusCCK++;
6539
6540 if(!priv->bCckHighPower)
6541 {
6542 report = pcck_buf->cck_agc_rpt & 0xc0;
6543 report = report>>6;
6544 switch(report)
6545 {
6546 //Fixed by Jacken from Bryant 2008-03-20
6547 //Original value is -38 , -26 , -14 , -2
6548 //Fixed value is -35 , -23 , -11 , 6
6549 case 0x3:
6550 rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
6551 break;
6552 case 0x2:
6553 rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
6554 break;
6555 case 0x1:
6556 rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
6557 break;
6558 case 0x0:
6559 rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);//6->8
6560 break;
6561 }
6562 }
6563 else
6564 {
6565 report = pdrvinfo->cfosho[0] & 0x60;
6566 report = report>>5;
6567 switch(report)
6568 {
6569 case 0x3:
6570 rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
6571 break;
6572 case 0x2:
6573 rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
6574 break;
6575 case 0x1:
6576 rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
6577 break;
6578 case 0x0:
6579 rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;//6->-8
6580 break;
6581 }
6582 }
6583
6584 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);//check it
6585 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
6586 //pstats->RecvSignalPower = pwdb_all;
6587 pstats->RecvSignalPower = rx_pwr_all;
6588
6589 //
6590 // (3) Get Signal Quality (EVM)
6591 //
6592 //if(bpacket_match_bssid)
6593 {
6594 u8 sq;
6595
6596 if(pstats->RxPWDBAll > 40)
6597 {
6598 sq = 100;
6599 }else
6600 {
6601 sq = pcck_buf->sq_rpt;
6602
6603 if(pcck_buf->sq_rpt > 64)
6604 sq = 0;
6605 else if (pcck_buf->sq_rpt < 20)
6606 sq = 100;
6607 else
6608 sq = ((64-sq) * 100) / 44;
6609 }
6610 pstats->SignalQuality = precord_stats->SignalQuality = sq;
6611 pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
6612 pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
6613 }
6614 }
6615 else
6616 {
6617 priv->stats.numqry_phystatusHT++;
6618
6619 // 2008/09/19 MH For 92S debug, RX RF path always enable!!
6620 priv->brfpath_rxenable[0] = priv->brfpath_rxenable[1] = TRUE;
6621
6622 //
6623 // (1)Get RSSI for HT rate
6624 //
6625 //for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
6626 for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
6627 {
6628 // 2008/01/30 MH we will judge RF RX path now.
6629 if (priv->brfpath_rxenable[i])
6630 rf_rx_num++;
6631 //else
6632 // continue;
6633
6634 //if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
6635 // continue;
6636
6637 //Fixed by Jacken from Bryant 2008-03-20
6638 //Original value is 106
6639 //rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
6640 rx_pwr[i] = ((pdrvinfo->gain_trsw[i]&0x3F)*2) - 110;
6641
6642 /* Translate DBM to percentage. */
6643 RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]); //check ok
6644 total_rssi += RSSI;
6645 RT_TRACE(COMP_RF, "RF-%d RXPWR=%x RSSI=%d\n", i, rx_pwr[i], RSSI);
6646
6647 //Get Rx snr value in DB
6648 //tmp_rxsnr = pofdm_buf->rxsnr_X[i];
6649 //rx_snrX = (char)(tmp_rxsnr);
6650 //rx_snrX /= 2;
6651 //priv->stats.rxSNRdB[i] = (long)rx_snrX;
6652 priv->stats.rxSNRdB[i] = (long)(pdrvinfo->rxsnr[i]/2);
6653
6654 /* Translate DBM to percentage. */
6655 //RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
6656 //total_rssi += RSSI;
6657
6658 /* Record Signal Strength for next packet */
6659 //if(bpacket_match_bssid)
6660 {
6661 pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
6662 precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
6663 }
6664 }
6665
6666
6667 //
6668 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
6669 //
6670 //Fixed by Jacken from Bryant 2008-03-20
6671 //Original value is 106
6672 //rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
6673 rx_pwr_all = (((pdrvinfo->pwdb_all ) >> 1 )& 0x7f) -106;
6674 pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
6675
6676 pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
6677 pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
6678 pstats->RecvSignalPower = rx_pwr_all;
6679
6680 //
6681 // (3)EVM of HT rate
6682 //
6683 //if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
6684 // pdrvinfo->RxRate<=DESC90_RATEMCS15)
6685 if(pDesc->RxHT && pDesc->RxMCS>=DESC92S_RATEMCS8 &&
6686 pDesc->RxMCS<=DESC92S_RATEMCS15)
6687 max_spatial_stream = 2; //both spatial stream make sense
6688 else
6689 max_spatial_stream = 1; //only spatial stream 1 makes sense
6690
6691 for(i=0; i<max_spatial_stream; i++)
6692 {
6693 //tmp_rxevm = pofdm_buf->rxevm_X[i];
6694 //rx_evmX = (char)(tmp_rxevm);
6695
6696 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
6697 // fill most significant bit to "zero" when doing shifting operation which may change a negative
6698 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
6699 //rx_evmX /= 2; //dbm
6700
6701 //evm = rtl819x_evm_dbtopercentage(rx_evmX);
6702 evm = rtl819x_evm_dbtopercentage( (pdrvinfo->rxevm[i] /*/ 2*/)); //dbm
6703 RT_TRACE(COMP_RF, "RXRATE=%x RXEVM=%x EVM=%s%d\n", pDesc->RxMCS, pdrvinfo->rxevm[i], "%", evm);
5f53d8ca
JC
6704
6705 //if(bpacket_match_bssid)
6706 {
6707 if(i==0) // Fill value in RFD, Get the first spatial stream only
6708 pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
6709 pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
6710 }
6711 }
6712
6713
6714 /* record rx statistics for debug */
6715 //rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
6716 prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
6717 //if(pdrvinfo->BW) //40M channel
6718 if(pDesc->BW) //40M channel
6719 priv->stats.received_bwtype[1+pdrvinfo->rxsc]++;
6720 else //20M channel
6721 priv->stats.received_bwtype[0]++;
6722 }
6723
6724 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
6725 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
6726 if(is_cck_rate)
6727 {
6728 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;//check ok
6729
6730 }
6731 else
6732 {
6733 //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
6734 // We can judge RX path number now.
6735 if (rf_rx_num != 0)
6736 pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
6737 }
6738}/* QueryRxPhyStatus8192S */
0f29f587
BZ
6739
6740void
6741rtl8192_record_rxdesc_forlateruse(
6742 struct ieee80211_rx_stats * psrc_stats,
6743 struct ieee80211_rx_stats * ptarget_stats
6744)
6745{
6746 ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
6747 ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
6748 ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
6749}
6750
6751static void rtl8192SU_query_rxphystatus(
5f53d8ca
JC
6752 struct r8192_priv * priv,
6753 struct ieee80211_rx_stats * pstats,
0f29f587 6754 rx_desc_819x_usb *pDesc,
5f53d8ca
JC
6755 rx_drvinfo_819x_usb * pdrvinfo,
6756 struct ieee80211_rx_stats * precord_stats,
6757 bool bpacket_match_bssid,
6758 bool bpacket_toself,
6759 bool bPacketBeacon,
6760 bool bToSelfBA
0f29f587
BZ
6761 );
6762void rtl8192SU_TranslateRxSignalStuff(struct sk_buff *skb,
6763 struct ieee80211_rx_stats * pstats,
6764 rx_desc_819x_usb *pDesc,
6765 rx_drvinfo_819x_usb *pdrvinfo)
5f53d8ca 6766{
0f29f587
BZ
6767 // TODO: We must only check packet for current MAC address. Not finish
6768 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
6769 struct net_device *dev=info->dev;
6770 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6771 bool bpacket_match_bssid, bpacket_toself;
6772 bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
6773 static struct ieee80211_rx_stats previous_stats;
6774 struct ieee80211_hdr_3addr *hdr;//by amy
6775 u16 fc,type;
5f53d8ca 6776
0f29f587 6777 // Get Signal Quality for only RX data queue (but not command queue)
5f53d8ca 6778
0f29f587
BZ
6779 u8* tmp_buf;
6780 //u16 tmp_buf_len = 0;
6781 u8 *praddr;
5f53d8ca 6782
0f29f587
BZ
6783 /* Get MAC frame start address. */
6784 tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
5f53d8ca 6785
0f29f587
BZ
6786 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
6787 fc = le16_to_cpu(hdr->frame_ctl);
6788 type = WLAN_FC_GET_TYPE(fc);
6789 praddr = hdr->addr1;
5f53d8ca 6790
0f29f587
BZ
6791 /* Check if the received packet is acceptabe. */
6792 bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
6793 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
6794 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
6795 bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
5f53d8ca
JC
6796
6797#if 1//cosa
6798 if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
6799 {
6800 bPacketBeacon = true;
6801 //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
6802 }
6803 if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
6804 {
6805 if((eqMacAddr(praddr,dev->dev_addr)))
6806 bToSelfBA = true;
6807 //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
6808 }
6809
6810#endif
6811
6812
6813 if(bpacket_match_bssid)
6814 {
6815 priv->stats.numpacket_matchbssid++;
6816 }
6817 if(bpacket_toself){
6818 priv->stats.numpacket_toself++;
6819 }
6820 //
6821 // Process PHY information for previous packet (RSSI/PWDB/EVM)
6822 //
6823 // Because phy information is contained in the last packet of AMPDU only, so driver
6824 // should process phy information of previous packet
6825 rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
6826 rtl8192SU_query_rxphystatus(priv, pstats, pDesc, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
6827 rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
6828
6829}
5f53d8ca
JC
6830
6831/**
6832* Function: UpdateReceivedRateHistogramStatistics
6833* Overview: Recored down the received data rate
6834*
6835* Input:
6836* struct net_device *dev
6837* struct ieee80211_rx_stats *stats
6838*
6839* Output:
6840*
6841* (priv->stats.ReceivedRateHistogram[] is updated)
6842* Return:
6843* None
6844*/
6845void
6846UpdateReceivedRateHistogramStatistics8190(
6847 struct net_device *dev,
6848 struct ieee80211_rx_stats *stats
6849 )
6850{
6851 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6852 u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
6853 u32 rateIndex;
6854 u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
6855
6856
6857 if(stats->bCRC)
6858 rcvType = 2;
6859 else if(stats->bICV)
6860 rcvType = 3;
6861
6862 if(stats->bShortPreamble)
6863 preamble_guardinterval = 1;// short
6864 else
6865 preamble_guardinterval = 0;// long
6866
6867 switch(stats->rate)
6868 {
6869 //
6870 // CCK rate
6871 //
6872 case MGN_1M: rateIndex = 0; break;
6873 case MGN_2M: rateIndex = 1; break;
6874 case MGN_5_5M: rateIndex = 2; break;
6875 case MGN_11M: rateIndex = 3; break;
6876 //
6877 // Legacy OFDM rate
6878 //
6879 case MGN_6M: rateIndex = 4; break;
6880 case MGN_9M: rateIndex = 5; break;
6881 case MGN_12M: rateIndex = 6; break;
6882 case MGN_18M: rateIndex = 7; break;
6883 case MGN_24M: rateIndex = 8; break;
6884 case MGN_36M: rateIndex = 9; break;
6885 case MGN_48M: rateIndex = 10; break;
6886 case MGN_54M: rateIndex = 11; break;
6887 //
6888 // 11n High throughput rate
6889 //
6890 case MGN_MCS0: rateIndex = 12; break;
6891 case MGN_MCS1: rateIndex = 13; break;
6892 case MGN_MCS2: rateIndex = 14; break;
6893 case MGN_MCS3: rateIndex = 15; break;
6894 case MGN_MCS4: rateIndex = 16; break;
6895 case MGN_MCS5: rateIndex = 17; break;
6896 case MGN_MCS6: rateIndex = 18; break;
6897 case MGN_MCS7: rateIndex = 19; break;
6898 case MGN_MCS8: rateIndex = 20; break;
6899 case MGN_MCS9: rateIndex = 21; break;
6900 case MGN_MCS10: rateIndex = 22; break;
6901 case MGN_MCS11: rateIndex = 23; break;
6902 case MGN_MCS12: rateIndex = 24; break;
6903 case MGN_MCS13: rateIndex = 25; break;
6904 case MGN_MCS14: rateIndex = 26; break;
6905 case MGN_MCS15: rateIndex = 27; break;
6906 default: rateIndex = 28; break;
6907 }
6908 priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
6909 priv->stats.received_rate_histogram[0][rateIndex]++; //total
6910 priv->stats.received_rate_histogram[rcvType][rateIndex]++;
6911}
6912
5f53d8ca
JC
6913void rtl8192SU_query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
6914{
6915 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
6916 struct net_device *dev=info->dev;
6917 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6918 //rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
6919 rx_drvinfo_819x_usb *driver_info = NULL;
6920
6921 //PRT_RFD_STATUS pRtRfdStatus = &pRfd->Status;
6922 //PHAL_DATA_8192SUSB pHalData = GET_HAL_DATA(Adapter);
6923 //pu1Byte pDesc = (pu1Byte)pDescIn;
6924 //PRX_DRIVER_INFO_8192S pDrvInfo;
6925
5f53d8ca
JC
6926 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
6927
6928 if(0)
6929 {
6930 int m = 0;
6931 printk("========================");
6932 for(m=0; m<skb->len; m++){
6933 if((m%32) == 0)
6934 printk("\n");
6935 printk("%2x ",((u8*)skb->data)[m]);
6936 }
6937 printk("\n========================\n");
6938
6939 }
6940
6941
6942 //
6943 //Get Rx Descriptor Raw Information
6944 //
6945 stats->Length = desc->Length ;
6946 stats->RxDrvInfoSize = desc->RxDrvInfoSize*RX_DRV_INFO_SIZE_UNIT;
6947 stats->RxBufShift = (desc->Shift)&0x03;
6948 stats->bICV = desc->ICV;
6949 stats->bCRC = desc->CRC32;
6950 stats->bHwError = stats->bCRC|stats->bICV;
6951 stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
6952 stats->bIsAMPDU = (desc->AMSDU==1);
6953 stats->bFirstMPDU = (desc->PAGGR==1) && (desc->FAGGR==1);
6954 stats->bShortPreamble = desc->SPLCP;
6955 stats->RxIs40MHzPacket = (desc->BW==1);
6956 stats->TimeStampLow = desc->TSFL;
6957
6958 if((desc->FAGGR==1) || (desc->PAGGR==1))
6959 {// Rx A-MPDU
6960 RT_TRACE(COMP_RXDESC, "FirstAGGR = %d, PartAggr = %d\n", desc->FAGGR, desc->PAGGR);
6961 }
6962//YJ,test,090310
6963if(stats->bHwError)
6964{
6965 if(stats->bICV)
6966 printk("%s: Receive ICV error!!!!!!!!!!!!!!!!!!!!!!\n", __FUNCTION__);
6967 if(stats->bCRC)
6968 printk("%s: Receive CRC error!!!!!!!!!!!!!!!!!!!!!!\n", __FUNCTION__);
6969}
6970
6971 if(IS_UNDER_11N_AES_MODE(priv->ieee80211))
6972 {
6973 // Always received ICV error packets in AES mode.
6974 // This fixed HW later MIC write bug.
6975 if(stats->bICV && !stats->bCRC)
6976 {
6977 stats->bICV = FALSE;
6978 stats->bHwError = FALSE;
6979 }
6980 }
6981
6982 // Transform HwRate to MRate
6983 if(!stats->bHwError)
6984 //stats->DataRate = HwRateToMRate(
6985 // (BOOLEAN)GET_RX_DESC_RXHT(pDesc),
6986 // (u1Byte)GET_RX_DESC_RXMCS(pDesc),
6987 // (BOOLEAN)GET_RX_DESC_PAGGR(pDesc));
6988 stats->rate = rtl8192SU_HwRateToMRate(desc->RxHT, desc->RxMCS, desc->PAGGR);
6989 else
6990 stats->rate = MGN_1M;
6991
6992 //
6993 // Collect Rx rate/AMPDU/TSFL
6994 //
6995 //UpdateRxdRateHistogramStatistics8192S(Adapter, pRfd);
6996 //UpdateRxAMPDUHistogramStatistics8192S(Adapter, pRfd);
6997 //UpdateRxPktTimeStamp8192S(Adapter, pRfd);
6998 UpdateReceivedRateHistogramStatistics8190(dev, stats);
6999 //UpdateRxAMPDUHistogramStatistics8192S(dev, stats); //FIXLZM
7000 UpdateRxPktTimeStamp8190(dev, stats);
7001
7002 //
7003 // Get PHY Status and RSVD parts.
7004 // <Roger_Notes> It only appears on last aggregated packet.
7005 //
7006 if (desc->PHYStatus)
7007 {
7008 //driver_info = (rx_drvinfo_819x_usb *)(skb->data + RX_DESC_SIZE + stats->RxBufShift);
7009 driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
7010 stats->RxBufShift);
7011 if(0)
7012 {
7013 int m = 0;
7014 printk("========================\n");
7015 printk("RX_DESC_SIZE:%d, RxBufShift:%d, RxDrvInfoSize:%d\n",
7016 RX_DESC_SIZE, stats->RxBufShift, stats->RxDrvInfoSize);
7017 for(m=0; m<32; m++){
7018 printk("%2x ",((u8*)driver_info)[m]);
7019 }
7020 printk("\n========================\n");
7021
7022 }
7023
7024 }
7025
7026 //YJ,add,090107
7027 skb_pull(skb, sizeof(rx_desc_819x_usb));
7028 //YJ,add,090107,end
7029
7030 //
7031 // Get Total offset of MPDU Frame Body
7032 //
7033 if((stats->RxBufShift + stats->RxDrvInfoSize) > 0)
7034 {
7035 stats->bShift = 1;
7036 //YJ,add,090107
7037 skb_pull(skb, stats->RxBufShift + stats->RxDrvInfoSize);
7038 //YJ,add,090107,end
7039 }
7040
7041 //
7042 // Get PHY Status and RSVD parts.
7043 // <Roger_Notes> It only appears on last aggregated packet.
7044 //
7045 if (desc->PHYStatus)
7046 {
7047 rtl8192SU_TranslateRxSignalStuff(skb, stats, desc, driver_info);
7048 }
7049}
5f53d8ca 7050
5f53d8ca
JC
7051//
7052// Description:
7053// The strarting address of wireless lan header will shift 1 or 2 or 3 or "more" bytes for the following reason :
7054// (1) QoS control : shift 2 bytes
7055// (2) Mesh Network : shift 1 or 3 bytes
7056// (3) RxDriverInfo occupies the front parts of Rx Packets buffer(shift units is in 8Bytes)
7057//
7058// It is because Lextra CPU used by 8186 or 865x series assert exception if the statrting address
7059// of IP header is not double word alignment.
7060// This features is supported in 818xb and 8190 only, but not 818x.
7061//
7062// parameter: PRT_RFD, Pointer of Reeceive frame descriptor which is initialized according to
7063// Rx Descriptor
7064// return value: unsigned int, number of total shifted bytes
7065//
7066// Notes: 2008/06/28, created by Roger
7067//
7068u32 GetRxPacketShiftBytes8192SU(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
7069{
7070 //PRT_RFD_STATUS pRtRfdStatus = &pRfd->Status;
7071
7072 return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize + Status->RxBufShift);
7073}
7074
7075void rtl8192SU_rx_nomal(struct sk_buff* skb)
7076{
7077 rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
7078 struct net_device *dev=info->dev;
7079 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7080 struct ieee80211_rx_stats stats = {
7081 .signal = 0,
7082 .noise = -98,
7083 .rate = 0,
7084 // .mac_time = jiffies,
7085 .freq = IEEE80211_24GHZ_BAND,
7086 };
7087 u32 rx_pkt_len = 0;
7088 struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
7089 bool unicast_packet = false;
7090
5f53d8ca
JC
7091 //printk("**********skb->len = %d\n", skb->len);
7092 /* 20 is for ps-poll */
7093 if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
7094
7095 /* first packet should not contain Rx aggregation header */
7096 rtl8192SU_query_rxdesc_status(skb, &stats, false);
7097 /* TODO */
7098
7099 /* hardware related info */
5f53d8ca
JC
7100 priv->stats.rxoktotal++; //YJ,test,090108
7101
7102 /* Process the MPDU recevied */
7103 skb_trim(skb, skb->len - 4/*sCrcLng*/);//FIXLZM
7104
7105 rx_pkt_len = skb->len;
7106 ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
7107 unicast_packet = false;
7108 if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
7109 //TODO
7110 }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
7111 //TODO
7112 }else {
7113 /* unicast packet */
7114 unicast_packet = true;
7115 }
7116
55c7d5fc 7117 if(!ieee80211_rtl_rx(priv->ieee80211,skb, &stats)) {
5f53d8ca
JC
7118 dev_kfree_skb_any(skb);
7119 } else {
7120 // priv->stats.rxoktotal++; //YJ,test,090108
7121 if(unicast_packet) {
7122 priv->stats.rxbytesunicast += rx_pkt_len;
7123 }
7124 }
7125
7126 //up is firs pkt, follow is next and next
5f53d8ca
JC
7127 }
7128 else
7129 {
7130 priv->stats.rxurberr++;
7131 printk("actual_length:%d\n", skb->len);
7132 dev_kfree_skb_any(skb);
7133 }
7134
7135}
5f53d8ca
JC
7136
7137void
7138rtl819xusb_process_received_packet(
7139 struct net_device *dev,
7140 struct ieee80211_rx_stats *pstats
7141 )
7142{
7143// bool bfreerfd=false, bqueued=false;
7144 u8* frame;
7145 u16 frame_len=0;
7146 struct r8192_priv *priv = ieee80211_priv(dev);
7147// u8 index = 0;
7148// u8 TID = 0;
7149 //u16 seqnum = 0;
7150 //PRX_TS_RECORD pts = NULL;
7151
7152 // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
7153 //porting by amy 080508
7154 pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
7155 frame = pstats->virtual_address;
7156 frame_len = pstats->packetlength;
7157#ifdef TODO // by amy about HCT
7158 if(!Adapter->bInHctTest)
7159 CountRxErrStatistics(Adapter, pRfd);
7160#endif
7161 {
7162 #ifdef ENABLE_PS //by amy for adding ps function in future
7163 RT_RF_POWER_STATE rtState;
7164 // When RF is off, we should not count the packet for hw/sw synchronize
7165 // reason, ie. there may be a duration while sw switch is changed and hw
7166 // switch is being changed. 2006.12.04, by shien chang.
7167 Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8* )(&rtState));
7168 if (rtState == eRfOff)
7169 {
7170 return;
7171 }
7172 #endif
7173 priv->stats.rxframgment++;
7174
7175 }
7176#ifdef TODO
7177 RmMonitorSignalStrength(Adapter, pRfd);
7178#endif
7179 /* 2007/01/16 MH Add RX command packet handle here. */
7180 /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
7181 if (rtl819xusb_rx_command_packet(dev, pstats))
7182 {
7183 return;
7184 }
7185
7186#ifdef SW_CRC_CHECK
7187 SwCrcCheck();
7188#endif
7189
7190
7191}
7192
7193void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
7194{
7195// rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
7196// struct net_device *dev=info->dev;
7197// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7198 rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
7199// rx_drvinfo_819x_usb *driver_info;
7200
7201 //
7202 //Get Rx Descriptor Information
7203 //
7204 stats->virtual_address = (u8*)skb->data;
7205 stats->Length = desc->Length;
7206 stats->RxDrvInfoSize = 0;
7207 stats->RxBufShift = 0;
7208 stats->packetlength = stats->Length-scrclng;
7209 stats->fraglength = stats->packetlength;
7210 stats->fragoffset = 0;
7211 stats->ntotalfrag = 1;
7212}
7213
5f53d8ca
JC
7214void rtl8192SU_rx_cmd(struct sk_buff *skb)
7215{
7216 struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
7217 struct net_device *dev = info->dev;
7218
7219 /* TODO */
7220 struct ieee80211_rx_stats stats = {
7221 .signal = 0,
7222 .noise = -98,
7223 .rate = 0,
7224 // .mac_time = jiffies,
7225 .freq = IEEE80211_24GHZ_BAND,
7226 };
7227
7228 //
7229 // Check buffer length to determine if this is a valid MPDU.
7230 //
7231 if( (skb->len >= sizeof(rx_desc_819x_usb)) && (skb->len <= RX_URB_SIZE) )//&&
7232 //(pHalData->SwChnlInProgress == FALSE))
7233 {
7234 //
7235 // Collection information in Rx descriptor.
7236 //
5f53d8ca
JC
7237 query_rx_cmdpkt_desc_status(skb,&stats);
7238 // this is to be done by amy 080508 prfd->queue_id = 1;
7239
7240 //
7241 // Process the MPDU recevied.
7242 //
7243 rtl819xusb_process_received_packet(dev,&stats);
7244
7245 dev_kfree_skb_any(skb);
7246 }
7247 else
7248 {
7249 //RTInsertTailListWithCnt(&pAdapter->RfdIdleQueue, &pRfd->List, &pAdapter->NumIdleRfd);
7250 //RT_ASSERT(pAdapter->NumIdleRfd <= pAdapter->NumRfd, ("HalUsbInCommandComplete8192SUsb(): Adapter->NumIdleRfd(%d)\n", pAdapter->NumIdleRfd));
7251 //RT_TRACE(COMP_RECV, DBG_LOUD, ("HalUsbInCommandComplete8192SUsb(): NOT enough Resources!! BufLenUsed(%d), NumIdleRfd(%d)\n",
7252 //pContext->BufLenUsed, pAdapter->NumIdleRfd));
7253 }
7254
7255 //
7256 // Reuse USB_IN_CONTEXT since we had finished processing the
7257 // buffer in USB_IN_CONTEXT.
7258 //
7259 //HalUsbReturnInContext(pAdapter, pContext);
7260
7261 //
7262 // Issue another bulk IN transfer.
7263 //
7264 //HalUsbInMpdu(pAdapter, PipeIndex);
7265
7266 RT_TRACE(COMP_RECV, "<--- HalUsbInCommandComplete8192SUsb()\n");
7267
7268}
5f53d8ca
JC
7269
7270void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
7271{
7272 struct sk_buff *skb;
7273 struct rtl8192_rx_info *info;
7274
7275 while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
7276 info = (struct rtl8192_rx_info *)skb->cb;
7277 switch (info->out_pipe) {
7278 /* Nomal packet pipe */
7279 case 3:
7280 //RT_TRACE(COMP_RECV, "normal in-pipe index(%d)\n",info->out_pipe);
7281 priv->IrpPendingCount--;
7282 priv->ops->rtl819x_rx_nomal(skb);
7283 break;
7284
7285 /* Command packet pipe */
7286 case 9:
7287 RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",\
7288 info->out_pipe);
7289 priv->ops->rtl819x_rx_cmd(skb);
7290 break;
7291
7292 default: /* should never get here! */
7293 RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",\
7294 info->out_pipe);
7295 dev_kfree_skb(skb);
7296 break;
7297
7298 }
7299 }
7300}
7301
7302
7303
7304/****************************************************************************
7305 ---------------------------- USB_STUFF---------------------------
7306*****************************************************************************/
5f53d8ca
JC
7307//LZM Merge from windows HalUsbSetQueuePipeMapping8192SUsb 090319
7308static void HalUsbSetQueuePipeMapping8192SUsb(struct usb_interface *intf, struct net_device *dev)
7309{
7310 struct r8192_priv *priv = ieee80211_priv(dev);
7311 struct usb_host_interface *iface_desc;
7312 struct usb_endpoint_descriptor *endpoint;
7313 u8 i = 0;
7314
7315 priv->ep_in_num = 0;
7316 priv->ep_out_num = 0;
7317 memset(priv->RtOutPipes,0,16);
7318 memset(priv->RtInPipes,0,16);
7319
5f53d8ca
JC
7320 iface_desc = intf->cur_altsetting;
7321 priv->ep_num = iface_desc->desc.bNumEndpoints;
7322
7323 for (i = 0; i < priv->ep_num; ++i) {
7324 endpoint = &iface_desc->endpoint[i].desc;
5f53d8ca
JC
7325 if (usb_endpoint_is_bulk_in(endpoint)) {
7326 priv->RtInPipes[priv->ep_in_num] = usb_endpoint_num(endpoint);
7327 priv->ep_in_num ++;
7328 //printk("in_endpoint_idx = %d\n", usb_endpoint_num(endpoint));
7329 } else if (usb_endpoint_is_bulk_out(endpoint)) {
7330 priv->RtOutPipes[priv->ep_out_num] = usb_endpoint_num(endpoint);
7331 priv->ep_out_num ++;
7332 //printk("out_endpoint_idx = %d\n", usb_endpoint_num(endpoint));
7333 }
5f53d8ca
JC
7334 }
7335 {
7336 memset(priv->txqueue_to_outpipemap,0,9);
7337 if (priv->ep_num == 6) {
7338 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
7339 u8 queuetopipe[] = {3, 2, 1, 0, 4, 4, 4, 4, 4};
7340
7341 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
7342 } else if (priv->ep_num == 4) {
7343 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
7344 u8 queuetopipe[] = {1, 1, 0, 0, 2, 2, 2, 2, 2};
7345
7346 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
7347 } else if (priv->ep_num > 9) {
7348 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
7349 u8 queuetopipe[] = {3, 2, 1, 0, 4, 8, 7, 6, 5};
7350
7351 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
7352 } else {//use sigle pipe
7353 // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
7354 u8 queuetopipe[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
7355 memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
7356 }
7357 }
7358 printk("==>ep_num:%d, in_ep_num:%d, out_ep_num:%d\n", priv->ep_num, priv->ep_in_num, priv->ep_out_num);
7359
7360 printk("==>RtInPipes:");
7361 for(i=0; i < priv->ep_in_num; i++)
7362 printk("%d ", priv->RtInPipes[i]);
7363 printk("\n");
7364
7365 printk("==>RtOutPipes:");
7366 for(i=0; i < priv->ep_out_num; i++)
7367 printk("%d ", priv->RtOutPipes[i]);
7368 printk("\n");
7369
7370 printk("==>txqueue_to_outpipemap for BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON:\n");
7371 for(i=0; i < 9; i++)
7372 printk("%d ", priv->txqueue_to_outpipemap[i]);
7373 printk("\n");
5f53d8ca
JC
7374
7375 return;
7376}
5f53d8ca 7377
77b92881
BZ
7378static const struct net_device_ops rtl8192_netdev_ops = {
7379 .ndo_open = rtl8192_open,
7380 .ndo_stop = rtl8192_close,
7381 .ndo_get_stats = rtl8192_stats,
7382 .ndo_tx_timeout = tx_timeout,
7383 .ndo_do_ioctl = rtl8192_ioctl,
7384 .ndo_set_multicast_list = r8192_set_multicast,
7385 .ndo_set_mac_address = r8192_set_mac_adr,
7386 .ndo_validate_addr = eth_validate_addr,
7387 .ndo_change_mtu = eth_change_mtu,
55c7d5fc 7388 .ndo_start_xmit = rtl8192_ieee80211_rtl_xmit,
77b92881
BZ
7389};
7390
5f53d8ca
JC
7391static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
7392 const struct usb_device_id *id)
5f53d8ca
JC
7393{
7394// unsigned long ioaddr = 0;
7395 struct net_device *dev = NULL;
7396 struct r8192_priv *priv= NULL;
5f53d8ca 7397 struct usb_device *udev = interface_to_usbdev(intf);
1ec9e48d 7398
5f53d8ca
JC
7399 RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
7400
7401 dev = alloc_ieee80211(sizeof(struct r8192_priv));
7402
5f53d8ca
JC
7403 usb_set_intfdata(intf, dev);
7404 SET_NETDEV_DEV(dev, &intf->dev);
5f53d8ca 7405 priv = ieee80211_priv(dev);
5f53d8ca 7406 priv->ieee80211 = netdev_priv(dev);
5f53d8ca
JC
7407 priv->udev=udev;
7408
5f53d8ca 7409 HalUsbSetQueuePipeMapping8192SUsb(intf, dev);
5f53d8ca 7410
5f53d8ca
JC
7411 //printk("===============>NIC 8192SU\n");
7412 priv->ops = &rtl8192su_ops;
5f53d8ca 7413
77b92881 7414 dev->netdev_ops = &rtl8192_netdev_ops;
5f53d8ca
JC
7415
7416 //DMESG("Oops: i'm coming\n");
5f53d8ca 7417 dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
3bd709f2 7418
5f53d8ca
JC
7419 dev->type=ARPHRD_ETHER;
7420
7421 dev->watchdog_timeo = HZ*3; //modified by john, 0805
7422
7423 if (dev_alloc_name(dev, ifname) < 0){
7424 RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
7425 ifname = "wlan%d";
7426 dev_alloc_name(dev, ifname);
7427 }
7428
7429 RT_TRACE(COMP_INIT, "Driver probe completed1\n");
7430#if 1
7431 if(rtl8192_init(dev)!=0){
7432 RT_TRACE(COMP_ERR, "Initialization failed");
7433 goto fail;
7434 }
7435#endif
7436 netif_carrier_off(dev);
7437 netif_stop_queue(dev);
7438
7439 register_netdev(dev);
7440 RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
7441 rtl8192_proc_init_one(dev);
7442
7443
7444 RT_TRACE(COMP_INIT, "Driver probe completed\n");
5f53d8ca 7445 return 0;
5f53d8ca
JC
7446fail:
7447 free_ieee80211(dev);
7448
7449 RT_TRACE(COMP_ERR, "wlan driver load failed\n");
5f53d8ca 7450 return -ENODEV;
5f53d8ca
JC
7451}
7452
7453//detach all the work and timer structure declared or inititialize in r8192U_init function.
7454void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
7455{
5f53d8ca
JC
7456 cancel_work_sync(&priv->reset_wq);
7457 cancel_work_sync(&priv->qos_activate);
7458 cancel_delayed_work(&priv->watch_dog_wq);
7459 cancel_delayed_work(&priv->update_beacon_wq);
7460 cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
7461 cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
7462 //cancel_work_sync(&priv->SetBWModeWorkItem);
7463 //cancel_work_sync(&priv->SwChnlWorkItem);
5f53d8ca
JC
7464}
7465
5f53d8ca 7466static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
5f53d8ca 7467{
5f53d8ca 7468 struct net_device *dev = usb_get_intfdata(intf);
5f53d8ca
JC
7469 struct r8192_priv *priv = ieee80211_priv(dev);
7470 if(dev){
7471
7472 unregister_netdev(dev);
7473
7474 RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
7475 rtl8192_proc_remove_one(dev);
7476
7477 rtl8192_down(dev);
7478 if (priv->pFirmware)
7479 {
7480 vfree(priv->pFirmware);
7481 priv->pFirmware = NULL;
7482 }
7483 // priv->rf_close(dev);
7484// rtl8192_SetRFPowerState(dev, eRfOff);
5f53d8ca 7485 destroy_workqueue(priv->priv_wq);
5f53d8ca
JC
7486 //rtl8192_irq_disable(dev);
7487 //rtl8192_reset(dev);
7488 mdelay(10);
7489
7490 }
7491 free_ieee80211(dev);
7492 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
7493}
7494
5d9baea9
BZ
7495/* fun with the built-in ieee80211 stack... */
7496extern int ieee80211_debug_init(void);
7497extern void ieee80211_debug_exit(void);
7498extern int ieee80211_crypto_init(void);
7499extern void ieee80211_crypto_deinit(void);
7500extern int ieee80211_crypto_tkip_init(void);
7501extern void ieee80211_crypto_tkip_exit(void);
7502extern int ieee80211_crypto_ccmp_init(void);
7503extern void ieee80211_crypto_ccmp_exit(void);
7504extern int ieee80211_crypto_wep_init(void);
7505extern void ieee80211_crypto_wep_exit(void);
7506
5f53d8ca
JC
7507static int __init rtl8192_usb_module_init(void)
7508{
5d9baea9
BZ
7509 int ret;
7510
7511#ifdef CONFIG_IEEE80211_DEBUG
7512 ret = ieee80211_debug_init();
7513 if (ret) {
7514 printk(KERN_ERR "ieee80211_debug_init() failed %d\n", ret);
7515 return ret;
7516 }
7517#endif
7518 ret = ieee80211_crypto_init();
7519 if (ret) {
7520 printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
7521 return ret;
7522 }
7523
7524 ret = ieee80211_crypto_tkip_init();
7525 if (ret) {
7526 printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n",
7527 ret);
7528 return ret;
7529 }
7530
7531 ret = ieee80211_crypto_ccmp_init();
7532 if (ret) {
7533 printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n",
7534 ret);
7535 return ret;
7536 }
7537
7538 ret = ieee80211_crypto_wep_init();
7539 if (ret) {
7540 printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
7541 return ret;
7542 }
7543
5f53d8ca
JC
7544 printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
7545 printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
7546 RT_TRACE(COMP_INIT, "Initializing module");
7547 RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
7548 rtl8192_proc_module_init();
7549 return usb_register(&rtl8192_usb_driver);
7550}
7551
7552
7553static void __exit rtl8192_usb_module_exit(void)
7554{
7555 usb_deregister(&rtl8192_usb_driver);
7556
7557 RT_TRACE(COMP_DOWN, "Exiting");
7558 rtl8192_proc_module_remove();
5d9baea9
BZ
7559
7560 ieee80211_crypto_tkip_exit();
7561 ieee80211_crypto_ccmp_exit();
7562 ieee80211_crypto_wep_exit();
7563 ieee80211_crypto_deinit();
7564#ifdef CONFIG_IEEE80211_DEBUG
7565 ieee80211_debug_exit();
7566#endif
5f53d8ca
JC
7567}
7568
7569
7570void rtl8192_try_wake_queue(struct net_device *dev, int pri)
7571{
7572 unsigned long flags;
7573 short enough_desc;
7574 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7575
7576 spin_lock_irqsave(&priv->tx_lock,flags);
7577 enough_desc = check_nic_enough_desc(dev,pri);
7578 spin_unlock_irqrestore(&priv->tx_lock,flags);
7579
7580 if(enough_desc)
55c7d5fc 7581 ieee80211_rtl_wake_queue(priv->ieee80211);
5f53d8ca
JC
7582}
7583
5f53d8ca
JC
7584void EnableHWSecurityConfig8192(struct net_device *dev)
7585{
7586 u8 SECR_value = 0x0;
7587 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
7588 struct ieee80211_device* ieee = priv->ieee80211;
7589
7590 SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
7591#if 1
7592 if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
7593 {
7594 SECR_value |= SCR_RxUseDK;
7595 SECR_value |= SCR_TxUseDK;
7596 }
7597 else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
7598 {
7599 SECR_value |= SCR_RxUseDK;
7600 SECR_value |= SCR_TxUseDK;
7601 }
7602#endif
7603 //add HWSec active enable here.
7604//default using hwsec. when peer AP is in N mode only and pairwise_key_type is none_aes(which HT_IOT_ACT_PURE_N_MODE indicates it), use software security. when peer AP is in b,g,n mode mixed and pairwise_key_type is none_aes, use g mode hw security. WB on 2008.7.4
7605
7606 ieee->hwsec_active = 1;
7607
7608 if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep)//!ieee->hwsec_support) //add hwsec_support flag to totol control hw_sec on/off
7609 {
7610 ieee->hwsec_active = 0;
7611 SECR_value &= ~SCR_RxDecEnable;
7612 }
7613
7614 RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
7615 ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
7616 {
7617 write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
7618 }
7619}
7620
7621
7622void setKey( struct net_device *dev,
7623 u8 EntryNo,
7624 u8 KeyIndex,
7625 u16 KeyType,
7626 u8 *MacAddr,
7627 u8 DefaultKey,
7628 u32 *KeyContent )
7629{
7630 u32 TargetCommand = 0;
7631 u32 TargetContent = 0;
7632 u16 usConfig = 0;
7633 u8 i;
7634 if (EntryNo >= TOTAL_CAM_ENTRY)
7635 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
7636
0ee9f67c 7637 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
5f53d8ca
JC
7638
7639 if (DefaultKey)
7640 usConfig |= BIT15 | (KeyType<<2);
7641 else
7642 usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
7643// usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
7644
7645
7646 for(i=0 ; i<CAM_CONTENT_COUNT; i++){
7647 TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
7648 TargetCommand |= BIT31|BIT16;
7649
7650 if(i==0){//MAC|Config
7651 TargetContent = (u32)(*(MacAddr+0)) << 16|
7652 (u32)(*(MacAddr+1)) << 24|
7653 (u32)usConfig;
7654
7655 write_nic_dword(dev, WCAMI, TargetContent);
7656 write_nic_dword(dev, RWCAM, TargetCommand);
7657 // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
7658 }
7659 else if(i==1){//MAC
7660 TargetContent = (u32)(*(MacAddr+2)) |
7661 (u32)(*(MacAddr+3)) << 8|
7662 (u32)(*(MacAddr+4)) << 16|
7663 (u32)(*(MacAddr+5)) << 24;
7664 write_nic_dword(dev, WCAMI, TargetContent);
7665 write_nic_dword(dev, RWCAM, TargetCommand);
7666 }
7667 else {
7668 //Key Material
7669 if(KeyContent !=NULL){
7670 write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
7671 write_nic_dword(dev, RWCAM, TargetCommand);
7672 }
7673 }
7674 }
7675
7676}
7677
7678/***************************************************************************
7679 ------------------- module init / exit stubs ----------------
7680****************************************************************************/
7681module_init(rtl8192_usb_module_init);
7682module_exit(rtl8192_usb_module_exit);
This page took 0.411394 seconds and 5 git commands to generate.