Exemple #1
0
bool
ar9300_handle_radar_bb_panic(struct ath_hal *ah)
{
    u_int32_t status;
    u_int32_t val;   
    struct ath_hal_9300 *ahp = AH9300(ah);
    bool asleep = ahp->ah_chip_full_sleep;
       
    status = AH_PRIVATE(ah)->ah_bb_panic_last_status;
   
    if ( status == 0x04000539 ) { 
        if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
            ar9300_set_power_mode(ah, HAL_PM_AWAKE, true);
        } 
        /* recover from this BB panic without reset*/
        /* set AR9300_DFS_FIRPWR to -1 */
        val = OS_REG_READ(ah, AR_PHY_RADAR_0);
        val &= (~AR_PHY_RADAR_0_FIRPWR);
        val |= SM( 0x7f, AR_PHY_RADAR_0_FIRPWR);
        OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
        OS_DELAY(1);
        /* set AR9300_DFS_FIRPWR to its default value */
        val = OS_REG_READ(ah, AR_PHY_RADAR_0);
        val &= ~AR_PHY_RADAR_0_FIRPWR;
        val |= SM( AR9300_DFS_FIRPWR, AR_PHY_RADAR_0_FIRPWR);
        OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
        if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
            ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, true);
        }   
        return true;
    } else if (status == 0x0400000a) {
        /* EV 92527 : reset required if we see this signature */
        HDPRINTF(ah, HAL_DBG_DFS, "%s: BB Panic -- 0x0400000a\n", __func__);
        return false;
    } else if (status == 0x1300000a) {
        /* EV92527: we do not need a reset if we see this signature */
        HDPRINTF(ah, HAL_DBG_DFS, "%s: BB Panic -- 0x1300000a\n", __func__);
        return true;
    } else if ((AR_SREV_WASP(ah) || AR_SREV_HONEYBEE(ah)) && (status == 0x04000409)) {
        return true;
    } else {
        if (ar9300_get_capability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK &&
            (status & 0xff00000f) == 0x04000009 &&
            status != 0x04000409 &&
            status != 0x04000b09 &&
            status != 0x04000e09 &&
            (status & 0x0000ff00))
        {
            /* disable RIFS Rx */
#ifdef AH_DEBUG
            HDPRINTF(ah, HAL_DBG_UNMASKABLE, "%s: BB status=0x%08x rifs=%d - disable\n",
                     __func__, status, ahp->ah_rifs_enabled);
#endif
            ar9300_set_rifs_delay(ah, false);
        }
        return false;
    }
}
Exemple #2
0
int papredistortionSingleTable(struct ath_hal *ah, HAL_CHANNEL *chan, int txChainMask)
{
	int chainNum;
	unsigned int PA_table[24], smallSignalGain; 
    int status = 0, disable_papd=1, chain_fail[3]={0,0,0};
    int paprd_retry_count;

	UserPrint("Run PA predistortion algorithm: txChainMask=0x%X.\n", txChainMask);

    /*
     * Before doing PAPRD training, we must disable pal spare of 
     * hw greeen tx function
     */
	ar9300_hwgreentx_set_pal_spare(AH,0);//ar9300_set_pal_spare(AH,0);
	LinkTransmitPAPDWarmUp(txChainMask);
	status=	ar9300_paprd_init_table(ah, chan);
	if(status==-1)
	{
		ar9300_enable_paprd(ah, AH_FALSE, chan);
		UserPrint("Warning:: PA predistortion failed in InitTable\n");
		return -1;
	}
    {
        struct ath_hal_9300 *ahp = AH9300(ah);
        UserPrint("Training power_x2 is %d, channel %d\n", ahp->paprd_training_power, chan->channel);
    }

	for(chainNum=0; chainNum<3; chainNum++)
	{
		unsigned int i, desired_gain, gain_index;
		if(txChainMask&(1<<chainNum)) 
		{
		    paprd_retry_count = 0;
			while (paprd_retry_count < 5)
		    {
			    ar9300_paprd_setup_gain_table(ah,chainNum);
			    LinkTransmitPAPD(ah, chainNum);
			    ar9300_paprd_is_done(ah);
			    status = ar9300_paprd_create_curve(ah, chan, chainNum);
			    if (status != HAL_EINPROGRESS)
			    {    
			        if(status==0) 
                    {
                        ar9300_populate_paprd_single_table(ah, chan, chainNum);
                        if (!AR_SREV_HONEYBEE(ah) && !AR_SREV_DRAGONFLY(ah)) {
                                if (txChainMask == 0x2 || txChainMask == 0x4){
                                    ar9300_populate_paprd_single_table(ah, chan, 0);
                                }
                        }
                        disable_papd = 0;
                    }
                    else
                    {
                        disable_papd = 1;
                        chain_fail[chainNum] = 1;
                    }
                    break;
                }
                else
                {
                    /* need re-train paprd */
                    paprd_retry_count++;
                }
            }
            if (paprd_retry_count > 5)
                UserPrint("Warning: ch%d PAPRD re-train fail\n", (1 << chainNum));
		}
	}
	if(disable_papd==0)
    {
		ar9300_enable_paprd(ah, AH_TRUE, chan);
        /*
         * restore PAL spare of hw green tx function 
         */
		ar9300_hwgreentx_set_pal_spare(AH,1);
    }
	else
    {
		ar9300_enable_paprd(ah, AH_FALSE, chan);
        UserPrint("Warning:: PA predistortion failed. chain_fail_flag %d %d %d\n", chain_fail[0], chain_fail[1], chain_fail[2]);
        /*
         * restore PAL spare of hw green tx function 
         */
		ar9300_hwgreentx_set_pal_spare(AH,1);
        return -1;
    }

	
	return 0;
}
Exemple #3
0
/*
 * Take the MHz channel value and set the Channel value
 *
 * ASSUMES: Writes enabled to analog bus
 *
 * Actual Expression,
 *
 * For 2GHz channel,
 * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
 * (freq_ref = 40MHz)
 *
 * For 5GHz channel,
 * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
 * (freq_ref = 40MHz/(24>>amode_ref_sel))
 *
 * For 5GHz channels which are 5MHz spaced,
 * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
 * (freq_ref = 40MHz)
 */
