blob: 763e028a5cc57e734c703acdca058df253af319d [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,
Jiri Pirkoafc4b132011-08-16 06:29:01 +0000749 .ndo_set_rx_mode = device_set_multi,
Forest Bonddd8db702009-06-13 07:38:54 -0400750};
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
Marcos Paulo de Souzaac31e9e2011-11-30 00:17:15 -0200903 pDevice->pRCBMem = kzalloc((sizeof(RCB) * pDevice->cbRD), GFP_KERNEL);
Forest Bond92b96792009-06-13 07:38:31 -0400904 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;
Forest Bond92b96792009-06-13 07:38:31 -0400915 pRCB = (PRCB) pDevice->pRCBMem;
916
917 for (ii = 0; ii < pDevice->cbRD; ii++) {
918
919 pDevice->apRCB[ii] = pRCB;
Andres More8611a292010-05-01 14:25:00 -0300920 pRCB->pDevice = (void *) pDevice;
Forest Bond92b96792009-06-13 07:38:31 -0400921 //allocate URBs
Jim Liebdad72fe2009-08-12 14:54:14 -0700922 pRCB->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400923
924 if (pRCB->pUrb == NULL) {
925 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx urb\n");
926 goto free_rx_tx;
927 }
928 pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
929 if (pRCB->skb == NULL) {
930 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx skb\n");
931 goto free_rx_tx;
932 }
933 pRCB->skb->dev = pDevice->dev;
934 pRCB->bBoolInUse = FALSE;
935 EnqueueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList, pRCB);
936 pDevice->NumRecvFreeList++;
937 pRCB++;
938 }
939
940
Jim Liebdad72fe2009-08-12 14:54:14 -0700941 pDevice->pControlURB = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400942 if (pDevice->pControlURB == NULL) {
943 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc control urb\n");
944 goto free_rx_tx;
945 }
946
Jim Liebdad72fe2009-08-12 14:54:14 -0700947 pDevice->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC);
Forest Bond92b96792009-06-13 07:38:31 -0400948 if (pDevice->pInterruptURB == NULL) {
949 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int urb\n");
Forest Bond92b96792009-06-13 07:38:31 -0400950 usb_free_urb(pDevice->pControlURB);
951 goto free_rx_tx;
952 }
953
954 pDevice->intBuf.pDataBuf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
955 if (pDevice->intBuf.pDataBuf == NULL) {
956 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int buf\n");
Forest Bond92b96792009-06-13 07:38:31 -0400957 usb_free_urb(pDevice->pControlURB);
958 usb_free_urb(pDevice->pInterruptURB);
959 goto free_rx_tx;
960 }
961
962 return TRUE;
963
964free_rx_tx:
965 device_free_rx_bufs(pDevice);
966
967free_tx:
968 device_free_tx_bufs(pDevice);
969
970 return FALSE;
971}
972
973
974
975
976static BOOL device_init_defrag_cb(PSDevice pDevice) {
977 int i;
978 PSDeFragControlBlock pDeF;
979
980 /* Init the fragment ctl entries */
981 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
982 pDeF = &(pDevice->sRxDFCB[i]);
983 if (!device_alloc_frag_buf(pDevice, pDeF)) {
984 DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
985 pDevice->dev->name);
986 goto free_frag;
Joe Perches9fc86022011-04-10 14:31:32 -0700987 }
Forest Bond92b96792009-06-13 07:38:31 -0400988 }
989 pDevice->cbDFCB = CB_MAX_RX_FRAG;
990 pDevice->cbFreeDFCB = pDevice->cbDFCB;
991 return TRUE;
992
993free_frag:
994 device_free_frag_bufs(pDevice);
995 return FALSE;
996}
997
998
999
1000static void device_free_frag_bufs(PSDevice pDevice) {
1001 PSDeFragControlBlock pDeF;
1002 int i;
1003
1004 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
1005
1006 pDeF = &(pDevice->sRxDFCB[i]);
1007
1008 if (pDeF->skb)
1009 dev_kfree_skb(pDeF->skb);
1010 }
1011}
1012
1013
1014
1015BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
1016
1017 pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1018 if (pDeF->skb == NULL)
1019 return FALSE;
1020 ASSERT(pDeF->skb);
1021 pDeF->skb->dev = pDevice->dev;
1022
1023 return TRUE;
1024}
1025
1026
1027/*-----------------------------------------------------------------*/
1028
1029static int device_open(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001030 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001031
Forest Bond92b96792009-06-13 07:38:31 -04001032 extern SWPAResult wpa_Result;
1033 memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname));
1034 wpa_Result.proto = 0;
1035 wpa_Result.key_mgmt = 0;
1036 wpa_Result.eap_type = 0;
1037 wpa_Result.authenticated = FALSE;
1038 pDevice->fWPA_Authened = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001039
1040 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_open...\n");
1041
1042
1043 pDevice->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
1044
1045 if (device_alloc_bufs(pDevice) == FALSE) {
1046 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_alloc_bufs fail... \n");
1047 return -ENOMEM;
1048 }
1049
1050 if (device_init_defrag_cb(pDevice)== FALSE) {
1051 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Initial defragement cb fail \n");
1052 goto free_rx_tx;
1053 }
1054
1055 MP_CLEAR_FLAG(pDevice, fMP_DISCONNECTED);
1056 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
1057 MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
1058 MP_SET_FLAG(pDevice, fMP_POST_READS);
1059 MP_SET_FLAG(pDevice, fMP_POST_WRITES);
1060
1061 //read config file
1062 Read_config_file(pDevice);
1063
1064 if (device_init_registers(pDevice, DEVICE_INIT_COLD) == FALSE) {
1065 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " init register fail\n");
1066 goto free_all;
1067 }
1068
1069 device_set_multi(pDevice->dev);
1070 // Init for Key Management
1071
1072 KeyvInitTable(pDevice,&pDevice->sKey);
Andres More9a0e7562010-04-13 21:54:48 -03001073 memcpy(pDevice->sMgmtObj.abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN);
1074 memcpy(pDevice->dev->dev_addr, pDevice->abyCurrentNetAddr, ETH_ALEN);
Forest Bond92b96792009-06-13 07:38:31 -04001075 pDevice->bStopTx0Pkt = FALSE;
1076 pDevice->bStopDataPkt = FALSE;
Andres More465711b2010-08-03 20:25:50 -03001077 pDevice->bRoaming = FALSE;
1078 pDevice->bIsRoaming = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001079 pDevice->bEnableRoaming = FALSE;
1080 if (pDevice->bDiversityRegCtlON) {
1081 device_init_diversity_timer(pDevice);
1082 }
1083
1084 vMgrObjectInit(pDevice);
1085 tasklet_init(&pDevice->RxMngWorkItem, (void *)RXvMngWorkItem, (unsigned long)pDevice);
1086 tasklet_init(&pDevice->ReadWorkItem, (void *)RXvWorkItem, (unsigned long)pDevice);
1087 tasklet_init(&pDevice->EventWorkItem, (void *)INTvWorkItem, (unsigned long)pDevice);
1088 add_timer(&(pDevice->sMgmtObj.sTimerSecondCallback));
Forest Bond92b96792009-06-13 07:38:31 -04001089 pDevice->int_interval = 100; //Max 100 microframes.
Forest Bond92b96792009-06-13 07:38:31 -04001090 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
1091
1092 pDevice->bIsRxWorkItemQueued = TRUE;
1093 pDevice->fKillEventPollingThread = FALSE;
1094 pDevice->bEventAvailable = FALSE;
1095
1096 pDevice->bWPADEVUp = FALSE;
1097#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1098 pDevice->bwextstep0 = FALSE;
1099 pDevice->bwextstep1 = FALSE;
1100 pDevice->bwextstep2 = FALSE;
1101 pDevice->bwextstep3 = FALSE;
1102 pDevice->bWPASuppWextEnabled = FALSE;
1103#endif
1104 pDevice->byReAssocCount = 0;
1105
1106 RXvWorkItem(pDevice);
1107 INTvWorkItem(pDevice);
1108
1109 // Patch: if WEP key already set by iwconfig but device not yet open
1110 if ((pDevice->bEncryptionEnable == TRUE) && (pDevice->bTransmitKey == TRUE)) {
1111 spin_lock_irq(&pDevice->lock);
1112 KeybSetDefaultKey( pDevice,
1113 &(pDevice->sKey),
1114 pDevice->byKeyIndex | (1 << 31),
1115 pDevice->uKeyLength,
1116 NULL,
1117 pDevice->abyKey,
1118 KEY_CTL_WEP
1119 );
1120 spin_unlock_irq(&pDevice->lock);
1121 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1122 }
1123
1124 if (pDevice->sMgmtObj.eConfigMode == WMAC_CONFIG_AP) {
Andres More0cbd8d92010-05-06 20:34:29 -03001125 bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001126 }
1127 else {
1128 //mike:mark@2008-11-10
Andres More0cbd8d92010-05-06 20:34:29 -03001129 bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
1130 /* bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); */
Forest Bond92b96792009-06-13 07:38:31 -04001131 }
1132
1133
1134 netif_stop_queue(pDevice->dev);
1135 pDevice->flags |= DEVICE_FLAGS_OPENED;
1136
Forest Bond92b96792009-06-13 07:38:31 -04001137{
1138 union iwreq_data wrqu;
1139 memset(&wrqu, 0, sizeof(wrqu));
1140 wrqu.data.flags = RT_UPDEV_EVENT_FLAG;
1141 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1142}
Forest Bond92b96792009-06-13 07:38:31 -04001143
1144 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
1145 return 0;
1146
1147free_all:
1148 device_free_frag_bufs(pDevice);
1149free_rx_tx:
1150 device_free_rx_bufs(pDevice);
1151 device_free_tx_bufs(pDevice);
1152 device_free_int_bufs(pDevice);
Jim Liebdad72fe2009-08-12 14:54:14 -07001153 usb_kill_urb(pDevice->pControlURB);
1154 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -04001155 usb_free_urb(pDevice->pControlURB);
1156 usb_free_urb(pDevice->pInterruptURB);
1157
1158 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open fail.. \n");
1159 return -ENOMEM;
1160}
1161
1162
1163
1164static int device_close(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001165 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001166 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1167
Forest Bond92b96792009-06-13 07:38:31 -04001168 int uu;
Forest Bond92b96792009-06-13 07:38:31 -04001169
1170 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close1 \n");
1171 if (pDevice == NULL)
1172 return -ENODEV;
1173
Forest Bond92b96792009-06-13 07:38:31 -04001174{
1175 union iwreq_data wrqu;
1176 memset(&wrqu, 0, sizeof(wrqu));
1177 wrqu.data.flags = RT_DOWNDEV_EVENT_FLAG;
1178 wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
1179}
Forest Bond92b96792009-06-13 07:38:31 -04001180
Forest Bond92b96792009-06-13 07:38:31 -04001181 if (pDevice->bLinkPass) {
Andres More0cbd8d92010-05-06 20:34:29 -03001182 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001183 mdelay(30);
1184 }
Forest Bond92b96792009-06-13 07:38:31 -04001185
Forest Bond92b96792009-06-13 07:38:31 -04001186device_release_WPADEV(pDevice);
1187
Forest Bond92b96792009-06-13 07:38:31 -04001188 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
1189 pMgmt->bShareKeyAlgorithm = FALSE;
1190 pDevice->bEncryptionEnable = FALSE;
1191 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
Andres More33d33e422010-05-19 23:50:00 -03001192 spin_lock_irq(&pDevice->lock);
1193 for (uu = 0; uu < MAX_KEY_TABLE; uu++)
Forest Bond92b96792009-06-13 07:38:31 -04001194 MACvDisableKeyEntry(pDevice,uu);
Andres More33d33e422010-05-19 23:50:00 -03001195 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001196
1197 if ((pDevice->flags & DEVICE_FLAGS_UNPLUG) == FALSE) {
1198 MACbShutdown(pDevice);
1199 }
1200 netif_stop_queue(pDevice->dev);
1201 MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
1202 MP_CLEAR_FLAG(pDevice, fMP_POST_WRITES);
1203 MP_CLEAR_FLAG(pDevice, fMP_POST_READS);
1204 pDevice->fKillEventPollingThread = TRUE;
1205 del_timer(&pDevice->sTimerCommand);
1206 del_timer(&pMgmt->sTimerSecondCallback);
1207
Forest Bond92b96792009-06-13 07:38:31 -04001208 del_timer(&pDevice->sTimerTxData);
Forest Bond92b96792009-06-13 07:38:31 -04001209
1210 if (pDevice->bDiversityRegCtlON) {
1211 del_timer(&pDevice->TimerSQ3Tmax1);
1212 del_timer(&pDevice->TimerSQ3Tmax2);
1213 del_timer(&pDevice->TimerSQ3Tmax3);
1214 }
1215 tasklet_kill(&pDevice->RxMngWorkItem);
1216 tasklet_kill(&pDevice->ReadWorkItem);
1217 tasklet_kill(&pDevice->EventWorkItem);
1218
Andres More465711b2010-08-03 20:25:50 -03001219 pDevice->bRoaming = FALSE;
1220 pDevice->bIsRoaming = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001221 pDevice->bEnableRoaming = FALSE;
1222 pDevice->bCmdRunning = FALSE;
1223 pDevice->bLinkPass = FALSE;
1224 memset(pMgmt->abyCurrBSSID, 0, 6);
1225 pMgmt->eCurrState = WMAC_STATE_IDLE;
1226
1227 device_free_tx_bufs(pDevice);
1228 device_free_rx_bufs(pDevice);
1229 device_free_int_bufs(pDevice);
1230 device_free_frag_bufs(pDevice);
1231
Jim Liebdad72fe2009-08-12 14:54:14 -07001232 usb_kill_urb(pDevice->pControlURB);
1233 usb_kill_urb(pDevice->pInterruptURB);
Forest Bond92b96792009-06-13 07:38:31 -04001234 usb_free_urb(pDevice->pControlURB);
1235 usb_free_urb(pDevice->pInterruptURB);
1236
1237 BSSvClearNodeDBTable(pDevice, 0);
1238 pDevice->flags &=(~DEVICE_FLAGS_OPENED);
1239
1240 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n");
1241
1242 return 0;
1243}
1244
Andres More26e5b652010-04-13 19:43:07 -03001245static void __devexit vt6656_disconnect(struct usb_interface *intf)
Forest Bond92b96792009-06-13 07:38:31 -04001246{
Andres More6cda24f2010-06-22 20:43:39 -03001247 PSDevice device = usb_get_intfdata(intf);
Forest Bond92b96792009-06-13 07:38:31 -04001248
Andres More6cda24f2010-06-22 20:43:39 -03001249 if (!device)
1250 return;
Forest Bond92b96792009-06-13 07:38:31 -04001251
Andres More6cda24f2010-06-22 20:43:39 -03001252 {
1253 union iwreq_data req;
1254 memset(&req, 0, sizeof(req));
1255 req.data.flags = RT_RMMOD_EVENT_FLAG;
1256 wireless_send_event(device->dev, IWEVCUSTOM, &req, NULL);
1257 }
Forest Bond92b96792009-06-13 07:38:31 -04001258
Andres More6cda24f2010-06-22 20:43:39 -03001259 device_release_WPADEV(device);
Forest Bond92b96792009-06-13 07:38:31 -04001260
Ben Hutchings31d5bbf2011-01-09 04:16:48 +00001261 if (device->firmware)
1262 release_firmware(device->firmware);
1263
Forest Bond92b96792009-06-13 07:38:31 -04001264 usb_set_intfdata(intf, NULL);
Andres More6cda24f2010-06-22 20:43:39 -03001265 usb_put_dev(interface_to_usbdev(intf));
Forest Bond92b96792009-06-13 07:38:31 -04001266
Andres More6cda24f2010-06-22 20:43:39 -03001267 device->flags |= DEVICE_FLAGS_UNPLUG;
Forest Bond92b96792009-06-13 07:38:31 -04001268
Andres More6cda24f2010-06-22 20:43:39 -03001269 if (device->dev) {
1270 unregister_netdev(device->dev);
1271 wpa_set_wpadev(device, 0);
1272 free_netdev(device->dev);
1273 }
Forest Bond92b96792009-06-13 07:38:31 -04001274}
1275
Andres Moree1669ed2010-07-12 13:10:27 -03001276static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev)
1277{
1278 PSDevice pDevice = netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001279
Andres Moree1669ed2010-07-12 13:10:27 -03001280 spin_lock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001281
Andres Moree1669ed2010-07-12 13:10:27 -03001282 if (unlikely(pDevice->bStopTx0Pkt))
1283 dev_kfree_skb_irq(skb);
1284 else
1285 vDMA0_tx_80211(pDevice, skb);
Forest Bond92b96792009-06-13 07:38:31 -04001286
Andres Moree1669ed2010-07-12 13:10:27 -03001287 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001288
Andres Moree1669ed2010-07-12 13:10:27 -03001289 return NETDEV_TX_OK;
Forest Bond92b96792009-06-13 07:38:31 -04001290}
1291
Andres More529e5b32010-07-12 19:28:25 -03001292static int device_xmit(struct sk_buff *skb, struct net_device *dev)
1293{
1294 PSDevice pDevice = netdev_priv(dev);
1295 struct net_device_stats *stats = &pDevice->stats;
Forest Bond92b96792009-06-13 07:38:31 -04001296
Andres More529e5b32010-07-12 19:28:25 -03001297 spin_lock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001298
Andres More529e5b32010-07-12 19:28:25 -03001299 netif_stop_queue(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001300
Andres More529e5b32010-07-12 19:28:25 -03001301 if (!pDevice->bLinkPass) {
1302 dev_kfree_skb_irq(skb);
1303 goto out;
1304 }
Forest Bond92b96792009-06-13 07:38:31 -04001305
Andres More529e5b32010-07-12 19:28:25 -03001306 if (pDevice->bStopDataPkt) {
1307 dev_kfree_skb_irq(skb);
1308 stats->tx_dropped++;
1309 goto out;
1310 }
Forest Bond92b96792009-06-13 07:38:31 -04001311
Andres More529e5b32010-07-12 19:28:25 -03001312 if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb)) {
1313 if (netif_queue_stopped(dev))
1314 netif_wake_queue(dev);
1315 }
Forest Bond92b96792009-06-13 07:38:31 -04001316
Andres More529e5b32010-07-12 19:28:25 -03001317out:
1318 spin_unlock_irq(&pDevice->lock);
Forest Bond92b96792009-06-13 07:38:31 -04001319
Andres More529e5b32010-07-12 19:28:25 -03001320 return NETDEV_TX_OK;
Forest Bond92b96792009-06-13 07:38:31 -04001321}
1322
Forest Bond92b96792009-06-13 07:38:31 -04001323static unsigned const ethernet_polynomial = 0x04c11db7U;
1324static inline u32 ether_crc(int length, unsigned char *data)
1325{
1326 int crc = -1;
1327
1328 while(--length >= 0) {
1329 unsigned char current_octet = *data++;
1330 int bit;
1331 for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
1332 crc = (crc << 1) ^
1333 ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
1334 }
1335 }
1336 return crc;
1337}
1338
1339//find out the start position of str2 from str1
Andres Morecc856e62010-05-17 21:34:01 -03001340static unsigned char *kstrstr(const unsigned char *str1,
1341 const unsigned char *str2) {
1342 int str1_len = strlen(str1);
1343 int str2_len = strlen(str2);
Forest Bond92b96792009-06-13 07:38:31 -04001344
1345 while (str1_len >= str2_len) {
1346 str1_len--;
1347 if(memcmp(str1,str2,str2_len)==0)
Andres Morecc856e62010-05-17 21:34:01 -03001348 return (unsigned char *) str1;
Forest Bond92b96792009-06-13 07:38:31 -04001349 str1++;
1350 }
1351 return NULL;
1352}
1353
Andres Morecc856e62010-05-17 21:34:01 -03001354static int Config_FileGetParameter(unsigned char *string,
1355 unsigned char *dest,
1356 unsigned char *source)
Forest Bond92b96792009-06-13 07:38:31 -04001357{
Andres Morecc856e62010-05-17 21:34:01 -03001358 unsigned char buf1[100];
1359 unsigned char buf2[100];
1360 unsigned char *start_p = NULL, *end_p = NULL, *tmp_p = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001361 int ii;
1362
1363 memset(buf1,0,100);
1364 strcat(buf1, string);
1365 strcat(buf1, "=");
1366 source+=strlen(buf1);
1367
1368//find target string start point
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001369 start_p = kstrstr(source,buf1);
1370 if (start_p == NULL)
Forest Bond92b96792009-06-13 07:38:31 -04001371 return FALSE;
1372
1373//check if current config line is marked by "#" ??
Andres More33d33e422010-05-19 23:50:00 -03001374 for (ii = 1; ; ii++) {
1375 if (memcmp(start_p - ii, "\n", 1) == 0)
1376 break;
1377 if (memcmp(start_p - ii, "#", 1) == 0)
1378 return FALSE;
1379 }
Forest Bond92b96792009-06-13 07:38:31 -04001380
1381//find target string end point
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001382 end_p = kstrstr(start_p,"\n");
1383 if (end_p == NULL) { //can't find "\n",but don't care
Forest Bond92b96792009-06-13 07:38:31 -04001384 end_p=start_p+strlen(start_p); //no include "\n"
1385 }
1386
1387 memset(buf2,0,100);
1388 memcpy(buf2,start_p,end_p-start_p); //get the tartget line
1389 buf2[end_p-start_p]='\0';
1390
1391 //find value
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001392 start_p = kstrstr(buf2,"=");
1393 if (start_p == NULL)
Forest Bond92b96792009-06-13 07:38:31 -04001394 return FALSE;
1395 memset(buf1,0,100);
1396 strcpy(buf1,start_p+1);
1397
1398 //except space
1399 tmp_p = buf1;
1400 while(*tmp_p != 0x00) {
1401 if(*tmp_p==' ')
1402 tmp_p++;
1403 else
1404 break;
1405 }
1406
1407 memcpy(dest,tmp_p,strlen(tmp_p));
1408 return TRUE;
1409}
1410
1411//if read fail,return NULL,or return data pointer;
Andres Morecc856e62010-05-17 21:34:01 -03001412static unsigned char *Config_FileOperation(PSDevice pDevice)
1413{
1414 unsigned char *config_path = CONFIG_PATH;
1415 unsigned char *buffer = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001416 struct file *filp=NULL;
1417 mm_segment_t old_fs = get_fs();
Forest Bond8f9c4662009-06-13 07:38:47 -04001418 //int oldfsuid=0,oldfsgid=0;
Andres Morecc856e62010-05-17 21:34:01 -03001419 int result = 0;
Forest Bond92b96792009-06-13 07:38:31 -04001420
1421 set_fs (KERNEL_DS);
Forest Bond8f9c4662009-06-13 07:38:47 -04001422 /* Can't do this anymore, so we rely on correct filesystem permissions:
1423 //Make sure a caller can read or write power as root
1424 oldfsuid=current->fsuid;
1425 oldfsgid=current->fsgid;
Forest Bond92b96792009-06-13 07:38:31 -04001426 current->fsuid = 0;
1427 current->fsgid = 0;
Forest Bond8f9c4662009-06-13 07:38:47 -04001428 */
Forest Bond92b96792009-06-13 07:38:31 -04001429
1430 //open file
1431 filp = filp_open(config_path, O_RDWR, 0);
1432 if (IS_ERR(filp)) {
1433 printk("Config_FileOperation file Not exist\n");
1434 result=-1;
1435 goto error2;
1436 }
1437
1438 if(!(filp->f_op) || !(filp->f_op->read) ||!(filp->f_op->write)) {
1439 printk("file %s cann't readable or writable?\n",config_path);
1440 result = -1;
1441 goto error1;
1442 }
1443
Julia Lawall32414872010-05-11 20:26:57 +02001444 buffer = kmalloc(1024, GFP_KERNEL);
Forest Bond92b96792009-06-13 07:38:31 -04001445 if(buffer==NULL) {
Justin P. Mattock682a4532011-02-24 22:13:27 -08001446 printk("allocate mem for file fail?\n");
Forest Bond92b96792009-06-13 07:38:31 -04001447 result = -1;
1448 goto error1;
1449 }
1450
1451 if(filp->f_op->read(filp, buffer, 1024, &filp->f_pos)<0) {
1452 printk("read file error?\n");
1453 result = -1;
1454 }
1455
1456error1:
1457 if(filp_close(filp,NULL))
1458 printk("Config_FileOperation:close file fail\n");
1459
1460error2:
1461 set_fs (old_fs);
Forest Bond8f9c4662009-06-13 07:38:47 -04001462
1463 /*
Forest Bond92b96792009-06-13 07:38:31 -04001464 current->fsuid=oldfsuid;
1465 current->fsgid=oldfsgid;
Forest Bond8f9c4662009-06-13 07:38:47 -04001466 */
Forest Bond92b96792009-06-13 07:38:31 -04001467
1468if(result!=0) {
Ilia Mirkin1d5c5362011-03-13 00:29:15 -05001469 kfree(buffer);
Forest Bond92b96792009-06-13 07:38:31 -04001470 buffer=NULL;
1471}
1472 return buffer;
1473}
1474
André Goddard Rosabbc9a992009-11-14 13:09:06 -02001475//return --->-1:fail; >=0:successful
Forest Bond92b96792009-06-13 07:38:31 -04001476static int Read_config_file(PSDevice pDevice) {
Andres Morecc856e62010-05-17 21:34:01 -03001477 int result = 0;
1478 unsigned char tmpbuffer[100];
1479 unsigned char *buffer = NULL;
Forest Bond92b96792009-06-13 07:38:31 -04001480
1481 //init config setting
1482 pDevice->config_file.ZoneType = -1;
1483 pDevice->config_file.eAuthenMode = -1;
1484 pDevice->config_file.eEncryptionStatus = -1;
1485
Joe Perchesbfbfeec2010-03-24 22:17:06 -07001486 buffer = Config_FileOperation(pDevice);
1487 if (buffer == NULL) {
Forest Bond92b96792009-06-13 07:38:31 -04001488 result =-1;
1489 return result;
1490 }
1491
1492//get zonetype
1493{
1494 memset(tmpbuffer,0,sizeof(tmpbuffer));
1495 if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer) ==TRUE) {
1496 if(memcmp(tmpbuffer,"USA",3)==0) {
1497 pDevice->config_file.ZoneType=ZoneType_USA;
1498 }
1499 else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
1500 pDevice->config_file.ZoneType=ZoneType_Japan;
1501 }
1502 else if(memcmp(tmpbuffer,"EUROPE",6)==0) {
1503 pDevice->config_file.ZoneType=ZoneType_Europe;
1504 }
1505 else {
1506 printk("Unknown Zonetype[%s]?\n",tmpbuffer);
1507 }
1508 }
1509}
1510
Forest Bond92b96792009-06-13 07:38:31 -04001511//get other parameter
1512 {
1513 memset(tmpbuffer,0,sizeof(tmpbuffer));
1514 if(Config_FileGetParameter("AUTHENMODE",tmpbuffer,buffer)==TRUE) {
1515 pDevice->config_file.eAuthenMode = (int) simple_strtol(tmpbuffer, NULL, 10);
1516 }
1517
1518 memset(tmpbuffer,0,sizeof(tmpbuffer));
1519 if(Config_FileGetParameter("ENCRYPTIONMODE",tmpbuffer,buffer)==TRUE) {
1520 pDevice->config_file.eEncryptionStatus= (int) simple_strtol(tmpbuffer, NULL, 10);
1521 }
1522 }
Forest Bond92b96792009-06-13 07:38:31 -04001523
1524 kfree(buffer);
1525 return result;
1526}
1527
1528static void device_set_multi(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001529 PSDevice pDevice = (PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001530 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1531 u32 mc_filter[2];
1532 int ii;
Jiri Pirko22bedad32010-04-01 21:22:57 +00001533 struct netdev_hw_addr *ha;
Forest Bond92b96792009-06-13 07:38:31 -04001534 BYTE pbyData[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1535 BYTE byTmpMode = 0;
1536 int rc;
1537
1538
1539 spin_lock_irq(&pDevice->lock);
1540 rc = CONTROLnsRequestIn(pDevice,
1541 MESSAGE_TYPE_READ,
1542 MAC_REG_RCR,
1543 MESSAGE_REQUEST_MACREG,
1544 1,
1545 &byTmpMode
1546 );
1547 if (rc == 0) pDevice->byRxMode = byTmpMode;
1548
1549 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode in= %x\n", pDevice->byRxMode);
1550
1551 if (dev->flags & IFF_PROMISC) { // Set promiscuous.
1552 DBG_PRT(MSG_LEVEL_ERR,KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
1553 // Unconditionally log net taps.
1554 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
1555 }
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001556 else if ((netdev_mc_count(dev) > pDevice->multicast_limit) ||
1557 (dev->flags & IFF_ALLMULTI)) {
Forest Bond92b96792009-06-13 07:38:31 -04001558 CONTROLnsRequestOut(pDevice,
1559 MESSAGE_TYPE_WRITE,
1560 MAC_REG_MAR0,
1561 MESSAGE_REQUEST_MACREG,
1562 8,
1563 pbyData
1564 );
1565 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1566 }
1567 else {
1568 memset(mc_filter, 0, sizeof(mc_filter));
Jiri Pirko22bedad32010-04-01 21:22:57 +00001569 netdev_for_each_mc_addr(ha, dev) {
1570 int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
Forest Bond92b96792009-06-13 07:38:31 -04001571 mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
1572 }
1573 for (ii = 0; ii < 4; ii++) {
1574 MACvWriteMultiAddr(pDevice, ii, *((PBYTE)&mc_filter[0] + ii));
1575 MACvWriteMultiAddr(pDevice, ii+ 4, *((PBYTE)&mc_filter[1] + ii));
1576 }
1577 pDevice->byRxMode &= ~(RCR_UNICAST);
1578 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1579 }
1580
1581 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
1582 // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac.
1583 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
1584 pDevice->byRxMode &= ~(RCR_UNICAST);
1585 }
1586 ControlvWriteByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_RCR, pDevice->byRxMode);
1587 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode out= %x\n", pDevice->byRxMode);
1588 spin_unlock_irq(&pDevice->lock);
1589
1590}
1591
1592
1593static struct net_device_stats *device_get_stats(struct net_device *dev) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001594 PSDevice pDevice=(PSDevice) netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001595
1596 return &pDevice->stats;
1597}
1598
1599
1600static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
Forest Bond1e28efa2009-06-13 07:38:50 -04001601 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond92b96792009-06-13 07:38:31 -04001602 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
1603 PSCmdRequest pReq;
1604 //BOOL bCommit = FALSE;
Forest Bond92b96792009-06-13 07:38:31 -04001605 struct iwreq *wrq = (struct iwreq *) rq;
1606 int rc =0;
Forest Bond92b96792009-06-13 07:38:31 -04001607
1608 if (pMgmt == NULL) {
1609 rc = -EFAULT;
1610 return rc;
1611 }
1612
1613 switch(cmd) {
1614
Forest Bond92b96792009-06-13 07:38:31 -04001615 case SIOCGIWNAME:
1616 rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL);
1617 break;
1618
1619 case SIOCSIWNWID:
Forest Bond92b96792009-06-13 07:38:31 -04001620 case SIOCGIWNWID: //0x8b03 support
Marcos Paulo de Souza428c1fb2011-11-28 19:16:37 +00001621 rc = -EOPNOTSUPP;
Forest Bond92b96792009-06-13 07:38:31 -04001622 break;
1623
1624 // Set frequency/channel
1625 case SIOCSIWFREQ:
1626 rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL);
1627 break;
1628
1629 // Get frequency/channel
1630 case SIOCGIWFREQ:
1631 rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL);
1632 break;
1633
1634 // Set desired network name (ESSID)
1635 case SIOCSIWESSID:
1636
1637 {
1638 char essid[IW_ESSID_MAX_SIZE+1];
1639 if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
1640 rc = -E2BIG;
1641 break;
1642 }
1643 if (copy_from_user(essid, wrq->u.essid.pointer,
1644 wrq->u.essid.length)) {
1645 rc = -EFAULT;
1646 break;
1647 }
1648 rc = iwctl_siwessid(dev, NULL,
1649 &(wrq->u.essid), essid);
1650 }
1651 break;
1652
1653
1654 // Get current network name (ESSID)
1655 case SIOCGIWESSID:
1656
1657 {
1658 char essid[IW_ESSID_MAX_SIZE+1];
Vasiliy Kulikoveacd1212010-10-29 00:02:11 +04001659 if (wrq->u.essid.pointer) {
Marcos Paulo de Souzacaa20de2011-12-28 21:12:12 +00001660 iwctl_giwessid(dev, NULL,
1661 &(wrq->u.essid), essid);
Forest Bond92b96792009-06-13 07:38:31 -04001662 if (copy_to_user(wrq->u.essid.pointer,
1663 essid,
1664 wrq->u.essid.length) )
1665 rc = -EFAULT;
Vasiliy Kulikoveacd1212010-10-29 00:02:11 +04001666 }
Forest Bond92b96792009-06-13 07:38:31 -04001667 }
1668 break;
1669
1670 case SIOCSIWAP:
1671
1672 rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL);
1673 break;
1674
1675
1676 // Get current Access Point (BSSID)
1677 case SIOCGIWAP:
1678 rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL);
1679 break;
1680
1681
1682 // Set desired station name
1683 case SIOCSIWNICKN:
1684 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n");
1685 rc = -EOPNOTSUPP;
1686 break;
1687
1688 // Get current station name
1689 case SIOCGIWNICKN:
1690 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n");
1691 rc = -EOPNOTSUPP;
1692 break;
1693
1694 // Set the desired bit-rate
1695 case SIOCSIWRATE:
1696 rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL);
1697 break;
1698
1699 // Get the current bit-rate
1700 case SIOCGIWRATE:
Marcos Paulo de Souza739ea072011-12-28 21:13:39 +00001701 iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001702 break;
1703
1704 // Set the desired RTS threshold
1705 case SIOCSIWRTS:
1706
Marcos Paulo de Souza2fdde902011-12-28 21:18:31 +00001707 rc = iwctl_siwrts(dev, &(wrq->u.rts));
Forest Bond92b96792009-06-13 07:38:31 -04001708 break;
1709
1710 // Get the current RTS threshold
1711 case SIOCGIWRTS:
1712
1713 rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL);
1714 break;
1715
1716 // Set the desired fragmentation threshold
1717 case SIOCSIWFRAG:
1718
1719 rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL);
1720 break;
1721
1722 // Get the current fragmentation threshold
1723 case SIOCGIWFRAG:
1724
1725 rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL);
1726 break;
1727
1728 // Set mode of operation
1729 case SIOCSIWMODE:
1730 rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL);
1731 break;
1732
1733 // Get mode of operation
1734 case SIOCGIWMODE:
Marcos Paulo de Souza5d11b172011-12-28 21:09:13 +00001735 iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
Forest Bond92b96792009-06-13 07:38:31 -04001736 break;
1737
1738 // Set WEP keys and mode
1739 case SIOCSIWENCODE:
1740 {
1741 char abyKey[WLAN_WEP232_KEYLEN];
1742
1743 if (wrq->u.encoding.pointer) {
1744
1745
1746 if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) {
1747 rc = -E2BIG;
1748 break;
1749 }
1750 memset(abyKey, 0, WLAN_WEP232_KEYLEN);
1751 if (copy_from_user(abyKey,
1752 wrq->u.encoding.pointer,
1753 wrq->u.encoding.length)) {
1754 rc = -EFAULT;
1755 break;
1756 }
1757 } else if (wrq->u.encoding.length != 0) {
1758 rc = -EINVAL;
1759 break;
1760 }
1761 rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey);
1762 }
1763 break;
1764
1765 // Get the WEP keys and mode
1766 case SIOCGIWENCODE:
1767
1768 if (!capable(CAP_NET_ADMIN)) {
1769 rc = -EPERM;
1770 break;
1771 }
1772 {
1773 char abyKey[WLAN_WEP232_KEYLEN];
1774
1775 rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey);
1776 if (rc != 0) break;
1777 if (wrq->u.encoding.pointer) {
1778 if (copy_to_user(wrq->u.encoding.pointer,
1779 abyKey,
1780 wrq->u.encoding.length))
1781 rc = -EFAULT;
1782 }
1783 }
1784 break;
1785
Forest Bond92b96792009-06-13 07:38:31 -04001786 // Get the current Tx-Power
1787 case SIOCGIWTXPOW:
1788 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
1789 rc = -EOPNOTSUPP;
1790 break;
1791
1792 case SIOCSIWTXPOW:
1793 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
1794 rc = -EOPNOTSUPP;
1795 break;
1796
Forest Bond92b96792009-06-13 07:38:31 -04001797 case SIOCSIWRETRY:
1798
1799 rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL);
1800 break;
1801
1802 case SIOCGIWRETRY:
1803
1804 rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL);
1805 break;
1806
Forest Bond92b96792009-06-13 07:38:31 -04001807 // Get range of parameters
1808 case SIOCGIWRANGE:
1809
1810 {
1811 struct iw_range range;
1812
Marcos Paulo de Souzaf9b9f932011-12-28 21:10:50 +00001813 iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *) &range);
Forest Bond92b96792009-06-13 07:38:31 -04001814 if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
1815 rc = -EFAULT;
1816 }
1817
1818 break;
1819
1820 case SIOCGIWPOWER:
1821
1822 rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL);
1823 break;
1824
1825
1826 case SIOCSIWPOWER:
1827
1828 rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL);
1829 break;
1830
1831
1832 case SIOCGIWSENS:
1833
1834 rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL);
1835 break;
1836
1837 case SIOCSIWSENS:
1838 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n");
1839 rc = -EOPNOTSUPP;
1840 break;
1841
1842 case SIOCGIWAPLIST:
1843 {
1844 char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
1845
1846 if (wrq->u.data.pointer) {
1847 rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
1848 if (rc == 0) {
1849 if (copy_to_user(wrq->u.data.pointer,
1850 buffer,
1851 (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality)))
1852 ))
1853 rc = -EFAULT;
1854 }
1855 }
1856 }
1857 break;
1858
1859
1860#ifdef WIRELESS_SPY
1861 // Set the spy list
1862 case SIOCSIWSPY:
1863
1864 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
1865 rc = -EOPNOTSUPP;
1866 break;
1867
1868 // Get the spy list
1869 case SIOCGIWSPY:
1870
1871 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
1872 rc = -EOPNOTSUPP;
1873 break;
1874
1875#endif // WIRELESS_SPY
1876
1877 case SIOCGIWPRIV:
1878 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n");
1879 rc = -EOPNOTSUPP;
1880/*
1881 if(wrq->u.data.pointer) {
1882 wrq->u.data.length = sizeof(iwctl_private_args) / sizeof( iwctl_private_args[0]);
1883
1884 if(copy_to_user(wrq->u.data.pointer,
1885 (u_char *) iwctl_private_args,
1886 sizeof(iwctl_private_args)))
1887 rc = -EFAULT;
1888 }
1889*/
1890 break;
1891
Forest Bond92b96792009-06-13 07:38:31 -04001892#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1893 case SIOCSIWAUTH:
Andres More465711b2010-08-03 20:25:50 -03001894 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
Forest Bond92b96792009-06-13 07:38:31 -04001895 rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
1896 break;
1897
1898 case SIOCGIWAUTH:
1899 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH \n");
1900 rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
1901 break;
1902
1903 case SIOCSIWGENIE:
1904 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE \n");
1905 rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1906 break;
1907
1908 case SIOCGIWGENIE:
1909 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE \n");
1910 rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1911 break;
1912
1913 case SIOCSIWENCODEEXT:
1914 {
1915 char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
1916 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n");
1917 if(wrq->u.encoding.pointer){
1918 memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1);
1919 if(wrq->u.encoding.length > (sizeof(struct iw_encode_ext)+ MAX_KEY_LEN)){
1920 rc = -E2BIG;
1921 break;
1922 }
1923 if(copy_from_user(extra, wrq->u.encoding.pointer,wrq->u.encoding.length)){
1924 rc = -EFAULT;
1925 break;
1926 }
1927 }else if(wrq->u.encoding.length != 0){
1928 rc = -EINVAL;
1929 break;
1930 }
1931 rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra);
1932 }
1933 break;
1934
1935 case SIOCGIWENCODEEXT:
1936 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n");
1937 rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
1938 break;
1939
1940 case SIOCSIWMLME:
1941 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME \n");
1942 rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
1943 break;
1944
1945#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
Forest Bond92b96792009-06-13 07:38:31 -04001946
Forest Bond92b96792009-06-13 07:38:31 -04001947 case IOCTL_CMD_TEST:
1948
1949 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1950 rc = -EFAULT;
1951 break;
1952 } else {
1953 rc = 0;
1954 }
1955 pReq = (PSCmdRequest)rq;
1956
1957 //20080130-01,<Remark> by Mike Liu
1958 // if(pDevice->bLinkPass==TRUE)
1959 pReq->wResult = MAGIC_CODE; //Linking status:0x3142
1960 //20080130-02,<Remark> by Mike Liu
1961 // else
1962 // pReq->wResult = MAGIC_CODE+1; //disconnect status:0x3143
1963 break;
1964
1965 case IOCTL_CMD_SET:
1966 if (!(pDevice->flags & DEVICE_FLAGS_OPENED) &&
1967 (((PSCmdRequest)rq)->wCmdCode !=WLAN_CMD_SET_WPA))
1968 {
1969 rc = -EFAULT;
1970 break;
1971 } else {
1972 rc = 0;
1973 }
1974
1975 if (test_and_set_bit( 0, (void*)&(pMgmt->uCmdBusy))) {
1976 return -EBUSY;
1977 }
1978 rc = private_ioctl(pDevice, rq);
1979 clear_bit( 0, (void*)&(pMgmt->uCmdBusy));
1980 break;
1981
1982 case IOCTL_CMD_HOSTAPD:
1983
1984 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1985 rc = -EFAULT;
1986 break;
1987 } else {
1988 rc = 0;
1989 }
1990
Forest Bondc30d7972010-04-17 11:03:38 -04001991 rc = vt6656_hostap_ioctl(pDevice, &wrq->u.data);
Forest Bond92b96792009-06-13 07:38:31 -04001992 break;
1993
1994 case IOCTL_CMD_WPA:
1995
1996 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
1997 rc = -EFAULT;
1998 break;
1999 } else {
2000 rc = 0;
2001 }
2002
Forest Bond92b96792009-06-13 07:38:31 -04002003 rc = wpa_ioctl(pDevice, &wrq->u.data);
Forest Bond92b96792009-06-13 07:38:31 -04002004 break;
2005
2006 case SIOCETHTOOL:
2007 return ethtool_ioctl(dev, (void *) rq->ifr_data);
2008 // All other calls are currently unsupported
2009
2010 default:
2011 rc = -EOPNOTSUPP;
2012 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd);
2013
2014
2015 }
2016
2017 if (pDevice->bCommit) {
2018 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2019 netif_stop_queue(pDevice->dev);
2020 spin_lock_irq(&pDevice->lock);
Andres More0cbd8d92010-05-06 20:34:29 -03002021 bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002022 spin_unlock_irq(&pDevice->lock);
2023 }
2024 else {
2025 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
2026 spin_lock_irq(&pDevice->lock);
2027//2007-1121-01<Modify>by EinsnLiu
Andres More0cbd8d92010-05-06 20:34:29 -03002028 if (pDevice->bLinkPass &&
Forest Bond92b96792009-06-13 07:38:31 -04002029 memcmp(pMgmt->abyCurrSSID,pMgmt->abyDesireSSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN)) {
Andres More0cbd8d92010-05-06 20:34:29 -03002030 bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002031 } else {
2032 pDevice->bLinkPass = FALSE;
2033 pMgmt->eCurrState = WMAC_STATE_IDLE;
2034 memset(pMgmt->abyCurrBSSID, 0, 6);
2035 }
2036 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
2037//End Modify
2038 netif_stop_queue(pDevice->dev);
2039#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
2040 pMgmt->eScanType = WMAC_SCAN_ACTIVE;
Andres More0cbd8d92010-05-06 20:34:29 -03002041 if (!pDevice->bWPASuppWextEnabled)
Forest Bond92b96792009-06-13 07:38:31 -04002042#endif
Andres More0cbd8d92010-05-06 20:34:29 -03002043 bScheduleCommand((void *) pDevice,
2044 WLAN_CMD_BSSID_SCAN,
2045 pMgmt->abyDesireSSID);
2046 bScheduleCommand((void *) pDevice,
2047 WLAN_CMD_SSID,
2048 NULL);
Forest Bond92b96792009-06-13 07:38:31 -04002049 spin_unlock_irq(&pDevice->lock);
2050 }
2051 pDevice->bCommit = FALSE;
2052 }
2053
2054
2055 return rc;
2056}
2057
2058
2059static int ethtool_ioctl(struct net_device *dev, void *useraddr)
2060{
2061 u32 ethcmd;
2062
2063 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
2064 return -EFAULT;
2065
2066 switch (ethcmd) {
2067 case ETHTOOL_GDRVINFO: {
2068 struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
2069 strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
2070 strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
2071 if (copy_to_user(useraddr, &info, sizeof(info)))
2072 return -EFAULT;
2073 return 0;
2074 }
2075
2076 }
2077
2078 return -EOPNOTSUPP;
2079}
2080
2081
2082/*------------------------------------------------------------------*/
2083
Andres More26e5b652010-04-13 19:43:07 -03002084MODULE_DEVICE_TABLE(usb, vt6656_table);
Forest Bond92b96792009-06-13 07:38:31 -04002085
Andres More26e5b652010-04-13 19:43:07 -03002086static struct usb_driver vt6656_driver = {
2087 .name = DEVICE_NAME,
2088 .probe = vt6656_probe,
2089 .disconnect = vt6656_disconnect,
2090 .id_table = vt6656_table,
Forest Bond92b96792009-06-13 07:38:31 -04002091#ifdef CONFIG_PM
Andres More26e5b652010-04-13 19:43:07 -03002092 .suspend = vt6656_suspend,
2093 .resume = vt6656_resume,
2094#endif /* CONFIG_PM */
Forest Bond92b96792009-06-13 07:38:31 -04002095};
2096
Greg Kroah-Hartmanbac2c122011-11-18 09:42:11 -08002097module_usb_driver(vt6656_driver);