Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
0004  * All rights reserved.
0005  *
0006  * Purpose: rf function code
0007  *
0008  * Author: Jerry Chen
0009  *
0010  * Date: Feb. 19, 2004
0011  *
0012  * Functions:
0013  *  vnt_rf_write_embedded   - Embedded write RF register via MAC
0014  *
0015  * Revision History:
0016  *  RF_VT3226: RobertYu:20051111, VT3226C0 and before
0017  *  RF_VT3226D0: RobertYu:20051228
0018  *  RF_VT3342A0: RobertYu:20060609
0019  *
0020  */
0021 
0022 #include <linux/errno.h>
0023 #include "mac.h"
0024 #include "rf.h"
0025 #include "baseband.h"
0026 #include "usbpipe.h"
0027 
0028 #define CB_AL2230_INIT_SEQ    15
0029 #define CB_AL7230_INIT_SEQ    16
0030 #define CB_VT3226_INIT_SEQ    11
0031 #define CB_VT3342_INIT_SEQ    13
0032 
0033 static u8 al2230_init_table[CB_AL2230_INIT_SEQ][3] = {
0034     {0x03, 0xf7, 0x90},
0035     {0x03, 0x33, 0x31},
0036     {0x01, 0xb8, 0x02},
0037     {0x00, 0xff, 0xf3},
0038     {0x00, 0x05, 0xa4},
0039     {0x0f, 0x4d, 0xc5},
0040     {0x08, 0x05, 0xb6},
0041     {0x01, 0x47, 0xc7},
0042     {0x00, 0x06, 0x88},
0043     {0x04, 0x03, 0xb9},
0044     {0x00, 0xdb, 0xba},
0045     {0x00, 0x09, 0x9b},
0046     {0x0b, 0xdf, 0xfc},
0047     {0x00, 0x00, 0x0d},
0048     {0x00, 0x58, 0x0f}
0049 };
0050 
0051 static u8 al2230_channel_table0[CB_MAX_CHANNEL_24G][3] = {
0052     {0x03, 0xf7, 0x90},
0053     {0x03, 0xf7, 0x90},
0054     {0x03, 0xe7, 0x90},
0055     {0x03, 0xe7, 0x90},
0056     {0x03, 0xf7, 0xa0},
0057     {0x03, 0xf7, 0xa0},
0058     {0x03, 0xe7, 0xa0},
0059     {0x03, 0xe7, 0xa0},
0060     {0x03, 0xf7, 0xb0},
0061     {0x03, 0xf7, 0xb0},
0062     {0x03, 0xe7, 0xb0},
0063     {0x03, 0xe7, 0xb0},
0064     {0x03, 0xf7, 0xc0},
0065     {0x03, 0xe7, 0xc0}
0066 };
0067 
0068 static u8 al2230_channel_table1[CB_MAX_CHANNEL_24G][3] = {
0069     {0x03, 0x33, 0x31},
0070     {0x0b, 0x33, 0x31},
0071     {0x03, 0x33, 0x31},
0072     {0x0b, 0x33, 0x31},
0073     {0x03, 0x33, 0x31},
0074     {0x0b, 0x33, 0x31},
0075     {0x03, 0x33, 0x31},
0076     {0x0b, 0x33, 0x31},
0077     {0x03, 0x33, 0x31},
0078     {0x0b, 0x33, 0x31},
0079     {0x03, 0x33, 0x31},
0080     {0x0b, 0x33, 0x31},
0081     {0x03, 0x33, 0x31},
0082     {0x06, 0x66, 0x61}
0083 };
0084 
0085 static u8 vt3226_init_table[CB_VT3226_INIT_SEQ][3] = {
0086     {0x03, 0xff, 0x80},
0087     {0x02, 0x82, 0xa1},
0088     {0x03, 0xc6, 0xa2},
0089     {0x01, 0x97, 0x93},
0090     {0x03, 0x66, 0x64},
0091     {0x00, 0x61, 0xa5},
0092     {0x01, 0x7b, 0xd6},
0093     {0x00, 0x80, 0x17},
0094     {0x03, 0xf8, 0x08},
0095     {0x00, 0x02, 0x39},
0096     {0x02, 0x00, 0x2a}
0097 };
0098 
0099 static u8 vt3226d0_init_table[CB_VT3226_INIT_SEQ][3] = {
0100     {0x03, 0xff, 0x80},
0101     {0x03, 0x02, 0x21},
0102     {0x03, 0xc6, 0xa2},
0103     {0x01, 0x97, 0x93},
0104     {0x03, 0x66, 0x64},
0105     {0x00, 0x71, 0xa5},
0106     {0x01, 0x15, 0xc6},
0107     {0x01, 0x2e, 0x07},
0108     {0x00, 0x58, 0x08},
0109     {0x00, 0x02, 0x79},
0110     {0x02, 0x01, 0xaa}
0111 };
0112 
0113 static u8 vt3226_channel_table0[CB_MAX_CHANNEL_24G][3] = {
0114     {0x01, 0x97, 0x83},
0115     {0x01, 0x97, 0x83},
0116     {0x01, 0x97, 0x93},
0117     {0x01, 0x97, 0x93},
0118     {0x01, 0x97, 0x93},
0119     {0x01, 0x97, 0x93},
0120     {0x01, 0x97, 0xa3},
0121     {0x01, 0x97, 0xa3},
0122     {0x01, 0x97, 0xa3},
0123     {0x01, 0x97, 0xa3},
0124     {0x01, 0x97, 0xb3},
0125     {0x01, 0x97, 0xb3},
0126     {0x01, 0x97, 0xb3},
0127     {0x03, 0x37, 0xc3}
0128 };
0129 
0130 static u8 vt3226_channel_table1[CB_MAX_CHANNEL_24G][3] = {
0131     {0x02, 0x66, 0x64},
0132     {0x03, 0x66, 0x64},
0133     {0x00, 0x66, 0x64},
0134     {0x01, 0x66, 0x64},
0135     {0x02, 0x66, 0x64},
0136     {0x03, 0x66, 0x64},
0137     {0x00, 0x66, 0x64},
0138     {0x01, 0x66, 0x64},
0139     {0x02, 0x66, 0x64},
0140     {0x03, 0x66, 0x64},
0141     {0x00, 0x66, 0x64},
0142     {0x01, 0x66, 0x64},
0143     {0x02, 0x66, 0x64},
0144     {0x00, 0xcc, 0xc4}
0145 };
0146 
0147 static const u32 vt3226d0_lo_current_table[CB_MAX_CHANNEL_24G] = {
0148     0x0135c600,
0149     0x0135c600,
0150     0x0235c600,
0151     0x0235c600,
0152     0x0235c600,
0153     0x0335c600,
0154     0x0335c600,
0155     0x0335c600,
0156     0x0335c600,
0157     0x0335c600,
0158     0x0335c600,
0159     0x0335c600,
0160     0x0335c600,
0161     0x0135c600
0162 };
0163 
0164 enum {
0165     VNT_TABLE_INIT = 0,
0166     VNT_TABLE_INIT_2 = 0,
0167     VNT_TABLE_0 = 1,
0168     VNT_TABLE_1 = 2,
0169     VNT_TABLE_2 = 1
0170 };
0171 
0172 struct vnt_table_info {
0173     u8 *addr;
0174     int length;
0175 };
0176 
0177 static const struct vnt_table_info vnt_table_seq[][3] = {
0178     {   /* RF_AL2230, RF_AL2230S init table, channel table 0 and 1 */
0179         {&al2230_init_table[0][0], CB_AL2230_INIT_SEQ * 3},
0180         {&al2230_channel_table0[0][0], CB_MAX_CHANNEL_24G * 3},
0181         {&al2230_channel_table1[0][0], CB_MAX_CHANNEL_24G * 3}
0182     }, {    /* RF_VT3226 init table, channel table 0 and 1 */
0183         {&vt3226_init_table[0][0], CB_VT3226_INIT_SEQ * 3},
0184         {&vt3226_channel_table0[0][0], CB_MAX_CHANNEL_24G * 3},
0185         {&vt3226_channel_table1[0][0], CB_MAX_CHANNEL_24G * 3}
0186     }, {    /* RF_VT3226D0 init table, channel table 0 and 1 */
0187         {&vt3226d0_init_table[0][0], CB_VT3226_INIT_SEQ * 3},
0188         {&vt3226_channel_table0[0][0], CB_MAX_CHANNEL_24G * 3},
0189         {&vt3226_channel_table1[0][0], CB_MAX_CHANNEL_24G * 3}
0190     }
0191 };
0192 
0193 /*
0194  * Description: Write to IF/RF, by embedded programming
0195  */
0196 int vnt_rf_write_embedded(struct vnt_private *priv, u32 data)
0197 {
0198     u8 reg_data[4];
0199 
0200     data |= (VNT_RF_REG_LEN << 3) | IFREGCTL_REGW;
0201 
0202     reg_data[0] = (u8)data;
0203     reg_data[1] = (u8)(data >> 8);
0204     reg_data[2] = (u8)(data >> 16);
0205     reg_data[3] = (u8)(data >> 24);
0206 
0207     return vnt_control_out(priv, MESSAGE_TYPE_WRITE_IFRF, 0, 0,
0208                    ARRAY_SIZE(reg_data), reg_data);
0209 }
0210 
0211 static u8 vnt_rf_addpower(struct vnt_private *priv)
0212 {
0213     int base;
0214     s32 rssi = -priv->current_rssi;
0215 
0216     if (!rssi)
0217         return 7;
0218 
0219     if (priv->rf_type == RF_VT3226D0)
0220         base = -60;
0221     else
0222         base = -70;
0223 
0224     if (rssi < base)
0225         return ((rssi - base + 1) / -5) * 2 + 5;
0226 
0227     return 0;
0228 }
0229 
0230 /* Set Tx power by power level and rate */
0231 static int vnt_rf_set_txpower(struct vnt_private *priv, u8 power,
0232                   struct ieee80211_channel *ch)
0233 {
0234     u32 power_setting = 0;
0235     int ret = 0;
0236 
0237     power += vnt_rf_addpower(priv);
0238     if (power > VNT_RF_MAX_POWER)
0239         power = VNT_RF_MAX_POWER;
0240 
0241     if (priv->power == power)
0242         return 0;
0243 
0244     priv->power = power;
0245 
0246     switch (priv->rf_type) {
0247     case RF_AL2230:
0248         power_setting = 0x0404090 | (power << 12);
0249 
0250         ret = vnt_rf_write_embedded(priv, power_setting);
0251         if (ret)
0252             return ret;
0253 
0254         if (ch->flags & IEEE80211_CHAN_NO_OFDM)
0255             ret = vnt_rf_write_embedded(priv, 0x0001b400);
0256         else
0257             ret = vnt_rf_write_embedded(priv, 0x0005a400);
0258 
0259         break;
0260     case RF_AL2230S:
0261         power_setting = 0x0404090 | (power << 12);
0262 
0263         ret = vnt_rf_write_embedded(priv, power_setting);
0264         if (ret)
0265             return ret;
0266 
0267         if (ch->flags & IEEE80211_CHAN_NO_OFDM) {
0268             ret = vnt_rf_write_embedded(priv, 0x040c1400);
0269             if (ret)
0270                 return ret;
0271 
0272             ret = vnt_rf_write_embedded(priv, 0x00299b00);
0273         } else {
0274             ret = vnt_rf_write_embedded(priv, 0x0005a400);
0275             if (ret)
0276                 return ret;
0277 
0278             ret = vnt_rf_write_embedded(priv, 0x00099b00);
0279         }
0280 
0281         break;
0282 
0283     case RF_VT3226:
0284         power_setting = ((0x3f - power) << 20) | (0x17 << 8);
0285 
0286         ret = vnt_rf_write_embedded(priv, power_setting);
0287         break;
0288     case RF_VT3226D0:
0289         if (ch->flags & IEEE80211_CHAN_NO_OFDM) {
0290             u16 hw_value = ch->hw_value;
0291 
0292             power_setting = ((0x3f - power) << 20) | (0xe07 << 8);
0293 
0294             ret = vnt_rf_write_embedded(priv, power_setting);
0295             if (ret)
0296                 return ret;
0297 
0298             ret = vnt_rf_write_embedded(priv, 0x03c6a200);
0299             if (ret)
0300                 return ret;
0301 
0302             dev_dbg(&priv->usb->dev,
0303                 "%s 11b channel [%d]\n", __func__, hw_value);
0304 
0305             hw_value--;
0306 
0307             if (hw_value < ARRAY_SIZE(vt3226d0_lo_current_table)) {
0308                 ret = vnt_rf_write_embedded(priv,
0309                                 vt3226d0_lo_current_table[hw_value]);
0310                 if (ret)
0311                     return ret;
0312             }
0313 
0314             ret = vnt_rf_write_embedded(priv, 0x015C0800);
0315         } else {
0316             dev_dbg(&priv->usb->dev,
0317                 "@@@@ %s> 11G mode\n", __func__);
0318 
0319             power_setting = ((0x3f - power) << 20) | (0x7 << 8);
0320 
0321             ret = vnt_rf_write_embedded(priv, power_setting);
0322             if (ret)
0323                 return ret;
0324 
0325             ret = vnt_rf_write_embedded(priv, 0x00C6A200);
0326             if (ret)
0327                 return ret;
0328 
0329             ret = vnt_rf_write_embedded(priv, 0x016BC600);
0330             if (ret)
0331                 return ret;
0332 
0333             ret = vnt_rf_write_embedded(priv, 0x00900800);
0334         }
0335 
0336         break;
0337 
0338     default:
0339         break;
0340     }
0341     return ret;
0342 }
0343 
0344 /* Set Tx power by channel number type */
0345 int vnt_rf_setpower(struct vnt_private *priv,
0346             struct ieee80211_channel *ch)
0347 {
0348     u16 channel;
0349     u8 power = priv->cck_pwr;
0350 
0351     if (!ch)
0352         return -EINVAL;
0353 
0354     /* set channel number to array number */
0355     channel = ch->hw_value - 1;
0356 
0357     if (ch->flags & IEEE80211_CHAN_NO_OFDM) {
0358         if (channel < ARRAY_SIZE(priv->cck_pwr_tbl))
0359             power = priv->cck_pwr_tbl[channel];
0360     } else if (ch->band == NL80211_BAND_5GHZ) {
0361         /* remove 14 channels to array size */
0362         channel -= 14;
0363 
0364         if (channel < ARRAY_SIZE(priv->ofdm_a_pwr_tbl))
0365             power = priv->ofdm_a_pwr_tbl[channel];
0366     } else {
0367         if (channel < ARRAY_SIZE(priv->ofdm_pwr_tbl))
0368             power = priv->ofdm_pwr_tbl[channel];
0369     }
0370 
0371     return vnt_rf_set_txpower(priv, power, ch);
0372 }
0373 
0374 /* Convert rssi to dbm */
0375 void vnt_rf_rssi_to_dbm(struct vnt_private *priv, u8 rssi, long *dbm)
0376 {
0377     u8 idx = ((rssi & 0xc0) >> 6) & 0x03;
0378     long b = rssi & 0x3f;
0379     long a = 0;
0380     u8 airoharf[4] = {0, 18, 0, 40};
0381 
0382     switch (priv->rf_type) {
0383     case RF_AL2230:
0384     case RF_AL2230S:
0385     case RF_VT3226:
0386     case RF_VT3226D0:
0387         a = airoharf[idx];
0388         break;
0389     default:
0390         break;
0391     }
0392 
0393     *dbm = -1 * (a + b * 2);
0394 }
0395 
0396 int vnt_rf_table_download(struct vnt_private *priv)
0397 {
0398     int ret;
0399     int idx = -1;
0400     const struct vnt_table_info *table_seq;
0401 
0402     switch (priv->rf_type) {
0403     case RF_AL2230:
0404     case RF_AL2230S:
0405         idx = 0;
0406         break;
0407     case RF_VT3226:
0408         idx = 1;
0409         break;
0410     case RF_VT3226D0:
0411         idx = 2;
0412         break;
0413     }
0414 
0415     if (idx < 0)
0416         return 0;
0417 
0418     table_seq = &vnt_table_seq[idx][0];
0419 
0420     /* Init Table */
0421     ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, 0,
0422                   MESSAGE_REQUEST_RF_INIT,
0423                   table_seq[VNT_TABLE_INIT].length,
0424                   table_seq[VNT_TABLE_INIT].addr);
0425     if (ret)
0426         return ret;
0427 
0428     /* Channel Table 0 */
0429     ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE,
0430                      MESSAGE_REQUEST_RF_CH0,
0431                      table_seq[VNT_TABLE_0].length,
0432                      table_seq[VNT_TABLE_0].addr);
0433     if (ret)
0434         return ret;
0435 
0436     /* Channel Table 1 */
0437     ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE,
0438                      MESSAGE_REQUEST_RF_CH1,
0439                      table_seq[VNT_TABLE_1].length,
0440                      table_seq[VNT_TABLE_1].addr);
0441 
0442     return ret;
0443 }