1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
8 * Purpose: rf function code
15 * vnt_rf_write_embedded - Embedded write RF register via MAC
18 * RF_VT3226: RobertYu:20051111, VT3226C0 and before
19 * RF_VT3226D0: RobertYu:20051228
20 * RF_VT3342A0: RobertYu:20060609
24 #include <linux/errno.h>
30 #define CB_AL2230_INIT_SEQ 15
31 #define CB_AL7230_INIT_SEQ 16
32 #define CB_VT3226_INIT_SEQ 11
33 #define CB_VT3342_INIT_SEQ 13
35 static u8 al2230_init_table
[CB_AL2230_INIT_SEQ
][3] = {
53 static u8 al2230_channel_table0
[CB_MAX_CHANNEL_24G
][3] = {
70 static u8 al2230_channel_table1
[CB_MAX_CHANNEL_24G
][3] = {
87 static u8 al7230_init_table
[CB_AL7230_INIT_SEQ
][3] = {
106 static u8 al7230_init_table_amode
[CB_AL7230_INIT_SEQ
][3] = {
125 static u8 al7230_channel_table0
[CB_MAX_CHANNEL
][3] = {
140 {0x0f, 0xf5, 0x20}, /* channel 15 Tf = 4915MHz */
184 static u8 al7230_channel_table1
[CB_MAX_CHANNEL
][3] = {
199 {0x1d, 0x55, 0x51}, /* channel = 15, Tf = 4915MHz */
243 static u8 al7230_channel_table2
[CB_MAX_CHANNEL
][3] = {
258 {0x7f, 0xd7, 0x84}, /* channel = 15 Tf = 4915MHz */
302 static u8 vt3226_init_table
[CB_VT3226_INIT_SEQ
][3] = {
316 static u8 vt3226d0_init_table
[CB_VT3226_INIT_SEQ
][3] = {
330 static u8 vt3226_channel_table0
[CB_MAX_CHANNEL_24G
][3] = {
347 static u8 vt3226_channel_table1
[CB_MAX_CHANNEL_24G
][3] = {
364 static const u32 vt3226d0_lo_current_table
[CB_MAX_CHANNEL_24G
] = {
381 static u8 vt3342a0_init_table
[CB_VT3342_INIT_SEQ
][3] = { /* 11b/g mode */
397 static u8 vt3342_channel_table0
[CB_MAX_CHANNEL
][3] = {
412 {0x01, 0x15, 0x13}, /* channel = 15 Tf = 4915MHz */
456 static u8 vt3342_channel_table1
[CB_MAX_CHANNEL
][3] = {
471 {0x00, 0x44, 0x44}, /* channel = 15 Tf = 4915MHz */
517 VNT_TABLE_INIT_2
= 0,
523 struct vnt_table_info
{
528 static const struct vnt_table_info vnt_table_seq
[][3] = {
529 { /* RF_AL2230, RF_AL2230S init table, channel table 0 and 1 */
530 {&al2230_init_table
[0][0], CB_AL2230_INIT_SEQ
* 3},
531 {&al2230_channel_table0
[0][0], CB_MAX_CHANNEL_24G
* 3},
532 {&al2230_channel_table1
[0][0], CB_MAX_CHANNEL_24G
* 3}
533 }, { /* RF_AIROHA7230 init table, channel table 0 and 1 */
534 {&al7230_init_table
[0][0], CB_AL7230_INIT_SEQ
* 3},
535 {&al7230_channel_table0
[0][0], CB_MAX_CHANNEL
* 3},
536 {&al7230_channel_table1
[0][0], CB_MAX_CHANNEL
* 3}
537 }, { /* RF_VT3226 init table, channel table 0 and 1 */
538 {&vt3226_init_table
[0][0], CB_VT3226_INIT_SEQ
* 3},
539 {&vt3226_channel_table0
[0][0], CB_MAX_CHANNEL_24G
* 3},
540 {&vt3226_channel_table1
[0][0], CB_MAX_CHANNEL_24G
* 3}
541 }, { /* RF_VT3226D0 init table, channel table 0 and 1 */
542 {&vt3226d0_init_table
[0][0], CB_VT3226_INIT_SEQ
* 3},
543 {&vt3226_channel_table0
[0][0], CB_MAX_CHANNEL_24G
* 3},
544 {&vt3226_channel_table1
[0][0], CB_MAX_CHANNEL_24G
* 3}
545 }, { /* RF_VT3342A0 init table, channel table 0 and 1 */
546 {&vt3342a0_init_table
[0][0], CB_VT3342_INIT_SEQ
* 3},
547 {&vt3342_channel_table0
[0][0], CB_MAX_CHANNEL
* 3},
548 {&vt3342_channel_table1
[0][0], CB_MAX_CHANNEL
* 3}
549 }, { /* RF_AIROHA7230 init table 2 and channel table 2 */
550 {&al7230_init_table_amode
[0][0], CB_AL7230_INIT_SEQ
* 3},
551 {&al7230_channel_table2
[0][0], CB_MAX_CHANNEL
* 3},
557 * Description: Write to IF/RF, by embedded programming
559 int vnt_rf_write_embedded(struct vnt_private
*priv
, u32 data
)
563 data
|= (VNT_RF_REG_LEN
<< 3) | IFREGCTL_REGW
;
565 reg_data
[0] = (u8
)data
;
566 reg_data
[1] = (u8
)(data
>> 8);
567 reg_data
[2] = (u8
)(data
>> 16);
568 reg_data
[3] = (u8
)(data
>> 24);
570 return vnt_control_out(priv
, MESSAGE_TYPE_WRITE_IFRF
, 0, 0,
571 ARRAY_SIZE(reg_data
), reg_data
);
574 static u8
vnt_rf_addpower(struct vnt_private
*priv
)
577 s32 rssi
= -priv
->current_rssi
;
582 if (priv
->rf_type
== RF_VT3226D0
)
588 return ((rssi
- base
+ 1) / -5) * 2 + 5;
593 /* Set Tx power by power level and rate */
594 static int vnt_rf_set_txpower(struct vnt_private
*priv
, u8 power
,
595 struct ieee80211_channel
*ch
)
597 u32 power_setting
= 0;
600 power
+= vnt_rf_addpower(priv
);
601 if (power
> VNT_RF_MAX_POWER
)
602 power
= VNT_RF_MAX_POWER
;
604 if (priv
->power
== power
)
609 switch (priv
->rf_type
) {
611 power_setting
= 0x0404090 | (power
<< 12);
613 ret
= vnt_rf_write_embedded(priv
, power_setting
);
617 if (ch
->flags
& IEEE80211_CHAN_NO_OFDM
)
618 ret
= vnt_rf_write_embedded(priv
, 0x0001b400);
620 ret
= vnt_rf_write_embedded(priv
, 0x0005a400);
624 power_setting
= 0x0404090 | (power
<< 12);
626 ret
= vnt_rf_write_embedded(priv
, power_setting
);
630 if (ch
->flags
& IEEE80211_CHAN_NO_OFDM
) {
631 ret
= vnt_rf_write_embedded(priv
, 0x040c1400);
635 ret
= vnt_rf_write_embedded(priv
, 0x00299b00);
637 ret
= vnt_rf_write_embedded(priv
, 0x0005a400);
641 ret
= vnt_rf_write_embedded(priv
, 0x00099b00);
647 if (ch
->flags
& IEEE80211_CHAN_NO_OFDM
)
648 ret
= vnt_rf_write_embedded(priv
, 0x111bb900);
650 ret
= vnt_rf_write_embedded(priv
, 0x221bb900);
656 * 0x080F1B00 for 3 wire control TxGain(D10)
657 * and 0x31 as TX Gain value
659 power_setting
= 0x080c0b00 | (power
<< 12);
661 ret
= vnt_rf_write_embedded(priv
, power_setting
);
665 power_setting
= ((0x3f - power
) << 20) | (0x17 << 8);
667 ret
= vnt_rf_write_embedded(priv
, power_setting
);
670 if (ch
->flags
& IEEE80211_CHAN_NO_OFDM
) {
671 u16 hw_value
= ch
->hw_value
;
673 power_setting
= ((0x3f - power
) << 20) | (0xe07 << 8);
675 ret
= vnt_rf_write_embedded(priv
, power_setting
);
679 ret
= vnt_rf_write_embedded(priv
, 0x03c6a200);
683 dev_dbg(&priv
->usb
->dev
,
684 "%s 11b channel [%d]\n", __func__
, hw_value
);
688 if (hw_value
< ARRAY_SIZE(vt3226d0_lo_current_table
)) {
689 ret
= vnt_rf_write_embedded(priv
,
690 vt3226d0_lo_current_table
[hw_value
]);
695 ret
= vnt_rf_write_embedded(priv
, 0x015C0800);
697 dev_dbg(&priv
->usb
->dev
,
698 "@@@@ %s> 11G mode\n", __func__
);
700 power_setting
= ((0x3f - power
) << 20) | (0x7 << 8);
702 ret
= vnt_rf_write_embedded(priv
, power_setting
);
706 ret
= vnt_rf_write_embedded(priv
, 0x00C6A200);
710 ret
= vnt_rf_write_embedded(priv
, 0x016BC600);
714 ret
= vnt_rf_write_embedded(priv
, 0x00900800);
720 power_setting
= ((0x3f - power
) << 20) | (0x27 << 8);
722 ret
= vnt_rf_write_embedded(priv
, power_setting
);
730 /* Set Tx power by channel number type */
731 int vnt_rf_setpower(struct vnt_private
*priv
,
732 struct ieee80211_channel
*ch
)
735 u8 power
= priv
->cck_pwr
;
740 /* set channel number to array number */
741 channel
= ch
->hw_value
- 1;
743 if (ch
->flags
& IEEE80211_CHAN_NO_OFDM
) {
744 if (channel
< ARRAY_SIZE(priv
->cck_pwr_tbl
))
745 power
= priv
->cck_pwr_tbl
[channel
];
746 } else if (ch
->band
== NL80211_BAND_5GHZ
) {
747 /* remove 14 channels to array size */
750 if (channel
< ARRAY_SIZE(priv
->ofdm_a_pwr_tbl
))
751 power
= priv
->ofdm_a_pwr_tbl
[channel
];
753 if (channel
< ARRAY_SIZE(priv
->ofdm_pwr_tbl
))
754 power
= priv
->ofdm_pwr_tbl
[channel
];
757 return vnt_rf_set_txpower(priv
, power
, ch
);
760 /* Convert rssi to dbm */
761 void vnt_rf_rssi_to_dbm(struct vnt_private
*priv
, u8 rssi
, long *dbm
)
763 u8 idx
= ((rssi
& 0xc0) >> 6) & 0x03;
764 long b
= rssi
& 0x3f;
766 u8 airoharf
[4] = {0, 18, 0, 40};
768 switch (priv
->rf_type
) {
781 *dbm
= -1 * (a
+ b
* 2);
784 int vnt_rf_table_download(struct vnt_private
*priv
)
788 const struct vnt_table_info
*table_seq
;
790 switch (priv
->rf_type
) {
812 table_seq
= &vnt_table_seq
[idx
][0];
815 ret
= vnt_control_out(priv
, MESSAGE_TYPE_WRITE
, 0,
816 MESSAGE_REQUEST_RF_INIT
,
817 table_seq
[VNT_TABLE_INIT
].length
,
818 table_seq
[VNT_TABLE_INIT
].addr
);
822 /* Channel Table 0 */
823 ret
= vnt_control_out_blocks(priv
, VNT_REG_BLOCK_SIZE
,
824 MESSAGE_REQUEST_RF_CH0
,
825 table_seq
[VNT_TABLE_0
].length
,
826 table_seq
[VNT_TABLE_0
].addr
);
830 /* Channel Table 1 */
831 ret
= vnt_control_out_blocks(priv
, VNT_REG_BLOCK_SIZE
,
832 MESSAGE_REQUEST_RF_CH1
,
833 table_seq
[VNT_TABLE_1
].length
,
834 table_seq
[VNT_TABLE_1
].addr
);
836 if (priv
->rf_type
== RF_AIROHA7230
) {
837 table_seq
= &vnt_table_seq
[5][0];
840 ret
= vnt_control_out(priv
, MESSAGE_TYPE_WRITE
, 0,
841 MESSAGE_REQUEST_RF_INIT2
,
842 table_seq
[VNT_TABLE_INIT_2
].length
,
843 table_seq
[VNT_TABLE_INIT_2
].addr
);
847 /* Channel Table 2 */
848 ret
= vnt_control_out_blocks(priv
, VNT_REG_BLOCK_SIZE
,
849 MESSAGE_REQUEST_RF_CH2
,
850 table_seq
[VNT_TABLE_2
].length
,
851 table_seq
[VNT_TABLE_2
].addr
);