blob: 73a083819100f17456cac2a2cd235eeb1ff2a882 [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
Andy Shevchenkod6a32aa2011-07-26 10:35:31 +0300614 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %pM\n",
615 pDevice->abyCurrentNetAddr);
Forest Bond92b96792009-06-13 07:38:31 -0400616 }
617
Forest Bond92b96792009-06-13 07:38:31 -0400618 // Set BB and packet type at the same time.
619 // Set Short Slot Time, xIFS, and RSPINF.
620 if (pDevice->byBBType == BB_TYPE_11A) {
621 CARDbAddBasicRate(pDevice, RATE_6M);
622 pDevice->bShortSlotTime = TRUE;
623 } else {
624 CARDbAddBasicRate(pDevice, RATE_1M);
625 pDevice->bShortSlotTime = FALSE;
626 }
627 BBvSetShortSlotTime(pDevice);
628 CARDvSetBSSMode(pDevice);
629
630 if (pDevice->bUpdateBBVGA) {
631 pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
632 pDevice->byBBVGANew = pDevice->byBBVGACurrent;
633 BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
634 }
635
636 pDevice->byRadioCtl = pDevice->abyEEPROM[EEP_OFS_RADIOCTL];
637 pDevice->bHWRadioOff = FALSE;
638 if ( (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) != 0 ) {
639 ntStatus = CONTROLnsRequestIn(pDevice,
640 MESSAGE_TYPE_READ,
641 MAC_REG_GPIOCTL1,
642 MESSAGE_REQUEST_MACREG,
643 1,
644 &byTmp);
645
646 if ( ntStatus != STATUS_SUCCESS ) {
647 spin_unlock_irq(&pDevice->lock);
648 return FALSE;
649 }
650 if ( (byTmp & GPIO3_DATA) == 0 ) {
651 pDevice->bHWRadioOff = TRUE;
652 MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
653 } else {
654 MACvRegBitsOff(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
655 pDevice->bHWRadioOff = FALSE;
656 }
657
658 } //EEP_RADIOCTL_ENABLE
659
660 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_TMLEN,0x38);
661 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
662 MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL0,0x01);
663
664 if ((pDevice->bHWRadioOff == TRUE) || (pDevice->bRadioControlOff == TRUE)) {
665 CARDbRadioPowerOff(pDevice);
666 } else {
667 CARDbRadioPowerOn(pDevice);
668 }
669
670 spin_unlock_irq(&pDevice->lock);
671 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----INIbInitAdapter Exit\n");
672 return TRUE;
673}
674
675static BOOL device_release_WPADEV(PSDevice pDevice)
676{
677 viawget_wpa_header *wpahdr;
678 int ii=0;
679 // wait_queue_head_t Set_wait;
680 //send device close to wpa_supplicnat layer
681 if (pDevice->bWPADEVUp==TRUE) {
682 wpahdr = (viawget_wpa_header *)pDevice->skb->data;
683 wpahdr->type = VIAWGET_DEVICECLOSE_MSG;
684 wpahdr->resp_ie_len = 0;
685 wpahdr->req_ie_len = 0;
686 skb_put(pDevice->skb, sizeof(viawget_wpa_header));
687 pDevice->skb->dev = pDevice->wpadev;
Jim Liebd899d4032009-07-23 17:22:42 -0700688 skb_reset_mac_header(pDevice->skb);
Forest Bond92b96792009-06-13 07:38:31 -0400689 pDevice->skb->pkt_type = PACKET_HOST;
690 pDevice->skb->protocol = htons(ETH_P_802_2);
691 memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
692 netif_rx(pDevice->skb);
693 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
694
695 //wait release WPADEV
696 // init_waitqueue_head(&Set_wait);
697 // wait_event_timeout(Set_wait, ((pDevice->wpadev==NULL)&&(pDevice->skb == NULL)),5*HZ); //1s wait
698 while(pDevice->bWPADEVUp==TRUE) {
699 set_current_state(TASK_UNINTERRUPTIBLE);
700 schedule_timeout (HZ/20); //wait 50ms
701 ii++;
702 if(ii>20)
703 break;
704 }
Joe Perches9fc86022011-04-10 14:31:32 -0700705 }
Forest Bond92b96792009-06-13 07:38:31 -0400706 return TRUE;
707}
708
709#ifdef CONFIG_PM /* Minimal support for suspend and resume */
Andres More26e5b652010-04-13 19:43:07 -0300710
711static int vt6656_suspend(struct usb_interface *intf, pm_message_t message)
Forest Bond92b96792009-06-13 07:38:31 -0400712{
Andres Moree54d9eb2010-06-21 15:35:43 -0300713 PSDevice device = usb_get_intfdata(intf);
Forest Bond92b96792009-06-13 07:38:31 -0400714
Andres Moree54d9eb2010-06-21 15:35:43 -0300715 if (!device || !device->dev)
716 return -ENODEV;
Forest Bond92b96792009-06-13 07:38:31 -0400717
Andres Moree54d9eb2010-06-21 15:35:43 -0300718 if (device->flags & DEVICE_FLAGS_OPENED)
719 device_close(device->dev);
720
721 usb_put_dev(interface_to_usbdev(intf));
722
723 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400724}
725
Andres More26e5b652010-04-13 19:43:07 -0300726static int vt6656_resume(struct usb_interface *intf)
Forest Bond92b96792009-06-13 07:38:31 -0400727{
Andres Moree54d9eb2010-06-21 15:35:43 -0300728 PSDevice device = usb_get_intfdata(intf);
Forest Bond92b96792009-06-13 07:38:31 -0400729
Andres Moree54d9eb2010-06-21 15:35:43 -0300730 if (!device || !device->dev)
731 return -ENODEV;
732
733 usb_get_dev(interface_to_usbdev(intf));
734
735 if (!(device->flags & DEVICE_FLAGS_OPENED))
736 device_open(device->dev);
737
738 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400739}
Forest Bond92b96792009-06-13 07:38:31 -0400740
Andres More26e5b652010-04-13 19:43:07 -0300741#endif /* CONFIG_PM */
Forest Bonddd8db702009-06-13 07:38:54 -0400742
743static const struct net_device_ops device_netdev_ops = {
744 .ndo_open = device_open,
745 .ndo_stop = device_close,
746 .ndo_do_ioctl = device_ioctl,
747 .ndo_get_stats = device_get_stats,
748 .ndo_start_xmit = device_xmit,
749 .ndo_set_multicast_list = device_set_multi,
750};
751
Andres More26e5b652010-04-13 19:43:07 -0300752static int __devinit
753vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
Forest Bond92b96792009-06-13 07:38:31 -0400754{
Andres More9a0e7562010-04-13 21:54:48 -0300755 u8 fake_mac[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
Forest Bond92b96792009-06-13 07:38:31 -0400756 struct usb_device *udev = interface_to_usbdev(intf);
Andres More7a8b0052010-07-12 12:40:01 -0300757 int rc = 0;
758 struct net_device *netdev = NULL;
759 PSDevice pDevice = NULL;
Forest Bond92b96792009-06-13 07:38:31 -0400760
Andres More7a8b0052010-07-12 12:40:01 -0300761 printk(KERN_NOTICE "%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
762 printk(KERN_NOTICE "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
Forest Bond92b96792009-06-13 07:38:31 -0400763
Andres More7a8b0052010-07-12 12:40:01 -0300764 udev = usb_get_dev(udev);
765 netdev = alloc_etherdev(sizeof(DEVICE_INFO));
Andres More7a8b0052010-07-12 12:40:01 -0300766 if (!netdev) {
767 printk(KERN_ERR DEVICE_NAME ": allocate net device failed\n");
Dan Carpentere3a92cd2010-08-10 08:00:12 +0200768 rc = -ENOMEM;
Andres More7a8b0052010-07-12 12:40:01 -0300769 goto err_nomem;
770 }
Forest Bond92b96792009-06-13 07:38:31 -0400771
Andres More7a8b0052010-07-12 12:40:01 -0300772 pDevice = netdev_priv(netdev);
773 memset(pDevice, 0, sizeof(DEVICE_INFO));
Forest Bond92b96792009-06-13 07:38:31 -0400774
Andres More7a8b0052010-07-12 12:40:01 -0300775 pDevice->dev = netdev;
776 pDevice->usb = udev;
Forest Bond1e28efa2009-06-13 07:38:50 -0400777
Andres More7a8b0052010-07-12 12:40:01 -0300778 device_set_options(pDevice);
779 spin_lock_init(&pDevice->lock);
Forest Bond1e28efa2009-06-13 07:38:50 -0400780
Andres More7a8b0052010-07-12 12:40:01 -0300781 pDevice->tx_80211 = device_dma0_tx_80211;
782 pDevice->sMgmtObj.pAdapter = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400783
Andres More7a8b0052010-07-12 12:40:01 -0300784 netdev->netdev_ops = &device_netdev_ops;
785 netdev->wireless_handlers =
786 (struct iw_handler_def *) &iwctl_handler_def;
Forest Bond92b96792009-06-13 07:38:31 -0400787
Andres More7a8b0052010-07-12 12:40:01 -0300788 usb_set_intfdata(intf, pDevice);
Forest Bond92b96792009-06-13 07:38:31 -0400789 SET_NETDEV_DEV(netdev, &intf->dev);
Andres More7a8b0052010-07-12 12:40:01 -0300790 memcpy(pDevice->dev->dev_addr, fake_mac, ETH_ALEN);
791 rc = register_netdev(netdev);
792 if (rc) {
793 printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
Dan Carpentere3a92cd2010-08-10 08:00:12 +0200794 goto err_netdev;
Andres More7a8b0052010-07-12 12:40:01 -0300795 }
Forest Bond92b96792009-06-13 07:38:31 -0400796
Andres More7a8b0052010-07-12 12:40:01 -0300797 usb_device_reset(pDevice);
Forest Bond92b96792009-06-13 07:38:31 -0400798
Andres More7a8b0052010-07-12 12:40:01 -0300799 {
800 union iwreq_data wrqu;
801 memset(&wrqu, 0, sizeof(wrqu));
802 wrqu.data.flags = RT_INSMOD_EVENT_FLAG;
803 wrqu.data.length = IFNAMSIZ;
804 wireless_send_event(pDevice->dev,
805 IWEVCUSTOM,
806 &wrqu,
807 pDevice->dev->name);
808 }
Forest Bond92b96792009-06-13 07:38:31 -0400809
810 return 0;
Forest Bond92b96792009-06-13 07:38:31 -0400811
Dan Carpentere3a92cd2010-08-10 08:00:12 +0200812err_netdev:
813 free_netdev(netdev);
Forest Bond92b96792009-06-13 07:38:31 -0400814err_nomem:
Andres More7a8b0052010-07-12 12:40:01 -0300815 usb_put_dev(udev);
Forest Bond92b96792009-06-13 07:38:31 -0400816
Dan Carpentere3a92cd2010-08-10 08:00:12 +0200817 return rc;
Forest Bond92b96792009-06-13 07:38:31 -0400818}
819
Andres More8611a292010-05-01 14:25:00 -0300820static void device_free_tx_bufs(PSDevice pDevice)
821{
Forest Bond92b96792009-06-13 07:38:31 -0400822 PUSB_SEND_CONTEXT pTxContext;
823 int ii;
824
825 for (ii = 0; ii < pDevice->cbTD; ii++) {
826
827 pTxContext = pDevice->apTD[ii];
828 //de-allocate URBs
829 if (pTxContext->pUrb) {
Jim Liebdad72fe2009-08-12 14:54:14 -0700830 usb_kill_urb(pTxContext->pUrb);
Forest Bond92b96792009-06-13 07:38:31 -0400831 usb_free_urb(pTxContext->pUrb);
832 }
Ilia Mirkin1d5c5362011-03-13 00:29:15 -0500833 kfree(pTxContext);
Forest Bond92b96792009-06-13 07:38:31 -0400834 }
835 return;
836}
837
838
Andres More8611a292010-05-01 14:25:00 -0300839static void device_free_rx_bufs(PSDevice pDevice)
840{
Forest Bond92b96792009-06-13 07:38:31 -0400841 PRCB pRCB;
842 int ii;
843
844 for (ii = 0; ii < pDevice->cbRD; ii++) {
845
846 pRCB = pDevice->apRCB[ii];
847 //de-allocate URBs
848 if (pRCB->pUrb) {
Jim Liebdad72fe2009-08-12 14:54:14 -0700849 usb_kill_urb(pRCB->pUrb);
Forest Bond92b96792009-06-13 07:38:31 -0400850 usb_free_urb(pRCB->pUrb);
851 }
852 //de-allocate skb
853 if (pRCB->skb)
854 dev_kfree_skb(pRCB->skb);
855 }
Ilia Mirkin1d5c5362011-03-13 00:29:15 -0500856 kfree(pDevice->pRCBMem);
Forest Bond92b96792009-06-13 07:38:31 -0400857
858 return;
859}
860
Forest Bond92b96792009-06-13 07:38:31 -0400861static void usb_device_reset(PSDevice pDevice)
862{
863 int status;
864 status = usb_reset_device(pDevice->usb);
865 if (status)
866 printk("usb_device_reset fail status=%d\n",status);
867 return ;
868}
Forest Bond92b96792009-06-13 07:38:31 -0400869
Andres More8611a292010-05-01 14:25:00 -0300870static void device_free_int_bufs(PSDevice pDevice)
871{
Ilia Mirkin1d5c5362011-03-13 00:29:15 -0500872 kfree(pDevice->intBuf.pDataBuf);
Forest Bond92b96792009-06-13 07:38:31 -0400873 return;
874}
875
876
877static BOOL device_alloc_bufs(PSDevice pDevice) {
878
879 PUSB_SEND_CONTEXT pTxContext;
880 PRCB pRCB;
881 int ii;
882
883
884 for (ii = 0; ii < pDevice->cbTD; ii++) {
885
886 pTxContext = kmalloc(sizeof(USB_SEND_CONTEXT), GFP_KERNEL);
887 if (pTxContext == NULL) {
888 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : allocate tx usb context failed\n", pDevice->dev->name);
889 goto free_tx;
890 }
891 pDevice->apTD[ii] = pTxContext;
Andres More8611a292010-05-01 14:25:00 -0300892 pTxContext->pDevice = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400893 //allocate URBs
Jim Liebdad72fe2009-08-12 14:54:14 -0700894 pTxContext->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400895 if (pTxContext->pUrb == NULL) {
896 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "alloc tx urb failed\n");
897 goto free_tx;
898 }
899 pTxContext->bBoolInUse = FALSE;
900 }
901
902 // allocate rcb mem
903 pDevice->pRCBMem = kmalloc((sizeof(RCB) * pDevice->cbRD), GFP_KERNEL);
904 if (pDevice->pRCBMem == NULL) {
905 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : alloc rx usb context failed\n", pDevice->dev->name);
906 goto free_tx;
907 }
908
909
910 pDevice->FirstRecvFreeList = NULL;
911 pDevice->LastRecvFreeList = NULL;
912 pDevice->FirstRecvMngList = NULL;
913 pDevice->LastRecvMngList = NULL;
914 pDevice->NumRecvFreeList = 0;
915 memset(pDevice->pRCBMem, 0, (sizeof(RCB) * pDevice->cbRD));
916 pRCB = (PRCB) pDevice->pRCBMem;
917
918 for (ii = 0; ii < pDevice->cbRD; ii++) {
919
920 pDevice->apRCB[ii] = pRCB;
Andres More8611a292010-05-01 14:25:00 -0300921 pRCB->pDevice = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400922 //allocate URBs
Jim Liebdad72fe2009-08-12 14:54:14 -0700923 pRCB->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400924
925 if (pRCB->pUrb == NULL) {
926 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx urb\n");
927 goto free_rx_tx;
928 }
929 pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
930 if (pRCB->skb == NULL) {
931 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx skb\n");
932 goto free_rx_tx;
933 }
934 pRCB->skb->dev = pDevice->dev;
935 pRCB->bBoolInUse = FALSE;
936 EnqueueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList, pRCB);
937 pDevice->NumRecvFreeList++;
938 pRCB++;
939 }
940
941
Jim Liebdad72fe2009-08-12 14:54:14 -0700942 pDevice->pControlURB = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400943 if (pDevice->pControlURB == NULL) {
944 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc control urb\n");
945 goto free_rx_tx;
946 }
947
Jim Liebdad72fe2009-08-12 14:54:14 -0700948 pDevice->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400949 if (pDevice->pInterruptURB == NULL) {
950 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int urb\n");
Forest Bond92b96792009-06-13 07:38:31 -0400951 usb_free_urb(pDevice->pControlURB);
952 goto free_rx_tx;
953 }
954
955 pDevice->intBuf.pDataBuf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
956 if (pDevice->intBuf.pDataBuf == NULL) {
957 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int buf\n");
Forest Bond92b96792009-06-13 07:38:31 -0400958 usb_free_urb(pDevice->pControlURB);
959 usb_free_urb(pDevice->pInterruptURB);
960 goto free_rx_tx;
961 }
962
963 return TRUE;
964
965free_rx_tx:
966 device_free_rx_bufs(pDevice);
967
968free_tx:
969 device_free_tx_bufs(pDevice);
970
971 return FALSE;
972}
973
974
975
976
977static BOOL device_init_defrag_cb(PSDevice pDevice) {
978 int i;
979 PSDeFragControlBlock pDeF;
980
981 /* Init the fragment ctl entries */
982 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
983 pDeF = &(pDevice->sRxDFCB[i]);
984 if (!device_alloc_frag_buf(pDevice, pDeF)) {
985 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
986 pDevice->dev->name);
987 goto free_frag;
Joe Perches9fc86022011-04-10 14:31:32 -0700988 }
Forest Bond92b96792009-06-13 07:38:31 -0400989 }
990 pDevice->cbDFCB = CB_MAX_RX_FRAG;
991 pDevice->cbFreeDFCB = pDevice->cbDFCB;
992 return TRUE;
993
994free_frag:
995 device_free_frag_bufs(pDevice);
996 return FALSE;
997}
998
999
1000
1001static void device_free_frag_bufs(PSDevice pDevice) {
1002 PSDeFragControlBlock pDeF;
1003 int i;
1004
1005 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
1006
1007 pDeF = &(pDevice->sRxDFCB[i]);
1008
1009 if (pDeF->skb)
1010 dev_kfree_skb(pDeF->skb);
1011 }
1012}
1013
1014
1015
1016BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
1017
1018 pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1019 if (pDeF->skb == NULL)
1020 return FALSE;
1021 ASSERT(pDeF->skb);
1022 pDeF->skb->dev = pDevice->dev;
1023
1024 return TRUE;
1025}
1026
1027
1028/*-----------------------------------------------------------------*/
1029
1030static int device_open(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001031 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001032
Forest Bond92b96792009-06-13 07:38:31 -04001033 extern SWPAResult wpa_Result;
1034 memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname));
1035 wpa_Result.proto = 0;
1036 wpa_Result.key_mgmt = 0;
1037 wpa_Result.eap_type = 0;
1038 wpa_Result.authenticated = FALSE;
1039 pDevice->fWPA_Authened = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001040
1041 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_open...\n");
1042
1043
1044 pDevice->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
1045
1046 if (device_alloc_bufs(pDevice) == FALSE) {
1047 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_alloc_bufs fail... \n");
1048 return -ENOMEM;
1049 }
1050
1051 if (device_init_defrag_cb(pDevice)== FALSE) {
1052 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Initial defragement cb fail \n");
1053 goto free_rx_tx;
1054 }
1055
1056 MP_CLEAR_FLAG(pDevice, fMP_DISCONNECTED);
1057 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
1058 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
1059 MP_SET_FLAG(pDevice, fMP_POST_READS);
1060 MP_SET_FLAG(pDevice, fMP_POST_WRITES);
1061
1062 //read config file
1063 Read_config_file(pDevice);
1064
1065 if (device_init_registers(pDevice, DEVICE_INIT_COLD) == FALSE) {
1066 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " init register fail\n");
1067 goto free_all;
1068 }
1069
1070 device_set_multi(pDevice->dev);
1071 // Init for Key Management
1072
1073 KeyvInitTable(pDevice,&pDevice->sKey);
Andres More9a0e7562010-04-13 21:54:48 -03001074 memcpy(pDevice->sMgmtObj.abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN);
1075 memcpy(pDevice->dev->dev_addr, pDevice->abyCurrentNetAddr, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001076 pDevice->bStopTx0Pkt = FALSE;
1077 pDevice->bStopDataPkt = FALSE;
Andres More465711b2010-08-03 20:25:50 -03001078 pDevice->bRoaming = FALSE;
1079 pDevice->bIsRoaming = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001080 pDevice->bEnableRoaming = FALSE;
1081 if (pDevice->bDiversityRegCtlON) {
1082 device_init_diversity_timer(pDevice);
1083 }
1084
1085 vMgrObjectInit(pDevice);
1086 tasklet_init(&pDevice->RxMngWorkItem, (void *)RXvMngWorkItem, (unsigned long)pDevice);
1087 tasklet_init(&pDevice->ReadWorkItem, (void *)RXvWorkItem, (unsigned long)pDevice);
1088 tasklet_init(&pDevice->EventWorkItem, (void *)INTvWorkItem, (unsigned long)pDevice);
1089 add_timer(&(pDevice->sMgmtObj.sTimerSecondCallback));
Forest Bond92b96792009-06-13 07:38:31 -04001090 pDevice->int_interval = 100; //Max 100 microframes.
Forest Bond92b96792009-06-13 07:38:31 -04001091 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1092
1093 pDevice->bIsRxWorkItemQueued = TRUE;
1094 pDevice->fKillEventPollingThread = FALSE;
1095 pDevice->bEventAvailable = FALSE;
1096
1097 pDevice->bWPADEVUp = FALSE;
1098#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1099 pDevice->bwextstep0 = FALSE;
1100 pDevice->bwextstep1 = FALSE;
1101 pDevice->bwextstep2 = FALSE;
1102 pDevice->bwextstep3 = FALSE;
1103 pDevice->bWPASuppWextEnabled = FALSE;
1104#endif
1105 pDevice->byReAssocCount = 0;
1106
1107 RXvWorkItem(pDevice);
1108 INTvWorkItem(pDevice);
1109
1110 // Patch: if WEP key already set by iwconfig but device not yet open
1111 if ((pDevice->bEncryptionEnable == TRUE) && (pDevice->bTransmitKey == TRUE)) {
1112 spin_lock_irq(&pDevice->lock);
1113 KeybSetDefaultKey( pDevice,
1114 &(pDevice->sKey),
1115 pDevice->byKeyIndex | (1 << 31),
1116 pDevice->uKeyLength,
1117 NULL,
1118 pDevice->abyKey,
1119 KEY_CTL_WEP
1120 );
1121 spin_unlock_irq(&pDevice->lock);
1122 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1123 }
1124
1125 if (pDevice->sMgmtObj.eConfigMode == WMAC_CONFIG_AP) {
Andres More0cbd8d92010-05-06 20:34:29 -03001126 bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001127 }
1128 else {
1129 //mike:mark@2008-11-10
Andres More0cbd8d92010-05-06 20:34:29 -03001130 bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
1131 /* bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); */
Forest Bond92b96792009-06-13 07:38:31 -04001132 }
1133
1134
1135 netif_stop_queue(pDevice->dev);
1136 pDevice->flags |= DEVICE_FLAGS_OPENED;
1137
Forest Bond92b96792009-06-13 07:38:31 -04001138{
1139 union iwreq_data wrqu;
1140 memset(&wrqu, 0, sizeof(wrqu));
1141 wrqu.data.flags = RT_UPDEV_EVENT_FLAG;
1142 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1143}
Forest Bond92b96792009-06-13 07:38:31 -04001144
1145 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
1146 return 0;
1147
1148free_all:
1149 device_free_frag_bufs(pDevice);
1150free_rx_tx:
1151 device_free_rx_bufs(pDevice);
1152 device_free_tx_bufs(pDevice);
1153 device_free_int_bufs(pDevice);
Jim Liebdad72fe2009-08-12 14:54:14 -07001154 usb_kill_urb(pDevice->pControlURB);
1155 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -04001156 usb_free_urb(pDevice->pControlURB);
1157 usb_free_urb(pDevice->pInterruptURB);
1158
1159 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open fail.. \n");
1160 return -ENOMEM;
1161}
1162
1163
1164
1165static int device_close(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001166 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001167 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1168
Forest Bond92b96792009-06-13 07:38:31 -04001169 int uu;
Forest Bond92b96792009-06-13 07:38:31 -04001170
1171 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close1 \n");
1172 if (pDevice == NULL)
1173 return -ENODEV;
1174
Forest Bond92b96792009-06-13 07:38:31 -04001175{
1176 union iwreq_data wrqu;
1177 memset(&wrqu, 0, sizeof(wrqu));
1178 wrqu.data.flags = RT_DOWNDEV_EVENT_FLAG;
1179 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1180}
Forest Bond92b96792009-06-13 07:38:31 -04001181
Forest Bond92b96792009-06-13 07:38:31 -04001182 if (pDevice->bLinkPass) {
Andres More0cbd8d92010-05-06 20:34:29 -03001183 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001184 mdelay(30);
1185 }
Forest Bond92b96792009-06-13 07:38:31 -04001186
Forest Bond92b96792009-06-13 07:38:31 -04001187device_release_WPADEV(pDevice);
1188
Forest Bond92b96792009-06-13 07:38:31 -04001189 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
1190 pMgmt->bShareKeyAlgorithm = FALSE;
1191 pDevice->bEncryptionEnable = FALSE;
1192 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
Andres More33d33e422010-05-19 23:50:00 -03001193 spin_lock_irq(&pDevice->lock);
1194 for (uu = 0; uu < MAX_KEY_TABLE; uu++)
Forest Bond92b96792009-06-13 07:38:31 -04001195 MACvDisableKeyEntry(pDevice,uu);
Andres More33d33e422010-05-19 23:50:00 -03001196 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001197
1198 if ((pDevice->flags & DEVICE_FLAGS_UNPLUG) == FALSE) {
1199 MACbShutdown(pDevice);
1200 }
1201 netif_stop_queue(pDevice->dev);
1202 MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
1203 MP_CLEAR_FLAG(pDevice, fMP_POST_WRITES);
1204 MP_CLEAR_FLAG(pDevice, fMP_POST_READS);
1205 pDevice->fKillEventPollingThread = TRUE;
1206 del_timer(&pDevice->sTimerCommand);
1207 del_timer(&pMgmt->sTimerSecondCallback);
1208
Forest Bond92b96792009-06-13 07:38:31 -04001209 del_timer(&pDevice->sTimerTxData);
Forest Bond92b96792009-06-13 07:38:31 -04001210
1211 if (pDevice->bDiversityRegCtlON) {
1212 del_timer(&pDevice->TimerSQ3Tmax1);
1213 del_timer(&pDevice->TimerSQ3Tmax2);
1214 del_timer(&pDevice->TimerSQ3Tmax3);
1215 }
1216 tasklet_kill(&pDevice->RxMngWorkItem);
1217 tasklet_kill(&pDevice->ReadWorkItem);
1218 tasklet_kill(&pDevice->EventWorkItem);
1219
Andres More465711b2010-08-03 20:25:50 -03001220 pDevice->bRoaming = FALSE;
1221 pDevice->bIsRoaming = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001222 pDevice->bEnableRoaming = FALSE;
1223 pDevice->bCmdRunning = FALSE;
1224 pDevice->bLinkPass = FALSE;
1225 memset(pMgmt->abyCurrBSSID, 0, 6);
1226 pMgmt->eCurrState = WMAC_STATE_IDLE;
1227
1228 device_free_tx_bufs(pDevice);
1229 device_free_rx_bufs(pDevice);
1230 device_free_int_bufs(pDevice);
1231 device_free_frag_bufs(pDevice);
1232
Jim Liebdad72fe2009-08-12 14:54:14 -07001233 usb_kill_urb(pDevice->pControlURB);
1234 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -04001235 usb_free_urb(pDevice->pControlURB);
1236 usb_free_urb(pDevice->pInterruptURB);
1237
1238 BSSvClearNodeDBTable(pDevice, 0);
1239 pDevice->flags &=(~DEVICE_FLAGS_OPENED);
1240
1241 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n");
1242
1243 return 0;
1244}
1245
Andres More26e5b652010-04-13 19:43:07 -03001246static void __devexit vt6656_disconnect(struct usb_interface *intf)
Forest Bond92b96792009-06-13 07:38:31 -04001247{
Andres More6cda24f2010-06-22 20:43:39 -03001248 PSDevice device = usb_get_intfdata(intf);
Forest Bond92b96792009-06-13 07:38:31 -04001249
Andres More6cda24f2010-06-22 20:43:39 -03001250 if (!device)
1251 return;
Forest Bond92b96792009-06-13 07:38:31 -04001252
Andres More6cda24f2010-06-22 20:43:39 -03001253 {
1254 union iwreq_data req;
1255 memset(&req, 0, sizeof(req));
1256 req.data.flags = RT_RMMOD_EVENT_FLAG;
1257 wireless_send_event(device->dev, IWEVCUSTOM, &req, NULL);
1258 }
Forest Bond92b96792009-06-13 07:38:31 -04001259
Andres More6cda24f2010-06-22 20:43:39 -03001260 device_release_WPADEV(device);
Forest Bond92b96792009-06-13 07:38:31 -04001261
Ben Hutchings31d5bbf2011-01-09 04:16:48 +00001262 if (device->firmware)
1263 release_firmware(device->firmware);
1264
Forest Bond92b96792009-06-13 07:38:31 -04001265 usb_set_intfdata(intf, NULL);
Andres More6cda24f2010-06-22 20:43:39 -03001266 usb_put_dev(interface_to_usbdev(intf));
Forest Bond92b96792009-06-13 07:38:31 -04001267
Andres More6cda24f2010-06-22 20:43:39 -03001268 device->flags |= DEVICE_FLAGS_UNPLUG;
Forest Bond92b96792009-06-13 07:38:31 -04001269
Andres More6cda24f2010-06-22 20:43:39 -03001270 if (device->dev) {
1271 unregister_netdev(device->dev);
1272 wpa_set_wpadev(device, 0);
1273 free_netdev(device->dev);
1274 }
Forest Bond92b96792009-06-13 07:38:31 -04001275}
1276
Andres Moree1669ed2010-07-12 13:10:27 -03001277static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev)
1278{
1279 PSDevice pDevice = netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001280
Andres Moree1669ed2010-07-12 13:10:27 -03001281 spin_lock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001282
Andres Moree1669ed2010-07-12 13:10:27 -03001283 if (unlikely(pDevice->bStopTx0Pkt))
1284 dev_kfree_skb_irq(skb);
1285 else
1286 vDMA0_tx_80211(pDevice, skb);
Forest Bond92b96792009-06-13 07:38:31 -04001287
Andres Moree1669ed2010-07-12 13:10:27 -03001288 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001289
Andres Moree1669ed2010-07-12 13:10:27 -03001290 return NETDEV_TX_OK;
Forest Bond92b96792009-06-13 07:38:31 -04001291}
1292
Andres More529e5b32010-07-12 19:28:25 -03001293static int device_xmit(struct sk_buff *skb, struct net_device *dev)
1294{
1295 PSDevice pDevice = netdev_priv(dev);
1296 struct net_device_stats *stats = &pDevice->stats;
Forest Bond92b96792009-06-13 07:38:31 -04001297
Andres More529e5b32010-07-12 19:28:25 -03001298 spin_lock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001299
Andres More529e5b32010-07-12 19:28:25 -03001300 netif_stop_queue(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001301
Andres More529e5b32010-07-12 19:28:25 -03001302 if (!pDevice->bLinkPass) {
1303 dev_kfree_skb_irq(skb);
1304 goto out;
1305 }
Forest Bond92b96792009-06-13 07:38:31 -04001306
Andres More529e5b32010-07-12 19:28:25 -03001307 if (pDevice->bStopDataPkt) {
1308 dev_kfree_skb_irq(skb);
1309 stats->tx_dropped++;
1310 goto out;
1311 }
Forest Bond92b96792009-06-13 07:38:31 -04001312
Andres More529e5b32010-07-12 19:28:25 -03001313 if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb)) {
1314 if (netif_queue_stopped(dev))
1315 netif_wake_queue(dev);
1316 }
Forest Bond92b96792009-06-13 07:38:31 -04001317
Andres More529e5b32010-07-12 19:28:25 -03001318out:
1319 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001320
Andres More529e5b32010-07-12 19:28:25 -03001321 return NETDEV_TX_OK;
Forest Bond92b96792009-06-13 07:38:31 -04001322}
1323
Forest Bond92b96792009-06-13 07:38:31 -04001324static unsigned const ethernet_polynomial = 0x04c11db7U;
1325static inline u32 ether_crc(int length, unsigned char *data)
1326{
1327 int crc = -1;
1328
1329 while(--length >= 0) {
1330 unsigned char current_octet = *data++;
1331 int bit;
1332 for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
1333 crc = (crc << 1) ^
1334 ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
1335 }
1336 }
1337 return crc;
1338}
1339
1340//find out the start position of str2 from str1
Andres Morecc856e62010-05-17 21:34:01 -03001341static unsigned char *kstrstr(const unsigned char *str1,
1342 const unsigned char *str2) {
1343 int str1_len = strlen(str1);
1344 int str2_len = strlen(str2);
Forest Bond92b96792009-06-13 07:38:31 -04001345
1346 while (str1_len >= str2_len) {
1347 str1_len--;
1348 if(memcmp(str1,str2,str2_len)==0)
Andres Morecc856e62010-05-17 21:34:01 -03001349 return (unsigned char *) str1;
Forest Bond92b96792009-06-13 07:38:31 -04001350 str1++;
1351 }
1352 return NULL;
1353}
1354
Andres Morecc856e62010-05-17 21:34:01 -03001355static int Config_FileGetParameter(unsigned char *string,
1356 unsigned char *dest,
1357 unsigned char *source)
Forest Bond92b96792009-06-13 07:38:31 -04001358{
Andres Morecc856e62010-05-17 21:34:01 -03001359 unsigned char buf1[100];
1360 unsigned char buf2[100];
1361 unsigned char *start_p = NULL, *end_p = NULL, *tmp_p = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001362 int ii;
1363
1364 memset(buf1,0,100);
1365 strcat(buf1, string);
1366 strcat(buf1, "=");
1367 source+=strlen(buf1);
1368
1369//find target string start point
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001370 start_p = kstrstr(source,buf1);
1371 if (start_p == NULL)
Forest Bond92b96792009-06-13 07:38:31 -04001372 return FALSE;
1373
1374//check if current config line is marked by "#" ??
Andres More33d33e422010-05-19 23:50:00 -03001375 for (ii = 1; ; ii++) {
1376 if (memcmp(start_p - ii, "\n", 1) == 0)
1377 break;
1378 if (memcmp(start_p - ii, "#", 1) == 0)
1379 return FALSE;
1380 }
Forest Bond92b96792009-06-13 07:38:31 -04001381
1382//find target string end point
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001383 end_p = kstrstr(start_p,"\n");
1384 if (end_p == NULL) { //can't find "\n",but don't care
Forest Bond92b96792009-06-13 07:38:31 -04001385 end_p=start_p+strlen(start_p); //no include "\n"
1386 }
1387
1388 memset(buf2,0,100);
1389 memcpy(buf2,start_p,end_p-start_p); //get the tartget line
1390 buf2[end_p-start_p]='\0';
1391
1392 //find value
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001393 start_p = kstrstr(buf2,"=");
1394 if (start_p == NULL)
Forest Bond92b96792009-06-13 07:38:31 -04001395 return FALSE;
1396 memset(buf1,0,100);
1397 strcpy(buf1,start_p+1);
1398
1399 //except space
1400 tmp_p = buf1;
1401 while(*tmp_p != 0x00) {
1402 if(*tmp_p==' ')
1403 tmp_p++;
1404 else
1405 break;
1406 }
1407
1408 memcpy(dest,tmp_p,strlen(tmp_p));
1409 return TRUE;
1410}
1411
1412//if read fail,return NULL,or return data pointer;
Andres Morecc856e62010-05-17 21:34:01 -03001413static unsigned char *Config_FileOperation(PSDevice pDevice)
1414{
1415 unsigned char *config_path = CONFIG_PATH;
1416 unsigned char *buffer = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001417 struct file *filp=NULL;
1418 mm_segment_t old_fs = get_fs();
Forest Bond8f9c4662009-06-13 07:38:47 -04001419 //int oldfsuid=0,oldfsgid=0;
Andres Morecc856e62010-05-17 21:34:01 -03001420 int result = 0;
Forest Bond92b96792009-06-13 07:38:31 -04001421
1422 set_fs (KERNEL_DS);
Forest Bond8f9c4662009-06-13 07:38:47 -04001423 /* Can't do this anymore, so we rely on correct filesystem permissions:
1424 //Make sure a caller can read or write power as root
1425 oldfsuid=current->fsuid;
1426 oldfsgid=current->fsgid;
Forest Bond92b96792009-06-13 07:38:31 -04001427 current->fsuid = 0;
1428 current->fsgid = 0;
Forest Bond8f9c4662009-06-13 07:38:47 -04001429 */
Forest Bond92b96792009-06-13 07:38:31 -04001430
1431 //open file
1432 filp = filp_open(config_path, O_RDWR, 0);
1433 if (IS_ERR(filp)) {
1434 printk("Config_FileOperation file Not exist\n");
1435 result=-1;
1436 goto error2;
1437 }
1438
1439 if(!(filp->f_op) || !(filp->f_op->read) ||!(filp->f_op->write)) {
1440 printk("file %s cann't readable or writable?\n",config_path);
1441 result = -1;
1442 goto error1;
1443 }
1444
Julia Lawall32414872010-05-11 20:26:57 +02001445 buffer = kmalloc(1024, GFP_KERNEL);
Forest Bond92b96792009-06-13 07:38:31 -04001446 if(buffer==NULL) {
Justin P. Mattock682a4532011-02-24 22:13:27 -08001447 printk("allocate mem for file fail?\n");
Forest Bond92b96792009-06-13 07:38:31 -04001448 result = -1;
1449 goto error1;
1450 }
1451
1452 if(filp->f_op->read(filp, buffer, 1024, &filp->f_pos)<0) {
1453 printk("read file error?\n");
1454 result = -1;
1455 }
1456
1457error1:
1458 if(filp_close(filp,NULL))
1459 printk("Config_FileOperation:close file fail\n");
1460
1461error2:
1462 set_fs (old_fs);
Forest Bond8f9c4662009-06-13 07:38:47 -04001463
1464 /*
Forest Bond92b96792009-06-13 07:38:31 -04001465 current->fsuid=oldfsuid;
1466 current->fsgid=oldfsgid;
Forest Bond8f9c4662009-06-13 07:38:47 -04001467 */
Forest Bond92b96792009-06-13 07:38:31 -04001468
1469if(result!=0) {
Ilia Mirkin1d5c5362011-03-13 00:29:15 -05001470 kfree(buffer);
Forest Bond92b96792009-06-13 07:38:31 -04001471 buffer=NULL;
1472}
1473 return buffer;
1474}
1475
André Goddard Rosabbc9a992009-11-14 13:09:06 -02001476//return --->-1:fail; >=0:successful
Forest Bond92b96792009-06-13 07:38:31 -04001477static int Read_config_file(PSDevice pDevice) {
Andres Morecc856e62010-05-17 21:34:01 -03001478 int result = 0;
1479 unsigned char tmpbuffer[100];
1480 unsigned char *buffer = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001481
1482 //init config setting
1483 pDevice->config_file.ZoneType = -1;
1484 pDevice->config_file.eAuthenMode = -1;
1485 pDevice->config_file.eEncryptionStatus = -1;
1486
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001487 buffer = Config_FileOperation(pDevice);
1488 if (buffer == NULL) {
Forest Bond92b96792009-06-13 07:38:31 -04001489 result =-1;
1490 return result;
1491 }
1492
1493//get zonetype
1494{
1495 memset(tmpbuffer,0,sizeof(tmpbuffer));
1496 if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer) ==TRUE) {
1497 if(memcmp(tmpbuffer,"USA",3)==0) {
1498 pDevice->config_file.ZoneType=ZoneType_USA;
1499 }
1500 else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
1501 pDevice->config_file.ZoneType=ZoneType_Japan;
1502 }
1503 else if(memcmp(tmpbuffer,"EUROPE",6)==0) {
1504 pDevice->config_file.ZoneType=ZoneType_Europe;
1505 }
1506 else {
1507 printk("Unknown Zonetype[%s]?\n",tmpbuffer);
1508 }
1509 }
1510}
1511
Forest Bond92b96792009-06-13 07:38:31 -04001512//get other parameter
1513 {
1514 memset(tmpbuffer,0,sizeof(tmpbuffer));
1515 if(Config_FileGetParameter("AUTHENMODE",tmpbuffer,buffer)==TRUE) {
1516 pDevice->config_file.eAuthenMode = (int) simple_strtol(tmpbuffer, NULL, 10);
1517 }
1518
1519 memset(tmpbuffer,0,sizeof(tmpbuffer));
1520 if(Config_FileGetParameter("ENCRYPTIONMODE",tmpbuffer,buffer)==TRUE) {
1521 pDevice->config_file.eEncryptionStatus= (int) simple_strtol(tmpbuffer, NULL, 10);
1522 }
1523 }
Forest Bond92b96792009-06-13 07:38:31 -04001524
1525 kfree(buffer);
1526 return result;
1527}
1528
1529static void device_set_multi(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001530 PSDevice pDevice = (PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001531 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1532 u32 mc_filter[2];
1533 int ii;
Jiri Pirko22bedad32010-04-01 21:22:57 +00001534 struct netdev_hw_addr *ha;
Forest Bond92b96792009-06-13 07:38:31 -04001535 BYTE pbyData[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1536 BYTE byTmpMode = 0;
1537 int rc;
1538
1539
1540 spin_lock_irq(&pDevice->lock);
1541 rc = CONTROLnsRequestIn(pDevice,
1542 MESSAGE_TYPE_READ,
1543 MAC_REG_RCR,
1544 MESSAGE_REQUEST_MACREG,
1545 1,
1546 &byTmpMode
1547 );
1548 if (rc == 0) pDevice->byRxMode = byTmpMode;
1549
1550 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode in= %x\n", pDevice->byRxMode);
1551
1552 if (dev->flags & IFF_PROMISC) { // Set promiscuous.
1553 DBG_PRT(MSG_LEVEL_ERR,KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
1554 // Unconditionally log net taps.
1555 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
1556 }
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001557 else if ((netdev_mc_count(dev) > pDevice->multicast_limit) ||
1558 (dev->flags & IFF_ALLMULTI)) {
Forest Bond92b96792009-06-13 07:38:31 -04001559 CONTROLnsRequestOut(pDevice,
1560 MESSAGE_TYPE_WRITE,
1561 MAC_REG_MAR0,
1562 MESSAGE_REQUEST_MACREG,
1563 8,
1564 pbyData
1565 );
1566 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1567 }
1568 else {
1569 memset(mc_filter, 0, sizeof(mc_filter));
Jiri Pirko22bedad32010-04-01 21:22:57 +00001570 netdev_for_each_mc_addr(ha, dev) {
1571 int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
Forest Bond92b96792009-06-13 07:38:31 -04001572 mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
1573 }
1574 for (ii = 0; ii < 4; ii++) {
1575 MACvWriteMultiAddr(pDevice, ii, *((PBYTE)&mc_filter[0] + ii));
1576 MACvWriteMultiAddr(pDevice, ii+ 4, *((PBYTE)&mc_filter[1] + ii));
1577 }
1578 pDevice->byRxMode &= ~(RCR_UNICAST);
1579 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1580 }
1581
1582 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
1583 // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac.
1584 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1585 pDevice->byRxMode &= ~(RCR_UNICAST);
1586 }
1587 ControlvWriteByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_RCR, pDevice->byRxMode);
1588 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode out= %x\n", pDevice->byRxMode);
1589 spin_unlock_irq(&pDevice->lock);
1590
1591}
1592
1593
1594static struct net_device_stats *device_get_stats(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001595 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001596
1597 return &pDevice->stats;
1598}
1599
1600
1601static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001602 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001603 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1604 PSCmdRequest pReq;
1605 //BOOL bCommit = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001606 struct iwreq *wrq = (struct iwreq *) rq;
1607 int rc =0;
Forest Bond92b96792009-06-13 07:38:31 -04001608
1609 if (pMgmt == NULL) {
1610 rc = -EFAULT;
1611 return rc;
1612 }
1613
1614 switch(cmd) {
1615
Forest Bond92b96792009-06-13 07:38:31 -04001616 case SIOCGIWNAME:
1617 rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL);
1618 break;
1619
1620 case SIOCSIWNWID:
1621 rc = -EOPNOTSUPP;
1622 break;
1623
1624 case SIOCGIWNWID: //0x8b03 support
1625 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1626 rc = iwctl_giwnwid(dev, NULL, &(wrq->u.nwid), NULL);
1627 #else
1628 rc = -EOPNOTSUPP;
1629 #endif
1630 break;
1631
1632 // Set frequency/channel
1633 case SIOCSIWFREQ:
1634 rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL);
1635 break;
1636
1637 // Get frequency/channel
1638 case SIOCGIWFREQ:
1639 rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL);
1640 break;
1641
1642 // Set desired network name (ESSID)
1643 case SIOCSIWESSID:
1644
1645 {
1646 char essid[IW_ESSID_MAX_SIZE+1];
1647 if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
1648 rc = -E2BIG;
1649 break;
1650 }
1651 if (copy_from_user(essid, wrq->u.essid.pointer,
1652 wrq->u.essid.length)) {
1653 rc = -EFAULT;
1654 break;
1655 }
1656 rc = iwctl_siwessid(dev, NULL,
1657 &(wrq->u.essid), essid);
1658 }
1659 break;
1660
1661
1662 // Get current network name (ESSID)
1663 case SIOCGIWESSID:
1664
1665 {
1666 char essid[IW_ESSID_MAX_SIZE+1];
Vasiliy Kulikoveacd1212010-10-29 00:02:11 +04001667 if (wrq->u.essid.pointer) {
Forest Bond92b96792009-06-13 07:38:31 -04001668 rc = iwctl_giwessid(dev, NULL,
1669 &(wrq->u.essid), essid);
1670 if (copy_to_user(wrq->u.essid.pointer,
1671 essid,
1672 wrq->u.essid.length) )
1673 rc = -EFAULT;
Vasiliy Kulikoveacd1212010-10-29 00:02:11 +04001674 }
Forest Bond92b96792009-06-13 07:38:31 -04001675 }
1676 break;
1677
1678 case SIOCSIWAP:
1679
1680 rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL);
1681 break;
1682
1683
1684 // Get current Access Point (BSSID)
1685 case SIOCGIWAP:
1686 rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL);
1687 break;
1688
1689
1690 // Set desired station name
1691 case SIOCSIWNICKN:
1692 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n");
1693 rc = -EOPNOTSUPP;
1694 break;
1695
1696 // Get current station name
1697 case SIOCGIWNICKN:
1698 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n");
1699 rc = -EOPNOTSUPP;
1700 break;
1701
1702 // Set the desired bit-rate
1703 case SIOCSIWRATE:
1704 rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL);
1705 break;
1706
1707 // Get the current bit-rate
1708 case SIOCGIWRATE:
1709
1710 rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
1711 break;
1712
1713 // Set the desired RTS threshold
1714 case SIOCSIWRTS:
1715
1716 rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL);
1717 break;
1718
1719 // Get the current RTS threshold
1720 case SIOCGIWRTS:
1721
1722 rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL);
1723 break;
1724
1725 // Set the desired fragmentation threshold
1726 case SIOCSIWFRAG:
1727
1728 rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL);
1729 break;
1730
1731 // Get the current fragmentation threshold
1732 case SIOCGIWFRAG:
1733
1734 rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL);
1735 break;
1736
1737 // Set mode of operation
1738 case SIOCSIWMODE:
1739 rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL);
1740 break;
1741
1742 // Get mode of operation
1743 case SIOCGIWMODE:
1744 rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
1745 break;
1746
1747 // Set WEP keys and mode
1748 case SIOCSIWENCODE:
1749 {
1750 char abyKey[WLAN_WEP232_KEYLEN];
1751
1752 if (wrq->u.encoding.pointer) {
1753
1754
1755 if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) {
1756 rc = -E2BIG;
1757 break;
1758 }
1759 memset(abyKey, 0, WLAN_WEP232_KEYLEN);
1760 if (copy_from_user(abyKey,
1761 wrq->u.encoding.pointer,
1762 wrq->u.encoding.length)) {
1763 rc = -EFAULT;
1764 break;
1765 }
1766 } else if (wrq->u.encoding.length != 0) {
1767 rc = -EINVAL;
1768 break;
1769 }
1770 rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey);
1771 }
1772 break;
1773
1774 // Get the WEP keys and mode
1775 case SIOCGIWENCODE:
1776
1777 if (!capable(CAP_NET_ADMIN)) {
1778 rc = -EPERM;
1779 break;
1780 }
1781 {
1782 char abyKey[WLAN_WEP232_KEYLEN];
1783
1784 rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey);
1785 if (rc != 0) break;
1786 if (wrq->u.encoding.pointer) {
1787 if (copy_to_user(wrq->u.encoding.pointer,
1788 abyKey,
1789 wrq->u.encoding.length))
1790 rc = -EFAULT;
1791 }
1792 }
1793 break;
1794
Forest Bond92b96792009-06-13 07:38:31 -04001795 // Get the current Tx-Power
1796 case SIOCGIWTXPOW:
1797 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
1798 rc = -EOPNOTSUPP;
1799 break;
1800
1801 case SIOCSIWTXPOW:
1802 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
1803 rc = -EOPNOTSUPP;
1804 break;
1805
Forest Bond92b96792009-06-13 07:38:31 -04001806 case SIOCSIWRETRY:
1807
1808 rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL);
1809 break;
1810
1811 case SIOCGIWRETRY:
1812
1813 rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL);
1814 break;
1815
Forest Bond92b96792009-06-13 07:38:31 -04001816 // Get range of parameters
1817 case SIOCGIWRANGE:
1818
1819 {
1820 struct iw_range range;
1821
1822 rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *) &range);
1823 if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
1824 rc = -EFAULT;
1825 }
1826
1827 break;
1828
1829 case SIOCGIWPOWER:
1830
1831 rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL);
1832 break;
1833
1834
1835 case SIOCSIWPOWER:
1836
1837 rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL);
1838 break;
1839
1840
1841 case SIOCGIWSENS:
1842
1843 rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL);
1844 break;
1845
1846 case SIOCSIWSENS:
1847 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n");
1848 rc = -EOPNOTSUPP;
1849 break;
1850
1851 case SIOCGIWAPLIST:
1852 {
1853 char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
1854
1855 if (wrq->u.data.pointer) {
1856 rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
1857 if (rc == 0) {
1858 if (copy_to_user(wrq->u.data.pointer,
1859 buffer,
1860 (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality)))
1861 ))
1862 rc = -EFAULT;
1863 }
1864 }
1865 }
1866 break;
1867
1868
1869#ifdef WIRELESS_SPY
1870 // Set the spy list
1871 case SIOCSIWSPY:
1872
1873 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
1874 rc = -EOPNOTSUPP;
1875 break;
1876
1877 // Get the spy list
1878 case SIOCGIWSPY:
1879
1880 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
1881 rc = -EOPNOTSUPP;
1882 break;
1883
1884#endif // WIRELESS_SPY
1885
1886 case SIOCGIWPRIV:
1887 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n");
1888 rc = -EOPNOTSUPP;
1889/*
1890 if(wrq->u.data.pointer) {
1891 wrq->u.data.length = sizeof(iwctl_private_args) / sizeof( iwctl_private_args[0]);
1892
1893 if(copy_to_user(wrq->u.data.pointer,
1894 (u_char *) iwctl_private_args,
1895 sizeof(iwctl_private_args)))
1896 rc = -EFAULT;
1897 }
1898*/
1899 break;
1900
Forest Bond92b96792009-06-13 07:38:31 -04001901#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1902 case SIOCSIWAUTH:
Andres More465711b2010-08-03 20:25:50 -03001903 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
Forest Bond92b96792009-06-13 07:38:31 -04001904 rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
1905 break;
1906
1907 case SIOCGIWAUTH:
1908 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH \n");
1909 rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
1910 break;
1911
1912 case SIOCSIWGENIE:
1913 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE \n");
1914 rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1915 break;
1916
1917 case SIOCGIWGENIE:
1918 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE \n");
1919 rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1920 break;
1921
1922 case SIOCSIWENCODEEXT:
1923 {
1924 char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
1925 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n");
1926 if(wrq->u.encoding.pointer){
1927 memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1);
1928 if(wrq->u.encoding.length > (sizeof(struct iw_encode_ext)+ MAX_KEY_LEN)){
1929 rc = -E2BIG;
1930 break;
1931 }
1932 if(copy_from_user(extra, wrq->u.encoding.pointer,wrq->u.encoding.length)){
1933 rc = -EFAULT;
1934 break;
1935 }
1936 }else if(wrq->u.encoding.length != 0){
1937 rc = -EINVAL;
1938 break;
1939 }
1940 rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra);
1941 }
1942 break;
1943
1944 case SIOCGIWENCODEEXT:
1945 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n");
1946 rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
1947 break;
1948
1949 case SIOCSIWMLME:
1950 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME \n");
1951 rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1952 break;
1953
1954#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
Forest Bond92b96792009-06-13 07:38:31 -04001955
Forest Bond92b96792009-06-13 07:38:31 -04001956 case IOCTL_CMD_TEST:
1957
1958 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1959 rc = -EFAULT;
1960 break;
1961 } else {
1962 rc = 0;
1963 }
1964 pReq = (PSCmdRequest)rq;
1965
1966 //20080130-01,<Remark> by Mike Liu
1967 // if(pDevice->bLinkPass==TRUE)
1968 pReq->wResult = MAGIC_CODE; //Linking status:0x3142
1969 //20080130-02,<Remark> by Mike Liu
1970 // else
1971 // pReq->wResult = MAGIC_CODE+1; //disconnect status:0x3143
1972 break;
1973
1974 case IOCTL_CMD_SET:
1975 if (!(pDevice->flags & DEVICE_FLAGS_OPENED) &&
1976 (((PSCmdRequest)rq)->wCmdCode !=WLAN_CMD_SET_WPA))
1977 {
1978 rc = -EFAULT;
1979 break;
1980 } else {
1981 rc = 0;
1982 }
1983
1984 if (test_and_set_bit( 0, (void*)&(pMgmt->uCmdBusy))) {
1985 return -EBUSY;
1986 }
1987 rc = private_ioctl(pDevice, rq);
1988 clear_bit( 0, (void*)&(pMgmt->uCmdBusy));
1989 break;
1990
1991 case IOCTL_CMD_HOSTAPD:
1992
1993 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1994 rc = -EFAULT;
1995 break;
1996 } else {
1997 rc = 0;
1998 }
1999
Forest Bondc30d7972010-04-17 11:03:38 -04002000 rc = vt6656_hostap_ioctl(pDevice, &wrq->u.data);
Forest Bond92b96792009-06-13 07:38:31 -04002001 break;
2002
2003 case IOCTL_CMD_WPA:
2004
2005 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
2006 rc = -EFAULT;
2007 break;
2008 } else {
2009 rc = 0;
2010 }
2011
Forest Bond92b96792009-06-13 07:38:31 -04002012 rc = wpa_ioctl(pDevice, &wrq->u.data);
Forest Bond92b96792009-06-13 07:38:31 -04002013 break;
2014
2015 case SIOCETHTOOL:
2016 return ethtool_ioctl(dev, (void *) rq->ifr_data);
2017 // All other calls are currently unsupported
2018
2019 default:
2020 rc = -EOPNOTSUPP;
2021 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd);
2022
2023
2024 }
2025
2026 if (pDevice->bCommit) {
2027 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2028 netif_stop_queue(pDevice->dev);
2029 spin_lock_irq(&pDevice->lock);
Andres More0cbd8d92010-05-06 20:34:29 -03002030 bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002031 spin_unlock_irq(&pDevice->lock);
2032 }
2033 else {
2034 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
2035 spin_lock_irq(&pDevice->lock);
2036//2007-1121-01<Modify>by EinsnLiu
Andres More0cbd8d92010-05-06 20:34:29 -03002037 if (pDevice->bLinkPass &&
Forest Bond92b96792009-06-13 07:38:31 -04002038 memcmp(pMgmt->abyCurrSSID,pMgmt->abyDesireSSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN)) {
Andres More0cbd8d92010-05-06 20:34:29 -03002039 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002040 } else {
2041 pDevice->bLinkPass = FALSE;
2042 pMgmt->eCurrState = WMAC_STATE_IDLE;
2043 memset(pMgmt->abyCurrBSSID, 0, 6);
2044 }
2045 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
2046//End Modify
2047 netif_stop_queue(pDevice->dev);
2048#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
2049 pMgmt->eScanType = WMAC_SCAN_ACTIVE;
Andres More0cbd8d92010-05-06 20:34:29 -03002050 if (!pDevice->bWPASuppWextEnabled)
Forest Bond92b96792009-06-13 07:38:31 -04002051#endif
Andres More0cbd8d92010-05-06 20:34:29 -03002052 bScheduleCommand((void *) pDevice,
2053 WLAN_CMD_BSSID_SCAN,
2054 pMgmt->abyDesireSSID);
2055 bScheduleCommand((void *) pDevice,
2056 WLAN_CMD_SSID,
2057 NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002058 spin_unlock_irq(&pDevice->lock);
2059 }
2060 pDevice->bCommit = FALSE;
2061 }
2062
2063
2064 return rc;
2065}
2066
2067
2068static int ethtool_ioctl(struct net_device *dev, void *useraddr)
2069{
2070 u32 ethcmd;
2071
2072 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
2073 return -EFAULT;
2074
2075 switch (ethcmd) {
2076 case ETHTOOL_GDRVINFO: {
2077 struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
2078 strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
2079 strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
2080 if (copy_to_user(useraddr, &info, sizeof(info)))
2081 return -EFAULT;
2082 return 0;
2083 }
2084
2085 }
2086
2087 return -EOPNOTSUPP;
2088}
2089
2090
2091/*------------------------------------------------------------------*/
2092
Andres More26e5b652010-04-13 19:43:07 -03002093MODULE_DEVICE_TABLE(usb, vt6656_table);
Forest Bond92b96792009-06-13 07:38:31 -04002094
Andres More26e5b652010-04-13 19:43:07 -03002095static struct usb_driver vt6656_driver = {
2096 .name = DEVICE_NAME,
2097 .probe = vt6656_probe,
2098 .disconnect = vt6656_disconnect,
2099 .id_table = vt6656_table,
Forest Bond92b96792009-06-13 07:38:31 -04002100#ifdef CONFIG_PM
Andres More26e5b652010-04-13 19:43:07 -03002101 .suspend = vt6656_suspend,
2102 .resume = vt6656_resume,
2103#endif /* CONFIG_PM */
Forest Bond92b96792009-06-13 07:38:31 -04002104};
2105
Andres More26e5b652010-04-13 19:43:07 -03002106static int __init vt6656_init_module(void)
Forest Bond92b96792009-06-13 07:38:31 -04002107{
Forest Bondf4a8df92009-06-13 07:38:56 -04002108 printk(KERN_NOTICE DEVICE_FULL_DRV_NAM " " DEVICE_VERSION);
Andres More26e5b652010-04-13 19:43:07 -03002109 return usb_register(&vt6656_driver);
Forest Bond92b96792009-06-13 07:38:31 -04002110}
2111
Andres More26e5b652010-04-13 19:43:07 -03002112static void __exit vt6656_cleanup_module(void)
Forest Bond92b96792009-06-13 07:38:31 -04002113{
Andres More26e5b652010-04-13 19:43:07 -03002114 usb_deregister(&vt6656_driver);
Forest Bond92b96792009-06-13 07:38:31 -04002115}
2116
Andres More26e5b652010-04-13 19:43:07 -03002117module_init(vt6656_init_module);
2118module_exit(vt6656_cleanup_module);