drivers/net/wireless/ath/ath9k/ar9003_paprd.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/ath/ath9k/ar9003_paprd.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ath/ath9k/ar9003_paprd.c
Extension
.c
Size
28582 bytes
Lines
1014
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (chan->channel >= UPPER_5G_SUB_BAND_START) {
			if (ar9003_get_paprd_rate_mask_ht20(ah, is2ghz)
								  & BIT(30))
				val = false;
		} else if (chan->channel >= MID_5G_SUB_BAND_START) {
			if (ar9003_get_paprd_rate_mask_ht20(ah, is2ghz)
								  & BIT(29))
				val = false;
		} else {
			if (ar9003_get_paprd_rate_mask_ht20(ah, is2ghz)
								  & BIT(28))
				val = false;
		}
	}

	if (val) {
		ah->paprd_table_write_done = true;
		ath9k_hw_apply_txpower(ah, chan, false);
	}

	REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
		      AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
	if (ah->caps.tx_chainmask & BIT(1))
		REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B1,
			      AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
	if (ah->caps.tx_chainmask & BIT(2))
		REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B2,
			      AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
}
EXPORT_SYMBOL(ar9003_paprd_enable);

static int ar9003_get_training_power_2g(struct ath_hw *ah)
{
	struct ath9k_channel *chan = ah->curchan;
	unsigned int power, scale, delta;

	scale = ar9003_get_paprd_scale_factor(ah, chan);

	if (AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
	    AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
		power = ah->paprd_target_power + 2;
	} else if (AR_SREV_9485(ah)) {
		power = 25;
	} else {
		power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
				       AR_PHY_POWERTX_RATE5_POWERTXHT20_0);

		delta = abs((int) ah->paprd_target_power - (int) power);
		if (delta > scale)
			return -1;

		if (delta < 4)
			power -= 4 - delta;
	}

	return power;
}

static int ar9003_get_training_power_5g(struct ath_hw *ah)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath9k_channel *chan = ah->curchan;
	unsigned int power, scale, delta;

	scale = ar9003_get_paprd_scale_factor(ah, chan);

	if (IS_CHAN_HT40(chan))
		power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE8,
			AR_PHY_POWERTX_RATE8_POWERTXHT40_5);
	else
		power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE6,
			AR_PHY_POWERTX_RATE6_POWERTXHT20_5);

	power += scale;
	delta = abs((int) ah->paprd_target_power - (int) power);
	if (delta > scale)
		return -1;

	switch (get_streams(ah->txchainmask)) {
	case 1:
		delta = 6;
		break;
	case 2:
		delta = 4;
		break;
	case 3:
		delta = 2;
		break;
	default:
		delta = 0;

Annotation

Implementation Notes