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