blob: e992d5d9e15bc13e80031e99591f92c1e62357c0 [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));
Andres More7a8b0052010-07-12 12:40:01 -0300773 if (!netdev) {
774 printk(KERN_ERR DEVICE_NAME ": allocate net device failed\n");
Dan Carpentere3a92cd2010-08-10 08:00:12 +0200775 rc = -ENOMEM;
Andres More7a8b0052010-07-12 12:40:01 -0300776 goto err_nomem;
777 }
Forest Bond92b96792009-06-13 07:38:31 -0400778
Andres More7a8b0052010-07-12 12:40:01 -0300779 pDevice = netdev_priv(netdev);
780 memset(pDevice, 0, sizeof(DEVICE_INFO));
Forest Bond92b96792009-06-13 07:38:31 -0400781
Andres More7a8b0052010-07-12 12:40:01 -0300782 pDevice->dev = netdev;
783 pDevice->usb = udev;
Forest Bond1e28efa2009-06-13 07:38:50 -0400784
Andres More7a8b0052010-07-12 12:40:01 -0300785 device_set_options(pDevice);
786 spin_lock_init(&pDevice->lock);
Forest Bond1e28efa2009-06-13 07:38:50 -0400787
Andres More7a8b0052010-07-12 12:40:01 -0300788 pDevice->tx_80211 = device_dma0_tx_80211;
789 pDevice->sMgmtObj.pAdapter = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400790
Andres More7a8b0052010-07-12 12:40:01 -0300791 netdev->netdev_ops = &device_netdev_ops;
792 netdev->wireless_handlers =
793 (struct iw_handler_def *) &iwctl_handler_def;
Forest Bond92b96792009-06-13 07:38:31 -0400794
Andres More7a8b0052010-07-12 12:40:01 -0300795 usb_set_intfdata(intf, pDevice);
Forest Bond92b96792009-06-13 07:38:31 -0400796 SET_NETDEV_DEV(netdev, &intf->dev);
Andres More7a8b0052010-07-12 12:40:01 -0300797 memcpy(pDevice->dev->dev_addr, fake_mac, ETH_ALEN);
798 rc = register_netdev(netdev);
799 if (rc) {
800 printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
Dan Carpentere3a92cd2010-08-10 08:00:12 +0200801 goto err_netdev;
Andres More7a8b0052010-07-12 12:40:01 -0300802 }
Forest Bond92b96792009-06-13 07:38:31 -0400803
Andres More7a8b0052010-07-12 12:40:01 -0300804 usb_device_reset(pDevice);
Forest Bond92b96792009-06-13 07:38:31 -0400805
Andres More7a8b0052010-07-12 12:40:01 -0300806 {
807 union iwreq_data wrqu;
808 memset(&wrqu, 0, sizeof(wrqu));
809 wrqu.data.flags = RT_INSMOD_EVENT_FLAG;
810 wrqu.data.length = IFNAMSIZ;
811 wireless_send_event(pDevice->dev,
812 IWEVCUSTOM,
813 &wrqu,
814 pDevice->dev->name);
815 }
Forest Bond92b96792009-06-13 07:38:31 -0400816
817 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400818
Dan Carpentere3a92cd2010-08-10 08:00:12 +0200819err_netdev:
820 free_netdev(netdev);
Forest Bond92b96792009-06-13 07:38:31 -0400821err_nomem:
Andres More7a8b0052010-07-12 12:40:01 -0300822 usb_put_dev(udev);
Forest Bond92b96792009-06-13 07:38:31 -0400823
Dan Carpentere3a92cd2010-08-10 08:00:12 +0200824 return rc;
Forest Bond92b96792009-06-13 07:38:31 -0400825}
826
Andres More8611a292010-05-01 14:25:00 -0300827static void device_free_tx_bufs(PSDevice pDevice)
828{
Forest Bond92b96792009-06-13 07:38:31 -0400829 PUSB_SEND_CONTEXT pTxContext;
830 int ii;
831
832 for (ii = 0; ii < pDevice->cbTD; ii++) {
833
834 pTxContext = pDevice->apTD[ii];
835 //de-allocate URBs
836 if (pTxContext->pUrb) {
Jim Liebdad72fe2009-08-12 14:54:14 -0700837 usb_kill_urb(pTxContext->pUrb);
Forest Bond92b96792009-06-13 07:38:31 -0400838 usb_free_urb(pTxContext->pUrb);
839 }
840 if (pTxContext)
841 kfree(pTxContext);
842 }
843 return;
844}
845
846
Andres More8611a292010-05-01 14:25:00 -0300847static void device_free_rx_bufs(PSDevice pDevice)
848{
Forest Bond92b96792009-06-13 07:38:31 -0400849 PRCB pRCB;
850 int ii;
851
852 for (ii = 0; ii < pDevice->cbRD; ii++) {
853
854 pRCB = pDevice->apRCB[ii];
855 //de-allocate URBs
856 if (pRCB->pUrb) {
Jim Liebdad72fe2009-08-12 14:54:14 -0700857 usb_kill_urb(pRCB->pUrb);
Forest Bond92b96792009-06-13 07:38:31 -0400858 usb_free_urb(pRCB->pUrb);
859 }
860 //de-allocate skb
861 if (pRCB->skb)
862 dev_kfree_skb(pRCB->skb);
863 }
864 if (pDevice->pRCBMem)
865 kfree(pDevice->pRCBMem);
866
867 return;
868}
869
Forest Bond92b96792009-06-13 07:38:31 -0400870static void usb_device_reset(PSDevice pDevice)
871{
872 int status;
873 status = usb_reset_device(pDevice->usb);
874 if (status)
875 printk("usb_device_reset fail status=%d\n",status);
876 return ;
877}
Forest Bond92b96792009-06-13 07:38:31 -0400878
Andres More8611a292010-05-01 14:25:00 -0300879static void device_free_int_bufs(PSDevice pDevice)
880{
Forest Bond92b96792009-06-13 07:38:31 -0400881 if (pDevice->intBuf.pDataBuf != NULL)
882 kfree(pDevice->intBuf.pDataBuf);
883 return;
884}
885
886
887static BOOL device_alloc_bufs(PSDevice pDevice) {
888
889 PUSB_SEND_CONTEXT pTxContext;
890 PRCB pRCB;
891 int ii;
892
893
894 for (ii = 0; ii < pDevice->cbTD; ii++) {
895
896 pTxContext = kmalloc(sizeof(USB_SEND_CONTEXT), GFP_KERNEL);
897 if (pTxContext == NULL) {
898 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : allocate tx usb context failed\n", pDevice->dev->name);
899 goto free_tx;
900 }
901 pDevice->apTD[ii] = pTxContext;
Andres More8611a292010-05-01 14:25:00 -0300902 pTxContext->pDevice = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400903 //allocate URBs
Jim Liebdad72fe2009-08-12 14:54:14 -0700904 pTxContext->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400905 if (pTxContext->pUrb == NULL) {
906 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "alloc tx urb failed\n");
907 goto free_tx;
908 }
909 pTxContext->bBoolInUse = FALSE;
910 }
911
912 // allocate rcb mem
913 pDevice->pRCBMem = kmalloc((sizeof(RCB) * pDevice->cbRD), GFP_KERNEL);
914 if (pDevice->pRCBMem == NULL) {
915 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : alloc rx usb context failed\n", pDevice->dev->name);
916 goto free_tx;
917 }
918
919
920 pDevice->FirstRecvFreeList = NULL;
921 pDevice->LastRecvFreeList = NULL;
922 pDevice->FirstRecvMngList = NULL;
923 pDevice->LastRecvMngList = NULL;
924 pDevice->NumRecvFreeList = 0;
925 memset(pDevice->pRCBMem, 0, (sizeof(RCB) * pDevice->cbRD));
926 pRCB = (PRCB) pDevice->pRCBMem;
927
928 for (ii = 0; ii < pDevice->cbRD; ii++) {
929
930 pDevice->apRCB[ii] = pRCB;
Andres More8611a292010-05-01 14:25:00 -0300931 pRCB->pDevice = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400932 //allocate URBs
Jim Liebdad72fe2009-08-12 14:54:14 -0700933 pRCB->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400934
935 if (pRCB->pUrb == NULL) {
936 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx urb\n");
937 goto free_rx_tx;
938 }
939 pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
940 if (pRCB->skb == NULL) {
941 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx skb\n");
942 goto free_rx_tx;
943 }
944 pRCB->skb->dev = pDevice->dev;
945 pRCB->bBoolInUse = FALSE;
946 EnqueueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList, pRCB);
947 pDevice->NumRecvFreeList++;
948 pRCB++;
949 }
950
951
Jim Liebdad72fe2009-08-12 14:54:14 -0700952 pDevice->pControlURB = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400953 if (pDevice->pControlURB == NULL) {
954 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc control urb\n");
955 goto free_rx_tx;
956 }
957
Jim Liebdad72fe2009-08-12 14:54:14 -0700958 pDevice->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400959 if (pDevice->pInterruptURB == NULL) {
960 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int urb\n");
Jim Liebdad72fe2009-08-12 14:54:14 -0700961 usb_kill_urb(pDevice->pControlURB);
Forest Bond92b96792009-06-13 07:38:31 -0400962 usb_free_urb(pDevice->pControlURB);
963 goto free_rx_tx;
964 }
965
966 pDevice->intBuf.pDataBuf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
967 if (pDevice->intBuf.pDataBuf == NULL) {
968 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int buf\n");
Jim Liebdad72fe2009-08-12 14:54:14 -0700969 usb_kill_urb(pDevice->pControlURB);
970 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -0400971 usb_free_urb(pDevice->pControlURB);
972 usb_free_urb(pDevice->pInterruptURB);
973 goto free_rx_tx;
974 }
975
976 return TRUE;
977
978free_rx_tx:
979 device_free_rx_bufs(pDevice);
980
981free_tx:
982 device_free_tx_bufs(pDevice);
983
984 return FALSE;
985}
986
987
988
989
990static BOOL device_init_defrag_cb(PSDevice pDevice) {
991 int i;
992 PSDeFragControlBlock pDeF;
993
994 /* Init the fragment ctl entries */
995 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
996 pDeF = &(pDevice->sRxDFCB[i]);
997 if (!device_alloc_frag_buf(pDevice, pDeF)) {
998 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
999 pDevice->dev->name);
1000 goto free_frag;
1001 };
1002 }
1003 pDevice->cbDFCB = CB_MAX_RX_FRAG;
1004 pDevice->cbFreeDFCB = pDevice->cbDFCB;
1005 return TRUE;
1006
1007free_frag:
1008 device_free_frag_bufs(pDevice);
1009 return FALSE;
1010}
1011
1012
1013
1014static void device_free_frag_bufs(PSDevice pDevice) {
1015 PSDeFragControlBlock pDeF;
1016 int i;
1017
1018 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
1019
1020 pDeF = &(pDevice->sRxDFCB[i]);
1021
1022 if (pDeF->skb)
1023 dev_kfree_skb(pDeF->skb);
1024 }
1025}
1026
1027
1028
1029BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
1030
1031 pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1032 if (pDeF->skb == NULL)
1033 return FALSE;
1034 ASSERT(pDeF->skb);
1035 pDeF->skb->dev = pDevice->dev;
1036
1037 return TRUE;
1038}
1039
1040
1041/*-----------------------------------------------------------------*/
1042
1043static int device_open(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001044 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001045
Forest Bond92b96792009-06-13 07:38:31 -04001046 extern SWPAResult wpa_Result;
1047 memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname));
1048 wpa_Result.proto = 0;
1049 wpa_Result.key_mgmt = 0;
1050 wpa_Result.eap_type = 0;
1051 wpa_Result.authenticated = FALSE;
1052 pDevice->fWPA_Authened = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001053
1054 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_open...\n");
1055
1056
1057 pDevice->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
1058
1059 if (device_alloc_bufs(pDevice) == FALSE) {
1060 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_alloc_bufs fail... \n");
1061 return -ENOMEM;
1062 }
1063
1064 if (device_init_defrag_cb(pDevice)== FALSE) {
1065 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Initial defragement cb fail \n");
1066 goto free_rx_tx;
1067 }
1068
1069 MP_CLEAR_FLAG(pDevice, fMP_DISCONNECTED);
1070 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
1071 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
1072 MP_SET_FLAG(pDevice, fMP_POST_READS);
1073 MP_SET_FLAG(pDevice, fMP_POST_WRITES);
1074
1075 //read config file
1076 Read_config_file(pDevice);
1077
1078 if (device_init_registers(pDevice, DEVICE_INIT_COLD) == FALSE) {
1079 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " init register fail\n");
1080 goto free_all;
1081 }
1082
1083 device_set_multi(pDevice->dev);
1084 // Init for Key Management
1085
1086 KeyvInitTable(pDevice,&pDevice->sKey);
Andres More9a0e7562010-04-13 21:54:48 -03001087 memcpy(pDevice->sMgmtObj.abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN);
1088 memcpy(pDevice->dev->dev_addr, pDevice->abyCurrentNetAddr, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001089 pDevice->bStopTx0Pkt = FALSE;
1090 pDevice->bStopDataPkt = FALSE;
Andres More465711b2010-08-03 20:25:50 -03001091 pDevice->bRoaming = FALSE;
1092 pDevice->bIsRoaming = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001093 pDevice->bEnableRoaming = FALSE;
1094 if (pDevice->bDiversityRegCtlON) {
1095 device_init_diversity_timer(pDevice);
1096 }
1097
1098 vMgrObjectInit(pDevice);
1099 tasklet_init(&pDevice->RxMngWorkItem, (void *)RXvMngWorkItem, (unsigned long)pDevice);
1100 tasklet_init(&pDevice->ReadWorkItem, (void *)RXvWorkItem, (unsigned long)pDevice);
1101 tasklet_init(&pDevice->EventWorkItem, (void *)INTvWorkItem, (unsigned long)pDevice);
1102 add_timer(&(pDevice->sMgmtObj.sTimerSecondCallback));
Forest Bond92b96792009-06-13 07:38:31 -04001103 pDevice->int_interval = 100; //Max 100 microframes.
Forest Bond92b96792009-06-13 07:38:31 -04001104 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1105
1106 pDevice->bIsRxWorkItemQueued = TRUE;
1107 pDevice->fKillEventPollingThread = FALSE;
1108 pDevice->bEventAvailable = FALSE;
1109
1110 pDevice->bWPADEVUp = FALSE;
1111#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1112 pDevice->bwextstep0 = FALSE;
1113 pDevice->bwextstep1 = FALSE;
1114 pDevice->bwextstep2 = FALSE;
1115 pDevice->bwextstep3 = FALSE;
1116 pDevice->bWPASuppWextEnabled = FALSE;
1117#endif
1118 pDevice->byReAssocCount = 0;
1119
1120 RXvWorkItem(pDevice);
1121 INTvWorkItem(pDevice);
1122
1123 // Patch: if WEP key already set by iwconfig but device not yet open
1124 if ((pDevice->bEncryptionEnable == TRUE) && (pDevice->bTransmitKey == TRUE)) {
1125 spin_lock_irq(&pDevice->lock);
1126 KeybSetDefaultKey( pDevice,
1127 &(pDevice->sKey),
1128 pDevice->byKeyIndex | (1 << 31),
1129 pDevice->uKeyLength,
1130 NULL,
1131 pDevice->abyKey,
1132 KEY_CTL_WEP
1133 );
1134 spin_unlock_irq(&pDevice->lock);
1135 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1136 }
1137
1138 if (pDevice->sMgmtObj.eConfigMode == WMAC_CONFIG_AP) {
Andres More0cbd8d92010-05-06 20:34:29 -03001139 bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001140 }
1141 else {
1142 //mike:mark@2008-11-10
Andres More0cbd8d92010-05-06 20:34:29 -03001143 bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
1144 /* bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); */
Forest Bond92b96792009-06-13 07:38:31 -04001145 }
1146
1147
1148 netif_stop_queue(pDevice->dev);
1149 pDevice->flags |= DEVICE_FLAGS_OPENED;
1150
Forest Bond92b96792009-06-13 07:38:31 -04001151{
1152 union iwreq_data wrqu;
1153 memset(&wrqu, 0, sizeof(wrqu));
1154 wrqu.data.flags = RT_UPDEV_EVENT_FLAG;
1155 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1156}
Forest Bond92b96792009-06-13 07:38:31 -04001157
1158 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
1159 return 0;
1160
1161free_all:
1162 device_free_frag_bufs(pDevice);
1163free_rx_tx:
1164 device_free_rx_bufs(pDevice);
1165 device_free_tx_bufs(pDevice);
1166 device_free_int_bufs(pDevice);
Jim Liebdad72fe2009-08-12 14:54:14 -07001167 usb_kill_urb(pDevice->pControlURB);
1168 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -04001169 usb_free_urb(pDevice->pControlURB);
1170 usb_free_urb(pDevice->pInterruptURB);
1171
1172 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open fail.. \n");
1173 return -ENOMEM;
1174}
1175
1176
1177
1178static int device_close(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001179 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001180 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1181
Forest Bond92b96792009-06-13 07:38:31 -04001182 int uu;
Forest Bond92b96792009-06-13 07:38:31 -04001183
1184 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close1 \n");
1185 if (pDevice == NULL)
1186 return -ENODEV;
1187
Forest Bond92b96792009-06-13 07:38:31 -04001188{
1189 union iwreq_data wrqu;
1190 memset(&wrqu, 0, sizeof(wrqu));
1191 wrqu.data.flags = RT_DOWNDEV_EVENT_FLAG;
1192 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1193}
Forest Bond92b96792009-06-13 07:38:31 -04001194
Forest Bond92b96792009-06-13 07:38:31 -04001195 if (pDevice->bLinkPass) {
Andres More0cbd8d92010-05-06 20:34:29 -03001196 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001197 mdelay(30);
1198 }
Forest Bond92b96792009-06-13 07:38:31 -04001199
Forest Bond92b96792009-06-13 07:38:31 -04001200device_release_WPADEV(pDevice);
1201
Forest Bond92b96792009-06-13 07:38:31 -04001202 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
1203 pMgmt->bShareKeyAlgorithm = FALSE;
1204 pDevice->bEncryptionEnable = FALSE;
1205 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
Andres More33d33e422010-05-19 23:50:00 -03001206 spin_lock_irq(&pDevice->lock);
1207 for (uu = 0; uu < MAX_KEY_TABLE; uu++)
Forest Bond92b96792009-06-13 07:38:31 -04001208 MACvDisableKeyEntry(pDevice,uu);
Andres More33d33e422010-05-19 23:50:00 -03001209 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001210
1211 if ((pDevice->flags & DEVICE_FLAGS_UNPLUG) == FALSE) {
1212 MACbShutdown(pDevice);
1213 }
1214 netif_stop_queue(pDevice->dev);
1215 MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
1216 MP_CLEAR_FLAG(pDevice, fMP_POST_WRITES);
1217 MP_CLEAR_FLAG(pDevice, fMP_POST_READS);
1218 pDevice->fKillEventPollingThread = TRUE;
1219 del_timer(&pDevice->sTimerCommand);
1220 del_timer(&pMgmt->sTimerSecondCallback);
1221
Forest Bond92b96792009-06-13 07:38:31 -04001222 del_timer(&pDevice->sTimerTxData);
Forest Bond92b96792009-06-13 07:38:31 -04001223
1224 if (pDevice->bDiversityRegCtlON) {
1225 del_timer(&pDevice->TimerSQ3Tmax1);
1226 del_timer(&pDevice->TimerSQ3Tmax2);
1227 del_timer(&pDevice->TimerSQ3Tmax3);
1228 }
1229 tasklet_kill(&pDevice->RxMngWorkItem);
1230 tasklet_kill(&pDevice->ReadWorkItem);
1231 tasklet_kill(&pDevice->EventWorkItem);
1232
Andres More465711b2010-08-03 20:25:50 -03001233 pDevice->bRoaming = FALSE;
1234 pDevice->bIsRoaming = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001235 pDevice->bEnableRoaming = FALSE;
1236 pDevice->bCmdRunning = FALSE;
1237 pDevice->bLinkPass = FALSE;
1238 memset(pMgmt->abyCurrBSSID, 0, 6);
1239 pMgmt->eCurrState = WMAC_STATE_IDLE;
1240
1241 device_free_tx_bufs(pDevice);
1242 device_free_rx_bufs(pDevice);
1243 device_free_int_bufs(pDevice);
1244 device_free_frag_bufs(pDevice);
1245
Jim Liebdad72fe2009-08-12 14:54:14 -07001246 usb_kill_urb(pDevice->pControlURB);
1247 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -04001248 usb_free_urb(pDevice->pControlURB);
1249 usb_free_urb(pDevice->pInterruptURB);
1250
1251 BSSvClearNodeDBTable(pDevice, 0);
1252 pDevice->flags &=(~DEVICE_FLAGS_OPENED);
1253
1254 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n");
1255
1256 return 0;
1257}
1258
Andres More26e5b652010-04-13 19:43:07 -03001259static void __devexit vt6656_disconnect(struct usb_interface *intf)
Forest Bond92b96792009-06-13 07:38:31 -04001260{
Andres More6cda24f2010-06-22 20:43:39 -03001261 PSDevice device = usb_get_intfdata(intf);
Forest Bond92b96792009-06-13 07:38:31 -04001262
Andres More6cda24f2010-06-22 20:43:39 -03001263 if (!device)
1264 return;
Forest Bond92b96792009-06-13 07:38:31 -04001265
Andres More6cda24f2010-06-22 20:43:39 -03001266 {
1267 union iwreq_data req;
1268 memset(&req, 0, sizeof(req));
1269 req.data.flags = RT_RMMOD_EVENT_FLAG;
1270 wireless_send_event(device->dev, IWEVCUSTOM, &req, NULL);
1271 }
Forest Bond92b96792009-06-13 07:38:31 -04001272
Andres More6cda24f2010-06-22 20:43:39 -03001273 device_release_WPADEV(device);
Forest Bond92b96792009-06-13 07:38:31 -04001274
Forest Bond92b96792009-06-13 07:38:31 -04001275 usb_set_intfdata(intf, NULL);
Andres More6cda24f2010-06-22 20:43:39 -03001276 usb_put_dev(interface_to_usbdev(intf));
Forest Bond92b96792009-06-13 07:38:31 -04001277
Andres More6cda24f2010-06-22 20:43:39 -03001278 device->flags |= DEVICE_FLAGS_UNPLUG;
Forest Bond92b96792009-06-13 07:38:31 -04001279
Andres More6cda24f2010-06-22 20:43:39 -03001280 if (device->dev) {
1281 unregister_netdev(device->dev);
1282 wpa_set_wpadev(device, 0);
1283 free_netdev(device->dev);
1284 }
Forest Bond92b96792009-06-13 07:38:31 -04001285}
1286
Andres Moree1669ed2010-07-12 13:10:27 -03001287static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev)
1288{
1289 PSDevice pDevice = netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001290
Andres Moree1669ed2010-07-12 13:10:27 -03001291 spin_lock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001292
Andres Moree1669ed2010-07-12 13:10:27 -03001293 if (unlikely(pDevice->bStopTx0Pkt))
1294 dev_kfree_skb_irq(skb);
1295 else
1296 vDMA0_tx_80211(pDevice, skb);
Forest Bond92b96792009-06-13 07:38:31 -04001297
Andres Moree1669ed2010-07-12 13:10:27 -03001298 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001299
Andres Moree1669ed2010-07-12 13:10:27 -03001300 return NETDEV_TX_OK;
Forest Bond92b96792009-06-13 07:38:31 -04001301}
1302
Andres More529e5b32010-07-12 19:28:25 -03001303static int device_xmit(struct sk_buff *skb, struct net_device *dev)
1304{
1305 PSDevice pDevice = netdev_priv(dev);
1306 struct net_device_stats *stats = &pDevice->stats;
Forest Bond92b96792009-06-13 07:38:31 -04001307
Andres More529e5b32010-07-12 19:28:25 -03001308 spin_lock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001309
Andres More529e5b32010-07-12 19:28:25 -03001310 netif_stop_queue(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001311
Andres More529e5b32010-07-12 19:28:25 -03001312 if (!pDevice->bLinkPass) {
1313 dev_kfree_skb_irq(skb);
1314 goto out;
1315 }
Forest Bond92b96792009-06-13 07:38:31 -04001316
Andres More529e5b32010-07-12 19:28:25 -03001317 if (pDevice->bStopDataPkt) {
1318 dev_kfree_skb_irq(skb);
1319 stats->tx_dropped++;
1320 goto out;
1321 }
Forest Bond92b96792009-06-13 07:38:31 -04001322
Andres More529e5b32010-07-12 19:28:25 -03001323 if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb)) {
1324 if (netif_queue_stopped(dev))
1325 netif_wake_queue(dev);
1326 }
Forest Bond92b96792009-06-13 07:38:31 -04001327
Andres More529e5b32010-07-12 19:28:25 -03001328out:
1329 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001330
Andres More529e5b32010-07-12 19:28:25 -03001331 return NETDEV_TX_OK;
Forest Bond92b96792009-06-13 07:38:31 -04001332}
1333
Forest Bond92b96792009-06-13 07:38:31 -04001334static unsigned const ethernet_polynomial = 0x04c11db7U;
1335static inline u32 ether_crc(int length, unsigned char *data)
1336{
1337 int crc = -1;
1338
1339 while(--length >= 0) {
1340 unsigned char current_octet = *data++;
1341 int bit;
1342 for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
1343 crc = (crc << 1) ^
1344 ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
1345 }
1346 }
1347 return crc;
1348}
1349
1350//find out the start position of str2 from str1
Andres Morecc856e62010-05-17 21:34:01 -03001351static unsigned char *kstrstr(const unsigned char *str1,
1352 const unsigned char *str2) {
1353 int str1_len = strlen(str1);
1354 int str2_len = strlen(str2);
Forest Bond92b96792009-06-13 07:38:31 -04001355
1356 while (str1_len >= str2_len) {
1357 str1_len--;
1358 if(memcmp(str1,str2,str2_len)==0)
Andres Morecc856e62010-05-17 21:34:01 -03001359 return (unsigned char *) str1;
Forest Bond92b96792009-06-13 07:38:31 -04001360 str1++;
1361 }
1362 return NULL;
1363}
1364
Andres Morecc856e62010-05-17 21:34:01 -03001365static int Config_FileGetParameter(unsigned char *string,
1366 unsigned char *dest,
1367 unsigned char *source)
Forest Bond92b96792009-06-13 07:38:31 -04001368{
Andres Morecc856e62010-05-17 21:34:01 -03001369 unsigned char buf1[100];
1370 unsigned char buf2[100];
1371 unsigned char *start_p = NULL, *end_p = NULL, *tmp_p = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001372 int ii;
1373
1374 memset(buf1,0,100);
1375 strcat(buf1, string);
1376 strcat(buf1, "=");
1377 source+=strlen(buf1);
1378
1379//find target string start point
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001380 start_p = kstrstr(source,buf1);
1381 if (start_p == NULL)
Forest Bond92b96792009-06-13 07:38:31 -04001382 return FALSE;
1383
1384//check if current config line is marked by "#" ??
Andres More33d33e422010-05-19 23:50:00 -03001385 for (ii = 1; ; ii++) {
1386 if (memcmp(start_p - ii, "\n", 1) == 0)
1387 break;
1388 if (memcmp(start_p - ii, "#", 1) == 0)
1389 return FALSE;
1390 }
Forest Bond92b96792009-06-13 07:38:31 -04001391
1392//find target string end point
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001393 end_p = kstrstr(start_p,"\n");
1394 if (end_p == NULL) { //can't find "\n",but don't care
Forest Bond92b96792009-06-13 07:38:31 -04001395 end_p=start_p+strlen(start_p); //no include "\n"
1396 }
1397
1398 memset(buf2,0,100);
1399 memcpy(buf2,start_p,end_p-start_p); //get the tartget line
1400 buf2[end_p-start_p]='\0';
1401
1402 //find value
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001403 start_p = kstrstr(buf2,"=");
1404 if (start_p == NULL)
Forest Bond92b96792009-06-13 07:38:31 -04001405 return FALSE;
1406 memset(buf1,0,100);
1407 strcpy(buf1,start_p+1);
1408
1409 //except space
1410 tmp_p = buf1;
1411 while(*tmp_p != 0x00) {
1412 if(*tmp_p==' ')
1413 tmp_p++;
1414 else
1415 break;
1416 }
1417
1418 memcpy(dest,tmp_p,strlen(tmp_p));
1419 return TRUE;
1420}
1421
1422//if read fail,return NULL,or return data pointer;
Andres Morecc856e62010-05-17 21:34:01 -03001423static unsigned char *Config_FileOperation(PSDevice pDevice)
1424{
1425 unsigned char *config_path = CONFIG_PATH;
1426 unsigned char *buffer = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001427 struct file *filp=NULL;
1428 mm_segment_t old_fs = get_fs();
Forest Bond8f9c4662009-06-13 07:38:47 -04001429 //int oldfsuid=0,oldfsgid=0;
Andres Morecc856e62010-05-17 21:34:01 -03001430 int result = 0;
Forest Bond92b96792009-06-13 07:38:31 -04001431
1432 set_fs (KERNEL_DS);
Forest Bond8f9c4662009-06-13 07:38:47 -04001433 /* Can't do this anymore, so we rely on correct filesystem permissions:
1434 //Make sure a caller can read or write power as root
1435 oldfsuid=current->fsuid;
1436 oldfsgid=current->fsgid;
Forest Bond92b96792009-06-13 07:38:31 -04001437 current->fsuid = 0;
1438 current->fsgid = 0;
Forest Bond8f9c4662009-06-13 07:38:47 -04001439 */
Forest Bond92b96792009-06-13 07:38:31 -04001440
1441 //open file
1442 filp = filp_open(config_path, O_RDWR, 0);
1443 if (IS_ERR(filp)) {
1444 printk("Config_FileOperation file Not exist\n");
1445 result=-1;
1446 goto error2;
1447 }
1448
1449 if(!(filp->f_op) || !(filp->f_op->read) ||!(filp->f_op->write)) {
1450 printk("file %s cann't readable or writable?\n",config_path);
1451 result = -1;
1452 goto error1;
1453 }
1454
Julia Lawall32414872010-05-11 20:26:57 +02001455 buffer = kmalloc(1024, GFP_KERNEL);
Forest Bond92b96792009-06-13 07:38:31 -04001456 if(buffer==NULL) {
1457 printk("alllocate mem for file fail?\n");
1458 result = -1;
1459 goto error1;
1460 }
1461
1462 if(filp->f_op->read(filp, buffer, 1024, &filp->f_pos)<0) {
1463 printk("read file error?\n");
1464 result = -1;
1465 }
1466
1467error1:
1468 if(filp_close(filp,NULL))
1469 printk("Config_FileOperation:close file fail\n");
1470
1471error2:
1472 set_fs (old_fs);
Forest Bond8f9c4662009-06-13 07:38:47 -04001473
1474 /*
Forest Bond92b96792009-06-13 07:38:31 -04001475 current->fsuid=oldfsuid;
1476 current->fsgid=oldfsgid;
Forest Bond8f9c4662009-06-13 07:38:47 -04001477 */
Forest Bond92b96792009-06-13 07:38:31 -04001478
1479if(result!=0) {
1480 if(buffer)
1481 kfree(buffer);
1482 buffer=NULL;
1483}
1484 return buffer;
1485}
1486
André Goddard Rosabbc9a992009-11-14 13:09:06 -02001487//return --->-1:fail; >=0:successful
Forest Bond92b96792009-06-13 07:38:31 -04001488static int Read_config_file(PSDevice pDevice) {
Andres Morecc856e62010-05-17 21:34:01 -03001489 int result = 0;
1490 unsigned char tmpbuffer[100];
1491 unsigned char *buffer = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001492
1493 //init config setting
1494 pDevice->config_file.ZoneType = -1;
1495 pDevice->config_file.eAuthenMode = -1;
1496 pDevice->config_file.eEncryptionStatus = -1;
1497
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001498 buffer = Config_FileOperation(pDevice);
1499 if (buffer == NULL) {
Forest Bond92b96792009-06-13 07:38:31 -04001500 result =-1;
1501 return result;
1502 }
1503
1504//get zonetype
1505{
1506 memset(tmpbuffer,0,sizeof(tmpbuffer));
1507 if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer) ==TRUE) {
1508 if(memcmp(tmpbuffer,"USA",3)==0) {
1509 pDevice->config_file.ZoneType=ZoneType_USA;
1510 }
1511 else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
1512 pDevice->config_file.ZoneType=ZoneType_Japan;
1513 }
1514 else if(memcmp(tmpbuffer,"EUROPE",6)==0) {
1515 pDevice->config_file.ZoneType=ZoneType_Europe;
1516 }
1517 else {
1518 printk("Unknown Zonetype[%s]?\n",tmpbuffer);
1519 }
1520 }
1521}
1522
Forest Bond92b96792009-06-13 07:38:31 -04001523//get other parameter
1524 {
1525 memset(tmpbuffer,0,sizeof(tmpbuffer));
1526 if(Config_FileGetParameter("AUTHENMODE",tmpbuffer,buffer)==TRUE) {
1527 pDevice->config_file.eAuthenMode = (int) simple_strtol(tmpbuffer, NULL, 10);
1528 }
1529
1530 memset(tmpbuffer,0,sizeof(tmpbuffer));
1531 if(Config_FileGetParameter("ENCRYPTIONMODE",tmpbuffer,buffer)==TRUE) {
1532 pDevice->config_file.eEncryptionStatus= (int) simple_strtol(tmpbuffer, NULL, 10);
1533 }
1534 }
Forest Bond92b96792009-06-13 07:38:31 -04001535
1536 kfree(buffer);
1537 return result;
1538}
1539
1540static void device_set_multi(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001541 PSDevice pDevice = (PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001542 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1543 u32 mc_filter[2];
1544 int ii;
Jiri Pirko22bedad32010-04-01 21:22:57 +00001545 struct netdev_hw_addr *ha;
Forest Bond92b96792009-06-13 07:38:31 -04001546 BYTE pbyData[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1547 BYTE byTmpMode = 0;
1548 int rc;
1549
1550
1551 spin_lock_irq(&pDevice->lock);
1552 rc = CONTROLnsRequestIn(pDevice,
1553 MESSAGE_TYPE_READ,
1554 MAC_REG_RCR,
1555 MESSAGE_REQUEST_MACREG,
1556 1,
1557 &byTmpMode
1558 );
1559 if (rc == 0) pDevice->byRxMode = byTmpMode;
1560
1561 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode in= %x\n", pDevice->byRxMode);
1562
1563 if (dev->flags & IFF_PROMISC) { // Set promiscuous.
1564 DBG_PRT(MSG_LEVEL_ERR,KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
1565 // Unconditionally log net taps.
1566 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
1567 }
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001568 else if ((netdev_mc_count(dev) > pDevice->multicast_limit) ||
1569 (dev->flags & IFF_ALLMULTI)) {
Forest Bond92b96792009-06-13 07:38:31 -04001570 CONTROLnsRequestOut(pDevice,
1571 MESSAGE_TYPE_WRITE,
1572 MAC_REG_MAR0,
1573 MESSAGE_REQUEST_MACREG,
1574 8,
1575 pbyData
1576 );
1577 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1578 }
1579 else {
1580 memset(mc_filter, 0, sizeof(mc_filter));
Jiri Pirko22bedad32010-04-01 21:22:57 +00001581 netdev_for_each_mc_addr(ha, dev) {
1582 int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
Forest Bond92b96792009-06-13 07:38:31 -04001583 mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
1584 }
1585 for (ii = 0; ii < 4; ii++) {
1586 MACvWriteMultiAddr(pDevice, ii, *((PBYTE)&mc_filter[0] + ii));
1587 MACvWriteMultiAddr(pDevice, ii+ 4, *((PBYTE)&mc_filter[1] + ii));
1588 }
1589 pDevice->byRxMode &= ~(RCR_UNICAST);
1590 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1591 }
1592
1593 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
1594 // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac.
1595 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1596 pDevice->byRxMode &= ~(RCR_UNICAST);
1597 }
1598 ControlvWriteByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_RCR, pDevice->byRxMode);
1599 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode out= %x\n", pDevice->byRxMode);
1600 spin_unlock_irq(&pDevice->lock);
1601
1602}
1603
1604
1605static struct net_device_stats *device_get_stats(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001606 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001607
1608 return &pDevice->stats;
1609}
1610
1611
1612static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001613 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001614 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1615 PSCmdRequest pReq;
1616 //BOOL bCommit = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001617 struct iwreq *wrq = (struct iwreq *) rq;
1618 int rc =0;
Forest Bond92b96792009-06-13 07:38:31 -04001619
1620 if (pMgmt == NULL) {
1621 rc = -EFAULT;
1622 return rc;
1623 }
1624
1625 switch(cmd) {
1626
Forest Bond92b96792009-06-13 07:38:31 -04001627 case SIOCGIWNAME:
1628 rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL);
1629 break;
1630
1631 case SIOCSIWNWID:
1632 rc = -EOPNOTSUPP;
1633 break;
1634
1635 case SIOCGIWNWID: //0x8b03 support
1636 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1637 rc = iwctl_giwnwid(dev, NULL, &(wrq->u.nwid), NULL);
1638 #else
1639 rc = -EOPNOTSUPP;
1640 #endif
1641 break;
1642
1643 // Set frequency/channel
1644 case SIOCSIWFREQ:
1645 rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL);
1646 break;
1647
1648 // Get frequency/channel
1649 case SIOCGIWFREQ:
1650 rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL);
1651 break;
1652
1653 // Set desired network name (ESSID)
1654 case SIOCSIWESSID:
1655
1656 {
1657 char essid[IW_ESSID_MAX_SIZE+1];
1658 if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
1659 rc = -E2BIG;
1660 break;
1661 }
1662 if (copy_from_user(essid, wrq->u.essid.pointer,
1663 wrq->u.essid.length)) {
1664 rc = -EFAULT;
1665 break;
1666 }
1667 rc = iwctl_siwessid(dev, NULL,
1668 &(wrq->u.essid), essid);
1669 }
1670 break;
1671
1672
1673 // Get current network name (ESSID)
1674 case SIOCGIWESSID:
1675
1676 {
1677 char essid[IW_ESSID_MAX_SIZE+1];
1678 if (wrq->u.essid.pointer)
1679 rc = iwctl_giwessid(dev, NULL,
1680 &(wrq->u.essid), essid);
1681 if (copy_to_user(wrq->u.essid.pointer,
1682 essid,
1683 wrq->u.essid.length) )
1684 rc = -EFAULT;
1685 }
1686 break;
1687
1688 case SIOCSIWAP:
1689
1690 rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL);
1691 break;
1692
1693
1694 // Get current Access Point (BSSID)
1695 case SIOCGIWAP:
1696 rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL);
1697 break;
1698
1699
1700 // Set desired station name
1701 case SIOCSIWNICKN:
1702 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n");
1703 rc = -EOPNOTSUPP;
1704 break;
1705
1706 // Get current station name
1707 case SIOCGIWNICKN:
1708 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n");
1709 rc = -EOPNOTSUPP;
1710 break;
1711
1712 // Set the desired bit-rate
1713 case SIOCSIWRATE:
1714 rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL);
1715 break;
1716
1717 // Get the current bit-rate
1718 case SIOCGIWRATE:
1719
1720 rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
1721 break;
1722
1723 // Set the desired RTS threshold
1724 case SIOCSIWRTS:
1725
1726 rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL);
1727 break;
1728
1729 // Get the current RTS threshold
1730 case SIOCGIWRTS:
1731
1732 rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL);
1733 break;
1734
1735 // Set the desired fragmentation threshold
1736 case SIOCSIWFRAG:
1737
1738 rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL);
1739 break;
1740
1741 // Get the current fragmentation threshold
1742 case SIOCGIWFRAG:
1743
1744 rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL);
1745 break;
1746
1747 // Set mode of operation
1748 case SIOCSIWMODE:
1749 rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL);
1750 break;
1751
1752 // Get mode of operation
1753 case SIOCGIWMODE:
1754 rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
1755 break;
1756
1757 // Set WEP keys and mode
1758 case SIOCSIWENCODE:
1759 {
1760 char abyKey[WLAN_WEP232_KEYLEN];
1761
1762 if (wrq->u.encoding.pointer) {
1763
1764
1765 if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) {
1766 rc = -E2BIG;
1767 break;
1768 }
1769 memset(abyKey, 0, WLAN_WEP232_KEYLEN);
1770 if (copy_from_user(abyKey,
1771 wrq->u.encoding.pointer,
1772 wrq->u.encoding.length)) {
1773 rc = -EFAULT;
1774 break;
1775 }
1776 } else if (wrq->u.encoding.length != 0) {
1777 rc = -EINVAL;
1778 break;
1779 }
1780 rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey);
1781 }
1782 break;
1783
1784 // Get the WEP keys and mode
1785 case SIOCGIWENCODE:
1786
1787 if (!capable(CAP_NET_ADMIN)) {
1788 rc = -EPERM;
1789 break;
1790 }
1791 {
1792 char abyKey[WLAN_WEP232_KEYLEN];
1793
1794 rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey);
1795 if (rc != 0) break;
1796 if (wrq->u.encoding.pointer) {
1797 if (copy_to_user(wrq->u.encoding.pointer,
1798 abyKey,
1799 wrq->u.encoding.length))
1800 rc = -EFAULT;
1801 }
1802 }
1803 break;
1804
Forest Bond92b96792009-06-13 07:38:31 -04001805 // Get the current Tx-Power
1806 case SIOCGIWTXPOW:
1807 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
1808 rc = -EOPNOTSUPP;
1809 break;
1810
1811 case SIOCSIWTXPOW:
1812 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
1813 rc = -EOPNOTSUPP;
1814 break;
1815
Forest Bond92b96792009-06-13 07:38:31 -04001816 case SIOCSIWRETRY:
1817
1818 rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL);
1819 break;
1820
1821 case SIOCGIWRETRY:
1822
1823 rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL);
1824 break;
1825
Forest Bond92b96792009-06-13 07:38:31 -04001826 // Get range of parameters
1827 case SIOCGIWRANGE:
1828
1829 {
1830 struct iw_range range;
1831
1832 rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *) &range);
1833 if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
1834 rc = -EFAULT;
1835 }
1836
1837 break;
1838
1839 case SIOCGIWPOWER:
1840
1841 rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL);
1842 break;
1843
1844
1845 case SIOCSIWPOWER:
1846
1847 rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL);
1848 break;
1849
1850
1851 case SIOCGIWSENS:
1852
1853 rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL);
1854 break;
1855
1856 case SIOCSIWSENS:
1857 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n");
1858 rc = -EOPNOTSUPP;
1859 break;
1860
1861 case SIOCGIWAPLIST:
1862 {
1863 char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
1864
1865 if (wrq->u.data.pointer) {
1866 rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
1867 if (rc == 0) {
1868 if (copy_to_user(wrq->u.data.pointer,
1869 buffer,
1870 (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality)))
1871 ))
1872 rc = -EFAULT;
1873 }
1874 }
1875 }
1876 break;
1877
1878
1879#ifdef WIRELESS_SPY
1880 // Set the spy list
1881 case SIOCSIWSPY:
1882
1883 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
1884 rc = -EOPNOTSUPP;
1885 break;
1886
1887 // Get the spy list
1888 case SIOCGIWSPY:
1889
1890 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
1891 rc = -EOPNOTSUPP;
1892 break;
1893
1894#endif // WIRELESS_SPY
1895
1896 case SIOCGIWPRIV:
1897 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n");
1898 rc = -EOPNOTSUPP;
1899/*
1900 if(wrq->u.data.pointer) {
1901 wrq->u.data.length = sizeof(iwctl_private_args) / sizeof( iwctl_private_args[0]);
1902
1903 if(copy_to_user(wrq->u.data.pointer,
1904 (u_char *) iwctl_private_args,
1905 sizeof(iwctl_private_args)))
1906 rc = -EFAULT;
1907 }
1908*/
1909 break;
1910
Forest Bond92b96792009-06-13 07:38:31 -04001911#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1912 case SIOCSIWAUTH:
Andres More465711b2010-08-03 20:25:50 -03001913 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
Forest Bond92b96792009-06-13 07:38:31 -04001914 rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
1915 break;
1916
1917 case SIOCGIWAUTH:
1918 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH \n");
1919 rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
1920 break;
1921
1922 case SIOCSIWGENIE:
1923 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE \n");
1924 rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1925 break;
1926
1927 case SIOCGIWGENIE:
1928 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE \n");
1929 rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1930 break;
1931
1932 case SIOCSIWENCODEEXT:
1933 {
1934 char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
1935 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n");
1936 if(wrq->u.encoding.pointer){
1937 memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1);
1938 if(wrq->u.encoding.length > (sizeof(struct iw_encode_ext)+ MAX_KEY_LEN)){
1939 rc = -E2BIG;
1940 break;
1941 }
1942 if(copy_from_user(extra, wrq->u.encoding.pointer,wrq->u.encoding.length)){
1943 rc = -EFAULT;
1944 break;
1945 }
1946 }else if(wrq->u.encoding.length != 0){
1947 rc = -EINVAL;
1948 break;
1949 }
1950 rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra);
1951 }
1952 break;
1953
1954 case SIOCGIWENCODEEXT:
1955 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n");
1956 rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
1957 break;
1958
1959 case SIOCSIWMLME:
1960 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME \n");
1961 rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1962 break;
1963
1964#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
Forest Bond92b96792009-06-13 07:38:31 -04001965
Forest Bond92b96792009-06-13 07:38:31 -04001966 case IOCTL_CMD_TEST:
1967
1968 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1969 rc = -EFAULT;
1970 break;
1971 } else {
1972 rc = 0;
1973 }
1974 pReq = (PSCmdRequest)rq;
1975
1976 //20080130-01,<Remark> by Mike Liu
1977 // if(pDevice->bLinkPass==TRUE)
1978 pReq->wResult = MAGIC_CODE; //Linking status:0x3142
1979 //20080130-02,<Remark> by Mike Liu
1980 // else
1981 // pReq->wResult = MAGIC_CODE+1; //disconnect status:0x3143
1982 break;
1983
1984 case IOCTL_CMD_SET:
1985 if (!(pDevice->flags & DEVICE_FLAGS_OPENED) &&
1986 (((PSCmdRequest)rq)->wCmdCode !=WLAN_CMD_SET_WPA))
1987 {
1988 rc = -EFAULT;
1989 break;
1990 } else {
1991 rc = 0;
1992 }
1993
1994 if (test_and_set_bit( 0, (void*)&(pMgmt->uCmdBusy))) {
1995 return -EBUSY;
1996 }
1997 rc = private_ioctl(pDevice, rq);
1998 clear_bit( 0, (void*)&(pMgmt->uCmdBusy));
1999 break;
2000
2001 case IOCTL_CMD_HOSTAPD:
2002
2003 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
2004 rc = -EFAULT;
2005 break;
2006 } else {
2007 rc = 0;
2008 }
2009
Forest Bondc30d7972010-04-17 11:03:38 -04002010 rc = vt6656_hostap_ioctl(pDevice, &wrq->u.data);
Forest Bond92b96792009-06-13 07:38:31 -04002011 break;
2012
2013 case IOCTL_CMD_WPA:
2014
2015 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
2016 rc = -EFAULT;
2017 break;
2018 } else {
2019 rc = 0;
2020 }
2021
Forest Bond92b96792009-06-13 07:38:31 -04002022 rc = wpa_ioctl(pDevice, &wrq->u.data);
Forest Bond92b96792009-06-13 07:38:31 -04002023 break;
2024
2025 case SIOCETHTOOL:
2026 return ethtool_ioctl(dev, (void *) rq->ifr_data);
2027 // All other calls are currently unsupported
2028
2029 default:
2030 rc = -EOPNOTSUPP;
2031 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd);
2032
2033
2034 }
2035
2036 if (pDevice->bCommit) {
2037 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2038 netif_stop_queue(pDevice->dev);
2039 spin_lock_irq(&pDevice->lock);
Andres More0cbd8d92010-05-06 20:34:29 -03002040 bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002041 spin_unlock_irq(&pDevice->lock);
2042 }
2043 else {
2044 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
2045 spin_lock_irq(&pDevice->lock);
2046//2007-1121-01<Modify>by EinsnLiu
Andres More0cbd8d92010-05-06 20:34:29 -03002047 if (pDevice->bLinkPass &&
Forest Bond92b96792009-06-13 07:38:31 -04002048 memcmp(pMgmt->abyCurrSSID,pMgmt->abyDesireSSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN)) {
Andres More0cbd8d92010-05-06 20:34:29 -03002049 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002050 } else {
2051 pDevice->bLinkPass = FALSE;
2052 pMgmt->eCurrState = WMAC_STATE_IDLE;
2053 memset(pMgmt->abyCurrBSSID, 0, 6);
2054 }
2055 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
2056//End Modify
2057 netif_stop_queue(pDevice->dev);
2058#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
2059 pMgmt->eScanType = WMAC_SCAN_ACTIVE;
Andres More0cbd8d92010-05-06 20:34:29 -03002060 if (!pDevice->bWPASuppWextEnabled)
Forest Bond92b96792009-06-13 07:38:31 -04002061#endif
Andres More0cbd8d92010-05-06 20:34:29 -03002062 bScheduleCommand((void *) pDevice,
2063 WLAN_CMD_BSSID_SCAN,
2064 pMgmt->abyDesireSSID);
2065 bScheduleCommand((void *) pDevice,
2066 WLAN_CMD_SSID,
2067 NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002068 spin_unlock_irq(&pDevice->lock);
2069 }
2070 pDevice->bCommit = FALSE;
2071 }
2072
2073
2074 return rc;
2075}
2076
2077
2078static int ethtool_ioctl(struct net_device *dev, void *useraddr)
2079{
2080 u32 ethcmd;
2081
2082 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
2083 return -EFAULT;
2084
2085 switch (ethcmd) {
2086 case ETHTOOL_GDRVINFO: {
2087 struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
2088 strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
2089 strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
2090 if (copy_to_user(useraddr, &info, sizeof(info)))
2091 return -EFAULT;
2092 return 0;
2093 }
2094
2095 }
2096
2097 return -EOPNOTSUPP;
2098}
2099
2100
2101/*------------------------------------------------------------------*/
2102
Andres More26e5b652010-04-13 19:43:07 -03002103MODULE_DEVICE_TABLE(usb, vt6656_table);
Forest Bond92b96792009-06-13 07:38:31 -04002104
Andres More26e5b652010-04-13 19:43:07 -03002105static struct usb_driver vt6656_driver = {
2106 .name = DEVICE_NAME,
2107 .probe = vt6656_probe,
2108 .disconnect = vt6656_disconnect,
2109 .id_table = vt6656_table,
Forest Bond92b96792009-06-13 07:38:31 -04002110#ifdef CONFIG_PM
Andres More26e5b652010-04-13 19:43:07 -03002111 .suspend = vt6656_suspend,
2112 .resume = vt6656_resume,
2113#endif /* CONFIG_PM */
Forest Bond92b96792009-06-13 07:38:31 -04002114};
2115
Andres More26e5b652010-04-13 19:43:07 -03002116static int __init vt6656_init_module(void)
Forest Bond92b96792009-06-13 07:38:31 -04002117{
Forest Bondf4a8df92009-06-13 07:38:56 -04002118 printk(KERN_NOTICE DEVICE_FULL_DRV_NAM " " DEVICE_VERSION);
Andres More26e5b652010-04-13 19:43:07 -03002119 return usb_register(&vt6656_driver);
Forest Bond92b96792009-06-13 07:38:31 -04002120}
2121
Andres More26e5b652010-04-13 19:43:07 -03002122static void __exit vt6656_cleanup_module(void)
Forest Bond92b96792009-06-13 07:38:31 -04002123{
Andres More26e5b652010-04-13 19:43:07 -03002124 usb_deregister(&vt6656_driver);
Forest Bond92b96792009-06-13 07:38:31 -04002125}
2126
Andres More26e5b652010-04-13 19:43:07 -03002127module_init(vt6656_init_module);
2128module_exit(vt6656_cleanup_module);