static HAL_BOOL
ar9300_set_channel(struct ath_hal *ah, struct ieee80211_channel *chan)
{
    u_int16_t b_mode, frac_mode = 0, a_mode_ref_sel = 0;
    u_int32_t freq, channel_sel, reg32;
    u_int8_t clk_25mhz = AH9300(ah)->clk_25mhz;
    CHAN_CENTERS centers;
    int load_synth_channel;
#ifdef	AH_DEBUG_ALQ
    HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
#endif

    /*
     * Put this behind AH_DEBUG_ALQ for now until the Hornet
     * channel_sel code below is made to work.
     */
#ifdef	AH_DEBUG_ALQ
    OS_MARK(ah, AH_MARK_SETCHANNEL, ichan->channel);
#endif

    ar9300_get_channel_centers(ah, chan, &centers);
    freq = centers.synth_center;

    if (freq < 4800) {     /* 2 GHz, fractional mode */
        b_mode = 1; /* 2 GHz */

        if (AR_SREV_HORNET(ah)) {
#if 0
            u_int32_t ichan =
              ieee80211_mhz2ieee(ah, chan->ic_freq, chan->ic_flags);
            HALASSERT(ichan > 0 && ichan <= 14);
            if (clk_25mhz) {
                channel_sel = ar9300_chansel_xtal_25M[ichan - 1];
            } else {
                channel_sel = ar9300_chansel_xtal_40M[ichan - 1];
            }
#endif
            uint32_t i;

            /*
             * Pay close attention to this bit!
             *
             * We need to map the actual desired synth frequency to
             * one of the channel select array entries.
             *
             * For HT20, it'll align with the channel we select.
             *
             * For HT40 though it won't - the centre frequency
             * will not be the frequency of chan->ic_freq or ichan->freq;
             * it needs to be whatever frequency maps to 'freq'.
             */
            i = ath_hal_mhz2ieee_2ghz(ah, freq);
            HALASSERT(i > 0 && i <= 14);
            if (clk_25mhz) {
                channel_sel = ar9300_chansel_xtal_25M[i - 1];
            } else {
                channel_sel = ar9300_chansel_xtal_40M[i - 1];
            }
        } else if (AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
            u_int32_t channel_frac;
            /* 
             * freq_ref = (40 / (refdiva >> a_mode_ref_sel));
             *     (where refdiva = 1 and amoderefsel = 0)
             * ndiv = ((chan_mhz * 4) / 3) / freq_ref;
             * chansel = int(ndiv),  chanfrac = (ndiv - chansel) * 0x20000
             */
            channel_sel = (freq * 4) / 120;
            channel_frac = (((freq * 4) % 120) * 0x20000) / 120;
            channel_sel = (channel_sel << 17) | (channel_frac);
        } else if (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah)) {
            u_int32_t channel_frac;
            if (clk_25mhz) {
                /* 
                 * freq_ref = (50 / (refdiva >> a_mode_ref_sel));
                 *     (where refdiva = 1 and amoderefsel = 0)
                 * ndiv = ((chan_mhz * 4) / 3) / freq_ref;
                 * chansel = int(ndiv),  chanfrac = (ndiv - chansel) * 0x20000
                 */
                if (AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah)) {
                    /* Doubler is off for Scorpion */
                    channel_sel = (freq * 4) / 75;
                    channel_frac = (((freq * 4) % 75) * 0x20000) / 75;
                } else {
                    channel_sel = (freq * 2) / 75;
                    channel_frac = (((freq * 2) % 75) * 0x20000) / 75;
                }
            } else {
                /* 
                 * freq_ref = (50 / (refdiva >> a_mode_ref_sel));
                 *     (where refdiva = 1 and amoderefsel = 0)
                 * ndiv = ((chan_mhz * 4) / 3) / freq_ref;
                 * chansel = int(ndiv),  chanfrac = (ndiv - chansel) * 0x20000
                 */
                if (AR_SREV_SCORPION(ah)) {
                    /* Doubler is off for Scorpion */
                    channel_sel = (freq * 4) / 120;
                    channel_frac = (((freq * 4) % 120) * 0x20000) / 120;
                } else {
                    channel_sel = (freq * 2) / 120;
                    channel_frac = (((freq * 2) % 120) * 0x20000) / 120;
                }
            }
            channel_sel = (channel_sel << 17) | (channel_frac);
        } else {
            channel_sel = CHANSEL_2G(freq);
        }
    } else {
        b_mode = 0; /* 5 GHz */
        if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && clk_25mhz){
            u_int32_t channel_frac;
            /* 
             * freq_ref = (50 / (refdiva >> amoderefsel));
             *     (refdiva = 1, amoderefsel = 0)
             * ndiv = ((chan_mhz * 2) / 3) / freq_ref;
             * chansel = int(ndiv),  chanfrac = (ndiv - chansel) * 0x20000
             */
            channel_sel = freq / 75 ;
            channel_frac = ((freq % 75) * 0x20000) / 75;
            channel_sel = (channel_sel << 17) | (channel_frac);
        } else {
            channel_sel = CHANSEL_5G(freq);
            /* Doubler is ON, so, divide channel_sel by 2. */
            channel_sel >>= 1;
        }
    }


	/* Enable fractional mode for all channels */
    frac_mode = 1;
    a_mode_ref_sel = 0;
    load_synth_channel = 0;
    
    reg32 = (b_mode << 29);
    OS_REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);

	/* Enable Long shift Select for Synthesizer */
    OS_REG_RMW_FIELD(ah,
        AR_PHY_65NM_CH0_SYNTH4, AR_PHY_SYNTH4_LONG_SHIFT_SELECT, 1);

    /* program synth. setting */
    reg32 =
        (channel_sel       <<  2) |
        (a_mode_ref_sel      << 28) |
        (frac_mode         << 30) |
        (load_synth_channel << 31);
    if (IEEE80211_IS_CHAN_QUARTER(chan)) {
        reg32 += CHANSEL_5G_DOT5MHZ;
    }
    OS_REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32);
    /* Toggle Load Synth channel bit */
    load_synth_channel = 1;
    reg32 |= load_synth_channel << 31;
    OS_REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32);


    AH_PRIVATE(ah)->ah_curchan = chan;

    return AH_TRUE;
}