staging: vt6656: remove unused variables bCmdClear and bNeedRadioOFF
[linux-2.6-block.git] / drivers / staging / vt6656 / main_usb.c
CommitLineData
92b96797
FB
1/*
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 *
26e5b65b 29 * vt6656_probe - module initial (insmod) driver entry
92b96797
FB
30 * device_remove1 - module remove entry
31 * device_open - allocate dma/descripter resource & initial mac/bbp function
a0a1f61a 32 * device_xmit - asynchronous data tx function
92b96797
FB
33 * device_set_multi - set mac filter
34 * device_ioctl - ioctl entry
a0a1f61a 35 * device_close - shutdown mac/bbp & free dma/descriptor resource
92b96797
FB
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
a0a1f61a 39 * device_dma0_xmit- tx PS buffered frame via dma0
92b96797
FB
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
7c51d177 49#include <linux/file.h>
92b96797 50#include "device.h"
92b96797 51#include "card.h"
92b96797 52#include "baseband.h"
92b96797 53#include "mac.h"
92b96797 54#include "power.h"
92b96797 55#include "wcmd.h"
92b96797 56#include "rxtx.h"
92b96797 57#include "dpc.h"
92b96797 58#include "rf.h"
92b96797 59#include "firmware.h"
62c8526d 60#include "usbpipe.h"
92b96797 61#include "channel.h"
92b96797 62#include "int.h"
92b96797 63
ec6e0f63 64/* static int msglevel = MSG_LEVEL_DEBUG; */
92b96797
FB
65static int msglevel =MSG_LEVEL_INFO;
66
ec6e0f63
AM
67/*
68 * define module options
69 */
92b96797 70
ec6e0f63
AM
71/* version information */
72#define DRIVER_AUTHOR \
73 "VIA Networking Technologies, Inc., <lyndonchen@vntek.com.tw>"
92b96797
FB
74MODULE_AUTHOR(DRIVER_AUTHOR);
75MODULE_LICENSE("GPL");
76MODULE_DESCRIPTION(DEVICE_FULL_DRV_NAM);
77
92b96797
FB
78#define DEVICE_PARAM(N,D) \
79 static int N[MAX_UINTS]=OPTION_DEFAULT;\
80 module_param_array(N, int, NULL, 0);\
81 MODULE_PARM_DESC(N, D);
82
92b96797
FB
83#define RX_DESC_DEF0 64
84DEVICE_PARAM(RxDescriptors0,"Number of receive usb desc buffer");
85
92b96797
FB
86#define TX_DESC_DEF0 64
87DEVICE_PARAM(TxDescriptors0,"Number of transmit usb desc buffer");
88
92b96797 89#define CHANNEL_DEF 6
92b96797
FB
90DEVICE_PARAM(Channel, "Channel number");
91
92b96797
FB
92/* PreambleType[] is the preamble length used for transmit.
93 0: indicate allows long preamble type
94 1: indicate allows short preamble type
95*/
96
97#define PREAMBLE_TYPE_DEF 1
98
99DEVICE_PARAM(PreambleType, "Preamble Type");
100
92b96797 101#define RTS_THRESH_DEF 2347
92b96797
FB
102DEVICE_PARAM(RTSThreshold, "RTS threshold");
103
92b96797 104#define FRAG_THRESH_DEF 2346
92b96797
FB
105DEVICE_PARAM(FragThreshold, "Fragmentation threshold");
106
92b96797
FB
107#define DATA_RATE_DEF 13
108/* datarate[] index
109 0: indicate 1 Mbps 0x02
110 1: indicate 2 Mbps 0x04
111 2: indicate 5.5 Mbps 0x0B
112 3: indicate 11 Mbps 0x16
113 4: indicate 6 Mbps 0x0c
114 5: indicate 9 Mbps 0x12
115 6: indicate 12 Mbps 0x18
116 7: indicate 18 Mbps 0x24
117 8: indicate 24 Mbps 0x30
118 9: indicate 36 Mbps 0x48
119 10: indicate 48 Mbps 0x60
120 11: indicate 54 Mbps 0x6c
121 12: indicate 72 Mbps 0x90
122 13: indicate auto rate
123*/
124
125DEVICE_PARAM(ConnectionRate, "Connection data rate");
126
92b96797 127#define OP_MODE_DEF 0
92b96797
FB
128DEVICE_PARAM(OPMode, "Infrastruct, adhoc, AP mode ");
129
130/* OpMode[] is used for transmit.
131 0: indicate infrastruct mode used
132 1: indicate adhoc mode used
133 2: indicate AP mode used
134*/
135
92b96797
FB
136/* PSMode[]
137 0: indicate disable power saving mode
138 1: indicate enable power saving mode
139*/
140
141#define PS_MODE_DEF 0
92b96797
FB
142DEVICE_PARAM(PSMode, "Power saving mode");
143
92b96797 144#define SHORT_RETRY_DEF 8
92b96797
FB
145DEVICE_PARAM(ShortRetryLimit, "Short frame retry limits");
146
92b96797 147#define LONG_RETRY_DEF 4
92b96797
FB
148DEVICE_PARAM(LongRetryLimit, "long frame retry limits");
149
92b96797
FB
150/* BasebandType[] baseband type selected
151 0: indicate 802.11a type
152 1: indicate 802.11b type
153 2: indicate 802.11g type
154*/
92b96797 155
24b46f9e 156#define BBP_TYPE_DEF 2
92b96797
FB
157DEVICE_PARAM(BasebandType, "baseband type");
158
92b96797
FB
159/* 80211hEnable[]
160 0: indicate disable 802.11h
161 1: indicate enable 802.11h
162*/
163
164#define X80211h_MODE_DEF 0
165
166DEVICE_PARAM(b80211hEnable, "802.11h mode");
167
ec6e0f63
AM
168/*
169 * Static vars definitions
170 */
92b96797 171
4d088876 172static struct usb_device_id vt6656_table[] = {
92b96797
FB
173 {USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)},
174 {}
175};
176
ec6e0f63 177/* frequency list (map channels to frequencies) */
92b96797
FB
178/*
179static const long frequency_list[] = {
180 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484,
181 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
182 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240,
183 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
184 5700, 5745, 5765, 5785, 5805, 5825
185 };
186
92b96797
FB
187*/
188
26e5b65b
AM
189static int vt6656_probe(struct usb_interface *intf,
190 const struct usb_device_id *id);
191static void vt6656_disconnect(struct usb_interface *intf);
92b96797 192
92b96797 193#ifdef CONFIG_PM /* Minimal support for suspend and resume */
26e5b65b
AM
194static int vt6656_suspend(struct usb_interface *intf, pm_message_t message);
195static int vt6656_resume(struct usb_interface *intf);
196#endif /* CONFIG_PM */
197
302433da 198static int device_init_registers(struct vnt_private *pDevice);
92b96797 199
dd0a774f
MP
200static void device_free_tx_bufs(struct vnt_private *pDevice);
201static void device_free_rx_bufs(struct vnt_private *pDevice);
202static void device_free_int_bufs(struct vnt_private *pDevice);
dfdcc425 203static bool device_alloc_bufs(struct vnt_private *pDevice);
dd0a774f 204
dd0a774f 205static void usb_device_reset(struct vnt_private *pDevice);
92b96797 206
92b96797 207static void
dd0a774f 208device_set_options(struct vnt_private *pDevice) {
92b96797
FB
209 pDevice->cbTD = TX_DESC_DEF0;
210 pDevice->cbRD = RX_DESC_DEF0;
92b96797
FB
211 pDevice->byShortRetryLimit = SHORT_RETRY_DEF;
212 pDevice->byLongRetryLimit = LONG_RETRY_DEF;
a0ad2776 213 pDevice->op_mode = NL80211_IFTYPE_UNSPECIFIED;
92b96797
FB
214 pDevice->byBBType = BBP_TYPE_DEF;
215 pDevice->byPacketType = pDevice->byBBType;
216 pDevice->byAutoFBCtrl = AUTO_FB_0;
92b96797 217 pDevice->byPreambleType = 0;
e269fc2d 218 pDevice->bExistSWNetAddr = false;
92b96797
FB
219}
220
ec6e0f63
AM
221/*
222 * initialization of MAC & BBP registers
223 */
302433da 224static int device_init_registers(struct vnt_private *pDevice)
92b96797 225{
748bf69c
MP
226 struct vnt_cmd_card_init *init_cmd = &pDevice->init_command;
227 struct vnt_rsp_card_init *init_rsp = &pDevice->init_response;
dd0a774f
MP
228 u8 byAntenna;
229 int ii;
dd0a774f 230 int ntStatus = STATUS_SUCCESS;
dd0a774f
MP
231 u8 byTmp;
232 u8 byCalibTXIQ = 0, byCalibTXDC = 0, byCalibRXIQ = 0;
92b96797 233
302433da
MP
234 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---->INIbInitAdapter. [%d][%d]\n",
235 DEVICE_INIT_COLD, pDevice->byPacketType);
236
45d63f89 237 if (!vnt_check_firmware_version(pDevice)) {
6a86b778 238 if (vnt_download_firmware(pDevice) == true) {
14321461 239 if (vnt_firmware_branch_to_sram(pDevice) == false) {
cbc06fb1 240 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
14321461 241 " vnt_firmware_branch_to_sram fail\n");
cbc06fb1
MP
242 return false;
243 }
244 } else {
245 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
246 " FIRMWAREbDownload fail\n");
cbc06fb1
MP
247 return false;
248 }
249 }
250
251 if (!BBbVT3184Init(pDevice)) {
252 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" BBbVT3184Init fail\n");
cbc06fb1
MP
253 return false;
254 }
92b96797 255
748bf69c
MP
256 init_cmd->init_class = DEVICE_INIT_COLD;
257 init_cmd->exist_sw_net_addr = (u8) pDevice->bExistSWNetAddr;
3d47a6fb 258 for (ii = 0; ii < 6; ii++)
748bf69c
MP
259 init_cmd->sw_net_addr[ii] = pDevice->abyCurrentNetAddr[ii];
260 init_cmd->short_retry_limit = pDevice->byShortRetryLimit;
261 init_cmd->long_retry_limit = pDevice->byLongRetryLimit;
3d47a6fb
MP
262
263 /* issue card_init command to device */
1390b02a 264 ntStatus = vnt_control_out(pDevice,
3d47a6fb 265 MESSAGE_TYPE_CARDINIT, 0, 0,
748bf69c 266 sizeof(struct vnt_cmd_card_init), (u8 *)init_cmd);
cbc06fb1
MP
267 if (ntStatus != STATUS_SUCCESS) {
268 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Issue Card init fail\n");
cbc06fb1
MP
269 return false;
270 }
92b96797 271
441c21c3 272 ntStatus = vnt_control_in(pDevice, MESSAGE_TYPE_INIT_RSP, 0, 0,
748bf69c 273 sizeof(struct vnt_rsp_card_init), (u8 *)init_rsp);
302433da
MP
274 if (ntStatus != STATUS_SUCCESS) {
275 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
276 "Cardinit request in status fail!\n");
302433da
MP
277 return false;
278 }
92b96797 279
ec6e0f63 280 /* local ID for AES functions */
441c21c3 281 ntStatus = vnt_control_in(pDevice, MESSAGE_TYPE_READ,
302433da
MP
282 MAC_REG_LOCALID, MESSAGE_REQUEST_MACREG, 1,
283 &pDevice->byLocalID);
7af94000 284 if (ntStatus != STATUS_SUCCESS)
302433da 285 return false;
92b96797 286
ec6e0f63
AM
287 /* do MACbSoftwareReset in MACvInitialize */
288
302433da
MP
289 pDevice->byTopOFDMBasicRate = RATE_24M;
290 pDevice->byTopCCKBasicRate = RATE_1M;
2486890a 291
ec6e0f63 292 /* target to IF pin while programming to RF chip */
302433da 293 pDevice->byCurPwr = 0xFF;
92b96797 294
302433da
MP
295 pDevice->byCCKPwr = pDevice->abyEEPROM[EEP_OFS_PWR_CCK];
296 pDevice->byOFDMPwrG = pDevice->abyEEPROM[EEP_OFS_PWR_OFDMG];
ec6e0f63
AM
297 /* load power table */
298 for (ii = 0; ii < 14; ii++) {
302433da
MP
299 pDevice->abyCCKPwrTbl[ii] =
300 pDevice->abyEEPROM[ii + EEP_OFS_CCK_PWR_TBL];
301
302 if (pDevice->abyCCKPwrTbl[ii] == 0)
303 pDevice->abyCCKPwrTbl[ii] = pDevice->byCCKPwr;
be973fcd 304 pDevice->abyOFDMPwrTbl[ii] =
302433da
MP
305 pDevice->abyEEPROM[ii + EEP_OFS_OFDM_PWR_TBL];
306 if (pDevice->abyOFDMPwrTbl[ii] == 0)
307 pDevice->abyOFDMPwrTbl[ii] = pDevice->byOFDMPwrG;
308 }
92b96797 309
ec6e0f63
AM
310 /*
311 * original zonetype is USA, but custom zonetype is Europe,
312 * then need to recover 12, 13, 14 channels with 11 channel
313 */
9ef2184d
MP
314 for (ii = 11; ii < 14; ii++) {
315 pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
316 pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
302433da 317 }
92b96797 318
302433da 319 pDevice->byOFDMPwrA = 0x34; /* same as RFbMA2829SelectChannel */
ec6e0f63 320
302433da
MP
321 /* load OFDM A power table */
322 for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) {
323 pDevice->abyOFDMAPwrTbl[ii] =
324 pDevice->abyEEPROM[ii + EEP_OFS_OFDMA_PWR_TBL];
325
326 if (pDevice->abyOFDMAPwrTbl[ii] == 0)
327 pDevice->abyOFDMAPwrTbl[ii] = pDevice->byOFDMPwrA;
328 }
92b96797 329
302433da 330 byAntenna = pDevice->abyEEPROM[EEP_OFS_ANTENNA];
92b96797 331
302433da
MP
332 if (byAntenna & EEP_ANTINV)
333 pDevice->bTxRxAntInv = true;
334 else
335 pDevice->bTxRxAntInv = false;
336
337 byAntenna &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
92b96797 338
ec6e0f63 339 if (byAntenna == 0) /* if not set default is both */
302433da
MP
340 byAntenna = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
341
342 if (byAntenna == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
343 pDevice->byAntennaCount = 2;
344 pDevice->byTxAntennaMode = ANT_B;
345 pDevice->dwTxAntennaSel = 1;
346 pDevice->dwRxAntennaSel = 1;
347
348 if (pDevice->bTxRxAntInv == true)
349 pDevice->byRxAntennaMode = ANT_A;
350 else
351 pDevice->byRxAntennaMode = ANT_B;
302433da 352 } else {
302433da
MP
353 pDevice->byAntennaCount = 1;
354 pDevice->dwTxAntennaSel = 0;
355 pDevice->dwRxAntennaSel = 0;
356
357 if (byAntenna & EEP_ANTENNA_AUX) {
358 pDevice->byTxAntennaMode = ANT_A;
359
360 if (pDevice->bTxRxAntInv == true)
361 pDevice->byRxAntennaMode = ANT_B;
362 else
363 pDevice->byRxAntennaMode = ANT_A;
364 } else {
365 pDevice->byTxAntennaMode = ANT_B;
366
367 if (pDevice->bTxRxAntInv == true)
368 pDevice->byRxAntennaMode = ANT_A;
369 else
370 pDevice->byRxAntennaMode = ANT_B;
371 }
372 }
373
ec6e0f63 374 /* get Auto Fall Back type */
cbc06fb1 375 pDevice->byAutoFBCtrl = AUTO_FB_0;
92b96797 376
ec6e0f63 377 /* default Auto Mode */
cbc06fb1 378 pDevice->byBBType = BB_TYPE_11G;
92b96797 379
ec6e0f63 380 /* get RFType */
748bf69c 381 pDevice->byRFType = init_rsp->rf_type;
92b96797 382
ec6e0f63 383 /* load vt3266 calibration parameters in EEPROM */
302433da
MP
384 if (pDevice->byRFType == RF_VT3226D0) {
385 if ((pDevice->abyEEPROM[EEP_OFS_MAJOR_VER] == 0x1) &&
386 (pDevice->abyEEPROM[EEP_OFS_MINOR_VER] >= 0x4)) {
387
388 byCalibTXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_IQ];
389 byCalibTXDC = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_DC];
390 byCalibRXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_RX_IQ];
391 if (byCalibTXIQ || byCalibTXDC || byCalibRXIQ) {
ec6e0f63 392 /* CR255, enable TX/RX IQ and DC compensation mode */
285d58c4 393 vnt_control_out_u8(pDevice,
cbc06fb1
MP
394 MESSAGE_REQUEST_BBREG,
395 0xff,
396 0x03);
ec6e0f63 397 /* CR251, TX I/Q Imbalance Calibration */
285d58c4 398 vnt_control_out_u8(pDevice,
cbc06fb1
MP
399 MESSAGE_REQUEST_BBREG,
400 0xfb,
401 byCalibTXIQ);
ec6e0f63 402 /* CR252, TX DC-Offset Calibration */
285d58c4 403 vnt_control_out_u8(pDevice,
cbc06fb1
MP
404 MESSAGE_REQUEST_BBREG,
405 0xfC,
406 byCalibTXDC);
ec6e0f63 407 /* CR253, RX I/Q Imbalance Calibration */
285d58c4 408 vnt_control_out_u8(pDevice,
cbc06fb1
MP
409 MESSAGE_REQUEST_BBREG,
410 0xfd,
411 byCalibRXIQ);
302433da 412 } else {
ec6e0f63 413 /* CR255, turn off BB Calibration compensation */
285d58c4 414 vnt_control_out_u8(pDevice,
cbc06fb1
MP
415 MESSAGE_REQUEST_BBREG,
416 0xff,
417 0x0);
302433da
MP
418 }
419 }
420 }
cbc06fb1 421
ec6e0f63 422 /* get permanent network address */
748bf69c 423 memcpy(pDevice->abyPermanentNetAddr, init_rsp->net_addr, 6);
9a0e756c 424 memcpy(pDevice->abyCurrentNetAddr,
cbc06fb1 425 pDevice->abyPermanentNetAddr, ETH_ALEN);
92b96797 426
ec6e0f63 427 /* if exist SW network address, use it */
d6a32aa1
AS
428 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %pM\n",
429 pDevice->abyCurrentNetAddr);
92b96797 430
cbc06fb1
MP
431 /*
432 * set BB and packet type at the same time
433 * set Short Slot Time, xIFS, and RSPINF
434 */
d35d5fbb 435 if (pDevice->byBBType == BB_TYPE_11A)
cbc06fb1 436 pDevice->bShortSlotTime = true;
d35d5fbb 437 else
cbc06fb1 438 pDevice->bShortSlotTime = false;
cbc06fb1
MP
439
440 BBvSetShortSlotTime(pDevice);
cbc06fb1 441
cbc06fb1
MP
442 pDevice->byRadioCtl = pDevice->abyEEPROM[EEP_OFS_RADIOCTL];
443 pDevice->bHWRadioOff = false;
444
445 if ((pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) != 0) {
441c21c3 446 ntStatus = vnt_control_in(pDevice, MESSAGE_TYPE_READ,
cbc06fb1
MP
447 MAC_REG_GPIOCTL1, MESSAGE_REQUEST_MACREG, 1, &byTmp);
448
7af94000 449 if (ntStatus != STATUS_SUCCESS)
cbc06fb1 450 return false;
cbc06fb1
MP
451
452 if ((byTmp & GPIO3_DATA) == 0) {
453 pDevice->bHWRadioOff = true;
36957537
MP
454 vnt_mac_reg_bits_on(pDevice, MAC_REG_GPIOCTL1,
455 GPIO3_INTMD);
cbc06fb1 456 } else {
a9bed1df
MP
457 vnt_mac_reg_bits_off(pDevice, MAC_REG_GPIOCTL1,
458 GPIO3_INTMD);
cbc06fb1
MP
459 pDevice->bHWRadioOff = false;
460 }
461
462 }
463
96f6975b 464 vnt_mac_set_led(pDevice, LEDSTS_TMLEN, 0x38);
cbc06fb1 465
96f6975b 466 vnt_mac_set_led(pDevice, LEDSTS_STS, LEDSTS_SLOW);
cbc06fb1 467
36957537 468 vnt_mac_reg_bits_on(pDevice, MAC_REG_GPIOCTL0, 0x01);
cbc06fb1
MP
469
470 if ((pDevice->bHWRadioOff == true) ||
471 (pDevice->bRadioControlOff == true)) {
fa26e0bd 472 vnt_radio_power_off(pDevice);
cbc06fb1 473 } else {
8a5e6c8c 474 vnt_radio_power_on(pDevice);
cbc06fb1
MP
475 }
476
cbc06fb1
MP
477 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----INIbInitAdapter Exit\n");
478
479 return true;
92b96797
FB
480}
481
f2625c24 482static void device_free_tx_bufs(struct vnt_private *priv)
8611a29a 483{
f2625c24
MP
484 struct vnt_usb_send_context *tx_context;
485 int ii;
486
487 for (ii = 0; ii < priv->cbTD; ii++) {
488 tx_context = priv->apTD[ii];
489 /* deallocate URBs */
30a05b39
MP
490 if (tx_context->urb) {
491 usb_kill_urb(tx_context->urb);
492 usb_free_urb(tx_context->urb);
f2625c24
MP
493 }
494
495 kfree(tx_context);
496 }
497
498 return;
92b96797
FB
499}
500
afc5eeb8 501static void device_free_rx_bufs(struct vnt_private *priv)
8611a29a 502{
afc5eeb8 503 struct vnt_rcb *rcb;
115cac2e 504 int ii;
92b96797 505
afc5eeb8
MP
506 for (ii = 0; ii < priv->cbRD; ii++) {
507 rcb = priv->apRCB[ii];
8cffb3cf
MP
508 if (!rcb)
509 continue;
92b96797 510
afc5eeb8
MP
511 /* deallocate URBs */
512 if (rcb->pUrb) {
513 usb_kill_urb(rcb->pUrb);
514 usb_free_urb(rcb->pUrb);
515 }
92b96797 516
afc5eeb8
MP
517 /* deallocate skb */
518 if (rcb->skb)
519 dev_kfree_skb(rcb->skb);
afc5eeb8 520
8cffb3cf
MP
521 kfree(rcb);
522 }
afc5eeb8
MP
523
524 return;
92b96797
FB
525}
526
dd0a774f 527static void usb_device_reset(struct vnt_private *pDevice)
92b96797
FB
528{
529 int status;
530 status = usb_reset_device(pDevice->usb);
531 if (status)
532 printk("usb_device_reset fail status=%d\n",status);
533 return ;
534}
92b96797 535
1506bf37 536static void device_free_int_bufs(struct vnt_private *priv)
8611a29a 537{
1506bf37
MP
538 kfree(priv->int_buf.data_buf);
539
f764e00d 540 return;
92b96797
FB
541}
542
35491de7 543static bool device_alloc_bufs(struct vnt_private *priv)
dd0a774f 544{
35491de7
MP
545 struct vnt_usb_send_context *tx_context;
546 struct vnt_rcb *rcb;
115cac2e 547 int ii;
92b96797 548
35491de7
MP
549 for (ii = 0; ii < priv->cbTD; ii++) {
550 tx_context = kmalloc(sizeof(struct vnt_usb_send_context),
551 GFP_KERNEL);
552 if (tx_context == NULL) {
31580eb5
MP
553 dev_err(&priv->usb->dev,
554 "allocate tx usb context failed\n");
35491de7
MP
555 goto free_tx;
556 }
92b96797 557
35491de7 558 priv->apTD[ii] = tx_context;
30a05b39 559 tx_context->priv = priv;
71d764ae 560 tx_context->pkt_no = ii;
35491de7
MP
561
562 /* allocate URBs */
30a05b39
MP
563 tx_context->urb = usb_alloc_urb(0, GFP_ATOMIC);
564 if (!tx_context->urb) {
35491de7
MP
565 DBG_PRT(MSG_LEVEL_ERR,
566 KERN_ERR "alloc tx urb failed\n");
567 goto free_tx;
568 }
92b96797 569
30a05b39 570 tx_context->in_use = false;
35491de7
MP
571 }
572
8cffb3cf
MP
573 for (ii = 0; ii < priv->cbRD; ii++) {
574 priv->apRCB[ii] = kzalloc(sizeof(struct vnt_rcb), GFP_KERNEL);
575 if (!priv->apRCB[ii]) {
576 dev_err(&priv->usb->dev,
577 "failed to allocate rcb no %d\n", ii);
578 goto free_rx_tx;
579 }
115cac2e 580
8cffb3cf 581 rcb = priv->apRCB[ii];
92b96797 582
35491de7 583 rcb->pDevice = priv;
92b96797 584
35491de7
MP
585 /* allocate URBs */
586 rcb->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
587 if (rcb->pUrb == NULL) {
588 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
589 " Failed to alloc rx urb\n");
590 goto free_rx_tx;
591 }
92b96797 592
63b9907f 593 rcb->skb = dev_alloc_skb(priv->rx_buf_sz);
35491de7
MP
594 if (rcb->skb == NULL) {
595 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
596 " Failed to alloc rx skb\n");
597 goto free_rx_tx;
598 }
92b96797 599
35491de7
MP
600 rcb->bBoolInUse = false;
601
8cffb3cf
MP
602 /* submit rx urb */
603 if (PIPEnsBulkInUsbRead(priv, rcb))
604 goto free_rx_tx;
92b96797
FB
605 }
606
35491de7
MP
607 priv->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC);
608 if (priv->pInterruptURB == NULL) {
609 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR"Failed to alloc int urb\n");
610 goto free_rx_tx;
92b96797
FB
611 }
612
35491de7
MP
613 priv->int_buf.data_buf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
614 if (priv->int_buf.data_buf == NULL) {
615 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR"Failed to alloc int buf\n");
616 usb_free_urb(priv->pInterruptURB);
617 goto free_rx_tx;
618 }
619
620 return true;
92b96797
FB
621
622free_rx_tx:
35491de7 623 device_free_rx_bufs(priv);
92b96797
FB
624
625free_tx:
35491de7 626 device_free_tx_bufs(priv);
92b96797 627
e269fc2d 628 return false;
92b96797
FB
629}
630
db8f37fa
MP
631static void vnt_tx_80211(struct ieee80211_hw *hw,
632 struct ieee80211_tx_control *control, struct sk_buff *skb)
633{
634 struct vnt_private *priv = hw->priv;
635
636 ieee80211_stop_queues(hw);
637
638 if (vnt_tx_packet(priv, skb)) {
639 ieee80211_free_txskb(hw, skb);
640
641 ieee80211_wake_queues(hw);
642 }
643}
644
645static int vnt_start(struct ieee80211_hw *hw)
646{
647 struct vnt_private *priv = hw->priv;
648
649 priv->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
650
651 if (device_alloc_bufs(priv) == false) {
652 dev_dbg(&priv->usb->dev, "device_alloc_bufs fail...\n");
653 return -ENOMEM;
654 }
655
656 MP_CLEAR_FLAG(priv, fMP_DISCONNECTED);
657 MP_SET_FLAG(priv, fMP_POST_READS);
658 MP_SET_FLAG(priv, fMP_POST_WRITES);
659
660 if (device_init_registers(priv) == false) {
661 dev_dbg(&priv->usb->dev, " init register fail\n");
662 goto free_all;
663 }
664
665 priv->int_interval = 1; /* bInterval is set to 1 */
666
db8f37fa
MP
667 INTvWorkItem(priv);
668
669 priv->flags |= DEVICE_FLAGS_OPENED;
670
671 ieee80211_wake_queues(hw);
672
673 return 0;
674
675free_all:
676 device_free_rx_bufs(priv);
677 device_free_tx_bufs(priv);
678 device_free_int_bufs(priv);
679
680 usb_kill_urb(priv->pInterruptURB);
681 usb_free_urb(priv->pInterruptURB);
682
683 return -ENOMEM;
684}
685
686static void vnt_stop(struct ieee80211_hw *hw)
687{
688 struct vnt_private *priv = hw->priv;
689 int i;
690
691 if (!priv)
692 return;
693
694 for (i = 0; i < MAX_KEY_TABLE; i++)
695 vnt_mac_disable_keyentry(priv, i);
696
697 /* clear all keys */
698 priv->key_entry_inuse = 0;
699
700 if ((priv->flags & DEVICE_FLAGS_UNPLUG) == false)
701 vnt_mac_shutdown(priv);
702
703 ieee80211_stop_queues(hw);
704
705 MP_SET_FLAG(priv, fMP_DISCONNECTED);
706 MP_CLEAR_FLAG(priv, fMP_POST_WRITES);
707 MP_CLEAR_FLAG(priv, fMP_POST_READS);
708
709 cancel_delayed_work_sync(&priv->run_command_work);
db8f37fa
MP
710
711 priv->bCmdRunning = false;
712
713 priv->flags &= ~DEVICE_FLAGS_OPENED;
714
715 device_free_tx_bufs(priv);
716 device_free_rx_bufs(priv);
717 device_free_int_bufs(priv);
718
719 usb_kill_urb(priv->pInterruptURB);
720 usb_free_urb(priv->pInterruptURB);
721
722 return;
723}
724
725static int vnt_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
726{
727 struct vnt_private *priv = hw->priv;
728
729 priv->vif = vif;
730
731 switch (vif->type) {
732 case NL80211_IFTYPE_STATION:
733 break;
734 case NL80211_IFTYPE_ADHOC:
735 vnt_mac_reg_bits_off(priv, MAC_REG_RCR, RCR_UNICAST);
736
737 vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_ADHOC);
738
739 break;
740 case NL80211_IFTYPE_AP:
741 vnt_mac_reg_bits_off(priv, MAC_REG_RCR, RCR_UNICAST);
742
743 vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_AP);
744
745 break;
746 default:
747 return -EOPNOTSUPP;
748 }
749
750 priv->op_mode = vif->type;
751
1ecd083e
MP
752 vnt_set_bss_mode(priv);
753
db8f37fa
MP
754 /* LED blink on TX */
755 vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_INTER);
756
757 return 0;
758}
759
760static void vnt_remove_interface(struct ieee80211_hw *hw,
761 struct ieee80211_vif *vif)
762{
763 struct vnt_private *priv = hw->priv;
764
765 switch (vif->type) {
766 case NL80211_IFTYPE_STATION:
767 break;
768 case NL80211_IFTYPE_ADHOC:
769 vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
770 vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
771 vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_ADHOC);
772 break;
773 case NL80211_IFTYPE_AP:
774 vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
775 vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
776 vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_AP);
777 break;
778 default:
779 break;
780 }
781
782 vnt_radio_power_off(priv);
783
784 priv->op_mode = NL80211_IFTYPE_UNSPECIFIED;
785
786 /* LED slow blink */
787 vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_SLOW);
788
789 return;
790}
791
792static int vnt_config(struct ieee80211_hw *hw, u32 changed)
793{
794 struct vnt_private *priv = hw->priv;
795 struct ieee80211_conf *conf = &hw->conf;
796 u8 bb_type;
797
798 if (changed & IEEE80211_CONF_CHANGE_PS) {
799 if (conf->flags & IEEE80211_CONF_PS)
800 vnt_enable_power_saving(priv, conf->listen_interval);
801 else
802 vnt_disable_power_saving(priv);
803 }
804
805 if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) ||
806 (conf->flags & IEEE80211_CONF_OFFCHANNEL)) {
807 vnt_set_channel(priv, conf->chandef.chan->hw_value);
808
809 if (conf->chandef.chan->band == IEEE80211_BAND_5GHZ)
810 bb_type = BB_TYPE_11A;
811 else
812 bb_type = BB_TYPE_11G;
813
814 if (priv->byBBType != bb_type) {
815 priv->byBBType = bb_type;
816
817 vnt_set_bss_mode(priv);
818 }
819 }
820
821 if (changed & IEEE80211_CONF_CHANGE_POWER) {
822 if (priv->byBBType == BB_TYPE_11B)
823 priv->wCurrentRate = RATE_1M;
824 else
825 priv->wCurrentRate = RATE_54M;
826
827 vnt_rf_setpower(priv, priv->wCurrentRate,
828 conf->chandef.chan->hw_value);
829 }
830
831 return 0;
832}
833
834static void vnt_bss_info_changed(struct ieee80211_hw *hw,
835 struct ieee80211_vif *vif, struct ieee80211_bss_conf *conf,
836 u32 changed)
837{
838 struct vnt_private *priv = hw->priv;
839 priv->current_aid = conf->aid;
840
841 if (changed & BSS_CHANGED_BSSID)
842 vnt_mac_set_bssid_addr(priv, (u8 *)conf->bssid);
843
844
845 if (changed & BSS_CHANGED_BASIC_RATES) {
846 priv->wBasicRate = conf->basic_rates;
847
848 vnt_update_top_rates(priv);
849
850 dev_dbg(&priv->usb->dev, "basic rates %x\n", conf->basic_rates);
851 }
852
853 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
854 if (conf->use_short_preamble) {
855 vnt_mac_enable_barker_preamble_mode(priv);
856 priv->byPreambleType = true;
857 } else {
858 vnt_mac_disable_barker_preamble_mode(priv);
859 priv->byPreambleType = false;
860 }
861 }
862
863 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
864 if (conf->use_cts_prot)
865 vnt_mac_enable_protect_mode(priv);
866 else
867 vnt_mac_disable_protect_mode(priv);
868 }
869
870 if (changed & BSS_CHANGED_ERP_SLOT) {
871 if (conf->use_short_slot)
872 priv->bShortSlotTime = true;
873 else
874 priv->bShortSlotTime = false;
875
876 BBvSetShortSlotTime(priv);
877 BBvSetVGAGainOffset(priv, priv->abyBBVGA[0]);
878 BBvUpdatePreEDThreshold(priv, false);
879 }
880
881 if (changed & BSS_CHANGED_TXPOWER)
882 vnt_rf_setpower(priv, priv->wCurrentRate,
883 conf->chandef.chan->hw_value);
884
885 if (changed & BSS_CHANGED_BEACON_ENABLED) {
886 dev_dbg(&priv->usb->dev,
887 "Beacon enable %d\n", conf->enable_beacon);
888
889 if (conf->enable_beacon) {
890 vnt_beacon_enable(priv, vif, conf);
891
892 vnt_mac_reg_bits_on(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
893 } else {
894 vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
895 }
896 }
897}
898
899static u64 vnt_prepare_multicast(struct ieee80211_hw *hw,
900 struct netdev_hw_addr_list *mc_list)
901{
902 struct vnt_private *priv = hw->priv;
903 struct netdev_hw_addr *ha;
904 u64 mc_filter = 0;
905 u32 bit_nr = 0;
906
907 netdev_hw_addr_list_for_each(ha, mc_list) {
908 bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
909
910 mc_filter |= 1ULL << (bit_nr & 0x3f);
911 }
912
913 priv->mc_list_count = mc_list->count;
914
915 return mc_filter;
916}
917
918static void vnt_configure(struct ieee80211_hw *hw,
919 unsigned int changed_flags, unsigned int *total_flags, u64 multicast)
920{
921 struct vnt_private *priv = hw->priv;
922 u8 rx_mode = 0;
923 int rc;
924
925 *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_PROMISC_IN_BSS |
926 FIF_BCN_PRBRESP_PROMISC;
927
928 rc = vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_RCR,
929 MESSAGE_REQUEST_MACREG, sizeof(u8), &rx_mode);
930
931 if (!rc)
932 rx_mode = RCR_MULTICAST | RCR_BROADCAST;
933
934 dev_dbg(&priv->usb->dev, "rx mode in = %x\n", rx_mode);
935
936 if (changed_flags & FIF_PROMISC_IN_BSS) {
937 /* unconditionally log net taps */
938 if (*total_flags & FIF_PROMISC_IN_BSS)
939 rx_mode |= RCR_UNICAST;
940 else
941 rx_mode &= ~RCR_UNICAST;
942 }
943
944 if (changed_flags & FIF_ALLMULTI) {
945 if (*total_flags & FIF_ALLMULTI) {
946 if (priv->mc_list_count > 2)
947 vnt_mac_set_filter(priv, ~0);
948 else
949 vnt_mac_set_filter(priv, multicast);
950
951 rx_mode |= RCR_MULTICAST | RCR_BROADCAST;
952 } else {
953 rx_mode &= ~(RCR_MULTICAST | RCR_BROADCAST);
954 }
955
956 }
957
958 if (changed_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)) {
959 if (*total_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC))
960 rx_mode &= ~RCR_BSSID;
961 else
962 rx_mode |= RCR_BSSID;
963 }
964
965 vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_RCR, rx_mode);
966
967 dev_dbg(&priv->usb->dev, "rx mode out= %x\n", rx_mode);
968
969 return;
970}
971
972static int vnt_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
973 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
974 struct ieee80211_key_conf *key)
975{
976 struct vnt_private *priv = hw->priv;
977
978 switch (cmd) {
979 case SET_KEY:
980 if (vnt_set_keys(hw, sta, vif, key))
981 return -EOPNOTSUPP;
982 break;
983 case DISABLE_KEY:
984 if (test_bit(key->hw_key_idx, &priv->key_entry_inuse))
985 clear_bit(key->hw_key_idx, &priv->key_entry_inuse);
986 default:
987 break;
988 }
989
990 return 0;
991}
992
993static void vnt_sw_scan_start(struct ieee80211_hw *hw)
994{
995 struct vnt_private *priv = hw->priv;
996
1ecd083e 997 vnt_set_bss_mode(priv);
db8f37fa
MP
998 /* Set max sensitivity*/
999 BBvUpdatePreEDThreshold(priv, true);
1000}
1001
1002static void vnt_sw_scan_complete(struct ieee80211_hw *hw)
1003{
1004 struct vnt_private *priv = hw->priv;
1005
1006 /* Return sensitivity to channel level*/
1007 BBvUpdatePreEDThreshold(priv, false);
1008}
1009
1786384e
MP
1010static int vnt_get_stats(struct ieee80211_hw *hw,
1011 struct ieee80211_low_level_stats *stats)
1012{
1013 struct vnt_private *priv = hw->priv;
1014
1015 memcpy(stats, &priv->low_stats, sizeof(*stats));
1016
1017 return 0;
1018}
1019
db8f37fa
MP
1020static u64 vnt_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1021{
1022 struct vnt_private *priv = hw->priv;
1023
1024 return priv->qwCurrTSF;
1025}
1026
1027static void vnt_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1028 u64 tsf)
1029{
1030 struct vnt_private *priv = hw->priv;
1031
1032 vnt_update_next_tbtt(priv, tsf, vif->bss_conf.beacon_int);
1033}
1034
1035static void vnt_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1036{
1037 struct vnt_private *priv = hw->priv;
1038
1039 vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1040
1041 vnt_clear_current_tsf(priv);
1042}
1043
1044static const struct ieee80211_ops vnt_mac_ops = {
1045 .tx = vnt_tx_80211,
1046 .start = vnt_start,
1047 .stop = vnt_stop,
1048 .add_interface = vnt_add_interface,
1049 .remove_interface = vnt_remove_interface,
1050 .config = vnt_config,
1051 .bss_info_changed = vnt_bss_info_changed,
1052 .prepare_multicast = vnt_prepare_multicast,
1053 .configure_filter = vnt_configure,
1054 .set_key = vnt_set_key,
1055 .sw_scan_start = vnt_sw_scan_start,
1056 .sw_scan_complete = vnt_sw_scan_complete,
1786384e 1057 .get_stats = vnt_get_stats,
db8f37fa
MP
1058 .get_tsf = vnt_get_tsf,
1059 .set_tsf = vnt_set_tsf,
1060 .reset_tsf = vnt_reset_tsf,
1061};
1062
1063int vnt_init(struct vnt_private *priv)
1064{
1065
1066 if (!(device_init_registers(priv)))
1067 return -EAGAIN;
1068
1069 SET_IEEE80211_PERM_ADDR(priv->hw, priv->abyPermanentNetAddr);
1070
110f97e9
MP
1071 vnt_init_bands(priv);
1072
db8f37fa
MP
1073 if (ieee80211_register_hw(priv->hw))
1074 return -ENODEV;
1075
30816f83
MP
1076 priv->mac_hw = true;
1077
ba911c9b
MP
1078 vnt_radio_power_off(priv);
1079
db8f37fa
MP
1080 return 0;
1081}
1082
1083static int
1084vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
1085{
1086 struct usb_device *udev;
1087 struct vnt_private *priv;
1088 struct ieee80211_hw *hw;
1089 struct wiphy *wiphy;
1090 int rc = 0;
1091
1092 udev = usb_get_dev(interface_to_usbdev(intf));
1093
1094 dev_notice(&udev->dev, "%s Ver. %s\n",
1095 DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
1096 dev_notice(&udev->dev,
1097 "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
1098
1099 hw = ieee80211_alloc_hw(sizeof(struct vnt_private), &vnt_mac_ops);
1100 if (!hw) {
1101 dev_err(&udev->dev, "could not register ieee80211_hw\n");
1102 goto err_nomem;
1103 }
1104
1105 priv = hw->priv;
1106 priv->hw = hw;
1107 priv->usb = udev;
1108
1109 device_set_options(priv);
1110
1111 spin_lock_init(&priv->lock);
1112 mutex_init(&priv->usb_lock);
1113
1114 INIT_DELAYED_WORK(&priv->run_command_work, vRunCommand);
db8f37fa 1115
db8f37fa
MP
1116 usb_set_intfdata(intf, priv);
1117
1118 wiphy = priv->hw->wiphy;
1119
1120 wiphy->frag_threshold = FRAG_THRESH_DEF;
1121 wiphy->rts_threshold = RTS_THRESH_DEF;
1122 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1123 BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
1124
1125 priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
1126 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
1127 IEEE80211_HW_SIGNAL_DBM |
1128 IEEE80211_HW_TIMING_BEACON_ONLY;
1129
1130 priv->hw->rate_control_algorithm = "pid";
1131 priv->hw->max_signal = 100;
1132
1133 SET_IEEE80211_DEV(priv->hw, &intf->dev);
1134
1135 usb_device_reset(priv);
1136
30816f83
MP
1137 MP_CLEAR_FLAG(priv, fMP_DISCONNECTED);
1138 vResetCommandTimer(priv);
1139
1140 bScheduleCommand(priv, WLAN_CMD_INIT_MAC80211, NULL);
1141
db8f37fa
MP
1142 return 0;
1143
1144err_nomem:
1145 usb_put_dev(udev);
1146
1147 return rc;
1148}
1149
0d7fe14f 1150static void vt6656_disconnect(struct usb_interface *intf)
92b96797 1151{
db8f37fa 1152 struct vnt_private *priv = usb_get_intfdata(intf);
92b96797 1153
db8f37fa 1154 if (!priv)
6cda24f5 1155 return;
92b96797 1156
30816f83
MP
1157 if (priv->mac_hw)
1158 ieee80211_unregister_hw(priv->hw);
db8f37fa 1159
92b96797 1160 usb_set_intfdata(intf, NULL);
6cda24f5 1161 usb_put_dev(interface_to_usbdev(intf));
92b96797 1162
db8f37fa 1163 priv->flags |= DEVICE_FLAGS_UNPLUG;
92b96797 1164
db8f37fa 1165 ieee80211_free_hw(priv->hw);
92b96797
FB
1166}
1167
db8f37fa
MP
1168#ifdef CONFIG_PM
1169
1170static int vt6656_suspend(struct usb_interface *intf, pm_message_t message)
1171{
1172 return 0;
1173}
1174
1175static int vt6656_resume(struct usb_interface *intf)
1176{
1177 return 0;
1178}
1179
1180#endif /* CONFIG_PM */
1181
26e5b65b 1182MODULE_DEVICE_TABLE(usb, vt6656_table);
92b96797 1183
26e5b65b
AM
1184static struct usb_driver vt6656_driver = {
1185 .name = DEVICE_NAME,
1186 .probe = vt6656_probe,
1187 .disconnect = vt6656_disconnect,
1188 .id_table = vt6656_table,
92b96797 1189#ifdef CONFIG_PM
26e5b65b
AM
1190 .suspend = vt6656_suspend,
1191 .resume = vt6656_resume,
1192#endif /* CONFIG_PM */
92b96797
FB
1193};
1194
bac2c126 1195module_usb_driver(vt6656_driver);