brintos

brintos / linux-shallow public Read only

0
0
Text · 9.2 KiB · 464602c Raw
444 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.4 * All rights reserved.5 *6 * Purpose: rf function code7 *8 * Author: Jerry Chen9 *10 * Date: Feb. 19, 200411 *12 * Functions:13 *	vnt_rf_write_embedded	- Embedded write RF register via MAC14 *15 * Revision History:16 *	RF_VT3226: RobertYu:20051111, VT3226C0 and before17 *	RF_VT3226D0: RobertYu:2005122818 *	RF_VT3342A0: RobertYu:2006060919 *20 */21 22#include <linux/errno.h>23#include "mac.h"24#include "rf.h"25#include "baseband.h"26#include "usbpipe.h"27 28#define CB_AL2230_INIT_SEQ    1529#define CB_AL7230_INIT_SEQ    1630#define CB_VT3226_INIT_SEQ    1131#define CB_VT3342_INIT_SEQ    1332 33static u8 al2230_init_table[CB_AL2230_INIT_SEQ][3] = {34	{0x03, 0xf7, 0x90},35	{0x03, 0x33, 0x31},36	{0x01, 0xb8, 0x02},37	{0x00, 0xff, 0xf3},38	{0x00, 0x05, 0xa4},39	{0x0f, 0x4d, 0xc5},40	{0x08, 0x05, 0xb6},41	{0x01, 0x47, 0xc7},42	{0x00, 0x06, 0x88},43	{0x04, 0x03, 0xb9},44	{0x00, 0xdb, 0xba},45	{0x00, 0x09, 0x9b},46	{0x0b, 0xdf, 0xfc},47	{0x00, 0x00, 0x0d},48	{0x00, 0x58, 0x0f}49};50 51static u8 al2230_channel_table0[CB_MAX_CHANNEL_24G][3] = {52	{0x03, 0xf7, 0x90},53	{0x03, 0xf7, 0x90},54	{0x03, 0xe7, 0x90},55	{0x03, 0xe7, 0x90},56	{0x03, 0xf7, 0xa0},57	{0x03, 0xf7, 0xa0},58	{0x03, 0xe7, 0xa0},59	{0x03, 0xe7, 0xa0},60	{0x03, 0xf7, 0xb0},61	{0x03, 0xf7, 0xb0},62	{0x03, 0xe7, 0xb0},63	{0x03, 0xe7, 0xb0},64	{0x03, 0xf7, 0xc0},65	{0x03, 0xe7, 0xc0}66};67 68static u8 al2230_channel_table1[CB_MAX_CHANNEL_24G][3] = {69	{0x03, 0x33, 0x31},70	{0x0b, 0x33, 0x31},71	{0x03, 0x33, 0x31},72	{0x0b, 0x33, 0x31},73	{0x03, 0x33, 0x31},74	{0x0b, 0x33, 0x31},75	{0x03, 0x33, 0x31},76	{0x0b, 0x33, 0x31},77	{0x03, 0x33, 0x31},78	{0x0b, 0x33, 0x31},79	{0x03, 0x33, 0x31},80	{0x0b, 0x33, 0x31},81	{0x03, 0x33, 0x31},82	{0x06, 0x66, 0x61}83};84 85static u8 vt3226_init_table[CB_VT3226_INIT_SEQ][3] = {86	{0x03, 0xff, 0x80},87	{0x02, 0x82, 0xa1},88	{0x03, 0xc6, 0xa2},89	{0x01, 0x97, 0x93},90	{0x03, 0x66, 0x64},91	{0x00, 0x61, 0xa5},92	{0x01, 0x7b, 0xd6},93	{0x00, 0x80, 0x17},94	{0x03, 0xf8, 0x08},95	{0x00, 0x02, 0x39},96	{0x02, 0x00, 0x2a}97};98 99static u8 vt3226d0_init_table[CB_VT3226_INIT_SEQ][3] = {100	{0x03, 0xff, 0x80},101	{0x03, 0x02, 0x21},102	{0x03, 0xc6, 0xa2},103	{0x01, 0x97, 0x93},104	{0x03, 0x66, 0x64},105	{0x00, 0x71, 0xa5},106	{0x01, 0x15, 0xc6},107	{0x01, 0x2e, 0x07},108	{0x00, 0x58, 0x08},109	{0x00, 0x02, 0x79},110	{0x02, 0x01, 0xaa}111};112 113static u8 vt3226_channel_table0[CB_MAX_CHANNEL_24G][3] = {114	{0x01, 0x97, 0x83},115	{0x01, 0x97, 0x83},116	{0x01, 0x97, 0x93},117	{0x01, 0x97, 0x93},118	{0x01, 0x97, 0x93},119	{0x01, 0x97, 0x93},120	{0x01, 0x97, 0xa3},121	{0x01, 0x97, 0xa3},122	{0x01, 0x97, 0xa3},123	{0x01, 0x97, 0xa3},124	{0x01, 0x97, 0xb3},125	{0x01, 0x97, 0xb3},126	{0x01, 0x97, 0xb3},127	{0x03, 0x37, 0xc3}128};129 130static u8 vt3226_channel_table1[CB_MAX_CHANNEL_24G][3] = {131	{0x02, 0x66, 0x64},132	{0x03, 0x66, 0x64},133	{0x00, 0x66, 0x64},134	{0x01, 0x66, 0x64},135	{0x02, 0x66, 0x64},136	{0x03, 0x66, 0x64},137	{0x00, 0x66, 0x64},138	{0x01, 0x66, 0x64},139	{0x02, 0x66, 0x64},140	{0x03, 0x66, 0x64},141	{0x00, 0x66, 0x64},142	{0x01, 0x66, 0x64},143	{0x02, 0x66, 0x64},144	{0x00, 0xcc, 0xc4}145};146 147static const u32 vt3226d0_lo_current_table[CB_MAX_CHANNEL_24G] = {148	0x0135c600,149	0x0135c600,150	0x0235c600,151	0x0235c600,152	0x0235c600,153	0x0335c600,154	0x0335c600,155	0x0335c600,156	0x0335c600,157	0x0335c600,158	0x0335c600,159	0x0335c600,160	0x0335c600,161	0x0135c600162};163 164enum {165	VNT_TABLE_INIT = 0,166	VNT_TABLE_INIT_2 = 0,167	VNT_TABLE_0 = 1,168	VNT_TABLE_1 = 2,169	VNT_TABLE_2 = 1170};171 172struct vnt_table_info {173	u8 *addr;174	int length;175};176 177static 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}190	}191};192 193/*194 * Description: Write to IF/RF, by embedded programming195 */196int vnt_rf_write_embedded(struct vnt_private *priv, u32 data)197{198	u8 reg_data[4];199 200	data |= (VNT_RF_REG_LEN << 3) | IFREGCTL_REGW;201 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);206 207	return vnt_control_out(priv, MESSAGE_TYPE_WRITE_IFRF, 0, 0,208			       ARRAY_SIZE(reg_data), reg_data);209}210 211static u8 vnt_rf_addpower(struct vnt_private *priv)212{213	int base;214	s32 rssi = -priv->current_rssi;215 216	if (!rssi)217		return 7;218 219	if (priv->rf_type == RF_VT3226D0)220		base = -60;221	else222		base = -70;223 224	if (rssi < base)225		return ((rssi - base + 1) / -5) * 2 + 5;226 227	return 0;228}229 230/* Set Tx power by power level and rate */231static int vnt_rf_set_txpower(struct vnt_private *priv, u8 power,232			      struct ieee80211_channel *ch)233{234	u32 power_setting = 0;235	int ret = 0;236 237	power += vnt_rf_addpower(priv);238	if (power > VNT_RF_MAX_POWER)239		power = VNT_RF_MAX_POWER;240 241	if (priv->power == power)242		return 0;243 244	priv->power = power;245 246	switch (priv->rf_type) {247	case RF_AL2230:248		power_setting = 0x0404090 | (power << 12);249 250		ret = vnt_rf_write_embedded(priv, power_setting);251		if (ret)252			return ret;253 254		if (ch->flags & IEEE80211_CHAN_NO_OFDM)255			ret = vnt_rf_write_embedded(priv, 0x0001b400);256		else257			ret = vnt_rf_write_embedded(priv, 0x0005a400);258 259		break;260	case RF_AL2230S:261		power_setting = 0x0404090 | (power << 12);262 263		ret = vnt_rf_write_embedded(priv, power_setting);264		if (ret)265			return ret;266 267		if (ch->flags & IEEE80211_CHAN_NO_OFDM) {268			ret = vnt_rf_write_embedded(priv, 0x040c1400);269			if (ret)270				return ret;271 272			ret = vnt_rf_write_embedded(priv, 0x00299b00);273		} else {274			ret = vnt_rf_write_embedded(priv, 0x0005a400);275			if (ret)276				return ret;277 278			ret = vnt_rf_write_embedded(priv, 0x00099b00);279		}280 281		break;282 283	case RF_VT3226:284		power_setting = ((0x3f - power) << 20) | (0x17 << 8);285 286		ret = vnt_rf_write_embedded(priv, power_setting);287		break;288	case RF_VT3226D0:289		if (ch->flags & IEEE80211_CHAN_NO_OFDM) {290			u16 hw_value = ch->hw_value;291 292			power_setting = ((0x3f - power) << 20) | (0xe07 << 8);293 294			ret = vnt_rf_write_embedded(priv, power_setting);295			if (ret)296				return ret;297 298			ret = vnt_rf_write_embedded(priv, 0x03c6a200);299			if (ret)300				return ret;301 302			dev_dbg(&priv->usb->dev,303				"%s 11b channel [%d]\n", __func__, hw_value);304 305			hw_value--;306 307			if (hw_value < ARRAY_SIZE(vt3226d0_lo_current_table)) {308				ret = vnt_rf_write_embedded(priv,309							    vt3226d0_lo_current_table[hw_value]);310				if (ret)311					return ret;312			}313 314			ret = vnt_rf_write_embedded(priv, 0x015C0800);315		} else {316			dev_dbg(&priv->usb->dev,317				"@@@@ %s> 11G mode\n", __func__);318 319			power_setting = ((0x3f - power) << 20) | (0x7 << 8);320 321			ret = vnt_rf_write_embedded(priv, power_setting);322			if (ret)323				return ret;324 325			ret = vnt_rf_write_embedded(priv, 0x00C6A200);326			if (ret)327				return ret;328 329			ret = vnt_rf_write_embedded(priv, 0x016BC600);330			if (ret)331				return ret;332 333			ret = vnt_rf_write_embedded(priv, 0x00900800);334		}335 336		break;337 338	default:339		break;340	}341	return ret;342}343 344/* Set Tx power by channel number type */345int vnt_rf_setpower(struct vnt_private *priv,346		    struct ieee80211_channel *ch)347{348	u16 channel;349	u8 power = priv->cck_pwr;350 351	if (!ch)352		return -EINVAL;353 354	/* set channel number to array number */355	channel = ch->hw_value - 1;356 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 */362		channel -= 14;363 364		if (channel < ARRAY_SIZE(priv->ofdm_a_pwr_tbl))365			power = priv->ofdm_a_pwr_tbl[channel];366	} else {367		if (channel < ARRAY_SIZE(priv->ofdm_pwr_tbl))368			power = priv->ofdm_pwr_tbl[channel];369	}370 371	return vnt_rf_set_txpower(priv, power, ch);372}373 374/* Convert rssi to dbm */375void vnt_rf_rssi_to_dbm(struct vnt_private *priv, u8 rssi, long *dbm)376{377	u8 idx = ((rssi & 0xc0) >> 6) & 0x03;378	long b = rssi & 0x3f;379	long a = 0;380	u8 airoharf[4] = {0, 18, 0, 40};381 382	switch (priv->rf_type) {383	case RF_AL2230:384	case RF_AL2230S:385	case RF_VT3226:386	case RF_VT3226D0:387		a = airoharf[idx];388		break;389	default:390		break;391	}392 393	*dbm = -1 * (a + b * 2);394}395 396int vnt_rf_table_download(struct vnt_private *priv)397{398	int ret;399	int idx = -1;400	const struct vnt_table_info *table_seq;401 402	switch (priv->rf_type) {403	case RF_AL2230:404	case RF_AL2230S:405		idx = 0;406		break;407	case RF_VT3226:408		idx = 1;409		break;410	case RF_VT3226D0:411		idx = 2;412		break;413	}414 415	if (idx < 0)416		return 0;417 418	table_seq = &vnt_table_seq[idx][0];419 420	/* Init Table */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);425	if (ret)426		return ret;427 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);433	if (ret)434		return ret;435 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);441 442	return ret;443}444