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

📄 ar5211.c

📁 无线网卡驱动 固件程序 There are currently 3 "programming generations" of Atheros 802.11 wireless devices (
💻 C
📖 第 1 页 / 共 5 页
字号:
	 * Configure additional registers	 */	if (hal->ah_radio == AR5K_AR5111) {		if (channel->c_channel_flags & IEEE80211_CHAN_B)			AR5K_REG_ENABLE_BITS(AR5K_AR5211_TXCFG,			    AR5K_AR5211_TXCFG_B_MODE);		else			AR5K_REG_DISABLE_BITS(AR5K_AR5211_TXCFG,			    AR5K_AR5211_TXCFG_B_MODE);	}	/* Set antenna mode */	AR5K_REG_MASKED_BITS(AR5K_AR5211_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 if (freq == AR5K_INI_RFGAIN_5GHZ)			ant[1] = HAL_ANT_FIXED_A;	}	AR5K_REG_WRITE(AR5K_AR5211_PHY_ANT_SWITCH_TABLE_0,	    hal->ah_antenna[ee_mode][ant[0]]);	AR5K_REG_WRITE(AR5K_AR5211_PHY_ANT_SWITCH_TABLE_1,	    hal->ah_antenna[ee_mode][ant[1]]);	/* Commit values from EEPROM */	AR5K_REG_WRITE_BITS(AR5K_AR5211_PHY_FC,	    AR5K_AR5211_PHY_FC_TX_CLIP, ee->ee_tx_clip);	AR5K_REG_WRITE(AR5K_AR5211_PHY(0x5a),	    AR5K_AR5211_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]));	AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x11),	    (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80, 0xffffc07f);	AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x12),	    (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000, 0xfffc0fff);	AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x14),	    (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |	    ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00), 0xffff0000);	AR5K_REG_WRITE(AR5K_AR5211_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_AR5211_PHY(0x0a),	    ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);	AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x19),	    (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);	AR5K_REG_MASKED_BITS(AR5K_AR5211_PHY(0x49), 4, 0xffffff01);	AR5K_REG_ENABLE_BITS(AR5K_AR5211_PHY_IQ,	    AR5K_AR5211_PHY_IQ_CORR_ENABLE |	    (ee->ee_i_cal[ee_mode] << AR5K_AR5211_PHY_IQ_CORR_Q_I_COFF_S) |	    ee->ee_q_cal[ee_mode]);	/*	 * Restore saved values	 */	AR5K_REG_WRITE(AR5K_AR5211_DCU_SEQNUM(0), s_seq);	AR5K_REG_WRITE(AR5K_AR5211_DEFAULT_ANTENNA, s_ant);	AR5K_REG_ENABLE_BITS(AR5K_AR5211_PCICFG, s_led[0]);	AR5K_REG_WRITE(AR5K_AR5211_GPIOCR, s_led[1]);	AR5K_REG_WRITE(AR5K_AR5211_GPIODO, s_led[2]);	/*	 * Misc	 */	bcopy(etherbroadcastaddr, mac, IEEE80211_ADDR_LEN);	ar5k_ar5211_set_associd(hal, mac, 0);	ar5k_ar5211_set_opmode(hal);	AR5K_REG_WRITE(AR5K_AR5211_PISR, 0xffffffff);	AR5K_REG_WRITE(AR5K_AR5211_RSSI_THR, AR5K_TUNE_RSSI_THRES);	/*	 * Set Rx/Tx DMA Configuration	 */	AR5K_REG_WRITE_BITS(AR5K_AR5211_TXCFG, AR5K_AR5211_TXCFG_SDMAMR,	    AR5K_AR5211_DMASIZE_512B | AR5K_AR5211_TXCFG_DMASIZE);	AR5K_REG_WRITE_BITS(AR5K_AR5211_RXCFG, AR5K_AR5211_RXCFG_SDMAMW,	    AR5K_AR5211_DMASIZE_512B);	/*	 * Set channel and calibrate the PHY	 */	if (ar5k_channel(hal, channel) == AH_FALSE)		return (AH_FALSE);	/*	 * Enable the PHY and wait until completion	 */	AR5K_REG_WRITE(AR5K_AR5211_PHY_ACTIVE, AR5K_AR5211_PHY_ENABLE);	data = AR5K_REG_READ(AR5K_AR5211_PHY_RX_DELAY) &	    AR5K_AR5211_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_AR5211_PHY_AGCCTL,	    AR5K_AR5211_PHY_AGCCTL_NF |	    AR5K_AR5211_PHY_AGCCTL_CAL);	if (channel->c_channel_flags & IEEE80211_CHAN_B) {		hal->ah_calibration = AH_FALSE;	} else {		hal->ah_calibration = AH_TRUE;		AR5K_REG_WRITE_BITS(AR5K_AR5211_PHY_IQ,		    AR5K_AR5211_PHY_IQ_CAL_NUM_LOG_MAX, 15);		AR5K_REG_ENABLE_BITS(AR5K_AR5211_PHY_IQ,		    AR5K_AR5211_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_AR5211_DCU_QCUMASK(i), i);		if (ar5k_ar5211_reset_tx_queue(hal, i) == AH_FALSE) {			AR5K_PRINTF("failed to reset TX queue #%d\n", i);			return (AH_FALSE);		}	}	/* Pre-enable interrupts */	ar5k_ar5211_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_ar5211_set_gpio_input(hal, 0);		if ((hal->ah_gpio[0] = ar5k_ar5211_get_gpio(hal, 0)) == 0)			ar5k_ar5211_set_gpio_intr(hal, 0, 1);		else			ar5k_ar5211_set_gpio_intr(hal, 0, 0);	}	/* 	 * Disable beacons and reset the register	 */	AR5K_REG_DISABLE_BITS(AR5K_AR5211_BEACON,	    AR5K_AR5211_BEACON_ENABLE | AR5K_AR5211_BEACON_RESET_TSF);	return (AH_TRUE);}void /*Unimplemented*/ar5k_ar5211_set_def_antenna(struct ath_hal *hal, u_int ant){	AR5K_TRACE;	return;}u_int/*Unimplemented*/ar5k_ar5211_get_def_antenna(struct ath_hal *hal){	AR5K_TRACE;	return 0;}voidar5k_ar5211_set_opmode(struct ath_hal *hal){	u_int32_t pcu_reg, low_id, high_id;	pcu_reg = 0;	switch (hal->ah_op_mode) {	case IEEE80211_M_IBSS:		pcu_reg |= AR5K_AR5211_STA_ID1_ADHOC |		    AR5K_AR5211_STA_ID1_DESC_ANTENNA;		break;	case IEEE80211_M_HOSTAP:		pcu_reg |= AR5K_AR5211_STA_ID1_AP |		    AR5K_AR5211_STA_ID1_RTS_DEFAULT_ANTENNA;		break;	case IEEE80211_M_STA:	case IEEE80211_M_MONITOR:		pcu_reg |= AR5K_AR5211_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_AR5211_STA_ID0, low_id);	AR5K_REG_WRITE(AR5K_AR5211_STA_ID1, pcu_reg | high_id);	return;}void /*New*/ar5k_ar5211_set_pcu_config(struct ath_hal *hal){	AR5K_TRACE;	ar5k_ar5211_set_opmode(hal);	return;}HAL_BOOLar5k_ar5211_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;	if (hal->ah_calibration == AH_FALSE ||	    AR5K_REG_READ(AR5K_AR5211_PHY_IQ) & AR5K_AR5211_PHY_IQ_RUN)		goto done;	hal->ah_calibration = AH_FALSE;	iq_corr = AR5K_REG_READ(AR5K_AR5211_PHY_IQRES_CAL_CORR);	i_pwr = AR5K_REG_READ(AR5K_AR5211_PHY_IQRES_CAL_PWR_I);	q_pwr = AR5K_REG_READ(AR5K_AR5211_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_AR5211_PHY_IQ,	    AR5K_AR5211_PHY_IQ_CORR_ENABLE |	    ((u_int32_t)q_coff) |	    ((u_int32_t)i_coff << AR5K_AR5211_PHY_IQ_CORR_Q_I_COFF_S)); done:	/* Start noise floor calibration */	AR5K_REG_ENABLE_BITS(AR5K_AR5211_PHY_AGCCTL,	    AR5K_AR5211_PHY_AGCCTL_NF);	return (AH_TRUE);}/* * Transmit functions */HAL_BOOLar5k_ar5211_update_tx_triglevel(struct ath_hal *hal, HAL_BOOL increase){	u_int32_t trigger_level, imr;	HAL_BOOL status = AH_FALSE;	/*	 * Disable interrupts by setting the mask	 */	imr = ar5k_ar5211_set_intr(hal, hal->ah_imr & ~HAL_INT_GLOBAL);	trigger_level = AR5K_REG_MS(AR5K_REG_READ(AR5K_AR5211_TXCFG),	    AR5K_AR5211_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_AR5211_TXCFG,	    AR5K_AR5211_TXCFG_TXFULL, trigger_level);	status = AH_TRUE; done:	/*	 * Restore interrupt mask	 */	ar5k_ar5211_set_intr(hal, imr);	return (status);}intar5k_ar5211_setup_tx_queue(struct ath_hal *hal, HAL_TX_QUEUE queue_type,    const HAL_TXQ_INFO *queue_info){	u_int queue;	/*	 * Get queue by type	 */	if (queue_type == HAL_TX_QUEUE_DATA) {		for (queue = HAL_TX_QUEUE_ID_DATA_MIN;		     hal->ah_txq[queue].tqi_type != HAL_TX_QUEUE_INACTIVE;		     queue++)			if (queue > HAL_TX_QUEUE_ID_DATA_MAX)				return (-1);	} else if (queue_type == HAL_TX_QUEUE_PSPOLL) {		queue = HAL_TX_QUEUE_ID_PSPOLL;	} else if (queue_type == HAL_TX_QUEUE_BEACON) {		queue = HAL_TX_QUEUE_ID_BEACON;	} else if (queue_type == HAL_TX_QUEUE_CAB) {		queue = HAL_TX_QUEUE_ID_CAB;	} else		return (-1);	/*	 * Setup internal queue structure	 */	bzero(&hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));	hal->ah_txq[queue].tqi_type = queue_type;	if (queue_info != NULL) {		if (ar5k_ar5211_setup_tx_queueprops(hal, queue, queue_info)		    != AH_TRUE)			return (-1);	}	AR5K_Q_ENABLE_BITS(hal->ah_txq_interrupts, queue);	return (queue);}HAL_BOOLar5k_ar5211_setup_tx_queueprops(struct ath_hal *hal, int queue,    const HAL_TXQ_INFO *queue_info){	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);	if (hal->ah_txq[queue].tqi_type == HAL_TX_QUEUE_INACTIVE)		return (AH_FALSE);	bcopy(queue_info, &hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));	if (queue_info->tqi_type == HAL_TX_QUEUE_DATA &&	    (queue_info->tqi_subtype >= HAL_WME_AC_VI) &&	    (queue_info->tqi_subtype <= HAL_WME_UPSD))		hal->ah_txq[queue].tqi_flags |=		    AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;	return (AH_TRUE);}HAL_BOOL /*New*/ar5k_ar5211_get_tx_queueprops(struct ath_hal *hal, int queue, HAL_TXQ_INFO *queue_info){	AR5K_TRACE;	memcpy(queue_info, &hal->ah_txq[queue], sizeof(HAL_TXQ_INFO));	return (AH_TRUE);}HAL_BOOLar5k_ar5211_release_tx_queue(struct ath_hal *hal, u_int queue){	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);	/* This queue will be skipped in further operations */	hal->ah_txq[queue].tqi_type = HAL_TX_QUEUE_INACTIVE;	AR5K_Q_DISABLE_BITS(hal->ah_txq_interrupts, queue);	return (AH_FALSE);}HAL_BOOLar5k_ar5211_reset_tx_queue(struct ath_hal *hal, u_int queue){	u_int32_t cw_min, cw_max, retry_lg, retry_sh;	struct ieee80211_channel *channel = (struct ieee80211_channel*)	    &hal->ah_current_channel;	HAL_TXQ_INFO *tq;	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);	tq = &hal->ah_txq[queue];	if (tq->tqi_type == HAL_TX_QUEUE_INACTIVE)		return (AH_TRUE);	/*	 * Set registers by channel mode	 */	if (IEEE80211_IS_CHAN_B(channel)) {		hal->ah_cw_min = AR5K_TUNE_CWMIN_11B;		cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX_11B;		hal->ah_aifs = AR5K_TUNE_AIFS_11B;	} else {		hal->ah_cw_min = AR5K_TUNE_CWMIN;		cw_max = hal->ah_cw_max = AR5K_TUNE_CWMAX;		hal->ah_aifs = AR5K_TUNE_AIFS;	}	/*	 * Set retry limits	 */	if (hal->ah_software_retry == AH_TRUE) {		/* XXX Need to test this */		retry_lg = hal->ah_limit_tx_retries;		retry_sh = retry_lg =		    retry_lg > AR5K_AR5211_DCU_RETRY_LMT_SH_RETRY ?		    AR5K_AR5211_DCU_RETRY_LMT_SH_RETRY : retry_lg;	} else {		retry_lg = AR5K_INIT_LG_RETRY;		retry_sh = AR5K_INIT_SH_RETRY;	}	AR5K_REG_WRITE(AR5K_AR5211_DCU_RETRY_LMT(queue),	    AR5K_REG_SM(AR5K_INIT_SLG_RETRY,	    AR5K_AR5211_DCU_RETRY_LMT_SLG_RETRY) |	    AR5K_REG_SM(AR5K_INIT_SSH_RETRY,	    AR5K_AR5211_DCU_RETRY_LMT_SSH_RETRY) |	    AR5K_REG_SM(retry_lg, AR5K_AR5211_DCU_RETRY_LMT_LG_RETRY) |	    AR5K_REG_SM(retry_sh, AR5K_AR5211_DCU_RETRY_LMT_SH_RETRY));	/*	 * Set initial content window (cw_min/cw_max)	 */	cw_min = 1;	while (cw_min < hal->ah_cw_min)		cw_min = (cw_min << 1) | 1;	cw_min = tq->tqi_cw_min < 0 ?	    (cw_min >> (-tq->tqi_cw_min)) :	    ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);	cw_max = tq->tqi_cw_max < 0 ?	    (cw_max >> (-tq->tqi_cw_max)) :	    ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);	AR5K_REG_WRITE(AR5K_AR5211_DCU_LCL_IFS(queue),	    AR5K_REG_SM(cw_min, AR5K_AR5211_DCU_LCL_IFS_CW_MIN) |	    AR5K_REG_SM(cw_max, AR5K_AR5211_DCU_LCL_IFS_CW_MAX) |	    AR5K_REG_SM(hal->ah_aifs + tq->tqi_aifs,	    AR5K_AR5211_DCU_LCL_IFS_AIFS));	/*	 * Set misc registers	 */	AR5K_REG_WRITE(AR5K_AR5211_QCU_MISC(queue),	    AR5K_AR5211_QCU_MISC_DCU_EARLY);	if (tq->tqi_cbr_period) {		AR5K_REG_WRITE(AR5K_AR5211_QCU_CBRCFG(queue),		    AR5K_REG_SM(tq->tqi_cbr_period,		    AR5K_AR5211_QCU_CBRCFG_INTVAL) |		    AR5K_REG_SM(tq->tqi_cbr_overflow_limit,		    AR5K_AR5211_QCU_CBRCFG_ORN_THRES));		AR5K_REG_ENABLE_BITS(AR5K_AR5211_QCU_MISC(queue),		    AR5K_AR5211_QCU_MISC_FRSHED_CBR);		if (tq->tqi_cbr_overflow_limit)			AR5K_REG_ENABLE_BITS(AR5K_AR5211_QCU_MISC(queue),			    AR5K_AR5211_QCU_MISC_CBR_THRES_ENABLE);	}	if (tq->tqi_ready_time) {		AR5K_REG_WRITE(AR5K_AR5211_QCU_RDYTIMECFG(queue),		    AR5K_REG_SM(tq->tqi_ready_time,		    AR5K_AR5211_QCU_RDYTIMECFG_INTVAL) |		    AR5K_AR5211_QCU_RDYTIMECFG_ENABLE);	}	if (tq->tqi_burst_time) {		AR5K_REG_WRITE(AR5K_AR5211_DCU_CHAN_TIME(queue),		    AR5K_REG_SM(tq->tqi_burst_time,		    AR5K_AR5211_DCU_CHAN_TIME_DUR) |		    AR5K_AR5211_DCU_CHAN_TIME_ENABLE);		if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) {			AR5K_REG_ENABLE_BITS(AR5K_AR5211_QCU_MISC(queue),			    AR5K_AR5211_QCU_MISC_TXE);		}	}	if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) {		AR5K_REG_WRITE(AR5K_AR5211_DCU_MISC(queue),		    AR5K_AR5211_DCU_MISC_POST_FR_BKOFF_DIS);	}	if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {		AR5K_REG_WRITE(AR5K_AR5211_DCU_MISC(queue),		    AR5K_AR5211_DCU_MISC_BACKOFF_FRAG);	}	/*	 * Set registers by queue type	 */	switch (tq->tqi_type) {	case HAL_TX_QUEUE_BEACON:		AR5K_REG_ENABLE_BITS(AR5K_AR5211_QCU_MISC(queue),		    AR5K_AR5211_QCU_MISC_FRSHED_DBA_GT |		    AR5K_AR5211_QCU_MISC_CBREXP_BCN |		    AR5K_AR5211_QCU_MISC_BCN_ENABLE);		AR5K_REG_ENABLE_BITS(AR5K_AR5211_DCU_MISC(queue),		    (AR5K_AR5211_DCU_MISC_ARBLOCK_CTL_GLOBAL <<		    AR5K_AR5211_DCU_MISC_ARBLOCK_CTL_GLOBAL) |		    AR5K_AR5211_DCU_MISC_POST_FR_BKOFF_DIS |

⌨️ 快捷键说明

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