0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
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 {
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 }, {
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 }, {
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
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
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
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
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
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
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
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
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
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 }