1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
6 * Purpose: rf function code
13 * vnt_rf_write_embedded - Embedded write RF register via MAC
16 * RF_VT3226: RobertYu:20051111, VT3226C0 and before
17 * RF_VT3226D0: RobertYu:20051228
18 * RF_VT3342A0: RobertYu:20060609
22 #include <linux/errno.h>
28 #define CB_AL2230_INIT_SEQ 15
29 #define CB_AL7230_INIT_SEQ 16
30 #define CB_VT3226_INIT_SEQ 11
31 #define CB_VT3342_INIT_SEQ 13
33 static u8 al2230_init_table[CB_AL2230_INIT_SEQ][3] = {
51 static u8 al2230_channel_table0[CB_MAX_CHANNEL_24G][3] = {
68 static u8 al2230_channel_table1[CB_MAX_CHANNEL_24G][3] = {
85 static u8 vt3226_init_table[CB_VT3226_INIT_SEQ][3] = {
99 static u8 vt3226d0_init_table[CB_VT3226_INIT_SEQ][3] = {
113 static u8 vt3226_channel_table0[CB_MAX_CHANNEL_24G][3] = {
130 static u8 vt3226_channel_table1[CB_MAX_CHANNEL_24G][3] = {
147 static const u32 vt3226d0_lo_current_table[CB_MAX_CHANNEL_24G] = {
166 VNT_TABLE_INIT_2 = 0,
172 struct vnt_table_info {
177 static const struct vnt_table_info vnt_table_seq[][3] = {
178 { /* RF_AL2230, RF_AL2230S init table, channel table 0 and 1 */
179 {&al2230_init_table[0][0], CB_AL2230_INIT_SEQ * 3},
180 {&al2230_channel_table0[0][0], CB_MAX_CHANNEL_24G * 3},
181 {&al2230_channel_table1[0][0], CB_MAX_CHANNEL_24G * 3}
182 }, { /* RF_VT3226 init table, channel table 0 and 1 */
183 {&vt3226_init_table[0][0], CB_VT3226_INIT_SEQ * 3},
184 {&vt3226_channel_table0[0][0], CB_MAX_CHANNEL_24G * 3},
185 {&vt3226_channel_table1[0][0], CB_MAX_CHANNEL_24G * 3}
186 }, { /* RF_VT3226D0 init table, channel table 0 and 1 */
187 {&vt3226d0_init_table[0][0], CB_VT3226_INIT_SEQ * 3},
188 {&vt3226_channel_table0[0][0], CB_MAX_CHANNEL_24G * 3},
189 {&vt3226_channel_table1[0][0], CB_MAX_CHANNEL_24G * 3}
194 * Description: Write to IF/RF, by embedded programming
196 int vnt_rf_write_embedded(struct vnt_private *priv, u32 data)
200 data |= (VNT_RF_REG_LEN << 3) | IFREGCTL_REGW;
202 reg_data[0] = (u8)data;
203 reg_data[1] = (u8)(data >> 8);
204 reg_data[2] = (u8)(data >> 16);
205 reg_data[3] = (u8)(data >> 24);
207 return vnt_control_out(priv, MESSAGE_TYPE_WRITE_IFRF, 0, 0,
208 ARRAY_SIZE(reg_data), reg_data);
211 static u8 vnt_rf_addpower(struct vnt_private *priv)
214 s32 rssi = -priv->current_rssi;
219 if (priv->rf_type == RF_VT3226D0)
225 return ((rssi - base + 1) / -5) * 2 + 5;
230 /* Set Tx power by power level and rate */
231 static int vnt_rf_set_txpower(struct vnt_private *priv, u8 power,
232 struct ieee80211_channel *ch)
234 u32 power_setting = 0;
237 power += vnt_rf_addpower(priv);
238 if (power > VNT_RF_MAX_POWER)
239 power = VNT_RF_MAX_POWER;
241 if (priv->power == power)
246 switch (priv->rf_type) {
248 power_setting = 0x0404090 | (power << 12);
250 ret = vnt_rf_write_embedded(priv, power_setting);
254 if (ch->flags & IEEE80211_CHAN_NO_OFDM)
255 ret = vnt_rf_write_embedded(priv, 0x0001b400);
257 ret = vnt_rf_write_embedded(priv, 0x0005a400);
261 power_setting = 0x0404090 | (power << 12);
263 ret = vnt_rf_write_embedded(priv, power_setting);
267 if (ch->flags & IEEE80211_CHAN_NO_OFDM) {
268 ret = vnt_rf_write_embedded(priv, 0x040c1400);
272 ret = vnt_rf_write_embedded(priv, 0x00299b00);
274 ret = vnt_rf_write_embedded(priv, 0x0005a400);
278 ret = vnt_rf_write_embedded(priv, 0x00099b00);
284 power_setting = ((0x3f - power) << 20) | (0x17 << 8);
286 ret = vnt_rf_write_embedded(priv, power_setting);
289 if (ch->flags & IEEE80211_CHAN_NO_OFDM) {
290 u16 hw_value = ch->hw_value;
292 power_setting = ((0x3f - power) << 20) | (0xe07 << 8);
294 ret = vnt_rf_write_embedded(priv, power_setting);
298 ret = vnt_rf_write_embedded(priv, 0x03c6a200);
302 dev_dbg(&priv->usb->dev,
303 "%s 11b channel [%d]\n", __func__, hw_value);
307 if (hw_value < ARRAY_SIZE(vt3226d0_lo_current_table)) {
308 ret = vnt_rf_write_embedded(priv,
309 vt3226d0_lo_current_table[hw_value]);
314 ret = vnt_rf_write_embedded(priv, 0x015C0800);
316 dev_dbg(&priv->usb->dev,
317 "@@@@ %s> 11G mode\n", __func__);
319 power_setting = ((0x3f - power) << 20) | (0x7 << 8);
321 ret = vnt_rf_write_embedded(priv, power_setting);
325 ret = vnt_rf_write_embedded(priv, 0x00C6A200);
329 ret = vnt_rf_write_embedded(priv, 0x016BC600);
333 ret = vnt_rf_write_embedded(priv, 0x00900800);
344 /* Set Tx power by channel number type */
345 int vnt_rf_setpower(struct vnt_private *priv,
346 struct ieee80211_channel *ch)
349 u8 power = priv->cck_pwr;
354 /* set channel number to array number */
355 channel = ch->hw_value - 1;
357 if (ch->flags & IEEE80211_CHAN_NO_OFDM) {
358 if (channel < ARRAY_SIZE(priv->cck_pwr_tbl))
359 power = priv->cck_pwr_tbl[channel];
360 } else if (ch->band == NL80211_BAND_5GHZ) {
361 /* remove 14 channels to array size */
364 if (channel < ARRAY_SIZE(priv->ofdm_a_pwr_tbl))
365 power = priv->ofdm_a_pwr_tbl[channel];
367 if (channel < ARRAY_SIZE(priv->ofdm_pwr_tbl))
368 power = priv->ofdm_pwr_tbl[channel];
371 return vnt_rf_set_txpower(priv, power, ch);
374 /* Convert rssi to dbm */
375 void vnt_rf_rssi_to_dbm(struct vnt_private *priv, u8 rssi, long *dbm)
377 u8 idx = ((rssi & 0xc0) >> 6) & 0x03;
378 long b = rssi & 0x3f;
380 u8 airoharf[4] = {0, 18, 0, 40};
382 switch (priv->rf_type) {
393 *dbm = -1 * (a + b * 2);
396 int vnt_rf_table_download(struct vnt_private *priv)
400 const struct vnt_table_info *table_seq;
402 switch (priv->rf_type) {
418 table_seq = &vnt_table_seq[idx][0];
421 ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, 0,
422 MESSAGE_REQUEST_RF_INIT,
423 table_seq[VNT_TABLE_INIT].length,
424 table_seq[VNT_TABLE_INIT].addr);
428 /* Channel Table 0 */
429 ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE,
430 MESSAGE_REQUEST_RF_CH0,
431 table_seq[VNT_TABLE_0].length,
432 table_seq[VNT_TABLE_0].addr);
436 /* Channel Table 1 */
437 ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE,
438 MESSAGE_REQUEST_RF_CH1,
439 table_seq[VNT_TABLE_1].length,
440 table_seq[VNT_TABLE_1].addr);