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

📄 ar5212.c

📁 无线网卡驱动 固件程序 There are currently 3 "programming generations" of Atheros 802.11 wireless devices (
💻 C
📖 第 1 页 / 共 5 页
字号:
		*status = HAL_EINVAL;		return (AH_FALSE);	}	if (channel->c_channel_flags & IEEE80211_CHAN_A) {		mode = AR5K_INI_VAL_11A;		freq = AR5K_INI_RFGAIN_5GHZ;		ee_mode = AR5K_EEPROM_MODE_11A;	} else if (channel->c_channel_flags & IEEE80211_CHAN_T) {		mode = AR5K_INI_VAL_11A_TURBO;		freq = AR5K_INI_RFGAIN_5GHZ;		ee_mode = AR5K_EEPROM_MODE_11A;	} else if (channel->c_channel_flags & IEEE80211_CHAN_B) {		mode = AR5K_INI_VAL_11B;		freq = AR5K_INI_RFGAIN_2GHZ;		ee_mode = AR5K_EEPROM_MODE_11B;	} else if (channel->c_channel_flags & IEEE80211_CHAN_G) {		mode = AR5K_INI_VAL_11G;		freq = AR5K_INI_RFGAIN_2GHZ;		ee_mode = AR5K_EEPROM_MODE_11G;	} else if (channel->c_channel_flags & CHANNEL_TG) {		mode = AR5K_INI_VAL_11G_TURBO;		freq = AR5K_INI_RFGAIN_2GHZ;		ee_mode = AR5K_EEPROM_MODE_11G;	} else if (channel->c_channel_flags & CHANNEL_XR) {		mode = AR5K_INI_VAL_XR;		freq = AR5K_INI_RFGAIN_5GHZ;		ee_mode = AR5K_EEPROM_MODE_11A;	} else {		AR5K_PRINTF("invalid channel: %d\n", channel->c_channel);		*status = HAL_EINVAL;		return (AH_FALSE);	}	/* PHY access enable */	AR5K_REG_WRITE(AR5K_AR5212_PHY(0), AR5K_AR5212_PHY_SHIFT_5GHZ);	/*	 * Write initial mode settings	 */	for (i = 0; i < AR5K_ELEMENTS(ar5212_mode); i++) {		if (ar5212_mode[i].mode_flags == AR5K_INI_FLAG_511X)			off = AR5K_INI_PHY_511X;		else if (ar5212_mode[i].mode_flags & AR5K_INI_FLAG_5111 &&		    hal->ah_radio == AR5K_AR5111)			off = AR5K_INI_PHY_5111;		else if (ar5212_mode[i].mode_flags & AR5K_INI_FLAG_5112 &&		    hal->ah_radio == AR5K_AR5112)			off = AR5K_INI_PHY_5112;		else			continue;		AR5K_REG_WAIT(i);		AR5K_REG_WRITE((u_int32_t)ar5212_mode[i].mode_register,		    ar5212_mode[i].mode_value[off][mode]);	}	/*	 * Write initial register settings	 */	for (i = 0; i < AR5K_ELEMENTS(ar5212_ini); i++) {		if (change_channel == AH_TRUE &&		    ar5212_ini[i].ini_register >= AR5K_AR5212_PCU_MIN &&		    ar5212_ini[i].ini_register <= AR5K_AR5212_PCU_MAX)			continue;		if ((hal->ah_radio == AR5K_AR5111 &&		    ar5212_ini[i].ini_flags & AR5K_INI_FLAG_5111) ||		    (hal->ah_radio == AR5K_AR5112 &&		    ar5212_ini[i].ini_flags & AR5K_INI_FLAG_5112)) {			AR5K_REG_WAIT(i);			AR5K_REG_WRITE((u_int32_t)ar5212_ini[i].ini_register,			    ar5212_ini[i].ini_value);		}	}	/*	 * Write initial RF gain settings	 */	if (ar5k_rfgain(hal, phy, freq) == AH_FALSE) {		*status = HAL_EIO;		return (AH_FALSE);	}	AR5K_DELAY(1000);	/*	 * Set rate duration table	 */	rt = ar5k_ar5212_get_rate_table(hal,	    channel->c_channel_flags & IEEE80211_CHAN_TURBO ?	    HAL_MODE_TURBO : HAL_MODE_XR);	for (i = 0; i < rt->rt_rate_count; i++) {		AR5K_REG_WRITE(AR5K_AR5212_RATE_DUR(rt->rt_info[i].r_rate_code),		    ath_hal_computetxtime(hal, rt, 14,		    rt->rt_info[i].r_control_rate, AH_FALSE));	}	if ((channel->c_channel_flags & IEEE80211_CHAN_TURBO) == 0) {		rt = ar5k_ar5212_get_rate_table(hal, HAL_MODE_11B);		for (i = 0; i < rt->rt_rate_count; i++) {			data = AR5K_AR5212_RATE_DUR(rt->rt_info[i].r_rate_code);			AR5K_REG_WRITE(data,			    ath_hal_computetxtime(hal, rt, 14,			    rt->rt_info[i].r_control_rate, AH_FALSE));			if (rt->rt_info[i].r_short_preamble) {				AR5K_REG_WRITE(data +				    (rt->rt_info[i].r_short_preamble << 2),				    ath_hal_computetxtime(hal, rt, 14,				    rt->rt_info[i].r_control_rate, AH_FALSE));			}		}	}	/* Fix for first revision of the AR5112 RF chipset */	if (hal->ah_radio >= AR5K_AR5112 &&		hal->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {			AR5K_REG_WRITE(AR5K_AR5212_PHY_CCKTXCTL,			AR5K_AR5212_PHY_CCKTXCTL_WORLD);		if (channel->c_channel_flags & IEEE80211_CHAN_OFDM)			data = 0xffb81020;		else			data = 0xffb80d20;		AR5K_REG_WRITE(AR5K_AR5212_PHY_FC, data);	}	/*	 * Set TX power (XXX use txpower from net80211)	 */	if (ar5k_ar5212_txpower(hal, channel,		AR5K_TUNE_DEFAULT_TXPOWER) == AH_FALSE) {		*status = HAL_EIO;		return (AH_FALSE);	}	/*	 * Write RF registers	 */	if (ar5k_rfregs(hal, channel, mode) == AH_FALSE) {		*status = HAL_EINPROGRESS;		return (AH_FALSE);	}	/*	 * Configure additional registers	 */	/* OFDM timings */	if (channel->c_channel_flags & IEEE80211_CHAN_OFDM) {		u_int32_t coef_scaled, coef_exp, coef_man, ds_coef_exp,		    ds_coef_man, clock;		clock = channel->c_channel_flags & IEEE80211_CHAN_T ? 80 : 40;		coef_scaled = ((5 * (clock << 24)) / 2) / channel->c_channel;		for (coef_exp = 31; coef_exp > 0; coef_exp--)			if ((coef_scaled >> coef_exp) & 0x1)				break;		if (!coef_exp) {			*status = HAL_EINVAL;			return (AH_FALSE);		}		coef_exp = 14 - (coef_exp - 24);		coef_man = coef_scaled + (1 << (24 - coef_exp - 1));		ds_coef_man = coef_man >> (24 - coef_exp);		ds_coef_exp = coef_exp - 16;		AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_TIMING_3,		    AR5K_AR5212_PHY_TIMING_3_DSC_MAN, ds_coef_man);		AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_TIMING_3,		    AR5K_AR5212_PHY_TIMING_3_DSC_EXP, ds_coef_exp);	}	if (hal->ah_radio == AR5K_AR5111) {		if (channel->c_channel_flags & IEEE80211_CHAN_B)			AR5K_REG_ENABLE_BITS(AR5K_AR5212_TXCFG,			    AR5K_AR5212_TXCFG_B_MODE);		else			AR5K_REG_DISABLE_BITS(AR5K_AR5212_TXCFG,			    AR5K_AR5212_TXCFG_B_MODE);	}	/* Set antenna mode */	AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x44),	    hal->ah_antenna[ee_mode][0], 0xfffffc06);	ant[0] = HAL_ANT_FIXED_A;	ant[1] = HAL_ANT_FIXED_B;	if (hal->ah_ant_diversity == AH_FALSE) {		if (freq == AR5K_INI_RFGAIN_2GHZ)			ant[0] = HAL_ANT_FIXED_B;		else			ant[1] = HAL_ANT_FIXED_A;	}	AR5K_REG_WRITE(AR5K_AR5212_PHY_ANT_SWITCH_TABLE_0,	    hal->ah_antenna[ee_mode][ant[0]]);	AR5K_REG_WRITE(AR5K_AR5212_PHY_ANT_SWITCH_TABLE_1,	    hal->ah_antenna[ee_mode][ant[1]]);	/* Commit values from EEPROM */	if (hal->ah_radio == AR5K_AR5111)		AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_FC,		    AR5K_AR5212_PHY_FC_TX_CLIP, ee->ee_tx_clip);	AR5K_REG_WRITE(AR5K_AR5212_PHY(0x5a),	    AR5K_AR5212_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]));	AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x11),	    (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80, 0xffffc07f);	AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x12),	    (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000, 0xfffc0fff);	AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x14),	    (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |	    ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00), 0xffff0000);	AR5K_REG_WRITE(AR5K_AR5212_PHY(0x0d),	    (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |	    (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |	    (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |	    (ee->ee_tx_frm2xpa_enable[ee_mode]));	AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x0a),	    ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);	AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x19),	    (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);	AR5K_REG_MASKED_BITS(AR5K_AR5212_PHY(0x49), 4, 0xffffff01);	AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,	    AR5K_AR5212_PHY_IQ_CORR_ENABLE |	    (ee->ee_i_cal[ee_mode] << AR5K_AR5212_PHY_IQ_CORR_Q_I_COFF_S) |	    ee->ee_q_cal[ee_mode]);	if (hal->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {		AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_GAIN_2GHZ,		    AR5K_AR5212_PHY_GAIN_2GHZ_MARGIN_TXRX,		    ee->ee_margin_tx_rx[ee_mode]);	}	/*	 * Restore saved values	 */	AR5K_REG_WRITE(AR5K_AR5212_DCU_SEQNUM(0), s_seq);	AR5K_REG_WRITE(AR5K_AR5212_DEFAULT_ANTENNA, s_ant);	AR5K_REG_ENABLE_BITS(AR5K_AR5212_PCICFG, s_led[0]);	AR5K_REG_WRITE(AR5K_AR5212_GPIOCR, s_led[1]);	AR5K_REG_WRITE(AR5K_AR5212_GPIODO, s_led[2]);	/*	 * Misc	 */	bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);	ar5k_ar5212_set_associd(hal, mac, 0);	ar5k_ar5212_set_opmode(hal);	AR5K_REG_WRITE(AR5K_AR5212_PISR, 0xffffffff);	AR5K_REG_WRITE(AR5K_AR5212_RSSI_THR, AR5K_TUNE_RSSI_THRES);	/*	 * Set Rx/Tx DMA Configuration	 */	AR5K_REG_WRITE_BITS(AR5K_AR5212_TXCFG, AR5K_AR5212_TXCFG_SDMAMR,	    AR5K_AR5212_DMASIZE_512B | AR5K_AR5212_TXCFG_DMASIZE);	AR5K_REG_WRITE_BITS(AR5K_AR5212_RXCFG, AR5K_AR5212_RXCFG_SDMAMW,	    AR5K_AR5212_DMASIZE_512B);	/*	 * Set channel and calibrate the PHY	 */	if (ar5k_channel(hal, channel) == AH_FALSE) {		*status = HAL_EIO;		return (AH_FALSE);	}	/*	 * Enable the PHY and wait until completion	 */	AR5K_REG_WRITE(AR5K_AR5212_PHY_ACTIVE, AR5K_AR5212_PHY_ENABLE);	data = AR5K_REG_READ(AR5K_AR5212_PHY_RX_DELAY) &	    AR5K_AR5212_PHY_RX_DELAY_M;	data = (channel->c_channel_flags & IEEE80211_CHAN_CCK) ?	    ((data << 2) / 22) : (data / 10);	AR5K_DELAY(100 + data);	/*	 * Start calibration	 */	AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_AGCCTL,	    AR5K_AR5212_PHY_AGCCTL_NF |	    AR5K_AR5212_PHY_AGCCTL_CAL);		hal->ah_calibration = AH_FALSE;	if ((channel->c_channel_flags & IEEE80211_CHAN_B) == 0) {		hal->ah_calibration = AH_TRUE;		AR5K_REG_WRITE_BITS(AR5K_AR5212_PHY_IQ,		    AR5K_AR5212_PHY_IQ_CAL_NUM_LOG_MAX, 15);		AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,		    AR5K_AR5212_PHY_IQ_RUN);	}	/*	 * Reset queues and start beacon timers at the end of the reset routine	 */	for (i = 0; i < hal->ah_capabilities.cap_queues.q_tx_num; i++) {		AR5K_REG_WRITE_Q(AR5K_AR5212_DCU_QCUMASK(i), i);		if (ar5k_ar5212_reset_tx_queue(hal, i) == AH_FALSE) {			AR5K_PRINTF("failed to reset TX queue #%d\n", i);			*status = HAL_EINVAL;			return (AH_FALSE);		}	}	/* Pre-enable interrupts */	ar5k_ar5212_set_intr(hal, HAL_INT_RX | HAL_INT_TX | HAL_INT_FATAL);	/*	 * Set RF kill flags if supported by the device (read from the EEPROM)	 */	if (AR5K_EEPROM_HDR_RFKILL(hal->ah_capabilities.cap_eeprom.ee_header)) {		ar5k_ar5212_set_gpio_input(hal, 0);		if ((hal->ah_gpio[0] = ar5k_ar5212_get_gpio(hal, 0)) == 0)			ar5k_ar5212_set_gpio_intr(hal, 0, 1);		else			ar5k_ar5212_set_gpio_intr(hal, 0, 0);	}	/*	 * Set the 32MHz reference clock	 */	AR5K_REG_WRITE(AR5K_AR5212_PHY_SCR, AR5K_AR5212_PHY_SCR_32MHZ);	AR5K_REG_WRITE(AR5K_AR5212_PHY_SLMT, AR5K_AR5212_PHY_SLMT_32MHZ);	AR5K_REG_WRITE(AR5K_AR5212_PHY_SCAL, AR5K_AR5212_PHY_SCAL_32MHZ);	AR5K_REG_WRITE(AR5K_AR5212_PHY_SCLOCK, AR5K_AR5212_PHY_SCLOCK_32MHZ);	AR5K_REG_WRITE(AR5K_AR5212_PHY_SDELAY, AR5K_AR5212_PHY_SDELAY_32MHZ);	AR5K_REG_WRITE(AR5K_AR5212_PHY_SPENDING, hal->ah_radio == AR5K_AR5111 ?	    AR5K_AR5212_PHY_SPENDING_AR5111 : AR5K_AR5212_PHY_SPENDING_AR5112);	/* 	 * Disable beacons and reset the register	 */	AR5K_REG_DISABLE_BITS(AR5K_AR5212_BEACON,	    AR5K_AR5212_BEACON_ENABLE | AR5K_AR5212_BEACON_RESET_TSF);	return (AH_TRUE);}void /*Unimplemented*/ar5k_ar5212_set_def_antenna(struct ath_hal *hal, u_int ant){	AR5K_TRACE;	return;}u_int/*Unimplemented*/ar5k_ar5212_get_def_antenna(struct ath_hal *hal){	AR5K_TRACE;	return 0;}void /*O.K.*/ar5k_ar5212_set_opmode(struct ath_hal *hal){	u_int32_t pcu_reg, low_id, high_id;	pcu_reg = 0;	AR5K_TRACE;	switch (hal->ah_op_mode) {	case IEEE80211_M_IBSS:		pcu_reg |= AR5K_AR5212_STA_ID1_ADHOC |		    AR5K_AR5212_STA_ID1_DESC_ANTENNA;		break;	case IEEE80211_M_HOSTAP:		pcu_reg |= AR5K_AR5212_STA_ID1_AP |		    AR5K_AR5212_STA_ID1_RTS_DEFAULT_ANTENNA;		break;	case IEEE80211_M_STA:	case IEEE80211_M_MONITOR:		pcu_reg |= AR5K_AR5212_STA_ID1_DEFAULT_ANTENNA;		break;	default:		return;	}	/*	 * Set PCU registers	 */	bcopy(&(hal->ah_sta_id[0]), &low_id, 4);	bcopy(&(hal->ah_sta_id[4]), &high_id, 2);	AR5K_REG_WRITE(AR5K_AR5212_STA_ID0, low_id);	AR5K_REG_WRITE(AR5K_AR5212_STA_ID1, pcu_reg | high_id);	return;}void /*New*/ar5k_ar5212_set_pcu_config(struct ath_hal *hal){	AR5K_TRACE;	ar5k_ar5212_set_opmode(hal);	return;}HAL_BOOL /*O.K.*/ar5k_ar5212_calibrate(struct ath_hal *hal, HAL_CHANNEL *channel){	u_int32_t i_pwr, q_pwr;	int32_t iq_corr, i_coff, i_coffd, q_coff, q_coffd;	AR5K_TRACE;	if (hal->ah_calibration == AH_FALSE ||	    AR5K_REG_READ(AR5K_AR5212_PHY_IQ) & AR5K_AR5212_PHY_IQ_RUN)		goto done;	hal->ah_calibration = AH_FALSE;	iq_corr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_CORR);	i_pwr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_PWR_I);	q_pwr = AR5K_REG_READ(AR5K_AR5212_PHY_IQRES_CAL_PWR_Q);	i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;	q_coffd = q_pwr >> 6;	if (i_coffd == 0 || q_coffd == 0)		goto done;	i_coff = ((-iq_corr) / i_coffd) & 0x3f;	q_coff = (((int32_t)i_pwr / q_coffd) - 64) & 0x1f;	/* Commit new IQ value */	AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_IQ,	    AR5K_AR5212_PHY_IQ_CORR_ENABLE |	    ((u_int32_t)q_coff) |	    ((u_int32_t)i_coff << AR5K_AR5212_PHY_IQ_CORR_Q_I_COFF_S)); done:	/* Start noise floor calibration */	AR5K_REG_ENABLE_BITS(AR5K_AR5212_PHY_AGCCTL,	    AR5K_AR5212_PHY_AGCCTL_NF);	/* Request RF gain */	if (channel->c_channel_flags & IEEE80211_CHAN_5GHZ) {		AR5K_REG_WRITE(AR5K_AR5212_PHY_PAPD_PROBE,		    AR5K_REG_SM(hal->ah_txpower.txp_max,		    AR5K_AR5212_PHY_PAPD_PROBE_TXPOWER) |		    AR5K_AR5212_PHY_PAPD_PROBE_TX_NEXT);		hal->ah_rf_gain = HAL_RFGAIN_READ_REQUESTED;	}	return (AH_TRUE);}/* * Transmit functions */HAL_BOOL /*O.K.*/ar5k_ar5212_update_tx_triglevel(struct ath_hal *hal, HAL_BOOL increase){	u_int32_t trigger_level, imr;	HAL_BOOL status = AH_FALSE;	AR5K_TRACE;	/*	 * Disable interrupts by setting the mask	 */	imr = ar5k_ar5212_set_intr(hal, hal->ah_imr & ~HAL_INT_GLOBAL);	trigger_level = AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5212_TXCFG),	    AR5K_AR5212_TXCFG_TXFULL);	if (increase == AH_FALSE) {		if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)			goto done;	} else		trigger_level +=		    ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);	/*	 * Update trigger level on success	 */	AR5K_REG_WRITE_BITS(AR5K_AR5212_TXCFG,	    AR5K_AR5212_TXCFG_TXFULL, trigger_level);	status = AH_TRUE; done:

⌨️ 快捷键说明

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