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 */
}
Exemple #3
0
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
}