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