blob: 4e465c46528032252dce28539cfab266e38ad28f [file] [log] [blame]
Forest Bond92b96792009-06-13 07:38:31 -04001/*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * File: main_usb.c
20 *
21 * Purpose: driver entry for initial, open, close, tx and rx.
22 *
23 * Author: Lyndon Chen
24 *
25 * Date: Dec 8, 2005
26 *
27 * Functions:
28 *
Andres More26e5b652010-04-13 19:43:07 -030029 * vt6656_probe - module initial (insmod) driver entry
Forest Bond92b96792009-06-13 07:38:31 -040030 * device_remove1 - module remove entry
31 * device_open - allocate dma/descripter resource & initial mac/bbp function
32 * device_xmit - asynchrous data tx function
33 * device_set_multi - set mac filter
34 * device_ioctl - ioctl entry
35 * device_close - shutdown mac/bbp & free dma/descripter resource
36 * device_alloc_frag_buf - rx fragement pre-allocated function
37 * device_free_tx_bufs - free tx buffer function
38 * device_dma0_tx_80211- tx 802.11 frame via dma0
39 * device_dma0_xmit- tx PS bufferred frame via dma0
40 * device_init_registers- initial MAC & BBP & RF internal registers.
41 * device_init_rings- initial tx/rx ring buffer
42 * device_init_defrag_cb- initial & allocate de-fragement buffer.
43 * device_tx_srv- tx interrupt service function
44 *
45 * Revision History:
46 */
47#undef __NO_VERSION__
48
Forest Bond92b96792009-06-13 07:38:31 -040049#include "device.h"
Forest Bond92b96792009-06-13 07:38:31 -040050#include "card.h"
Forest Bond92b96792009-06-13 07:38:31 -040051#include "baseband.h"
Forest Bond92b96792009-06-13 07:38:31 -040052#include "mac.h"
Forest Bond92b96792009-06-13 07:38:31 -040053#include "tether.h"
Forest Bond92b96792009-06-13 07:38:31 -040054#include "wmgr.h"
Forest Bond92b96792009-06-13 07:38:31 -040055#include "wctl.h"
Forest Bond92b96792009-06-13 07:38:31 -040056#include "power.h"
Forest Bond92b96792009-06-13 07:38:31 -040057#include "wcmd.h"
Forest Bond92b96792009-06-13 07:38:31 -040058#include "iocmd.h"
Forest Bond92b96792009-06-13 07:38:31 -040059#include "tcrc.h"
Forest Bond92b96792009-06-13 07:38:31 -040060#include "rxtx.h"
Forest Bond92b96792009-06-13 07:38:31 -040061#include "bssdb.h"
Forest Bond92b96792009-06-13 07:38:31 -040062#include "hostap.h"
Forest Bond92b96792009-06-13 07:38:31 -040063#include "wpactl.h"
Forest Bond92b96792009-06-13 07:38:31 -040064#include "ioctl.h"
Forest Bond92b96792009-06-13 07:38:31 -040065#include "iwctl.h"
Forest Bond92b96792009-06-13 07:38:31 -040066#include "dpc.h"
Forest Bond92b96792009-06-13 07:38:31 -040067#include "datarate.h"
Forest Bond92b96792009-06-13 07:38:31 -040068#include "rf.h"
Forest Bond92b96792009-06-13 07:38:31 -040069#include "firmware.h"
Forest Bond92b96792009-06-13 07:38:31 -040070#include "rndis.h"
Forest Bond92b96792009-06-13 07:38:31 -040071#include "control.h"
Forest Bond92b96792009-06-13 07:38:31 -040072#include "channel.h"
Forest Bond92b96792009-06-13 07:38:31 -040073#include "int.h"
Forest Bond92b96792009-06-13 07:38:31 -040074#include "iowpa.h"
Forest Bond92b96792009-06-13 07:38:31 -040075
76/*--------------------- Static Definitions -------------------------*/
77//static int msglevel =MSG_LEVEL_DEBUG;
78static int msglevel =MSG_LEVEL_INFO;
79
80//
81// Define module options
82//
83
84// Version Information
85#define DRIVER_AUTHOR "VIA Networking Technologies, Inc., <lyndonchen@vntek.com.tw>"
86MODULE_AUTHOR(DRIVER_AUTHOR);
87MODULE_LICENSE("GPL");
88MODULE_DESCRIPTION(DEVICE_FULL_DRV_NAM);
89
Forest Bond92b96792009-06-13 07:38:31 -040090#define DEVICE_PARAM(N,D) \
91 static int N[MAX_UINTS]=OPTION_DEFAULT;\
92 module_param_array(N, int, NULL, 0);\
93 MODULE_PARM_DESC(N, D);
94
Forest Bond92b96792009-06-13 07:38:31 -040095#define RX_DESC_MIN0 16
96#define RX_DESC_MAX0 128
97#define RX_DESC_DEF0 64
98DEVICE_PARAM(RxDescriptors0,"Number of receive usb desc buffer");
99
100
101#define TX_DESC_MIN0 16
102#define TX_DESC_MAX0 128
103#define TX_DESC_DEF0 64
104DEVICE_PARAM(TxDescriptors0,"Number of transmit usb desc buffer");
105
106
107#define CHANNEL_MIN 1
108#define CHANNEL_MAX 14
109#define CHANNEL_DEF 6
110
111DEVICE_PARAM(Channel, "Channel number");
112
113
114/* PreambleType[] is the preamble length used for transmit.
115 0: indicate allows long preamble type
116 1: indicate allows short preamble type
117*/
118
119#define PREAMBLE_TYPE_DEF 1
120
121DEVICE_PARAM(PreambleType, "Preamble Type");
122
123
124#define RTS_THRESH_MIN 512
125#define RTS_THRESH_MAX 2347
126#define RTS_THRESH_DEF 2347
127
128DEVICE_PARAM(RTSThreshold, "RTS threshold");
129
130
131#define FRAG_THRESH_MIN 256
132#define FRAG_THRESH_MAX 2346
133#define FRAG_THRESH_DEF 2346
134
135DEVICE_PARAM(FragThreshold, "Fragmentation threshold");
136
137
138#define DATA_RATE_MIN 0
139#define DATA_RATE_MAX 13
140#define DATA_RATE_DEF 13
141/* datarate[] index
142 0: indicate 1 Mbps 0x02
143 1: indicate 2 Mbps 0x04
144 2: indicate 5.5 Mbps 0x0B
145 3: indicate 11 Mbps 0x16
146 4: indicate 6 Mbps 0x0c
147 5: indicate 9 Mbps 0x12
148 6: indicate 12 Mbps 0x18
149 7: indicate 18 Mbps 0x24
150 8: indicate 24 Mbps 0x30
151 9: indicate 36 Mbps 0x48
152 10: indicate 48 Mbps 0x60
153 11: indicate 54 Mbps 0x6c
154 12: indicate 72 Mbps 0x90
155 13: indicate auto rate
156*/
157
158DEVICE_PARAM(ConnectionRate, "Connection data rate");
159
160#define OP_MODE_MAX 2
161#define OP_MODE_DEF 0
162#define OP_MODE_MIN 0
163
164DEVICE_PARAM(OPMode, "Infrastruct, adhoc, AP mode ");
165
166/* OpMode[] is used for transmit.
167 0: indicate infrastruct mode used
168 1: indicate adhoc mode used
169 2: indicate AP mode used
170*/
171
172
173/* PSMode[]
174 0: indicate disable power saving mode
175 1: indicate enable power saving mode
176*/
177
178#define PS_MODE_DEF 0
179
180DEVICE_PARAM(PSMode, "Power saving mode");
181
182
183#define SHORT_RETRY_MIN 0
184#define SHORT_RETRY_MAX 31
185#define SHORT_RETRY_DEF 8
186
187
188DEVICE_PARAM(ShortRetryLimit, "Short frame retry limits");
189
190#define LONG_RETRY_MIN 0
191#define LONG_RETRY_MAX 15
192#define LONG_RETRY_DEF 4
193
194
195DEVICE_PARAM(LongRetryLimit, "long frame retry limits");
196
197
198/* BasebandType[] baseband type selected
199 0: indicate 802.11a type
200 1: indicate 802.11b type
201 2: indicate 802.11g type
202*/
203#define BBP_TYPE_MIN 0
204#define BBP_TYPE_MAX 2
205#define BBP_TYPE_DEF 2
206
207DEVICE_PARAM(BasebandType, "baseband type");
208
209
210
211/* 80211hEnable[]
212 0: indicate disable 802.11h
213 1: indicate enable 802.11h
214*/
215
216#define X80211h_MODE_DEF 0
217
218DEVICE_PARAM(b80211hEnable, "802.11h mode");
219
220
221//
222// Static vars definitions
223//
224
Andres More26e5b652010-04-13 19:43:07 -0300225static struct usb_device_id vt6656_table[] __devinitdata = {
Forest Bond92b96792009-06-13 07:38:31 -0400226 {USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)},
227 {}
228};
229
Forest Bond92b96792009-06-13 07:38:31 -0400230// Frequency list (map channels to frequencies)
231/*
232static const long frequency_list[] = {
233 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484,
234 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
235 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240,
236 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
237 5700, 5745, 5765, 5785, 5805, 5825
238 };
239
240
241#ifndef IW_ENCODE_NOKEY
242#define IW_ENCODE_NOKEY 0x0800
243#define IW_ENCODE_MODE (IW_ENCODE_DISABLED | IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN)
244#endif
245
Forest Bond92b96792009-06-13 07:38:31 -0400246static const struct iw_handler_def iwctl_handler_def;
Forest Bond92b96792009-06-13 07:38:31 -0400247*/
248
Forest Bond92b96792009-06-13 07:38:31 -0400249/*--------------------- Static Functions --------------------------*/
Andres More26e5b652010-04-13 19:43:07 -0300250
251static int vt6656_probe(struct usb_interface *intf,
252 const struct usb_device_id *id);
253static void vt6656_disconnect(struct usb_interface *intf);
254
Forest Bond92b96792009-06-13 07:38:31 -0400255#ifdef CONFIG_PM /* Minimal support for suspend and resume */
Andres More26e5b652010-04-13 19:43:07 -0300256static int vt6656_suspend(struct usb_interface *intf, pm_message_t message);
257static int vt6656_resume(struct usb_interface *intf);
258#endif /* CONFIG_PM */
259
Forest Bond92b96792009-06-13 07:38:31 -0400260static struct net_device_stats *device_get_stats(struct net_device *dev);
261static int device_open(struct net_device *dev);
262static int device_xmit(struct sk_buff *skb, struct net_device *dev);
263static void device_set_multi(struct net_device *dev);
264static int device_close(struct net_device *dev);
265static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
266
267static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType);
268static BOOL device_init_defrag_cb(PSDevice pDevice);
269static void device_init_diversity_timer(PSDevice pDevice);
270static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev);
271
272static int ethtool_ioctl(struct net_device *dev, void *useraddr);
273static void device_free_tx_bufs(PSDevice pDevice);
274static void device_free_rx_bufs(PSDevice pDevice);
275static void device_free_int_bufs(PSDevice pDevice);
276static void device_free_frag_bufs(PSDevice pDevice);
277static BOOL device_alloc_bufs(PSDevice pDevice);
278
279static int Read_config_file(PSDevice pDevice);
Andres Morecc856e62010-05-17 21:34:01 -0300280static unsigned char *Config_FileOperation(PSDevice pDevice);
281static int Config_FileGetParameter(unsigned char *string,
282 unsigned char *dest,
283 unsigned char *source);
Forest Bond92b96792009-06-13 07:38:31 -0400284
285//2008-0714<Add>by Mike Liu
286static BOOL device_release_WPADEV(PSDevice pDevice);
287
Forest Bond92b96792009-06-13 07:38:31 -0400288static void usb_device_reset(PSDevice pDevice);
Forest Bond92b96792009-06-13 07:38:31 -0400289
290
291
292/*--------------------- Export Variables --------------------------*/
293
294/*--------------------- Export Functions --------------------------*/
295
296
297static void
298device_set_options(PSDevice pDevice) {
299
Andres More9a0e7562010-04-13 21:54:48 -0300300 BYTE abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
301 BYTE abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
302 u8 abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
Forest Bond92b96792009-06-13 07:38:31 -0400303
Andres More9a0e7562010-04-13 21:54:48 -0300304 memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN);
305 memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN);
306 memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400307
308 pDevice->cbTD = TX_DESC_DEF0;
309 pDevice->cbRD = RX_DESC_DEF0;
310 pDevice->uChannel = CHANNEL_DEF;
311 pDevice->wRTSThreshold = RTS_THRESH_DEF;
312 pDevice->wFragmentationThreshold = FRAG_THRESH_DEF;
313 pDevice->byShortRetryLimit = SHORT_RETRY_DEF;
314 pDevice->byLongRetryLimit = LONG_RETRY_DEF;
315 pDevice->wMaxTransmitMSDULifetime = DEFAULT_MSDU_LIFETIME;
316 pDevice->byShortPreamble = PREAMBLE_TYPE_DEF;
317 pDevice->ePSMode = PS_MODE_DEF;
318 pDevice->b11hEnable = X80211h_MODE_DEF;
319 pDevice->eOPMode = OP_MODE_DEF;
320 pDevice->uConnectionRate = DATA_RATE_DEF;
321 if (pDevice->uConnectionRate < RATE_AUTO) pDevice->bFixRate = TRUE;
322 pDevice->byBBType = BBP_TYPE_DEF;
323 pDevice->byPacketType = pDevice->byBBType;
324 pDevice->byAutoFBCtrl = AUTO_FB_0;
325 pDevice->bUpdateBBVGA = TRUE;
326 pDevice->byFOETuning = 0;
327 pDevice->byAutoPwrTunning = 0;
328 pDevice->wCTSDuration = 0;
329 pDevice->byPreambleType = 0;
330 pDevice->bExistSWNetAddr = FALSE;
331// pDevice->bDiversityRegCtlON = TRUE;
332 pDevice->bDiversityRegCtlON = FALSE;
333}
334
335
Andres More8611a292010-05-01 14:25:00 -0300336static void device_init_diversity_timer(PSDevice pDevice)
337{
Forest Bond92b96792009-06-13 07:38:31 -0400338 init_timer(&pDevice->TimerSQ3Tmax1);
Andres Morecc856e62010-05-17 21:34:01 -0300339 pDevice->TimerSQ3Tmax1.data = (unsigned long)pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400340 pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack;
341 pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ);
342
343 init_timer(&pDevice->TimerSQ3Tmax2);
Andres Morecc856e62010-05-17 21:34:01 -0300344 pDevice->TimerSQ3Tmax2.data = (unsigned long)pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400345 pDevice->TimerSQ3Tmax2.function = (TimerFunction)TimerSQ3CallBack;
346 pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ);
347
348 init_timer(&pDevice->TimerSQ3Tmax3);
Andres Morecc856e62010-05-17 21:34:01 -0300349 pDevice->TimerSQ3Tmax3.data = (unsigned long)pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400350 pDevice->TimerSQ3Tmax3.function = (TimerFunction)TimerSQ3Tmax3CallBack;
351 pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ);
352
353 return;
354}
355
356
357//
358// Initialiation of MAC & BBP registers
359//
360
361static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
362{
Andres More9a0e7562010-04-13 21:54:48 -0300363 u8 abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
364 u8 abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
365 u8 abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
Forest Bond92b96792009-06-13 07:38:31 -0400366 BYTE byAntenna;
Andres Morecc856e62010-05-17 21:34:01 -0300367 unsigned int ii;
Forest Bond92b96792009-06-13 07:38:31 -0400368 CMD_CARD_INIT sInitCmd;
369 NTSTATUS ntStatus = STATUS_SUCCESS;
370 RSP_CARD_INIT sInitRsp;
371 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
372 BYTE byTmp;
373 BYTE byCalibTXIQ = 0;
374 BYTE byCalibTXDC = 0;
375 BYTE byCalibRXIQ = 0;
376
377 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---->INIbInitAdapter. [%d][%d]\n", InitType, pDevice->byPacketType);
378 spin_lock_irq(&pDevice->lock);
Andres More9a0e7562010-04-13 21:54:48 -0300379 if (InitType == DEVICE_INIT_COLD) {
380 memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN);
381 memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN);
382 memcpy(pDevice->abySNAP_Bridgetunnel,
383 abySNAP_Bridgetunnel,
384 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400385
386 if ( !FIRMWAREbCheckVersion(pDevice) ) {
387 if (FIRMWAREbDownload(pDevice) == TRUE) {
388 if (FIRMWAREbBrach2Sram(pDevice) == FALSE) {
389 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" FIRMWAREbBrach2Sram fail \n");
390 spin_unlock_irq(&pDevice->lock);
391 return FALSE;
392 }
393 } else {
394
395 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" FIRMWAREbDownload fail \n");
396 spin_unlock_irq(&pDevice->lock);
397 return FALSE;
398 }
399 }
400
401 if ( !BBbVT3184Init(pDevice) ) {
402 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" BBbVT3184Init fail \n");
403 spin_unlock_irq(&pDevice->lock);
404 return FALSE;
405 }
406 }
407
408 sInitCmd.byInitClass = (BYTE)InitType;
409 sInitCmd.bExistSWNetAddr = (BYTE) pDevice->bExistSWNetAddr;
410 for(ii=0;ii<6;ii++)
411 sInitCmd.bySWNetAddr[ii] = pDevice->abyCurrentNetAddr[ii];
412 sInitCmd.byShortRetryLimit = pDevice->byShortRetryLimit;
413 sInitCmd.byLongRetryLimit = pDevice->byLongRetryLimit;
414
415 //issue Card_init command to device
416 ntStatus = CONTROLnsRequestOut(pDevice,
417 MESSAGE_TYPE_CARDINIT,
418 0,
419 0,
420 sizeof(CMD_CARD_INIT),
421 (PBYTE) &(sInitCmd));
422
423 if ( ntStatus != STATUS_SUCCESS ) {
424 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Issue Card init fail \n");
425 spin_unlock_irq(&pDevice->lock);
426 return FALSE;
427 }
428 if (InitType == DEVICE_INIT_COLD) {
429
430 ntStatus = CONTROLnsRequestIn(pDevice,MESSAGE_TYPE_INIT_RSP,0,0,sizeof(RSP_CARD_INIT), (PBYTE) &(sInitRsp));
431
432 if (ntStatus != STATUS_SUCCESS) {
433 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Cardinit request in status fail!\n");
434 spin_unlock_irq(&pDevice->lock);
435 return FALSE;
436 }
437
438 //Local ID for AES functions
439 ntStatus = CONTROLnsRequestIn(pDevice,
440 MESSAGE_TYPE_READ,
441 MAC_REG_LOCALID,
442 MESSAGE_REQUEST_MACREG,
443 1,
444 &pDevice->byLocalID);
445
446 if ( ntStatus != STATUS_SUCCESS ) {
447 spin_unlock_irq(&pDevice->lock);
448 return FALSE;
449 }
450
451 // Do MACbSoftwareReset in MACvInitialize
452 // force CCK
453 pDevice->bCCK = TRUE;
454 pDevice->bProtectMode = FALSE; //Only used in 11g type, sync with ERP IE
455 pDevice->bNonERPPresent = FALSE;
456 pDevice->bBarkerPreambleMd = FALSE;
457 if ( pDevice->bFixRate ) {
458 pDevice->wCurrentRate = (WORD) pDevice->uConnectionRate;
459 } else {
460 if ( pDevice->byBBType == BB_TYPE_11B )
461 pDevice->wCurrentRate = RATE_11M;
462 else
463 pDevice->wCurrentRate = RATE_54M;
464 }
465
466 CHvInitChannelTable(pDevice);
467
468 pDevice->byTopOFDMBasicRate = RATE_24M;
469 pDevice->byTopCCKBasicRate = RATE_1M;
470 pDevice->byRevId = 0; //Target to IF pin while programming to RF chip.
471 pDevice->byCurPwr = 0xFF;
472
473 pDevice->byCCKPwr = pDevice->abyEEPROM[EEP_OFS_PWR_CCK];
474 pDevice->byOFDMPwrG = pDevice->abyEEPROM[EEP_OFS_PWR_OFDMG];
475 // Load power Table
476 for (ii=0;ii<14;ii++) {
477 pDevice->abyCCKPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_CCK_PWR_TBL];
478 if (pDevice->abyCCKPwrTbl[ii] == 0)
479 pDevice->abyCCKPwrTbl[ii] = pDevice->byCCKPwr;
480 pDevice->abyOFDMPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_OFDM_PWR_TBL];
481 if (pDevice->abyOFDMPwrTbl[ii] == 0)
482 pDevice->abyOFDMPwrTbl[ii] = pDevice->byOFDMPwrG;
483 }
484
485 //original zonetype is USA,but customize zonetype is europe,
486 // then need recover 12,13 ,14 channel with 11 channel
487 if(((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) ||
488 (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe))&&
489 (pDevice->byOriginalZonetype == ZoneType_USA)) {
490 for(ii=11;ii<14;ii++) {
491 pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
492 pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
493 }
494 }
495
496 //{{ RobertYu: 20041124
497 pDevice->byOFDMPwrA = 0x34; // same as RFbMA2829SelectChannel
498 // Load OFDM A Power Table
499 for (ii=0;ii<CB_MAX_CHANNEL_5G;ii++) { //RobertYu:20041224, bug using CB_MAX_CHANNEL
500 pDevice->abyOFDMAPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_OFDMA_PWR_TBL];
501 if (pDevice->abyOFDMAPwrTbl[ii] == 0)
502 pDevice->abyOFDMAPwrTbl[ii] = pDevice->byOFDMPwrA;
503 }
504 //}} RobertYu
505
506 byAntenna = pDevice->abyEEPROM[EEP_OFS_ANTENNA];
507 if (byAntenna & EEP_ANTINV)
508 pDevice->bTxRxAntInv = TRUE;
509 else
510 pDevice->bTxRxAntInv = FALSE;
511
512 byAntenna &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
513
514 if (byAntenna == 0) // if not set default is All
515 byAntenna = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
516
517 if (byAntenna == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
518 pDevice->byAntennaCount = 2;
519 pDevice->byTxAntennaMode = ANT_B;
520 pDevice->dwTxAntennaSel = 1;
521 pDevice->dwRxAntennaSel = 1;
522 if (pDevice->bTxRxAntInv == TRUE)
523 pDevice->byRxAntennaMode = ANT_A;
524 else
525 pDevice->byRxAntennaMode = ANT_B;
526
527 if (pDevice->bDiversityRegCtlON)
528 pDevice->bDiversityEnable = TRUE;
529 else
530 pDevice->bDiversityEnable = FALSE;
531 } else {
532 pDevice->bDiversityEnable = FALSE;
533 pDevice->byAntennaCount = 1;
534 pDevice->dwTxAntennaSel = 0;
535 pDevice->dwRxAntennaSel = 0;
536 if (byAntenna & EEP_ANTENNA_AUX) {
537 pDevice->byTxAntennaMode = ANT_A;
538 if (pDevice->bTxRxAntInv == TRUE)
539 pDevice->byRxAntennaMode = ANT_B;
540 else
541 pDevice->byRxAntennaMode = ANT_A;
542 } else {
543 pDevice->byTxAntennaMode = ANT_B;
544 if (pDevice->bTxRxAntInv == TRUE)
545 pDevice->byRxAntennaMode = ANT_A;
546 else
547 pDevice->byRxAntennaMode = ANT_B;
548 }
549 }
550 pDevice->ulDiversityNValue = 100*255;
551 pDevice->ulDiversityMValue = 100*16;
552 pDevice->byTMax = 1;
553 pDevice->byTMax2 = 4;
554 pDevice->ulSQ3TH = 0;
555 pDevice->byTMax3 = 64;
556 // -----------------------------------------------------------------
557
558 //Get Auto Fall Back Type
559 pDevice->byAutoFBCtrl = AUTO_FB_0;
560
561 // Set SCAN Time
562 pDevice->uScanTime = WLAN_SCAN_MINITIME;
563
564 // default Auto Mode
565 //pDevice->NetworkType = Ndis802_11Automode;
566 pDevice->eConfigPHYMode = PHY_TYPE_AUTO;
567 pDevice->byBBType = BB_TYPE_11G;
568
569 // initialize BBP registers
570 pDevice->ulTxPower = 25;
571
572 // Get Channel range
573 pDevice->byMinChannel = 1;
574 pDevice->byMaxChannel = CB_MAX_CHANNEL;
575
576 // Get RFType
577 pDevice->byRFType = sInitRsp.byRFType;
578
579 if ((pDevice->byRFType & RF_EMU) != 0) {
580 // force change RevID for VT3253 emu
581 pDevice->byRevId = 0x80;
582 }
583
584 // Load EEPROM calibrated vt3266 parameters
585 if (pDevice->byRFType == RF_VT3226D0) {
586 if((pDevice->abyEEPROM[EEP_OFS_MAJOR_VER] == 0x1) &&
587 (pDevice->abyEEPROM[EEP_OFS_MINOR_VER] >= 0x4)) {
588 byCalibTXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_IQ];
589 byCalibTXDC = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_DC];
590 byCalibRXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_RX_IQ];
591 if( (byCalibTXIQ || byCalibTXDC || byCalibRXIQ) ) {
592 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFF, 0x03); // CR255, Set BB to support TX/RX IQ and DC compensation Mode
593 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFB, byCalibTXIQ); // CR251, TX I/Q Imbalance Calibration
594 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFC, byCalibTXDC); // CR252, TX DC-Offset Calibration
595 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFD, byCalibRXIQ); // CR253, RX I/Q Imbalance Calibration
596 } else {
597 // turn off BB Calibration compensation
598 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFF, 0x0); // CR255
599 }
600 }
601 }
602 pMgmt->eScanType = WMAC_SCAN_PASSIVE;
603 pMgmt->uCurrChannel = pDevice->uChannel;
604 pMgmt->uIBSSChannel = pDevice->uChannel;
605 CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel);
606
607 // get Permanent network address
Jim Lieb3e362592009-08-12 14:54:11 -0700608 memcpy(pDevice->abyPermanentNetAddr,&(sInitRsp.byNetAddr[0]),6);
Andres More9a0e7562010-04-13 21:54:48 -0300609 memcpy(pDevice->abyCurrentNetAddr,
610 pDevice->abyPermanentNetAddr,
611 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400612
613 // if exist SW network address, use SW network address.
614
615 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %02x-%02x-%02x=%02x-%02x-%02x\n",
616 pDevice->abyCurrentNetAddr[0],
617 pDevice->abyCurrentNetAddr[1],
618 pDevice->abyCurrentNetAddr[2],
619 pDevice->abyCurrentNetAddr[3],
620 pDevice->abyCurrentNetAddr[4],
621 pDevice->abyCurrentNetAddr[5]);
622 }
623
624
625
626 // Set BB and packet type at the same time.
627 // Set Short Slot Time, xIFS, and RSPINF.
628 if (pDevice->byBBType == BB_TYPE_11A) {
629 CARDbAddBasicRate(pDevice, RATE_6M);
630 pDevice->bShortSlotTime = TRUE;
631 } else {
632 CARDbAddBasicRate(pDevice, RATE_1M);
633 pDevice->bShortSlotTime = FALSE;
634 }
635 BBvSetShortSlotTime(pDevice);
636 CARDvSetBSSMode(pDevice);
637
638 if (pDevice->bUpdateBBVGA) {
639 pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
640 pDevice->byBBVGANew = pDevice->byBBVGACurrent;
641 BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
642 }
643
644 pDevice->byRadioCtl = pDevice->abyEEPROM[EEP_OFS_RADIOCTL];
645 pDevice->bHWRadioOff = FALSE;
646 if ( (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) != 0 ) {
647 ntStatus = CONTROLnsRequestIn(pDevice,
648 MESSAGE_TYPE_READ,
649 MAC_REG_GPIOCTL1,
650 MESSAGE_REQUEST_MACREG,
651 1,
652 &byTmp);
653
654 if ( ntStatus != STATUS_SUCCESS ) {
655 spin_unlock_irq(&pDevice->lock);
656 return FALSE;
657 }
658 if ( (byTmp & GPIO3_DATA) == 0 ) {
659 pDevice->bHWRadioOff = TRUE;
660 MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
661 } else {
662 MACvRegBitsOff(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
663 pDevice->bHWRadioOff = FALSE;
664 }
665
666 } //EEP_RADIOCTL_ENABLE
667
668 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_TMLEN,0x38);
669 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
670 MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL0,0x01);
671
672 if ((pDevice->bHWRadioOff == TRUE) || (pDevice->bRadioControlOff == TRUE)) {
673 CARDbRadioPowerOff(pDevice);
674 } else {
675 CARDbRadioPowerOn(pDevice);
676 }
677
678 spin_unlock_irq(&pDevice->lock);
679 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----INIbInitAdapter Exit\n");
680 return TRUE;
681}
682
683static BOOL device_release_WPADEV(PSDevice pDevice)
684{
685 viawget_wpa_header *wpahdr;
686 int ii=0;
687 // wait_queue_head_t Set_wait;
688 //send device close to wpa_supplicnat layer
689 if (pDevice->bWPADEVUp==TRUE) {
690 wpahdr = (viawget_wpa_header *)pDevice->skb->data;
691 wpahdr->type = VIAWGET_DEVICECLOSE_MSG;
692 wpahdr->resp_ie_len = 0;
693 wpahdr->req_ie_len = 0;
694 skb_put(pDevice->skb, sizeof(viawget_wpa_header));
695 pDevice->skb->dev = pDevice->wpadev;
Jim Liebd899d4032009-07-23 17:22:42 -0700696 skb_reset_mac_header(pDevice->skb);
Forest Bond92b96792009-06-13 07:38:31 -0400697 pDevice->skb->pkt_type = PACKET_HOST;
698 pDevice->skb->protocol = htons(ETH_P_802_2);
699 memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
700 netif_rx(pDevice->skb);
701 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
702
703 //wait release WPADEV
704 // init_waitqueue_head(&Set_wait);
705 // wait_event_timeout(Set_wait, ((pDevice->wpadev==NULL)&&(pDevice->skb == NULL)),5*HZ); //1s wait
706 while(pDevice->bWPADEVUp==TRUE) {
707 set_current_state(TASK_UNINTERRUPTIBLE);
708 schedule_timeout (HZ/20); //wait 50ms
709 ii++;
710 if(ii>20)
711 break;
712 }
713 };
714 return TRUE;
715}
716
717#ifdef CONFIG_PM /* Minimal support for suspend and resume */
Andres More26e5b652010-04-13 19:43:07 -0300718
719static int vt6656_suspend(struct usb_interface *intf, pm_message_t message)
Forest Bond92b96792009-06-13 07:38:31 -0400720{
721 PSDevice pDevice = usb_get_intfdata(intf);
722 struct net_device *dev = pDevice->dev;
723
724 printk("VNTWUSB Suspend Start======>\n");
725if(dev != NULL) {
726 if(pDevice->flags & DEVICE_FLAGS_OPENED)
727 device_close(dev);
728}
729
730 usb_put_dev(interface_to_usbdev(intf));
731 return 0;
732}
733
Andres More26e5b652010-04-13 19:43:07 -0300734static int vt6656_resume(struct usb_interface *intf)
Forest Bond92b96792009-06-13 07:38:31 -0400735{
736 PSDevice pDevice = usb_get_intfdata(intf);
737 struct net_device *dev = pDevice->dev;
738
739 printk("VNTWUSB Resume Start======>\n");
740 if(dev != NULL) {
741 usb_get_dev(interface_to_usbdev(intf));
742 if(!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
743 if(device_open(dev)!=0)
744 printk("VNTWUSB Resume Start======>open fail\n");
745 }
746 }
747 return 0;
748}
Forest Bond92b96792009-06-13 07:38:31 -0400749
Andres More26e5b652010-04-13 19:43:07 -0300750#endif /* CONFIG_PM */
Forest Bonddd8db702009-06-13 07:38:54 -0400751
752static const struct net_device_ops device_netdev_ops = {
753 .ndo_open = device_open,
754 .ndo_stop = device_close,
755 .ndo_do_ioctl = device_ioctl,
756 .ndo_get_stats = device_get_stats,
757 .ndo_start_xmit = device_xmit,
758 .ndo_set_multicast_list = device_set_multi,
759};
760
761
Andres More26e5b652010-04-13 19:43:07 -0300762static int __devinit
763vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
Forest Bond92b96792009-06-13 07:38:31 -0400764{
Andres More9a0e7562010-04-13 21:54:48 -0300765 u8 fake_mac[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
Forest Bond92b96792009-06-13 07:38:31 -0400766 struct usb_device *udev = interface_to_usbdev(intf);
767 int rc = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400768 struct net_device *netdev = NULL;
769 PSDevice pDevice = NULL;
770
771
772 printk(KERN_NOTICE "%s Ver. %s\n",DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
773 printk(KERN_NOTICE "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
774
Forest Bond92b96792009-06-13 07:38:31 -0400775 udev = usb_get_dev(udev);
Forest Bond92b96792009-06-13 07:38:31 -0400776
Forest Bond1e28efa2009-06-13 07:38:50 -0400777 netdev = alloc_etherdev(sizeof(DEVICE_INFO));
Forest Bond92b96792009-06-13 07:38:31 -0400778
779 if (netdev == NULL) {
780 printk(KERN_ERR DEVICE_NAME ": allocate net device failed \n");
781 kfree(pDevice);
782 goto err_nomem;
783 }
Forest Bond1e28efa2009-06-13 07:38:50 -0400784
785 pDevice = netdev_priv(netdev);
786 memset(pDevice, 0, sizeof(DEVICE_INFO));
787
Forest Bond92b96792009-06-13 07:38:31 -0400788 pDevice->dev = netdev;
789 pDevice->usb = udev;
790
Forest Bond92b96792009-06-13 07:38:31 -0400791 // Set initial settings
792 device_set_options(pDevice);
793 spin_lock_init(&pDevice->lock);
794
795 pDevice->tx_80211 = device_dma0_tx_80211;
Andres More8611a292010-05-01 14:25:00 -0300796 pDevice->sMgmtObj.pAdapter = (void *)pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400797
Forest Bonddd8db702009-06-13 07:38:54 -0400798 netdev->netdev_ops = &device_netdev_ops;
799
Forest Bond92b96792009-06-13 07:38:31 -0400800 netdev->wireless_handlers = (struct iw_handler_def *)&iwctl_handler_def;
Forest Bond92b96792009-06-13 07:38:31 -0400801
Forest Bond92b96792009-06-13 07:38:31 -0400802 //2008-0623-01<Remark>by MikeLiu
803 //2007-0821-01<Add>by MikeLiu
Forest Bond92b96792009-06-13 07:38:31 -0400804 usb_set_intfdata(intf, pDevice);
805 SET_NETDEV_DEV(netdev, &intf->dev);
Andres More9a0e7562010-04-13 21:54:48 -0300806 memcpy(pDevice->dev->dev_addr, fake_mac, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400807 rc = register_netdev(netdev);
808 if (rc != 0) {
809 printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
810 free_netdev(netdev);
811 kfree(pDevice);
812 return -ENODEV;
813 }
Forest Bond92b96792009-06-13 07:38:31 -0400814
815//2008-07-21-01<Add>by MikeLiu
816//register wpadev
miaofngdda79402009-07-15 10:33:35 -0400817#if 0
Forest Bond92b96792009-06-13 07:38:31 -0400818 if(wpa_set_wpadev(pDevice, 1)!=0) {
819 printk("Fail to Register WPADEV?\n");
820 unregister_netdev(pDevice->dev);
821 free_netdev(netdev);
822 kfree(pDevice);
823 }
miaofngdda79402009-07-15 10:33:35 -0400824#endif
Forest Bond92b96792009-06-13 07:38:31 -0400825 usb_device_reset(pDevice);
Forest Bond92b96792009-06-13 07:38:31 -0400826
827#ifdef SndEvt_ToAPI
828{
829 union iwreq_data wrqu;
830 memset(&wrqu, 0, sizeof(wrqu));
831 wrqu.data.flags = RT_INSMOD_EVENT_FLAG;
832 wrqu.data.length =IFNAMSIZ;
833 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pDevice->dev->name);
834}
835#endif
836
837 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400838
839
840err_nomem:
Forest Bond92b96792009-06-13 07:38:31 -0400841 //2008-0922-01<Add>by MikeLiu, decrease usb counter.
842 usb_put_dev(udev);
843
844 return -ENOMEM;
Forest Bond92b96792009-06-13 07:38:31 -0400845}
846
847
Andres More8611a292010-05-01 14:25:00 -0300848static void device_free_tx_bufs(PSDevice pDevice)
849{
Forest Bond92b96792009-06-13 07:38:31 -0400850 PUSB_SEND_CONTEXT pTxContext;
851 int ii;
852
853 for (ii = 0; ii < pDevice->cbTD; ii++) {
854
855 pTxContext = pDevice->apTD[ii];
856 //de-allocate URBs
857 if (pTxContext->pUrb) {
Jim Liebdad72fe2009-08-12 14:54:14 -0700858 usb_kill_urb(pTxContext->pUrb);
Forest Bond92b96792009-06-13 07:38:31 -0400859 usb_free_urb(pTxContext->pUrb);
860 }
861 if (pTxContext)
862 kfree(pTxContext);
863 }
864 return;
865}
866
867
Andres More8611a292010-05-01 14:25:00 -0300868static void device_free_rx_bufs(PSDevice pDevice)
869{
Forest Bond92b96792009-06-13 07:38:31 -0400870 PRCB pRCB;
871 int ii;
872
873 for (ii = 0; ii < pDevice->cbRD; ii++) {
874
875 pRCB = pDevice->apRCB[ii];
876 //de-allocate URBs
877 if (pRCB->pUrb) {
Jim Liebdad72fe2009-08-12 14:54:14 -0700878 usb_kill_urb(pRCB->pUrb);
Forest Bond92b96792009-06-13 07:38:31 -0400879 usb_free_urb(pRCB->pUrb);
880 }
881 //de-allocate skb
882 if (pRCB->skb)
883 dev_kfree_skb(pRCB->skb);
884 }
885 if (pDevice->pRCBMem)
886 kfree(pDevice->pRCBMem);
887
888 return;
889}
890
891//2007-1107-02<Add>by MikeLiu
Forest Bond92b96792009-06-13 07:38:31 -0400892static void usb_device_reset(PSDevice pDevice)
893{
894 int status;
895 status = usb_reset_device(pDevice->usb);
896 if (status)
897 printk("usb_device_reset fail status=%d\n",status);
898 return ;
899}
Forest Bond92b96792009-06-13 07:38:31 -0400900
Andres More8611a292010-05-01 14:25:00 -0300901static void device_free_int_bufs(PSDevice pDevice)
902{
Forest Bond92b96792009-06-13 07:38:31 -0400903 if (pDevice->intBuf.pDataBuf != NULL)
904 kfree(pDevice->intBuf.pDataBuf);
905 return;
906}
907
908
909static BOOL device_alloc_bufs(PSDevice pDevice) {
910
911 PUSB_SEND_CONTEXT pTxContext;
912 PRCB pRCB;
913 int ii;
914
915
916 for (ii = 0; ii < pDevice->cbTD; ii++) {
917
918 pTxContext = kmalloc(sizeof(USB_SEND_CONTEXT), GFP_KERNEL);
919 if (pTxContext == NULL) {
920 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : allocate tx usb context failed\n", pDevice->dev->name);
921 goto free_tx;
922 }
923 pDevice->apTD[ii] = pTxContext;
Andres More8611a292010-05-01 14:25:00 -0300924 pTxContext->pDevice = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400925 //allocate URBs
Jim Liebdad72fe2009-08-12 14:54:14 -0700926 pTxContext->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400927 if (pTxContext->pUrb == NULL) {
928 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "alloc tx urb failed\n");
929 goto free_tx;
930 }
931 pTxContext->bBoolInUse = FALSE;
932 }
933
934 // allocate rcb mem
935 pDevice->pRCBMem = kmalloc((sizeof(RCB) * pDevice->cbRD), GFP_KERNEL);
936 if (pDevice->pRCBMem == NULL) {
937 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : alloc rx usb context failed\n", pDevice->dev->name);
938 goto free_tx;
939 }
940
941
942 pDevice->FirstRecvFreeList = NULL;
943 pDevice->LastRecvFreeList = NULL;
944 pDevice->FirstRecvMngList = NULL;
945 pDevice->LastRecvMngList = NULL;
946 pDevice->NumRecvFreeList = 0;
947 memset(pDevice->pRCBMem, 0, (sizeof(RCB) * pDevice->cbRD));
948 pRCB = (PRCB) pDevice->pRCBMem;
949
950 for (ii = 0; ii < pDevice->cbRD; ii++) {
951
952 pDevice->apRCB[ii] = pRCB;
Andres More8611a292010-05-01 14:25:00 -0300953 pRCB->pDevice = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400954 //allocate URBs
Jim Liebdad72fe2009-08-12 14:54:14 -0700955 pRCB->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400956
957 if (pRCB->pUrb == NULL) {
958 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx urb\n");
959 goto free_rx_tx;
960 }
961 pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
962 if (pRCB->skb == NULL) {
963 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx skb\n");
964 goto free_rx_tx;
965 }
966 pRCB->skb->dev = pDevice->dev;
967 pRCB->bBoolInUse = FALSE;
968 EnqueueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList, pRCB);
969 pDevice->NumRecvFreeList++;
970 pRCB++;
971 }
972
973
Jim Liebdad72fe2009-08-12 14:54:14 -0700974 pDevice->pControlURB = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400975 if (pDevice->pControlURB == NULL) {
976 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc control urb\n");
977 goto free_rx_tx;
978 }
979
Jim Liebdad72fe2009-08-12 14:54:14 -0700980 pDevice->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400981 if (pDevice->pInterruptURB == NULL) {
982 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int urb\n");
Jim Liebdad72fe2009-08-12 14:54:14 -0700983 usb_kill_urb(pDevice->pControlURB);
Forest Bond92b96792009-06-13 07:38:31 -0400984 usb_free_urb(pDevice->pControlURB);
985 goto free_rx_tx;
986 }
987
988 pDevice->intBuf.pDataBuf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
989 if (pDevice->intBuf.pDataBuf == NULL) {
990 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int buf\n");
Jim Liebdad72fe2009-08-12 14:54:14 -0700991 usb_kill_urb(pDevice->pControlURB);
992 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -0400993 usb_free_urb(pDevice->pControlURB);
994 usb_free_urb(pDevice->pInterruptURB);
995 goto free_rx_tx;
996 }
997
998 return TRUE;
999
1000free_rx_tx:
1001 device_free_rx_bufs(pDevice);
1002
1003free_tx:
1004 device_free_tx_bufs(pDevice);
1005
1006 return FALSE;
1007}
1008
1009
1010
1011
1012static BOOL device_init_defrag_cb(PSDevice pDevice) {
1013 int i;
1014 PSDeFragControlBlock pDeF;
1015
1016 /* Init the fragment ctl entries */
1017 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
1018 pDeF = &(pDevice->sRxDFCB[i]);
1019 if (!device_alloc_frag_buf(pDevice, pDeF)) {
1020 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
1021 pDevice->dev->name);
1022 goto free_frag;
1023 };
1024 }
1025 pDevice->cbDFCB = CB_MAX_RX_FRAG;
1026 pDevice->cbFreeDFCB = pDevice->cbDFCB;
1027 return TRUE;
1028
1029free_frag:
1030 device_free_frag_bufs(pDevice);
1031 return FALSE;
1032}
1033
1034
1035
1036static void device_free_frag_bufs(PSDevice pDevice) {
1037 PSDeFragControlBlock pDeF;
1038 int i;
1039
1040 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
1041
1042 pDeF = &(pDevice->sRxDFCB[i]);
1043
1044 if (pDeF->skb)
1045 dev_kfree_skb(pDeF->skb);
1046 }
1047}
1048
1049
1050
1051BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
1052
1053 pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1054 if (pDeF->skb == NULL)
1055 return FALSE;
1056 ASSERT(pDeF->skb);
1057 pDeF->skb->dev = pDevice->dev;
1058
1059 return TRUE;
1060}
1061
1062
1063/*-----------------------------------------------------------------*/
1064
1065static int device_open(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001066 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001067
1068#ifdef WPA_SM_Transtatus
1069 extern SWPAResult wpa_Result;
1070 memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname));
1071 wpa_Result.proto = 0;
1072 wpa_Result.key_mgmt = 0;
1073 wpa_Result.eap_type = 0;
1074 wpa_Result.authenticated = FALSE;
1075 pDevice->fWPA_Authened = FALSE;
1076#endif
1077
1078 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_open...\n");
1079
1080
1081 pDevice->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
1082
1083 if (device_alloc_bufs(pDevice) == FALSE) {
1084 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_alloc_bufs fail... \n");
1085 return -ENOMEM;
1086 }
1087
1088 if (device_init_defrag_cb(pDevice)== FALSE) {
1089 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Initial defragement cb fail \n");
1090 goto free_rx_tx;
1091 }
1092
1093 MP_CLEAR_FLAG(pDevice, fMP_DISCONNECTED);
1094 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
1095 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
1096 MP_SET_FLAG(pDevice, fMP_POST_READS);
1097 MP_SET_FLAG(pDevice, fMP_POST_WRITES);
1098
1099 //read config file
1100 Read_config_file(pDevice);
1101
1102 if (device_init_registers(pDevice, DEVICE_INIT_COLD) == FALSE) {
1103 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " init register fail\n");
1104 goto free_all;
1105 }
1106
1107 device_set_multi(pDevice->dev);
1108 // Init for Key Management
1109
1110 KeyvInitTable(pDevice,&pDevice->sKey);
Andres More9a0e7562010-04-13 21:54:48 -03001111 memcpy(pDevice->sMgmtObj.abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN);
1112 memcpy(pDevice->dev->dev_addr, pDevice->abyCurrentNetAddr, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001113 pDevice->bStopTx0Pkt = FALSE;
1114 pDevice->bStopDataPkt = FALSE;
1115 pDevice->bRoaming = FALSE; //DavidWang
1116 pDevice->bIsRoaming = FALSE;//DavidWang
1117 pDevice->bEnableRoaming = FALSE;
1118 if (pDevice->bDiversityRegCtlON) {
1119 device_init_diversity_timer(pDevice);
1120 }
1121
1122 vMgrObjectInit(pDevice);
1123 tasklet_init(&pDevice->RxMngWorkItem, (void *)RXvMngWorkItem, (unsigned long)pDevice);
1124 tasklet_init(&pDevice->ReadWorkItem, (void *)RXvWorkItem, (unsigned long)pDevice);
1125 tasklet_init(&pDevice->EventWorkItem, (void *)INTvWorkItem, (unsigned long)pDevice);
1126 add_timer(&(pDevice->sMgmtObj.sTimerSecondCallback));
Forest Bond92b96792009-06-13 07:38:31 -04001127 pDevice->int_interval = 100; //Max 100 microframes.
Forest Bond92b96792009-06-13 07:38:31 -04001128 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1129
1130 pDevice->bIsRxWorkItemQueued = TRUE;
1131 pDevice->fKillEventPollingThread = FALSE;
1132 pDevice->bEventAvailable = FALSE;
1133
1134 pDevice->bWPADEVUp = FALSE;
1135#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1136 pDevice->bwextstep0 = FALSE;
1137 pDevice->bwextstep1 = FALSE;
1138 pDevice->bwextstep2 = FALSE;
1139 pDevice->bwextstep3 = FALSE;
1140 pDevice->bWPASuppWextEnabled = FALSE;
1141#endif
1142 pDevice->byReAssocCount = 0;
1143
1144 RXvWorkItem(pDevice);
1145 INTvWorkItem(pDevice);
1146
1147 // Patch: if WEP key already set by iwconfig but device not yet open
1148 if ((pDevice->bEncryptionEnable == TRUE) && (pDevice->bTransmitKey == TRUE)) {
1149 spin_lock_irq(&pDevice->lock);
1150 KeybSetDefaultKey( pDevice,
1151 &(pDevice->sKey),
1152 pDevice->byKeyIndex | (1 << 31),
1153 pDevice->uKeyLength,
1154 NULL,
1155 pDevice->abyKey,
1156 KEY_CTL_WEP
1157 );
1158 spin_unlock_irq(&pDevice->lock);
1159 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1160 }
1161
1162 if (pDevice->sMgmtObj.eConfigMode == WMAC_CONFIG_AP) {
Andres More0cbd8d92010-05-06 20:34:29 -03001163 bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001164 }
1165 else {
1166 //mike:mark@2008-11-10
Andres More0cbd8d92010-05-06 20:34:29 -03001167 bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
1168 /* bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); */
Forest Bond92b96792009-06-13 07:38:31 -04001169 }
1170
1171
1172 netif_stop_queue(pDevice->dev);
1173 pDevice->flags |= DEVICE_FLAGS_OPENED;
1174
1175#ifdef SndEvt_ToAPI
1176{
1177 union iwreq_data wrqu;
1178 memset(&wrqu, 0, sizeof(wrqu));
1179 wrqu.data.flags = RT_UPDEV_EVENT_FLAG;
1180 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1181}
1182#endif
1183
1184 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
1185 return 0;
1186
1187free_all:
1188 device_free_frag_bufs(pDevice);
1189free_rx_tx:
1190 device_free_rx_bufs(pDevice);
1191 device_free_tx_bufs(pDevice);
1192 device_free_int_bufs(pDevice);
Jim Liebdad72fe2009-08-12 14:54:14 -07001193 usb_kill_urb(pDevice->pControlURB);
1194 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -04001195 usb_free_urb(pDevice->pControlURB);
1196 usb_free_urb(pDevice->pInterruptURB);
1197
1198 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open fail.. \n");
1199 return -ENOMEM;
1200}
1201
1202
1203
1204static int device_close(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001205 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001206 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1207
Forest Bond92b96792009-06-13 07:38:31 -04001208 int uu;
Forest Bond92b96792009-06-13 07:38:31 -04001209
1210 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close1 \n");
1211 if (pDevice == NULL)
1212 return -ENODEV;
1213
1214#ifdef SndEvt_ToAPI
1215{
1216 union iwreq_data wrqu;
1217 memset(&wrqu, 0, sizeof(wrqu));
1218 wrqu.data.flags = RT_DOWNDEV_EVENT_FLAG;
1219 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1220}
1221#endif
1222
1223//2007-1121-02<Add>by EinsnLiu
1224 if (pDevice->bLinkPass) {
Andres More0cbd8d92010-05-06 20:34:29 -03001225 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001226 mdelay(30);
1227 }
1228//End Add
1229
1230//2008-0714-01<Add>by MikeLiu
1231device_release_WPADEV(pDevice);
1232
Forest Bond92b96792009-06-13 07:38:31 -04001233 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
1234 pMgmt->bShareKeyAlgorithm = FALSE;
1235 pDevice->bEncryptionEnable = FALSE;
1236 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1237 spin_lock_irq(&pDevice->lock);
1238 for(uu=0;uu<MAX_KEY_TABLE;uu++)
1239 MACvDisableKeyEntry(pDevice,uu);
1240 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001241
1242 if ((pDevice->flags & DEVICE_FLAGS_UNPLUG) == FALSE) {
1243 MACbShutdown(pDevice);
1244 }
1245 netif_stop_queue(pDevice->dev);
1246 MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
1247 MP_CLEAR_FLAG(pDevice, fMP_POST_WRITES);
1248 MP_CLEAR_FLAG(pDevice, fMP_POST_READS);
1249 pDevice->fKillEventPollingThread = TRUE;
1250 del_timer(&pDevice->sTimerCommand);
1251 del_timer(&pMgmt->sTimerSecondCallback);
1252
1253//2007-0115-02<Add>by MikeLiu
1254#ifdef TxInSleep
1255 del_timer(&pDevice->sTimerTxData);
1256#endif
1257
1258 if (pDevice->bDiversityRegCtlON) {
1259 del_timer(&pDevice->TimerSQ3Tmax1);
1260 del_timer(&pDevice->TimerSQ3Tmax2);
1261 del_timer(&pDevice->TimerSQ3Tmax3);
1262 }
1263 tasklet_kill(&pDevice->RxMngWorkItem);
1264 tasklet_kill(&pDevice->ReadWorkItem);
1265 tasklet_kill(&pDevice->EventWorkItem);
1266
1267 pDevice->bRoaming = FALSE; //DavidWang
1268 pDevice->bIsRoaming = FALSE;//DavidWang
1269 pDevice->bEnableRoaming = FALSE;
1270 pDevice->bCmdRunning = FALSE;
1271 pDevice->bLinkPass = FALSE;
1272 memset(pMgmt->abyCurrBSSID, 0, 6);
1273 pMgmt->eCurrState = WMAC_STATE_IDLE;
1274
1275 device_free_tx_bufs(pDevice);
1276 device_free_rx_bufs(pDevice);
1277 device_free_int_bufs(pDevice);
1278 device_free_frag_bufs(pDevice);
1279
Jim Liebdad72fe2009-08-12 14:54:14 -07001280 usb_kill_urb(pDevice->pControlURB);
1281 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -04001282 usb_free_urb(pDevice->pControlURB);
1283 usb_free_urb(pDevice->pInterruptURB);
1284
1285 BSSvClearNodeDBTable(pDevice, 0);
1286 pDevice->flags &=(~DEVICE_FLAGS_OPENED);
1287
1288 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n");
1289
1290 return 0;
1291}
1292
Forest Bond92b96792009-06-13 07:38:31 -04001293
Andres More26e5b652010-04-13 19:43:07 -03001294static void __devexit vt6656_disconnect(struct usb_interface *intf)
Forest Bond92b96792009-06-13 07:38:31 -04001295{
Forest Bond92b96792009-06-13 07:38:31 -04001296
1297 PSDevice pDevice = usb_get_intfdata(intf);
Forest Bond92b96792009-06-13 07:38:31 -04001298
1299 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_disconnect1.. \n");
1300 if (pDevice == NULL)
1301 return;
1302
1303#ifdef SndEvt_ToAPI
1304{
1305 union iwreq_data wrqu;
1306 memset(&wrqu, 0, sizeof(wrqu));
1307 wrqu.data.flags = RT_RMMOD_EVENT_FLAG;
1308 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1309}
1310#endif
1311
1312//2008-0714-01<Add>by MikeLiu
1313device_release_WPADEV(pDevice);
1314
Forest Bond92b96792009-06-13 07:38:31 -04001315 usb_set_intfdata(intf, NULL);
1316//2008-0922-01<Add>by MikeLiu, decrease usb counter.
1317 usb_put_dev(interface_to_usbdev(intf));
1318
Forest Bond92b96792009-06-13 07:38:31 -04001319 pDevice->flags |= DEVICE_FLAGS_UNPLUG;
1320 if (pDevice->dev != NULL) {
1321 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "unregister_netdev..\n");
1322 unregister_netdev(pDevice->dev);
1323
1324//2008-07-21-01<Add>by MikeLiu
1325//unregister wpadev
1326 if(wpa_set_wpadev(pDevice, 0)!=0)
1327 printk("unregister wpadev fail?\n");
1328
Forest Bond92b96792009-06-13 07:38:31 -04001329 free_netdev(pDevice->dev);
Forest Bond92b96792009-06-13 07:38:31 -04001330 }
1331
Forest Bond92b96792009-06-13 07:38:31 -04001332 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_disconnect3.. \n");
1333}
1334
1335
1336
1337
1338static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001339 PSDevice pDevice=netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001340 PBYTE pbMPDU;
Andres Morecc856e62010-05-17 21:34:01 -03001341 unsigned int cbMPDULen = 0;
Forest Bond92b96792009-06-13 07:38:31 -04001342
1343
1344 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211\n");
1345 spin_lock_irq(&pDevice->lock);
1346
1347 if (pDevice->bStopTx0Pkt == TRUE) {
1348 dev_kfree_skb_irq(skb);
1349 spin_unlock_irq(&pDevice->lock);
1350 return 0;
1351 };
1352
1353
1354 cbMPDULen = skb->len;
1355 pbMPDU = skb->data;
1356
1357 vDMA0_tx_80211(pDevice, skb);
1358
1359 spin_unlock_irq(&pDevice->lock);
1360
1361 return 0;
1362
1363}
1364
1365
1366static int device_xmit(struct sk_buff *skb, struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001367 PSDevice pDevice=netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001368 struct net_device_stats* pStats = &pDevice->stats;
1369
1370
1371 spin_lock_irq(&pDevice->lock);
1372
1373 netif_stop_queue(pDevice->dev);
1374
1375 if (pDevice->bLinkPass == FALSE) {
1376 dev_kfree_skb_irq(skb);
1377 spin_unlock_irq(&pDevice->lock);
1378 return 0;
1379 }
1380 if (pDevice->bStopDataPkt == TRUE) {
1381 dev_kfree_skb_irq(skb);
1382 pStats->tx_dropped++;
1383 spin_unlock_irq(&pDevice->lock);
1384 return 0;
1385 }
1386
1387 if(nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) !=0) { //mike add:xmit fail!
1388 if (netif_queue_stopped(pDevice->dev))
1389 netif_wake_queue(pDevice->dev);
1390 }
1391
1392 spin_unlock_irq(&pDevice->lock);
1393
1394 return 0;
1395}
1396
1397
1398
1399static unsigned const ethernet_polynomial = 0x04c11db7U;
1400static inline u32 ether_crc(int length, unsigned char *data)
1401{
1402 int crc = -1;
1403
1404 while(--length >= 0) {
1405 unsigned char current_octet = *data++;
1406 int bit;
1407 for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
1408 crc = (crc << 1) ^
1409 ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
1410 }
1411 }
1412 return crc;
1413}
1414
1415//find out the start position of str2 from str1
Andres Morecc856e62010-05-17 21:34:01 -03001416static unsigned char *kstrstr(const unsigned char *str1,
1417 const unsigned char *str2) {
1418 int str1_len = strlen(str1);
1419 int str2_len = strlen(str2);
Forest Bond92b96792009-06-13 07:38:31 -04001420
1421 while (str1_len >= str2_len) {
1422 str1_len--;
1423 if(memcmp(str1,str2,str2_len)==0)
Andres Morecc856e62010-05-17 21:34:01 -03001424 return (unsigned char *) str1;
Forest Bond92b96792009-06-13 07:38:31 -04001425 str1++;
1426 }
1427 return NULL;
1428}
1429
Andres Morecc856e62010-05-17 21:34:01 -03001430static int Config_FileGetParameter(unsigned char *string,
1431 unsigned char *dest,
1432 unsigned char *source)
Forest Bond92b96792009-06-13 07:38:31 -04001433{
Andres Morecc856e62010-05-17 21:34:01 -03001434 unsigned char buf1[100];
1435 unsigned char buf2[100];
1436 unsigned char *start_p = NULL, *end_p = NULL, *tmp_p = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001437 int ii;
1438
1439 memset(buf1,0,100);
1440 strcat(buf1, string);
1441 strcat(buf1, "=");
1442 source+=strlen(buf1);
1443
1444//find target string start point
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001445 start_p = kstrstr(source,buf1);
1446 if (start_p == NULL)
Forest Bond92b96792009-06-13 07:38:31 -04001447 return FALSE;
1448
1449//check if current config line is marked by "#" ??
1450for(ii=1;;ii++) {
1451 if(memcmp(start_p-ii,"\n",1)==0)
1452 break;
1453 if(memcmp(start_p-ii,"#",1)==0)
1454 return FALSE;
1455}
1456
1457//find target string end point
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001458 end_p = kstrstr(start_p,"\n");
1459 if (end_p == NULL) { //can't find "\n",but don't care
Forest Bond92b96792009-06-13 07:38:31 -04001460 end_p=start_p+strlen(start_p); //no include "\n"
1461 }
1462
1463 memset(buf2,0,100);
1464 memcpy(buf2,start_p,end_p-start_p); //get the tartget line
1465 buf2[end_p-start_p]='\0';
1466
1467 //find value
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001468 start_p = kstrstr(buf2,"=");
1469 if (start_p == NULL)
Forest Bond92b96792009-06-13 07:38:31 -04001470 return FALSE;
1471 memset(buf1,0,100);
1472 strcpy(buf1,start_p+1);
1473
1474 //except space
1475 tmp_p = buf1;
1476 while(*tmp_p != 0x00) {
1477 if(*tmp_p==' ')
1478 tmp_p++;
1479 else
1480 break;
1481 }
1482
1483 memcpy(dest,tmp_p,strlen(tmp_p));
1484 return TRUE;
1485}
1486
1487//if read fail,return NULL,or return data pointer;
Andres Morecc856e62010-05-17 21:34:01 -03001488static unsigned char *Config_FileOperation(PSDevice pDevice)
1489{
1490 unsigned char *config_path = CONFIG_PATH;
1491 unsigned char *buffer = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001492 struct file *filp=NULL;
1493 mm_segment_t old_fs = get_fs();
Forest Bond8f9c4662009-06-13 07:38:47 -04001494 //int oldfsuid=0,oldfsgid=0;
Andres Morecc856e62010-05-17 21:34:01 -03001495 int result = 0;
Forest Bond92b96792009-06-13 07:38:31 -04001496
1497 set_fs (KERNEL_DS);
Forest Bond8f9c4662009-06-13 07:38:47 -04001498 /* Can't do this anymore, so we rely on correct filesystem permissions:
1499 //Make sure a caller can read or write power as root
1500 oldfsuid=current->fsuid;
1501 oldfsgid=current->fsgid;
Forest Bond92b96792009-06-13 07:38:31 -04001502 current->fsuid = 0;
1503 current->fsgid = 0;
Forest Bond8f9c4662009-06-13 07:38:47 -04001504 */
Forest Bond92b96792009-06-13 07:38:31 -04001505
1506 //open file
1507 filp = filp_open(config_path, O_RDWR, 0);
1508 if (IS_ERR(filp)) {
1509 printk("Config_FileOperation file Not exist\n");
1510 result=-1;
1511 goto error2;
1512 }
1513
1514 if(!(filp->f_op) || !(filp->f_op->read) ||!(filp->f_op->write)) {
1515 printk("file %s cann't readable or writable?\n",config_path);
1516 result = -1;
1517 goto error1;
1518 }
1519
Julia Lawall32414872010-05-11 20:26:57 +02001520 buffer = kmalloc(1024, GFP_KERNEL);
Forest Bond92b96792009-06-13 07:38:31 -04001521 if(buffer==NULL) {
1522 printk("alllocate mem for file fail?\n");
1523 result = -1;
1524 goto error1;
1525 }
1526
1527 if(filp->f_op->read(filp, buffer, 1024, &filp->f_pos)<0) {
1528 printk("read file error?\n");
1529 result = -1;
1530 }
1531
1532error1:
1533 if(filp_close(filp,NULL))
1534 printk("Config_FileOperation:close file fail\n");
1535
1536error2:
1537 set_fs (old_fs);
Forest Bond8f9c4662009-06-13 07:38:47 -04001538
1539 /*
Forest Bond92b96792009-06-13 07:38:31 -04001540 current->fsuid=oldfsuid;
1541 current->fsgid=oldfsgid;
Forest Bond8f9c4662009-06-13 07:38:47 -04001542 */
Forest Bond92b96792009-06-13 07:38:31 -04001543
1544if(result!=0) {
1545 if(buffer)
1546 kfree(buffer);
1547 buffer=NULL;
1548}
1549 return buffer;
1550}
1551
André Goddard Rosabbc9a992009-11-14 13:09:06 -02001552//return --->-1:fail; >=0:successful
Forest Bond92b96792009-06-13 07:38:31 -04001553static int Read_config_file(PSDevice pDevice) {
Andres Morecc856e62010-05-17 21:34:01 -03001554 int result = 0;
1555 unsigned char tmpbuffer[100];
1556 unsigned char *buffer = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001557
1558 //init config setting
1559 pDevice->config_file.ZoneType = -1;
1560 pDevice->config_file.eAuthenMode = -1;
1561 pDevice->config_file.eEncryptionStatus = -1;
1562
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001563 buffer = Config_FileOperation(pDevice);
1564 if (buffer == NULL) {
Forest Bond92b96792009-06-13 07:38:31 -04001565 result =-1;
1566 return result;
1567 }
1568
1569//get zonetype
1570{
1571 memset(tmpbuffer,0,sizeof(tmpbuffer));
1572 if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer) ==TRUE) {
1573 if(memcmp(tmpbuffer,"USA",3)==0) {
1574 pDevice->config_file.ZoneType=ZoneType_USA;
1575 }
1576 else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
1577 pDevice->config_file.ZoneType=ZoneType_Japan;
1578 }
1579 else if(memcmp(tmpbuffer,"EUROPE",6)==0) {
1580 pDevice->config_file.ZoneType=ZoneType_Europe;
1581 }
1582 else {
1583 printk("Unknown Zonetype[%s]?\n",tmpbuffer);
1584 }
1585 }
1586}
1587
1588#if 1
1589//get other parameter
1590 {
1591 memset(tmpbuffer,0,sizeof(tmpbuffer));
1592 if(Config_FileGetParameter("AUTHENMODE",tmpbuffer,buffer)==TRUE) {
1593 pDevice->config_file.eAuthenMode = (int) simple_strtol(tmpbuffer, NULL, 10);
1594 }
1595
1596 memset(tmpbuffer,0,sizeof(tmpbuffer));
1597 if(Config_FileGetParameter("ENCRYPTIONMODE",tmpbuffer,buffer)==TRUE) {
1598 pDevice->config_file.eEncryptionStatus= (int) simple_strtol(tmpbuffer, NULL, 10);
1599 }
1600 }
1601#endif
1602
1603 kfree(buffer);
1604 return result;
1605}
1606
1607static void device_set_multi(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001608 PSDevice pDevice = (PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001609 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1610 u32 mc_filter[2];
1611 int ii;
Jiri Pirkod5907942010-02-18 05:10:14 +00001612 struct dev_mc_list *mclist;
Forest Bond92b96792009-06-13 07:38:31 -04001613 BYTE pbyData[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1614 BYTE byTmpMode = 0;
1615 int rc;
1616
1617
1618 spin_lock_irq(&pDevice->lock);
1619 rc = CONTROLnsRequestIn(pDevice,
1620 MESSAGE_TYPE_READ,
1621 MAC_REG_RCR,
1622 MESSAGE_REQUEST_MACREG,
1623 1,
1624 &byTmpMode
1625 );
1626 if (rc == 0) pDevice->byRxMode = byTmpMode;
1627
1628 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode in= %x\n", pDevice->byRxMode);
1629
1630 if (dev->flags & IFF_PROMISC) { // Set promiscuous.
1631 DBG_PRT(MSG_LEVEL_ERR,KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
1632 // Unconditionally log net taps.
1633 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
1634 }
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001635 else if ((netdev_mc_count(dev) > pDevice->multicast_limit) ||
1636 (dev->flags & IFF_ALLMULTI)) {
Forest Bond92b96792009-06-13 07:38:31 -04001637 CONTROLnsRequestOut(pDevice,
1638 MESSAGE_TYPE_WRITE,
1639 MAC_REG_MAR0,
1640 MESSAGE_REQUEST_MACREG,
1641 8,
1642 pbyData
1643 );
1644 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1645 }
1646 else {
1647 memset(mc_filter, 0, sizeof(mc_filter));
Jiri Pirkod5907942010-02-18 05:10:14 +00001648 netdev_for_each_mc_addr(mclist, dev) {
Forest Bond92b96792009-06-13 07:38:31 -04001649 int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
1650 mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
1651 }
1652 for (ii = 0; ii < 4; ii++) {
1653 MACvWriteMultiAddr(pDevice, ii, *((PBYTE)&mc_filter[0] + ii));
1654 MACvWriteMultiAddr(pDevice, ii+ 4, *((PBYTE)&mc_filter[1] + ii));
1655 }
1656 pDevice->byRxMode &= ~(RCR_UNICAST);
1657 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1658 }
1659
1660 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
1661 // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac.
1662 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1663 pDevice->byRxMode &= ~(RCR_UNICAST);
1664 }
1665 ControlvWriteByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_RCR, pDevice->byRxMode);
1666 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode out= %x\n", pDevice->byRxMode);
1667 spin_unlock_irq(&pDevice->lock);
1668
1669}
1670
1671
1672static struct net_device_stats *device_get_stats(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001673 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001674
1675 return &pDevice->stats;
1676}
1677
1678
1679static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001680 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001681 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1682 PSCmdRequest pReq;
1683 //BOOL bCommit = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001684 struct iwreq *wrq = (struct iwreq *) rq;
1685 int rc =0;
Forest Bond92b96792009-06-13 07:38:31 -04001686
1687 if (pMgmt == NULL) {
1688 rc = -EFAULT;
1689 return rc;
1690 }
1691
1692 switch(cmd) {
1693
Forest Bond92b96792009-06-13 07:38:31 -04001694 case SIOCGIWNAME:
1695 rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL);
1696 break;
1697
1698 case SIOCSIWNWID:
1699 rc = -EOPNOTSUPP;
1700 break;
1701
1702 case SIOCGIWNWID: //0x8b03 support
1703 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1704 rc = iwctl_giwnwid(dev, NULL, &(wrq->u.nwid), NULL);
1705 #else
1706 rc = -EOPNOTSUPP;
1707 #endif
1708 break;
1709
1710 // Set frequency/channel
1711 case SIOCSIWFREQ:
1712 rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL);
1713 break;
1714
1715 // Get frequency/channel
1716 case SIOCGIWFREQ:
1717 rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL);
1718 break;
1719
1720 // Set desired network name (ESSID)
1721 case SIOCSIWESSID:
1722
1723 {
1724 char essid[IW_ESSID_MAX_SIZE+1];
1725 if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
1726 rc = -E2BIG;
1727 break;
1728 }
1729 if (copy_from_user(essid, wrq->u.essid.pointer,
1730 wrq->u.essid.length)) {
1731 rc = -EFAULT;
1732 break;
1733 }
1734 rc = iwctl_siwessid(dev, NULL,
1735 &(wrq->u.essid), essid);
1736 }
1737 break;
1738
1739
1740 // Get current network name (ESSID)
1741 case SIOCGIWESSID:
1742
1743 {
1744 char essid[IW_ESSID_MAX_SIZE+1];
1745 if (wrq->u.essid.pointer)
1746 rc = iwctl_giwessid(dev, NULL,
1747 &(wrq->u.essid), essid);
1748 if (copy_to_user(wrq->u.essid.pointer,
1749 essid,
1750 wrq->u.essid.length) )
1751 rc = -EFAULT;
1752 }
1753 break;
1754
1755 case SIOCSIWAP:
1756
1757 rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL);
1758 break;
1759
1760
1761 // Get current Access Point (BSSID)
1762 case SIOCGIWAP:
1763 rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL);
1764 break;
1765
1766
1767 // Set desired station name
1768 case SIOCSIWNICKN:
1769 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n");
1770 rc = -EOPNOTSUPP;
1771 break;
1772
1773 // Get current station name
1774 case SIOCGIWNICKN:
1775 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n");
1776 rc = -EOPNOTSUPP;
1777 break;
1778
1779 // Set the desired bit-rate
1780 case SIOCSIWRATE:
1781 rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL);
1782 break;
1783
1784 // Get the current bit-rate
1785 case SIOCGIWRATE:
1786
1787 rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
1788 break;
1789
1790 // Set the desired RTS threshold
1791 case SIOCSIWRTS:
1792
1793 rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL);
1794 break;
1795
1796 // Get the current RTS threshold
1797 case SIOCGIWRTS:
1798
1799 rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL);
1800 break;
1801
1802 // Set the desired fragmentation threshold
1803 case SIOCSIWFRAG:
1804
1805 rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL);
1806 break;
1807
1808 // Get the current fragmentation threshold
1809 case SIOCGIWFRAG:
1810
1811 rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL);
1812 break;
1813
1814 // Set mode of operation
1815 case SIOCSIWMODE:
1816 rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL);
1817 break;
1818
1819 // Get mode of operation
1820 case SIOCGIWMODE:
1821 rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
1822 break;
1823
1824 // Set WEP keys and mode
1825 case SIOCSIWENCODE:
1826 {
1827 char abyKey[WLAN_WEP232_KEYLEN];
1828
1829 if (wrq->u.encoding.pointer) {
1830
1831
1832 if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) {
1833 rc = -E2BIG;
1834 break;
1835 }
1836 memset(abyKey, 0, WLAN_WEP232_KEYLEN);
1837 if (copy_from_user(abyKey,
1838 wrq->u.encoding.pointer,
1839 wrq->u.encoding.length)) {
1840 rc = -EFAULT;
1841 break;
1842 }
1843 } else if (wrq->u.encoding.length != 0) {
1844 rc = -EINVAL;
1845 break;
1846 }
1847 rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey);
1848 }
1849 break;
1850
1851 // Get the WEP keys and mode
1852 case SIOCGIWENCODE:
1853
1854 if (!capable(CAP_NET_ADMIN)) {
1855 rc = -EPERM;
1856 break;
1857 }
1858 {
1859 char abyKey[WLAN_WEP232_KEYLEN];
1860
1861 rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey);
1862 if (rc != 0) break;
1863 if (wrq->u.encoding.pointer) {
1864 if (copy_to_user(wrq->u.encoding.pointer,
1865 abyKey,
1866 wrq->u.encoding.length))
1867 rc = -EFAULT;
1868 }
1869 }
1870 break;
1871
Forest Bond92b96792009-06-13 07:38:31 -04001872 // Get the current Tx-Power
1873 case SIOCGIWTXPOW:
1874 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
1875 rc = -EOPNOTSUPP;
1876 break;
1877
1878 case SIOCSIWTXPOW:
1879 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
1880 rc = -EOPNOTSUPP;
1881 break;
1882
Forest Bond92b96792009-06-13 07:38:31 -04001883 case SIOCSIWRETRY:
1884
1885 rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL);
1886 break;
1887
1888 case SIOCGIWRETRY:
1889
1890 rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL);
1891 break;
1892
Forest Bond92b96792009-06-13 07:38:31 -04001893 // Get range of parameters
1894 case SIOCGIWRANGE:
1895
1896 {
1897 struct iw_range range;
1898
1899 rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *) &range);
1900 if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
1901 rc = -EFAULT;
1902 }
1903
1904 break;
1905
1906 case SIOCGIWPOWER:
1907
1908 rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL);
1909 break;
1910
1911
1912 case SIOCSIWPOWER:
1913
1914 rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL);
1915 break;
1916
1917
1918 case SIOCGIWSENS:
1919
1920 rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL);
1921 break;
1922
1923 case SIOCSIWSENS:
1924 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n");
1925 rc = -EOPNOTSUPP;
1926 break;
1927
1928 case SIOCGIWAPLIST:
1929 {
1930 char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
1931
1932 if (wrq->u.data.pointer) {
1933 rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
1934 if (rc == 0) {
1935 if (copy_to_user(wrq->u.data.pointer,
1936 buffer,
1937 (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality)))
1938 ))
1939 rc = -EFAULT;
1940 }
1941 }
1942 }
1943 break;
1944
1945
1946#ifdef WIRELESS_SPY
1947 // Set the spy list
1948 case SIOCSIWSPY:
1949
1950 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
1951 rc = -EOPNOTSUPP;
1952 break;
1953
1954 // Get the spy list
1955 case SIOCGIWSPY:
1956
1957 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
1958 rc = -EOPNOTSUPP;
1959 break;
1960
1961#endif // WIRELESS_SPY
1962
1963 case SIOCGIWPRIV:
1964 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n");
1965 rc = -EOPNOTSUPP;
1966/*
1967 if(wrq->u.data.pointer) {
1968 wrq->u.data.length = sizeof(iwctl_private_args) / sizeof( iwctl_private_args[0]);
1969
1970 if(copy_to_user(wrq->u.data.pointer,
1971 (u_char *) iwctl_private_args,
1972 sizeof(iwctl_private_args)))
1973 rc = -EFAULT;
1974 }
1975*/
1976 break;
1977
1978
Forest Bond92b96792009-06-13 07:38:31 -04001979//2008-0409-07, <Add> by Einsn Liu
1980#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1981 case SIOCSIWAUTH:
1982 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
1983 rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
1984 break;
1985
1986 case SIOCGIWAUTH:
1987 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH \n");
1988 rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
1989 break;
1990
1991 case SIOCSIWGENIE:
1992 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE \n");
1993 rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1994 break;
1995
1996 case SIOCGIWGENIE:
1997 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE \n");
1998 rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1999 break;
2000
2001 case SIOCSIWENCODEEXT:
2002 {
2003 char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
2004 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n");
2005 if(wrq->u.encoding.pointer){
2006 memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1);
2007 if(wrq->u.encoding.length > (sizeof(struct iw_encode_ext)+ MAX_KEY_LEN)){
2008 rc = -E2BIG;
2009 break;
2010 }
2011 if(copy_from_user(extra, wrq->u.encoding.pointer,wrq->u.encoding.length)){
2012 rc = -EFAULT;
2013 break;
2014 }
2015 }else if(wrq->u.encoding.length != 0){
2016 rc = -EINVAL;
2017 break;
2018 }
2019 rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra);
2020 }
2021 break;
2022
2023 case SIOCGIWENCODEEXT:
2024 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n");
2025 rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
2026 break;
2027
2028 case SIOCSIWMLME:
2029 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME \n");
2030 rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
2031 break;
2032
2033#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
2034//End Add -- //2008-0409-07, <Add> by Einsn Liu
2035
Forest Bond92b96792009-06-13 07:38:31 -04002036 case IOCTL_CMD_TEST:
2037
2038 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
2039 rc = -EFAULT;
2040 break;
2041 } else {
2042 rc = 0;
2043 }
2044 pReq = (PSCmdRequest)rq;
2045
2046 //20080130-01,<Remark> by Mike Liu
2047 // if(pDevice->bLinkPass==TRUE)
2048 pReq->wResult = MAGIC_CODE; //Linking status:0x3142
2049 //20080130-02,<Remark> by Mike Liu
2050 // else
2051 // pReq->wResult = MAGIC_CODE+1; //disconnect status:0x3143
2052 break;
2053
2054 case IOCTL_CMD_SET:
2055 if (!(pDevice->flags & DEVICE_FLAGS_OPENED) &&
2056 (((PSCmdRequest)rq)->wCmdCode !=WLAN_CMD_SET_WPA))
2057 {
2058 rc = -EFAULT;
2059 break;
2060 } else {
2061 rc = 0;
2062 }
2063
2064 if (test_and_set_bit( 0, (void*)&(pMgmt->uCmdBusy))) {
2065 return -EBUSY;
2066 }
2067 rc = private_ioctl(pDevice, rq);
2068 clear_bit( 0, (void*)&(pMgmt->uCmdBusy));
2069 break;
2070
2071 case IOCTL_CMD_HOSTAPD:
2072
2073 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
2074 rc = -EFAULT;
2075 break;
2076 } else {
2077 rc = 0;
2078 }
2079
Forest Bondc30d7972010-04-17 11:03:38 -04002080 rc = vt6656_hostap_ioctl(pDevice, &wrq->u.data);
Forest Bond92b96792009-06-13 07:38:31 -04002081 break;
2082
2083 case IOCTL_CMD_WPA:
2084
2085 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
2086 rc = -EFAULT;
2087 break;
2088 } else {
2089 rc = 0;
2090 }
2091
Forest Bond92b96792009-06-13 07:38:31 -04002092 rc = wpa_ioctl(pDevice, &wrq->u.data);
Forest Bond92b96792009-06-13 07:38:31 -04002093 break;
2094
2095 case SIOCETHTOOL:
2096 return ethtool_ioctl(dev, (void *) rq->ifr_data);
2097 // All other calls are currently unsupported
2098
2099 default:
2100 rc = -EOPNOTSUPP;
2101 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd);
2102
2103
2104 }
2105
2106 if (pDevice->bCommit) {
2107 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2108 netif_stop_queue(pDevice->dev);
2109 spin_lock_irq(&pDevice->lock);
Andres More0cbd8d92010-05-06 20:34:29 -03002110 bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002111 spin_unlock_irq(&pDevice->lock);
2112 }
2113 else {
2114 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
2115 spin_lock_irq(&pDevice->lock);
2116//2007-1121-01<Modify>by EinsnLiu
Andres More0cbd8d92010-05-06 20:34:29 -03002117 if (pDevice->bLinkPass &&
Forest Bond92b96792009-06-13 07:38:31 -04002118 memcmp(pMgmt->abyCurrSSID,pMgmt->abyDesireSSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN)) {
Andres More0cbd8d92010-05-06 20:34:29 -03002119 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002120 } else {
2121 pDevice->bLinkPass = FALSE;
2122 pMgmt->eCurrState = WMAC_STATE_IDLE;
2123 memset(pMgmt->abyCurrBSSID, 0, 6);
2124 }
2125 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
2126//End Modify
2127 netif_stop_queue(pDevice->dev);
2128#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
2129 pMgmt->eScanType = WMAC_SCAN_ACTIVE;
Andres More0cbd8d92010-05-06 20:34:29 -03002130 if (!pDevice->bWPASuppWextEnabled)
Forest Bond92b96792009-06-13 07:38:31 -04002131#endif
Andres More0cbd8d92010-05-06 20:34:29 -03002132 bScheduleCommand((void *) pDevice,
2133 WLAN_CMD_BSSID_SCAN,
2134 pMgmt->abyDesireSSID);
2135 bScheduleCommand((void *) pDevice,
2136 WLAN_CMD_SSID,
2137 NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002138 spin_unlock_irq(&pDevice->lock);
2139 }
2140 pDevice->bCommit = FALSE;
2141 }
2142
2143
2144 return rc;
2145}
2146
2147
2148static int ethtool_ioctl(struct net_device *dev, void *useraddr)
2149{
2150 u32 ethcmd;
2151
2152 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
2153 return -EFAULT;
2154
2155 switch (ethcmd) {
2156 case ETHTOOL_GDRVINFO: {
2157 struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
2158 strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
2159 strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
2160 if (copy_to_user(useraddr, &info, sizeof(info)))
2161 return -EFAULT;
2162 return 0;
2163 }
2164
2165 }
2166
2167 return -EOPNOTSUPP;
2168}
2169
2170
2171/*------------------------------------------------------------------*/
2172
Andres More26e5b652010-04-13 19:43:07 -03002173MODULE_DEVICE_TABLE(usb, vt6656_table);
Forest Bond92b96792009-06-13 07:38:31 -04002174
Andres More26e5b652010-04-13 19:43:07 -03002175static struct usb_driver vt6656_driver = {
2176 .name = DEVICE_NAME,
2177 .probe = vt6656_probe,
2178 .disconnect = vt6656_disconnect,
2179 .id_table = vt6656_table,
Forest Bond92b96792009-06-13 07:38:31 -04002180#ifdef CONFIG_PM
Andres More26e5b652010-04-13 19:43:07 -03002181 .suspend = vt6656_suspend,
2182 .resume = vt6656_resume,
2183#endif /* CONFIG_PM */
Forest Bond92b96792009-06-13 07:38:31 -04002184};
2185
Andres More26e5b652010-04-13 19:43:07 -03002186static int __init vt6656_init_module(void)
Forest Bond92b96792009-06-13 07:38:31 -04002187{
Forest Bondf4a8df92009-06-13 07:38:56 -04002188 printk(KERN_NOTICE DEVICE_FULL_DRV_NAM " " DEVICE_VERSION);
Andres More26e5b652010-04-13 19:43:07 -03002189 return usb_register(&vt6656_driver);
Forest Bond92b96792009-06-13 07:38:31 -04002190}
2191
Andres More26e5b652010-04-13 19:43:07 -03002192static void __exit vt6656_cleanup_module(void)
Forest Bond92b96792009-06-13 07:38:31 -04002193{
Andres More26e5b652010-04-13 19:43:07 -03002194 usb_deregister(&vt6656_driver);
Forest Bond92b96792009-06-13 07:38:31 -04002195}
2196
Andres More26e5b652010-04-13 19:43:07 -03002197module_init(vt6656_init_module);
2198module_exit(vt6656_cleanup_module);