blob: 3a58214c2744eb94bd259a710d729afed75b0377 [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
Forest Bond92b96792009-06-13 07:38:31 -0400285static BOOL device_release_WPADEV(PSDevice pDevice);
286
Forest Bond92b96792009-06-13 07:38:31 -0400287static void usb_device_reset(PSDevice pDevice);
Forest Bond92b96792009-06-13 07:38:31 -0400288
289
290
291/*--------------------- Export Variables --------------------------*/
292
293/*--------------------- Export Functions --------------------------*/
294
295
296static void
297device_set_options(PSDevice pDevice) {
298
Andres More9a0e7562010-04-13 21:54:48 -0300299 BYTE abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
300 BYTE abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
301 u8 abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
Forest Bond92b96792009-06-13 07:38:31 -0400302
Andres More9a0e7562010-04-13 21:54:48 -0300303 memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN);
304 memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN);
305 memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400306
307 pDevice->cbTD = TX_DESC_DEF0;
308 pDevice->cbRD = RX_DESC_DEF0;
309 pDevice->uChannel = CHANNEL_DEF;
310 pDevice->wRTSThreshold = RTS_THRESH_DEF;
311 pDevice->wFragmentationThreshold = FRAG_THRESH_DEF;
312 pDevice->byShortRetryLimit = SHORT_RETRY_DEF;
313 pDevice->byLongRetryLimit = LONG_RETRY_DEF;
314 pDevice->wMaxTransmitMSDULifetime = DEFAULT_MSDU_LIFETIME;
315 pDevice->byShortPreamble = PREAMBLE_TYPE_DEF;
316 pDevice->ePSMode = PS_MODE_DEF;
317 pDevice->b11hEnable = X80211h_MODE_DEF;
318 pDevice->eOPMode = OP_MODE_DEF;
319 pDevice->uConnectionRate = DATA_RATE_DEF;
320 if (pDevice->uConnectionRate < RATE_AUTO) pDevice->bFixRate = TRUE;
321 pDevice->byBBType = BBP_TYPE_DEF;
322 pDevice->byPacketType = pDevice->byBBType;
323 pDevice->byAutoFBCtrl = AUTO_FB_0;
324 pDevice->bUpdateBBVGA = TRUE;
325 pDevice->byFOETuning = 0;
326 pDevice->byAutoPwrTunning = 0;
327 pDevice->wCTSDuration = 0;
328 pDevice->byPreambleType = 0;
329 pDevice->bExistSWNetAddr = FALSE;
330// pDevice->bDiversityRegCtlON = TRUE;
331 pDevice->bDiversityRegCtlON = FALSE;
332}
333
334
Andres More8611a292010-05-01 14:25:00 -0300335static void device_init_diversity_timer(PSDevice pDevice)
336{
Forest Bond92b96792009-06-13 07:38:31 -0400337 init_timer(&pDevice->TimerSQ3Tmax1);
Andres Morecc856e62010-05-17 21:34:01 -0300338 pDevice->TimerSQ3Tmax1.data = (unsigned long)pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400339 pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack;
340 pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ);
341
342 init_timer(&pDevice->TimerSQ3Tmax2);
Andres Morecc856e62010-05-17 21:34:01 -0300343 pDevice->TimerSQ3Tmax2.data = (unsigned long)pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400344 pDevice->TimerSQ3Tmax2.function = (TimerFunction)TimerSQ3CallBack;
345 pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ);
346
347 init_timer(&pDevice->TimerSQ3Tmax3);
Andres Morecc856e62010-05-17 21:34:01 -0300348 pDevice->TimerSQ3Tmax3.data = (unsigned long)pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400349 pDevice->TimerSQ3Tmax3.function = (TimerFunction)TimerSQ3Tmax3CallBack;
350 pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ);
351
352 return;
353}
354
355
356//
357// Initialiation of MAC & BBP registers
358//
359
360static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
361{
Andres More9a0e7562010-04-13 21:54:48 -0300362 u8 abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
363 u8 abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
364 u8 abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
Forest Bond92b96792009-06-13 07:38:31 -0400365 BYTE byAntenna;
Andres Morecc856e62010-05-17 21:34:01 -0300366 unsigned int ii;
Forest Bond92b96792009-06-13 07:38:31 -0400367 CMD_CARD_INIT sInitCmd;
Andres More6487c492010-08-02 20:51:57 -0300368 int ntStatus = STATUS_SUCCESS;
Forest Bond92b96792009-06-13 07:38:31 -0400369 RSP_CARD_INIT sInitRsp;
370 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
371 BYTE byTmp;
372 BYTE byCalibTXIQ = 0;
373 BYTE byCalibTXDC = 0;
374 BYTE byCalibRXIQ = 0;
375
376 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---->INIbInitAdapter. [%d][%d]\n", InitType, pDevice->byPacketType);
377 spin_lock_irq(&pDevice->lock);
Andres More9a0e7562010-04-13 21:54:48 -0300378 if (InitType == DEVICE_INIT_COLD) {
379 memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN);
380 memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN);
381 memcpy(pDevice->abySNAP_Bridgetunnel,
382 abySNAP_Bridgetunnel,
383 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400384
385 if ( !FIRMWAREbCheckVersion(pDevice) ) {
386 if (FIRMWAREbDownload(pDevice) == TRUE) {
387 if (FIRMWAREbBrach2Sram(pDevice) == FALSE) {
388 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" FIRMWAREbBrach2Sram fail \n");
389 spin_unlock_irq(&pDevice->lock);
390 return FALSE;
391 }
392 } else {
393
394 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" FIRMWAREbDownload fail \n");
395 spin_unlock_irq(&pDevice->lock);
396 return FALSE;
397 }
398 }
399
400 if ( !BBbVT3184Init(pDevice) ) {
401 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" BBbVT3184Init fail \n");
402 spin_unlock_irq(&pDevice->lock);
403 return FALSE;
404 }
405 }
406
407 sInitCmd.byInitClass = (BYTE)InitType;
408 sInitCmd.bExistSWNetAddr = (BYTE) pDevice->bExistSWNetAddr;
Andres More33d33e422010-05-19 23:50:00 -0300409 for (ii = 0; ii < 6; ii++)
410 sInitCmd.bySWNetAddr[ii] = pDevice->abyCurrentNetAddr[ii];
Forest Bond92b96792009-06-13 07:38:31 -0400411 sInitCmd.byShortRetryLimit = pDevice->byShortRetryLimit;
412 sInitCmd.byLongRetryLimit = pDevice->byLongRetryLimit;
413
414 //issue Card_init command to device
415 ntStatus = CONTROLnsRequestOut(pDevice,
416 MESSAGE_TYPE_CARDINIT,
417 0,
418 0,
419 sizeof(CMD_CARD_INIT),
420 (PBYTE) &(sInitCmd));
421
422 if ( ntStatus != STATUS_SUCCESS ) {
423 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Issue Card init fail \n");
424 spin_unlock_irq(&pDevice->lock);
425 return FALSE;
426 }
427 if (InitType == DEVICE_INIT_COLD) {
428
429 ntStatus = CONTROLnsRequestIn(pDevice,MESSAGE_TYPE_INIT_RSP,0,0,sizeof(RSP_CARD_INIT), (PBYTE) &(sInitRsp));
430
431 if (ntStatus != STATUS_SUCCESS) {
432 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Cardinit request in status fail!\n");
433 spin_unlock_irq(&pDevice->lock);
434 return FALSE;
435 }
436
437 //Local ID for AES functions
438 ntStatus = CONTROLnsRequestIn(pDevice,
439 MESSAGE_TYPE_READ,
440 MAC_REG_LOCALID,
441 MESSAGE_REQUEST_MACREG,
442 1,
443 &pDevice->byLocalID);
444
445 if ( ntStatus != STATUS_SUCCESS ) {
446 spin_unlock_irq(&pDevice->lock);
447 return FALSE;
448 }
449
450 // Do MACbSoftwareReset in MACvInitialize
451 // force CCK
452 pDevice->bCCK = TRUE;
453 pDevice->bProtectMode = FALSE; //Only used in 11g type, sync with ERP IE
454 pDevice->bNonERPPresent = FALSE;
455 pDevice->bBarkerPreambleMd = FALSE;
456 if ( pDevice->bFixRate ) {
457 pDevice->wCurrentRate = (WORD) pDevice->uConnectionRate;
458 } else {
459 if ( pDevice->byBBType == BB_TYPE_11B )
460 pDevice->wCurrentRate = RATE_11M;
461 else
462 pDevice->wCurrentRate = RATE_54M;
463 }
464
465 CHvInitChannelTable(pDevice);
466
467 pDevice->byTopOFDMBasicRate = RATE_24M;
468 pDevice->byTopCCKBasicRate = RATE_1M;
469 pDevice->byRevId = 0; //Target to IF pin while programming to RF chip.
470 pDevice->byCurPwr = 0xFF;
471
472 pDevice->byCCKPwr = pDevice->abyEEPROM[EEP_OFS_PWR_CCK];
473 pDevice->byOFDMPwrG = pDevice->abyEEPROM[EEP_OFS_PWR_OFDMG];
474 // Load power Table
475 for (ii=0;ii<14;ii++) {
476 pDevice->abyCCKPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_CCK_PWR_TBL];
477 if (pDevice->abyCCKPwrTbl[ii] == 0)
478 pDevice->abyCCKPwrTbl[ii] = pDevice->byCCKPwr;
479 pDevice->abyOFDMPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_OFDM_PWR_TBL];
480 if (pDevice->abyOFDMPwrTbl[ii] == 0)
481 pDevice->abyOFDMPwrTbl[ii] = pDevice->byOFDMPwrG;
482 }
483
484 //original zonetype is USA,but customize zonetype is europe,
485 // then need recover 12,13 ,14 channel with 11 channel
486 if(((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) ||
487 (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe))&&
488 (pDevice->byOriginalZonetype == ZoneType_USA)) {
Andres More33d33e422010-05-19 23:50:00 -0300489 for (ii = 11; ii < 14; ii++) {
490 pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
491 pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
492 }
Forest Bond92b96792009-06-13 07:38:31 -0400493 }
494
495 //{{ RobertYu: 20041124
496 pDevice->byOFDMPwrA = 0x34; // same as RFbMA2829SelectChannel
497 // Load OFDM A Power Table
498 for (ii=0;ii<CB_MAX_CHANNEL_5G;ii++) { //RobertYu:20041224, bug using CB_MAX_CHANNEL
499 pDevice->abyOFDMAPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_OFDMA_PWR_TBL];
500 if (pDevice->abyOFDMAPwrTbl[ii] == 0)
501 pDevice->abyOFDMAPwrTbl[ii] = pDevice->byOFDMPwrA;
502 }
503 //}} RobertYu
504
505 byAntenna = pDevice->abyEEPROM[EEP_OFS_ANTENNA];
506 if (byAntenna & EEP_ANTINV)
507 pDevice->bTxRxAntInv = TRUE;
508 else
509 pDevice->bTxRxAntInv = FALSE;
510
511 byAntenna &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
512
513 if (byAntenna == 0) // if not set default is All
514 byAntenna = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
515
516 if (byAntenna == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
517 pDevice->byAntennaCount = 2;
518 pDevice->byTxAntennaMode = ANT_B;
519 pDevice->dwTxAntennaSel = 1;
520 pDevice->dwRxAntennaSel = 1;
521 if (pDevice->bTxRxAntInv == TRUE)
522 pDevice->byRxAntennaMode = ANT_A;
523 else
524 pDevice->byRxAntennaMode = ANT_B;
525
526 if (pDevice->bDiversityRegCtlON)
527 pDevice->bDiversityEnable = TRUE;
528 else
529 pDevice->bDiversityEnable = FALSE;
530 } else {
531 pDevice->bDiversityEnable = FALSE;
532 pDevice->byAntennaCount = 1;
533 pDevice->dwTxAntennaSel = 0;
534 pDevice->dwRxAntennaSel = 0;
535 if (byAntenna & EEP_ANTENNA_AUX) {
536 pDevice->byTxAntennaMode = ANT_A;
537 if (pDevice->bTxRxAntInv == TRUE)
538 pDevice->byRxAntennaMode = ANT_B;
539 else
540 pDevice->byRxAntennaMode = ANT_A;
541 } else {
542 pDevice->byTxAntennaMode = ANT_B;
543 if (pDevice->bTxRxAntInv == TRUE)
544 pDevice->byRxAntennaMode = ANT_A;
545 else
546 pDevice->byRxAntennaMode = ANT_B;
547 }
548 }
549 pDevice->ulDiversityNValue = 100*255;
550 pDevice->ulDiversityMValue = 100*16;
551 pDevice->byTMax = 1;
552 pDevice->byTMax2 = 4;
553 pDevice->ulSQ3TH = 0;
554 pDevice->byTMax3 = 64;
555 // -----------------------------------------------------------------
556
557 //Get Auto Fall Back Type
558 pDevice->byAutoFBCtrl = AUTO_FB_0;
559
560 // Set SCAN Time
561 pDevice->uScanTime = WLAN_SCAN_MINITIME;
562
563 // default Auto Mode
564 //pDevice->NetworkType = Ndis802_11Automode;
565 pDevice->eConfigPHYMode = PHY_TYPE_AUTO;
566 pDevice->byBBType = BB_TYPE_11G;
567
568 // initialize BBP registers
569 pDevice->ulTxPower = 25;
570
571 // Get Channel range
572 pDevice->byMinChannel = 1;
573 pDevice->byMaxChannel = CB_MAX_CHANNEL;
574
575 // Get RFType
576 pDevice->byRFType = sInitRsp.byRFType;
577
578 if ((pDevice->byRFType & RF_EMU) != 0) {
579 // force change RevID for VT3253 emu
580 pDevice->byRevId = 0x80;
581 }
582
583 // Load EEPROM calibrated vt3266 parameters
584 if (pDevice->byRFType == RF_VT3226D0) {
585 if((pDevice->abyEEPROM[EEP_OFS_MAJOR_VER] == 0x1) &&
586 (pDevice->abyEEPROM[EEP_OFS_MINOR_VER] >= 0x4)) {
587 byCalibTXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_IQ];
588 byCalibTXDC = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_DC];
589 byCalibRXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_RX_IQ];
590 if( (byCalibTXIQ || byCalibTXDC || byCalibRXIQ) ) {
591 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFF, 0x03); // CR255, Set BB to support TX/RX IQ and DC compensation Mode
592 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFB, byCalibTXIQ); // CR251, TX I/Q Imbalance Calibration
593 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFC, byCalibTXDC); // CR252, TX DC-Offset Calibration
594 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFD, byCalibRXIQ); // CR253, RX I/Q Imbalance Calibration
595 } else {
596 // turn off BB Calibration compensation
597 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFF, 0x0); // CR255
598 }
599 }
600 }
601 pMgmt->eScanType = WMAC_SCAN_PASSIVE;
602 pMgmt->uCurrChannel = pDevice->uChannel;
603 pMgmt->uIBSSChannel = pDevice->uChannel;
604 CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel);
605
606 // get Permanent network address
Jim Lieb3e362592009-08-12 14:54:11 -0700607 memcpy(pDevice->abyPermanentNetAddr,&(sInitRsp.byNetAddr[0]),6);
Andres More9a0e7562010-04-13 21:54:48 -0300608 memcpy(pDevice->abyCurrentNetAddr,
609 pDevice->abyPermanentNetAddr,
610 ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -0400611
612 // if exist SW network address, use SW network address.
613
614 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %02x-%02x-%02x=%02x-%02x-%02x\n",
615 pDevice->abyCurrentNetAddr[0],
616 pDevice->abyCurrentNetAddr[1],
617 pDevice->abyCurrentNetAddr[2],
618 pDevice->abyCurrentNetAddr[3],
619 pDevice->abyCurrentNetAddr[4],
620 pDevice->abyCurrentNetAddr[5]);
621 }
622
623
624
625 // Set BB and packet type at the same time.
626 // Set Short Slot Time, xIFS, and RSPINF.
627 if (pDevice->byBBType == BB_TYPE_11A) {
628 CARDbAddBasicRate(pDevice, RATE_6M);
629 pDevice->bShortSlotTime = TRUE;
630 } else {
631 CARDbAddBasicRate(pDevice, RATE_1M);
632 pDevice->bShortSlotTime = FALSE;
633 }
634 BBvSetShortSlotTime(pDevice);
635 CARDvSetBSSMode(pDevice);
636
637 if (pDevice->bUpdateBBVGA) {
638 pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
639 pDevice->byBBVGANew = pDevice->byBBVGACurrent;
640 BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
641 }
642
643 pDevice->byRadioCtl = pDevice->abyEEPROM[EEP_OFS_RADIOCTL];
644 pDevice->bHWRadioOff = FALSE;
645 if ( (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) != 0 ) {
646 ntStatus = CONTROLnsRequestIn(pDevice,
647 MESSAGE_TYPE_READ,
648 MAC_REG_GPIOCTL1,
649 MESSAGE_REQUEST_MACREG,
650 1,
651 &byTmp);
652
653 if ( ntStatus != STATUS_SUCCESS ) {
654 spin_unlock_irq(&pDevice->lock);
655 return FALSE;
656 }
657 if ( (byTmp & GPIO3_DATA) == 0 ) {
658 pDevice->bHWRadioOff = TRUE;
659 MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
660 } else {
661 MACvRegBitsOff(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
662 pDevice->bHWRadioOff = FALSE;
663 }
664
665 } //EEP_RADIOCTL_ENABLE
666
667 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_TMLEN,0x38);
668 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
669 MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL0,0x01);
670
671 if ((pDevice->bHWRadioOff == TRUE) || (pDevice->bRadioControlOff == TRUE)) {
672 CARDbRadioPowerOff(pDevice);
673 } else {
674 CARDbRadioPowerOn(pDevice);
675 }
676
677 spin_unlock_irq(&pDevice->lock);
678 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----INIbInitAdapter Exit\n");
679 return TRUE;
680}
681
682static BOOL device_release_WPADEV(PSDevice pDevice)
683{
684 viawget_wpa_header *wpahdr;
685 int ii=0;
686 // wait_queue_head_t Set_wait;
687 //send device close to wpa_supplicnat layer
688 if (pDevice->bWPADEVUp==TRUE) {
689 wpahdr = (viawget_wpa_header *)pDevice->skb->data;
690 wpahdr->type = VIAWGET_DEVICECLOSE_MSG;
691 wpahdr->resp_ie_len = 0;
692 wpahdr->req_ie_len = 0;
693 skb_put(pDevice->skb, sizeof(viawget_wpa_header));
694 pDevice->skb->dev = pDevice->wpadev;
Jim Liebd899d4032009-07-23 17:22:42 -0700695 skb_reset_mac_header(pDevice->skb);
Forest Bond92b96792009-06-13 07:38:31 -0400696 pDevice->skb->pkt_type = PACKET_HOST;
697 pDevice->skb->protocol = htons(ETH_P_802_2);
698 memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
699 netif_rx(pDevice->skb);
700 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
701
702 //wait release WPADEV
703 // init_waitqueue_head(&Set_wait);
704 // wait_event_timeout(Set_wait, ((pDevice->wpadev==NULL)&&(pDevice->skb == NULL)),5*HZ); //1s wait
705 while(pDevice->bWPADEVUp==TRUE) {
706 set_current_state(TASK_UNINTERRUPTIBLE);
707 schedule_timeout (HZ/20); //wait 50ms
708 ii++;
709 if(ii>20)
710 break;
711 }
712 };
713 return TRUE;
714}
715
716#ifdef CONFIG_PM /* Minimal support for suspend and resume */
Andres More26e5b652010-04-13 19:43:07 -0300717
718static int vt6656_suspend(struct usb_interface *intf, pm_message_t message)
Forest Bond92b96792009-06-13 07:38:31 -0400719{
Andres Moree54d9eb2010-06-21 15:35:43 -0300720 PSDevice device = usb_get_intfdata(intf);
Forest Bond92b96792009-06-13 07:38:31 -0400721
Andres Moree54d9eb2010-06-21 15:35:43 -0300722 if (!device || !device->dev)
723 return -ENODEV;
Forest Bond92b96792009-06-13 07:38:31 -0400724
Andres Moree54d9eb2010-06-21 15:35:43 -0300725 if (device->flags & DEVICE_FLAGS_OPENED)
726 device_close(device->dev);
727
728 usb_put_dev(interface_to_usbdev(intf));
729
730 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400731}
732
Andres More26e5b652010-04-13 19:43:07 -0300733static int vt6656_resume(struct usb_interface *intf)
Forest Bond92b96792009-06-13 07:38:31 -0400734{
Andres Moree54d9eb2010-06-21 15:35:43 -0300735 PSDevice device = usb_get_intfdata(intf);
Forest Bond92b96792009-06-13 07:38:31 -0400736
Andres Moree54d9eb2010-06-21 15:35:43 -0300737 if (!device || !device->dev)
738 return -ENODEV;
739
740 usb_get_dev(interface_to_usbdev(intf));
741
742 if (!(device->flags & DEVICE_FLAGS_OPENED))
743 device_open(device->dev);
744
745 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400746}
Forest Bond92b96792009-06-13 07:38:31 -0400747
Andres More26e5b652010-04-13 19:43:07 -0300748#endif /* CONFIG_PM */
Forest Bonddd8db702009-06-13 07:38:54 -0400749
750static const struct net_device_ops device_netdev_ops = {
751 .ndo_open = device_open,
752 .ndo_stop = device_close,
753 .ndo_do_ioctl = device_ioctl,
754 .ndo_get_stats = device_get_stats,
755 .ndo_start_xmit = device_xmit,
756 .ndo_set_multicast_list = device_set_multi,
757};
758
Andres More26e5b652010-04-13 19:43:07 -0300759static int __devinit
760vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
Forest Bond92b96792009-06-13 07:38:31 -0400761{
Andres More9a0e7562010-04-13 21:54:48 -0300762 u8 fake_mac[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
Forest Bond92b96792009-06-13 07:38:31 -0400763 struct usb_device *udev = interface_to_usbdev(intf);
Andres More7a8b0052010-07-12 12:40:01 -0300764 int rc = 0;
765 struct net_device *netdev = NULL;
766 PSDevice pDevice = NULL;
Forest Bond92b96792009-06-13 07:38:31 -0400767
Andres More7a8b0052010-07-12 12:40:01 -0300768 printk(KERN_NOTICE "%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
769 printk(KERN_NOTICE "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
Forest Bond92b96792009-06-13 07:38:31 -0400770
Andres More7a8b0052010-07-12 12:40:01 -0300771 udev = usb_get_dev(udev);
772 netdev = alloc_etherdev(sizeof(DEVICE_INFO));
Forest Bond92b96792009-06-13 07:38:31 -0400773
Andres More7a8b0052010-07-12 12:40:01 -0300774 if (!netdev) {
775 printk(KERN_ERR DEVICE_NAME ": allocate net device failed\n");
776 kfree(pDevice);
777 goto err_nomem;
778 }
Forest Bond92b96792009-06-13 07:38:31 -0400779
Andres More7a8b0052010-07-12 12:40:01 -0300780 pDevice = netdev_priv(netdev);
781 memset(pDevice, 0, sizeof(DEVICE_INFO));
Forest Bond92b96792009-06-13 07:38:31 -0400782
Andres More7a8b0052010-07-12 12:40:01 -0300783 pDevice->dev = netdev;
784 pDevice->usb = udev;
Forest Bond1e28efa2009-06-13 07:38:50 -0400785
Andres More7a8b0052010-07-12 12:40:01 -0300786 device_set_options(pDevice);
787 spin_lock_init(&pDevice->lock);
Forest Bond1e28efa2009-06-13 07:38:50 -0400788
Andres More7a8b0052010-07-12 12:40:01 -0300789 pDevice->tx_80211 = device_dma0_tx_80211;
790 pDevice->sMgmtObj.pAdapter = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400791
Andres More7a8b0052010-07-12 12:40:01 -0300792 netdev->netdev_ops = &device_netdev_ops;
793 netdev->wireless_handlers =
794 (struct iw_handler_def *) &iwctl_handler_def;
Forest Bond92b96792009-06-13 07:38:31 -0400795
Andres More7a8b0052010-07-12 12:40:01 -0300796 usb_set_intfdata(intf, pDevice);
Forest Bond92b96792009-06-13 07:38:31 -0400797 SET_NETDEV_DEV(netdev, &intf->dev);
Andres More7a8b0052010-07-12 12:40:01 -0300798 memcpy(pDevice->dev->dev_addr, fake_mac, ETH_ALEN);
799 rc = register_netdev(netdev);
800 if (rc) {
801 printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
Forest Bond92b96792009-06-13 07:38:31 -0400802 free_netdev(netdev);
Andres More7a8b0052010-07-12 12:40:01 -0300803 kfree(pDevice);
804 return -ENODEV;
805 }
Forest Bond92b96792009-06-13 07:38:31 -0400806
Andres More7a8b0052010-07-12 12:40:01 -0300807 usb_device_reset(pDevice);
Forest Bond92b96792009-06-13 07:38:31 -0400808
Andres More7a8b0052010-07-12 12:40:01 -0300809 {
810 union iwreq_data wrqu;
811 memset(&wrqu, 0, sizeof(wrqu));
812 wrqu.data.flags = RT_INSMOD_EVENT_FLAG;
813 wrqu.data.length = IFNAMSIZ;
814 wireless_send_event(pDevice->dev,
815 IWEVCUSTOM,
816 &wrqu,
817 pDevice->dev->name);
818 }
Forest Bond92b96792009-06-13 07:38:31 -0400819
820 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400821
Forest Bond92b96792009-06-13 07:38:31 -0400822err_nomem:
Andres More7a8b0052010-07-12 12:40:01 -0300823 usb_put_dev(udev);
Forest Bond92b96792009-06-13 07:38:31 -0400824
Andres More7a8b0052010-07-12 12:40:01 -0300825 return -ENOMEM;
Forest Bond92b96792009-06-13 07:38:31 -0400826}
827
Andres More8611a292010-05-01 14:25:00 -0300828static void device_free_tx_bufs(PSDevice pDevice)
829{
Forest Bond92b96792009-06-13 07:38:31 -0400830 PUSB_SEND_CONTEXT pTxContext;
831 int ii;
832
833 for (ii = 0; ii < pDevice->cbTD; ii++) {
834
835 pTxContext = pDevice->apTD[ii];
836 //de-allocate URBs
837 if (pTxContext->pUrb) {
Jim Liebdad72fe2009-08-12 14:54:14 -0700838 usb_kill_urb(pTxContext->pUrb);
Forest Bond92b96792009-06-13 07:38:31 -0400839 usb_free_urb(pTxContext->pUrb);
840 }
841 if (pTxContext)
842 kfree(pTxContext);
843 }
844 return;
845}
846
847
Andres More8611a292010-05-01 14:25:00 -0300848static void device_free_rx_bufs(PSDevice pDevice)
849{
Forest Bond92b96792009-06-13 07:38:31 -0400850 PRCB pRCB;
851 int ii;
852
853 for (ii = 0; ii < pDevice->cbRD; ii++) {
854
855 pRCB = pDevice->apRCB[ii];
856 //de-allocate URBs
857 if (pRCB->pUrb) {
Jim Liebdad72fe2009-08-12 14:54:14 -0700858 usb_kill_urb(pRCB->pUrb);
Forest Bond92b96792009-06-13 07:38:31 -0400859 usb_free_urb(pRCB->pUrb);
860 }
861 //de-allocate skb
862 if (pRCB->skb)
863 dev_kfree_skb(pRCB->skb);
864 }
865 if (pDevice->pRCBMem)
866 kfree(pDevice->pRCBMem);
867
868 return;
869}
870
Forest Bond92b96792009-06-13 07:38:31 -0400871static void usb_device_reset(PSDevice pDevice)
872{
873 int status;
874 status = usb_reset_device(pDevice->usb);
875 if (status)
876 printk("usb_device_reset fail status=%d\n",status);
877 return ;
878}
Forest Bond92b96792009-06-13 07:38:31 -0400879
Andres More8611a292010-05-01 14:25:00 -0300880static void device_free_int_bufs(PSDevice pDevice)
881{
Forest Bond92b96792009-06-13 07:38:31 -0400882 if (pDevice->intBuf.pDataBuf != NULL)
883 kfree(pDevice->intBuf.pDataBuf);
884 return;
885}
886
887
888static BOOL device_alloc_bufs(PSDevice pDevice) {
889
890 PUSB_SEND_CONTEXT pTxContext;
891 PRCB pRCB;
892 int ii;
893
894
895 for (ii = 0; ii < pDevice->cbTD; ii++) {
896
897 pTxContext = kmalloc(sizeof(USB_SEND_CONTEXT), GFP_KERNEL);
898 if (pTxContext == NULL) {
899 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : allocate tx usb context failed\n", pDevice->dev->name);
900 goto free_tx;
901 }
902 pDevice->apTD[ii] = pTxContext;
Andres More8611a292010-05-01 14:25:00 -0300903 pTxContext->pDevice = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400904 //allocate URBs
Jim Liebdad72fe2009-08-12 14:54:14 -0700905 pTxContext->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400906 if (pTxContext->pUrb == NULL) {
907 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "alloc tx urb failed\n");
908 goto free_tx;
909 }
910 pTxContext->bBoolInUse = FALSE;
911 }
912
913 // allocate rcb mem
914 pDevice->pRCBMem = kmalloc((sizeof(RCB) * pDevice->cbRD), GFP_KERNEL);
915 if (pDevice->pRCBMem == NULL) {
916 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : alloc rx usb context failed\n", pDevice->dev->name);
917 goto free_tx;
918 }
919
920
921 pDevice->FirstRecvFreeList = NULL;
922 pDevice->LastRecvFreeList = NULL;
923 pDevice->FirstRecvMngList = NULL;
924 pDevice->LastRecvMngList = NULL;
925 pDevice->NumRecvFreeList = 0;
926 memset(pDevice->pRCBMem, 0, (sizeof(RCB) * pDevice->cbRD));
927 pRCB = (PRCB) pDevice->pRCBMem;
928
929 for (ii = 0; ii < pDevice->cbRD; ii++) {
930
931 pDevice->apRCB[ii] = pRCB;
Andres More8611a292010-05-01 14:25:00 -0300932 pRCB->pDevice = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400933 //allocate URBs
Jim Liebdad72fe2009-08-12 14:54:14 -0700934 pRCB->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400935
936 if (pRCB->pUrb == NULL) {
937 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx urb\n");
938 goto free_rx_tx;
939 }
940 pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
941 if (pRCB->skb == NULL) {
942 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx skb\n");
943 goto free_rx_tx;
944 }
945 pRCB->skb->dev = pDevice->dev;
946 pRCB->bBoolInUse = FALSE;
947 EnqueueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList, pRCB);
948 pDevice->NumRecvFreeList++;
949 pRCB++;
950 }
951
952
Jim Liebdad72fe2009-08-12 14:54:14 -0700953 pDevice->pControlURB = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400954 if (pDevice->pControlURB == NULL) {
955 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc control urb\n");
956 goto free_rx_tx;
957 }
958
Jim Liebdad72fe2009-08-12 14:54:14 -0700959 pDevice->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400960 if (pDevice->pInterruptURB == NULL) {
961 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int urb\n");
Jim Liebdad72fe2009-08-12 14:54:14 -0700962 usb_kill_urb(pDevice->pControlURB);
Forest Bond92b96792009-06-13 07:38:31 -0400963 usb_free_urb(pDevice->pControlURB);
964 goto free_rx_tx;
965 }
966
967 pDevice->intBuf.pDataBuf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
968 if (pDevice->intBuf.pDataBuf == NULL) {
969 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int buf\n");
Jim Liebdad72fe2009-08-12 14:54:14 -0700970 usb_kill_urb(pDevice->pControlURB);
971 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -0400972 usb_free_urb(pDevice->pControlURB);
973 usb_free_urb(pDevice->pInterruptURB);
974 goto free_rx_tx;
975 }
976
977 return TRUE;
978
979free_rx_tx:
980 device_free_rx_bufs(pDevice);
981
982free_tx:
983 device_free_tx_bufs(pDevice);
984
985 return FALSE;
986}
987
988
989
990
991static BOOL device_init_defrag_cb(PSDevice pDevice) {
992 int i;
993 PSDeFragControlBlock pDeF;
994
995 /* Init the fragment ctl entries */
996 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
997 pDeF = &(pDevice->sRxDFCB[i]);
998 if (!device_alloc_frag_buf(pDevice, pDeF)) {
999 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
1000 pDevice->dev->name);
1001 goto free_frag;
1002 };
1003 }
1004 pDevice->cbDFCB = CB_MAX_RX_FRAG;
1005 pDevice->cbFreeDFCB = pDevice->cbDFCB;
1006 return TRUE;
1007
1008free_frag:
1009 device_free_frag_bufs(pDevice);
1010 return FALSE;
1011}
1012
1013
1014
1015static void device_free_frag_bufs(PSDevice pDevice) {
1016 PSDeFragControlBlock pDeF;
1017 int i;
1018
1019 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
1020
1021 pDeF = &(pDevice->sRxDFCB[i]);
1022
1023 if (pDeF->skb)
1024 dev_kfree_skb(pDeF->skb);
1025 }
1026}
1027
1028
1029
1030BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
1031
1032 pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1033 if (pDeF->skb == NULL)
1034 return FALSE;
1035 ASSERT(pDeF->skb);
1036 pDeF->skb->dev = pDevice->dev;
1037
1038 return TRUE;
1039}
1040
1041
1042/*-----------------------------------------------------------------*/
1043
1044static int device_open(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001045 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001046
Forest Bond92b96792009-06-13 07:38:31 -04001047 extern SWPAResult wpa_Result;
1048 memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname));
1049 wpa_Result.proto = 0;
1050 wpa_Result.key_mgmt = 0;
1051 wpa_Result.eap_type = 0;
1052 wpa_Result.authenticated = FALSE;
1053 pDevice->fWPA_Authened = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001054
1055 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_open...\n");
1056
1057
1058 pDevice->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
1059
1060 if (device_alloc_bufs(pDevice) == FALSE) {
1061 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_alloc_bufs fail... \n");
1062 return -ENOMEM;
1063 }
1064
1065 if (device_init_defrag_cb(pDevice)== FALSE) {
1066 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Initial defragement cb fail \n");
1067 goto free_rx_tx;
1068 }
1069
1070 MP_CLEAR_FLAG(pDevice, fMP_DISCONNECTED);
1071 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
1072 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
1073 MP_SET_FLAG(pDevice, fMP_POST_READS);
1074 MP_SET_FLAG(pDevice, fMP_POST_WRITES);
1075
1076 //read config file
1077 Read_config_file(pDevice);
1078
1079 if (device_init_registers(pDevice, DEVICE_INIT_COLD) == FALSE) {
1080 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " init register fail\n");
1081 goto free_all;
1082 }
1083
1084 device_set_multi(pDevice->dev);
1085 // Init for Key Management
1086
1087 KeyvInitTable(pDevice,&pDevice->sKey);
Andres More9a0e7562010-04-13 21:54:48 -03001088 memcpy(pDevice->sMgmtObj.abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN);
1089 memcpy(pDevice->dev->dev_addr, pDevice->abyCurrentNetAddr, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001090 pDevice->bStopTx0Pkt = FALSE;
1091 pDevice->bStopDataPkt = FALSE;
Andres More465711b2010-08-03 20:25:50 -03001092 pDevice->bRoaming = FALSE;
1093 pDevice->bIsRoaming = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001094 pDevice->bEnableRoaming = FALSE;
1095 if (pDevice->bDiversityRegCtlON) {
1096 device_init_diversity_timer(pDevice);
1097 }
1098
1099 vMgrObjectInit(pDevice);
1100 tasklet_init(&pDevice->RxMngWorkItem, (void *)RXvMngWorkItem, (unsigned long)pDevice);
1101 tasklet_init(&pDevice->ReadWorkItem, (void *)RXvWorkItem, (unsigned long)pDevice);
1102 tasklet_init(&pDevice->EventWorkItem, (void *)INTvWorkItem, (unsigned long)pDevice);
1103 add_timer(&(pDevice->sMgmtObj.sTimerSecondCallback));
Forest Bond92b96792009-06-13 07:38:31 -04001104 pDevice->int_interval = 100; //Max 100 microframes.
Forest Bond92b96792009-06-13 07:38:31 -04001105 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1106
1107 pDevice->bIsRxWorkItemQueued = TRUE;
1108 pDevice->fKillEventPollingThread = FALSE;
1109 pDevice->bEventAvailable = FALSE;
1110
1111 pDevice->bWPADEVUp = FALSE;
1112#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1113 pDevice->bwextstep0 = FALSE;
1114 pDevice->bwextstep1 = FALSE;
1115 pDevice->bwextstep2 = FALSE;
1116 pDevice->bwextstep3 = FALSE;
1117 pDevice->bWPASuppWextEnabled = FALSE;
1118#endif
1119 pDevice->byReAssocCount = 0;
1120
1121 RXvWorkItem(pDevice);
1122 INTvWorkItem(pDevice);
1123
1124 // Patch: if WEP key already set by iwconfig but device not yet open
1125 if ((pDevice->bEncryptionEnable == TRUE) && (pDevice->bTransmitKey == TRUE)) {
1126 spin_lock_irq(&pDevice->lock);
1127 KeybSetDefaultKey( pDevice,
1128 &(pDevice->sKey),
1129 pDevice->byKeyIndex | (1 << 31),
1130 pDevice->uKeyLength,
1131 NULL,
1132 pDevice->abyKey,
1133 KEY_CTL_WEP
1134 );
1135 spin_unlock_irq(&pDevice->lock);
1136 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1137 }
1138
1139 if (pDevice->sMgmtObj.eConfigMode == WMAC_CONFIG_AP) {
Andres More0cbd8d92010-05-06 20:34:29 -03001140 bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001141 }
1142 else {
1143 //mike:mark@2008-11-10
Andres More0cbd8d92010-05-06 20:34:29 -03001144 bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
1145 /* bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); */
Forest Bond92b96792009-06-13 07:38:31 -04001146 }
1147
1148
1149 netif_stop_queue(pDevice->dev);
1150 pDevice->flags |= DEVICE_FLAGS_OPENED;
1151
Forest Bond92b96792009-06-13 07:38:31 -04001152{
1153 union iwreq_data wrqu;
1154 memset(&wrqu, 0, sizeof(wrqu));
1155 wrqu.data.flags = RT_UPDEV_EVENT_FLAG;
1156 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1157}
Forest Bond92b96792009-06-13 07:38:31 -04001158
1159 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
1160 return 0;
1161
1162free_all:
1163 device_free_frag_bufs(pDevice);
1164free_rx_tx:
1165 device_free_rx_bufs(pDevice);
1166 device_free_tx_bufs(pDevice);
1167 device_free_int_bufs(pDevice);
Jim Liebdad72fe2009-08-12 14:54:14 -07001168 usb_kill_urb(pDevice->pControlURB);
1169 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -04001170 usb_free_urb(pDevice->pControlURB);
1171 usb_free_urb(pDevice->pInterruptURB);
1172
1173 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open fail.. \n");
1174 return -ENOMEM;
1175}
1176
1177
1178
1179static int device_close(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001180 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001181 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1182
Forest Bond92b96792009-06-13 07:38:31 -04001183 int uu;
Forest Bond92b96792009-06-13 07:38:31 -04001184
1185 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close1 \n");
1186 if (pDevice == NULL)
1187 return -ENODEV;
1188
Forest Bond92b96792009-06-13 07:38:31 -04001189{
1190 union iwreq_data wrqu;
1191 memset(&wrqu, 0, sizeof(wrqu));
1192 wrqu.data.flags = RT_DOWNDEV_EVENT_FLAG;
1193 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1194}
Forest Bond92b96792009-06-13 07:38:31 -04001195
Forest Bond92b96792009-06-13 07:38:31 -04001196 if (pDevice->bLinkPass) {
Andres More0cbd8d92010-05-06 20:34:29 -03001197 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001198 mdelay(30);
1199 }
Forest Bond92b96792009-06-13 07:38:31 -04001200
Forest Bond92b96792009-06-13 07:38:31 -04001201device_release_WPADEV(pDevice);
1202
Forest Bond92b96792009-06-13 07:38:31 -04001203 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
1204 pMgmt->bShareKeyAlgorithm = FALSE;
1205 pDevice->bEncryptionEnable = FALSE;
1206 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
Andres More33d33e422010-05-19 23:50:00 -03001207 spin_lock_irq(&pDevice->lock);
1208 for (uu = 0; uu < MAX_KEY_TABLE; uu++)
Forest Bond92b96792009-06-13 07:38:31 -04001209 MACvDisableKeyEntry(pDevice,uu);
Andres More33d33e422010-05-19 23:50:00 -03001210 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001211
1212 if ((pDevice->flags & DEVICE_FLAGS_UNPLUG) == FALSE) {
1213 MACbShutdown(pDevice);
1214 }
1215 netif_stop_queue(pDevice->dev);
1216 MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
1217 MP_CLEAR_FLAG(pDevice, fMP_POST_WRITES);
1218 MP_CLEAR_FLAG(pDevice, fMP_POST_READS);
1219 pDevice->fKillEventPollingThread = TRUE;
1220 del_timer(&pDevice->sTimerCommand);
1221 del_timer(&pMgmt->sTimerSecondCallback);
1222
Forest Bond92b96792009-06-13 07:38:31 -04001223 del_timer(&pDevice->sTimerTxData);
Forest Bond92b96792009-06-13 07:38:31 -04001224
1225 if (pDevice->bDiversityRegCtlON) {
1226 del_timer(&pDevice->TimerSQ3Tmax1);
1227 del_timer(&pDevice->TimerSQ3Tmax2);
1228 del_timer(&pDevice->TimerSQ3Tmax3);
1229 }
1230 tasklet_kill(&pDevice->RxMngWorkItem);
1231 tasklet_kill(&pDevice->ReadWorkItem);
1232 tasklet_kill(&pDevice->EventWorkItem);
1233
Andres More465711b2010-08-03 20:25:50 -03001234 pDevice->bRoaming = FALSE;
1235 pDevice->bIsRoaming = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001236 pDevice->bEnableRoaming = FALSE;
1237 pDevice->bCmdRunning = FALSE;
1238 pDevice->bLinkPass = FALSE;
1239 memset(pMgmt->abyCurrBSSID, 0, 6);
1240 pMgmt->eCurrState = WMAC_STATE_IDLE;
1241
1242 device_free_tx_bufs(pDevice);
1243 device_free_rx_bufs(pDevice);
1244 device_free_int_bufs(pDevice);
1245 device_free_frag_bufs(pDevice);
1246
Jim Liebdad72fe2009-08-12 14:54:14 -07001247 usb_kill_urb(pDevice->pControlURB);
1248 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -04001249 usb_free_urb(pDevice->pControlURB);
1250 usb_free_urb(pDevice->pInterruptURB);
1251
1252 BSSvClearNodeDBTable(pDevice, 0);
1253 pDevice->flags &=(~DEVICE_FLAGS_OPENED);
1254
1255 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n");
1256
1257 return 0;
1258}
1259
Andres More26e5b652010-04-13 19:43:07 -03001260static void __devexit vt6656_disconnect(struct usb_interface *intf)
Forest Bond92b96792009-06-13 07:38:31 -04001261{
Andres More6cda24f2010-06-22 20:43:39 -03001262 PSDevice device = usb_get_intfdata(intf);
Forest Bond92b96792009-06-13 07:38:31 -04001263
Andres More6cda24f2010-06-22 20:43:39 -03001264 if (!device)
1265 return;
Forest Bond92b96792009-06-13 07:38:31 -04001266
Andres More6cda24f2010-06-22 20:43:39 -03001267 {
1268 union iwreq_data req;
1269 memset(&req, 0, sizeof(req));
1270 req.data.flags = RT_RMMOD_EVENT_FLAG;
1271 wireless_send_event(device->dev, IWEVCUSTOM, &req, NULL);
1272 }
Forest Bond92b96792009-06-13 07:38:31 -04001273
Andres More6cda24f2010-06-22 20:43:39 -03001274 device_release_WPADEV(device);
Forest Bond92b96792009-06-13 07:38:31 -04001275
Forest Bond92b96792009-06-13 07:38:31 -04001276 usb_set_intfdata(intf, NULL);
Andres More6cda24f2010-06-22 20:43:39 -03001277 usb_put_dev(interface_to_usbdev(intf));
Forest Bond92b96792009-06-13 07:38:31 -04001278
Andres More6cda24f2010-06-22 20:43:39 -03001279 device->flags |= DEVICE_FLAGS_UNPLUG;
Forest Bond92b96792009-06-13 07:38:31 -04001280
Andres More6cda24f2010-06-22 20:43:39 -03001281 if (device->dev) {
1282 unregister_netdev(device->dev);
1283 wpa_set_wpadev(device, 0);
1284 free_netdev(device->dev);
1285 }
Forest Bond92b96792009-06-13 07:38:31 -04001286}
1287
Andres Moree1669ed2010-07-12 13:10:27 -03001288static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev)
1289{
1290 PSDevice pDevice = netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001291
Andres Moree1669ed2010-07-12 13:10:27 -03001292 spin_lock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001293
Andres Moree1669ed2010-07-12 13:10:27 -03001294 if (unlikely(pDevice->bStopTx0Pkt))
1295 dev_kfree_skb_irq(skb);
1296 else
1297 vDMA0_tx_80211(pDevice, skb);
Forest Bond92b96792009-06-13 07:38:31 -04001298
Andres Moree1669ed2010-07-12 13:10:27 -03001299 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001300
Andres Moree1669ed2010-07-12 13:10:27 -03001301 return NETDEV_TX_OK;
Forest Bond92b96792009-06-13 07:38:31 -04001302}
1303
Andres More529e5b32010-07-12 19:28:25 -03001304static int device_xmit(struct sk_buff *skb, struct net_device *dev)
1305{
1306 PSDevice pDevice = netdev_priv(dev);
1307 struct net_device_stats *stats = &pDevice->stats;
Forest Bond92b96792009-06-13 07:38:31 -04001308
Andres More529e5b32010-07-12 19:28:25 -03001309 spin_lock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001310
Andres More529e5b32010-07-12 19:28:25 -03001311 netif_stop_queue(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001312
Andres More529e5b32010-07-12 19:28:25 -03001313 if (!pDevice->bLinkPass) {
1314 dev_kfree_skb_irq(skb);
1315 goto out;
1316 }
Forest Bond92b96792009-06-13 07:38:31 -04001317
Andres More529e5b32010-07-12 19:28:25 -03001318 if (pDevice->bStopDataPkt) {
1319 dev_kfree_skb_irq(skb);
1320 stats->tx_dropped++;
1321 goto out;
1322 }
Forest Bond92b96792009-06-13 07:38:31 -04001323
Andres More529e5b32010-07-12 19:28:25 -03001324 if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb)) {
1325 if (netif_queue_stopped(dev))
1326 netif_wake_queue(dev);
1327 }
Forest Bond92b96792009-06-13 07:38:31 -04001328
Andres More529e5b32010-07-12 19:28:25 -03001329out:
1330 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001331
Andres More529e5b32010-07-12 19:28:25 -03001332 return NETDEV_TX_OK;
Forest Bond92b96792009-06-13 07:38:31 -04001333}
1334
Forest Bond92b96792009-06-13 07:38:31 -04001335static unsigned const ethernet_polynomial = 0x04c11db7U;
1336static inline u32 ether_crc(int length, unsigned char *data)
1337{
1338 int crc = -1;
1339
1340 while(--length >= 0) {
1341 unsigned char current_octet = *data++;
1342 int bit;
1343 for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
1344 crc = (crc << 1) ^
1345 ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
1346 }
1347 }
1348 return crc;
1349}
1350
1351//find out the start position of str2 from str1
Andres Morecc856e62010-05-17 21:34:01 -03001352static unsigned char *kstrstr(const unsigned char *str1,
1353 const unsigned char *str2) {
1354 int str1_len = strlen(str1);
1355 int str2_len = strlen(str2);
Forest Bond92b96792009-06-13 07:38:31 -04001356
1357 while (str1_len >= str2_len) {
1358 str1_len--;
1359 if(memcmp(str1,str2,str2_len)==0)
Andres Morecc856e62010-05-17 21:34:01 -03001360 return (unsigned char *) str1;
Forest Bond92b96792009-06-13 07:38:31 -04001361 str1++;
1362 }
1363 return NULL;
1364}
1365
Andres Morecc856e62010-05-17 21:34:01 -03001366static int Config_FileGetParameter(unsigned char *string,
1367 unsigned char *dest,
1368 unsigned char *source)
Forest Bond92b96792009-06-13 07:38:31 -04001369{
Andres Morecc856e62010-05-17 21:34:01 -03001370 unsigned char buf1[100];
1371 unsigned char buf2[100];
1372 unsigned char *start_p = NULL, *end_p = NULL, *tmp_p = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001373 int ii;
1374
1375 memset(buf1,0,100);
1376 strcat(buf1, string);
1377 strcat(buf1, "=");
1378 source+=strlen(buf1);
1379
1380//find target string start point
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001381 start_p = kstrstr(source,buf1);
1382 if (start_p == NULL)
Forest Bond92b96792009-06-13 07:38:31 -04001383 return FALSE;
1384
1385//check if current config line is marked by "#" ??
Andres More33d33e422010-05-19 23:50:00 -03001386 for (ii = 1; ; ii++) {
1387 if (memcmp(start_p - ii, "\n", 1) == 0)
1388 break;
1389 if (memcmp(start_p - ii, "#", 1) == 0)
1390 return FALSE;
1391 }
Forest Bond92b96792009-06-13 07:38:31 -04001392
1393//find target string end point
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001394 end_p = kstrstr(start_p,"\n");
1395 if (end_p == NULL) { //can't find "\n",but don't care
Forest Bond92b96792009-06-13 07:38:31 -04001396 end_p=start_p+strlen(start_p); //no include "\n"
1397 }
1398
1399 memset(buf2,0,100);
1400 memcpy(buf2,start_p,end_p-start_p); //get the tartget line
1401 buf2[end_p-start_p]='\0';
1402
1403 //find value
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001404 start_p = kstrstr(buf2,"=");
1405 if (start_p == NULL)
Forest Bond92b96792009-06-13 07:38:31 -04001406 return FALSE;
1407 memset(buf1,0,100);
1408 strcpy(buf1,start_p+1);
1409
1410 //except space
1411 tmp_p = buf1;
1412 while(*tmp_p != 0x00) {
1413 if(*tmp_p==' ')
1414 tmp_p++;
1415 else
1416 break;
1417 }
1418
1419 memcpy(dest,tmp_p,strlen(tmp_p));
1420 return TRUE;
1421}
1422
1423//if read fail,return NULL,or return data pointer;
Andres Morecc856e62010-05-17 21:34:01 -03001424static unsigned char *Config_FileOperation(PSDevice pDevice)
1425{
1426 unsigned char *config_path = CONFIG_PATH;
1427 unsigned char *buffer = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001428 struct file *filp=NULL;
1429 mm_segment_t old_fs = get_fs();
Forest Bond8f9c4662009-06-13 07:38:47 -04001430 //int oldfsuid=0,oldfsgid=0;
Andres Morecc856e62010-05-17 21:34:01 -03001431 int result = 0;
Forest Bond92b96792009-06-13 07:38:31 -04001432
1433 set_fs (KERNEL_DS);
Forest Bond8f9c4662009-06-13 07:38:47 -04001434 /* Can't do this anymore, so we rely on correct filesystem permissions:
1435 //Make sure a caller can read or write power as root
1436 oldfsuid=current->fsuid;
1437 oldfsgid=current->fsgid;
Forest Bond92b96792009-06-13 07:38:31 -04001438 current->fsuid = 0;
1439 current->fsgid = 0;
Forest Bond8f9c4662009-06-13 07:38:47 -04001440 */
Forest Bond92b96792009-06-13 07:38:31 -04001441
1442 //open file
1443 filp = filp_open(config_path, O_RDWR, 0);
1444 if (IS_ERR(filp)) {
1445 printk("Config_FileOperation file Not exist\n");
1446 result=-1;
1447 goto error2;
1448 }
1449
1450 if(!(filp->f_op) || !(filp->f_op->read) ||!(filp->f_op->write)) {
1451 printk("file %s cann't readable or writable?\n",config_path);
1452 result = -1;
1453 goto error1;
1454 }
1455
Julia Lawall32414872010-05-11 20:26:57 +02001456 buffer = kmalloc(1024, GFP_KERNEL);
Forest Bond92b96792009-06-13 07:38:31 -04001457 if(buffer==NULL) {
1458 printk("alllocate mem for file fail?\n");
1459 result = -1;
1460 goto error1;
1461 }
1462
1463 if(filp->f_op->read(filp, buffer, 1024, &filp->f_pos)<0) {
1464 printk("read file error?\n");
1465 result = -1;
1466 }
1467
1468error1:
1469 if(filp_close(filp,NULL))
1470 printk("Config_FileOperation:close file fail\n");
1471
1472error2:
1473 set_fs (old_fs);
Forest Bond8f9c4662009-06-13 07:38:47 -04001474
1475 /*
Forest Bond92b96792009-06-13 07:38:31 -04001476 current->fsuid=oldfsuid;
1477 current->fsgid=oldfsgid;
Forest Bond8f9c4662009-06-13 07:38:47 -04001478 */
Forest Bond92b96792009-06-13 07:38:31 -04001479
1480if(result!=0) {
1481 if(buffer)
1482 kfree(buffer);
1483 buffer=NULL;
1484}
1485 return buffer;
1486}
1487
André Goddard Rosabbc9a992009-11-14 13:09:06 -02001488//return --->-1:fail; >=0:successful
Forest Bond92b96792009-06-13 07:38:31 -04001489static int Read_config_file(PSDevice pDevice) {
Andres Morecc856e62010-05-17 21:34:01 -03001490 int result = 0;
1491 unsigned char tmpbuffer[100];
1492 unsigned char *buffer = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001493
1494 //init config setting
1495 pDevice->config_file.ZoneType = -1;
1496 pDevice->config_file.eAuthenMode = -1;
1497 pDevice->config_file.eEncryptionStatus = -1;
1498
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001499 buffer = Config_FileOperation(pDevice);
1500 if (buffer == NULL) {
Forest Bond92b96792009-06-13 07:38:31 -04001501 result =-1;
1502 return result;
1503 }
1504
1505//get zonetype
1506{
1507 memset(tmpbuffer,0,sizeof(tmpbuffer));
1508 if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer) ==TRUE) {
1509 if(memcmp(tmpbuffer,"USA",3)==0) {
1510 pDevice->config_file.ZoneType=ZoneType_USA;
1511 }
1512 else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
1513 pDevice->config_file.ZoneType=ZoneType_Japan;
1514 }
1515 else if(memcmp(tmpbuffer,"EUROPE",6)==0) {
1516 pDevice->config_file.ZoneType=ZoneType_Europe;
1517 }
1518 else {
1519 printk("Unknown Zonetype[%s]?\n",tmpbuffer);
1520 }
1521 }
1522}
1523
Forest Bond92b96792009-06-13 07:38:31 -04001524//get other parameter
1525 {
1526 memset(tmpbuffer,0,sizeof(tmpbuffer));
1527 if(Config_FileGetParameter("AUTHENMODE",tmpbuffer,buffer)==TRUE) {
1528 pDevice->config_file.eAuthenMode = (int) simple_strtol(tmpbuffer, NULL, 10);
1529 }
1530
1531 memset(tmpbuffer,0,sizeof(tmpbuffer));
1532 if(Config_FileGetParameter("ENCRYPTIONMODE",tmpbuffer,buffer)==TRUE) {
1533 pDevice->config_file.eEncryptionStatus= (int) simple_strtol(tmpbuffer, NULL, 10);
1534 }
1535 }
Forest Bond92b96792009-06-13 07:38:31 -04001536
1537 kfree(buffer);
1538 return result;
1539}
1540
1541static void device_set_multi(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001542 PSDevice pDevice = (PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001543 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1544 u32 mc_filter[2];
1545 int ii;
Jiri Pirko22bedad32010-04-01 21:22:57 +00001546 struct netdev_hw_addr *ha;
Forest Bond92b96792009-06-13 07:38:31 -04001547 BYTE pbyData[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1548 BYTE byTmpMode = 0;
1549 int rc;
1550
1551
1552 spin_lock_irq(&pDevice->lock);
1553 rc = CONTROLnsRequestIn(pDevice,
1554 MESSAGE_TYPE_READ,
1555 MAC_REG_RCR,
1556 MESSAGE_REQUEST_MACREG,
1557 1,
1558 &byTmpMode
1559 );
1560 if (rc == 0) pDevice->byRxMode = byTmpMode;
1561
1562 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode in= %x\n", pDevice->byRxMode);
1563
1564 if (dev->flags & IFF_PROMISC) { // Set promiscuous.
1565 DBG_PRT(MSG_LEVEL_ERR,KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
1566 // Unconditionally log net taps.
1567 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
1568 }
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001569 else if ((netdev_mc_count(dev) > pDevice->multicast_limit) ||
1570 (dev->flags & IFF_ALLMULTI)) {
Forest Bond92b96792009-06-13 07:38:31 -04001571 CONTROLnsRequestOut(pDevice,
1572 MESSAGE_TYPE_WRITE,
1573 MAC_REG_MAR0,
1574 MESSAGE_REQUEST_MACREG,
1575 8,
1576 pbyData
1577 );
1578 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1579 }
1580 else {
1581 memset(mc_filter, 0, sizeof(mc_filter));
Jiri Pirko22bedad32010-04-01 21:22:57 +00001582 netdev_for_each_mc_addr(ha, dev) {
1583 int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
Forest Bond92b96792009-06-13 07:38:31 -04001584 mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
1585 }
1586 for (ii = 0; ii < 4; ii++) {
1587 MACvWriteMultiAddr(pDevice, ii, *((PBYTE)&mc_filter[0] + ii));
1588 MACvWriteMultiAddr(pDevice, ii+ 4, *((PBYTE)&mc_filter[1] + ii));
1589 }
1590 pDevice->byRxMode &= ~(RCR_UNICAST);
1591 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1592 }
1593
1594 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
1595 // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac.
1596 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1597 pDevice->byRxMode &= ~(RCR_UNICAST);
1598 }
1599 ControlvWriteByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_RCR, pDevice->byRxMode);
1600 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode out= %x\n", pDevice->byRxMode);
1601 spin_unlock_irq(&pDevice->lock);
1602
1603}
1604
1605
1606static struct net_device_stats *device_get_stats(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001607 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001608
1609 return &pDevice->stats;
1610}
1611
1612
1613static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001614 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001615 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1616 PSCmdRequest pReq;
1617 //BOOL bCommit = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001618 struct iwreq *wrq = (struct iwreq *) rq;
1619 int rc =0;
Forest Bond92b96792009-06-13 07:38:31 -04001620
1621 if (pMgmt == NULL) {
1622 rc = -EFAULT;
1623 return rc;
1624 }
1625
1626 switch(cmd) {
1627
Forest Bond92b96792009-06-13 07:38:31 -04001628 case SIOCGIWNAME:
1629 rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL);
1630 break;
1631
1632 case SIOCSIWNWID:
1633 rc = -EOPNOTSUPP;
1634 break;
1635
1636 case SIOCGIWNWID: //0x8b03 support
1637 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1638 rc = iwctl_giwnwid(dev, NULL, &(wrq->u.nwid), NULL);
1639 #else
1640 rc = -EOPNOTSUPP;
1641 #endif
1642 break;
1643
1644 // Set frequency/channel
1645 case SIOCSIWFREQ:
1646 rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL);
1647 break;
1648
1649 // Get frequency/channel
1650 case SIOCGIWFREQ:
1651 rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL);
1652 break;
1653
1654 // Set desired network name (ESSID)
1655 case SIOCSIWESSID:
1656
1657 {
1658 char essid[IW_ESSID_MAX_SIZE+1];
1659 if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
1660 rc = -E2BIG;
1661 break;
1662 }
1663 if (copy_from_user(essid, wrq->u.essid.pointer,
1664 wrq->u.essid.length)) {
1665 rc = -EFAULT;
1666 break;
1667 }
1668 rc = iwctl_siwessid(dev, NULL,
1669 &(wrq->u.essid), essid);
1670 }
1671 break;
1672
1673
1674 // Get current network name (ESSID)
1675 case SIOCGIWESSID:
1676
1677 {
1678 char essid[IW_ESSID_MAX_SIZE+1];
1679 if (wrq->u.essid.pointer)
1680 rc = iwctl_giwessid(dev, NULL,
1681 &(wrq->u.essid), essid);
1682 if (copy_to_user(wrq->u.essid.pointer,
1683 essid,
1684 wrq->u.essid.length) )
1685 rc = -EFAULT;
1686 }
1687 break;
1688
1689 case SIOCSIWAP:
1690
1691 rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL);
1692 break;
1693
1694
1695 // Get current Access Point (BSSID)
1696 case SIOCGIWAP:
1697 rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL);
1698 break;
1699
1700
1701 // Set desired station name
1702 case SIOCSIWNICKN:
1703 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n");
1704 rc = -EOPNOTSUPP;
1705 break;
1706
1707 // Get current station name
1708 case SIOCGIWNICKN:
1709 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n");
1710 rc = -EOPNOTSUPP;
1711 break;
1712
1713 // Set the desired bit-rate
1714 case SIOCSIWRATE:
1715 rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL);
1716 break;
1717
1718 // Get the current bit-rate
1719 case SIOCGIWRATE:
1720
1721 rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
1722 break;
1723
1724 // Set the desired RTS threshold
1725 case SIOCSIWRTS:
1726
1727 rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL);
1728 break;
1729
1730 // Get the current RTS threshold
1731 case SIOCGIWRTS:
1732
1733 rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL);
1734 break;
1735
1736 // Set the desired fragmentation threshold
1737 case SIOCSIWFRAG:
1738
1739 rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL);
1740 break;
1741
1742 // Get the current fragmentation threshold
1743 case SIOCGIWFRAG:
1744
1745 rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL);
1746 break;
1747
1748 // Set mode of operation
1749 case SIOCSIWMODE:
1750 rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL);
1751 break;
1752
1753 // Get mode of operation
1754 case SIOCGIWMODE:
1755 rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
1756 break;
1757
1758 // Set WEP keys and mode
1759 case SIOCSIWENCODE:
1760 {
1761 char abyKey[WLAN_WEP232_KEYLEN];
1762
1763 if (wrq->u.encoding.pointer) {
1764
1765
1766 if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) {
1767 rc = -E2BIG;
1768 break;
1769 }
1770 memset(abyKey, 0, WLAN_WEP232_KEYLEN);
1771 if (copy_from_user(abyKey,
1772 wrq->u.encoding.pointer,
1773 wrq->u.encoding.length)) {
1774 rc = -EFAULT;
1775 break;
1776 }
1777 } else if (wrq->u.encoding.length != 0) {
1778 rc = -EINVAL;
1779 break;
1780 }
1781 rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey);
1782 }
1783 break;
1784
1785 // Get the WEP keys and mode
1786 case SIOCGIWENCODE:
1787
1788 if (!capable(CAP_NET_ADMIN)) {
1789 rc = -EPERM;
1790 break;
1791 }
1792 {
1793 char abyKey[WLAN_WEP232_KEYLEN];
1794
1795 rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey);
1796 if (rc != 0) break;
1797 if (wrq->u.encoding.pointer) {
1798 if (copy_to_user(wrq->u.encoding.pointer,
1799 abyKey,
1800 wrq->u.encoding.length))
1801 rc = -EFAULT;
1802 }
1803 }
1804 break;
1805
Forest Bond92b96792009-06-13 07:38:31 -04001806 // Get the current Tx-Power
1807 case SIOCGIWTXPOW:
1808 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
1809 rc = -EOPNOTSUPP;
1810 break;
1811
1812 case SIOCSIWTXPOW:
1813 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
1814 rc = -EOPNOTSUPP;
1815 break;
1816
Forest Bond92b96792009-06-13 07:38:31 -04001817 case SIOCSIWRETRY:
1818
1819 rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL);
1820 break;
1821
1822 case SIOCGIWRETRY:
1823
1824 rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL);
1825 break;
1826
Forest Bond92b96792009-06-13 07:38:31 -04001827 // Get range of parameters
1828 case SIOCGIWRANGE:
1829
1830 {
1831 struct iw_range range;
1832
1833 rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *) &range);
1834 if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
1835 rc = -EFAULT;
1836 }
1837
1838 break;
1839
1840 case SIOCGIWPOWER:
1841
1842 rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL);
1843 break;
1844
1845
1846 case SIOCSIWPOWER:
1847
1848 rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL);
1849 break;
1850
1851
1852 case SIOCGIWSENS:
1853
1854 rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL);
1855 break;
1856
1857 case SIOCSIWSENS:
1858 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n");
1859 rc = -EOPNOTSUPP;
1860 break;
1861
1862 case SIOCGIWAPLIST:
1863 {
1864 char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
1865
1866 if (wrq->u.data.pointer) {
1867 rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
1868 if (rc == 0) {
1869 if (copy_to_user(wrq->u.data.pointer,
1870 buffer,
1871 (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality)))
1872 ))
1873 rc = -EFAULT;
1874 }
1875 }
1876 }
1877 break;
1878
1879
1880#ifdef WIRELESS_SPY
1881 // Set the spy list
1882 case SIOCSIWSPY:
1883
1884 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
1885 rc = -EOPNOTSUPP;
1886 break;
1887
1888 // Get the spy list
1889 case SIOCGIWSPY:
1890
1891 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
1892 rc = -EOPNOTSUPP;
1893 break;
1894
1895#endif // WIRELESS_SPY
1896
1897 case SIOCGIWPRIV:
1898 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n");
1899 rc = -EOPNOTSUPP;
1900/*
1901 if(wrq->u.data.pointer) {
1902 wrq->u.data.length = sizeof(iwctl_private_args) / sizeof( iwctl_private_args[0]);
1903
1904 if(copy_to_user(wrq->u.data.pointer,
1905 (u_char *) iwctl_private_args,
1906 sizeof(iwctl_private_args)))
1907 rc = -EFAULT;
1908 }
1909*/
1910 break;
1911
Forest Bond92b96792009-06-13 07:38:31 -04001912#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1913 case SIOCSIWAUTH:
Andres More465711b2010-08-03 20:25:50 -03001914 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
Forest Bond92b96792009-06-13 07:38:31 -04001915 rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
1916 break;
1917
1918 case SIOCGIWAUTH:
1919 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH \n");
1920 rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
1921 break;
1922
1923 case SIOCSIWGENIE:
1924 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE \n");
1925 rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1926 break;
1927
1928 case SIOCGIWGENIE:
1929 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE \n");
1930 rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1931 break;
1932
1933 case SIOCSIWENCODEEXT:
1934 {
1935 char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
1936 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n");
1937 if(wrq->u.encoding.pointer){
1938 memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1);
1939 if(wrq->u.encoding.length > (sizeof(struct iw_encode_ext)+ MAX_KEY_LEN)){
1940 rc = -E2BIG;
1941 break;
1942 }
1943 if(copy_from_user(extra, wrq->u.encoding.pointer,wrq->u.encoding.length)){
1944 rc = -EFAULT;
1945 break;
1946 }
1947 }else if(wrq->u.encoding.length != 0){
1948 rc = -EINVAL;
1949 break;
1950 }
1951 rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra);
1952 }
1953 break;
1954
1955 case SIOCGIWENCODEEXT:
1956 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n");
1957 rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
1958 break;
1959
1960 case SIOCSIWMLME:
1961 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME \n");
1962 rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1963 break;
1964
1965#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
Forest Bond92b96792009-06-13 07:38:31 -04001966
Forest Bond92b96792009-06-13 07:38:31 -04001967 case IOCTL_CMD_TEST:
1968
1969 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1970 rc = -EFAULT;
1971 break;
1972 } else {
1973 rc = 0;
1974 }
1975 pReq = (PSCmdRequest)rq;
1976
1977 //20080130-01,<Remark> by Mike Liu
1978 // if(pDevice->bLinkPass==TRUE)
1979 pReq->wResult = MAGIC_CODE; //Linking status:0x3142
1980 //20080130-02,<Remark> by Mike Liu
1981 // else
1982 // pReq->wResult = MAGIC_CODE+1; //disconnect status:0x3143
1983 break;
1984
1985 case IOCTL_CMD_SET:
1986 if (!(pDevice->flags & DEVICE_FLAGS_OPENED) &&
1987 (((PSCmdRequest)rq)->wCmdCode !=WLAN_CMD_SET_WPA))
1988 {
1989 rc = -EFAULT;
1990 break;
1991 } else {
1992 rc = 0;
1993 }
1994
1995 if (test_and_set_bit( 0, (void*)&(pMgmt->uCmdBusy))) {
1996 return -EBUSY;
1997 }
1998 rc = private_ioctl(pDevice, rq);
1999 clear_bit( 0, (void*)&(pMgmt->uCmdBusy));
2000 break;
2001
2002 case IOCTL_CMD_HOSTAPD:
2003
2004 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
2005 rc = -EFAULT;
2006 break;
2007 } else {
2008 rc = 0;
2009 }
2010
Forest Bondc30d7972010-04-17 11:03:38 -04002011 rc = vt6656_hostap_ioctl(pDevice, &wrq->u.data);
Forest Bond92b96792009-06-13 07:38:31 -04002012 break;
2013
2014 case IOCTL_CMD_WPA:
2015
2016 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
2017 rc = -EFAULT;
2018 break;
2019 } else {
2020 rc = 0;
2021 }
2022
Forest Bond92b96792009-06-13 07:38:31 -04002023 rc = wpa_ioctl(pDevice, &wrq->u.data);
Forest Bond92b96792009-06-13 07:38:31 -04002024 break;
2025
2026 case SIOCETHTOOL:
2027 return ethtool_ioctl(dev, (void *) rq->ifr_data);
2028 // All other calls are currently unsupported
2029
2030 default:
2031 rc = -EOPNOTSUPP;
2032 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd);
2033
2034
2035 }
2036
2037 if (pDevice->bCommit) {
2038 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2039 netif_stop_queue(pDevice->dev);
2040 spin_lock_irq(&pDevice->lock);
Andres More0cbd8d92010-05-06 20:34:29 -03002041 bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002042 spin_unlock_irq(&pDevice->lock);
2043 }
2044 else {
2045 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
2046 spin_lock_irq(&pDevice->lock);
2047//2007-1121-01<Modify>by EinsnLiu
Andres More0cbd8d92010-05-06 20:34:29 -03002048 if (pDevice->bLinkPass &&
Forest Bond92b96792009-06-13 07:38:31 -04002049 memcmp(pMgmt->abyCurrSSID,pMgmt->abyDesireSSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN)) {
Andres More0cbd8d92010-05-06 20:34:29 -03002050 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002051 } else {
2052 pDevice->bLinkPass = FALSE;
2053 pMgmt->eCurrState = WMAC_STATE_IDLE;
2054 memset(pMgmt->abyCurrBSSID, 0, 6);
2055 }
2056 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
2057//End Modify
2058 netif_stop_queue(pDevice->dev);
2059#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
2060 pMgmt->eScanType = WMAC_SCAN_ACTIVE;
Andres More0cbd8d92010-05-06 20:34:29 -03002061 if (!pDevice->bWPASuppWextEnabled)
Forest Bond92b96792009-06-13 07:38:31 -04002062#endif
Andres More0cbd8d92010-05-06 20:34:29 -03002063 bScheduleCommand((void *) pDevice,
2064 WLAN_CMD_BSSID_SCAN,
2065 pMgmt->abyDesireSSID);
2066 bScheduleCommand((void *) pDevice,
2067 WLAN_CMD_SSID,
2068 NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002069 spin_unlock_irq(&pDevice->lock);
2070 }
2071 pDevice->bCommit = FALSE;
2072 }
2073
2074
2075 return rc;
2076}
2077
2078
2079static int ethtool_ioctl(struct net_device *dev, void *useraddr)
2080{
2081 u32 ethcmd;
2082
2083 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
2084 return -EFAULT;
2085
2086 switch (ethcmd) {
2087 case ETHTOOL_GDRVINFO: {
2088 struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
2089 strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
2090 strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
2091 if (copy_to_user(useraddr, &info, sizeof(info)))
2092 return -EFAULT;
2093 return 0;
2094 }
2095
2096 }
2097
2098 return -EOPNOTSUPP;
2099}
2100
2101
2102/*------------------------------------------------------------------*/
2103
Andres More26e5b652010-04-13 19:43:07 -03002104MODULE_DEVICE_TABLE(usb, vt6656_table);
Forest Bond92b96792009-06-13 07:38:31 -04002105
Andres More26e5b652010-04-13 19:43:07 -03002106static struct usb_driver vt6656_driver = {
2107 .name = DEVICE_NAME,
2108 .probe = vt6656_probe,
2109 .disconnect = vt6656_disconnect,
2110 .id_table = vt6656_table,
Forest Bond92b96792009-06-13 07:38:31 -04002111#ifdef CONFIG_PM
Andres More26e5b652010-04-13 19:43:07 -03002112 .suspend = vt6656_suspend,
2113 .resume = vt6656_resume,
2114#endif /* CONFIG_PM */
Forest Bond92b96792009-06-13 07:38:31 -04002115};
2116
Andres More26e5b652010-04-13 19:43:07 -03002117static int __init vt6656_init_module(void)
Forest Bond92b96792009-06-13 07:38:31 -04002118{
Forest Bondf4a8df92009-06-13 07:38:56 -04002119 printk(KERN_NOTICE DEVICE_FULL_DRV_NAM " " DEVICE_VERSION);
Andres More26e5b652010-04-13 19:43:07 -03002120 return usb_register(&vt6656_driver);
Forest Bond92b96792009-06-13 07:38:31 -04002121}
2122
Andres More26e5b652010-04-13 19:43:07 -03002123static void __exit vt6656_cleanup_module(void)
Forest Bond92b96792009-06-13 07:38:31 -04002124{
Andres More26e5b652010-04-13 19:43:07 -03002125 usb_deregister(&vt6656_driver);
Forest Bond92b96792009-06-13 07:38:31 -04002126}
2127
Andres More26e5b652010-04-13 19:43:07 -03002128module_init(vt6656_init_module);
2129module_exit(vt6656_cleanup_module);