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

📄 ar5210_xmit.c

📁 Atheros wifi driver source code
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting * Copyright (c) 2002-2005 Atheros Communications, Inc. * All rights reserved. * * $Id: ar5210_xmit.c,v 1.1.1.1 2006/09/12 03:45:22 steven Exp $ */#include "opt_ah.h"#ifdef AH_SUPPORT_AR5210#include "ah.h"#include "ah_internal.h"#include "ah_desc.h"#include "ar5210/ar5210.h"#include "ar5210/ar5210reg.h"#include "ar5210/ar5210phy.h"#include "ar5210/ar5210desc.h"/* * Set the properties of the tx queue with the parameters * from qInfo.  The queue must previously have been setup * with a call to ar5210SetupTxQueue. */HAL_BOOLar5210SetTxQueueProps(struct ath_hal *ah, int q, const HAL_TXQ_INFO *qInfo){	struct ath_hal_5210 *ahp = AH5210(ah);	if (q >= HAL_NUM_TX_QUEUES) {		HALDEBUG(ah, "%s: invalid queue num %u\n", __func__, q);		return AH_FALSE;	}	return ath_hal_setTxQProps(ah, &ahp->ah_txq[q], qInfo);}/* * Return the properties for the specified tx queue. */HAL_BOOLar5210GetTxQueueProps(struct ath_hal *ah, int q, HAL_TXQ_INFO *qInfo){	struct ath_hal_5210 *ahp = AH5210(ah);	if (q >= HAL_NUM_TX_QUEUES) {		HALDEBUG(ah, "%s: invalid queue num %u\n", __func__, q);		return AH_FALSE;	}	return ath_hal_getTxQProps(ah, qInfo, &ahp->ah_txq[q]);}/* * Allocate and initialize a tx DCU/QCU combination. */intar5210SetupTxQueue(struct ath_hal *ah, HAL_TX_QUEUE type,	const HAL_TXQ_INFO *qInfo){	struct ath_hal_5210 *ahp = AH5210(ah);	HAL_TX_QUEUE_INFO *qi;	int q;	switch (type) {	case HAL_TX_QUEUE_BEACON:		q = 2;		break;	case HAL_TX_QUEUE_CAB:		q = 1;		break;	case HAL_TX_QUEUE_DATA:		q = 0;		break;	default:		HALDEBUG(ah, "%s: bad tx queue type %u\n", __func__, type);		return -1;	}	HALDEBUG(ah, "%s: queue %u\n", __func__, q);	qi = &ahp->ah_txq[q];	if (qi->tqi_type != HAL_TX_QUEUE_INACTIVE) {		HALDEBUG(ah, "%s: tx queue %u already active\n", __func__, q);		return -1;	}	OS_MEMZERO(qi, sizeof(HAL_TX_QUEUE_INFO));	qi->tqi_type = type;	if (qInfo == AH_NULL) {		/* by default enable OK+ERR+DESC+URN interrupts */		qi->tqi_qflags =			  TXQ_FLAG_TXOKINT_ENABLE			| TXQ_FLAG_TXERRINT_ENABLE			| TXQ_FLAG_TXDESCINT_ENABLE			| TXQ_FLAG_TXURNINT_ENABLE			;		qi->tqi_aifs = INIT_AIFS;		qi->tqi_cwmin = HAL_TXQ_USEDEFAULT;	/* NB: do at reset */		qi->tqi_shretry = INIT_SH_RETRY;		qi->tqi_lgretry = INIT_LG_RETRY;	} else		(void) ar5210SetTxQueueProps(ah, q, qInfo);	/* NB: must be followed by ar5210ResetTxQueue */	return q;}/* * Free a tx DCU/QCU combination. */HAL_BOOLar5210ReleaseTxQueue(struct ath_hal *ah, u_int q){	struct ath_hal_5210 *ahp = AH5210(ah);	HAL_TX_QUEUE_INFO *qi;	if (q >= HAL_NUM_TX_QUEUES) {		HALDEBUG(ah, "%s: invalid queue num %u\n", __func__, q);		return AH_FALSE;	}	qi = &ahp->ah_txq[q];	if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {		HALDEBUG(ah, "%s: inactive queue %u\n", __func__, q);		return AH_FALSE;	}	HALDEBUG(ah, "%s: release queue %u\n", __func__, q);	qi->tqi_type = HAL_TX_QUEUE_INACTIVE;	ahp->ah_txOkInterruptMask &= ~(1 << q);	ahp->ah_txErrInterruptMask &= ~(1 << q);	ahp->ah_txDescInterruptMask &= ~(1 << q);	ahp->ah_txEolInterruptMask &= ~(1 << q);	ahp->ah_txUrnInterruptMask &= ~(1 << q);	return AH_TRUE;#undef N}HAL_BOOLar5210ResetTxQueue(struct ath_hal *ah, u_int q){	struct ath_hal_5210 *ahp = AH5210(ah);	HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;	HAL_TX_QUEUE_INFO *qi;	u_int32_t cwMin;	if (q >= HAL_NUM_TX_QUEUES) {		HALDEBUG(ah, "%s: invalid queue num %u\n", __func__, q);		return AH_FALSE;	}	qi = &ahp->ah_txq[q];	if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {		HALDEBUG(ah, "%s: inactive queue %u\n", __func__, q);		return AH_FALSE;	}	/*	 * Ignore any non-data queue(s).	 */	if (qi->tqi_type != HAL_TX_QUEUE_DATA)		return AH_TRUE;	/* Set turbo mode / base mode parameters on or off */	if (IS_CHAN_TURBO(chan)) {		OS_REG_WRITE(ah, AR_SLOT_TIME, INIT_SLOT_TIME_TURBO);		OS_REG_WRITE(ah, AR_TIME_OUT, INIT_ACK_CTS_TIMEOUT_TURBO);		OS_REG_WRITE(ah, AR_USEC, INIT_TRANSMIT_LATENCY_TURBO);		OS_REG_WRITE(ah, AR_IFS0, 			((INIT_SIFS_TURBO + qi->tqi_aifs * INIT_SLOT_TIME_TURBO)				<< AR_IFS0_DIFS_S)			| INIT_SIFS_TURBO);		OS_REG_WRITE(ah, AR_IFS1, INIT_PROTO_TIME_CNTRL_TURBO);		OS_REG_WRITE(ah, AR_PHY(17),			(OS_REG_READ(ah, AR_PHY(17)) & ~0x7F) | 0x38);		OS_REG_WRITE(ah, AR_PHY_FRCTL,			AR_PHY_SERVICE_ERR | AR_PHY_TXURN_ERR |			AR_PHY_ILLLEN_ERR | AR_PHY_ILLRATE_ERR |			AR_PHY_PARITY_ERR | AR_PHY_TIMING_ERR |			0x2020 |			AR_PHY_TURBO_MODE | AR_PHY_TURBO_SHORT);	} else {		OS_REG_WRITE(ah, AR_SLOT_TIME, INIT_SLOT_TIME);		OS_REG_WRITE(ah, AR_TIME_OUT, INIT_ACK_CTS_TIMEOUT);		OS_REG_WRITE(ah, AR_USEC, INIT_TRANSMIT_LATENCY);		OS_REG_WRITE(ah, AR_IFS0, 			((INIT_SIFS + qi->tqi_aifs * INIT_SLOT_TIME)				<< AR_IFS0_DIFS_S)			| INIT_SIFS);		OS_REG_WRITE(ah, AR_IFS1, INIT_PROTO_TIME_CNTRL);		OS_REG_WRITE(ah, AR_PHY(17),			(OS_REG_READ(ah, AR_PHY(17)) & ~0x7F) | 0x1C);		OS_REG_WRITE(ah, AR_PHY_FRCTL,			AR_PHY_SERVICE_ERR | AR_PHY_TXURN_ERR |			AR_PHY_ILLLEN_ERR | AR_PHY_ILLRATE_ERR |			AR_PHY_PARITY_ERR | AR_PHY_TIMING_ERR | 0x1020);	}	if (qi->tqi_cwmin == HAL_TXQ_USEDEFAULT)		cwMin = INIT_CWMIN;	else		cwMin = qi->tqi_cwmin;	/* Set cwmin and retry limit values */	OS_REG_WRITE(ah, AR_RETRY_LMT, 		  (cwMin << AR_RETRY_LMT_CW_MIN_S)		 | SM(INIT_SLG_RETRY, AR_RETRY_LMT_SLG_RETRY)		 | SM(INIT_SSH_RETRY, AR_RETRY_LMT_SSH_RETRY)		 | SM(qi->tqi_lgretry, AR_RETRY_LMT_LG_RETRY)		 | SM(qi->tqi_shretry, AR_RETRY_LMT_SH_RETRY)	);	if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)		ahp->ah_txOkInterruptMask |= 1 << q;	else		ahp->ah_txOkInterruptMask &= ~(1 << q);	if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)		ahp->ah_txErrInterruptMask |= 1 << q;	else		ahp->ah_txErrInterruptMask &= ~(1 << q);	if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)		ahp->ah_txDescInterruptMask |= 1 << q;	else		ahp->ah_txDescInterruptMask &= ~(1 << q);	if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)		ahp->ah_txEolInterruptMask |= 1 << q;	else		ahp->ah_txEolInterruptMask &= ~(1 << q);	if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)		ahp->ah_txUrnInterruptMask |= 1 << q;	else		ahp->ah_txUrnInterruptMask &= ~(1 << q);	return AH_TRUE;}/* * Get the TXDP for the "main" data queue.  Needs to be extended * for multiple Q functionality */u_int32_tar5210GetTxDP(struct ath_hal *ah, u_int q){	struct ath_hal_5210 *ahp = AH5210(ah);	HAL_TX_QUEUE_INFO *qi;	HALASSERT(q < HAL_NUM_TX_QUEUES);	qi = &ahp->ah_txq[q];	switch (qi->tqi_type) {	case HAL_TX_QUEUE_DATA:		return OS_REG_READ(ah, AR_TXDP0);	case HAL_TX_QUEUE_INACTIVE:		HALDEBUG(ah, "%s: inactive queue %u\n", __func__, q);		/* fall thru... */	default:		break;	}	return 0xffffffff;}/* * Set the TxDP for the "main" data queue. */HAL_BOOLar5210SetTxDP(struct ath_hal *ah, u_int q, u_int32_t txdp){	struct ath_hal_5210 *ahp = AH5210(ah);	HAL_TX_QUEUE_INFO *qi;	HALASSERT(q < HAL_NUM_TX_QUEUES);	HALDEBUGn(ah, 2, "%s: queue %u 0x%x\n", __func__, q, txdp);	qi = &ahp->ah_txq[q];	switch (qi->tqi_type) {	case HAL_TX_QUEUE_DATA:#ifdef AH_DEBUG		/*		 * Make sure that TXE is deasserted before setting the		 * TXDP.  If TXE is still asserted, setting TXDP will		 * have no effect.		 */		if (OS_REG_READ(ah, AR_CR) & AR_CR_TXE0)			ath_hal_printf(ah, "%s: TXE asserted; AR_CR=0x%x\n",				__func__, OS_REG_READ(ah, AR_CR));#endif		OS_REG_WRITE(ah, AR_TXDP0, txdp);		break;	case HAL_TX_QUEUE_BEACON:	case HAL_TX_QUEUE_CAB:		OS_REG_WRITE(ah, AR_TXDP1, txdp);		break;	case HAL_TX_QUEUE_INACTIVE:		HALDEBUG(ah, "%s: inactive queue %u\n", __func__, q);		/* fall thru... */	default:		return AH_FALSE;	}	return AH_TRUE;}/* * Update Tx FIFO trigger level. * * Set bIncTrigLevel to TRUE to increase the trigger level. * Set bIncTrigLevel to FALSE to decrease the trigger level. *

⌨️ 快捷键说明

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