blob: d943fb965ff6820b3738023e4194bce0fa100569 [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
Andres More26e5b652010-04-13 19:43:07 -0300760static int __devinit
761vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
Forest Bond92b96792009-06-13 07:38:31 -0400762{
Andres More9a0e7562010-04-13 21:54:48 -0300763 u8 fake_mac[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
Forest Bond92b96792009-06-13 07:38:31 -0400764 struct usb_device *udev = interface_to_usbdev(intf);
Andres More7a8b0052010-07-12 12:40:01 -0300765 int rc = 0;
766 struct net_device *netdev = NULL;
767 PSDevice pDevice = NULL;
Forest Bond92b96792009-06-13 07:38:31 -0400768
Andres More7a8b0052010-07-12 12:40:01 -0300769 printk(KERN_NOTICE "%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
770 printk(KERN_NOTICE "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
Forest Bond92b96792009-06-13 07:38:31 -0400771
Andres More7a8b0052010-07-12 12:40:01 -0300772 udev = usb_get_dev(udev);
773 netdev = alloc_etherdev(sizeof(DEVICE_INFO));
Forest Bond92b96792009-06-13 07:38:31 -0400774
Andres More7a8b0052010-07-12 12:40:01 -0300775 if (!netdev) {
776 printk(KERN_ERR DEVICE_NAME ": allocate net device failed\n");
777 kfree(pDevice);
778 goto err_nomem;
779 }
Forest Bond92b96792009-06-13 07:38:31 -0400780
Andres More7a8b0052010-07-12 12:40:01 -0300781 pDevice = netdev_priv(netdev);
782 memset(pDevice, 0, sizeof(DEVICE_INFO));
Forest Bond92b96792009-06-13 07:38:31 -0400783
Andres More7a8b0052010-07-12 12:40:01 -0300784 pDevice->dev = netdev;
785 pDevice->usb = udev;
Forest Bond1e28efa2009-06-13 07:38:50 -0400786
Andres More7a8b0052010-07-12 12:40:01 -0300787 device_set_options(pDevice);
788 spin_lock_init(&pDevice->lock);
Forest Bond1e28efa2009-06-13 07:38:50 -0400789
Andres More7a8b0052010-07-12 12:40:01 -0300790 pDevice->tx_80211 = device_dma0_tx_80211;
791 pDevice->sMgmtObj.pAdapter = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400792
Andres More7a8b0052010-07-12 12:40:01 -0300793 netdev->netdev_ops = &device_netdev_ops;
794 netdev->wireless_handlers =
795 (struct iw_handler_def *) &iwctl_handler_def;
Forest Bond92b96792009-06-13 07:38:31 -0400796
Andres More7a8b0052010-07-12 12:40:01 -0300797 usb_set_intfdata(intf, pDevice);
Forest Bond92b96792009-06-13 07:38:31 -0400798 SET_NETDEV_DEV(netdev, &intf->dev);
Andres More7a8b0052010-07-12 12:40:01 -0300799 memcpy(pDevice->dev->dev_addr, fake_mac, ETH_ALEN);
800 rc = register_netdev(netdev);
801 if (rc) {
802 printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
Forest Bond92b96792009-06-13 07:38:31 -0400803 free_netdev(netdev);
Andres More7a8b0052010-07-12 12:40:01 -0300804 kfree(pDevice);
805 return -ENODEV;
806 }
Forest Bond92b96792009-06-13 07:38:31 -0400807
Andres More7a8b0052010-07-12 12:40:01 -0300808 usb_device_reset(pDevice);
Forest Bond92b96792009-06-13 07:38:31 -0400809
Andres More7a8b0052010-07-12 12:40:01 -0300810 {
811 union iwreq_data wrqu;
812 memset(&wrqu, 0, sizeof(wrqu));
813 wrqu.data.flags = RT_INSMOD_EVENT_FLAG;
814 wrqu.data.length = IFNAMSIZ;
815 wireless_send_event(pDevice->dev,
816 IWEVCUSTOM,
817 &wrqu,
818 pDevice->dev->name);
819 }
Forest Bond92b96792009-06-13 07:38:31 -0400820
821 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400822
Forest Bond92b96792009-06-13 07:38:31 -0400823err_nomem:
Andres More7a8b0052010-07-12 12:40:01 -0300824 usb_put_dev(udev);
Forest Bond92b96792009-06-13 07:38:31 -0400825
Andres More7a8b0052010-07-12 12:40:01 -0300826 return -ENOMEM;
Forest Bond92b96792009-06-13 07:38:31 -0400827}
828
Andres More8611a292010-05-01 14:25:00 -0300829static void device_free_tx_bufs(PSDevice pDevice)
830{
Forest Bond92b96792009-06-13 07:38:31 -0400831 PUSB_SEND_CONTEXT pTxContext;
832 int ii;
833
834 for (ii = 0; ii < pDevice->cbTD; ii++) {
835
836 pTxContext = pDevice->apTD[ii];
837 //de-allocate URBs
838 if (pTxContext->pUrb) {
Jim Liebdad72fe2009-08-12 14:54:14 -0700839 usb_kill_urb(pTxContext->pUrb);
Forest Bond92b96792009-06-13 07:38:31 -0400840 usb_free_urb(pTxContext->pUrb);
841 }
842 if (pTxContext)
843 kfree(pTxContext);
844 }
845 return;
846}
847
848
Andres More8611a292010-05-01 14:25:00 -0300849static void device_free_rx_bufs(PSDevice pDevice)
850{
Forest Bond92b96792009-06-13 07:38:31 -0400851 PRCB pRCB;
852 int ii;
853
854 for (ii = 0; ii < pDevice->cbRD; ii++) {
855
856 pRCB = pDevice->apRCB[ii];
857 //de-allocate URBs
858 if (pRCB->pUrb) {
Jim Liebdad72fe2009-08-12 14:54:14 -0700859 usb_kill_urb(pRCB->pUrb);
Forest Bond92b96792009-06-13 07:38:31 -0400860 usb_free_urb(pRCB->pUrb);
861 }
862 //de-allocate skb
863 if (pRCB->skb)
864 dev_kfree_skb(pRCB->skb);
865 }
866 if (pDevice->pRCBMem)
867 kfree(pDevice->pRCBMem);
868
869 return;
870}
871
872//2007-1107-02<Add>by MikeLiu
Forest Bond92b96792009-06-13 07:38:31 -0400873static void usb_device_reset(PSDevice pDevice)
874{
875 int status;
876 status = usb_reset_device(pDevice->usb);
877 if (status)
878 printk("usb_device_reset fail status=%d\n",status);
879 return ;
880}
Forest Bond92b96792009-06-13 07:38:31 -0400881
Andres More8611a292010-05-01 14:25:00 -0300882static void device_free_int_bufs(PSDevice pDevice)
883{
Forest Bond92b96792009-06-13 07:38:31 -0400884 if (pDevice->intBuf.pDataBuf != NULL)
885 kfree(pDevice->intBuf.pDataBuf);
886 return;
887}
888
889
890static BOOL device_alloc_bufs(PSDevice pDevice) {
891
892 PUSB_SEND_CONTEXT pTxContext;
893 PRCB pRCB;
894 int ii;
895
896
897 for (ii = 0; ii < pDevice->cbTD; ii++) {
898
899 pTxContext = kmalloc(sizeof(USB_SEND_CONTEXT), GFP_KERNEL);
900 if (pTxContext == NULL) {
901 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : allocate tx usb context failed\n", pDevice->dev->name);
902 goto free_tx;
903 }
904 pDevice->apTD[ii] = pTxContext;
Andres More8611a292010-05-01 14:25:00 -0300905 pTxContext->pDevice = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400906 //allocate URBs
Jim Liebdad72fe2009-08-12 14:54:14 -0700907 pTxContext->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400908 if (pTxContext->pUrb == NULL) {
909 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "alloc tx urb failed\n");
910 goto free_tx;
911 }
912 pTxContext->bBoolInUse = FALSE;
913 }
914
915 // allocate rcb mem
916 pDevice->pRCBMem = kmalloc((sizeof(RCB) * pDevice->cbRD), GFP_KERNEL);
917 if (pDevice->pRCBMem == NULL) {
918 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : alloc rx usb context failed\n", pDevice->dev->name);
919 goto free_tx;
920 }
921
922
923 pDevice->FirstRecvFreeList = NULL;
924 pDevice->LastRecvFreeList = NULL;
925 pDevice->FirstRecvMngList = NULL;
926 pDevice->LastRecvMngList = NULL;
927 pDevice->NumRecvFreeList = 0;
928 memset(pDevice->pRCBMem, 0, (sizeof(RCB) * pDevice->cbRD));
929 pRCB = (PRCB) pDevice->pRCBMem;
930
931 for (ii = 0; ii < pDevice->cbRD; ii++) {
932
933 pDevice->apRCB[ii] = pRCB;
Andres More8611a292010-05-01 14:25:00 -0300934 pRCB->pDevice = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400935 //allocate URBs
Jim Liebdad72fe2009-08-12 14:54:14 -0700936 pRCB->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400937
938 if (pRCB->pUrb == NULL) {
939 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx urb\n");
940 goto free_rx_tx;
941 }
942 pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
943 if (pRCB->skb == NULL) {
944 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx skb\n");
945 goto free_rx_tx;
946 }
947 pRCB->skb->dev = pDevice->dev;
948 pRCB->bBoolInUse = FALSE;
949 EnqueueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList, pRCB);
950 pDevice->NumRecvFreeList++;
951 pRCB++;
952 }
953
954
Jim Liebdad72fe2009-08-12 14:54:14 -0700955 pDevice->pControlURB = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400956 if (pDevice->pControlURB == NULL) {
957 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc control urb\n");
958 goto free_rx_tx;
959 }
960
Jim Liebdad72fe2009-08-12 14:54:14 -0700961 pDevice->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400962 if (pDevice->pInterruptURB == NULL) {
963 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int urb\n");
Jim Liebdad72fe2009-08-12 14:54:14 -0700964 usb_kill_urb(pDevice->pControlURB);
Forest Bond92b96792009-06-13 07:38:31 -0400965 usb_free_urb(pDevice->pControlURB);
966 goto free_rx_tx;
967 }
968
969 pDevice->intBuf.pDataBuf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
970 if (pDevice->intBuf.pDataBuf == NULL) {
971 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int buf\n");
Jim Liebdad72fe2009-08-12 14:54:14 -0700972 usb_kill_urb(pDevice->pControlURB);
973 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -0400974 usb_free_urb(pDevice->pControlURB);
975 usb_free_urb(pDevice->pInterruptURB);
976 goto free_rx_tx;
977 }
978
979 return TRUE;
980
981free_rx_tx:
982 device_free_rx_bufs(pDevice);
983
984free_tx:
985 device_free_tx_bufs(pDevice);
986
987 return FALSE;
988}
989
990
991
992
993static BOOL device_init_defrag_cb(PSDevice pDevice) {
994 int i;
995 PSDeFragControlBlock pDeF;
996
997 /* Init the fragment ctl entries */
998 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
999 pDeF = &(pDevice->sRxDFCB[i]);
1000 if (!device_alloc_frag_buf(pDevice, pDeF)) {
1001 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
1002 pDevice->dev->name);
1003 goto free_frag;
1004 };
1005 }
1006 pDevice->cbDFCB = CB_MAX_RX_FRAG;
1007 pDevice->cbFreeDFCB = pDevice->cbDFCB;
1008 return TRUE;
1009
1010free_frag:
1011 device_free_frag_bufs(pDevice);
1012 return FALSE;
1013}
1014
1015
1016
1017static void device_free_frag_bufs(PSDevice pDevice) {
1018 PSDeFragControlBlock pDeF;
1019 int i;
1020
1021 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
1022
1023 pDeF = &(pDevice->sRxDFCB[i]);
1024
1025 if (pDeF->skb)
1026 dev_kfree_skb(pDeF->skb);
1027 }
1028}
1029
1030
1031
1032BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
1033
1034 pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1035 if (pDeF->skb == NULL)
1036 return FALSE;
1037 ASSERT(pDeF->skb);
1038 pDeF->skb->dev = pDevice->dev;
1039
1040 return TRUE;
1041}
1042
1043
1044/*-----------------------------------------------------------------*/
1045
1046static int device_open(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001047 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001048
1049#ifdef WPA_SM_Transtatus
1050 extern SWPAResult wpa_Result;
1051 memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname));
1052 wpa_Result.proto = 0;
1053 wpa_Result.key_mgmt = 0;
1054 wpa_Result.eap_type = 0;
1055 wpa_Result.authenticated = FALSE;
1056 pDevice->fWPA_Authened = FALSE;
1057#endif
1058
1059 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_open...\n");
1060
1061
1062 pDevice->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
1063
1064 if (device_alloc_bufs(pDevice) == FALSE) {
1065 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_alloc_bufs fail... \n");
1066 return -ENOMEM;
1067 }
1068
1069 if (device_init_defrag_cb(pDevice)== FALSE) {
1070 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Initial defragement cb fail \n");
1071 goto free_rx_tx;
1072 }
1073
1074 MP_CLEAR_FLAG(pDevice, fMP_DISCONNECTED);
1075 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
1076 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
1077 MP_SET_FLAG(pDevice, fMP_POST_READS);
1078 MP_SET_FLAG(pDevice, fMP_POST_WRITES);
1079
1080 //read config file
1081 Read_config_file(pDevice);
1082
1083 if (device_init_registers(pDevice, DEVICE_INIT_COLD) == FALSE) {
1084 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " init register fail\n");
1085 goto free_all;
1086 }
1087
1088 device_set_multi(pDevice->dev);
1089 // Init for Key Management
1090
1091 KeyvInitTable(pDevice,&pDevice->sKey);
Andres More9a0e7562010-04-13 21:54:48 -03001092 memcpy(pDevice->sMgmtObj.abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN);
1093 memcpy(pDevice->dev->dev_addr, pDevice->abyCurrentNetAddr, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001094 pDevice->bStopTx0Pkt = FALSE;
1095 pDevice->bStopDataPkt = FALSE;
1096 pDevice->bRoaming = FALSE; //DavidWang
1097 pDevice->bIsRoaming = FALSE;//DavidWang
1098 pDevice->bEnableRoaming = FALSE;
1099 if (pDevice->bDiversityRegCtlON) {
1100 device_init_diversity_timer(pDevice);
1101 }
1102
1103 vMgrObjectInit(pDevice);
1104 tasklet_init(&pDevice->RxMngWorkItem, (void *)RXvMngWorkItem, (unsigned long)pDevice);
1105 tasklet_init(&pDevice->ReadWorkItem, (void *)RXvWorkItem, (unsigned long)pDevice);
1106 tasklet_init(&pDevice->EventWorkItem, (void *)INTvWorkItem, (unsigned long)pDevice);
1107 add_timer(&(pDevice->sMgmtObj.sTimerSecondCallback));
Forest Bond92b96792009-06-13 07:38:31 -04001108 pDevice->int_interval = 100; //Max 100 microframes.
Forest Bond92b96792009-06-13 07:38:31 -04001109 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1110
1111 pDevice->bIsRxWorkItemQueued = TRUE;
1112 pDevice->fKillEventPollingThread = FALSE;
1113 pDevice->bEventAvailable = FALSE;
1114
1115 pDevice->bWPADEVUp = FALSE;
1116#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1117 pDevice->bwextstep0 = FALSE;
1118 pDevice->bwextstep1 = FALSE;
1119 pDevice->bwextstep2 = FALSE;
1120 pDevice->bwextstep3 = FALSE;
1121 pDevice->bWPASuppWextEnabled = FALSE;
1122#endif
1123 pDevice->byReAssocCount = 0;
1124
1125 RXvWorkItem(pDevice);
1126 INTvWorkItem(pDevice);
1127
1128 // Patch: if WEP key already set by iwconfig but device not yet open
1129 if ((pDevice->bEncryptionEnable == TRUE) && (pDevice->bTransmitKey == TRUE)) {
1130 spin_lock_irq(&pDevice->lock);
1131 KeybSetDefaultKey( pDevice,
1132 &(pDevice->sKey),
1133 pDevice->byKeyIndex | (1 << 31),
1134 pDevice->uKeyLength,
1135 NULL,
1136 pDevice->abyKey,
1137 KEY_CTL_WEP
1138 );
1139 spin_unlock_irq(&pDevice->lock);
1140 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1141 }
1142
1143 if (pDevice->sMgmtObj.eConfigMode == WMAC_CONFIG_AP) {
Andres More0cbd8d92010-05-06 20:34:29 -03001144 bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001145 }
1146 else {
1147 //mike:mark@2008-11-10
Andres More0cbd8d92010-05-06 20:34:29 -03001148 bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
1149 /* bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); */
Forest Bond92b96792009-06-13 07:38:31 -04001150 }
1151
1152
1153 netif_stop_queue(pDevice->dev);
1154 pDevice->flags |= DEVICE_FLAGS_OPENED;
1155
Forest Bond92b96792009-06-13 07:38:31 -04001156{
1157 union iwreq_data wrqu;
1158 memset(&wrqu, 0, sizeof(wrqu));
1159 wrqu.data.flags = RT_UPDEV_EVENT_FLAG;
1160 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1161}
Forest Bond92b96792009-06-13 07:38:31 -04001162
1163 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
1164 return 0;
1165
1166free_all:
1167 device_free_frag_bufs(pDevice);
1168free_rx_tx:
1169 device_free_rx_bufs(pDevice);
1170 device_free_tx_bufs(pDevice);
1171 device_free_int_bufs(pDevice);
Jim Liebdad72fe2009-08-12 14:54:14 -07001172 usb_kill_urb(pDevice->pControlURB);
1173 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -04001174 usb_free_urb(pDevice->pControlURB);
1175 usb_free_urb(pDevice->pInterruptURB);
1176
1177 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open fail.. \n");
1178 return -ENOMEM;
1179}
1180
1181
1182
1183static int device_close(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001184 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001185 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1186
Forest Bond92b96792009-06-13 07:38:31 -04001187 int uu;
Forest Bond92b96792009-06-13 07:38:31 -04001188
1189 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close1 \n");
1190 if (pDevice == NULL)
1191 return -ENODEV;
1192
Forest Bond92b96792009-06-13 07:38:31 -04001193{
1194 union iwreq_data wrqu;
1195 memset(&wrqu, 0, sizeof(wrqu));
1196 wrqu.data.flags = RT_DOWNDEV_EVENT_FLAG;
1197 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1198}
Forest Bond92b96792009-06-13 07:38:31 -04001199
1200//2007-1121-02<Add>by EinsnLiu
1201 if (pDevice->bLinkPass) {
Andres More0cbd8d92010-05-06 20:34:29 -03001202 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001203 mdelay(30);
1204 }
1205//End Add
1206
1207//2008-0714-01<Add>by MikeLiu
1208device_release_WPADEV(pDevice);
1209
Forest Bond92b96792009-06-13 07:38:31 -04001210 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
1211 pMgmt->bShareKeyAlgorithm = FALSE;
1212 pDevice->bEncryptionEnable = FALSE;
1213 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
Andres More33d33e422010-05-19 23:50:00 -03001214 spin_lock_irq(&pDevice->lock);
1215 for (uu = 0; uu < MAX_KEY_TABLE; uu++)
Forest Bond92b96792009-06-13 07:38:31 -04001216 MACvDisableKeyEntry(pDevice,uu);
Andres More33d33e422010-05-19 23:50:00 -03001217 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001218
1219 if ((pDevice->flags & DEVICE_FLAGS_UNPLUG) == FALSE) {
1220 MACbShutdown(pDevice);
1221 }
1222 netif_stop_queue(pDevice->dev);
1223 MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
1224 MP_CLEAR_FLAG(pDevice, fMP_POST_WRITES);
1225 MP_CLEAR_FLAG(pDevice, fMP_POST_READS);
1226 pDevice->fKillEventPollingThread = TRUE;
1227 del_timer(&pDevice->sTimerCommand);
1228 del_timer(&pMgmt->sTimerSecondCallback);
1229
Forest Bond92b96792009-06-13 07:38:31 -04001230 del_timer(&pDevice->sTimerTxData);
Forest Bond92b96792009-06-13 07:38:31 -04001231
1232 if (pDevice->bDiversityRegCtlON) {
1233 del_timer(&pDevice->TimerSQ3Tmax1);
1234 del_timer(&pDevice->TimerSQ3Tmax2);
1235 del_timer(&pDevice->TimerSQ3Tmax3);
1236 }
1237 tasklet_kill(&pDevice->RxMngWorkItem);
1238 tasklet_kill(&pDevice->ReadWorkItem);
1239 tasklet_kill(&pDevice->EventWorkItem);
1240
1241 pDevice->bRoaming = FALSE; //DavidWang
1242 pDevice->bIsRoaming = FALSE;//DavidWang
1243 pDevice->bEnableRoaming = FALSE;
1244 pDevice->bCmdRunning = FALSE;
1245 pDevice->bLinkPass = FALSE;
1246 memset(pMgmt->abyCurrBSSID, 0, 6);
1247 pMgmt->eCurrState = WMAC_STATE_IDLE;
1248
1249 device_free_tx_bufs(pDevice);
1250 device_free_rx_bufs(pDevice);
1251 device_free_int_bufs(pDevice);
1252 device_free_frag_bufs(pDevice);
1253
Jim Liebdad72fe2009-08-12 14:54:14 -07001254 usb_kill_urb(pDevice->pControlURB);
1255 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -04001256 usb_free_urb(pDevice->pControlURB);
1257 usb_free_urb(pDevice->pInterruptURB);
1258
1259 BSSvClearNodeDBTable(pDevice, 0);
1260 pDevice->flags &=(~DEVICE_FLAGS_OPENED);
1261
1262 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n");
1263
1264 return 0;
1265}
1266
Andres More26e5b652010-04-13 19:43:07 -03001267static void __devexit vt6656_disconnect(struct usb_interface *intf)
Forest Bond92b96792009-06-13 07:38:31 -04001268{
Andres More6cda24f2010-06-22 20:43:39 -03001269 PSDevice device = usb_get_intfdata(intf);
Forest Bond92b96792009-06-13 07:38:31 -04001270
Andres More6cda24f2010-06-22 20:43:39 -03001271 if (!device)
1272 return;
Forest Bond92b96792009-06-13 07:38:31 -04001273
Andres More6cda24f2010-06-22 20:43:39 -03001274 {
1275 union iwreq_data req;
1276 memset(&req, 0, sizeof(req));
1277 req.data.flags = RT_RMMOD_EVENT_FLAG;
1278 wireless_send_event(device->dev, IWEVCUSTOM, &req, NULL);
1279 }
Forest Bond92b96792009-06-13 07:38:31 -04001280
Andres More6cda24f2010-06-22 20:43:39 -03001281 device_release_WPADEV(device);
Forest Bond92b96792009-06-13 07:38:31 -04001282
Forest Bond92b96792009-06-13 07:38:31 -04001283 usb_set_intfdata(intf, NULL);
Andres More6cda24f2010-06-22 20:43:39 -03001284 usb_put_dev(interface_to_usbdev(intf));
Forest Bond92b96792009-06-13 07:38:31 -04001285
Andres More6cda24f2010-06-22 20:43:39 -03001286 device->flags |= DEVICE_FLAGS_UNPLUG;
Forest Bond92b96792009-06-13 07:38:31 -04001287
Andres More6cda24f2010-06-22 20:43:39 -03001288 if (device->dev) {
1289 unregister_netdev(device->dev);
1290 wpa_set_wpadev(device, 0);
1291 free_netdev(device->dev);
1292 }
Forest Bond92b96792009-06-13 07:38:31 -04001293}
1294
Andres Moree1669ed2010-07-12 13:10:27 -03001295static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev)
1296{
1297 PSDevice pDevice = netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001298
Andres Moree1669ed2010-07-12 13:10:27 -03001299 spin_lock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001300
Andres Moree1669ed2010-07-12 13:10:27 -03001301 if (unlikely(pDevice->bStopTx0Pkt))
1302 dev_kfree_skb_irq(skb);
1303 else
1304 vDMA0_tx_80211(pDevice, skb);
Forest Bond92b96792009-06-13 07:38:31 -04001305
Andres Moree1669ed2010-07-12 13:10:27 -03001306 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001307
Andres Moree1669ed2010-07-12 13:10:27 -03001308 return NETDEV_TX_OK;
Forest Bond92b96792009-06-13 07:38:31 -04001309}
1310
Forest Bond92b96792009-06-13 07:38:31 -04001311static int device_xmit(struct sk_buff *skb, struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001312 PSDevice pDevice=netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001313 struct net_device_stats* pStats = &pDevice->stats;
1314
1315
1316 spin_lock_irq(&pDevice->lock);
1317
1318 netif_stop_queue(pDevice->dev);
1319
1320 if (pDevice->bLinkPass == FALSE) {
1321 dev_kfree_skb_irq(skb);
1322 spin_unlock_irq(&pDevice->lock);
1323 return 0;
1324 }
1325 if (pDevice->bStopDataPkt == TRUE) {
1326 dev_kfree_skb_irq(skb);
1327 pStats->tx_dropped++;
1328 spin_unlock_irq(&pDevice->lock);
1329 return 0;
1330 }
1331
1332 if(nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) !=0) { //mike add:xmit fail!
1333 if (netif_queue_stopped(pDevice->dev))
1334 netif_wake_queue(pDevice->dev);
1335 }
1336
1337 spin_unlock_irq(&pDevice->lock);
1338
1339 return 0;
1340}
1341
1342
1343
1344static unsigned const ethernet_polynomial = 0x04c11db7U;
1345static inline u32 ether_crc(int length, unsigned char *data)
1346{
1347 int crc = -1;
1348
1349 while(--length >= 0) {
1350 unsigned char current_octet = *data++;
1351 int bit;
1352 for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
1353 crc = (crc << 1) ^
1354 ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
1355 }
1356 }
1357 return crc;
1358}
1359
1360//find out the start position of str2 from str1
Andres Morecc856e62010-05-17 21:34:01 -03001361static unsigned char *kstrstr(const unsigned char *str1,
1362 const unsigned char *str2) {
1363 int str1_len = strlen(str1);
1364 int str2_len = strlen(str2);
Forest Bond92b96792009-06-13 07:38:31 -04001365
1366 while (str1_len >= str2_len) {
1367 str1_len--;
1368 if(memcmp(str1,str2,str2_len)==0)
Andres Morecc856e62010-05-17 21:34:01 -03001369 return (unsigned char *) str1;
Forest Bond92b96792009-06-13 07:38:31 -04001370 str1++;
1371 }
1372 return NULL;
1373}
1374
Andres Morecc856e62010-05-17 21:34:01 -03001375static int Config_FileGetParameter(unsigned char *string,
1376 unsigned char *dest,
1377 unsigned char *source)
Forest Bond92b96792009-06-13 07:38:31 -04001378{
Andres Morecc856e62010-05-17 21:34:01 -03001379 unsigned char buf1[100];
1380 unsigned char buf2[100];
1381 unsigned char *start_p = NULL, *end_p = NULL, *tmp_p = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001382 int ii;
1383
1384 memset(buf1,0,100);
1385 strcat(buf1, string);
1386 strcat(buf1, "=");
1387 source+=strlen(buf1);
1388
1389//find target string start point
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001390 start_p = kstrstr(source,buf1);
1391 if (start_p == NULL)
Forest Bond92b96792009-06-13 07:38:31 -04001392 return FALSE;
1393
1394//check if current config line is marked by "#" ??
Andres More33d33e422010-05-19 23:50:00 -03001395 for (ii = 1; ; ii++) {
1396 if (memcmp(start_p - ii, "\n", 1) == 0)
1397 break;
1398 if (memcmp(start_p - ii, "#", 1) == 0)
1399 return FALSE;
1400 }
Forest Bond92b96792009-06-13 07:38:31 -04001401
1402//find target string end point
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001403 end_p = kstrstr(start_p,"\n");
1404 if (end_p == NULL) { //can't find "\n",but don't care
Forest Bond92b96792009-06-13 07:38:31 -04001405 end_p=start_p+strlen(start_p); //no include "\n"
1406 }
1407
1408 memset(buf2,0,100);
1409 memcpy(buf2,start_p,end_p-start_p); //get the tartget line
1410 buf2[end_p-start_p]='\0';
1411
1412 //find value
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001413 start_p = kstrstr(buf2,"=");
1414 if (start_p == NULL)
Forest Bond92b96792009-06-13 07:38:31 -04001415 return FALSE;
1416 memset(buf1,0,100);
1417 strcpy(buf1,start_p+1);
1418
1419 //except space
1420 tmp_p = buf1;
1421 while(*tmp_p != 0x00) {
1422 if(*tmp_p==' ')
1423 tmp_p++;
1424 else
1425 break;
1426 }
1427
1428 memcpy(dest,tmp_p,strlen(tmp_p));
1429 return TRUE;
1430}
1431
1432//if read fail,return NULL,or return data pointer;
Andres Morecc856e62010-05-17 21:34:01 -03001433static unsigned char *Config_FileOperation(PSDevice pDevice)
1434{
1435 unsigned char *config_path = CONFIG_PATH;
1436 unsigned char *buffer = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001437 struct file *filp=NULL;
1438 mm_segment_t old_fs = get_fs();
Forest Bond8f9c4662009-06-13 07:38:47 -04001439 //int oldfsuid=0,oldfsgid=0;
Andres Morecc856e62010-05-17 21:34:01 -03001440 int result = 0;
Forest Bond92b96792009-06-13 07:38:31 -04001441
1442 set_fs (KERNEL_DS);
Forest Bond8f9c4662009-06-13 07:38:47 -04001443 /* Can't do this anymore, so we rely on correct filesystem permissions:
1444 //Make sure a caller can read or write power as root
1445 oldfsuid=current->fsuid;
1446 oldfsgid=current->fsgid;
Forest Bond92b96792009-06-13 07:38:31 -04001447 current->fsuid = 0;
1448 current->fsgid = 0;
Forest Bond8f9c4662009-06-13 07:38:47 -04001449 */
Forest Bond92b96792009-06-13 07:38:31 -04001450
1451 //open file
1452 filp = filp_open(config_path, O_RDWR, 0);
1453 if (IS_ERR(filp)) {
1454 printk("Config_FileOperation file Not exist\n");
1455 result=-1;
1456 goto error2;
1457 }
1458
1459 if(!(filp->f_op) || !(filp->f_op->read) ||!(filp->f_op->write)) {
1460 printk("file %s cann't readable or writable?\n",config_path);
1461 result = -1;
1462 goto error1;
1463 }
1464
Julia Lawall32414872010-05-11 20:26:57 +02001465 buffer = kmalloc(1024, GFP_KERNEL);
Forest Bond92b96792009-06-13 07:38:31 -04001466 if(buffer==NULL) {
1467 printk("alllocate mem for file fail?\n");
1468 result = -1;
1469 goto error1;
1470 }
1471
1472 if(filp->f_op->read(filp, buffer, 1024, &filp->f_pos)<0) {
1473 printk("read file error?\n");
1474 result = -1;
1475 }
1476
1477error1:
1478 if(filp_close(filp,NULL))
1479 printk("Config_FileOperation:close file fail\n");
1480
1481error2:
1482 set_fs (old_fs);
Forest Bond8f9c4662009-06-13 07:38:47 -04001483
1484 /*
Forest Bond92b96792009-06-13 07:38:31 -04001485 current->fsuid=oldfsuid;
1486 current->fsgid=oldfsgid;
Forest Bond8f9c4662009-06-13 07:38:47 -04001487 */
Forest Bond92b96792009-06-13 07:38:31 -04001488
1489if(result!=0) {
1490 if(buffer)
1491 kfree(buffer);
1492 buffer=NULL;
1493}
1494 return buffer;
1495}
1496
André Goddard Rosabbc9a992009-11-14 13:09:06 -02001497//return --->-1:fail; >=0:successful
Forest Bond92b96792009-06-13 07:38:31 -04001498static int Read_config_file(PSDevice pDevice) {
Andres Morecc856e62010-05-17 21:34:01 -03001499 int result = 0;
1500 unsigned char tmpbuffer[100];
1501 unsigned char *buffer = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001502
1503 //init config setting
1504 pDevice->config_file.ZoneType = -1;
1505 pDevice->config_file.eAuthenMode = -1;
1506 pDevice->config_file.eEncryptionStatus = -1;
1507
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001508 buffer = Config_FileOperation(pDevice);
1509 if (buffer == NULL) {
Forest Bond92b96792009-06-13 07:38:31 -04001510 result =-1;
1511 return result;
1512 }
1513
1514//get zonetype
1515{
1516 memset(tmpbuffer,0,sizeof(tmpbuffer));
1517 if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer) ==TRUE) {
1518 if(memcmp(tmpbuffer,"USA",3)==0) {
1519 pDevice->config_file.ZoneType=ZoneType_USA;
1520 }
1521 else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
1522 pDevice->config_file.ZoneType=ZoneType_Japan;
1523 }
1524 else if(memcmp(tmpbuffer,"EUROPE",6)==0) {
1525 pDevice->config_file.ZoneType=ZoneType_Europe;
1526 }
1527 else {
1528 printk("Unknown Zonetype[%s]?\n",tmpbuffer);
1529 }
1530 }
1531}
1532
Forest Bond92b96792009-06-13 07:38:31 -04001533//get other parameter
1534 {
1535 memset(tmpbuffer,0,sizeof(tmpbuffer));
1536 if(Config_FileGetParameter("AUTHENMODE",tmpbuffer,buffer)==TRUE) {
1537 pDevice->config_file.eAuthenMode = (int) simple_strtol(tmpbuffer, NULL, 10);
1538 }
1539
1540 memset(tmpbuffer,0,sizeof(tmpbuffer));
1541 if(Config_FileGetParameter("ENCRYPTIONMODE",tmpbuffer,buffer)==TRUE) {
1542 pDevice->config_file.eEncryptionStatus= (int) simple_strtol(tmpbuffer, NULL, 10);
1543 }
1544 }
Forest Bond92b96792009-06-13 07:38:31 -04001545
1546 kfree(buffer);
1547 return result;
1548}
1549
1550static void device_set_multi(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001551 PSDevice pDevice = (PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001552 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1553 u32 mc_filter[2];
1554 int ii;
Jiri Pirko22bedad32010-04-01 21:22:57 +00001555 struct netdev_hw_addr *ha;
Forest Bond92b96792009-06-13 07:38:31 -04001556 BYTE pbyData[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1557 BYTE byTmpMode = 0;
1558 int rc;
1559
1560
1561 spin_lock_irq(&pDevice->lock);
1562 rc = CONTROLnsRequestIn(pDevice,
1563 MESSAGE_TYPE_READ,
1564 MAC_REG_RCR,
1565 MESSAGE_REQUEST_MACREG,
1566 1,
1567 &byTmpMode
1568 );
1569 if (rc == 0) pDevice->byRxMode = byTmpMode;
1570
1571 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode in= %x\n", pDevice->byRxMode);
1572
1573 if (dev->flags & IFF_PROMISC) { // Set promiscuous.
1574 DBG_PRT(MSG_LEVEL_ERR,KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
1575 // Unconditionally log net taps.
1576 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
1577 }
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001578 else if ((netdev_mc_count(dev) > pDevice->multicast_limit) ||
1579 (dev->flags & IFF_ALLMULTI)) {
Forest Bond92b96792009-06-13 07:38:31 -04001580 CONTROLnsRequestOut(pDevice,
1581 MESSAGE_TYPE_WRITE,
1582 MAC_REG_MAR0,
1583 MESSAGE_REQUEST_MACREG,
1584 8,
1585 pbyData
1586 );
1587 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1588 }
1589 else {
1590 memset(mc_filter, 0, sizeof(mc_filter));
Jiri Pirko22bedad32010-04-01 21:22:57 +00001591 netdev_for_each_mc_addr(ha, dev) {
1592 int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
Forest Bond92b96792009-06-13 07:38:31 -04001593 mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
1594 }
1595 for (ii = 0; ii < 4; ii++) {
1596 MACvWriteMultiAddr(pDevice, ii, *((PBYTE)&mc_filter[0] + ii));
1597 MACvWriteMultiAddr(pDevice, ii+ 4, *((PBYTE)&mc_filter[1] + ii));
1598 }
1599 pDevice->byRxMode &= ~(RCR_UNICAST);
1600 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1601 }
1602
1603 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
1604 // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac.
1605 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1606 pDevice->byRxMode &= ~(RCR_UNICAST);
1607 }
1608 ControlvWriteByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_RCR, pDevice->byRxMode);
1609 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode out= %x\n", pDevice->byRxMode);
1610 spin_unlock_irq(&pDevice->lock);
1611
1612}
1613
1614
1615static struct net_device_stats *device_get_stats(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001616 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001617
1618 return &pDevice->stats;
1619}
1620
1621
1622static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001623 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001624 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1625 PSCmdRequest pReq;
1626 //BOOL bCommit = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001627 struct iwreq *wrq = (struct iwreq *) rq;
1628 int rc =0;
Forest Bond92b96792009-06-13 07:38:31 -04001629
1630 if (pMgmt == NULL) {
1631 rc = -EFAULT;
1632 return rc;
1633 }
1634
1635 switch(cmd) {
1636
Forest Bond92b96792009-06-13 07:38:31 -04001637 case SIOCGIWNAME:
1638 rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL);
1639 break;
1640
1641 case SIOCSIWNWID:
1642 rc = -EOPNOTSUPP;
1643 break;
1644
1645 case SIOCGIWNWID: //0x8b03 support
1646 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1647 rc = iwctl_giwnwid(dev, NULL, &(wrq->u.nwid), NULL);
1648 #else
1649 rc = -EOPNOTSUPP;
1650 #endif
1651 break;
1652
1653 // Set frequency/channel
1654 case SIOCSIWFREQ:
1655 rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL);
1656 break;
1657
1658 // Get frequency/channel
1659 case SIOCGIWFREQ:
1660 rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL);
1661 break;
1662
1663 // Set desired network name (ESSID)
1664 case SIOCSIWESSID:
1665
1666 {
1667 char essid[IW_ESSID_MAX_SIZE+1];
1668 if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
1669 rc = -E2BIG;
1670 break;
1671 }
1672 if (copy_from_user(essid, wrq->u.essid.pointer,
1673 wrq->u.essid.length)) {
1674 rc = -EFAULT;
1675 break;
1676 }
1677 rc = iwctl_siwessid(dev, NULL,
1678 &(wrq->u.essid), essid);
1679 }
1680 break;
1681
1682
1683 // Get current network name (ESSID)
1684 case SIOCGIWESSID:
1685
1686 {
1687 char essid[IW_ESSID_MAX_SIZE+1];
1688 if (wrq->u.essid.pointer)
1689 rc = iwctl_giwessid(dev, NULL,
1690 &(wrq->u.essid), essid);
1691 if (copy_to_user(wrq->u.essid.pointer,
1692 essid,
1693 wrq->u.essid.length) )
1694 rc = -EFAULT;
1695 }
1696 break;
1697
1698 case SIOCSIWAP:
1699
1700 rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL);
1701 break;
1702
1703
1704 // Get current Access Point (BSSID)
1705 case SIOCGIWAP:
1706 rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL);
1707 break;
1708
1709
1710 // Set desired station name
1711 case SIOCSIWNICKN:
1712 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n");
1713 rc = -EOPNOTSUPP;
1714 break;
1715
1716 // Get current station name
1717 case SIOCGIWNICKN:
1718 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n");
1719 rc = -EOPNOTSUPP;
1720 break;
1721
1722 // Set the desired bit-rate
1723 case SIOCSIWRATE:
1724 rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL);
1725 break;
1726
1727 // Get the current bit-rate
1728 case SIOCGIWRATE:
1729
1730 rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
1731 break;
1732
1733 // Set the desired RTS threshold
1734 case SIOCSIWRTS:
1735
1736 rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL);
1737 break;
1738
1739 // Get the current RTS threshold
1740 case SIOCGIWRTS:
1741
1742 rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL);
1743 break;
1744
1745 // Set the desired fragmentation threshold
1746 case SIOCSIWFRAG:
1747
1748 rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL);
1749 break;
1750
1751 // Get the current fragmentation threshold
1752 case SIOCGIWFRAG:
1753
1754 rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL);
1755 break;
1756
1757 // Set mode of operation
1758 case SIOCSIWMODE:
1759 rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL);
1760 break;
1761
1762 // Get mode of operation
1763 case SIOCGIWMODE:
1764 rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
1765 break;
1766
1767 // Set WEP keys and mode
1768 case SIOCSIWENCODE:
1769 {
1770 char abyKey[WLAN_WEP232_KEYLEN];
1771
1772 if (wrq->u.encoding.pointer) {
1773
1774
1775 if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) {
1776 rc = -E2BIG;
1777 break;
1778 }
1779 memset(abyKey, 0, WLAN_WEP232_KEYLEN);
1780 if (copy_from_user(abyKey,
1781 wrq->u.encoding.pointer,
1782 wrq->u.encoding.length)) {
1783 rc = -EFAULT;
1784 break;
1785 }
1786 } else if (wrq->u.encoding.length != 0) {
1787 rc = -EINVAL;
1788 break;
1789 }
1790 rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey);
1791 }
1792 break;
1793
1794 // Get the WEP keys and mode
1795 case SIOCGIWENCODE:
1796
1797 if (!capable(CAP_NET_ADMIN)) {
1798 rc = -EPERM;
1799 break;
1800 }
1801 {
1802 char abyKey[WLAN_WEP232_KEYLEN];
1803
1804 rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey);
1805 if (rc != 0) break;
1806 if (wrq->u.encoding.pointer) {
1807 if (copy_to_user(wrq->u.encoding.pointer,
1808 abyKey,
1809 wrq->u.encoding.length))
1810 rc = -EFAULT;
1811 }
1812 }
1813 break;
1814
Forest Bond92b96792009-06-13 07:38:31 -04001815 // Get the current Tx-Power
1816 case SIOCGIWTXPOW:
1817 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
1818 rc = -EOPNOTSUPP;
1819 break;
1820
1821 case SIOCSIWTXPOW:
1822 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
1823 rc = -EOPNOTSUPP;
1824 break;
1825
Forest Bond92b96792009-06-13 07:38:31 -04001826 case SIOCSIWRETRY:
1827
1828 rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL);
1829 break;
1830
1831 case SIOCGIWRETRY:
1832
1833 rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL);
1834 break;
1835
Forest Bond92b96792009-06-13 07:38:31 -04001836 // Get range of parameters
1837 case SIOCGIWRANGE:
1838
1839 {
1840 struct iw_range range;
1841
1842 rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *) &range);
1843 if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
1844 rc = -EFAULT;
1845 }
1846
1847 break;
1848
1849 case SIOCGIWPOWER:
1850
1851 rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL);
1852 break;
1853
1854
1855 case SIOCSIWPOWER:
1856
1857 rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL);
1858 break;
1859
1860
1861 case SIOCGIWSENS:
1862
1863 rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL);
1864 break;
1865
1866 case SIOCSIWSENS:
1867 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n");
1868 rc = -EOPNOTSUPP;
1869 break;
1870
1871 case SIOCGIWAPLIST:
1872 {
1873 char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
1874
1875 if (wrq->u.data.pointer) {
1876 rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
1877 if (rc == 0) {
1878 if (copy_to_user(wrq->u.data.pointer,
1879 buffer,
1880 (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality)))
1881 ))
1882 rc = -EFAULT;
1883 }
1884 }
1885 }
1886 break;
1887
1888
1889#ifdef WIRELESS_SPY
1890 // Set the spy list
1891 case SIOCSIWSPY:
1892
1893 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
1894 rc = -EOPNOTSUPP;
1895 break;
1896
1897 // Get the spy list
1898 case SIOCGIWSPY:
1899
1900 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
1901 rc = -EOPNOTSUPP;
1902 break;
1903
1904#endif // WIRELESS_SPY
1905
1906 case SIOCGIWPRIV:
1907 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n");
1908 rc = -EOPNOTSUPP;
1909/*
1910 if(wrq->u.data.pointer) {
1911 wrq->u.data.length = sizeof(iwctl_private_args) / sizeof( iwctl_private_args[0]);
1912
1913 if(copy_to_user(wrq->u.data.pointer,
1914 (u_char *) iwctl_private_args,
1915 sizeof(iwctl_private_args)))
1916 rc = -EFAULT;
1917 }
1918*/
1919 break;
1920
1921
Forest Bond92b96792009-06-13 07:38:31 -04001922//2008-0409-07, <Add> by Einsn Liu
1923#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1924 case SIOCSIWAUTH:
1925 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
1926 rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
1927 break;
1928
1929 case SIOCGIWAUTH:
1930 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH \n");
1931 rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
1932 break;
1933
1934 case SIOCSIWGENIE:
1935 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE \n");
1936 rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1937 break;
1938
1939 case SIOCGIWGENIE:
1940 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE \n");
1941 rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1942 break;
1943
1944 case SIOCSIWENCODEEXT:
1945 {
1946 char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
1947 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n");
1948 if(wrq->u.encoding.pointer){
1949 memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1);
1950 if(wrq->u.encoding.length > (sizeof(struct iw_encode_ext)+ MAX_KEY_LEN)){
1951 rc = -E2BIG;
1952 break;
1953 }
1954 if(copy_from_user(extra, wrq->u.encoding.pointer,wrq->u.encoding.length)){
1955 rc = -EFAULT;
1956 break;
1957 }
1958 }else if(wrq->u.encoding.length != 0){
1959 rc = -EINVAL;
1960 break;
1961 }
1962 rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra);
1963 }
1964 break;
1965
1966 case SIOCGIWENCODEEXT:
1967 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n");
1968 rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
1969 break;
1970
1971 case SIOCSIWMLME:
1972 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME \n");
1973 rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1974 break;
1975
1976#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1977//End Add -- //2008-0409-07, <Add> by Einsn Liu
1978
Forest Bond92b96792009-06-13 07:38:31 -04001979 case IOCTL_CMD_TEST:
1980
1981 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1982 rc = -EFAULT;
1983 break;
1984 } else {
1985 rc = 0;
1986 }
1987 pReq = (PSCmdRequest)rq;
1988
1989 //20080130-01,<Remark> by Mike Liu
1990 // if(pDevice->bLinkPass==TRUE)
1991 pReq->wResult = MAGIC_CODE; //Linking status:0x3142
1992 //20080130-02,<Remark> by Mike Liu
1993 // else
1994 // pReq->wResult = MAGIC_CODE+1; //disconnect status:0x3143
1995 break;
1996
1997 case IOCTL_CMD_SET:
1998 if (!(pDevice->flags & DEVICE_FLAGS_OPENED) &&
1999 (((PSCmdRequest)rq)->wCmdCode !=WLAN_CMD_SET_WPA))
2000 {
2001 rc = -EFAULT;
2002 break;
2003 } else {
2004 rc = 0;
2005 }
2006
2007 if (test_and_set_bit( 0, (void*)&(pMgmt->uCmdBusy))) {
2008 return -EBUSY;
2009 }
2010 rc = private_ioctl(pDevice, rq);
2011 clear_bit( 0, (void*)&(pMgmt->uCmdBusy));
2012 break;
2013
2014 case IOCTL_CMD_HOSTAPD:
2015
2016 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
2017 rc = -EFAULT;
2018 break;
2019 } else {
2020 rc = 0;
2021 }
2022
Forest Bondc30d7972010-04-17 11:03:38 -04002023 rc = vt6656_hostap_ioctl(pDevice, &wrq->u.data);
Forest Bond92b96792009-06-13 07:38:31 -04002024 break;
2025
2026 case IOCTL_CMD_WPA:
2027
2028 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
2029 rc = -EFAULT;
2030 break;
2031 } else {
2032 rc = 0;
2033 }
2034
Forest Bond92b96792009-06-13 07:38:31 -04002035 rc = wpa_ioctl(pDevice, &wrq->u.data);
Forest Bond92b96792009-06-13 07:38:31 -04002036 break;
2037
2038 case SIOCETHTOOL:
2039 return ethtool_ioctl(dev, (void *) rq->ifr_data);
2040 // All other calls are currently unsupported
2041
2042 default:
2043 rc = -EOPNOTSUPP;
2044 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd);
2045
2046
2047 }
2048
2049 if (pDevice->bCommit) {
2050 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2051 netif_stop_queue(pDevice->dev);
2052 spin_lock_irq(&pDevice->lock);
Andres More0cbd8d92010-05-06 20:34:29 -03002053 bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002054 spin_unlock_irq(&pDevice->lock);
2055 }
2056 else {
2057 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
2058 spin_lock_irq(&pDevice->lock);
2059//2007-1121-01<Modify>by EinsnLiu
Andres More0cbd8d92010-05-06 20:34:29 -03002060 if (pDevice->bLinkPass &&
Forest Bond92b96792009-06-13 07:38:31 -04002061 memcmp(pMgmt->abyCurrSSID,pMgmt->abyDesireSSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN)) {
Andres More0cbd8d92010-05-06 20:34:29 -03002062 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002063 } else {
2064 pDevice->bLinkPass = FALSE;
2065 pMgmt->eCurrState = WMAC_STATE_IDLE;
2066 memset(pMgmt->abyCurrBSSID, 0, 6);
2067 }
2068 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
2069//End Modify
2070 netif_stop_queue(pDevice->dev);
2071#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
2072 pMgmt->eScanType = WMAC_SCAN_ACTIVE;
Andres More0cbd8d92010-05-06 20:34:29 -03002073 if (!pDevice->bWPASuppWextEnabled)
Forest Bond92b96792009-06-13 07:38:31 -04002074#endif
Andres More0cbd8d92010-05-06 20:34:29 -03002075 bScheduleCommand((void *) pDevice,
2076 WLAN_CMD_BSSID_SCAN,
2077 pMgmt->abyDesireSSID);
2078 bScheduleCommand((void *) pDevice,
2079 WLAN_CMD_SSID,
2080 NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002081 spin_unlock_irq(&pDevice->lock);
2082 }
2083 pDevice->bCommit = FALSE;
2084 }
2085
2086
2087 return rc;
2088}
2089
2090
2091static int ethtool_ioctl(struct net_device *dev, void *useraddr)
2092{
2093 u32 ethcmd;
2094
2095 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
2096 return -EFAULT;
2097
2098 switch (ethcmd) {
2099 case ETHTOOL_GDRVINFO: {
2100 struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
2101 strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
2102 strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
2103 if (copy_to_user(useraddr, &info, sizeof(info)))
2104 return -EFAULT;
2105 return 0;
2106 }
2107
2108 }
2109
2110 return -EOPNOTSUPP;
2111}
2112
2113
2114/*------------------------------------------------------------------*/
2115
Andres More26e5b652010-04-13 19:43:07 -03002116MODULE_DEVICE_TABLE(usb, vt6656_table);
Forest Bond92b96792009-06-13 07:38:31 -04002117
Andres More26e5b652010-04-13 19:43:07 -03002118static struct usb_driver vt6656_driver = {
2119 .name = DEVICE_NAME,
2120 .probe = vt6656_probe,
2121 .disconnect = vt6656_disconnect,
2122 .id_table = vt6656_table,
Forest Bond92b96792009-06-13 07:38:31 -04002123#ifdef CONFIG_PM
Andres More26e5b652010-04-13 19:43:07 -03002124 .suspend = vt6656_suspend,
2125 .resume = vt6656_resume,
2126#endif /* CONFIG_PM */
Forest Bond92b96792009-06-13 07:38:31 -04002127};
2128
Andres More26e5b652010-04-13 19:43:07 -03002129static int __init vt6656_init_module(void)
Forest Bond92b96792009-06-13 07:38:31 -04002130{
Forest Bondf4a8df92009-06-13 07:38:56 -04002131 printk(KERN_NOTICE DEVICE_FULL_DRV_NAM " " DEVICE_VERSION);
Andres More26e5b652010-04-13 19:43:07 -03002132 return usb_register(&vt6656_driver);
Forest Bond92b96792009-06-13 07:38:31 -04002133}
2134
Andres More26e5b652010-04-13 19:43:07 -03002135static void __exit vt6656_cleanup_module(void)
Forest Bond92b96792009-06-13 07:38:31 -04002136{
Andres More26e5b652010-04-13 19:43:07 -03002137 usb_deregister(&vt6656_driver);
Forest Bond92b96792009-06-13 07:38:31 -04002138}
2139
Andres More26e5b652010-04-13 19:43:07 -03002140module_init(vt6656_init_module);
2141module_exit(vt6656_cleanup_module);