blob: 1ff394074cba398ba39e8b370c2a923f0d540b83 [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 }
Joe Perches9fc86022011-04-10 14:31:32 -0700712 }
Forest Bond92b96792009-06-13 07:38:31 -0400713 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,
Jiri Pirkoafc4b132011-08-16 06:29:01 +0000756 .ndo_set_rx_mode = device_set_multi,
Forest Bonddd8db702009-06-13 07:38:54 -0400757};
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 }
Ilia Mirkin1d5c5362011-03-13 00:29:15 -0500840 kfree(pTxContext);
Forest Bond92b96792009-06-13 07:38:31 -0400841 }
842 return;
843}
844
845
Andres More8611a292010-05-01 14:25:00 -0300846static void device_free_rx_bufs(PSDevice pDevice)
847{
Forest Bond92b96792009-06-13 07:38:31 -0400848 PRCB pRCB;
849 int ii;
850
851 for (ii = 0; ii < pDevice->cbRD; ii++) {
852
853 pRCB = pDevice->apRCB[ii];
854 //de-allocate URBs
855 if (pRCB->pUrb) {
Jim Liebdad72fe2009-08-12 14:54:14 -0700856 usb_kill_urb(pRCB->pUrb);
Forest Bond92b96792009-06-13 07:38:31 -0400857 usb_free_urb(pRCB->pUrb);
858 }
859 //de-allocate skb
860 if (pRCB->skb)
861 dev_kfree_skb(pRCB->skb);
862 }
Ilia Mirkin1d5c5362011-03-13 00:29:15 -0500863 kfree(pDevice->pRCBMem);
Forest Bond92b96792009-06-13 07:38:31 -0400864
865 return;
866}
867
Forest Bond92b96792009-06-13 07:38:31 -0400868static void usb_device_reset(PSDevice pDevice)
869{
870 int status;
871 status = usb_reset_device(pDevice->usb);
872 if (status)
873 printk("usb_device_reset fail status=%d\n",status);
874 return ;
875}
Forest Bond92b96792009-06-13 07:38:31 -0400876
Andres More8611a292010-05-01 14:25:00 -0300877static void device_free_int_bufs(PSDevice pDevice)
878{
Ilia Mirkin1d5c5362011-03-13 00:29:15 -0500879 kfree(pDevice->intBuf.pDataBuf);
Forest Bond92b96792009-06-13 07:38:31 -0400880 return;
881}
882
883
884static BOOL device_alloc_bufs(PSDevice pDevice) {
885
886 PUSB_SEND_CONTEXT pTxContext;
887 PRCB pRCB;
888 int ii;
889
890
891 for (ii = 0; ii < pDevice->cbTD; ii++) {
892
893 pTxContext = kmalloc(sizeof(USB_SEND_CONTEXT), GFP_KERNEL);
894 if (pTxContext == NULL) {
895 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : allocate tx usb context failed\n", pDevice->dev->name);
896 goto free_tx;
897 }
898 pDevice->apTD[ii] = pTxContext;
Andres More8611a292010-05-01 14:25:00 -0300899 pTxContext->pDevice = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400900 //allocate URBs
Jim Liebdad72fe2009-08-12 14:54:14 -0700901 pTxContext->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400902 if (pTxContext->pUrb == NULL) {
903 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "alloc tx urb failed\n");
904 goto free_tx;
905 }
906 pTxContext->bBoolInUse = FALSE;
907 }
908
909 // allocate rcb mem
910 pDevice->pRCBMem = kmalloc((sizeof(RCB) * pDevice->cbRD), GFP_KERNEL);
911 if (pDevice->pRCBMem == NULL) {
912 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : alloc rx usb context failed\n", pDevice->dev->name);
913 goto free_tx;
914 }
915
916
917 pDevice->FirstRecvFreeList = NULL;
918 pDevice->LastRecvFreeList = NULL;
919 pDevice->FirstRecvMngList = NULL;
920 pDevice->LastRecvMngList = NULL;
921 pDevice->NumRecvFreeList = 0;
922 memset(pDevice->pRCBMem, 0, (sizeof(RCB) * pDevice->cbRD));
923 pRCB = (PRCB) pDevice->pRCBMem;
924
925 for (ii = 0; ii < pDevice->cbRD; ii++) {
926
927 pDevice->apRCB[ii] = pRCB;
Andres More8611a292010-05-01 14:25:00 -0300928 pRCB->pDevice = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400929 //allocate URBs
Jim Liebdad72fe2009-08-12 14:54:14 -0700930 pRCB->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400931
932 if (pRCB->pUrb == NULL) {
933 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx urb\n");
934 goto free_rx_tx;
935 }
936 pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
937 if (pRCB->skb == NULL) {
938 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx skb\n");
939 goto free_rx_tx;
940 }
941 pRCB->skb->dev = pDevice->dev;
942 pRCB->bBoolInUse = FALSE;
943 EnqueueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList, pRCB);
944 pDevice->NumRecvFreeList++;
945 pRCB++;
946 }
947
948
Jim Liebdad72fe2009-08-12 14:54:14 -0700949 pDevice->pControlURB = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400950 if (pDevice->pControlURB == NULL) {
951 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc control urb\n");
952 goto free_rx_tx;
953 }
954
Jim Liebdad72fe2009-08-12 14:54:14 -0700955 pDevice->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400956 if (pDevice->pInterruptURB == NULL) {
957 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int urb\n");
Forest Bond92b96792009-06-13 07:38:31 -0400958 usb_free_urb(pDevice->pControlURB);
959 goto free_rx_tx;
960 }
961
962 pDevice->intBuf.pDataBuf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
963 if (pDevice->intBuf.pDataBuf == NULL) {
964 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int buf\n");
Forest Bond92b96792009-06-13 07:38:31 -0400965 usb_free_urb(pDevice->pControlURB);
966 usb_free_urb(pDevice->pInterruptURB);
967 goto free_rx_tx;
968 }
969
970 return TRUE;
971
972free_rx_tx:
973 device_free_rx_bufs(pDevice);
974
975free_tx:
976 device_free_tx_bufs(pDevice);
977
978 return FALSE;
979}
980
981
982
983
984static BOOL device_init_defrag_cb(PSDevice pDevice) {
985 int i;
986 PSDeFragControlBlock pDeF;
987
988 /* Init the fragment ctl entries */
989 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
990 pDeF = &(pDevice->sRxDFCB[i]);
991 if (!device_alloc_frag_buf(pDevice, pDeF)) {
992 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
993 pDevice->dev->name);
994 goto free_frag;
Joe Perches9fc86022011-04-10 14:31:32 -0700995 }
Forest Bond92b96792009-06-13 07:38:31 -0400996 }
997 pDevice->cbDFCB = CB_MAX_RX_FRAG;
998 pDevice->cbFreeDFCB = pDevice->cbDFCB;
999 return TRUE;
1000
1001free_frag:
1002 device_free_frag_bufs(pDevice);
1003 return FALSE;
1004}
1005
1006
1007
1008static void device_free_frag_bufs(PSDevice pDevice) {
1009 PSDeFragControlBlock pDeF;
1010 int i;
1011
1012 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
1013
1014 pDeF = &(pDevice->sRxDFCB[i]);
1015
1016 if (pDeF->skb)
1017 dev_kfree_skb(pDeF->skb);
1018 }
1019}
1020
1021
1022
1023BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
1024
1025 pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1026 if (pDeF->skb == NULL)
1027 return FALSE;
1028 ASSERT(pDeF->skb);
1029 pDeF->skb->dev = pDevice->dev;
1030
1031 return TRUE;
1032}
1033
1034
1035/*-----------------------------------------------------------------*/
1036
1037static int device_open(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001038 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001039
Forest Bond92b96792009-06-13 07:38:31 -04001040 extern SWPAResult wpa_Result;
1041 memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname));
1042 wpa_Result.proto = 0;
1043 wpa_Result.key_mgmt = 0;
1044 wpa_Result.eap_type = 0;
1045 wpa_Result.authenticated = FALSE;
1046 pDevice->fWPA_Authened = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001047
1048 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_open...\n");
1049
1050
1051 pDevice->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
1052
1053 if (device_alloc_bufs(pDevice) == FALSE) {
1054 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_alloc_bufs fail... \n");
1055 return -ENOMEM;
1056 }
1057
1058 if (device_init_defrag_cb(pDevice)== FALSE) {
1059 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Initial defragement cb fail \n");
1060 goto free_rx_tx;
1061 }
1062
1063 MP_CLEAR_FLAG(pDevice, fMP_DISCONNECTED);
1064 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
1065 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
1066 MP_SET_FLAG(pDevice, fMP_POST_READS);
1067 MP_SET_FLAG(pDevice, fMP_POST_WRITES);
1068
1069 //read config file
1070 Read_config_file(pDevice);
1071
1072 if (device_init_registers(pDevice, DEVICE_INIT_COLD) == FALSE) {
1073 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " init register fail\n");
1074 goto free_all;
1075 }
1076
1077 device_set_multi(pDevice->dev);
1078 // Init for Key Management
1079
1080 KeyvInitTable(pDevice,&pDevice->sKey);
Andres More9a0e7562010-04-13 21:54:48 -03001081 memcpy(pDevice->sMgmtObj.abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN);
1082 memcpy(pDevice->dev->dev_addr, pDevice->abyCurrentNetAddr, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001083 pDevice->bStopTx0Pkt = FALSE;
1084 pDevice->bStopDataPkt = FALSE;
Andres More465711b2010-08-03 20:25:50 -03001085 pDevice->bRoaming = FALSE;
1086 pDevice->bIsRoaming = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001087 pDevice->bEnableRoaming = FALSE;
1088 if (pDevice->bDiversityRegCtlON) {
1089 device_init_diversity_timer(pDevice);
1090 }
1091
1092 vMgrObjectInit(pDevice);
1093 tasklet_init(&pDevice->RxMngWorkItem, (void *)RXvMngWorkItem, (unsigned long)pDevice);
1094 tasklet_init(&pDevice->ReadWorkItem, (void *)RXvWorkItem, (unsigned long)pDevice);
1095 tasklet_init(&pDevice->EventWorkItem, (void *)INTvWorkItem, (unsigned long)pDevice);
1096 add_timer(&(pDevice->sMgmtObj.sTimerSecondCallback));
Forest Bond92b96792009-06-13 07:38:31 -04001097 pDevice->int_interval = 100; //Max 100 microframes.
Forest Bond92b96792009-06-13 07:38:31 -04001098 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1099
1100 pDevice->bIsRxWorkItemQueued = TRUE;
1101 pDevice->fKillEventPollingThread = FALSE;
1102 pDevice->bEventAvailable = FALSE;
1103
1104 pDevice->bWPADEVUp = FALSE;
1105#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1106 pDevice->bwextstep0 = FALSE;
1107 pDevice->bwextstep1 = FALSE;
1108 pDevice->bwextstep2 = FALSE;
1109 pDevice->bwextstep3 = FALSE;
1110 pDevice->bWPASuppWextEnabled = FALSE;
1111#endif
1112 pDevice->byReAssocCount = 0;
1113
1114 RXvWorkItem(pDevice);
1115 INTvWorkItem(pDevice);
1116
1117 // Patch: if WEP key already set by iwconfig but device not yet open
1118 if ((pDevice->bEncryptionEnable == TRUE) && (pDevice->bTransmitKey == TRUE)) {
1119 spin_lock_irq(&pDevice->lock);
1120 KeybSetDefaultKey( pDevice,
1121 &(pDevice->sKey),
1122 pDevice->byKeyIndex | (1 << 31),
1123 pDevice->uKeyLength,
1124 NULL,
1125 pDevice->abyKey,
1126 KEY_CTL_WEP
1127 );
1128 spin_unlock_irq(&pDevice->lock);
1129 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1130 }
1131
1132 if (pDevice->sMgmtObj.eConfigMode == WMAC_CONFIG_AP) {
Andres More0cbd8d92010-05-06 20:34:29 -03001133 bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001134 }
1135 else {
1136 //mike:mark@2008-11-10
Andres More0cbd8d92010-05-06 20:34:29 -03001137 bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
1138 /* bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); */
Forest Bond92b96792009-06-13 07:38:31 -04001139 }
1140
1141
1142 netif_stop_queue(pDevice->dev);
1143 pDevice->flags |= DEVICE_FLAGS_OPENED;
1144
Forest Bond92b96792009-06-13 07:38:31 -04001145{
1146 union iwreq_data wrqu;
1147 memset(&wrqu, 0, sizeof(wrqu));
1148 wrqu.data.flags = RT_UPDEV_EVENT_FLAG;
1149 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1150}
Forest Bond92b96792009-06-13 07:38:31 -04001151
1152 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
1153 return 0;
1154
1155free_all:
1156 device_free_frag_bufs(pDevice);
1157free_rx_tx:
1158 device_free_rx_bufs(pDevice);
1159 device_free_tx_bufs(pDevice);
1160 device_free_int_bufs(pDevice);
Jim Liebdad72fe2009-08-12 14:54:14 -07001161 usb_kill_urb(pDevice->pControlURB);
1162 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -04001163 usb_free_urb(pDevice->pControlURB);
1164 usb_free_urb(pDevice->pInterruptURB);
1165
1166 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open fail.. \n");
1167 return -ENOMEM;
1168}
1169
1170
1171
1172static int device_close(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001173 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001174 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1175
Forest Bond92b96792009-06-13 07:38:31 -04001176 int uu;
Forest Bond92b96792009-06-13 07:38:31 -04001177
1178 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close1 \n");
1179 if (pDevice == NULL)
1180 return -ENODEV;
1181
Forest Bond92b96792009-06-13 07:38:31 -04001182{
1183 union iwreq_data wrqu;
1184 memset(&wrqu, 0, sizeof(wrqu));
1185 wrqu.data.flags = RT_DOWNDEV_EVENT_FLAG;
1186 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1187}
Forest Bond92b96792009-06-13 07:38:31 -04001188
Forest Bond92b96792009-06-13 07:38:31 -04001189 if (pDevice->bLinkPass) {
Andres More0cbd8d92010-05-06 20:34:29 -03001190 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001191 mdelay(30);
1192 }
Forest Bond92b96792009-06-13 07:38:31 -04001193
Forest Bond92b96792009-06-13 07:38:31 -04001194device_release_WPADEV(pDevice);
1195
Forest Bond92b96792009-06-13 07:38:31 -04001196 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
1197 pMgmt->bShareKeyAlgorithm = FALSE;
1198 pDevice->bEncryptionEnable = FALSE;
1199 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
Andres More33d33e422010-05-19 23:50:00 -03001200 spin_lock_irq(&pDevice->lock);
1201 for (uu = 0; uu < MAX_KEY_TABLE; uu++)
Forest Bond92b96792009-06-13 07:38:31 -04001202 MACvDisableKeyEntry(pDevice,uu);
Andres More33d33e422010-05-19 23:50:00 -03001203 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001204
1205 if ((pDevice->flags & DEVICE_FLAGS_UNPLUG) == FALSE) {
1206 MACbShutdown(pDevice);
1207 }
1208 netif_stop_queue(pDevice->dev);
1209 MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
1210 MP_CLEAR_FLAG(pDevice, fMP_POST_WRITES);
1211 MP_CLEAR_FLAG(pDevice, fMP_POST_READS);
1212 pDevice->fKillEventPollingThread = TRUE;
1213 del_timer(&pDevice->sTimerCommand);
1214 del_timer(&pMgmt->sTimerSecondCallback);
1215
Forest Bond92b96792009-06-13 07:38:31 -04001216 del_timer(&pDevice->sTimerTxData);
Forest Bond92b96792009-06-13 07:38:31 -04001217
1218 if (pDevice->bDiversityRegCtlON) {
1219 del_timer(&pDevice->TimerSQ3Tmax1);
1220 del_timer(&pDevice->TimerSQ3Tmax2);
1221 del_timer(&pDevice->TimerSQ3Tmax3);
1222 }
1223 tasklet_kill(&pDevice->RxMngWorkItem);
1224 tasklet_kill(&pDevice->ReadWorkItem);
1225 tasklet_kill(&pDevice->EventWorkItem);
1226
Andres More465711b2010-08-03 20:25:50 -03001227 pDevice->bRoaming = FALSE;
1228 pDevice->bIsRoaming = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001229 pDevice->bEnableRoaming = FALSE;
1230 pDevice->bCmdRunning = FALSE;
1231 pDevice->bLinkPass = FALSE;
1232 memset(pMgmt->abyCurrBSSID, 0, 6);
1233 pMgmt->eCurrState = WMAC_STATE_IDLE;
1234
1235 device_free_tx_bufs(pDevice);
1236 device_free_rx_bufs(pDevice);
1237 device_free_int_bufs(pDevice);
1238 device_free_frag_bufs(pDevice);
1239
Jim Liebdad72fe2009-08-12 14:54:14 -07001240 usb_kill_urb(pDevice->pControlURB);
1241 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -04001242 usb_free_urb(pDevice->pControlURB);
1243 usb_free_urb(pDevice->pInterruptURB);
1244
1245 BSSvClearNodeDBTable(pDevice, 0);
1246 pDevice->flags &=(~DEVICE_FLAGS_OPENED);
1247
1248 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n");
1249
1250 return 0;
1251}
1252
Andres More26e5b652010-04-13 19:43:07 -03001253static void __devexit vt6656_disconnect(struct usb_interface *intf)
Forest Bond92b96792009-06-13 07:38:31 -04001254{
Andres More6cda24f2010-06-22 20:43:39 -03001255 PSDevice device = usb_get_intfdata(intf);
Forest Bond92b96792009-06-13 07:38:31 -04001256
Andres More6cda24f2010-06-22 20:43:39 -03001257 if (!device)
1258 return;
Forest Bond92b96792009-06-13 07:38:31 -04001259
Andres More6cda24f2010-06-22 20:43:39 -03001260 {
1261 union iwreq_data req;
1262 memset(&req, 0, sizeof(req));
1263 req.data.flags = RT_RMMOD_EVENT_FLAG;
1264 wireless_send_event(device->dev, IWEVCUSTOM, &req, NULL);
1265 }
Forest Bond92b96792009-06-13 07:38:31 -04001266
Andres More6cda24f2010-06-22 20:43:39 -03001267 device_release_WPADEV(device);
Forest Bond92b96792009-06-13 07:38:31 -04001268
Ben Hutchings31d5bbf2011-01-09 04:16:48 +00001269 if (device->firmware)
1270 release_firmware(device->firmware);
1271
Forest Bond92b96792009-06-13 07:38:31 -04001272 usb_set_intfdata(intf, NULL);
Andres More6cda24f2010-06-22 20:43:39 -03001273 usb_put_dev(interface_to_usbdev(intf));
Forest Bond92b96792009-06-13 07:38:31 -04001274
Andres More6cda24f2010-06-22 20:43:39 -03001275 device->flags |= DEVICE_FLAGS_UNPLUG;
Forest Bond92b96792009-06-13 07:38:31 -04001276
Andres More6cda24f2010-06-22 20:43:39 -03001277 if (device->dev) {
1278 unregister_netdev(device->dev);
1279 wpa_set_wpadev(device, 0);
1280 free_netdev(device->dev);
1281 }
Forest Bond92b96792009-06-13 07:38:31 -04001282}
1283
Andres Moree1669ed2010-07-12 13:10:27 -03001284static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev)
1285{
1286 PSDevice pDevice = netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001287
Andres Moree1669ed2010-07-12 13:10:27 -03001288 spin_lock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001289
Andres Moree1669ed2010-07-12 13:10:27 -03001290 if (unlikely(pDevice->bStopTx0Pkt))
1291 dev_kfree_skb_irq(skb);
1292 else
1293 vDMA0_tx_80211(pDevice, skb);
Forest Bond92b96792009-06-13 07:38:31 -04001294
Andres Moree1669ed2010-07-12 13:10:27 -03001295 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001296
Andres Moree1669ed2010-07-12 13:10:27 -03001297 return NETDEV_TX_OK;
Forest Bond92b96792009-06-13 07:38:31 -04001298}
1299
Andres More529e5b32010-07-12 19:28:25 -03001300static int device_xmit(struct sk_buff *skb, struct net_device *dev)
1301{
1302 PSDevice pDevice = netdev_priv(dev);
1303 struct net_device_stats *stats = &pDevice->stats;
Forest Bond92b96792009-06-13 07:38:31 -04001304
Andres More529e5b32010-07-12 19:28:25 -03001305 spin_lock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001306
Andres More529e5b32010-07-12 19:28:25 -03001307 netif_stop_queue(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001308
Andres More529e5b32010-07-12 19:28:25 -03001309 if (!pDevice->bLinkPass) {
1310 dev_kfree_skb_irq(skb);
1311 goto out;
1312 }
Forest Bond92b96792009-06-13 07:38:31 -04001313
Andres More529e5b32010-07-12 19:28:25 -03001314 if (pDevice->bStopDataPkt) {
1315 dev_kfree_skb_irq(skb);
1316 stats->tx_dropped++;
1317 goto out;
1318 }
Forest Bond92b96792009-06-13 07:38:31 -04001319
Andres More529e5b32010-07-12 19:28:25 -03001320 if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb)) {
1321 if (netif_queue_stopped(dev))
1322 netif_wake_queue(dev);
1323 }
Forest Bond92b96792009-06-13 07:38:31 -04001324
Andres More529e5b32010-07-12 19:28:25 -03001325out:
1326 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001327
Andres More529e5b32010-07-12 19:28:25 -03001328 return NETDEV_TX_OK;
Forest Bond92b96792009-06-13 07:38:31 -04001329}
1330
Forest Bond92b96792009-06-13 07:38:31 -04001331static unsigned const ethernet_polynomial = 0x04c11db7U;
1332static inline u32 ether_crc(int length, unsigned char *data)
1333{
1334 int crc = -1;
1335
1336 while(--length >= 0) {
1337 unsigned char current_octet = *data++;
1338 int bit;
1339 for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
1340 crc = (crc << 1) ^
1341 ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
1342 }
1343 }
1344 return crc;
1345}
1346
1347//find out the start position of str2 from str1
Andres Morecc856e62010-05-17 21:34:01 -03001348static unsigned char *kstrstr(const unsigned char *str1,
1349 const unsigned char *str2) {
1350 int str1_len = strlen(str1);
1351 int str2_len = strlen(str2);
Forest Bond92b96792009-06-13 07:38:31 -04001352
1353 while (str1_len >= str2_len) {
1354 str1_len--;
1355 if(memcmp(str1,str2,str2_len)==0)
Andres Morecc856e62010-05-17 21:34:01 -03001356 return (unsigned char *) str1;
Forest Bond92b96792009-06-13 07:38:31 -04001357 str1++;
1358 }
1359 return NULL;
1360}
1361
Andres Morecc856e62010-05-17 21:34:01 -03001362static int Config_FileGetParameter(unsigned char *string,
1363 unsigned char *dest,
1364 unsigned char *source)
Forest Bond92b96792009-06-13 07:38:31 -04001365{
Andres Morecc856e62010-05-17 21:34:01 -03001366 unsigned char buf1[100];
1367 unsigned char buf2[100];
1368 unsigned char *start_p = NULL, *end_p = NULL, *tmp_p = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001369 int ii;
1370
1371 memset(buf1,0,100);
1372 strcat(buf1, string);
1373 strcat(buf1, "=");
1374 source+=strlen(buf1);
1375
1376//find target string start point
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001377 start_p = kstrstr(source,buf1);
1378 if (start_p == NULL)
Forest Bond92b96792009-06-13 07:38:31 -04001379 return FALSE;
1380
1381//check if current config line is marked by "#" ??
Andres More33d33e422010-05-19 23:50:00 -03001382 for (ii = 1; ; ii++) {
1383 if (memcmp(start_p - ii, "\n", 1) == 0)
1384 break;
1385 if (memcmp(start_p - ii, "#", 1) == 0)
1386 return FALSE;
1387 }
Forest Bond92b96792009-06-13 07:38:31 -04001388
1389//find target string end point
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001390 end_p = kstrstr(start_p,"\n");
1391 if (end_p == NULL) { //can't find "\n",but don't care
Forest Bond92b96792009-06-13 07:38:31 -04001392 end_p=start_p+strlen(start_p); //no include "\n"
1393 }
1394
1395 memset(buf2,0,100);
1396 memcpy(buf2,start_p,end_p-start_p); //get the tartget line
1397 buf2[end_p-start_p]='\0';
1398
1399 //find value
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001400 start_p = kstrstr(buf2,"=");
1401 if (start_p == NULL)
Forest Bond92b96792009-06-13 07:38:31 -04001402 return FALSE;
1403 memset(buf1,0,100);
1404 strcpy(buf1,start_p+1);
1405
1406 //except space
1407 tmp_p = buf1;
1408 while(*tmp_p != 0x00) {
1409 if(*tmp_p==' ')
1410 tmp_p++;
1411 else
1412 break;
1413 }
1414
1415 memcpy(dest,tmp_p,strlen(tmp_p));
1416 return TRUE;
1417}
1418
1419//if read fail,return NULL,or return data pointer;
Andres Morecc856e62010-05-17 21:34:01 -03001420static unsigned char *Config_FileOperation(PSDevice pDevice)
1421{
1422 unsigned char *config_path = CONFIG_PATH;
1423 unsigned char *buffer = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001424 struct file *filp=NULL;
1425 mm_segment_t old_fs = get_fs();
Forest Bond8f9c4662009-06-13 07:38:47 -04001426 //int oldfsuid=0,oldfsgid=0;
Andres Morecc856e62010-05-17 21:34:01 -03001427 int result = 0;
Forest Bond92b96792009-06-13 07:38:31 -04001428
1429 set_fs (KERNEL_DS);
Forest Bond8f9c4662009-06-13 07:38:47 -04001430 /* Can't do this anymore, so we rely on correct filesystem permissions:
1431 //Make sure a caller can read or write power as root
1432 oldfsuid=current->fsuid;
1433 oldfsgid=current->fsgid;
Forest Bond92b96792009-06-13 07:38:31 -04001434 current->fsuid = 0;
1435 current->fsgid = 0;
Forest Bond8f9c4662009-06-13 07:38:47 -04001436 */
Forest Bond92b96792009-06-13 07:38:31 -04001437
1438 //open file
1439 filp = filp_open(config_path, O_RDWR, 0);
1440 if (IS_ERR(filp)) {
1441 printk("Config_FileOperation file Not exist\n");
1442 result=-1;
1443 goto error2;
1444 }
1445
1446 if(!(filp->f_op) || !(filp->f_op->read) ||!(filp->f_op->write)) {
1447 printk("file %s cann't readable or writable?\n",config_path);
1448 result = -1;
1449 goto error1;
1450 }
1451
Julia Lawall32414872010-05-11 20:26:57 +02001452 buffer = kmalloc(1024, GFP_KERNEL);
Forest Bond92b96792009-06-13 07:38:31 -04001453 if(buffer==NULL) {
Justin P. Mattock682a4532011-02-24 22:13:27 -08001454 printk("allocate mem for file fail?\n");
Forest Bond92b96792009-06-13 07:38:31 -04001455 result = -1;
1456 goto error1;
1457 }
1458
1459 if(filp->f_op->read(filp, buffer, 1024, &filp->f_pos)<0) {
1460 printk("read file error?\n");
1461 result = -1;
1462 }
1463
1464error1:
1465 if(filp_close(filp,NULL))
1466 printk("Config_FileOperation:close file fail\n");
1467
1468error2:
1469 set_fs (old_fs);
Forest Bond8f9c4662009-06-13 07:38:47 -04001470
1471 /*
Forest Bond92b96792009-06-13 07:38:31 -04001472 current->fsuid=oldfsuid;
1473 current->fsgid=oldfsgid;
Forest Bond8f9c4662009-06-13 07:38:47 -04001474 */
Forest Bond92b96792009-06-13 07:38:31 -04001475
1476if(result!=0) {
Ilia Mirkin1d5c5362011-03-13 00:29:15 -05001477 kfree(buffer);
Forest Bond92b96792009-06-13 07:38:31 -04001478 buffer=NULL;
1479}
1480 return buffer;
1481}
1482
André Goddard Rosabbc9a992009-11-14 13:09:06 -02001483//return --->-1:fail; >=0:successful
Forest Bond92b96792009-06-13 07:38:31 -04001484static int Read_config_file(PSDevice pDevice) {
Andres Morecc856e62010-05-17 21:34:01 -03001485 int result = 0;
1486 unsigned char tmpbuffer[100];
1487 unsigned char *buffer = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001488
1489 //init config setting
1490 pDevice->config_file.ZoneType = -1;
1491 pDevice->config_file.eAuthenMode = -1;
1492 pDevice->config_file.eEncryptionStatus = -1;
1493
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001494 buffer = Config_FileOperation(pDevice);
1495 if (buffer == NULL) {
Forest Bond92b96792009-06-13 07:38:31 -04001496 result =-1;
1497 return result;
1498 }
1499
1500//get zonetype
1501{
1502 memset(tmpbuffer,0,sizeof(tmpbuffer));
1503 if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer) ==TRUE) {
1504 if(memcmp(tmpbuffer,"USA",3)==0) {
1505 pDevice->config_file.ZoneType=ZoneType_USA;
1506 }
1507 else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
1508 pDevice->config_file.ZoneType=ZoneType_Japan;
1509 }
1510 else if(memcmp(tmpbuffer,"EUROPE",6)==0) {
1511 pDevice->config_file.ZoneType=ZoneType_Europe;
1512 }
1513 else {
1514 printk("Unknown Zonetype[%s]?\n",tmpbuffer);
1515 }
1516 }
1517}
1518
Forest Bond92b96792009-06-13 07:38:31 -04001519//get other parameter
1520 {
1521 memset(tmpbuffer,0,sizeof(tmpbuffer));
1522 if(Config_FileGetParameter("AUTHENMODE",tmpbuffer,buffer)==TRUE) {
1523 pDevice->config_file.eAuthenMode = (int) simple_strtol(tmpbuffer, NULL, 10);
1524 }
1525
1526 memset(tmpbuffer,0,sizeof(tmpbuffer));
1527 if(Config_FileGetParameter("ENCRYPTIONMODE",tmpbuffer,buffer)==TRUE) {
1528 pDevice->config_file.eEncryptionStatus= (int) simple_strtol(tmpbuffer, NULL, 10);
1529 }
1530 }
Forest Bond92b96792009-06-13 07:38:31 -04001531
1532 kfree(buffer);
1533 return result;
1534}
1535
1536static void device_set_multi(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001537 PSDevice pDevice = (PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001538 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1539 u32 mc_filter[2];
1540 int ii;
Jiri Pirko22bedad32010-04-01 21:22:57 +00001541 struct netdev_hw_addr *ha;
Forest Bond92b96792009-06-13 07:38:31 -04001542 BYTE pbyData[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1543 BYTE byTmpMode = 0;
1544 int rc;
1545
1546
1547 spin_lock_irq(&pDevice->lock);
1548 rc = CONTROLnsRequestIn(pDevice,
1549 MESSAGE_TYPE_READ,
1550 MAC_REG_RCR,
1551 MESSAGE_REQUEST_MACREG,
1552 1,
1553 &byTmpMode
1554 );
1555 if (rc == 0) pDevice->byRxMode = byTmpMode;
1556
1557 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode in= %x\n", pDevice->byRxMode);
1558
1559 if (dev->flags & IFF_PROMISC) { // Set promiscuous.
1560 DBG_PRT(MSG_LEVEL_ERR,KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
1561 // Unconditionally log net taps.
1562 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
1563 }
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001564 else if ((netdev_mc_count(dev) > pDevice->multicast_limit) ||
1565 (dev->flags & IFF_ALLMULTI)) {
Forest Bond92b96792009-06-13 07:38:31 -04001566 CONTROLnsRequestOut(pDevice,
1567 MESSAGE_TYPE_WRITE,
1568 MAC_REG_MAR0,
1569 MESSAGE_REQUEST_MACREG,
1570 8,
1571 pbyData
1572 );
1573 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1574 }
1575 else {
1576 memset(mc_filter, 0, sizeof(mc_filter));
Jiri Pirko22bedad32010-04-01 21:22:57 +00001577 netdev_for_each_mc_addr(ha, dev) {
1578 int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
Forest Bond92b96792009-06-13 07:38:31 -04001579 mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
1580 }
1581 for (ii = 0; ii < 4; ii++) {
1582 MACvWriteMultiAddr(pDevice, ii, *((PBYTE)&mc_filter[0] + ii));
1583 MACvWriteMultiAddr(pDevice, ii+ 4, *((PBYTE)&mc_filter[1] + ii));
1584 }
1585 pDevice->byRxMode &= ~(RCR_UNICAST);
1586 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1587 }
1588
1589 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
1590 // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac.
1591 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1592 pDevice->byRxMode &= ~(RCR_UNICAST);
1593 }
1594 ControlvWriteByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_RCR, pDevice->byRxMode);
1595 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode out= %x\n", pDevice->byRxMode);
1596 spin_unlock_irq(&pDevice->lock);
1597
1598}
1599
1600
1601static struct net_device_stats *device_get_stats(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001602 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001603
1604 return &pDevice->stats;
1605}
1606
1607
1608static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001609 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001610 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1611 PSCmdRequest pReq;
1612 //BOOL bCommit = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001613 struct iwreq *wrq = (struct iwreq *) rq;
1614 int rc =0;
Forest Bond92b96792009-06-13 07:38:31 -04001615
1616 if (pMgmt == NULL) {
1617 rc = -EFAULT;
1618 return rc;
1619 }
1620
1621 switch(cmd) {
1622
Forest Bond92b96792009-06-13 07:38:31 -04001623 case SIOCGIWNAME:
1624 rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL);
1625 break;
1626
1627 case SIOCSIWNWID:
1628 rc = -EOPNOTSUPP;
1629 break;
1630
1631 case SIOCGIWNWID: //0x8b03 support
1632 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1633 rc = iwctl_giwnwid(dev, NULL, &(wrq->u.nwid), NULL);
1634 #else
1635 rc = -EOPNOTSUPP;
1636 #endif
1637 break;
1638
1639 // Set frequency/channel
1640 case SIOCSIWFREQ:
1641 rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL);
1642 break;
1643
1644 // Get frequency/channel
1645 case SIOCGIWFREQ:
1646 rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL);
1647 break;
1648
1649 // Set desired network name (ESSID)
1650 case SIOCSIWESSID:
1651
1652 {
1653 char essid[IW_ESSID_MAX_SIZE+1];
1654 if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
1655 rc = -E2BIG;
1656 break;
1657 }
1658 if (copy_from_user(essid, wrq->u.essid.pointer,
1659 wrq->u.essid.length)) {
1660 rc = -EFAULT;
1661 break;
1662 }
1663 rc = iwctl_siwessid(dev, NULL,
1664 &(wrq->u.essid), essid);
1665 }
1666 break;
1667
1668
1669 // Get current network name (ESSID)
1670 case SIOCGIWESSID:
1671
1672 {
1673 char essid[IW_ESSID_MAX_SIZE+1];
Vasiliy Kulikoveacd1212010-10-29 00:02:11 +04001674 if (wrq->u.essid.pointer) {
Forest Bond92b96792009-06-13 07:38:31 -04001675 rc = iwctl_giwessid(dev, NULL,
1676 &(wrq->u.essid), essid);
1677 if (copy_to_user(wrq->u.essid.pointer,
1678 essid,
1679 wrq->u.essid.length) )
1680 rc = -EFAULT;
Vasiliy Kulikoveacd1212010-10-29 00:02:11 +04001681 }
Forest Bond92b96792009-06-13 07:38:31 -04001682 }
1683 break;
1684
1685 case SIOCSIWAP:
1686
1687 rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL);
1688 break;
1689
1690
1691 // Get current Access Point (BSSID)
1692 case SIOCGIWAP:
1693 rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL);
1694 break;
1695
1696
1697 // Set desired station name
1698 case SIOCSIWNICKN:
1699 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n");
1700 rc = -EOPNOTSUPP;
1701 break;
1702
1703 // Get current station name
1704 case SIOCGIWNICKN:
1705 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n");
1706 rc = -EOPNOTSUPP;
1707 break;
1708
1709 // Set the desired bit-rate
1710 case SIOCSIWRATE:
1711 rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL);
1712 break;
1713
1714 // Get the current bit-rate
1715 case SIOCGIWRATE:
1716
1717 rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
1718 break;
1719
1720 // Set the desired RTS threshold
1721 case SIOCSIWRTS:
1722
1723 rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL);
1724 break;
1725
1726 // Get the current RTS threshold
1727 case SIOCGIWRTS:
1728
1729 rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL);
1730 break;
1731
1732 // Set the desired fragmentation threshold
1733 case SIOCSIWFRAG:
1734
1735 rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL);
1736 break;
1737
1738 // Get the current fragmentation threshold
1739 case SIOCGIWFRAG:
1740
1741 rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL);
1742 break;
1743
1744 // Set mode of operation
1745 case SIOCSIWMODE:
1746 rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL);
1747 break;
1748
1749 // Get mode of operation
1750 case SIOCGIWMODE:
1751 rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
1752 break;
1753
1754 // Set WEP keys and mode
1755 case SIOCSIWENCODE:
1756 {
1757 char abyKey[WLAN_WEP232_KEYLEN];
1758
1759 if (wrq->u.encoding.pointer) {
1760
1761
1762 if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) {
1763 rc = -E2BIG;
1764 break;
1765 }
1766 memset(abyKey, 0, WLAN_WEP232_KEYLEN);
1767 if (copy_from_user(abyKey,
1768 wrq->u.encoding.pointer,
1769 wrq->u.encoding.length)) {
1770 rc = -EFAULT;
1771 break;
1772 }
1773 } else if (wrq->u.encoding.length != 0) {
1774 rc = -EINVAL;
1775 break;
1776 }
1777 rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey);
1778 }
1779 break;
1780
1781 // Get the WEP keys and mode
1782 case SIOCGIWENCODE:
1783
1784 if (!capable(CAP_NET_ADMIN)) {
1785 rc = -EPERM;
1786 break;
1787 }
1788 {
1789 char abyKey[WLAN_WEP232_KEYLEN];
1790
1791 rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey);
1792 if (rc != 0) break;
1793 if (wrq->u.encoding.pointer) {
1794 if (copy_to_user(wrq->u.encoding.pointer,
1795 abyKey,
1796 wrq->u.encoding.length))
1797 rc = -EFAULT;
1798 }
1799 }
1800 break;
1801
Forest Bond92b96792009-06-13 07:38:31 -04001802 // Get the current Tx-Power
1803 case SIOCGIWTXPOW:
1804 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
1805 rc = -EOPNOTSUPP;
1806 break;
1807
1808 case SIOCSIWTXPOW:
1809 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
1810 rc = -EOPNOTSUPP;
1811 break;
1812
Forest Bond92b96792009-06-13 07:38:31 -04001813 case SIOCSIWRETRY:
1814
1815 rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL);
1816 break;
1817
1818 case SIOCGIWRETRY:
1819
1820 rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL);
1821 break;
1822
Forest Bond92b96792009-06-13 07:38:31 -04001823 // Get range of parameters
1824 case SIOCGIWRANGE:
1825
1826 {
1827 struct iw_range range;
1828
1829 rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *) &range);
1830 if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
1831 rc = -EFAULT;
1832 }
1833
1834 break;
1835
1836 case SIOCGIWPOWER:
1837
1838 rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL);
1839 break;
1840
1841
1842 case SIOCSIWPOWER:
1843
1844 rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL);
1845 break;
1846
1847
1848 case SIOCGIWSENS:
1849
1850 rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL);
1851 break;
1852
1853 case SIOCSIWSENS:
1854 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n");
1855 rc = -EOPNOTSUPP;
1856 break;
1857
1858 case SIOCGIWAPLIST:
1859 {
1860 char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
1861
1862 if (wrq->u.data.pointer) {
1863 rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
1864 if (rc == 0) {
1865 if (copy_to_user(wrq->u.data.pointer,
1866 buffer,
1867 (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality)))
1868 ))
1869 rc = -EFAULT;
1870 }
1871 }
1872 }
1873 break;
1874
1875
1876#ifdef WIRELESS_SPY
1877 // Set the spy list
1878 case SIOCSIWSPY:
1879
1880 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
1881 rc = -EOPNOTSUPP;
1882 break;
1883
1884 // Get the spy list
1885 case SIOCGIWSPY:
1886
1887 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
1888 rc = -EOPNOTSUPP;
1889 break;
1890
1891#endif // WIRELESS_SPY
1892
1893 case SIOCGIWPRIV:
1894 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n");
1895 rc = -EOPNOTSUPP;
1896/*
1897 if(wrq->u.data.pointer) {
1898 wrq->u.data.length = sizeof(iwctl_private_args) / sizeof( iwctl_private_args[0]);
1899
1900 if(copy_to_user(wrq->u.data.pointer,
1901 (u_char *) iwctl_private_args,
1902 sizeof(iwctl_private_args)))
1903 rc = -EFAULT;
1904 }
1905*/
1906 break;
1907
Forest Bond92b96792009-06-13 07:38:31 -04001908#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1909 case SIOCSIWAUTH:
Andres More465711b2010-08-03 20:25:50 -03001910 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
Forest Bond92b96792009-06-13 07:38:31 -04001911 rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
1912 break;
1913
1914 case SIOCGIWAUTH:
1915 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH \n");
1916 rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
1917 break;
1918
1919 case SIOCSIWGENIE:
1920 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE \n");
1921 rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1922 break;
1923
1924 case SIOCGIWGENIE:
1925 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE \n");
1926 rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1927 break;
1928
1929 case SIOCSIWENCODEEXT:
1930 {
1931 char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
1932 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n");
1933 if(wrq->u.encoding.pointer){
1934 memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1);
1935 if(wrq->u.encoding.length > (sizeof(struct iw_encode_ext)+ MAX_KEY_LEN)){
1936 rc = -E2BIG;
1937 break;
1938 }
1939 if(copy_from_user(extra, wrq->u.encoding.pointer,wrq->u.encoding.length)){
1940 rc = -EFAULT;
1941 break;
1942 }
1943 }else if(wrq->u.encoding.length != 0){
1944 rc = -EINVAL;
1945 break;
1946 }
1947 rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra);
1948 }
1949 break;
1950
1951 case SIOCGIWENCODEEXT:
1952 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n");
1953 rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
1954 break;
1955
1956 case SIOCSIWMLME:
1957 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME \n");
1958 rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1959 break;
1960
1961#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
Forest Bond92b96792009-06-13 07:38:31 -04001962
Forest Bond92b96792009-06-13 07:38:31 -04001963 case IOCTL_CMD_TEST:
1964
1965 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1966 rc = -EFAULT;
1967 break;
1968 } else {
1969 rc = 0;
1970 }
1971 pReq = (PSCmdRequest)rq;
1972
1973 //20080130-01,<Remark> by Mike Liu
1974 // if(pDevice->bLinkPass==TRUE)
1975 pReq->wResult = MAGIC_CODE; //Linking status:0x3142
1976 //20080130-02,<Remark> by Mike Liu
1977 // else
1978 // pReq->wResult = MAGIC_CODE+1; //disconnect status:0x3143
1979 break;
1980
1981 case IOCTL_CMD_SET:
1982 if (!(pDevice->flags & DEVICE_FLAGS_OPENED) &&
1983 (((PSCmdRequest)rq)->wCmdCode !=WLAN_CMD_SET_WPA))
1984 {
1985 rc = -EFAULT;
1986 break;
1987 } else {
1988 rc = 0;
1989 }
1990
1991 if (test_and_set_bit( 0, (void*)&(pMgmt->uCmdBusy))) {
1992 return -EBUSY;
1993 }
1994 rc = private_ioctl(pDevice, rq);
1995 clear_bit( 0, (void*)&(pMgmt->uCmdBusy));
1996 break;
1997
1998 case IOCTL_CMD_HOSTAPD:
1999
2000 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
2001 rc = -EFAULT;
2002 break;
2003 } else {
2004 rc = 0;
2005 }
2006
Forest Bondc30d7972010-04-17 11:03:38 -04002007 rc = vt6656_hostap_ioctl(pDevice, &wrq->u.data);
Forest Bond92b96792009-06-13 07:38:31 -04002008 break;
2009
2010 case IOCTL_CMD_WPA:
2011
2012 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
2013 rc = -EFAULT;
2014 break;
2015 } else {
2016 rc = 0;
2017 }
2018
Forest Bond92b96792009-06-13 07:38:31 -04002019 rc = wpa_ioctl(pDevice, &wrq->u.data);
Forest Bond92b96792009-06-13 07:38:31 -04002020 break;
2021
2022 case SIOCETHTOOL:
2023 return ethtool_ioctl(dev, (void *) rq->ifr_data);
2024 // All other calls are currently unsupported
2025
2026 default:
2027 rc = -EOPNOTSUPP;
2028 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd);
2029
2030
2031 }
2032
2033 if (pDevice->bCommit) {
2034 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2035 netif_stop_queue(pDevice->dev);
2036 spin_lock_irq(&pDevice->lock);
Andres More0cbd8d92010-05-06 20:34:29 -03002037 bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002038 spin_unlock_irq(&pDevice->lock);
2039 }
2040 else {
2041 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
2042 spin_lock_irq(&pDevice->lock);
2043//2007-1121-01<Modify>by EinsnLiu
Andres More0cbd8d92010-05-06 20:34:29 -03002044 if (pDevice->bLinkPass &&
Forest Bond92b96792009-06-13 07:38:31 -04002045 memcmp(pMgmt->abyCurrSSID,pMgmt->abyDesireSSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN)) {
Andres More0cbd8d92010-05-06 20:34:29 -03002046 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002047 } else {
2048 pDevice->bLinkPass = FALSE;
2049 pMgmt->eCurrState = WMAC_STATE_IDLE;
2050 memset(pMgmt->abyCurrBSSID, 0, 6);
2051 }
2052 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
2053//End Modify
2054 netif_stop_queue(pDevice->dev);
2055#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
2056 pMgmt->eScanType = WMAC_SCAN_ACTIVE;
Andres More0cbd8d92010-05-06 20:34:29 -03002057 if (!pDevice->bWPASuppWextEnabled)
Forest Bond92b96792009-06-13 07:38:31 -04002058#endif
Andres More0cbd8d92010-05-06 20:34:29 -03002059 bScheduleCommand((void *) pDevice,
2060 WLAN_CMD_BSSID_SCAN,
2061 pMgmt->abyDesireSSID);
2062 bScheduleCommand((void *) pDevice,
2063 WLAN_CMD_SSID,
2064 NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002065 spin_unlock_irq(&pDevice->lock);
2066 }
2067 pDevice->bCommit = FALSE;
2068 }
2069
2070
2071 return rc;
2072}
2073
2074
2075static int ethtool_ioctl(struct net_device *dev, void *useraddr)
2076{
2077 u32 ethcmd;
2078
2079 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
2080 return -EFAULT;
2081
2082 switch (ethcmd) {
2083 case ETHTOOL_GDRVINFO: {
2084 struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
2085 strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
2086 strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
2087 if (copy_to_user(useraddr, &info, sizeof(info)))
2088 return -EFAULT;
2089 return 0;
2090 }
2091
2092 }
2093
2094 return -EOPNOTSUPP;
2095}
2096
2097
2098/*------------------------------------------------------------------*/
2099
Andres More26e5b652010-04-13 19:43:07 -03002100MODULE_DEVICE_TABLE(usb, vt6656_table);
Forest Bond92b96792009-06-13 07:38:31 -04002101
Andres More26e5b652010-04-13 19:43:07 -03002102static struct usb_driver vt6656_driver = {
2103 .name = DEVICE_NAME,
2104 .probe = vt6656_probe,
2105 .disconnect = vt6656_disconnect,
2106 .id_table = vt6656_table,
Forest Bond92b96792009-06-13 07:38:31 -04002107#ifdef CONFIG_PM
Andres More26e5b652010-04-13 19:43:07 -03002108 .suspend = vt6656_suspend,
2109 .resume = vt6656_resume,
2110#endif /* CONFIG_PM */
Forest Bond92b96792009-06-13 07:38:31 -04002111};
2112
Andres More26e5b652010-04-13 19:43:07 -03002113static int __init vt6656_init_module(void)
Forest Bond92b96792009-06-13 07:38:31 -04002114{
Forest Bondf4a8df92009-06-13 07:38:56 -04002115 printk(KERN_NOTICE DEVICE_FULL_DRV_NAM " " DEVICE_VERSION);
Andres More26e5b652010-04-13 19:43:07 -03002116 return usb_register(&vt6656_driver);
Forest Bond92b96792009-06-13 07:38:31 -04002117}
2118
Andres More26e5b652010-04-13 19:43:07 -03002119static void __exit vt6656_cleanup_module(void)
Forest Bond92b96792009-06-13 07:38:31 -04002120{
Andres More26e5b652010-04-13 19:43:07 -03002121 usb_deregister(&vt6656_driver);
Forest Bond92b96792009-06-13 07:38:31 -04002122}
2123
Andres More26e5b652010-04-13 19:43:07 -03002124module_init(vt6656_init_module);
2125module_exit(vt6656_cleanup_module);