blob: 6a04245e9ed3f042baa70279bbb983c7c43ec59f [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;
Andres More33d33e422010-05-19 23:50:00 -0300410 for (ii = 0; ii < 6; ii++)
411 sInitCmd.bySWNetAddr[ii] = pDevice->abyCurrentNetAddr[ii];
Forest Bond92b96792009-06-13 07:38:31 -0400412 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)) {
Andres More33d33e422010-05-19 23:50:00 -0300490 for (ii = 11; ii < 14; ii++) {
491 pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
492 pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
493 }
Forest Bond92b96792009-06-13 07:38:31 -0400494 }
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{
Andres Moree54d9eb2010-06-21 15:35:43 -0300721 PSDevice device = usb_get_intfdata(intf);
Forest Bond92b96792009-06-13 07:38:31 -0400722
Andres Moree54d9eb2010-06-21 15:35:43 -0300723 if (!device || !device->dev)
724 return -ENODEV;
Forest Bond92b96792009-06-13 07:38:31 -0400725
Andres Moree54d9eb2010-06-21 15:35:43 -0300726 if (device->flags & DEVICE_FLAGS_OPENED)
727 device_close(device->dev);
728
729 usb_put_dev(interface_to_usbdev(intf));
730
731 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400732}
733
Andres More26e5b652010-04-13 19:43:07 -0300734static int vt6656_resume(struct usb_interface *intf)
Forest Bond92b96792009-06-13 07:38:31 -0400735{
Andres Moree54d9eb2010-06-21 15:35:43 -0300736 PSDevice device = usb_get_intfdata(intf);
Forest Bond92b96792009-06-13 07:38:31 -0400737
Andres Moree54d9eb2010-06-21 15:35:43 -0300738 if (!device || !device->dev)
739 return -ENODEV;
740
741 usb_get_dev(interface_to_usbdev(intf));
742
743 if (!(device->flags & DEVICE_FLAGS_OPENED))
744 device_open(device->dev);
745
746 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400747}
Forest Bond92b96792009-06-13 07:38:31 -0400748
Andres More26e5b652010-04-13 19:43:07 -0300749#endif /* CONFIG_PM */
Forest Bonddd8db702009-06-13 07:38:54 -0400750
751static const struct net_device_ops device_netdev_ops = {
752 .ndo_open = device_open,
753 .ndo_stop = device_close,
754 .ndo_do_ioctl = device_ioctl,
755 .ndo_get_stats = device_get_stats,
756 .ndo_start_xmit = device_xmit,
757 .ndo_set_multicast_list = device_set_multi,
758};
759
760
Andres More26e5b652010-04-13 19:43:07 -0300761static int __devinit
762vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
Forest Bond92b96792009-06-13 07:38:31 -0400763{
Andres More9a0e7562010-04-13 21:54:48 -0300764 u8 fake_mac[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
Forest Bond92b96792009-06-13 07:38:31 -0400765 struct usb_device *udev = interface_to_usbdev(intf);
766 int rc = 0;
Forest Bond92b96792009-06-13 07:38:31 -0400767 struct net_device *netdev = NULL;
768 PSDevice pDevice = NULL;
769
770
771 printk(KERN_NOTICE "%s Ver. %s\n",DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
772 printk(KERN_NOTICE "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
773
Forest Bond92b96792009-06-13 07:38:31 -0400774 udev = usb_get_dev(udev);
Forest Bond92b96792009-06-13 07:38:31 -0400775
Forest Bond1e28efa2009-06-13 07:38:50 -0400776 netdev = alloc_etherdev(sizeof(DEVICE_INFO));
Forest Bond92b96792009-06-13 07:38:31 -0400777
778 if (netdev == NULL) {
779 printk(KERN_ERR DEVICE_NAME ": allocate net device failed \n");
780 kfree(pDevice);
781 goto err_nomem;
782 }
Forest Bond1e28efa2009-06-13 07:38:50 -0400783
784 pDevice = netdev_priv(netdev);
785 memset(pDevice, 0, sizeof(DEVICE_INFO));
786
Forest Bond92b96792009-06-13 07:38:31 -0400787 pDevice->dev = netdev;
788 pDevice->usb = udev;
789
Forest Bond92b96792009-06-13 07:38:31 -0400790 // Set initial settings
791 device_set_options(pDevice);
792 spin_lock_init(&pDevice->lock);
793
794 pDevice->tx_80211 = device_dma0_tx_80211;
Andres More8611a292010-05-01 14:25:00 -0300795 pDevice->sMgmtObj.pAdapter = (void *)pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400796
Forest Bonddd8db702009-06-13 07:38:54 -0400797 netdev->netdev_ops = &device_netdev_ops;
798
Forest Bond92b96792009-06-13 07:38:31 -0400799 netdev->wireless_handlers = (struct iw_handler_def *)&iwctl_handler_def;
Forest Bond92b96792009-06-13 07:38:31 -0400800
Forest Bond92b96792009-06-13 07:38:31 -0400801 //2008-0623-01<Remark>by MikeLiu
802 //2007-0821-01<Add>by MikeLiu
Forest Bond92b96792009-06-13 07:38:31 -0400803 usb_set_intfdata(intf, pDevice);
804 SET_NETDEV_DEV(netdev, &intf->dev);
Andres More9a0e7562010-04-13 21:54:48 -0300805 memcpy(pDevice->dev->dev_addr, fake_mac, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400806 rc = register_netdev(netdev);
807 if (rc != 0) {
808 printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
809 free_netdev(netdev);
810 kfree(pDevice);
811 return -ENODEV;
812 }
Forest Bond92b96792009-06-13 07:38:31 -0400813
Forest Bond92b96792009-06-13 07:38:31 -0400814 usb_device_reset(pDevice);
Forest Bond92b96792009-06-13 07:38:31 -0400815
816#ifdef SndEvt_ToAPI
817{
818 union iwreq_data wrqu;
819 memset(&wrqu, 0, sizeof(wrqu));
820 wrqu.data.flags = RT_INSMOD_EVENT_FLAG;
821 wrqu.data.length =IFNAMSIZ;
822 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pDevice->dev->name);
823}
824#endif
825
826 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400827
828
829err_nomem:
Forest Bond92b96792009-06-13 07:38:31 -0400830 //2008-0922-01<Add>by MikeLiu, decrease usb counter.
831 usb_put_dev(udev);
832
833 return -ENOMEM;
Forest Bond92b96792009-06-13 07:38:31 -0400834}
835
836
Andres More8611a292010-05-01 14:25:00 -0300837static void device_free_tx_bufs(PSDevice pDevice)
838{
Forest Bond92b96792009-06-13 07:38:31 -0400839 PUSB_SEND_CONTEXT pTxContext;
840 int ii;
841
842 for (ii = 0; ii < pDevice->cbTD; ii++) {
843
844 pTxContext = pDevice->apTD[ii];
845 //de-allocate URBs
846 if (pTxContext->pUrb) {
Jim Liebdad72fe2009-08-12 14:54:14 -0700847 usb_kill_urb(pTxContext->pUrb);
Forest Bond92b96792009-06-13 07:38:31 -0400848 usb_free_urb(pTxContext->pUrb);
849 }
850 if (pTxContext)
851 kfree(pTxContext);
852 }
853 return;
854}
855
856
Andres More8611a292010-05-01 14:25:00 -0300857static void device_free_rx_bufs(PSDevice pDevice)
858{
Forest Bond92b96792009-06-13 07:38:31 -0400859 PRCB pRCB;
860 int ii;
861
862 for (ii = 0; ii < pDevice->cbRD; ii++) {
863
864 pRCB = pDevice->apRCB[ii];
865 //de-allocate URBs
866 if (pRCB->pUrb) {
Jim Liebdad72fe2009-08-12 14:54:14 -0700867 usb_kill_urb(pRCB->pUrb);
Forest Bond92b96792009-06-13 07:38:31 -0400868 usb_free_urb(pRCB->pUrb);
869 }
870 //de-allocate skb
871 if (pRCB->skb)
872 dev_kfree_skb(pRCB->skb);
873 }
874 if (pDevice->pRCBMem)
875 kfree(pDevice->pRCBMem);
876
877 return;
878}
879
880//2007-1107-02<Add>by MikeLiu
Forest Bond92b96792009-06-13 07:38:31 -0400881static void usb_device_reset(PSDevice pDevice)
882{
883 int status;
884 status = usb_reset_device(pDevice->usb);
885 if (status)
886 printk("usb_device_reset fail status=%d\n",status);
887 return ;
888}
Forest Bond92b96792009-06-13 07:38:31 -0400889
Andres More8611a292010-05-01 14:25:00 -0300890static void device_free_int_bufs(PSDevice pDevice)
891{
Forest Bond92b96792009-06-13 07:38:31 -0400892 if (pDevice->intBuf.pDataBuf != NULL)
893 kfree(pDevice->intBuf.pDataBuf);
894 return;
895}
896
897
898static BOOL device_alloc_bufs(PSDevice pDevice) {
899
900 PUSB_SEND_CONTEXT pTxContext;
901 PRCB pRCB;
902 int ii;
903
904
905 for (ii = 0; ii < pDevice->cbTD; ii++) {
906
907 pTxContext = kmalloc(sizeof(USB_SEND_CONTEXT), GFP_KERNEL);
908 if (pTxContext == NULL) {
909 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : allocate tx usb context failed\n", pDevice->dev->name);
910 goto free_tx;
911 }
912 pDevice->apTD[ii] = pTxContext;
Andres More8611a292010-05-01 14:25:00 -0300913 pTxContext->pDevice = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400914 //allocate URBs
Jim Liebdad72fe2009-08-12 14:54:14 -0700915 pTxContext->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400916 if (pTxContext->pUrb == NULL) {
917 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "alloc tx urb failed\n");
918 goto free_tx;
919 }
920 pTxContext->bBoolInUse = FALSE;
921 }
922
923 // allocate rcb mem
924 pDevice->pRCBMem = kmalloc((sizeof(RCB) * pDevice->cbRD), GFP_KERNEL);
925 if (pDevice->pRCBMem == NULL) {
926 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : alloc rx usb context failed\n", pDevice->dev->name);
927 goto free_tx;
928 }
929
930
931 pDevice->FirstRecvFreeList = NULL;
932 pDevice->LastRecvFreeList = NULL;
933 pDevice->FirstRecvMngList = NULL;
934 pDevice->LastRecvMngList = NULL;
935 pDevice->NumRecvFreeList = 0;
936 memset(pDevice->pRCBMem, 0, (sizeof(RCB) * pDevice->cbRD));
937 pRCB = (PRCB) pDevice->pRCBMem;
938
939 for (ii = 0; ii < pDevice->cbRD; ii++) {
940
941 pDevice->apRCB[ii] = pRCB;
Andres More8611a292010-05-01 14:25:00 -0300942 pRCB->pDevice = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400943 //allocate URBs
Jim Liebdad72fe2009-08-12 14:54:14 -0700944 pRCB->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400945
946 if (pRCB->pUrb == NULL) {
947 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx urb\n");
948 goto free_rx_tx;
949 }
950 pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
951 if (pRCB->skb == NULL) {
952 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx skb\n");
953 goto free_rx_tx;
954 }
955 pRCB->skb->dev = pDevice->dev;
956 pRCB->bBoolInUse = FALSE;
957 EnqueueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList, pRCB);
958 pDevice->NumRecvFreeList++;
959 pRCB++;
960 }
961
962
Jim Liebdad72fe2009-08-12 14:54:14 -0700963 pDevice->pControlURB = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400964 if (pDevice->pControlURB == NULL) {
965 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc control urb\n");
966 goto free_rx_tx;
967 }
968
Jim Liebdad72fe2009-08-12 14:54:14 -0700969 pDevice->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400970 if (pDevice->pInterruptURB == NULL) {
971 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int urb\n");
Jim Liebdad72fe2009-08-12 14:54:14 -0700972 usb_kill_urb(pDevice->pControlURB);
Forest Bond92b96792009-06-13 07:38:31 -0400973 usb_free_urb(pDevice->pControlURB);
974 goto free_rx_tx;
975 }
976
977 pDevice->intBuf.pDataBuf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
978 if (pDevice->intBuf.pDataBuf == NULL) {
979 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int buf\n");
Jim Liebdad72fe2009-08-12 14:54:14 -0700980 usb_kill_urb(pDevice->pControlURB);
981 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -0400982 usb_free_urb(pDevice->pControlURB);
983 usb_free_urb(pDevice->pInterruptURB);
984 goto free_rx_tx;
985 }
986
987 return TRUE;
988
989free_rx_tx:
990 device_free_rx_bufs(pDevice);
991
992free_tx:
993 device_free_tx_bufs(pDevice);
994
995 return FALSE;
996}
997
998
999
1000
1001static BOOL device_init_defrag_cb(PSDevice pDevice) {
1002 int i;
1003 PSDeFragControlBlock pDeF;
1004
1005 /* Init the fragment ctl entries */
1006 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
1007 pDeF = &(pDevice->sRxDFCB[i]);
1008 if (!device_alloc_frag_buf(pDevice, pDeF)) {
1009 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
1010 pDevice->dev->name);
1011 goto free_frag;
1012 };
1013 }
1014 pDevice->cbDFCB = CB_MAX_RX_FRAG;
1015 pDevice->cbFreeDFCB = pDevice->cbDFCB;
1016 return TRUE;
1017
1018free_frag:
1019 device_free_frag_bufs(pDevice);
1020 return FALSE;
1021}
1022
1023
1024
1025static void device_free_frag_bufs(PSDevice pDevice) {
1026 PSDeFragControlBlock pDeF;
1027 int i;
1028
1029 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
1030
1031 pDeF = &(pDevice->sRxDFCB[i]);
1032
1033 if (pDeF->skb)
1034 dev_kfree_skb(pDeF->skb);
1035 }
1036}
1037
1038
1039
1040BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
1041
1042 pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1043 if (pDeF->skb == NULL)
1044 return FALSE;
1045 ASSERT(pDeF->skb);
1046 pDeF->skb->dev = pDevice->dev;
1047
1048 return TRUE;
1049}
1050
1051
1052/*-----------------------------------------------------------------*/
1053
1054static int device_open(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001055 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001056
1057#ifdef WPA_SM_Transtatus
1058 extern SWPAResult wpa_Result;
1059 memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname));
1060 wpa_Result.proto = 0;
1061 wpa_Result.key_mgmt = 0;
1062 wpa_Result.eap_type = 0;
1063 wpa_Result.authenticated = FALSE;
1064 pDevice->fWPA_Authened = FALSE;
1065#endif
1066
1067 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_open...\n");
1068
1069
1070 pDevice->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
1071
1072 if (device_alloc_bufs(pDevice) == FALSE) {
1073 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_alloc_bufs fail... \n");
1074 return -ENOMEM;
1075 }
1076
1077 if (device_init_defrag_cb(pDevice)== FALSE) {
1078 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Initial defragement cb fail \n");
1079 goto free_rx_tx;
1080 }
1081
1082 MP_CLEAR_FLAG(pDevice, fMP_DISCONNECTED);
1083 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
1084 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
1085 MP_SET_FLAG(pDevice, fMP_POST_READS);
1086 MP_SET_FLAG(pDevice, fMP_POST_WRITES);
1087
1088 //read config file
1089 Read_config_file(pDevice);
1090
1091 if (device_init_registers(pDevice, DEVICE_INIT_COLD) == FALSE) {
1092 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " init register fail\n");
1093 goto free_all;
1094 }
1095
1096 device_set_multi(pDevice->dev);
1097 // Init for Key Management
1098
1099 KeyvInitTable(pDevice,&pDevice->sKey);
Andres More9a0e7562010-04-13 21:54:48 -03001100 memcpy(pDevice->sMgmtObj.abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN);
1101 memcpy(pDevice->dev->dev_addr, pDevice->abyCurrentNetAddr, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001102 pDevice->bStopTx0Pkt = FALSE;
1103 pDevice->bStopDataPkt = FALSE;
1104 pDevice->bRoaming = FALSE; //DavidWang
1105 pDevice->bIsRoaming = FALSE;//DavidWang
1106 pDevice->bEnableRoaming = FALSE;
1107 if (pDevice->bDiversityRegCtlON) {
1108 device_init_diversity_timer(pDevice);
1109 }
1110
1111 vMgrObjectInit(pDevice);
1112 tasklet_init(&pDevice->RxMngWorkItem, (void *)RXvMngWorkItem, (unsigned long)pDevice);
1113 tasklet_init(&pDevice->ReadWorkItem, (void *)RXvWorkItem, (unsigned long)pDevice);
1114 tasklet_init(&pDevice->EventWorkItem, (void *)INTvWorkItem, (unsigned long)pDevice);
1115 add_timer(&(pDevice->sMgmtObj.sTimerSecondCallback));
Forest Bond92b96792009-06-13 07:38:31 -04001116 pDevice->int_interval = 100; //Max 100 microframes.
Forest Bond92b96792009-06-13 07:38:31 -04001117 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1118
1119 pDevice->bIsRxWorkItemQueued = TRUE;
1120 pDevice->fKillEventPollingThread = FALSE;
1121 pDevice->bEventAvailable = FALSE;
1122
1123 pDevice->bWPADEVUp = FALSE;
1124#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1125 pDevice->bwextstep0 = FALSE;
1126 pDevice->bwextstep1 = FALSE;
1127 pDevice->bwextstep2 = FALSE;
1128 pDevice->bwextstep3 = FALSE;
1129 pDevice->bWPASuppWextEnabled = FALSE;
1130#endif
1131 pDevice->byReAssocCount = 0;
1132
1133 RXvWorkItem(pDevice);
1134 INTvWorkItem(pDevice);
1135
1136 // Patch: if WEP key already set by iwconfig but device not yet open
1137 if ((pDevice->bEncryptionEnable == TRUE) && (pDevice->bTransmitKey == TRUE)) {
1138 spin_lock_irq(&pDevice->lock);
1139 KeybSetDefaultKey( pDevice,
1140 &(pDevice->sKey),
1141 pDevice->byKeyIndex | (1 << 31),
1142 pDevice->uKeyLength,
1143 NULL,
1144 pDevice->abyKey,
1145 KEY_CTL_WEP
1146 );
1147 spin_unlock_irq(&pDevice->lock);
1148 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1149 }
1150
1151 if (pDevice->sMgmtObj.eConfigMode == WMAC_CONFIG_AP) {
Andres More0cbd8d92010-05-06 20:34:29 -03001152 bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001153 }
1154 else {
1155 //mike:mark@2008-11-10
Andres More0cbd8d92010-05-06 20:34:29 -03001156 bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
1157 /* bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); */
Forest Bond92b96792009-06-13 07:38:31 -04001158 }
1159
1160
1161 netif_stop_queue(pDevice->dev);
1162 pDevice->flags |= DEVICE_FLAGS_OPENED;
1163
1164#ifdef SndEvt_ToAPI
1165{
1166 union iwreq_data wrqu;
1167 memset(&wrqu, 0, sizeof(wrqu));
1168 wrqu.data.flags = RT_UPDEV_EVENT_FLAG;
1169 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1170}
1171#endif
1172
1173 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
1174 return 0;
1175
1176free_all:
1177 device_free_frag_bufs(pDevice);
1178free_rx_tx:
1179 device_free_rx_bufs(pDevice);
1180 device_free_tx_bufs(pDevice);
1181 device_free_int_bufs(pDevice);
Jim Liebdad72fe2009-08-12 14:54:14 -07001182 usb_kill_urb(pDevice->pControlURB);
1183 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -04001184 usb_free_urb(pDevice->pControlURB);
1185 usb_free_urb(pDevice->pInterruptURB);
1186
1187 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open fail.. \n");
1188 return -ENOMEM;
1189}
1190
1191
1192
1193static int device_close(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001194 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001195 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1196
Forest Bond92b96792009-06-13 07:38:31 -04001197 int uu;
Forest Bond92b96792009-06-13 07:38:31 -04001198
1199 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close1 \n");
1200 if (pDevice == NULL)
1201 return -ENODEV;
1202
1203#ifdef SndEvt_ToAPI
1204{
1205 union iwreq_data wrqu;
1206 memset(&wrqu, 0, sizeof(wrqu));
1207 wrqu.data.flags = RT_DOWNDEV_EVENT_FLAG;
1208 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1209}
1210#endif
1211
1212//2007-1121-02<Add>by EinsnLiu
1213 if (pDevice->bLinkPass) {
Andres More0cbd8d92010-05-06 20:34:29 -03001214 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001215 mdelay(30);
1216 }
1217//End Add
1218
1219//2008-0714-01<Add>by MikeLiu
1220device_release_WPADEV(pDevice);
1221
Forest Bond92b96792009-06-13 07:38:31 -04001222 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
1223 pMgmt->bShareKeyAlgorithm = FALSE;
1224 pDevice->bEncryptionEnable = FALSE;
1225 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
Andres More33d33e422010-05-19 23:50:00 -03001226 spin_lock_irq(&pDevice->lock);
1227 for (uu = 0; uu < MAX_KEY_TABLE; uu++)
Forest Bond92b96792009-06-13 07:38:31 -04001228 MACvDisableKeyEntry(pDevice,uu);
Andres More33d33e422010-05-19 23:50:00 -03001229 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001230
1231 if ((pDevice->flags & DEVICE_FLAGS_UNPLUG) == FALSE) {
1232 MACbShutdown(pDevice);
1233 }
1234 netif_stop_queue(pDevice->dev);
1235 MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
1236 MP_CLEAR_FLAG(pDevice, fMP_POST_WRITES);
1237 MP_CLEAR_FLAG(pDevice, fMP_POST_READS);
1238 pDevice->fKillEventPollingThread = TRUE;
1239 del_timer(&pDevice->sTimerCommand);
1240 del_timer(&pMgmt->sTimerSecondCallback);
1241
1242//2007-0115-02<Add>by MikeLiu
1243#ifdef TxInSleep
1244 del_timer(&pDevice->sTimerTxData);
1245#endif
1246
1247 if (pDevice->bDiversityRegCtlON) {
1248 del_timer(&pDevice->TimerSQ3Tmax1);
1249 del_timer(&pDevice->TimerSQ3Tmax2);
1250 del_timer(&pDevice->TimerSQ3Tmax3);
1251 }
1252 tasklet_kill(&pDevice->RxMngWorkItem);
1253 tasklet_kill(&pDevice->ReadWorkItem);
1254 tasklet_kill(&pDevice->EventWorkItem);
1255
1256 pDevice->bRoaming = FALSE; //DavidWang
1257 pDevice->bIsRoaming = FALSE;//DavidWang
1258 pDevice->bEnableRoaming = FALSE;
1259 pDevice->bCmdRunning = FALSE;
1260 pDevice->bLinkPass = FALSE;
1261 memset(pMgmt->abyCurrBSSID, 0, 6);
1262 pMgmt->eCurrState = WMAC_STATE_IDLE;
1263
1264 device_free_tx_bufs(pDevice);
1265 device_free_rx_bufs(pDevice);
1266 device_free_int_bufs(pDevice);
1267 device_free_frag_bufs(pDevice);
1268
Jim Liebdad72fe2009-08-12 14:54:14 -07001269 usb_kill_urb(pDevice->pControlURB);
1270 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -04001271 usb_free_urb(pDevice->pControlURB);
1272 usb_free_urb(pDevice->pInterruptURB);
1273
1274 BSSvClearNodeDBTable(pDevice, 0);
1275 pDevice->flags &=(~DEVICE_FLAGS_OPENED);
1276
1277 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n");
1278
1279 return 0;
1280}
1281
Andres More26e5b652010-04-13 19:43:07 -03001282static void __devexit vt6656_disconnect(struct usb_interface *intf)
Forest Bond92b96792009-06-13 07:38:31 -04001283{
Andres More6cda24f2010-06-22 20:43:39 -03001284 PSDevice device = usb_get_intfdata(intf);
Forest Bond92b96792009-06-13 07:38:31 -04001285
Andres More6cda24f2010-06-22 20:43:39 -03001286 if (!device)
1287 return;
Forest Bond92b96792009-06-13 07:38:31 -04001288
1289#ifdef SndEvt_ToAPI
Andres More6cda24f2010-06-22 20:43:39 -03001290 {
1291 union iwreq_data req;
1292 memset(&req, 0, sizeof(req));
1293 req.data.flags = RT_RMMOD_EVENT_FLAG;
1294 wireless_send_event(device->dev, IWEVCUSTOM, &req, NULL);
1295 }
Forest Bond92b96792009-06-13 07:38:31 -04001296#endif
1297
Andres More6cda24f2010-06-22 20:43:39 -03001298 device_release_WPADEV(device);
Forest Bond92b96792009-06-13 07:38:31 -04001299
Forest Bond92b96792009-06-13 07:38:31 -04001300 usb_set_intfdata(intf, NULL);
Andres More6cda24f2010-06-22 20:43:39 -03001301 usb_put_dev(interface_to_usbdev(intf));
Forest Bond92b96792009-06-13 07:38:31 -04001302
Andres More6cda24f2010-06-22 20:43:39 -03001303 device->flags |= DEVICE_FLAGS_UNPLUG;
Forest Bond92b96792009-06-13 07:38:31 -04001304
Andres More6cda24f2010-06-22 20:43:39 -03001305 if (device->dev) {
1306 unregister_netdev(device->dev);
1307 wpa_set_wpadev(device, 0);
1308 free_netdev(device->dev);
1309 }
Forest Bond92b96792009-06-13 07:38:31 -04001310}
1311
Forest Bond92b96792009-06-13 07:38:31 -04001312static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001313 PSDevice pDevice=netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001314 PBYTE pbMPDU;
Andres Morecc856e62010-05-17 21:34:01 -03001315 unsigned int cbMPDULen = 0;
Forest Bond92b96792009-06-13 07:38:31 -04001316
1317
1318 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211\n");
1319 spin_lock_irq(&pDevice->lock);
1320
1321 if (pDevice->bStopTx0Pkt == TRUE) {
1322 dev_kfree_skb_irq(skb);
1323 spin_unlock_irq(&pDevice->lock);
1324 return 0;
1325 };
1326
1327
1328 cbMPDULen = skb->len;
1329 pbMPDU = skb->data;
1330
1331 vDMA0_tx_80211(pDevice, skb);
1332
1333 spin_unlock_irq(&pDevice->lock);
1334
1335 return 0;
1336
1337}
1338
1339
1340static int device_xmit(struct sk_buff *skb, struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001341 PSDevice pDevice=netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001342 struct net_device_stats* pStats = &pDevice->stats;
1343
1344
1345 spin_lock_irq(&pDevice->lock);
1346
1347 netif_stop_queue(pDevice->dev);
1348
1349 if (pDevice->bLinkPass == FALSE) {
1350 dev_kfree_skb_irq(skb);
1351 spin_unlock_irq(&pDevice->lock);
1352 return 0;
1353 }
1354 if (pDevice->bStopDataPkt == TRUE) {
1355 dev_kfree_skb_irq(skb);
1356 pStats->tx_dropped++;
1357 spin_unlock_irq(&pDevice->lock);
1358 return 0;
1359 }
1360
1361 if(nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) !=0) { //mike add:xmit fail!
1362 if (netif_queue_stopped(pDevice->dev))
1363 netif_wake_queue(pDevice->dev);
1364 }
1365
1366 spin_unlock_irq(&pDevice->lock);
1367
1368 return 0;
1369}
1370
1371
1372
1373static unsigned const ethernet_polynomial = 0x04c11db7U;
1374static inline u32 ether_crc(int length, unsigned char *data)
1375{
1376 int crc = -1;
1377
1378 while(--length >= 0) {
1379 unsigned char current_octet = *data++;
1380 int bit;
1381 for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
1382 crc = (crc << 1) ^
1383 ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
1384 }
1385 }
1386 return crc;
1387}
1388
1389//find out the start position of str2 from str1
Andres Morecc856e62010-05-17 21:34:01 -03001390static unsigned char *kstrstr(const unsigned char *str1,
1391 const unsigned char *str2) {
1392 int str1_len = strlen(str1);
1393 int str2_len = strlen(str2);
Forest Bond92b96792009-06-13 07:38:31 -04001394
1395 while (str1_len >= str2_len) {
1396 str1_len--;
1397 if(memcmp(str1,str2,str2_len)==0)
Andres Morecc856e62010-05-17 21:34:01 -03001398 return (unsigned char *) str1;
Forest Bond92b96792009-06-13 07:38:31 -04001399 str1++;
1400 }
1401 return NULL;
1402}
1403
Andres Morecc856e62010-05-17 21:34:01 -03001404static int Config_FileGetParameter(unsigned char *string,
1405 unsigned char *dest,
1406 unsigned char *source)
Forest Bond92b96792009-06-13 07:38:31 -04001407{
Andres Morecc856e62010-05-17 21:34:01 -03001408 unsigned char buf1[100];
1409 unsigned char buf2[100];
1410 unsigned char *start_p = NULL, *end_p = NULL, *tmp_p = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001411 int ii;
1412
1413 memset(buf1,0,100);
1414 strcat(buf1, string);
1415 strcat(buf1, "=");
1416 source+=strlen(buf1);
1417
1418//find target string start point
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001419 start_p = kstrstr(source,buf1);
1420 if (start_p == NULL)
Forest Bond92b96792009-06-13 07:38:31 -04001421 return FALSE;
1422
1423//check if current config line is marked by "#" ??
Andres More33d33e422010-05-19 23:50:00 -03001424 for (ii = 1; ; ii++) {
1425 if (memcmp(start_p - ii, "\n", 1) == 0)
1426 break;
1427 if (memcmp(start_p - ii, "#", 1) == 0)
1428 return FALSE;
1429 }
Forest Bond92b96792009-06-13 07:38:31 -04001430
1431//find target string end point
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001432 end_p = kstrstr(start_p,"\n");
1433 if (end_p == NULL) { //can't find "\n",but don't care
Forest Bond92b96792009-06-13 07:38:31 -04001434 end_p=start_p+strlen(start_p); //no include "\n"
1435 }
1436
1437 memset(buf2,0,100);
1438 memcpy(buf2,start_p,end_p-start_p); //get the tartget line
1439 buf2[end_p-start_p]='\0';
1440
1441 //find value
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001442 start_p = kstrstr(buf2,"=");
1443 if (start_p == NULL)
Forest Bond92b96792009-06-13 07:38:31 -04001444 return FALSE;
1445 memset(buf1,0,100);
1446 strcpy(buf1,start_p+1);
1447
1448 //except space
1449 tmp_p = buf1;
1450 while(*tmp_p != 0x00) {
1451 if(*tmp_p==' ')
1452 tmp_p++;
1453 else
1454 break;
1455 }
1456
1457 memcpy(dest,tmp_p,strlen(tmp_p));
1458 return TRUE;
1459}
1460
1461//if read fail,return NULL,or return data pointer;
Andres Morecc856e62010-05-17 21:34:01 -03001462static unsigned char *Config_FileOperation(PSDevice pDevice)
1463{
1464 unsigned char *config_path = CONFIG_PATH;
1465 unsigned char *buffer = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001466 struct file *filp=NULL;
1467 mm_segment_t old_fs = get_fs();
Forest Bond8f9c4662009-06-13 07:38:47 -04001468 //int oldfsuid=0,oldfsgid=0;
Andres Morecc856e62010-05-17 21:34:01 -03001469 int result = 0;
Forest Bond92b96792009-06-13 07:38:31 -04001470
1471 set_fs (KERNEL_DS);
Forest Bond8f9c4662009-06-13 07:38:47 -04001472 /* Can't do this anymore, so we rely on correct filesystem permissions:
1473 //Make sure a caller can read or write power as root
1474 oldfsuid=current->fsuid;
1475 oldfsgid=current->fsgid;
Forest Bond92b96792009-06-13 07:38:31 -04001476 current->fsuid = 0;
1477 current->fsgid = 0;
Forest Bond8f9c4662009-06-13 07:38:47 -04001478 */
Forest Bond92b96792009-06-13 07:38:31 -04001479
1480 //open file
1481 filp = filp_open(config_path, O_RDWR, 0);
1482 if (IS_ERR(filp)) {
1483 printk("Config_FileOperation file Not exist\n");
1484 result=-1;
1485 goto error2;
1486 }
1487
1488 if(!(filp->f_op) || !(filp->f_op->read) ||!(filp->f_op->write)) {
1489 printk("file %s cann't readable or writable?\n",config_path);
1490 result = -1;
1491 goto error1;
1492 }
1493
Julia Lawall32414872010-05-11 20:26:57 +02001494 buffer = kmalloc(1024, GFP_KERNEL);
Forest Bond92b96792009-06-13 07:38:31 -04001495 if(buffer==NULL) {
1496 printk("alllocate mem for file fail?\n");
1497 result = -1;
1498 goto error1;
1499 }
1500
1501 if(filp->f_op->read(filp, buffer, 1024, &filp->f_pos)<0) {
1502 printk("read file error?\n");
1503 result = -1;
1504 }
1505
1506error1:
1507 if(filp_close(filp,NULL))
1508 printk("Config_FileOperation:close file fail\n");
1509
1510error2:
1511 set_fs (old_fs);
Forest Bond8f9c4662009-06-13 07:38:47 -04001512
1513 /*
Forest Bond92b96792009-06-13 07:38:31 -04001514 current->fsuid=oldfsuid;
1515 current->fsgid=oldfsgid;
Forest Bond8f9c4662009-06-13 07:38:47 -04001516 */
Forest Bond92b96792009-06-13 07:38:31 -04001517
1518if(result!=0) {
1519 if(buffer)
1520 kfree(buffer);
1521 buffer=NULL;
1522}
1523 return buffer;
1524}
1525
André Goddard Rosabbc9a992009-11-14 13:09:06 -02001526//return --->-1:fail; >=0:successful
Forest Bond92b96792009-06-13 07:38:31 -04001527static int Read_config_file(PSDevice pDevice) {
Andres Morecc856e62010-05-17 21:34:01 -03001528 int result = 0;
1529 unsigned char tmpbuffer[100];
1530 unsigned char *buffer = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001531
1532 //init config setting
1533 pDevice->config_file.ZoneType = -1;
1534 pDevice->config_file.eAuthenMode = -1;
1535 pDevice->config_file.eEncryptionStatus = -1;
1536
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001537 buffer = Config_FileOperation(pDevice);
1538 if (buffer == NULL) {
Forest Bond92b96792009-06-13 07:38:31 -04001539 result =-1;
1540 return result;
1541 }
1542
1543//get zonetype
1544{
1545 memset(tmpbuffer,0,sizeof(tmpbuffer));
1546 if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer) ==TRUE) {
1547 if(memcmp(tmpbuffer,"USA",3)==0) {
1548 pDevice->config_file.ZoneType=ZoneType_USA;
1549 }
1550 else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
1551 pDevice->config_file.ZoneType=ZoneType_Japan;
1552 }
1553 else if(memcmp(tmpbuffer,"EUROPE",6)==0) {
1554 pDevice->config_file.ZoneType=ZoneType_Europe;
1555 }
1556 else {
1557 printk("Unknown Zonetype[%s]?\n",tmpbuffer);
1558 }
1559 }
1560}
1561
1562#if 1
1563//get other parameter
1564 {
1565 memset(tmpbuffer,0,sizeof(tmpbuffer));
1566 if(Config_FileGetParameter("AUTHENMODE",tmpbuffer,buffer)==TRUE) {
1567 pDevice->config_file.eAuthenMode = (int) simple_strtol(tmpbuffer, NULL, 10);
1568 }
1569
1570 memset(tmpbuffer,0,sizeof(tmpbuffer));
1571 if(Config_FileGetParameter("ENCRYPTIONMODE",tmpbuffer,buffer)==TRUE) {
1572 pDevice->config_file.eEncryptionStatus= (int) simple_strtol(tmpbuffer, NULL, 10);
1573 }
1574 }
1575#endif
1576
1577 kfree(buffer);
1578 return result;
1579}
1580
1581static void device_set_multi(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001582 PSDevice pDevice = (PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001583 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1584 u32 mc_filter[2];
1585 int ii;
Jiri Pirko22bedad32010-04-01 21:22:57 +00001586 struct netdev_hw_addr *ha;
Forest Bond92b96792009-06-13 07:38:31 -04001587 BYTE pbyData[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1588 BYTE byTmpMode = 0;
1589 int rc;
1590
1591
1592 spin_lock_irq(&pDevice->lock);
1593 rc = CONTROLnsRequestIn(pDevice,
1594 MESSAGE_TYPE_READ,
1595 MAC_REG_RCR,
1596 MESSAGE_REQUEST_MACREG,
1597 1,
1598 &byTmpMode
1599 );
1600 if (rc == 0) pDevice->byRxMode = byTmpMode;
1601
1602 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode in= %x\n", pDevice->byRxMode);
1603
1604 if (dev->flags & IFF_PROMISC) { // Set promiscuous.
1605 DBG_PRT(MSG_LEVEL_ERR,KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
1606 // Unconditionally log net taps.
1607 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
1608 }
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001609 else if ((netdev_mc_count(dev) > pDevice->multicast_limit) ||
1610 (dev->flags & IFF_ALLMULTI)) {
Forest Bond92b96792009-06-13 07:38:31 -04001611 CONTROLnsRequestOut(pDevice,
1612 MESSAGE_TYPE_WRITE,
1613 MAC_REG_MAR0,
1614 MESSAGE_REQUEST_MACREG,
1615 8,
1616 pbyData
1617 );
1618 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1619 }
1620 else {
1621 memset(mc_filter, 0, sizeof(mc_filter));
Jiri Pirko22bedad32010-04-01 21:22:57 +00001622 netdev_for_each_mc_addr(ha, dev) {
1623 int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
Forest Bond92b96792009-06-13 07:38:31 -04001624 mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
1625 }
1626 for (ii = 0; ii < 4; ii++) {
1627 MACvWriteMultiAddr(pDevice, ii, *((PBYTE)&mc_filter[0] + ii));
1628 MACvWriteMultiAddr(pDevice, ii+ 4, *((PBYTE)&mc_filter[1] + ii));
1629 }
1630 pDevice->byRxMode &= ~(RCR_UNICAST);
1631 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1632 }
1633
1634 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
1635 // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac.
1636 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1637 pDevice->byRxMode &= ~(RCR_UNICAST);
1638 }
1639 ControlvWriteByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_RCR, pDevice->byRxMode);
1640 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode out= %x\n", pDevice->byRxMode);
1641 spin_unlock_irq(&pDevice->lock);
1642
1643}
1644
1645
1646static struct net_device_stats *device_get_stats(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001647 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001648
1649 return &pDevice->stats;
1650}
1651
1652
1653static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001654 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001655 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1656 PSCmdRequest pReq;
1657 //BOOL bCommit = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001658 struct iwreq *wrq = (struct iwreq *) rq;
1659 int rc =0;
Forest Bond92b96792009-06-13 07:38:31 -04001660
1661 if (pMgmt == NULL) {
1662 rc = -EFAULT;
1663 return rc;
1664 }
1665
1666 switch(cmd) {
1667
Forest Bond92b96792009-06-13 07:38:31 -04001668 case SIOCGIWNAME:
1669 rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL);
1670 break;
1671
1672 case SIOCSIWNWID:
1673 rc = -EOPNOTSUPP;
1674 break;
1675
1676 case SIOCGIWNWID: //0x8b03 support
1677 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1678 rc = iwctl_giwnwid(dev, NULL, &(wrq->u.nwid), NULL);
1679 #else
1680 rc = -EOPNOTSUPP;
1681 #endif
1682 break;
1683
1684 // Set frequency/channel
1685 case SIOCSIWFREQ:
1686 rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL);
1687 break;
1688
1689 // Get frequency/channel
1690 case SIOCGIWFREQ:
1691 rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL);
1692 break;
1693
1694 // Set desired network name (ESSID)
1695 case SIOCSIWESSID:
1696
1697 {
1698 char essid[IW_ESSID_MAX_SIZE+1];
1699 if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
1700 rc = -E2BIG;
1701 break;
1702 }
1703 if (copy_from_user(essid, wrq->u.essid.pointer,
1704 wrq->u.essid.length)) {
1705 rc = -EFAULT;
1706 break;
1707 }
1708 rc = iwctl_siwessid(dev, NULL,
1709 &(wrq->u.essid), essid);
1710 }
1711 break;
1712
1713
1714 // Get current network name (ESSID)
1715 case SIOCGIWESSID:
1716
1717 {
1718 char essid[IW_ESSID_MAX_SIZE+1];
1719 if (wrq->u.essid.pointer)
1720 rc = iwctl_giwessid(dev, NULL,
1721 &(wrq->u.essid), essid);
1722 if (copy_to_user(wrq->u.essid.pointer,
1723 essid,
1724 wrq->u.essid.length) )
1725 rc = -EFAULT;
1726 }
1727 break;
1728
1729 case SIOCSIWAP:
1730
1731 rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL);
1732 break;
1733
1734
1735 // Get current Access Point (BSSID)
1736 case SIOCGIWAP:
1737 rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL);
1738 break;
1739
1740
1741 // Set desired station name
1742 case SIOCSIWNICKN:
1743 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n");
1744 rc = -EOPNOTSUPP;
1745 break;
1746
1747 // Get current station name
1748 case SIOCGIWNICKN:
1749 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n");
1750 rc = -EOPNOTSUPP;
1751 break;
1752
1753 // Set the desired bit-rate
1754 case SIOCSIWRATE:
1755 rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL);
1756 break;
1757
1758 // Get the current bit-rate
1759 case SIOCGIWRATE:
1760
1761 rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
1762 break;
1763
1764 // Set the desired RTS threshold
1765 case SIOCSIWRTS:
1766
1767 rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL);
1768 break;
1769
1770 // Get the current RTS threshold
1771 case SIOCGIWRTS:
1772
1773 rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL);
1774 break;
1775
1776 // Set the desired fragmentation threshold
1777 case SIOCSIWFRAG:
1778
1779 rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL);
1780 break;
1781
1782 // Get the current fragmentation threshold
1783 case SIOCGIWFRAG:
1784
1785 rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL);
1786 break;
1787
1788 // Set mode of operation
1789 case SIOCSIWMODE:
1790 rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL);
1791 break;
1792
1793 // Get mode of operation
1794 case SIOCGIWMODE:
1795 rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
1796 break;
1797
1798 // Set WEP keys and mode
1799 case SIOCSIWENCODE:
1800 {
1801 char abyKey[WLAN_WEP232_KEYLEN];
1802
1803 if (wrq->u.encoding.pointer) {
1804
1805
1806 if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) {
1807 rc = -E2BIG;
1808 break;
1809 }
1810 memset(abyKey, 0, WLAN_WEP232_KEYLEN);
1811 if (copy_from_user(abyKey,
1812 wrq->u.encoding.pointer,
1813 wrq->u.encoding.length)) {
1814 rc = -EFAULT;
1815 break;
1816 }
1817 } else if (wrq->u.encoding.length != 0) {
1818 rc = -EINVAL;
1819 break;
1820 }
1821 rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey);
1822 }
1823 break;
1824
1825 // Get the WEP keys and mode
1826 case SIOCGIWENCODE:
1827
1828 if (!capable(CAP_NET_ADMIN)) {
1829 rc = -EPERM;
1830 break;
1831 }
1832 {
1833 char abyKey[WLAN_WEP232_KEYLEN];
1834
1835 rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey);
1836 if (rc != 0) break;
1837 if (wrq->u.encoding.pointer) {
1838 if (copy_to_user(wrq->u.encoding.pointer,
1839 abyKey,
1840 wrq->u.encoding.length))
1841 rc = -EFAULT;
1842 }
1843 }
1844 break;
1845
Forest Bond92b96792009-06-13 07:38:31 -04001846 // Get the current Tx-Power
1847 case SIOCGIWTXPOW:
1848 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
1849 rc = -EOPNOTSUPP;
1850 break;
1851
1852 case SIOCSIWTXPOW:
1853 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
1854 rc = -EOPNOTSUPP;
1855 break;
1856
Forest Bond92b96792009-06-13 07:38:31 -04001857 case SIOCSIWRETRY:
1858
1859 rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL);
1860 break;
1861
1862 case SIOCGIWRETRY:
1863
1864 rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL);
1865 break;
1866
Forest Bond92b96792009-06-13 07:38:31 -04001867 // Get range of parameters
1868 case SIOCGIWRANGE:
1869
1870 {
1871 struct iw_range range;
1872
1873 rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *) &range);
1874 if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
1875 rc = -EFAULT;
1876 }
1877
1878 break;
1879
1880 case SIOCGIWPOWER:
1881
1882 rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL);
1883 break;
1884
1885
1886 case SIOCSIWPOWER:
1887
1888 rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL);
1889 break;
1890
1891
1892 case SIOCGIWSENS:
1893
1894 rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL);
1895 break;
1896
1897 case SIOCSIWSENS:
1898 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n");
1899 rc = -EOPNOTSUPP;
1900 break;
1901
1902 case SIOCGIWAPLIST:
1903 {
1904 char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
1905
1906 if (wrq->u.data.pointer) {
1907 rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
1908 if (rc == 0) {
1909 if (copy_to_user(wrq->u.data.pointer,
1910 buffer,
1911 (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality)))
1912 ))
1913 rc = -EFAULT;
1914 }
1915 }
1916 }
1917 break;
1918
1919
1920#ifdef WIRELESS_SPY
1921 // Set the spy list
1922 case SIOCSIWSPY:
1923
1924 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
1925 rc = -EOPNOTSUPP;
1926 break;
1927
1928 // Get the spy list
1929 case SIOCGIWSPY:
1930
1931 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
1932 rc = -EOPNOTSUPP;
1933 break;
1934
1935#endif // WIRELESS_SPY
1936
1937 case SIOCGIWPRIV:
1938 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n");
1939 rc = -EOPNOTSUPP;
1940/*
1941 if(wrq->u.data.pointer) {
1942 wrq->u.data.length = sizeof(iwctl_private_args) / sizeof( iwctl_private_args[0]);
1943
1944 if(copy_to_user(wrq->u.data.pointer,
1945 (u_char *) iwctl_private_args,
1946 sizeof(iwctl_private_args)))
1947 rc = -EFAULT;
1948 }
1949*/
1950 break;
1951
1952
Forest Bond92b96792009-06-13 07:38:31 -04001953//2008-0409-07, <Add> by Einsn Liu
1954#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1955 case SIOCSIWAUTH:
1956 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
1957 rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
1958 break;
1959
1960 case SIOCGIWAUTH:
1961 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH \n");
1962 rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
1963 break;
1964
1965 case SIOCSIWGENIE:
1966 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE \n");
1967 rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1968 break;
1969
1970 case SIOCGIWGENIE:
1971 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE \n");
1972 rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1973 break;
1974
1975 case SIOCSIWENCODEEXT:
1976 {
1977 char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
1978 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n");
1979 if(wrq->u.encoding.pointer){
1980 memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1);
1981 if(wrq->u.encoding.length > (sizeof(struct iw_encode_ext)+ MAX_KEY_LEN)){
1982 rc = -E2BIG;
1983 break;
1984 }
1985 if(copy_from_user(extra, wrq->u.encoding.pointer,wrq->u.encoding.length)){
1986 rc = -EFAULT;
1987 break;
1988 }
1989 }else if(wrq->u.encoding.length != 0){
1990 rc = -EINVAL;
1991 break;
1992 }
1993 rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra);
1994 }
1995 break;
1996
1997 case SIOCGIWENCODEEXT:
1998 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n");
1999 rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
2000 break;
2001
2002 case SIOCSIWMLME:
2003 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME \n");
2004 rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
2005 break;
2006
2007#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
2008//End Add -- //2008-0409-07, <Add> by Einsn Liu
2009
Forest Bond92b96792009-06-13 07:38:31 -04002010 case IOCTL_CMD_TEST:
2011
2012 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
2013 rc = -EFAULT;
2014 break;
2015 } else {
2016 rc = 0;
2017 }
2018 pReq = (PSCmdRequest)rq;
2019
2020 //20080130-01,<Remark> by Mike Liu
2021 // if(pDevice->bLinkPass==TRUE)
2022 pReq->wResult = MAGIC_CODE; //Linking status:0x3142
2023 //20080130-02,<Remark> by Mike Liu
2024 // else
2025 // pReq->wResult = MAGIC_CODE+1; //disconnect status:0x3143
2026 break;
2027
2028 case IOCTL_CMD_SET:
2029 if (!(pDevice->flags & DEVICE_FLAGS_OPENED) &&
2030 (((PSCmdRequest)rq)->wCmdCode !=WLAN_CMD_SET_WPA))
2031 {
2032 rc = -EFAULT;
2033 break;
2034 } else {
2035 rc = 0;
2036 }
2037
2038 if (test_and_set_bit( 0, (void*)&(pMgmt->uCmdBusy))) {
2039 return -EBUSY;
2040 }
2041 rc = private_ioctl(pDevice, rq);
2042 clear_bit( 0, (void*)&(pMgmt->uCmdBusy));
2043 break;
2044
2045 case IOCTL_CMD_HOSTAPD:
2046
2047 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
2048 rc = -EFAULT;
2049 break;
2050 } else {
2051 rc = 0;
2052 }
2053
Forest Bondc30d7972010-04-17 11:03:38 -04002054 rc = vt6656_hostap_ioctl(pDevice, &wrq->u.data);
Forest Bond92b96792009-06-13 07:38:31 -04002055 break;
2056
2057 case IOCTL_CMD_WPA:
2058
2059 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
2060 rc = -EFAULT;
2061 break;
2062 } else {
2063 rc = 0;
2064 }
2065
Forest Bond92b96792009-06-13 07:38:31 -04002066 rc = wpa_ioctl(pDevice, &wrq->u.data);
Forest Bond92b96792009-06-13 07:38:31 -04002067 break;
2068
2069 case SIOCETHTOOL:
2070 return ethtool_ioctl(dev, (void *) rq->ifr_data);
2071 // All other calls are currently unsupported
2072
2073 default:
2074 rc = -EOPNOTSUPP;
2075 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd);
2076
2077
2078 }
2079
2080 if (pDevice->bCommit) {
2081 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2082 netif_stop_queue(pDevice->dev);
2083 spin_lock_irq(&pDevice->lock);
Andres More0cbd8d92010-05-06 20:34:29 -03002084 bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002085 spin_unlock_irq(&pDevice->lock);
2086 }
2087 else {
2088 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
2089 spin_lock_irq(&pDevice->lock);
2090//2007-1121-01<Modify>by EinsnLiu
Andres More0cbd8d92010-05-06 20:34:29 -03002091 if (pDevice->bLinkPass &&
Forest Bond92b96792009-06-13 07:38:31 -04002092 memcmp(pMgmt->abyCurrSSID,pMgmt->abyDesireSSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN)) {
Andres More0cbd8d92010-05-06 20:34:29 -03002093 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002094 } else {
2095 pDevice->bLinkPass = FALSE;
2096 pMgmt->eCurrState = WMAC_STATE_IDLE;
2097 memset(pMgmt->abyCurrBSSID, 0, 6);
2098 }
2099 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
2100//End Modify
2101 netif_stop_queue(pDevice->dev);
2102#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
2103 pMgmt->eScanType = WMAC_SCAN_ACTIVE;
Andres More0cbd8d92010-05-06 20:34:29 -03002104 if (!pDevice->bWPASuppWextEnabled)
Forest Bond92b96792009-06-13 07:38:31 -04002105#endif
Andres More0cbd8d92010-05-06 20:34:29 -03002106 bScheduleCommand((void *) pDevice,
2107 WLAN_CMD_BSSID_SCAN,
2108 pMgmt->abyDesireSSID);
2109 bScheduleCommand((void *) pDevice,
2110 WLAN_CMD_SSID,
2111 NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002112 spin_unlock_irq(&pDevice->lock);
2113 }
2114 pDevice->bCommit = FALSE;
2115 }
2116
2117
2118 return rc;
2119}
2120
2121
2122static int ethtool_ioctl(struct net_device *dev, void *useraddr)
2123{
2124 u32 ethcmd;
2125
2126 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
2127 return -EFAULT;
2128
2129 switch (ethcmd) {
2130 case ETHTOOL_GDRVINFO: {
2131 struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
2132 strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
2133 strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
2134 if (copy_to_user(useraddr, &info, sizeof(info)))
2135 return -EFAULT;
2136 return 0;
2137 }
2138
2139 }
2140
2141 return -EOPNOTSUPP;
2142}
2143
2144
2145/*------------------------------------------------------------------*/
2146
Andres More26e5b652010-04-13 19:43:07 -03002147MODULE_DEVICE_TABLE(usb, vt6656_table);
Forest Bond92b96792009-06-13 07:38:31 -04002148
Andres More26e5b652010-04-13 19:43:07 -03002149static struct usb_driver vt6656_driver = {
2150 .name = DEVICE_NAME,
2151 .probe = vt6656_probe,
2152 .disconnect = vt6656_disconnect,
2153 .id_table = vt6656_table,
Forest Bond92b96792009-06-13 07:38:31 -04002154#ifdef CONFIG_PM
Andres More26e5b652010-04-13 19:43:07 -03002155 .suspend = vt6656_suspend,
2156 .resume = vt6656_resume,
2157#endif /* CONFIG_PM */
Forest Bond92b96792009-06-13 07:38:31 -04002158};
2159
Andres More26e5b652010-04-13 19:43:07 -03002160static int __init vt6656_init_module(void)
Forest Bond92b96792009-06-13 07:38:31 -04002161{
Forest Bondf4a8df92009-06-13 07:38:56 -04002162 printk(KERN_NOTICE DEVICE_FULL_DRV_NAM " " DEVICE_VERSION);
Andres More26e5b652010-04-13 19:43:07 -03002163 return usb_register(&vt6656_driver);
Forest Bond92b96792009-06-13 07:38:31 -04002164}
2165
Andres More26e5b652010-04-13 19:43:07 -03002166static void __exit vt6656_cleanup_module(void)
Forest Bond92b96792009-06-13 07:38:31 -04002167{
Andres More26e5b652010-04-13 19:43:07 -03002168 usb_deregister(&vt6656_driver);
Forest Bond92b96792009-06-13 07:38:31 -04002169}
2170
Andres More26e5b652010-04-13 19:43:07 -03002171module_init(vt6656_init_module);
2172module_exit(vt6656_cleanup_module);