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