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