⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iwl-4965.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	return -1;}static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel){	s32 b = -1;	for (b = 0; b < EEPROM_TX_POWER_BANDS; b++) {		if (priv->eeprom.calib_info.band_info[b].ch_from == 0)			continue;		if ((channel >= priv->eeprom.calib_info.band_info[b].ch_from)		    && (channel <= priv->eeprom.calib_info.band_info[b].ch_to))			break;	}	return b;}static s32 iwl4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2){	s32 val;	if (x2 == x1)		return y1;	else {		iwl4965_math_div_round((x2 - x) * (y1 - y2), (x2 - x1), &val);		return val + y2;	}}static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,				    struct iwl_eeprom_calib_ch_info *chan_info){	s32 s = -1;	u32 c;	u32 m;	const struct iwl_eeprom_calib_measure *m1;	const struct iwl_eeprom_calib_measure *m2;	struct iwl_eeprom_calib_measure *omeas;	u32 ch_i1;	u32 ch_i2;	s = iwl4965_get_sub_band(priv, channel);	if (s >= EEPROM_TX_POWER_BANDS) {		IWL_ERROR("Tx Power can not find channel %d ", channel);		return -1;	}	ch_i1 = priv->eeprom.calib_info.band_info[s].ch1.ch_num;	ch_i2 = priv->eeprom.calib_info.band_info[s].ch2.ch_num;	chan_info->ch_num = (u8) channel;	IWL_DEBUG_TXPOWER("channel %d subband %d factory cal ch %d & %d\n",			  channel, s, ch_i1, ch_i2);	for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) {		for (m = 0; m < EEPROM_TX_POWER_MEASUREMENTS; m++) {			m1 = &(priv->eeprom.calib_info.band_info[s].ch1.			       measurements[c][m]);			m2 = &(priv->eeprom.calib_info.band_info[s].ch2.			       measurements[c][m]);			omeas = &(chan_info->measurements[c][m]);			omeas->actual_pow =			    (u8) iwl4965_interpolate_value(channel, ch_i1,							   m1->actual_pow,							   ch_i2,							   m2->actual_pow);			omeas->gain_idx =			    (u8) iwl4965_interpolate_value(channel, ch_i1,							   m1->gain_idx, ch_i2,							   m2->gain_idx);			omeas->temperature =			    (u8) iwl4965_interpolate_value(channel, ch_i1,							   m1->temperature,							   ch_i2,							   m2->temperature);			omeas->pa_det =			    (s8) iwl4965_interpolate_value(channel, ch_i1,							   m1->pa_det, ch_i2,							   m2->pa_det);			IWL_DEBUG_TXPOWER			    ("chain %d meas %d AP1=%d AP2=%d AP=%d\n", c, m,			     m1->actual_pow, m2->actual_pow, omeas->actual_pow);			IWL_DEBUG_TXPOWER			    ("chain %d meas %d NI1=%d NI2=%d NI=%d\n", c, m,			     m1->gain_idx, m2->gain_idx, omeas->gain_idx);			IWL_DEBUG_TXPOWER			    ("chain %d meas %d PA1=%d PA2=%d PA=%d\n", c, m,			     m1->pa_det, m2->pa_det, omeas->pa_det);			IWL_DEBUG_TXPOWER			    ("chain %d meas %d  T1=%d  T2=%d  T=%d\n", c, m,			     m1->temperature, m2->temperature,			     omeas->temperature);		}	}	return 0;}/* bit-rate-dependent table to prevent Tx distortion, in half-dB units, * for OFDM 6, 12, 18, 24, 36, 48, 54, 60 MBit, and CCK all rates. */static s32 back_off_table[] = {	10, 10, 10, 10, 10, 15, 17, 20,	/* OFDM SISO 20 MHz */	10, 10, 10, 10, 10, 15, 17, 20,	/* OFDM MIMO 20 MHz */	10, 10, 10, 10, 10, 15, 17, 20,	/* OFDM SISO 40 MHz */	10, 10, 10, 10, 10, 15, 17, 20,	/* OFDM MIMO 40 MHz */	10			/* CCK */};/* Thermal compensation values for txpower for various frequency ranges ... *   ratios from 3:1 to 4.5:1 of degrees (Celsius) per half-dB gain adjust */static struct iwl_txpower_comp_entry {	s32 degrees_per_05db_a;	s32 degrees_per_05db_a_denom;} tx_power_cmp_tble[CALIB_CH_GROUP_MAX] = {	{9, 2},			/* group 0 5.2, ch  34-43 */	{4, 1},			/* group 1 5.2, ch  44-70 */	{4, 1},			/* group 2 5.2, ch  71-124 */	{4, 1},			/* group 3 5.2, ch 125-200 */	{3, 1}			/* group 4 2.4, ch   all */};static s32 get_min_power_index(s32 rate_power_index, u32 band){	if (!band) {		if ((rate_power_index & 7) <= 4)			return MIN_TX_GAIN_INDEX_52GHZ_EXT;	}	return MIN_TX_GAIN_INDEX;}struct gain_entry {	u8 dsp;	u8 radio;};static const struct gain_entry gain_table[2][108] = {	/* 5.2GHz power gain index table */	{	 {123, 0x3F},		/* highest txpower */	 {117, 0x3F},	 {110, 0x3F},	 {104, 0x3F},	 {98, 0x3F},	 {110, 0x3E},	 {104, 0x3E},	 {98, 0x3E},	 {110, 0x3D},	 {104, 0x3D},	 {98, 0x3D},	 {110, 0x3C},	 {104, 0x3C},	 {98, 0x3C},	 {110, 0x3B},	 {104, 0x3B},	 {98, 0x3B},	 {110, 0x3A},	 {104, 0x3A},	 {98, 0x3A},	 {110, 0x39},	 {104, 0x39},	 {98, 0x39},	 {110, 0x38},	 {104, 0x38},	 {98, 0x38},	 {110, 0x37},	 {104, 0x37},	 {98, 0x37},	 {110, 0x36},	 {104, 0x36},	 {98, 0x36},	 {110, 0x35},	 {104, 0x35},	 {98, 0x35},	 {110, 0x34},	 {104, 0x34},	 {98, 0x34},	 {110, 0x33},	 {104, 0x33},	 {98, 0x33},	 {110, 0x32},	 {104, 0x32},	 {98, 0x32},	 {110, 0x31},	 {104, 0x31},	 {98, 0x31},	 {110, 0x30},	 {104, 0x30},	 {98, 0x30},	 {110, 0x25},	 {104, 0x25},	 {98, 0x25},	 {110, 0x24},	 {104, 0x24},	 {98, 0x24},	 {110, 0x23},	 {104, 0x23},	 {98, 0x23},	 {110, 0x22},	 {104, 0x18},	 {98, 0x18},	 {110, 0x17},	 {104, 0x17},	 {98, 0x17},	 {110, 0x16},	 {104, 0x16},	 {98, 0x16},	 {110, 0x15},	 {104, 0x15},	 {98, 0x15},	 {110, 0x14},	 {104, 0x14},	 {98, 0x14},	 {110, 0x13},	 {104, 0x13},	 {98, 0x13},	 {110, 0x12},	 {104, 0x08},	 {98, 0x08},	 {110, 0x07},	 {104, 0x07},	 {98, 0x07},	 {110, 0x06},	 {104, 0x06},	 {98, 0x06},	 {110, 0x05},	 {104, 0x05},	 {98, 0x05},	 {110, 0x04},	 {104, 0x04},	 {98, 0x04},	 {110, 0x03},	 {104, 0x03},	 {98, 0x03},	 {110, 0x02},	 {104, 0x02},	 {98, 0x02},	 {110, 0x01},	 {104, 0x01},	 {98, 0x01},	 {110, 0x00},	 {104, 0x00},	 {98, 0x00},	 {93, 0x00},	 {88, 0x00},	 {83, 0x00},	 {78, 0x00},	 },	/* 2.4GHz power gain index table */	{	 {110, 0x3f},		/* highest txpower */	 {104, 0x3f},	 {98, 0x3f},	 {110, 0x3e},	 {104, 0x3e},	 {98, 0x3e},	 {110, 0x3d},	 {104, 0x3d},	 {98, 0x3d},	 {110, 0x3c},	 {104, 0x3c},	 {98, 0x3c},	 {110, 0x3b},	 {104, 0x3b},	 {98, 0x3b},	 {110, 0x3a},	 {104, 0x3a},	 {98, 0x3a},	 {110, 0x39},	 {104, 0x39},	 {98, 0x39},	 {110, 0x38},	 {104, 0x38},	 {98, 0x38},	 {110, 0x37},	 {104, 0x37},	 {98, 0x37},	 {110, 0x36},	 {104, 0x36},	 {98, 0x36},	 {110, 0x35},	 {104, 0x35},	 {98, 0x35},	 {110, 0x34},	 {104, 0x34},	 {98, 0x34},	 {110, 0x33},	 {104, 0x33},	 {98, 0x33},	 {110, 0x32},	 {104, 0x32},	 {98, 0x32},	 {110, 0x31},	 {104, 0x31},	 {98, 0x31},	 {110, 0x30},	 {104, 0x30},	 {98, 0x30},	 {110, 0x6},	 {104, 0x6},	 {98, 0x6},	 {110, 0x5},	 {104, 0x5},	 {98, 0x5},	 {110, 0x4},	 {104, 0x4},	 {98, 0x4},	 {110, 0x3},	 {104, 0x3},	 {98, 0x3},	 {110, 0x2},	 {104, 0x2},	 {98, 0x2},	 {110, 0x1},	 {104, 0x1},	 {98, 0x1},	 {110, 0x0},	 {104, 0x0},	 {98, 0x0},	 {97, 0},	 {96, 0},	 {95, 0},	 {94, 0},	 {93, 0},	 {92, 0},	 {91, 0},	 {90, 0},	 {89, 0},	 {88, 0},	 {87, 0},	 {86, 0},	 {85, 0},	 {84, 0},	 {83, 0},	 {82, 0},	 {81, 0},	 {80, 0},	 {79, 0},	 {78, 0},	 {77, 0},	 {76, 0},	 {75, 0},	 {74, 0},	 {73, 0},	 {72, 0},	 {71, 0},	 {70, 0},	 {69, 0},	 {68, 0},	 {67, 0},	 {66, 0},	 {65, 0},	 {64, 0},	 {63, 0},	 {62, 0},	 {61, 0},	 {60, 0},	 {59, 0},	 }};static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,				    u8 is_fat, u8 ctrl_chan_high,				    struct iwl_tx_power_db *tx_power_tbl){	u8 saturation_power;	s32 target_power;	s32 user_target_power;	s32 power_limit;	s32 current_temp;	s32 reg_limit;	s32 current_regulatory;	s32 txatten_grp = CALIB_CH_GROUP_MAX;	int i;	int c;	const struct iwl_channel_info *ch_info = NULL;	struct iwl_eeprom_calib_ch_info ch_eeprom_info;	const struct iwl_eeprom_calib_measure *measurement;	s16 voltage;	s32 init_voltage;	s32 voltage_compensation;	s32 degrees_per_05db_num;	s32 degrees_per_05db_denom;	s32 factory_temp;	s32 temperature_comp[2];	s32 factory_gain_index[2];	s32 factory_actual_pwr[2];	s32 power_index;	/* Sanity check requested level (dBm) */	if (priv->user_txpower_limit < IWL_TX_POWER_TARGET_POWER_MIN) {		IWL_WARNING("Requested user TXPOWER %d below limit.\n",			    priv->user_txpower_limit);		return -EINVAL;	}	if (priv->user_txpower_limit > IWL_TX_POWER_TARGET_POWER_MAX) {		IWL_WARNING("Requested user TXPOWER %d above limit.\n",			    priv->user_txpower_limit);		return -EINVAL;	}	/* user_txpower_limit is in dBm, convert to half-dBm (half-dB units	 *   are used for indexing into txpower table) */	user_target_power = 2 * priv->user_txpower_limit;	/* Get current (RXON) channel, band, width */	ch_info =		iwl4965_get_channel_txpower_info(priv, priv->phymode, channel);	IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band,			  is_fat);	if (!ch_info)		return -EINVAL;	/* get txatten group, used to select 1) thermal txpower adjustment	 *   and 2) mimo txpower balance between Tx chains. */	txatten_grp = iwl4965_get_tx_atten_grp(channel);	if (txatten_grp < 0)		return -EINVAL;	IWL_DEBUG_TXPOWER("channel %d belongs to txatten group %d\n",			  channel, txatten_grp);	if (is_fat) {		if (ctrl_chan_high)			channel -= 2;		else			channel += 2;	}	/* hardware txpower limits ...	 * saturation (clipping distortion) txpowers are in half-dBm */	if (band)		saturation_power = priv->eeprom.calib_info.saturation_power24;	else		saturation_power = priv->eeprom.calib_info.saturation_power52;	if (saturation_power < IWL_TX_POWER_SATURATION_MIN ||	    saturation_power > IWL_TX_POWER_SATURATION_MAX) {		if (band)			saturation_power = IWL_TX_POWER_DEFAULT_SATURATION_24;		else			saturation_power = IWL_TX_POWER_DEFAULT_SATURATION_52;	}	/* regulatory txpower limits ... reg_limit values are in half-dBm,	 *   max_power_avg values are in dBm, convert * 2 */	if (is_fat)		reg_limit = ch_info->fat_max_power_avg * 2;	else		reg_limit = ch_info->max_power_avg * 2;	if ((reg_limit < IWL_TX_POWER_REGULATORY_MIN) ||	    (reg_limit > IWL_TX_POWER_REGULATORY_MAX)) {		if (band)			reg_limit = IWL_TX_POWER_DEFAULT_REGULATORY_24;		else			reg_limit = IWL_TX_POWER_DEFAULT_REGULATORY_52;	}	/* Interpolate txpower calibration values for this channel,	 *   based on factory calibration tests on spaced channels. */	iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info);	/* calculate tx gain adjustment based on power supply voltage */	voltage = priv->eeprom.calib_info.voltage;	init_vo

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -