Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux...
[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 *
92b96797
FB
15 *
16 * File: main_usb.c
17 *
18 * Purpose: driver entry for initial, open, close, tx and rx.
19 *
20 * Author: Lyndon Chen
21 *
22 * Date: Dec 8, 2005
23 *
24 * Functions:
25 *
26e5b65b 26 * vt6656_probe - module initial (insmod) driver entry
afc7ef64 27 * vnt_free_tx_bufs - free tx buffer function
500e1fb3 28 * vnt_init_registers- initial MAC & BBP & RF internal registers.
92b96797
FB
29 *
30 * Revision History:
31 */
32#undef __NO_VERSION__
33
e2382233 34#include <linux/etherdevice.h>
7c51d177 35#include <linux/file.h>
92b96797 36#include "device.h"
92b96797 37#include "card.h"
92b96797 38#include "baseband.h"
92b96797 39#include "mac.h"
92b96797 40#include "power.h"
92b96797 41#include "wcmd.h"
92b96797 42#include "rxtx.h"
92b96797 43#include "dpc.h"
92b96797 44#include "rf.h"
92b96797 45#include "firmware.h"
62c8526d 46#include "usbpipe.h"
92b96797 47#include "channel.h"
92b96797 48#include "int.h"
92b96797 49
ec6e0f63
AM
50/*
51 * define module options
52 */
92b96797 53
ec6e0f63
AM
54/* version information */
55#define DRIVER_AUTHOR \
56 "VIA Networking Technologies, Inc., <lyndonchen@vntek.com.tw>"
92b96797
FB
57MODULE_AUTHOR(DRIVER_AUTHOR);
58MODULE_LICENSE("GPL");
59MODULE_DESCRIPTION(DEVICE_FULL_DRV_NAM);
60
dbf0a03b 61#define RX_DESC_DEF0 64
2f020ebc
MP
62static int vnt_rx_buffers = RX_DESC_DEF0;
63module_param_named(rx_buffers, vnt_rx_buffers, int, 0644);
64MODULE_PARM_DESC(rx_buffers, "Number of receive usb rx buffers");
92b96797 65
dbf0a03b 66#define TX_DESC_DEF0 64
3220e3a4 67static int vnt_tx_buffers = TX_DESC_DEF0;
1b6953dd 68module_param_named(tx_buffers, vnt_tx_buffers, int, 0644);
3220e3a4
MP
69MODULE_PARM_DESC(tx_buffers, "Number of receive usb tx buffers");
70
92b96797 71#define RTS_THRESH_DEF 2347
92b96797 72#define FRAG_THRESH_DEF 2346
92b96797 73#define SHORT_RETRY_DEF 8
92b96797 74#define LONG_RETRY_DEF 4
92b96797 75
92b96797 76/* BasebandType[] baseband type selected
d2713e51 77 * 0: indicate 802.11a type
78 * 1: indicate 802.11b type
79 * 2: indicate 802.11g type
80 */
92b96797 81
24b46f9e 82#define BBP_TYPE_DEF 2
92b96797 83
ec6e0f63
AM
84/*
85 * Static vars definitions
86 */
92b96797 87
ee705c3b 88static const struct usb_device_id vt6656_table[] = {
92b96797
FB
89 {USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)},
90 {}
91};
92
7665cf21 93static void vnt_set_options(struct vnt_private *priv)
28e067f4 94{
3220e3a4
MP
95 /* Set number of TX buffers */
96 if (vnt_tx_buffers < CB_MIN_TX_DESC || vnt_tx_buffers > CB_MAX_TX_DESC)
03b7e354 97 priv->num_tx_context = TX_DESC_DEF0;
3220e3a4 98 else
03b7e354 99 priv->num_tx_context = vnt_tx_buffers;
2f020ebc
MP
100
101 /* Set number of RX buffers */
102 if (vnt_rx_buffers < CB_MIN_RX_DESC || vnt_rx_buffers > CB_MAX_RX_DESC)
6da4738f 103 priv->num_rcb = RX_DESC_DEF0;
2f020ebc 104 else
6da4738f 105 priv->num_rcb = vnt_rx_buffers;
2f020ebc 106
388e5cb8
MP
107 priv->short_retry_limit = SHORT_RETRY_DEF;
108 priv->long_retry_limit = LONG_RETRY_DEF;
da3b67b3 109 priv->op_mode = NL80211_IFTYPE_UNSPECIFIED;
65df77e2 110 priv->bb_type = BBP_TYPE_DEF;
e12471db 111 priv->packet_type = priv->bb_type;
a6177aef 112 priv->auto_fb_ctrl = AUTO_FB_0;
98e93fe5 113 priv->preamble_type = 0;
35cc8f94 114 priv->exist_sw_net_addr = false;
92b96797
FB
115}
116
ec6e0f63
AM
117/*
118 * initialization of MAC & BBP registers
119 */
500e1fb3 120static int vnt_init_registers(struct vnt_private *priv)
92b96797 121{
3ce54934
MP
122 struct vnt_cmd_card_init *init_cmd = &priv->init_command;
123 struct vnt_rsp_card_init *init_rsp = &priv->init_response;
124 u8 antenna;
dd0a774f 125 int ii;
3ce54934
MP
126 int status = STATUS_SUCCESS;
127 u8 tmp;
128 u8 calib_tx_iq = 0, calib_tx_dc = 0, calib_rx_iq = 0;
92b96797 129
4e62dcc9 130 dev_dbg(&priv->usb->dev, "---->INIbInitAdapter. [%d][%d]\n",
c6bf6d2d 131 DEVICE_INIT_COLD, priv->packet_type);
302433da 132
3ce54934
MP
133 if (!vnt_check_firmware_version(priv)) {
134 if (vnt_download_firmware(priv) == true) {
135 if (vnt_firmware_branch_to_sram(priv) == false) {
4e62dcc9 136 dev_dbg(&priv->usb->dev,
14321461 137 " vnt_firmware_branch_to_sram fail\n");
cbc06fb1
MP
138 return false;
139 }
140 } else {
4e62dcc9 141 dev_dbg(&priv->usb->dev, "FIRMWAREbDownload fail\n");
cbc06fb1
MP
142 return false;
143 }
144 }
145
3ce54934 146 if (!vnt_vt3184_init(priv)) {
4e62dcc9 147 dev_dbg(&priv->usb->dev, "vnt_vt3184_init fail\n");
cbc06fb1
MP
148 return false;
149 }
92b96797 150
748bf69c 151 init_cmd->init_class = DEVICE_INIT_COLD;
35cc8f94 152 init_cmd->exist_sw_net_addr = priv->exist_sw_net_addr;
3d47a6fb 153 for (ii = 0; ii < 6; ii++)
ebf9b312 154 init_cmd->sw_net_addr[ii] = priv->current_net_addr[ii];
388e5cb8
MP
155 init_cmd->short_retry_limit = priv->short_retry_limit;
156 init_cmd->long_retry_limit = priv->long_retry_limit;
3d47a6fb
MP
157
158 /* issue card_init command to device */
c6bf6d2d
SM
159 status = vnt_control_out(priv, MESSAGE_TYPE_CARDINIT, 0, 0,
160 sizeof(struct vnt_cmd_card_init),
161 (u8 *)init_cmd);
3ce54934 162 if (status != STATUS_SUCCESS) {
4e62dcc9 163 dev_dbg(&priv->usb->dev, "Issue Card init fail\n");
cbc06fb1
MP
164 return false;
165 }
92b96797 166
3ce54934 167 status = vnt_control_in(priv, MESSAGE_TYPE_INIT_RSP, 0, 0,
c6bf6d2d
SM
168 sizeof(struct vnt_rsp_card_init),
169 (u8 *)init_rsp);
3ce54934 170 if (status != STATUS_SUCCESS) {
4e62dcc9 171 dev_dbg(&priv->usb->dev,
302433da 172 "Cardinit request in status fail!\n");
302433da
MP
173 return false;
174 }
92b96797 175
ec6e0f63 176 /* local ID for AES functions */
c6bf6d2d
SM
177 status = vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_LOCALID,
178 MESSAGE_REQUEST_MACREG, 1, &priv->local_id);
3ce54934 179 if (status != STATUS_SUCCESS)
302433da 180 return false;
92b96797 181
ec6e0f63
AM
182 /* do MACbSoftwareReset in MACvInitialize */
183
3c8a5b25 184 priv->top_ofdm_basic_rate = RATE_24M;
d80bf43c 185 priv->top_cck_basic_rate = RATE_1M;
2486890a 186
ec6e0f63 187 /* target to IF pin while programming to RF chip */
5a97491c 188 priv->power = 0xFF;
92b96797 189
5a97491c
MP
190 priv->cck_pwr = priv->eeprom[EEP_OFS_PWR_CCK];
191 priv->ofdm_pwr_g = priv->eeprom[EEP_OFS_PWR_OFDMG];
ec6e0f63
AM
192 /* load power table */
193 for (ii = 0; ii < 14; ii++) {
5a97491c 194 priv->cck_pwr_tbl[ii] =
bbb11263 195 priv->eeprom[ii + EEP_OFS_CCK_PWR_TBL];
5a97491c
MP
196 if (priv->cck_pwr_tbl[ii] == 0)
197 priv->cck_pwr_tbl[ii] = priv->cck_pwr;
3ce54934 198
5a97491c 199 priv->ofdm_pwr_tbl[ii] =
bbb11263 200 priv->eeprom[ii + EEP_OFS_OFDM_PWR_TBL];
5a97491c
MP
201 if (priv->ofdm_pwr_tbl[ii] == 0)
202 priv->ofdm_pwr_tbl[ii] = priv->ofdm_pwr_g;
302433da 203 }
92b96797 204
ec6e0f63
AM
205 /*
206 * original zonetype is USA, but custom zonetype is Europe,
207 * then need to recover 12, 13, 14 channels with 11 channel
208 */
9ef2184d 209 for (ii = 11; ii < 14; ii++) {
5a97491c
MP
210 priv->cck_pwr_tbl[ii] = priv->cck_pwr_tbl[10];
211 priv->ofdm_pwr_tbl[ii] = priv->ofdm_pwr_tbl[10];
302433da 212 }
92b96797 213
5a97491c 214 priv->ofdm_pwr_a = 0x34; /* same as RFbMA2829SelectChannel */
ec6e0f63 215
302433da
MP
216 /* load OFDM A power table */
217 for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) {
5a97491c 218 priv->ofdm_a_pwr_tbl[ii] =
bbb11263 219 priv->eeprom[ii + EEP_OFS_OFDMA_PWR_TBL];
302433da 220
5a97491c
MP
221 if (priv->ofdm_a_pwr_tbl[ii] == 0)
222 priv->ofdm_a_pwr_tbl[ii] = priv->ofdm_pwr_a;
302433da 223 }
92b96797 224
bbb11263 225 antenna = priv->eeprom[EEP_OFS_ANTENNA];
92b96797 226
3ce54934 227 if (antenna & EEP_ANTINV)
2044dbdb 228 priv->tx_rx_ant_inv = true;
302433da 229 else
2044dbdb 230 priv->tx_rx_ant_inv = false;
302433da 231
3ce54934 232 antenna &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
92b96797 233
3ce54934
MP
234 if (antenna == 0) /* if not set default is both */
235 antenna = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
302433da 236
3ce54934 237 if (antenna == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
2044dbdb
MP
238 priv->tx_antenna_mode = ANT_B;
239 priv->rx_antenna_sel = 1;
302433da 240
f72ea988 241 if (priv->tx_rx_ant_inv)
2044dbdb 242 priv->rx_antenna_mode = ANT_A;
302433da 243 else
2044dbdb 244 priv->rx_antenna_mode = ANT_B;
302433da 245 } else {
2044dbdb 246 priv->rx_antenna_sel = 0;
302433da 247
3ce54934 248 if (antenna & EEP_ANTENNA_AUX) {
2044dbdb 249 priv->tx_antenna_mode = ANT_A;
302433da 250
f72ea988 251 if (priv->tx_rx_ant_inv)
2044dbdb 252 priv->rx_antenna_mode = ANT_B;
302433da 253 else
2044dbdb 254 priv->rx_antenna_mode = ANT_A;
302433da 255 } else {
2044dbdb 256 priv->tx_antenna_mode = ANT_B;
302433da 257
f72ea988 258 if (priv->tx_rx_ant_inv)
2044dbdb 259 priv->rx_antenna_mode = ANT_A;
302433da 260 else
2044dbdb 261 priv->rx_antenna_mode = ANT_B;
302433da
MP
262 }
263 }
264
ed0db513 265 /* Set initial antenna mode */
2044dbdb 266 vnt_set_antenna_mode(priv, priv->rx_antenna_mode);
ed0db513 267
ec6e0f63 268 /* get Auto Fall Back type */
a6177aef 269 priv->auto_fb_ctrl = AUTO_FB_0;
92b96797 270
ec6e0f63 271 /* default Auto Mode */
65df77e2 272 priv->bb_type = BB_TYPE_11G;
92b96797 273
ec6e0f63 274 /* get RFType */
6242ecae 275 priv->rf_type = init_rsp->rf_type;
92b96797 276
ec6e0f63 277 /* load vt3266 calibration parameters in EEPROM */
6242ecae 278 if (priv->rf_type == RF_VT3226D0) {
bbb11263
MP
279 if ((priv->eeprom[EEP_OFS_MAJOR_VER] == 0x1) &&
280 (priv->eeprom[EEP_OFS_MINOR_VER] >= 0x4)) {
bbb11263
MP
281 calib_tx_iq = priv->eeprom[EEP_OFS_CALIB_TX_IQ];
282 calib_tx_dc = priv->eeprom[EEP_OFS_CALIB_TX_DC];
283 calib_rx_iq = priv->eeprom[EEP_OFS_CALIB_RX_IQ];
3ce54934 284 if (calib_tx_iq || calib_tx_dc || calib_rx_iq) {
33e9ab3d 285 /* CR255, enable TX/RX IQ and
d2713e51 286 * DC compensation mode
287 */
3ce54934 288 vnt_control_out_u8(priv,
33e9ab3d
PST
289 MESSAGE_REQUEST_BBREG,
290 0xff,
291 0x03);
292 /* CR251, TX I/Q Imbalance Calibration */
3ce54934 293 vnt_control_out_u8(priv,
33e9ab3d
PST
294 MESSAGE_REQUEST_BBREG,
295 0xfb,
3ce54934 296 calib_tx_iq);
33e9ab3d 297 /* CR252, TX DC-Offset Calibration */
3ce54934 298 vnt_control_out_u8(priv,
33e9ab3d
PST
299 MESSAGE_REQUEST_BBREG,
300 0xfC,
3ce54934 301 calib_tx_dc);
33e9ab3d 302 /* CR253, RX I/Q Imbalance Calibration */
3ce54934 303 vnt_control_out_u8(priv,
33e9ab3d
PST
304 MESSAGE_REQUEST_BBREG,
305 0xfd,
3ce54934 306 calib_rx_iq);
302433da 307 } else {
33e9ab3d 308 /* CR255, turn off
d2713e51 309 * BB Calibration compensation
310 */
3ce54934 311 vnt_control_out_u8(priv,
33e9ab3d
PST
312 MESSAGE_REQUEST_BBREG,
313 0xff,
314 0x0);
302433da
MP
315 }
316 }
317 }
cbc06fb1 318
ec6e0f63 319 /* get permanent network address */
41e8321a 320 memcpy(priv->permanent_net_addr, init_rsp->net_addr, 6);
e2382233 321 ether_addr_copy(priv->current_net_addr, priv->permanent_net_addr);
92b96797 322
ec6e0f63 323 /* if exist SW network address, use it */
4e62dcc9 324 dev_dbg(&priv->usb->dev, "Network address = %pM\n",
ebf9b312 325 priv->current_net_addr);
92b96797 326
cbc06fb1 327 /*
2ce7b194
NA
328 * set BB and packet type at the same time
329 * set Short Slot Time, xIFS, and RSPINF
330 */
65df77e2 331 if (priv->bb_type == BB_TYPE_11A)
a641c9ec 332 priv->short_slot_time = true;
d35d5fbb 333 else
a641c9ec 334 priv->short_slot_time = false;
cbc06fb1 335
3ce54934 336 vnt_set_short_slot_time(priv);
cbc06fb1 337
bbb11263 338 priv->radio_ctl = priv->eeprom[EEP_OFS_RADIOCTL];
cbc06fb1 339
2044dbdb 340 if ((priv->radio_ctl & EEP_RADIOCTL_ENABLE) != 0) {
3ce54934 341 status = vnt_control_in(priv, MESSAGE_TYPE_READ,
c6bf6d2d
SM
342 MAC_REG_GPIOCTL1,
343 MESSAGE_REQUEST_MACREG, 1, &tmp);
cbc06fb1 344
3ce54934 345 if (status != STATUS_SUCCESS)
cbc06fb1 346 return false;
cbc06fb1 347
d7f2d8f6 348 if ((tmp & GPIO3_DATA) == 0)
3ce54934 349 vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL1,
c6bf6d2d 350 GPIO3_INTMD);
d7f2d8f6 351 else
3ce54934 352 vnt_mac_reg_bits_off(priv, MAC_REG_GPIOCTL1,
c6bf6d2d 353 GPIO3_INTMD);
cbc06fb1
MP
354 }
355
3ce54934 356 vnt_mac_set_led(priv, LEDSTS_TMLEN, 0x38);
cbc06fb1 357
3ce54934 358 vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_SLOW);
cbc06fb1 359
3ce54934 360 vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL0, 0x01);
cbc06fb1 361
d7f2d8f6 362 vnt_radio_power_on(priv);
cbc06fb1 363
4e62dcc9 364 dev_dbg(&priv->usb->dev, "<----INIbInitAdapter Exit\n");
cbc06fb1
MP
365
366 return true;
92b96797
FB
367}
368
afc7ef64 369static void vnt_free_tx_bufs(struct vnt_private *priv)
8611a29a 370{
f2625c24
MP
371 struct vnt_usb_send_context *tx_context;
372 int ii;
373
03b7e354 374 for (ii = 0; ii < priv->num_tx_context; ii++) {
f7e4a8f4 375 tx_context = priv->tx_context[ii];
f2625c24 376 /* deallocate URBs */
30a05b39
MP
377 if (tx_context->urb) {
378 usb_kill_urb(tx_context->urb);
379 usb_free_urb(tx_context->urb);
f2625c24
MP
380 }
381
382 kfree(tx_context);
383 }
92b96797
FB
384}
385
0dd6e68a 386static void vnt_free_rx_bufs(struct vnt_private *priv)
8611a29a 387{
afc5eeb8 388 struct vnt_rcb *rcb;
115cac2e 389 int ii;
92b96797 390
6da4738f 391 for (ii = 0; ii < priv->num_rcb; ii++) {
8577011c 392 rcb = priv->rcb[ii];
8cffb3cf
MP
393 if (!rcb)
394 continue;
92b96797 395
afc5eeb8 396 /* deallocate URBs */
325de984
MP
397 if (rcb->urb) {
398 usb_kill_urb(rcb->urb);
399 usb_free_urb(rcb->urb);
afc5eeb8 400 }
92b96797 401
afc5eeb8
MP
402 /* deallocate skb */
403 if (rcb->skb)
404 dev_kfree_skb(rcb->skb);
afc5eeb8 405
8cffb3cf
MP
406 kfree(rcb);
407 }
92b96797
FB
408}
409
1c2fd56b 410static void vnt_free_int_bufs(struct vnt_private *priv)
8611a29a 411{
1506bf37 412 kfree(priv->int_buf.data_buf);
92b96797
FB
413}
414
ef484423 415static bool vnt_alloc_bufs(struct vnt_private *priv)
dd0a774f 416{
35491de7
MP
417 struct vnt_usb_send_context *tx_context;
418 struct vnt_rcb *rcb;
115cac2e 419 int ii;
92b96797 420
03b7e354 421 for (ii = 0; ii < priv->num_tx_context; ii++) {
f124a478 422 tx_context = kmalloc(sizeof(*tx_context), GFP_KERNEL);
27f31cf9 423 if (!tx_context)
35491de7 424 goto free_tx;
92b96797 425
f7e4a8f4 426 priv->tx_context[ii] = tx_context;
30a05b39 427 tx_context->priv = priv;
71d764ae 428 tx_context->pkt_no = ii;
35491de7
MP
429
430 /* allocate URBs */
3e0f86b3 431 tx_context->urb = usb_alloc_urb(0, GFP_KERNEL);
68d81dea 432 if (!tx_context->urb)
35491de7 433 goto free_tx;
92b96797 434
30a05b39 435 tx_context->in_use = false;
35491de7
MP
436 }
437
6da4738f 438 for (ii = 0; ii < priv->num_rcb; ii++) {
f124a478 439 priv->rcb[ii] = kzalloc(sizeof(*priv->rcb[ii]), GFP_KERNEL);
8577011c 440 if (!priv->rcb[ii]) {
8cffb3cf 441 dev_err(&priv->usb->dev,
c6bf6d2d 442 "failed to allocate rcb no %d\n", ii);
8cffb3cf
MP
443 goto free_rx_tx;
444 }
115cac2e 445
8577011c 446 rcb = priv->rcb[ii];
92b96797 447
325de984 448 rcb->priv = priv;
92b96797 449
35491de7 450 /* allocate URBs */
3e0f86b3 451 rcb->urb = usb_alloc_urb(0, GFP_KERNEL);
68d81dea 452 if (!rcb->urb)
35491de7 453 goto free_rx_tx;
92b96797 454
63b9907f 455 rcb->skb = dev_alloc_skb(priv->rx_buf_sz);
27f31cf9 456 if (!rcb->skb)
35491de7 457 goto free_rx_tx;
92b96797 458
325de984 459 rcb->in_use = false;
35491de7 460
8cffb3cf 461 /* submit rx urb */
2dc37af0 462 if (vnt_submit_rx_urb(priv, rcb))
8cffb3cf 463 goto free_rx_tx;
92b96797
FB
464 }
465
3e0f86b3 466 priv->interrupt_urb = usb_alloc_urb(0, GFP_KERNEL);
68d81dea 467 if (!priv->interrupt_urb)
35491de7 468 goto free_rx_tx;
92b96797 469
35491de7 470 priv->int_buf.data_buf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
27f31cf9 471 if (!priv->int_buf.data_buf) {
3d582487 472 usb_free_urb(priv->interrupt_urb);
35491de7
MP
473 goto free_rx_tx;
474 }
475
476 return true;
92b96797
FB
477
478free_rx_tx:
0dd6e68a 479 vnt_free_rx_bufs(priv);
92b96797
FB
480
481free_tx:
afc7ef64 482 vnt_free_tx_bufs(priv);
92b96797 483
e269fc2d 484 return false;
92b96797
FB
485}
486
db8f37fa 487static void vnt_tx_80211(struct ieee80211_hw *hw,
c6bf6d2d
SM
488 struct ieee80211_tx_control *control,
489 struct sk_buff *skb)
db8f37fa
MP
490{
491 struct vnt_private *priv = hw->priv;
492
b914b494 493 if (vnt_tx_packet(priv, skb))
db8f37fa 494 ieee80211_free_txskb(hw, skb);
db8f37fa
MP
495}
496
497static int vnt_start(struct ieee80211_hw *hw)
498{
499 struct vnt_private *priv = hw->priv;
500
501 priv->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
502
5699c0f4 503 if (!vnt_alloc_bufs(priv)) {
ef484423 504 dev_dbg(&priv->usb->dev, "vnt_alloc_bufs fail...\n");
db8f37fa
MP
505 return -ENOMEM;
506 }
507
2ab3d46d 508 clear_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags);
db8f37fa 509
500e1fb3 510 if (vnt_init_registers(priv) == false) {
db8f37fa
MP
511 dev_dbg(&priv->usb->dev, " init register fail\n");
512 goto free_all;
513 }
514
dc32190f
MP
515 if (vnt_key_init_table(priv))
516 goto free_all;
517
db8f37fa
MP
518 priv->int_interval = 1; /* bInterval is set to 1 */
519
62001939 520 vnt_int_start_interrupt(priv);
db8f37fa 521
db8f37fa
MP
522 ieee80211_wake_queues(hw);
523
524 return 0;
525
526free_all:
0dd6e68a 527 vnt_free_rx_bufs(priv);
afc7ef64 528 vnt_free_tx_bufs(priv);
1c2fd56b 529 vnt_free_int_bufs(priv);
db8f37fa 530
3d582487
MP
531 usb_kill_urb(priv->interrupt_urb);
532 usb_free_urb(priv->interrupt_urb);
db8f37fa
MP
533
534 return -ENOMEM;
535}
536
537static void vnt_stop(struct ieee80211_hw *hw)
538{
539 struct vnt_private *priv = hw->priv;
540 int i;
541
542 if (!priv)
543 return;
544
545 for (i = 0; i < MAX_KEY_TABLE; i++)
546 vnt_mac_disable_keyentry(priv, i);
547
548 /* clear all keys */
549 priv->key_entry_inuse = 0;
550
cbcc9a36 551 if (!test_bit(DEVICE_FLAGS_UNPLUG, &priv->flags))
db8f37fa
MP
552 vnt_mac_shutdown(priv);
553
554 ieee80211_stop_queues(hw);
555
4c3b0d45 556 set_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags);
db8f37fa
MP
557
558 cancel_delayed_work_sync(&priv->run_command_work);
db8f37fa 559
33a60b87 560 priv->cmd_running = false;
db8f37fa 561
afc7ef64 562 vnt_free_tx_bufs(priv);
0dd6e68a 563 vnt_free_rx_bufs(priv);
1c2fd56b 564 vnt_free_int_bufs(priv);
db8f37fa 565
3d582487
MP
566 usb_kill_urb(priv->interrupt_urb);
567 usb_free_urb(priv->interrupt_urb);
db8f37fa
MP
568}
569
570static int vnt_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
571{
572 struct vnt_private *priv = hw->priv;
573
574 priv->vif = vif;
575
576 switch (vif->type) {
577 case NL80211_IFTYPE_STATION:
578 break;
579 case NL80211_IFTYPE_ADHOC:
580 vnt_mac_reg_bits_off(priv, MAC_REG_RCR, RCR_UNICAST);
581
582 vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_ADHOC);
583
584 break;
585 case NL80211_IFTYPE_AP:
586 vnt_mac_reg_bits_off(priv, MAC_REG_RCR, RCR_UNICAST);
587
588 vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_AP);
589
590 break;
591 default:
592 return -EOPNOTSUPP;
593 }
594
595 priv->op_mode = vif->type;
596
1ecd083e
MP
597 vnt_set_bss_mode(priv);
598
db8f37fa
MP
599 /* LED blink on TX */
600 vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_INTER);
601
602 return 0;
603}
604
605static void vnt_remove_interface(struct ieee80211_hw *hw,
c6bf6d2d 606 struct ieee80211_vif *vif)
db8f37fa
MP
607{
608 struct vnt_private *priv = hw->priv;
609
610 switch (vif->type) {
611 case NL80211_IFTYPE_STATION:
612 break;
613 case NL80211_IFTYPE_ADHOC:
614 vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
615 vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
616 vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_ADHOC);
617 break;
618 case NL80211_IFTYPE_AP:
619 vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
620 vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
621 vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_AP);
622 break;
623 default:
624 break;
625 }
626
627 vnt_radio_power_off(priv);
628
629 priv->op_mode = NL80211_IFTYPE_UNSPECIFIED;
630
631 /* LED slow blink */
632 vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_SLOW);
db8f37fa
MP
633}
634
635static int vnt_config(struct ieee80211_hw *hw, u32 changed)
636{
637 struct vnt_private *priv = hw->priv;
638 struct ieee80211_conf *conf = &hw->conf;
db8f37fa
MP
639
640 if (changed & IEEE80211_CONF_CHANGE_PS) {
641 if (conf->flags & IEEE80211_CONF_PS)
642 vnt_enable_power_saving(priv, conf->listen_interval);
643 else
644 vnt_disable_power_saving(priv);
645 }
646
647 if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) ||
c6bf6d2d 648 (conf->flags & IEEE80211_CONF_OFFCHANNEL)) {
db8f37fa
MP
649 vnt_set_channel(priv, conf->chandef.chan->hw_value);
650
57fbcce3 651 if (conf->chandef.chan->band == NL80211_BAND_5GHZ)
c1260357 652 priv->bb_type = BB_TYPE_11A;
db8f37fa 653 else
c1260357 654 priv->bb_type = BB_TYPE_11G;
db8f37fa
MP
655 }
656
657 if (changed & IEEE80211_CONF_CHANGE_POWER) {
65df77e2 658 if (priv->bb_type == BB_TYPE_11B)
8b84c1da 659 priv->current_rate = RATE_1M;
db8f37fa 660 else
8b84c1da 661 priv->current_rate = RATE_54M;
db8f37fa 662
8b84c1da 663 vnt_rf_setpower(priv, priv->current_rate,
db8f37fa
MP
664 conf->chandef.chan->hw_value);
665 }
666
667 return 0;
668}
669
670static void vnt_bss_info_changed(struct ieee80211_hw *hw,
c6bf6d2d
SM
671 struct ieee80211_vif *vif,
672 struct ieee80211_bss_conf *conf, u32 changed)
db8f37fa
MP
673{
674 struct vnt_private *priv = hw->priv;
14c5e41f 675
db8f37fa
MP
676 priv->current_aid = conf->aid;
677
d309509f 678 if (changed & BSS_CHANGED_BSSID && conf->bssid)
db8f37fa
MP
679 vnt_mac_set_bssid_addr(priv, (u8 *)conf->bssid);
680
db8f37fa 681 if (changed & BSS_CHANGED_BASIC_RATES) {
93a73558 682 priv->basic_rates = conf->basic_rates;
db8f37fa
MP
683
684 vnt_update_top_rates(priv);
c1260357 685 vnt_set_bss_mode(priv);
db8f37fa
MP
686
687 dev_dbg(&priv->usb->dev, "basic rates %x\n", conf->basic_rates);
688 }
689
690 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
691 if (conf->use_short_preamble) {
692 vnt_mac_enable_barker_preamble_mode(priv);
98e93fe5 693 priv->preamble_type = true;
db8f37fa
MP
694 } else {
695 vnt_mac_disable_barker_preamble_mode(priv);
98e93fe5 696 priv->preamble_type = false;
db8f37fa
MP
697 }
698 }
699
700 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
701 if (conf->use_cts_prot)
702 vnt_mac_enable_protect_mode(priv);
703 else
704 vnt_mac_disable_protect_mode(priv);
705 }
706
707 if (changed & BSS_CHANGED_ERP_SLOT) {
708 if (conf->use_short_slot)
a641c9ec 709 priv->short_slot_time = true;
db8f37fa 710 else
a641c9ec 711 priv->short_slot_time = false;
db8f37fa 712
3c956cc0 713 vnt_set_short_slot_time(priv);
66e496c4 714 vnt_update_ifs(priv);
c37cbd37 715 vnt_set_vga_gain_offset(priv, priv->bb_vga[0]);
80dcc0ae 716 vnt_update_pre_ed_threshold(priv, false);
db8f37fa
MP
717 }
718
719 if (changed & BSS_CHANGED_TXPOWER)
8b84c1da 720 vnt_rf_setpower(priv, priv->current_rate,
c6bf6d2d 721 conf->chandef.chan->hw_value);
db8f37fa
MP
722
723 if (changed & BSS_CHANGED_BEACON_ENABLED) {
724 dev_dbg(&priv->usb->dev,
c6bf6d2d 725 "Beacon enable %d\n", conf->enable_beacon);
db8f37fa
MP
726
727 if (conf->enable_beacon) {
728 vnt_beacon_enable(priv, vif, conf);
729
730 vnt_mac_reg_bits_on(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
731 } else {
732 vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
733 }
734 }
c1515879
MP
735
736 if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BEACON_INFO) &&
737 priv->op_mode != NL80211_IFTYPE_AP) {
738 if (conf->assoc && conf->beacon_rate) {
739 vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL,
740 TFTCTL_TSFCNTREN);
741
742 vnt_adjust_tsf(priv, conf->beacon_rate->hw_value,
743 conf->sync_tsf, priv->current_tsf);
744
745 vnt_mac_set_beacon_interval(priv, conf->beacon_int);
746
747 vnt_reset_next_tbtt(priv, conf->beacon_int);
748 } else {
749 vnt_clear_current_tsf(priv);
750
751 vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL,
752 TFTCTL_TSFCNTREN);
753 }
754 }
db8f37fa
MP
755}
756
757static u64 vnt_prepare_multicast(struct ieee80211_hw *hw,
c6bf6d2d 758 struct netdev_hw_addr_list *mc_list)
db8f37fa
MP
759{
760 struct vnt_private *priv = hw->priv;
761 struct netdev_hw_addr *ha;
762 u64 mc_filter = 0;
763 u32 bit_nr = 0;
764
765 netdev_hw_addr_list_for_each(ha, mc_list) {
766 bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
767
768 mc_filter |= 1ULL << (bit_nr & 0x3f);
769 }
770
771 priv->mc_list_count = mc_list->count;
772
773 return mc_filter;
774}
775
776static void vnt_configure(struct ieee80211_hw *hw,
c6bf6d2d
SM
777 unsigned int changed_flags,
778 unsigned int *total_flags, u64 multicast)
db8f37fa
MP
779{
780 struct vnt_private *priv = hw->priv;
781 u8 rx_mode = 0;
782 int rc;
783
df140465 784 *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC;
db8f37fa
MP
785
786 rc = vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_RCR,
c6bf6d2d 787 MESSAGE_REQUEST_MACREG, sizeof(u8), &rx_mode);
db8f37fa
MP
788
789 if (!rc)
790 rx_mode = RCR_MULTICAST | RCR_BROADCAST;
791
792 dev_dbg(&priv->usb->dev, "rx mode in = %x\n", rx_mode);
793
db8f37fa
MP
794 if (changed_flags & FIF_ALLMULTI) {
795 if (*total_flags & FIF_ALLMULTI) {
796 if (priv->mc_list_count > 2)
797 vnt_mac_set_filter(priv, ~0);
798 else
799 vnt_mac_set_filter(priv, multicast);
800
801 rx_mode |= RCR_MULTICAST | RCR_BROADCAST;
802 } else {
803 rx_mode &= ~(RCR_MULTICAST | RCR_BROADCAST);
804 }
db8f37fa
MP
805 }
806
807 if (changed_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)) {
808 if (*total_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC))
809 rx_mode &= ~RCR_BSSID;
810 else
811 rx_mode |= RCR_BSSID;
812 }
813
814 vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_RCR, rx_mode);
815
816 dev_dbg(&priv->usb->dev, "rx mode out= %x\n", rx_mode);
db8f37fa
MP
817}
818
819static int vnt_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
c6bf6d2d
SM
820 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
821 struct ieee80211_key_conf *key)
db8f37fa
MP
822{
823 struct vnt_private *priv = hw->priv;
824
825 switch (cmd) {
826 case SET_KEY:
827 if (vnt_set_keys(hw, sta, vif, key))
828 return -EOPNOTSUPP;
829 break;
830 case DISABLE_KEY:
831 if (test_bit(key->hw_key_idx, &priv->key_entry_inuse))
832 clear_bit(key->hw_key_idx, &priv->key_entry_inuse);
833 default:
834 break;
835 }
836
837 return 0;
838}
839
a344d677
JB
840static void vnt_sw_scan_start(struct ieee80211_hw *hw,
841 struct ieee80211_vif *vif,
842 const u8 *addr)
db8f37fa
MP
843{
844 struct vnt_private *priv = hw->priv;
845
846 /* Set max sensitivity*/
80dcc0ae 847 vnt_update_pre_ed_threshold(priv, true);
db8f37fa
MP
848}
849
a344d677
JB
850static void vnt_sw_scan_complete(struct ieee80211_hw *hw,
851 struct ieee80211_vif *vif)
db8f37fa
MP
852{
853 struct vnt_private *priv = hw->priv;
854
855 /* Return sensitivity to channel level*/
80dcc0ae 856 vnt_update_pre_ed_threshold(priv, false);
db8f37fa
MP
857}
858
1786384e 859static int vnt_get_stats(struct ieee80211_hw *hw,
c6bf6d2d 860 struct ieee80211_low_level_stats *stats)
1786384e
MP
861{
862 struct vnt_private *priv = hw->priv;
863
864 memcpy(stats, &priv->low_stats, sizeof(*stats));
865
866 return 0;
867}
868
db8f37fa
MP
869static u64 vnt_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
870{
871 struct vnt_private *priv = hw->priv;
872
113f0b91 873 return priv->current_tsf;
db8f37fa
MP
874}
875
876static void vnt_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
877 u64 tsf)
878{
879 struct vnt_private *priv = hw->priv;
880
881 vnt_update_next_tbtt(priv, tsf, vif->bss_conf.beacon_int);
882}
883
884static void vnt_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
885{
886 struct vnt_private *priv = hw->priv;
887
888 vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
889
890 vnt_clear_current_tsf(priv);
891}
892
893static const struct ieee80211_ops vnt_mac_ops = {
894 .tx = vnt_tx_80211,
895 .start = vnt_start,
896 .stop = vnt_stop,
897 .add_interface = vnt_add_interface,
898 .remove_interface = vnt_remove_interface,
899 .config = vnt_config,
900 .bss_info_changed = vnt_bss_info_changed,
901 .prepare_multicast = vnt_prepare_multicast,
902 .configure_filter = vnt_configure,
903 .set_key = vnt_set_key,
904 .sw_scan_start = vnt_sw_scan_start,
905 .sw_scan_complete = vnt_sw_scan_complete,
1786384e 906 .get_stats = vnt_get_stats,
db8f37fa
MP
907 .get_tsf = vnt_get_tsf,
908 .set_tsf = vnt_set_tsf,
909 .reset_tsf = vnt_reset_tsf,
910};
911
912int vnt_init(struct vnt_private *priv)
913{
500e1fb3 914 if (!(vnt_init_registers(priv)))
db8f37fa
MP
915 return -EAGAIN;
916
41e8321a 917 SET_IEEE80211_PERM_ADDR(priv->hw, priv->permanent_net_addr);
db8f37fa 918
110f97e9
MP
919 vnt_init_bands(priv);
920
db8f37fa
MP
921 if (ieee80211_register_hw(priv->hw))
922 return -ENODEV;
923
30816f83
MP
924 priv->mac_hw = true;
925
ba911c9b
MP
926 vnt_radio_power_off(priv);
927
db8f37fa
MP
928 return 0;
929}
930
931static int
932vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
933{
934 struct usb_device *udev;
935 struct vnt_private *priv;
936 struct ieee80211_hw *hw;
937 struct wiphy *wiphy;
938 int rc = 0;
939
940 udev = usb_get_dev(interface_to_usbdev(intf));
941
942 dev_notice(&udev->dev, "%s Ver. %s\n",
c6bf6d2d 943 DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
db8f37fa 944 dev_notice(&udev->dev,
c6bf6d2d 945 "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
db8f37fa
MP
946
947 hw = ieee80211_alloc_hw(sizeof(struct vnt_private), &vnt_mac_ops);
948 if (!hw) {
949 dev_err(&udev->dev, "could not register ieee80211_hw\n");
20ff1418 950 rc = -ENOMEM;
db8f37fa
MP
951 goto err_nomem;
952 }
953
954 priv = hw->priv;
955 priv->hw = hw;
956 priv->usb = udev;
957
7665cf21 958 vnt_set_options(priv);
db8f37fa
MP
959
960 spin_lock_init(&priv->lock);
961 mutex_init(&priv->usb_lock);
962
592365ae 963 INIT_DELAYED_WORK(&priv->run_command_work, vnt_run_command);
db8f37fa 964
db8f37fa
MP
965 usb_set_intfdata(intf, priv);
966
967 wiphy = priv->hw->wiphy;
968
969 wiphy->frag_threshold = FRAG_THRESH_DEF;
970 wiphy->rts_threshold = RTS_THRESH_DEF;
971 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
972 BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
973
30686bf7
JB
974 ieee80211_hw_set(priv->hw, TIMING_BEACON_ONLY);
975 ieee80211_hw_set(priv->hw, SIGNAL_DBM);
976 ieee80211_hw_set(priv->hw, RX_INCLUDES_FCS);
977 ieee80211_hw_set(priv->hw, REPORTS_TX_ACK_STATUS);
49a315bf 978 ieee80211_hw_set(priv->hw, SUPPORTS_PS);
db8f37fa 979
db8f37fa
MP
980 priv->hw->max_signal = 100;
981
982 SET_IEEE80211_DEV(priv->hw, &intf->dev);
983
00916cfc
CL
984 rc = usb_reset_device(priv->usb);
985 if (rc)
986 dev_warn(&priv->usb->dev,
987 "%s reset fail status=%d\n", __func__, rc);
db8f37fa 988
2ab3d46d 989 clear_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags);
68cc161e 990 vnt_reset_command_timer(priv);
30816f83 991
57981a65 992 vnt_schedule_command(priv, WLAN_CMD_INIT_MAC80211);
30816f83 993
db8f37fa
MP
994 return 0;
995
996err_nomem:
997 usb_put_dev(udev);
998
999 return rc;
1000}
1001
0d7fe14f 1002static void vt6656_disconnect(struct usb_interface *intf)
92b96797 1003{
db8f37fa 1004 struct vnt_private *priv = usb_get_intfdata(intf);
92b96797 1005
db8f37fa 1006 if (!priv)
6cda24f5 1007 return;
92b96797 1008
30816f83
MP
1009 if (priv->mac_hw)
1010 ieee80211_unregister_hw(priv->hw);
db8f37fa 1011
92b96797 1012 usb_set_intfdata(intf, NULL);
6cda24f5 1013 usb_put_dev(interface_to_usbdev(intf));
92b96797 1014
4c3b0d45 1015 set_bit(DEVICE_FLAGS_UNPLUG, &priv->flags);
92b96797 1016
db8f37fa 1017 ieee80211_free_hw(priv->hw);
92b96797
FB
1018}
1019
db8f37fa
MP
1020#ifdef CONFIG_PM
1021
1022static int vt6656_suspend(struct usb_interface *intf, pm_message_t message)
1023{
1024 return 0;
1025}
1026
1027static int vt6656_resume(struct usb_interface *intf)
1028{
1029 return 0;
1030}
1031
1032#endif /* CONFIG_PM */
1033
26e5b65b 1034MODULE_DEVICE_TABLE(usb, vt6656_table);
92b96797 1035
26e5b65b
AM
1036static struct usb_driver vt6656_driver = {
1037 .name = DEVICE_NAME,
1038 .probe = vt6656_probe,
1039 .disconnect = vt6656_disconnect,
1040 .id_table = vt6656_table,
92b96797 1041#ifdef CONFIG_PM
26e5b65b
AM
1042 .suspend = vt6656_suspend,
1043 .resume = vt6656_resume,
1044#endif /* CONFIG_PM */
92b96797
FB
1045};
1046
bac2c126 1047module_usb_driver(vt6656_driver);