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

📄 ar5210.c

📁 无线网卡驱动 固件程序 There are currently 3 "programming generations" of Atheros 802.11 wireless devices (
💻 C
📖 第 1 页 / 共 4 页
字号:
	 */	AR5K_REG_DISABLE_BITS(AR5K_AR5210_DIAG_SW,	    AR5K_AR5210_DIAG_SW_DIS_TX | AR5K_AR5210_DIAG_SW_DIS_RX);	AR5K_REG_WRITE(AR5K_AR5210_BEACON, beacon);#undef AGC_ENABLE#undef AGC_DISABLE	return (AH_TRUE);}HAL_BOOLar5k_ar5210_do_calibrate(struct ath_hal *hal, HAL_CHANNEL *channel){	/*	 * Enable calibration and wait until completion	 */	AR5K_REG_ENABLE_BITS(AR5K_AR5210_PHY_AGCCTL,	    AR5K_AR5210_PHY_AGCCTL_CAL);	if (ar5k_register_timeout(hal, AR5K_AR5210_PHY_AGCCTL,		AR5K_AR5210_PHY_AGCCTL_CAL, 0, AH_FALSE) == AH_FALSE) {		AR5K_PRINTF("calibration timeout (%uMHz)\n",		    channel->c_channel);		return (AH_FALSE);	}	return (AH_TRUE);}HAL_BOOLar5k_ar5210_noise_floor(struct ath_hal *hal, HAL_CHANNEL *channel){	int i;	u_int32_t noise_floor;	/*	 * Enable noise floor calibration and wait until completion	 */	AR5K_REG_ENABLE_BITS(AR5K_AR5210_PHY_AGCCTL,	    AR5K_AR5210_PHY_AGCCTL_NF);	if (ar5k_register_timeout(hal, AR5K_AR5210_PHY_AGCCTL,		AR5K_AR5210_PHY_AGCCTL_NF, 0, AH_FALSE) == AH_FALSE) {		AR5K_PRINTF("noise floor calibration timeout (%uMHz)\n",		    channel->c_channel);		return (AH_FALSE);	}	/* wait until the noise floor is calibrated */	for (i = 20; i > 0; i--) {		AR5K_DELAY(1000);		noise_floor = AR5K_REG_READ(AR5K_AR5210_PHY_NF);		if (AR5K_AR5210_PHY_NF_RVAL(noise_floor) &		    AR5K_AR5210_PHY_NF_ACTIVE)			noise_floor = AR5K_AR5210_PHY_NF_AVAL(noise_floor);		if (noise_floor <= AR5K_TUNE_NOISE_FLOOR)			break;	}	if (noise_floor > AR5K_TUNE_NOISE_FLOOR) {		AR5K_PRINTF("noise floor calibration failed (%uMHz)\n",		    channel->c_channel);		return (AH_FALSE);	}	return (AH_TRUE);}/* * Transmit functions */HAL_BOOLar5k_ar5210_update_tx_triglevel(struct ath_hal *hal, HAL_BOOL increase){	u_int32_t trigger_level;	HAL_BOOL status = AH_FALSE;	/*	 * Disable interrupts by setting the mask	 */	AR5K_REG_DISABLE_BITS(AR5K_AR5210_IMR, HAL_INT_GLOBAL);	trigger_level = AR5K_REG_READ(AR5K_AR5210_TRIG_LVL);	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(AR5K_AR5210_TRIG_LVL, trigger_level);	status = AH_TRUE; done:	/*	 * Restore interrupt mask	 */	AR5K_REG_ENABLE_BITS(AR5K_AR5210_IMR, HAL_INT_GLOBAL);	return (status);}intar5k_ar5210_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	 */	switch (queue_type) {	case HAL_TX_QUEUE_DATA:		queue = 0;		break;	case HAL_TX_QUEUE_BEACON:	case HAL_TX_QUEUE_CAB:		queue = 1;		break;	default:		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_ar5210_setup_tx_queueprops(hal,			queue, queue_info) != AH_TRUE)			return (-1);	}	return (queue);}HAL_BOOLar5k_ar5210_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);	hal->ah_txq[queue].tqi_aifs = queue_info->tqi_aifs;	hal->ah_txq[queue].tqi_cw_max = queue_info->tqi_cw_max;	hal->ah_txq[queue].tqi_cw_min = queue_info->tqi_cw_min;	hal->ah_txq[queue].tqi_flags = queue_info->tqi_flags;	return (AH_TRUE);}HAL_BOOL /*New*/ar5k_ar5210_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_ar5210_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;	return (AH_FALSE);}voidar5k_ar5210_init_tx_queue(struct ath_hal *hal, u_int aifs, HAL_BOOL turbo){	int i;	struct {		u_int16_t mode_register;		u_int32_t mode_base, mode_turbo;	} initial[] = AR5K_AR5210_INI_MODE(aifs);	/*	 * Write initial mode register settings	 */	for (i = 0; i < AR5K_ELEMENTS(initial); i++)		AR5K_REG_WRITE((u_int32_t)initial[i].mode_register,		    turbo == AH_TRUE ?		    initial[i].mode_turbo : initial[i].mode_base);}HAL_BOOLar5k_ar5210_reset_tx_queue(struct ath_hal *hal, u_int queue){	u_int32_t cw_min, retry_lg, retry_sh;	HAL_TXQ_INFO *tq;	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);	tq = &hal->ah_txq[queue];	/* Only handle data queues, others will be ignored */	if (tq->tqi_type != HAL_TX_QUEUE_DATA)		return (AH_TRUE);	/* Set turbo/base mode parameters */	ar5k_ar5210_init_tx_queue(hal, hal->ah_aifs + tq->tqi_aifs,	    hal->ah_turbo == AH_TRUE ? AH_TRUE : AH_FALSE);	/*	 * 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_AR5210_RETRY_LMT_SH_RETRY ?		    AR5K_AR5210_RETRY_LMT_SH_RETRY : retry_lg;	} else {		retry_lg = AR5K_INIT_LG_RETRY;		retry_sh = AR5K_INIT_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);	/* Commit values */	AR5K_REG_WRITE(AR5K_AR5210_RETRY_LMT,	    (cw_min << AR5K_AR5210_RETRY_LMT_CW_MIN_S)	    | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, AR5K_AR5210_RETRY_LMT_SLG_RETRY)	    | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, AR5K_AR5210_RETRY_LMT_SSH_RETRY)	    | AR5K_REG_SM(retry_lg, AR5K_AR5210_RETRY_LMT_LG_RETRY)	    | AR5K_REG_SM(retry_sh, AR5K_AR5210_RETRY_LMT_SH_RETRY));	return (AH_TRUE);}u_int32_tar5k_ar5210_get_tx_buf(struct ath_hal *hal, u_int queue){	u_int16_t tx_reg;	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);	/*	 * Get the transmit queue descriptor pointer register by type	 */	switch (hal->ah_txq[queue].tqi_type) {	case HAL_TX_QUEUE_DATA:		tx_reg = AR5K_AR5210_TXDP0;		break;	case HAL_TX_QUEUE_BEACON:	case HAL_TX_QUEUE_CAB:		tx_reg = AR5K_AR5210_TXDP1;		break;	default:		return (0xffffffff);	}	return (AR5K_REG_READ(tx_reg));}HAL_BOOLar5k_ar5210_put_tx_buf(struct ath_hal *hal, u_int queue, u_int32_t phys_addr){	u_int16_t tx_reg;	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);	/*	 * Get the transmit queue descriptor pointer register by type	 */	switch (hal->ah_txq[queue].tqi_type) {	case HAL_TX_QUEUE_DATA:		tx_reg = AR5K_AR5210_TXDP0;		break;	case HAL_TX_QUEUE_BEACON:	case HAL_TX_QUEUE_CAB:		tx_reg = AR5K_AR5210_TXDP1;		break;	default:		return (AH_FALSE);	}	/* Set descriptor pointer */	AR5K_REG_WRITE(tx_reg, phys_addr);	return (AH_TRUE);}u_int32_t  /*Unimplemented*/ar5k_ar5210_num_tx_pending(struct ath_hal *hal, u_int queue) {	AR5K_TRACE;	return (AH_FALSE);}HAL_BOOLar5k_ar5210_tx_start(struct ath_hal *hal, u_int queue){	u_int32_t tx_queue;	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);	tx_queue = AR5K_REG_READ(AR5K_AR5210_CR);	/*	 * Set the queue type	 */	switch (hal->ah_txq[queue].tqi_type) {	case HAL_TX_QUEUE_DATA:		tx_queue |= AR5K_AR5210_CR_TXE0 & ~AR5K_AR5210_CR_TXD0;		break;	case HAL_TX_QUEUE_BEACON:		tx_queue |= AR5K_AR5210_CR_TXE1 & ~AR5K_AR5210_CR_TXD1;		AR5K_REG_WRITE(AR5K_AR5210_BSR,		    AR5K_AR5210_BCR_TQ1V | AR5K_AR5210_BCR_BDMAE);		break;	case HAL_TX_QUEUE_CAB:		tx_queue |= AR5K_AR5210_CR_TXE1 & ~AR5K_AR5210_CR_TXD1;		AR5K_REG_WRITE(AR5K_AR5210_BSR,		    AR5K_AR5210_BCR_TQ1FV | AR5K_AR5210_BCR_TQ1V |		    AR5K_AR5210_BCR_BDMAE);		break;	default:		return (AH_FALSE);	}	/* Start queue */	AR5K_REG_WRITE(AR5K_AR5210_CR, tx_queue);	return (AH_TRUE);}HAL_BOOLar5k_ar5210_stop_tx_dma(struct ath_hal *hal, u_int queue){	u_int32_t tx_queue;	AR5K_ASSERT_ENTRY(queue, hal->ah_capabilities.cap_queues.q_tx_num);	tx_queue = AR5K_REG_READ(AR5K_AR5210_CR);	/*	 * Set by queue type	 */	switch (hal->ah_txq[queue].tqi_type) {	case HAL_TX_QUEUE_DATA:		tx_queue |= AR5K_AR5210_CR_TXD0 & ~AR5K_AR5210_CR_TXE0;		break;	case HAL_TX_QUEUE_BEACON:	case HAL_TX_QUEUE_CAB:		/* XXX Fix me... */		tx_queue |= AR5K_AR5210_CR_TXD1 & ~AR5K_AR5210_CR_TXD1;		AR5K_REG_WRITE(AR5K_AR5210_BSR, 0);		break;	default:		return (AH_FALSE);	}	/* Stop queue */	AR5K_REG_WRITE(AR5K_AR5210_CR, tx_queue);	return (AH_TRUE);}HAL_BOOL /*O.K. - Initialize tx_desc and clear ds_hw */ar5k_ar5210_setup_tx_desc(struct ath_hal *hal, struct ath_desc *desc,    u_int packet_length, u_int header_length, HAL_PKT_TYPE type, u_int tx_power,    u_int tx_rate0, u_int tx_tries0, u_int key_index, u_int antenna_mode,    u_int flags, u_int rtscts_rate, u_int rtscts_duration){	u_int32_t frame_type;	struct ar5k_ar5210_tx_desc *tx_desc;	tx_desc = (struct ar5k_ar5210_tx_desc*)&desc->ds_ctl0;	/*Clear ds_hw*/	bzero(desc->ds_hw, sizeof(desc->ds_hw));	/*	 * Validate input	 */	if (tx_tries0 == 0)		return (AH_FALSE);	/* Initialize status descriptor */	tx_desc->tx_control_0 = 0;	tx_desc->tx_control_1 = 0;	/* Setup status descriptor */	if ((tx_desc->tx_control_0 = (packet_length &	    AR5K_AR5210_DESC_TX_CTL0_FRAME_LEN)) != packet_length)		return (AH_FALSE);	if ((tx_desc->tx_control_0 = (header_length &	    AR5K_AR5210_DESC_TX_CTL0_HEADER_LEN)) != header_length)		return (AH_FALSE);	if (type == HAL_PKT_TYPE_BEACON || type == HAL_PKT_TYPE_PROBE_RESP)		frame_type = AR5K_AR5210_DESC_TX_FRAME_TYPE_NO_DELAY;	else if (type == HAL_PKT_TYPE_PIFS)		frame_type = AR5K_AR5210_DESC_TX_FRAME_TYPE_PIFS;	else		frame_type = type;	tx_desc->tx_control_0 =	    AR5K_REG_SM(frame_type, AR5K_AR5210_DESC_TX_CTL0_FRAME_TYPE);	tx_desc->tx_control_0 |=	    AR5K_REG_SM(tx_rate0, AR5K_AR5210_DESC_TX_CTL0_XMIT_RATE);#define _TX_FLAGS(_c, _flag)						\	if (flags & HAL_TXDESC_##_flag)					\		tx_desc->tx_control_##_c |=				\			AR5K_AR5210_DESC_TX_CTL##_c##_##_flag	_TX_FLAGS(0, CLRDMASK);	_TX_FLAGS(0, INTREQ);	_TX_FLAGS(0, RTSENA);#undef _TX_FLAGS	/*	 * WEP crap	 */	if (key_index != HAL_TXKEYIX_INVALID) {		tx_desc->tx_control_0 |=		    AR5K_AR5210_DESC_TX_CTL0_ENCRYPT_KEY_VALID;		tx_desc->tx_control_1 |=		    AR5K_REG_SM(key_index,		    AR5K_AR5210_DESC_TX_CTL1_ENCRYPT_KEY_INDEX);	}	/*	 * RTS/CTS	 */	if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {		tx_desc->tx_control_1 |=		    rtscts_duration & AR5K_AR5210_DESC_TX_CTL1_RTS_DURATION;	}	return (AH_TRUE);}HAL_BOOL /*Added an argument *last_desc -need revision -don't clear descriptor here*/ar5k_ar5210_fill_tx_desc(struct ath_hal *hal, struct ath_desc *desc,    u_int segment_length, HAL_BOOL first_segment, HAL_BOOL last_segment, const struct ath_desc *last_desc){	struct ar5k_ar5210_tx_desc *tx_desc;	tx_desc = (struct ar5k_ar5210_tx_desc*)&desc->ds_ctl0;	/* Clear status descriptor *///	bzero(desc->ds_hw, sizeof(desc->ds_hw));	/* Validate segment length and initialize the descriptor */	if ((tx_desc->tx_control_1 = (segment_length &	    AR5K_AR5210_DESC_TX_CTL1_BUF_LEN)) != segment_length)		return (AH_FALSE);	if (first_segment != AH_TRUE)		tx_desc->tx_control_0 &= ~AR5K_AR5210_DESC_TX_CTL0_FRAME_LEN;	if (last_segment != AH_TRUE)		tx_desc->tx_control_1 |= AR5K_AR5210_DESC_TX_CTL1_MORE;	return (AH_TRUE);}HAL_BOOLar5k_ar5210_setup_xtx_desc(struct ath_hal *hal, struct ath_desc *desc,    u_int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2,    u_int tx_rate3, u_int tx_tries3){	/*	 * Does this function is for setting up XR? Not sure...	 * Nevertheless, I didn't find any information about XR support	 * by the AR5210. This seems to be a slightly new feature.	 */	return (AH_FALSE);}HAL_STATUSar5k_ar5210_proc_tx_desc(struct ath_hal *hal, struct ath_desc *desc){	struct ar5k_ar5210_tx_status *tx_status;	struct ar5k_ar5210_tx_desc *tx_desc;	tx_desc = (struct ar5k_ar5210_tx_desc*)&desc->ds_ctl0;	tx_status = (struct ar5k_ar5210_tx_status*)&desc->ds_hw[0];	/* No frame has been send or error */	if ((tx_status->tx_status_1 & AR5K_AR5210_DESC_TX_STATUS1_DONE) == 0)		return (HAL_EINPROGRESS);	/*	 * Get descriptor status	 */	desc->ds_us.tx.ts_tstamp =	    AR5K_REG_MS(tx_status->tx_status_0,	    AR5K_AR5210_DESC_TX_STATUS0_SEND_TIMESTAMP);	desc->ds_us.tx.ts_shortretry =	    AR5K_REG_MS(tx_status->tx_status_0,	    AR5K_AR5210_DESC_TX_STATUS0_SHORT_RETRY_COUNT);	desc->ds_us.tx.ts_longretry =	    AR5K_REG_MS(tx_status->tx_status_0,	    AR5K_AR5210_DESC_TX_STATUS0_LONG_RETRY_COUNT);	desc->ds_us.tx.ts_seqnum =	    AR5K_REG_MS(tx_status->tx_status_1,	    AR5K_AR5210_DESC_TX_STATUS1_SEQ_NUM);	desc->ds_us.tx.ts_rssi =	    AR5K_REG_MS(tx_status->tx_status_1,	    AR5K_AR5210_DESC_TX_STATUS1_ACK_SIG_STRENGTH);	desc->ds_us.tx.ts_antenna = 1;	desc->ds_us.tx.ts_status = 0;	desc->ds_us.tx.ts_rate =	    AR5K_REG_MS(tx_desc->tx_control_0,	    AR5K_AR5210_DESC_TX_CTL0_XMIT_RATE);	if ((tx_status->tx_status_0 &	    AR5K_AR5210_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0) {		if (tx_status->tx_status_0 &		    AR5K_AR5210_DESC_TX_STATUS0_EXCESSIVE_RETRIES)			desc->ds_us.tx.ts_status |= HAL_TXERR_XRETRY;		if (tx_status->tx_status_0 &		    AR5K_AR5210_DESC_TX_STATUS0_FIFO_UNDERRUN)			desc->ds_us.tx.ts_status |= HAL_TXERR_FIFO;		if (tx_status->tx_status_0 &		    AR5K_AR5210_DESC_TX_STATUS0_FILTERED)			desc->ds_us.tx.ts_status |= HAL_TXERR_FILT;	}	return (HAL_OK);}HAL_BOOLar5k_ar5210_has_veol(struct ath_hal *hal){	return (AH_FALSE);}void /*Unimplemented*/ar5k_ar5210_get_tx_inter_queue(struct ath_hal *hal, u_int32_t *i){	AR5K_TRACE;	/* XXX */	return;}/* * Receive functions */u_int32_tar5k_ar5210_get_rx_buf(struct ath_hal *hal){	return (AR5K_REG_READ(AR5K_AR5210_RXDP));}voidar5k_ar5210_put_rx_buf(struct ath_hal *hal, u_int32_t phys_addr){	AR5K_REG_WRITE(AR5K_AR5210_RXDP, phys_addr);}voidar5k_ar5210_start_rx(struct ath_hal *hal){	AR5K_REG_WRITE(AR5K_AR5210_CR, AR5K_AR5210_CR_RXE);}HAL_BOOLar5k_ar5210_stop_rx_dma(struct ath_hal *hal){	int i;	AR5K_REG_WRITE(AR5K_AR5210_CR, AR5K_AR5210_CR_RXD);	/*	 * It may take some time to disable the DMA receive unit	 */	for (i = 2000;	     i > 0 && (AR5K_REG_READ(AR5K_AR5210_CR) & AR5K_AR5210_CR_RXE) != 0;	     i--)		AR5K_DELAY(10);	return (i > 0 ? AH_TRUE : AH_FALSE);}voidar5k_ar5210_start_rx_pcu(struct ath_hal *hal){	AR5K_REG_DISABLE_BITS(AR5K_AR5210_DIAG_SW, AR5K_AR5210_DIAG_SW_DIS_RX);}voidar5k_ar5210_stop_pcu_recv(struct ath_hal *hal){	AR5K_REG_ENABLE_BITS(AR5K_AR5210_DIAG_SW, AR5K_AR5210_DIAG_SW_DIS_RX);}

⌨️ 快捷键说明

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