linux/drivers/staging/vt6656/baseband.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 * Purpose: Implement functions to access baseband
   7 *
   8 * Author: Jerry Chen
   9 *
  10 * Date: Jun. 5, 2002
  11 *
  12 * Functions:
  13 *      vnt_get_frame_time      - Calculate data frame transmitting time
  14 *      vnt_get_phy_field       - Calculate PhyLength, PhyService and Phy
  15 *                                Signal parameter for baseband Tx
  16 *      vnt_vt3184_init         - VIA VT3184 baseband chip init code
  17 *
  18 * Revision History:
  19 *
  20 *
  21 */
  22
  23#include <linux/bits.h>
  24#include <linux/errno.h>
  25#include <linux/kernel.h>
  26#include "device.h"
  27#include "mac.h"
  28#include "baseband.h"
  29#include "rf.h"
  30#include "usbpipe.h"
  31
  32static const u8 vnt_vt3184_agc[] = {
  33        0x00, 0x00, 0x02, 0x02, 0x04, 0x04, 0x06, 0x06,
  34        0x08, 0x08, 0x0a, 0x0a, 0x0c, 0x0c, 0x0e, 0x0e, /* 0x0f */
  35        0x10, 0x10, 0x12, 0x12, 0x14, 0x14, 0x16, 0x16,
  36        0x18, 0x18, 0x1a, 0x1a, 0x1c, 0x1c, 0x1e, 0x1e, /* 0x1f */
  37        0x20, 0x20, 0x22, 0x22, 0x24, 0x24, 0x26, 0x26,
  38        0x28, 0x28, 0x2a, 0x2a, 0x2c, 0x2c, 0x2e, 0x2e, /* 0x2f */
  39        0x30, 0x30, 0x32, 0x32, 0x34, 0x34, 0x36, 0x36,
  40        0x38, 0x38, 0x3a, 0x3a, 0x3c, 0x3c, 0x3e, 0x3e  /* 0x3f */
  41};
  42
  43static u8 vnt_vt3184_al2230[] = {
  44        0x31, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
  45        0x70, 0x45, 0x2a, 0x76, 0x00, 0x00, 0x80, 0x00, /* 0x0f */
  46        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  47        0x00, 0x00, 0x00, 0x8e, 0x0a, 0x00, 0x00, 0x00, /* 0x1f */
  48        0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00,
  49        0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x0c, /* 0x2f */
  50        0x26, 0x5b, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa,
  51        0xff, 0xff, 0x79, 0x00, 0x00, 0x0b, 0x48, 0x04, /* 0x3f */
  52        0x00, 0x08, 0x00, 0x08, 0x08, 0x14, 0x05, 0x09,
  53        0x00, 0x00, 0x00, 0x00, 0x09, 0x73, 0x00, 0xc5, /* 0x4f */
  54        0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  55        0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5f */
  56        0xe4, 0x80, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0a,
  57        0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* 0x6f */
  58        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  59        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7f */
  60        0x8c, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
  61        0x08, 0x00, 0x1f, 0xb7, 0x88, 0x47, 0xaa, 0x00, /* 0x8f */
  62        0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xeb,
  63        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x9f */
  64        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
  65        0x18, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x18, /* 0xaf */
  66        0x38, 0x30, 0x00, 0x00, 0xff, 0x0f, 0xe4, 0xe2,
  67        0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, /* 0xbf */
  68        0x18, 0x20, 0x07, 0x18, 0xff, 0xff, 0x0e, 0x0a,
  69        0x0e, 0x00, 0x82, 0xa7, 0x3c, 0x10, 0x30, 0x05, /* 0xcf */
  70        0x40, 0x12, 0x00, 0x00, 0x10, 0x28, 0x80, 0x2a,
  71        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf */
  72        0x00, 0xf3, 0x00, 0x00, 0x00, 0x10, 0x00, 0x12,
  73        0x00, 0xf4, 0x00, 0xff, 0x79, 0x20, 0x30, 0x05, /* 0xef */
  74        0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  75        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  /* 0xff */
  76};
  77
  78/* {{RobertYu:20060515, new BB setting for VT3226D0 */
  79static const u8 vnt_vt3184_vt3226d0[] = {
  80        0x31, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
  81        0x70, 0x45, 0x2a, 0x76, 0x00, 0x00, 0x80, 0x00, /* 0x0f */
  82        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  83        0x00, 0x00, 0x00, 0x8e, 0x0a, 0x00, 0x00, 0x00, /* 0x1f */
  84        0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00,
  85        0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x0c, /* 0x2f */
  86        0x26, 0x5b, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa,
  87        0xff, 0xff, 0x79, 0x00, 0x00, 0x0b, 0x48, 0x04, /* 0x3f */
  88        0x00, 0x08, 0x00, 0x08, 0x08, 0x14, 0x05, 0x09,
  89        0x00, 0x00, 0x00, 0x00, 0x09, 0x73, 0x00, 0xc5, /* 0x4f */
  90        0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  91        0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5f */
  92        0xe4, 0x80, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0a,
  93        0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* 0x6f */
  94        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  95        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7f */
  96        0x8c, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
  97        0x08, 0x00, 0x1f, 0xb7, 0x88, 0x47, 0xaa, 0x00, /* 0x8f */
  98        0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xeb,
  99        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x9f */
 100        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
 101        0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, /* 0xaf */
 102        0x38, 0x30, 0x00, 0x00, 0xff, 0x0f, 0xe4, 0xe2,
 103        0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, /* 0xbf */
 104        0x18, 0x20, 0x07, 0x18, 0xff, 0xff, 0x10, 0x0a,
 105        0x0e, 0x00, 0x84, 0xa7, 0x3c, 0x10, 0x24, 0x05, /* 0xcf */
 106        0x40, 0x12, 0x00, 0x00, 0x10, 0x28, 0x80, 0x2a,
 107        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf */
 108        0x00, 0xf3, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10,
 109        0x00, 0xf4, 0x00, 0xff, 0x79, 0x20, 0x30, 0x08, /* 0xef */
 110        0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 111        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  /* 0xff */
 112};
 113
 114struct vnt_threshold {
 115        u8 bb_pre_ed_rssi;
 116        u8 cr_201;
 117        u8 cr_206;
 118};
 119
 120static const struct vnt_threshold al2230_vnt_threshold[] = {
 121        {0, 0x00, 0x30},        /* Max sensitivity */
 122        {68, 0x00, 0x36},
 123        {67, 0x00, 0x43},
 124        {66, 0x00, 0x51},
 125        {65, 0x00, 0x62},
 126        {64, 0x00, 0x79},
 127        {63, 0x00, 0x93},
 128        {62, 0x00, 0xb9},
 129        {61, 0x00, 0xe3},
 130        {60, 0x01, 0x18},
 131        {59, 0x01, 0x54},
 132        {58, 0x01, 0xa0},
 133        {57, 0x02, 0x20},
 134        {56, 0x02, 0xa0},
 135        {55, 0x03, 0x00},
 136        {53, 0x06, 0x00},
 137        {51, 0x09, 0x00},
 138        {49, 0x0e, 0x00},
 139        {47, 0x15, 0x00},
 140        {46, 0x1a, 0x00},
 141        {45, 0xff, 0x00}
 142};
 143
 144static const struct vnt_threshold vt3226_vnt_threshold[] = {
 145        {0, 0x00, 0x24},        /* Max sensitivity */
 146        {68, 0x00, 0x2d},
 147        {67, 0x00, 0x36},
 148        {66, 0x00, 0x43},
 149        {65, 0x00, 0x52},
 150        {64, 0x00, 0x68},
 151        {63, 0x00, 0x80},
 152        {62, 0x00, 0x9c},
 153        {61, 0x00, 0xc0},
 154        {60, 0x00, 0xea},
 155        {59, 0x01, 0x30},
 156        {58, 0x01, 0x70},
 157        {57, 0x01, 0xb0},
 158        {56, 0x02, 0x30},
 159        {55, 0x02, 0xc0},
 160        {53, 0x04, 0x00},
 161        {51, 0x07, 0x00},
 162        {49, 0x0a, 0x00},
 163        {47, 0x11, 0x00},
 164        {45, 0x18, 0x00},
 165        {43, 0x26, 0x00},
 166        {42, 0x36, 0x00},
 167        {41, 0xff, 0x00}
 168};
 169
 170static const struct vnt_threshold vt3342_vnt_threshold[] = {
 171        {0, 0x00, 0x38},        /* Max sensitivity */
 172        {66, 0x00, 0x43},
 173        {65, 0x00, 0x52},
 174        {64, 0x00, 0x68},
 175        {63, 0x00, 0x80},
 176        {62, 0x00, 0x9c},
 177        {61, 0x00, 0xc0},
 178        {60, 0x00, 0xea},
 179        {59, 0x01, 0x30},
 180        {58, 0x01, 0x70},
 181        {57, 0x01, 0xb0},
 182        {56, 0x02, 0x30},
 183        {55, 0x02, 0xc0},
 184        {53, 0x04, 0x00},
 185        {51, 0x07, 0x00},
 186        {49, 0x0a, 0x00},
 187        {47, 0x11, 0x00},
 188        {45, 0x18, 0x00},
 189        {43, 0x26, 0x00},
 190        {42, 0x36, 0x00},
 191        {41, 0xff, 0x00}
 192};
 193
 194/*
 195 * Description: Set Antenna mode
 196 *
 197 * Parameters:
 198 *  In:
 199 *      priv            - Device Structure
 200 *      antenna_mode    - Antenna Mode
 201 *  Out:
 202 *      none
 203 *
 204 * Return Value: none
 205 *
 206 */
 207int vnt_set_antenna_mode(struct vnt_private *priv, u8 antenna_mode)
 208{
 209        switch (antenna_mode) {
 210        case ANT_TXA:
 211        case ANT_TXB:
 212                break;
 213        case ANT_RXA:
 214                priv->bb_rx_conf &= 0xFC;
 215                break;
 216        case ANT_RXB:
 217                priv->bb_rx_conf &= 0xFE;
 218                priv->bb_rx_conf |= 0x02;
 219                break;
 220        }
 221
 222        return vnt_control_out(priv, MESSAGE_TYPE_SET_ANTMD,
 223                               (u16)antenna_mode, 0, 0, NULL);
 224}
 225
 226/*
 227 * Description: Set Antenna mode
 228 *
 229 * Parameters:
 230 *  In:
 231 *      pDevice          - Device Structure
 232 *      byAntennaMode    - Antenna Mode
 233 *  Out:
 234 *      none
 235 *
 236 * Return Value: none
 237 *
 238 */
 239
 240int vnt_vt3184_init(struct vnt_private *priv)
 241{
 242        int ret;
 243        u16 length;
 244        u8 *addr = NULL;
 245        const u8 *c_addr;
 246        u8 data;
 247
 248        ret = vnt_control_in(priv, MESSAGE_TYPE_READ, 0, MESSAGE_REQUEST_EEPROM,
 249                             EEP_MAX_CONTEXT_SIZE, priv->eeprom);
 250        if (ret)
 251                goto end;
 252
 253        priv->rf_type = priv->eeprom[EEP_OFS_RFTYPE];
 254
 255        dev_dbg(&priv->usb->dev, "RF Type %d\n", priv->rf_type);
 256
 257        if ((priv->rf_type == RF_AL2230) ||
 258            (priv->rf_type == RF_AL2230S) ||
 259            (priv->rf_type == RF_AIROHA7230)) {
 260                priv->bb_rx_conf = vnt_vt3184_al2230[10];
 261                length = sizeof(vnt_vt3184_al2230);
 262                addr = vnt_vt3184_al2230;
 263
 264                if (priv->rf_type == RF_AIROHA7230)
 265                        addr[0xd7] = 0x06;
 266
 267                priv->bb_vga[0] = 0x1c;
 268                priv->bb_vga[1] = 0x10;
 269                priv->bb_vga[2] = 0x0;
 270                priv->bb_vga[3] = 0x0;
 271
 272        } else if ((priv->rf_type == RF_VT3226) ||
 273                   (priv->rf_type == RF_VT3226D0) ||
 274                   (priv->rf_type == RF_VT3342A0)) {
 275                priv->bb_rx_conf = vnt_vt3184_vt3226d0[10];
 276                length = sizeof(vnt_vt3184_vt3226d0);
 277                c_addr = vnt_vt3184_vt3226d0;
 278
 279                priv->bb_vga[0] = 0x20;
 280                priv->bb_vga[1] = 0x10;
 281                priv->bb_vga[2] = 0x0;
 282                priv->bb_vga[3] = 0x0;
 283
 284                /* Fix VT3226 DFC system timing issue */
 285                ret = vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL2,
 286                                          SOFTPWRCTL_RFLEOPT);
 287                if (ret)
 288                        goto end;
 289        } else {
 290                goto end;
 291        }
 292
 293        if (addr)
 294                c_addr = addr;
 295
 296        ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE,
 297                                     MESSAGE_REQUEST_BBREG, length, c_addr);
 298        if (ret)
 299                goto end;
 300
 301        ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, 0,
 302                              MESSAGE_REQUEST_BBAGC,
 303                              sizeof(vnt_vt3184_agc), vnt_vt3184_agc);
 304        if (ret)
 305                goto end;
 306
 307        if ((priv->rf_type == RF_VT3226) ||
 308            (priv->rf_type == RF_VT3342A0) ||
 309            (priv->rf_type == RF_VT3226D0)) {
 310                data = (priv->rf_type == RF_VT3226D0) ? 0x11 : 0x23;
 311
 312                ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG,
 313                                         MAC_REG_ITRTMSET, data);
 314                if (ret)
 315                        goto end;
 316
 317                ret = vnt_mac_reg_bits_on(priv, MAC_REG_PAPEDELAY, BIT(0));
 318                if (ret)
 319                        goto end;
 320        }
 321
 322        ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x04, 0x7f);
 323        if (ret)
 324                goto end;
 325
 326        ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0x01);
 327        if (ret)
 328                goto end;
 329
 330        ret = vnt_rf_table_download(priv);
 331        if (ret)
 332                goto end;
 333
 334        /* Fix for TX USB resets from vendors driver */
 335        ret = vnt_control_in(priv, MESSAGE_TYPE_READ, USB_REG4,
 336                             MESSAGE_REQUEST_MEM, sizeof(data), &data);
 337        if (ret)
 338                goto end;
 339
 340        data |= 0x2;
 341
 342        ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, USB_REG4,
 343                              MESSAGE_REQUEST_MEM, sizeof(data), &data);
 344
 345end:
 346        return ret;
 347}
 348
 349/*
 350 * Description: Set ShortSlotTime mode
 351 *
 352 * Parameters:
 353 *  In:
 354 *      priv    - Device Structure
 355 *  Out:
 356 *      none
 357 *
 358 * Return Value: none
 359 *
 360 */
 361int vnt_set_short_slot_time(struct vnt_private *priv)
 362{
 363        int ret = 0;
 364        u8 bb_vga = 0;
 365
 366        if (priv->short_slot_time)
 367                priv->bb_rx_conf &= 0xdf;
 368        else
 369                priv->bb_rx_conf |= 0x20;
 370
 371        ret = vnt_control_in_u8(priv, MESSAGE_REQUEST_BBREG, 0xe7, &bb_vga);
 372        if (ret)
 373                return ret;
 374
 375        if (bb_vga == priv->bb_vga[0])
 376                priv->bb_rx_conf |= 0x20;
 377
 378        return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a,
 379                                  priv->bb_rx_conf);
 380}
 381
 382int vnt_set_vga_gain_offset(struct vnt_private *priv, u8 data)
 383{
 384        int ret;
 385
 386        ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xE7, data);
 387        if (ret)
 388                return ret;
 389
 390        /* patch for 3253B0 Baseband with Cardbus module */
 391        if (priv->short_slot_time)
 392                priv->bb_rx_conf &= 0xdf; /* 1101 1111 */
 393        else
 394                priv->bb_rx_conf |= 0x20; /* 0010 0000 */
 395
 396        return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a,
 397                                  priv->bb_rx_conf);
 398}
 399
 400/*
 401 * Description: vnt_set_deep_sleep
 402 *
 403 * Parameters:
 404 *  In:
 405 *      priv    - Device Structure
 406 *  Out:
 407 *      none
 408 *
 409 * Return Value: none
 410 *
 411 */
 412int vnt_set_deep_sleep(struct vnt_private *priv)
 413{
 414        int ret = 0;
 415
 416        /* CR12 */
 417        ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0c, 0x17);
 418        if (ret)
 419                return ret;
 420
 421        /* CR13 */
 422        return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0xB9);
 423}
 424
 425int vnt_exit_deep_sleep(struct vnt_private *priv)
 426{
 427        int ret = 0;
 428
 429        /* CR12 */
 430        ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0c, 0x00);
 431        if (ret)
 432                return ret;
 433
 434        /* CR13 */
 435        return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0x01);
 436}
 437
 438int vnt_update_pre_ed_threshold(struct vnt_private *priv, int scanning)
 439{
 440        const struct vnt_threshold *threshold = NULL;
 441        u8 length;
 442        u8 cr_201, cr_206;
 443        u8 ed_inx;
 444        int ret;
 445
 446        switch (priv->rf_type) {
 447        case RF_AL2230:
 448        case RF_AL2230S:
 449        case RF_AIROHA7230:
 450                threshold = al2230_vnt_threshold;
 451                length = ARRAY_SIZE(al2230_vnt_threshold);
 452                break;
 453
 454        case RF_VT3226:
 455        case RF_VT3226D0:
 456                threshold = vt3226_vnt_threshold;
 457                length = ARRAY_SIZE(vt3226_vnt_threshold);
 458                break;
 459
 460        case RF_VT3342A0:
 461                threshold = vt3342_vnt_threshold;
 462                length = ARRAY_SIZE(vt3342_vnt_threshold);
 463                break;
 464        }
 465
 466        if (!threshold)
 467                return -EINVAL;
 468
 469        for (ed_inx = scanning ? 0 : length - 1; ed_inx > 0; ed_inx--) {
 470                if (priv->bb_pre_ed_rssi <= threshold[ed_inx].bb_pre_ed_rssi)
 471                        break;
 472        }
 473
 474        cr_201 = threshold[ed_inx].cr_201;
 475        cr_206 = threshold[ed_inx].cr_206;
 476
 477        if (ed_inx == priv->bb_pre_ed_index && !scanning)
 478                return 0;
 479
 480        priv->bb_pre_ed_index = ed_inx;
 481
 482        dev_dbg(&priv->usb->dev, "%s bb_pre_ed_rssi %d\n",
 483                __func__, priv->bb_pre_ed_rssi);
 484
 485        ret = vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xc9, cr_201);
 486        if (ret)
 487                return ret;
 488
 489        return vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xce, cr_206);
 490}
 491
 492