void ar9300_disp_tpc_tables(struct ath_hal *ah) { struct ath_hal_9300 *ahp = AH9300(ah); HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan; u_int mode = ath_hal_get_curmode(ah, chan); const HAL_RATE_TABLE *rt; int i, j; /* Check whether TPC is enabled */ if (!AH_PRIVATE(ah)->ah_config.ath_hal_desc_tpc) { ath_hal_printf(ah, "\n TPC Register method in use\n"); return; } rt = ar9300_get_rate_table(ah, mode); HALASSERT(rt != NULL); ath_hal_printf(ah, "\n===TARGET POWER TABLE===\n"); for (j = 0 ; j < ar9300_get_ntxchains(ahp->ah_tx_chainmask) ; j++ ) { for (i = 0; i < rt->rateCount; i++) { int16_t txpower[AR9300_MAX_CHAINS]; txpower[j] = ahp->txpower[i][j]; ath_hal_printf(ah, " Index[%2d] Rate[0x%02x] %6d kbps " "Power (%d Chain) [%2d.%1d dBm]\n", i, rt->info[i].rate_code, rt->info[i].rateKbps, j + 1, txpower[j] / 2, txpower[j]%2 * 5); } } ath_hal_printf(ah, "\n"); ath_hal_printf(ah, "\n\n===TARGET POWER TABLE with STBC===\n"); for ( j = 0 ; j < ar9300_get_ntxchains(ahp->ah_tx_chainmask) ; j++ ) { for (i = 0; i < rt->rateCount; i++) { int16_t txpower[AR9300_MAX_CHAINS]; txpower[j] = ahp->txpower_stbc[i][j]; /* Do not display invalid configurations */ if ((rt->info[i].rate_code < AR9300_MCS0_RATE_CODE) || (rt->info[i].rate_code > AR9300_MCS23_RATE_CODE) || ar9300_invalid_stbc_cfg(j, rt->info[i].rate_code) == AH_TRUE) { continue; } ath_hal_printf(ah, " Index[%2d] Rate[0x%02x] %6d kbps " "Power (%d Chain) [%2d.%1d dBm]\n", i, rt->info[i].rate_code, rt->info[i].rateKbps, j + 1, txpower[j] / 2, txpower[j]%2 * 5); } } ath_hal_printf(ah, "\n"); }
u_int8_t *ar9300_get_tpc_tables(struct ath_hal *ah) { struct ath_hal_9300 *ahp = AH9300(ah); HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan; u_int mode = ath_hal_get_curmode(ah, chan); const HAL_RATE_TABLE *rt; u_int8_t *data; struct rate_power_tbl *table; int i, j; /* Check whether TPC is enabled */ if (!AH_PRIVATE(ah)->ah_config.ath_hal_desc_tpc) { ath_hal_printf(ah, "\n TPC Register method in use\n"); return NULL; } rt = ar9300_get_rate_table(ah, mode); HALASSERT(rt != NULL); data = (u_int8_t *)ath_hal_malloc(ah, 1 + rt->rateCount * sizeof(struct rate_power_tbl)); if (data == NULL) return NULL; OS_MEMZERO(data, 1 + rt->rateCount * sizeof(struct rate_power_tbl)); /* store the rate count at the beginning */ *data = rt->rateCount; table = (struct rate_power_tbl *)&data[1]; for (j = 0 ; j < ar9300_get_ntxchains(ahp->ah_tx_chainmask) ; j++ ) { for (i = 0; i < rt->rateCount; i++) { table[i].rateIdx = i; table[i].rateCode = rt->info[i].rate_code; table[i].rateKbps = rt->info[i].rateKbps; switch (j) { case 0: table[i].chain1 = rt->info[i].rate_code <= 0x87 ? 1 : 0; break; case 1: table[i].chain2 = rt->info[i].rate_code <= 0x8f ? 1 : 0; break; case 2: table[i].chain3 = 1; break; default: break; } if ((j == 0 && table[i].chain1) || (j == 1 && table[i].chain2) || (j == 2 && table[i].chain3)) table[i].txpower[j] = ahp->txpower[i][j]; } } for ( j = 0 ; j < ar9300_get_ntxchains(ahp->ah_tx_chainmask) ; j++ ) { for (i = 0; i < rt->rateCount; i++) { /* Do not display invalid configurations */ if ((rt->info[i].rate_code < AR9300_MCS0_RATE_CODE) || (rt->info[i].rate_code > AR9300_MCS23_RATE_CODE) || ar9300_invalid_stbc_cfg(j, rt->info[i].rate_code) == AH_TRUE) { continue; } table[i].stbc = 1; table[i].txpower_stbc[j] = ahp->txpower_stbc[i][j]; } } return data; /* the caller is responsible to free data */ }
void ar5416Set11nRateScenario(struct ath_hal *ah, void *ds, void *lastds, u_int dur_update_en, u_int rts_cts_rate, u_int rts_cts_duration, HAL_11N_RATE_SERIES series[], u_int nseries, u_int flags, u_int32_t smartAntenna) #endif { struct ath_hal_private *ap = AH_PRIVATE(ah); struct ar5416_desc *ads = AR5416DESC(ds); struct ar5416_desc *last_ads = AR5416DESC(lastds); u_int32_t ds_ctl0; u_int mode; HALASSERT(nseries == 4); (void)nseries; (void)rts_cts_duration; /* use H/W to calculate RTSCTSDuration */ /* * Rate control settings override */ ds_ctl0 = ads->ds_ctl0; if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) { if (flags & HAL_TXDESC_RTSENA) { ds_ctl0 &= ~AR_CTSEnable; ds_ctl0 |= AR_RTSEnable; } else { ds_ctl0 &= ~AR_RTSEnable; ds_ctl0 |= AR_CTSEnable; } } else { ds_ctl0 = (ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable)); } mode = ath_hal_get_curmode(ah, ap->ah_curchan); if (ap->ah_config.ath_hal_desc_tpc) { int16_t txpower; txpower = ar5416GetRateTxPower(ah, mode, series[0].rate_index, series[0].ch_sel); if(series[0].tx_power_cap == 0) { /*For short range mode, set txpower to MAX to put series[0].TxPowerCap into the descriptor*/ txpower = HAL_TXPOWER_MAX; } ds_ctl0 &= ~AR_XmitPower0; if (AR_SREV_MERLIN_10_OR_LATER(ah)) { u_int count; for (count=0; count < nseries; count++) { series[count].tx_power_cap -= AR5416_PWR_TABLE_OFFSET_DB * 2; } } ds_ctl0 |= set11nTxPower(0, AH_MIN(txpower, series[0].tx_power_cap)); } ads->ds_ctl0 = ds_ctl0; ads->ds_ctl2 = set11nTries(series, 0) | set11nTries(series, 1) | set11nTries(series, 2) | set11nTries(series, 3) | (dur_update_en ? AR_DurUpdateEna : 0) | SM(0, AR_BurstDur); ads->ds_ctl3 = set11nRate(series, 0) | set11nRate(series, 1) | set11nRate(series, 2) | set11nRate(series, 3); ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0) | set11nPktDurRTSCTS(series, 1); ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2) | set11nPktDurRTSCTS(series, 3); ads->ds_ctl7 = set11nRateFlags(series, 0) | set11nRateFlags(series, 1) | set11nRateFlags(series, 2) | set11nRateFlags(series, 3) | SM(rts_cts_rate, AR_RTSCTSRate); if (ap->ah_config.ath_hal_desc_tpc && AR_SREV_OWL_20_OR_LATER(ah)) { int16_t txpower; txpower = ar5416GetRateTxPower( ah, mode, series[1].rate_index, series[1].ch_sel); ads->ds_ctl9 = set11nTxPower(1, AH_MIN(txpower, series[1].tx_power_cap)); txpower = ar5416GetRateTxPower( ah, mode, series[2].rate_index, series[2].ch_sel); ads->ds_ctl10 = set11nTxPower(2, AH_MIN(txpower, series[2].tx_power_cap)); txpower = ar5416GetRateTxPower( ah, mode, series[3].rate_index, series[3].ch_sel); ads->ds_ctl11 = set11nTxPower(3, AH_MIN(txpower, series[3].tx_power_cap)); } #ifdef AH_NEED_DESC_SWAP last_ads->ds_ctl2 = __bswap32(ads->ds_ctl2); last_ads->ds_ctl3 = __bswap32(ads->ds_ctl3); #else last_ads->ds_ctl2 = ads->ds_ctl2; last_ads->ds_ctl3 = ads->ds_ctl3; #endif }