示例#1
0
void
ath_phyerr_attach(struct ath_softc *sc)
{
    struct ieee80211com *ic = &sc->sc_ic;
    sc->sc_phyerr_cap = 0;

    if (ath_hal_getcapability(sc->sc_ah, HAL_CAP_PHYDIAG, HAL_CAP_RADAR, NULL) == HAL_OK) {
        sc->sc_phyerr_cap |= ATH_RADAR_EN;
        if ((ic->ic_ath_cap & (IEEE80211_ATHC_TURBOP)) &&
                (ic->ic_ath_cap & (IEEE80211_ATHC_AR)))
            sc->sc_phyerr_cap |= ATH_RADAR_AR_EN;
    }
    sc->sc_phyerr_state = (void *) kmalloc(sizeof(struct ath_phyerr_state), GFP_KERNEL);
    ath_reset_radar(sc);
    ath_reset_ar(sc);
};
示例#2
0
/*
 * Enable radar check.  Return 1 if the driver should
 * enable radar PHY errors, or 0 if not.
 */
int
ath_dfs_radar_enable(struct ath_softc *sc, struct ieee80211_channel *chan)
{
#if 0
    HAL_PHYERR_PARAM pe;

    /* Check if the hardware supports radar reporting */
    /* XXX TODO: migrate HAL_CAP_RADAR/HAL_CAP_AR to somewhere public! */
    if (ath_hal_getcapability(sc->sc_ah,
                              HAL_CAP_PHYDIAG, 0, NULL) != HAL_OK)
        return (0);

    /* Check if the current channel is radar-enabled */
    if (! IEEE80211_IS_CHAN_DFS(chan))
        return (0);

    /* Fetch the default parameters */
    memset(&pe, '\0', sizeof(pe));
    if (! ath_hal_getdfsdefaultthresh(sc->sc_ah, &pe))
        return (0);

    /* Enable radar PHY error reporting */
    sc->sc_dodfs = 1;

    /* Tell the hardware to enable radar reporting */
    pe.pe_enabled = 1;

    /* Flip on extension channel events only if doing HT40 */
    if (IEEE80211_IS_CHAN_HT40(chan))
        pe.pe_extchannel = 1;
    else
        pe.pe_extchannel = 0;

    ath_hal_enabledfs(sc->sc_ah, &pe);

    /*
     * Disable strong signal fast diversity - needed for
     * AR5212 and similar PHYs for reliable short pulse
     * duration.
     */
    (void) ath_hal_setcapability(sc->sc_ah, HAL_CAP_DIVERSITY, 2, 0, NULL);

    return (1);
#else
    return (0);
#endif
}
示例#3
0
/*
 * Attach to a device instance.  Setup the public definition
 * of how much per-node space we need and setup the private
 * phy tables that have rate control parameters.  These tables
 * are normally part of the Atheros hal but are not included
 * in our hal as the rate control data was not being used and
 * was considered proprietary (at the time).
 */
struct atheros_softc *
ath_rate_attach(struct ath_hal *ah)
{
    struct atheros_softc *asc;

    RC_OS_MALLOC(&asc, sizeof(struct atheros_softc), RATECTRL_MEMTAG);
    if (asc == NULL)
        return NULL;

    OS_MEMZERO(asc, sizeof(struct atheros_softc));

    /*
     * Use the magic number to figure out the chip type.
     * There's probably a better way to do this but for
     * now this suffices.
     *
     * NB: We don't have a separate set of tables for the
     *     5210; treat it like a 5211 since it has the same
     *     tx descriptor format and (hopefully) sufficiently
     *     similar operating characteristics to work ok.
     */
    switch (ah->ah_magic) {
#ifdef AH_SUPPORT_AR5212
    case 0x19570405:
    case 0x19541014:    /* 5212 */
        ar5212AttachRateTables(asc);
        asc->prate_maprix = ar5212_rate_maprix;
        break;
#endif
    case 0x19641014:    /* 5416 */
    case 0x19741014:    /* 9300 */
        ar5416AttachRateTables(asc);
        asc->prate_maprix = ar5416_rate_maprix;
        break;
    default:
        ASSERT(0);
        break;
    }

    /* Save Maximum TX Trigger Level (used for 11n) */
    ath_hal_getcapability(ah, HAL_CAP_TX_TRIG_LEVEL_MAX, 0, &asc->txTrigLevelMax);

    /*  return alias for atheros_softc * */
    return asc;
}
示例#4
0
int spectral_enter_raw_capture_mode(ath_dev_t dev, void *indata)
{
    struct ath_softc *sc = ATH_DEV_TO_SC(dev);
    SPECTRAL_ADC_CAPTURE_PARAMS *params = (SPECTRAL_ADC_CAPTURE_PARAMS*)indata;
    HAL_CHANNEL hchan;
    int error = 0;

    if (ath_hal_getcapability(sc->sc_ah, HAL_CAP_RAW_ADC_CAPTURE, 0, NULL) != HAL_OK) {
        DPRINTF(sc, ATH_DEBUG_ANY, "%s[%d]: called but raw capture mode not supported!\n", __func__, __LINE__);
        return -ENOTSUP;
    }

    /* sanity check input version */
    if (params->version != SPECTRAL_ADC_API_VERSION) {
        DPRINTF(sc, ATH_DEBUG_ANY, "%s[%d]: version mismatch: expect %d got %d\n", 
                __func__, __LINE__, params->version, SPECTRAL_ADC_API_VERSION);
        return -EINVAL; 
    }

    if (sc->sc_invalid) {
        DPRINTF(sc, ATH_DEBUG_ANY, "%s[%d]: called but device is invalid or removed!\n", __func__, __LINE__);
        return -ENXIO;
    }

    if (sc->sc_raw_adc_capture_enabled) {
        DPRINTF(sc, ATH_DEBUG_ANY, "%s[%d]: already raw capture mode - calling spectral_exit_raw_capture_mode() first\n", __func__, __LINE__);
        spectral_exit_raw_capture_mode(dev);
    }

    /* save current channel and chain mask so we can restore later */
    sc->sc_save_rx_chainmask = sc->sc_rx_chainmask;
    sc->sc_save_current_chan = sc->sc_curchan;
    sc->sc_save_current_opmode = sc->sc_opmode;
    /* ensure chain mask is valid */
    params->chain_info.chain_mask &= sc->sc_rx_chainmask;
    /* store requested capture params */
    sc->sc_adc_chain_mask = params->chain_info.chain_mask;
    sc->sc_adc_num_chains = sc->sc_mask2chains[params->chain_info.chain_mask];
    sc->sc_adc_capture_flags = params->capture_flags;
    /* set new chain mask */
    ath_set_rx_chainmask(dev, params->chain_info.chain_mask);
    /* change channel to that requested */
    OS_MEMZERO(&hchan, sizeof(hchan));
    hchan.channel = params->freq;
    if (hchan.channel > 5000)
        hchan.channel_flags = CHANNEL_A_HT20;
    else
        hchan.channel_flags = CHANNEL_G_HT20;
    sc->sc_full_reset = 1; /* ensure we do a full reset */
    ath_set_channel(dev, &hchan, 0, 0, 0); 
    /* save channel info to return with capture data later */
    sc->sc_adc_chan_flags = sc->sc_curchan.channel_flags;
    sc->sc_adc_freq = sc->sc_curchan.channel;
    sc->sc_adc_ieee = ath_hal_mhz2ieee(sc->sc_ah, sc->sc_adc_freq, sc->sc_adc_chan_flags);
    /* did the channel change succeed ?*/
    if (sc->sc_curchan.channel != hchan.channel ||
        sc->sc_curchan.channel_flags != hchan.channel_flags) {
        DPRINTF(sc, ATH_DEBUG_ANY, "%s[%d]: set chan to %dMhz[%x] FAILED! current chan=%dMhz[0x%x]\n", 
                __func__, __LINE__, hchan.channel, hchan.channel_flags, 
                sc->sc_curchan.channel, sc->sc_curchan.channel_flags);
        error = -EINVAL; 
    } else {
        /* ok, all set up - enter raw capture mode */
        DPRINTF(sc, ATH_DEBUG_ANY, "%s[%d]: chan is now %dMhz flags=0x%x mask=0x%x\n", __func__, __LINE__, 
                sc->sc_curchan.channel, sc->sc_curchan.channel_flags, params->chain_info.chain_mask);
        sc->sc_raw_adc_capture_enabled = 1;
        sc->sc_opmode = HAL_M_RAW_ADC_CAPTURE;
        ath_hal_enable_test_addac_mode(sc->sc_ah);
    }

    return error;
}
示例#5
0
/*
 * Calculate the receive filter according to the
 * operating mode and state:
 *
 * o always accept unicast, broadcast, and multicast traffic
 * o accept PHY error frames when hardware doesn't have MIB support
 *   to count and we need them for ANI (sta mode only until recently)
 *   and we are not scanning (ANI is disabled)
 *   NB: older hal's add rx filter bits out of sight and we need to
 *	 blindly preserve them
 * o probe request frames are accepted only when operating in
 *   hostap, adhoc, mesh, or monitor modes
 * o enable promiscuous mode
 *   - when in monitor mode
 *   - if interface marked PROMISC (assumes bridge setting is filtered)
 * o accept beacons:
 *   - when operating in station mode for collecting rssi data when
 *     the station is otherwise quiet, or
 *   - when operating in adhoc mode so the 802.11 layer creates
 *     node table entries for peers,
 *   - when scanning
 *   - when doing s/w beacon miss (e.g. for ap+sta)
 *   - when operating in ap mode in 11g to detect overlapping bss that
 *     require protection
 *   - when operating in mesh mode to detect neighbors
 * o accept control frames:
 *   - when in monitor mode
 * XXX HT protection for 11n
 */
u_int32_t
ath_calcrxfilter(struct ath_softc *sc)
{
	struct ieee80211com *ic = &sc->sc_ic;
	u_int32_t rfilt;

	rfilt = HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST | HAL_RX_FILTER_MCAST;
	if (!sc->sc_needmib && !sc->sc_scanning)
		rfilt |= HAL_RX_FILTER_PHYERR;
	if (ic->ic_opmode != IEEE80211_M_STA)
		rfilt |= HAL_RX_FILTER_PROBEREQ;
	/* XXX ic->ic_monvaps != 0? */
	if (ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_promisc > 0)
		rfilt |= HAL_RX_FILTER_PROM;

	/*
	 * Only listen to all beacons if we're scanning.
	 *
	 * Otherwise we only really need to hear beacons from
	 * our own BSSID.
	 *
	 * IBSS? software beacon miss? Just receive all beacons.
	 * We need to hear beacons/probe requests from everyone so
	 * we can merge ibss.
	 */
	if (ic->ic_opmode == IEEE80211_M_IBSS || sc->sc_swbmiss) {
		rfilt |= HAL_RX_FILTER_BEACON;
	} else if (ic->ic_opmode == IEEE80211_M_STA) {
		if (sc->sc_do_mybeacon && ! sc->sc_scanning) {
			rfilt |= HAL_RX_FILTER_MYBEACON;
		} else { /* scanning, non-mybeacon chips */
			rfilt |= HAL_RX_FILTER_BEACON;
		}
	}

	/*
	 * NB: We don't recalculate the rx filter when
	 * ic_protmode changes; otherwise we could do
	 * this only when ic_protmode != NONE.
	 */
	if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
	    IEEE80211_IS_CHAN_ANYG(ic->ic_curchan))
		rfilt |= HAL_RX_FILTER_BEACON;

	/*
	 * Enable hardware PS-POLL RX only for hostap mode;
	 * STA mode sends PS-POLL frames but never
	 * receives them.
	 */
	if (ath_hal_getcapability(sc->sc_ah, HAL_CAP_PSPOLL,
	    0, NULL) == HAL_OK &&
	    ic->ic_opmode == IEEE80211_M_HOSTAP)
		rfilt |= HAL_RX_FILTER_PSPOLL;

	if (sc->sc_nmeshvaps) {
		rfilt |= HAL_RX_FILTER_BEACON;
		if (sc->sc_hasbmatch)
			rfilt |= HAL_RX_FILTER_BSSID;
		else
			rfilt |= HAL_RX_FILTER_PROM;
	}
	if (ic->ic_opmode == IEEE80211_M_MONITOR)
		rfilt |= HAL_RX_FILTER_CONTROL;

	/*
	 * Enable RX of compressed BAR frames only when doing
	 * 802.11n. Required for A-MPDU.
	 */
	if (IEEE80211_IS_CHAN_HT(ic->ic_curchan))
		rfilt |= HAL_RX_FILTER_COMPBAR;

	/*
	 * Enable radar PHY errors if requested by the
	 * DFS module.
	 */
	if (sc->sc_dodfs)
		rfilt |= HAL_RX_FILTER_PHYRADAR;

	/*
	 * Enable spectral PHY errors if requested by the
	 * spectral module.
	 */
	if (sc->sc_dospectral)
		rfilt |= HAL_RX_FILTER_PHYRADAR;

	DPRINTF(sc, ATH_DEBUG_MODE, "%s: RX filter 0x%x, %s\n",
	    __func__, rfilt, ieee80211_opmode_name[ic->ic_opmode]);
	return rfilt;
}
示例#6
0
文件: dfs_init.c 项目: KHATEEBNSIT/AP
/* This function Initialize the radar filter tables 
 * if the ath dfs domain is uninitalized or
 *    ath dfs domain is different from hal dfs domain
 */
int dfs_init_radar_filters( struct ath_softc *sc )
{
    u_int32_t T, Tmax, haldfsdomain;
    int numpulses,p,n, i;
    int numradars = 0, numb5radars = 0;
    struct ath_dfs *dfs = sc->sc_dfs;
    struct dfs_filtertype *ft = NULL;
    struct dfs_filter *rf=NULL;
    struct dfs_pulse *dfs_radars;
    struct dfs_bin5pulse *b5pulses=NULL;
    int32_t min_rssithresh=DFS_MAX_RSSI_VALUE;
    u_int32_t max_pulsedur=0;


    if ( dfs == NULL ) {
        DFS_DPRINTK(sc, ATH_DEBUG_DFS, "dfs is NULL %s",__func__);
    	return 1;
    }

    /* clear up the dfs domain flag first */
#ifndef ATH_DFS_RADAR_DETECTION_ONLY
    dfs->sc_dfs_isdfsregdomain = 0;
#endif

    /* clear athsstats/DFS related information */
    sc->sc_stats.ast_dfs_stats.event_count = 0;
    sc->sc_stats.ast_dfs_stats.chirp_count = 0;
    sc->sc_stats.ast_dfs_stats.num_filter = 0;

    if (ath_hal_getcapability(sc->sc_ah, HAL_CAP_PHYDIAG,
				  HAL_CAP_RADAR, NULL) == HAL_OK) {
    /* Init DFS radar filters */
    ath_hal_getcapability(sc->sc_ah, HAL_CAP_DFS_DMN, 0, &haldfsdomain);

    if ( (dfs->dfsdomain == DFS_UNINIT_DOMAIN) ||
	 ( dfs->dfsdomain != haldfsdomain ) )
    {
            /* set the dfs domain from HAL */
            dfs->dfsdomain = haldfsdomain;
	    DFS_DPRINTK(sc, ATH_DEBUG_DFS2, "DFS domain=%d\n",dfs->dfsdomain);
	    if (domainoverride != DFS_UNINIT_DOMAIN) {
		DFS_DPRINTK(sc, ATH_DEBUG_DFS, 
			   "Overriding DFS domain with %d\n",domainoverride); 
		dfs->dfsdomain = domainoverride;
	    }
	    dfs_radars = ath_hal_getdfsradars(sc->sc_ah, dfs->dfsdomain,
			     &numradars, &b5pulses, &numb5radars,
			     &(dfs->dfs_defaultparams));
	    if (dfs_radars == NULL) {
		DFS_DPRINTK(sc, ATH_DEBUG_DFS, "%s: Unknown dfs domain %d\n",
			    __func__, dfs->dfsdomain);
		/* Disable radar detection since we don't have a radar domain */
		dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN;
		return 0;
	    }
#ifndef ATH_DFS_RADAR_DETECTION_ONLY
        dfs->sc_dfs_isdfsregdomain = 1;
#endif

	    dfs->dfs_rinfo.rn_numradars = 0;
	    /* Clear filter type table */
	    for (n=0; n<256; n++) {
		for (i=0;i<DFS_MAX_RADAR_OVERLAP; i++)
		    (dfs->dfs_radartable[n])[i] = -1;
            }
	    /* Now, initialize the radar filters */
	    for (p=0; p<numradars; p++) {
		ft = NULL;
		for (n=0; n<dfs->dfs_rinfo.rn_numradars; n++) {
		    if ((dfs_radars[p].rp_pulsedur == dfs->dfs_radarf[n]->ft_filterdur) &&
		       (dfs_radars[p].rp_numpulses == dfs->dfs_radarf[n]->ft_numpulses) &&
		       (dfs_radars[p].rp_mindur == dfs->dfs_radarf[n]->ft_mindur) &&
		       (dfs_radars[p].rp_maxdur == dfs->dfs_radarf[n]->ft_maxdur)) {
		       ft = dfs->dfs_radarf[n];
		       break;
		    }
		}
		if (ft == NULL) {
		    /* No filter of the appropriate dur was found */
		    if ((dfs->dfs_rinfo.rn_numradars+1) >DFS_MAX_RADAR_TYPES) {
			DFS_DPRINTK(sc, ATH_DEBUG_DFS, "%s: Too many filter types\n",
			__func__);
			goto bad4;
		    }
		    ft = dfs->dfs_radarf[dfs->dfs_rinfo.rn_numradars];
		    ft->ft_numfilters = 0;
		    ft->ft_numpulses = dfs_radars[p].rp_numpulses;
		    ft->ft_patterntype = dfs_radars[p].rp_patterntype;
		    ft->ft_mindur = dfs_radars[p].rp_mindur;
		    ft->ft_maxdur = dfs_radars[p].rp_maxdur;
		    ft->ft_filterdur = dfs_radars[p].rp_pulsedur;
		    ft->ft_rssithresh = dfs_radars[p].rp_rssithresh;
		    ft->ft_rssimargin = dfs_radars[p].rp_rssimargin;
		    ft->ft_minpri = 1000000;

		    if (ft->ft_rssithresh < min_rssithresh)
		    min_rssithresh = ft->ft_rssithresh;
		    if (ft->ft_maxdur > max_pulsedur)
		    max_pulsedur = ft->ft_maxdur;
		    for (i=ft->ft_mindur; i<=ft->ft_maxdur; i++) {
			u_int32_t stop=0,tableindex=0;
			while ((tableindex < DFS_MAX_RADAR_OVERLAP) && (!stop)) {
			    if ((dfs->dfs_radartable[i])[tableindex] == -1)
				stop = 1;
			    else
				tableindex++;
			}
			if (stop) {
			    (dfs->dfs_radartable[i])[tableindex] =
				(int8_t) (dfs->dfs_rinfo.rn_numradars);
			} else {
			    DFS_DPRINTK(sc, ATH_DEBUG_DFS,
				"%s: Too many overlapping radar filters\n",
				__func__);
			    goto bad4;
			}
		    }
		    dfs->dfs_rinfo.rn_numradars++;
		}
		rf = &(ft->ft_filters[ft->ft_numfilters++]);
		dfs_reset_delayline(&rf->rf_dl);
		numpulses = dfs_radars[p].rp_numpulses;

		rf->rf_numpulses = numpulses;
		rf->rf_patterntype = dfs_radars[p].rp_patterntype;
		rf->rf_pulseid = dfs_radars[p].rp_pulseid;
		rf->rf_mindur = dfs_radars[p].rp_mindur;
		rf->rf_maxdur = dfs_radars[p].rp_maxdur;
		rf->rf_numpulses = dfs_radars[p].rp_numpulses;
		rf->rf_ignore_pri_window = dfs_radars[p].rp_ignore_pri_window;
		T = (100000000/dfs_radars[p].rp_max_pulsefreq) -
        		100*(dfs_radars[p].rp_meanoffset);
                rf->rf_minpri =
		        dfs_round((int32_t)T - (100*(dfs_radars[p].rp_pulsevar)));
		Tmax = (100000000/dfs_radars[p].rp_pulsefreq) -
		        100*(dfs_radars[p].rp_meanoffset);
        	rf->rf_maxpri =
	        	dfs_round((int32_t)Tmax + (100*(dfs_radars[p].rp_pulsevar)));

	        if( rf->rf_minpri < ft->ft_minpri )
		    ft->ft_minpri = rf->rf_minpri;

		rf->rf_fixed_pri_radar_pulse = ( dfs_radars[p].rp_max_pulsefreq == dfs_radars[p].rp_pulsefreq ) ? 1 : 0;
		rf->rf_threshold = dfs_radars[p].rp_threshold;
		rf->rf_filterlen = rf->rf_maxpri * rf->rf_numpulses;

		DFS_DPRINTK(sc, ATH_DEBUG_DFS2, "minprf = %d maxprf = %d pulsevar = %d thresh=%d\n",
		dfs_radars[p].rp_pulsefreq, dfs_radars[p].rp_max_pulsefreq, dfs_radars[p].rp_pulsevar, rf->rf_threshold);
		DFS_DPRINTK(sc, ATH_DEBUG_DFS2,
		"minpri = %d maxpri = %d filterlen = %d filterID = %d\n",
		rf->rf_minpri, rf->rf_maxpri, rf->rf_filterlen, rf->rf_pulseid);

                /* initialize athsstats/DFS related information */
                i = sc->sc_stats.ast_dfs_stats.num_filter;
                sc->sc_stats.ast_dfs_stats.fstat[i].max_pri_count = 0;
                sc->sc_stats.ast_dfs_stats.fstat[i].max_used_pri = 0;
                sc->sc_stats.ast_dfs_stats.fstat[i].excess_pri = 0;
                sc->sc_stats.ast_dfs_stats.fstat[i].pri_threshold_reached = 0;
                sc->sc_stats.ast_dfs_stats.fstat[i].dur_threshold_reached = 0;
                sc->sc_stats.ast_dfs_stats.fstat[i].rssi_threshold_reached = 0;
                sc->sc_stats.ast_dfs_stats.fstat[i].filter_id = rf->rf_pulseid;
                sc->sc_stats.ast_dfs_stats.num_filter++;

	    }

#ifdef DFS_DEBUG
	    dfs_print_filters(sc);
#endif
	    dfs->dfs_rinfo.rn_numbin5radars  = numb5radars;
	    if ( dfs->dfs_b5radars == NULL ) {
		dfs->dfs_b5radars = (struct dfs_bin5radars *)OS_MALLOC(sc->sc_osdev, numb5radars * sizeof(struct dfs_bin5radars),
		GFP_KERNEL);
		if (dfs->dfs_b5radars == NULL) {
		    DFS_DPRINTK(sc, ATH_DEBUG_DFS, 
		    "%s: cannot allocate memory for bin5 radars\n",
		    __func__);
		    goto bad4;
		}
	    }
	    for (n=0; n<numb5radars; n++) {
		dfs->dfs_b5radars[n].br_pulse = b5pulses[n];
		dfs->dfs_b5radars[n].br_pulse.b5_timewindow *= 1000000;
		if (dfs->dfs_b5radars[n].br_pulse.b5_rssithresh < min_rssithresh)
		min_rssithresh = dfs->dfs_b5radars[n].br_pulse.b5_rssithresh;
		if (dfs->dfs_b5radars[n].br_pulse.b5_maxdur > max_pulsedur )
		max_pulsedur = dfs->dfs_b5radars[n].br_pulse.b5_maxdur;
	    }
	    dfs_reset_alldelaylines(sc);
	    dfs_reset_radarq(sc);
	    dfs->dfs_curchan_radindex = -1;
	    dfs->dfs_extchan_radindex = -1;
	    dfs->dfs_rinfo.rn_minrssithresh = min_rssithresh;
	    /* Convert durations to TSF ticks */
	    dfs->dfs_rinfo.rn_maxpulsedur = dfs_round((int32_t)((max_pulsedur*100/80)*100));
	    /* relax the max pulse duration a little bit due to inaccuracy caused by chirping. */
	    dfs->dfs_rinfo.rn_maxpulsedur = dfs->dfs_rinfo.rn_maxpulsedur +20;
	    DFS_DPRINTK (sc, ATH_DEBUG_DFS, "DFS min filter rssiThresh = %d\n",min_rssithresh);
	    DFS_DPRINTK (sc, ATH_DEBUG_DFS, "DFS max pulse dur = %d ticks\n", dfs->dfs_rinfo.rn_maxpulsedur);
	    return 0;

	bad4:
	     return 1;
        }
     }
     return 0;
}
示例#7
0
/*
 * Calculate the receive filter according to the
 * operating mode and state:
 *
 * o always accept unicast, broadcast, and multicast traffic
 * o accept PHY error frames when hardware doesn't have MIB support
 *   to count and we need them for ANI (sta mode only until recently)
 *   and we are not scanning (ANI is disabled)
 *   NB: older hal's add rx filter bits out of sight and we need to
 *	 blindly preserve them
 * o probe request frames are accepted only when operating in
 *   hostap, adhoc, mesh, or monitor modes
 * o enable promiscuous mode
 *   - when in monitor mode
 *   - if interface marked PROMISC (assumes bridge setting is filtered)
 * o accept beacons:
 *   - when operating in station mode for collecting rssi data when
 *     the station is otherwise quiet, or
 *   - when operating in adhoc mode so the 802.11 layer creates
 *     node table entries for peers,
 *   - when scanning
 *   - when doing s/w beacon miss (e.g. for ap+sta)
 *   - when operating in ap mode in 11g to detect overlapping bss that
 *     require protection
 *   - when operating in mesh mode to detect neighbors
 * o accept control frames:
 *   - when in monitor mode
 * XXX HT protection for 11n
 */
u_int32_t
ath_calcrxfilter(struct ath_softc *sc)
{
	struct ifnet *ifp = sc->sc_ifp;
	struct ieee80211com *ic = ifp->if_l2com;
	u_int32_t rfilt;

	rfilt = HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST | HAL_RX_FILTER_MCAST;
	if (!sc->sc_needmib && !sc->sc_scanning)
		rfilt |= HAL_RX_FILTER_PHYERR;
	if (ic->ic_opmode != IEEE80211_M_STA)
		rfilt |= HAL_RX_FILTER_PROBEREQ;
	/* XXX ic->ic_monvaps != 0? */
	if (ic->ic_opmode == IEEE80211_M_MONITOR || (ifp->if_flags & IFF_PROMISC))
		rfilt |= HAL_RX_FILTER_PROM;
	if (ic->ic_opmode == IEEE80211_M_STA ||
	    ic->ic_opmode == IEEE80211_M_IBSS ||
	    sc->sc_swbmiss || sc->sc_scanning)
		rfilt |= HAL_RX_FILTER_BEACON;
	/*
	 * NB: We don't recalculate the rx filter when
	 * ic_protmode changes; otherwise we could do
	 * this only when ic_protmode != NONE.
	 */
	if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
	    IEEE80211_IS_CHAN_ANYG(ic->ic_curchan))
		rfilt |= HAL_RX_FILTER_BEACON;

	/*
	 * Enable hardware PS-POLL RX only for hostap mode;
	 * STA mode sends PS-POLL frames but never
	 * receives them.
	 */
	if (ath_hal_getcapability(sc->sc_ah, HAL_CAP_PSPOLL,
	    0, NULL) == HAL_OK &&
	    ic->ic_opmode == IEEE80211_M_HOSTAP)
		rfilt |= HAL_RX_FILTER_PSPOLL;

	if (sc->sc_nmeshvaps) {
		rfilt |= HAL_RX_FILTER_BEACON;
		if (sc->sc_hasbmatch)
			rfilt |= HAL_RX_FILTER_BSSID;
		else
			rfilt |= HAL_RX_FILTER_PROM;
	}
	if (ic->ic_opmode == IEEE80211_M_MONITOR)
		rfilt |= HAL_RX_FILTER_CONTROL;

	/*
	 * Enable RX of compressed BAR frames only when doing
	 * 802.11n. Required for A-MPDU.
	 */
	if (IEEE80211_IS_CHAN_HT(ic->ic_curchan))
		rfilt |= HAL_RX_FILTER_COMPBAR;

	/*
	 * Enable radar PHY errors if requested by the
	 * DFS module.
	 */
	if (sc->sc_dodfs)
		rfilt |= HAL_RX_FILTER_PHYRADAR;

	/*
	 * Enable spectral PHY errors if requested by the
	 * spectral module.
	 */
	if (sc->sc_dospectral)
		rfilt |= HAL_RX_FILTER_PHYRADAR;

	DPRINTF(sc, ATH_DEBUG_MODE, "%s: RX filter 0x%x, %s if_flags 0x%x\n",
	    __func__, rfilt, ieee80211_opmode_name[ic->ic_opmode], ifp->if_flags);
	return rfilt;
}
示例#8
0
文件: dfs.c 项目: jorneytu/wlan
int
dfs_attach(struct ath_softc *sc)
{
	int i, n;
	struct ath_dfs *dfs = sc->sc_dfs;
#define	N(a)	(sizeof(a)/sizeof(a[0]))

	if (dfs != NULL) {
		DFS_DPRINTK(sc, ATH_DEBUG_DFS, "%s: sc_dfs was not NULL\n",
			__func__);
		return 1;
	}
	dfs = (struct ath_dfs *)OS_MALLOC(sc->sc_osdev, sizeof(struct ath_dfs), GFP_KERNEL);
	if (dfs == NULL) {
		DFS_DPRINTK(sc, ATH_DEBUG_DFS,
			"%s: ath_dfs allocation failed\n", __func__);
		return 1;
	}

	OS_MEMZERO(dfs, sizeof (struct ath_dfs));
        sc->sc_dfs = dfs;
        dfs->dfs_nol=NULL;
        dfs_clear_stats(sc);

        /* Get capability information - can extension channel radar be detected and should we use combined radar RSSI or not.*/
        if (ath_hal_getcapability(sc->sc_ah, HAL_CAP_COMBINED_RADAR_RSSI, 0, 0) 
                                   == HAL_OK) {
                sc->sc_dfs->sc_dfs_combined_rssi_ok = 1;
        } else {
                sc->sc_dfs->sc_dfs_combined_rssi_ok = 0;
        }
        if (ath_hal_getcapability(sc->sc_ah, HAL_CAP_EXT_CHAN_DFS, 0, 0) 
                                    == HAL_OK) {
            sc->sc_dfs->sc_dfs_ext_chan_ok = 1;
        } else {
            sc->sc_dfs->sc_dfs_ext_chan_ok = 0;
        }

        if (ath_hal_hasenhanceddfssupport(sc->sc_ah)) {
            sc->sc_dfs->sc_dfs_use_enhancement = 1;
            DFS_DPRINTK(sc, ATH_DEBUG_DFS, "%s: use DFS enhancements\n", __func__);
        } else {
            sc->sc_dfs->sc_dfs_use_enhancement = 0;
        }
sc->sc_dfs->sc_dfs_cac_time = ATH_DFS_WAIT_MS;
        sc->sc_dfs->sc_dfstesttime = ATH_DFS_TEST_RETURN_PERIOD_MS;
	ATH_DFSQ_LOCK_INIT(dfs);
	STAILQ_INIT(&dfs->dfs_radarq);
	ATH_ARQ_LOCK_INIT(dfs);
	STAILQ_INIT(&dfs->dfs_arq);
	STAILQ_INIT(&(dfs->dfs_eventq));
	ATH_DFSEVENTQ_LOCK_INIT(dfs);
	dfs->events = (struct dfs_event *)OS_MALLOC(sc->sc_osdev,
                       sizeof(struct dfs_event)*DFS_MAX_EVENTS,
                       GFP_KERNEL);
	if (dfs->events == NULL) {
		OS_FREE(dfs);
                sc->sc_dfs = NULL;
		DFS_DPRINTK(sc, ATH_DEBUG_DFS,
			"%s: events allocation failed\n", __func__);
		return 1;
	}
	for (i=0; i<DFS_MAX_EVENTS; i++) {
		STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), &dfs->events[i], re_list);
	}

        dfs->pulses = (struct dfs_pulseline *)OS_MALLOC(sc->sc_osdev, sizeof(struct dfs_pulseline), GFP_KERNEL);

        if (dfs->pulses == NULL) {
                OS_FREE(dfs->events);   
                dfs->events = NULL;
                OS_FREE(dfs);
                sc->sc_dfs = NULL;
                DFS_DPRINTK(sc, ATH_DEBUG_DFS,
                        "%s: pulse buffer allocation failed\n", __func__);
                return 1;
        }

        dfs->pulses->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK;
#ifdef ATH_ENABLE_AR
	if (ath_hal_getcapability(sc->sc_ah, HAL_CAP_PHYDIAG,
				  HAL_CAP_AR, NULL) == HAL_OK) {
		dfs_reset_ar(sc);
		dfs_reset_arq(sc);
		dfs->dfs_proc_phyerr |= DFS_AR_EN;
	}
#endif
	if (ath_hal_getcapability(sc->sc_ah, HAL_CAP_PHYDIAG,
				  HAL_CAP_RADAR, NULL) == HAL_OK) {
		u_int32_t val;
		/* 
		 * If we have fast diversity capability, read off
		 * Strong Signal fast diversity count set in the ini
		 * file, and store so we can restore the value when
		 * radar is disabled
		 */
		if (ath_hal_getcapability(sc->sc_ah, HAL_CAP_DIVERSITY, HAL_CAP_STRONG_DIV,
					  &val) == HAL_OK) {
			dfs->dfs_rinfo.rn_fastdivGCval = val;
		}
		dfs->dfs_proc_phyerr |= DFS_RADAR_EN;

                /* Allocate memory for radar filters */
		for (n=0; n<DFS_MAX_RADAR_TYPES; n++) {
			dfs->dfs_radarf[n] = (struct dfs_filtertype *)OS_MALLOC(sc->sc_osdev, sizeof(struct dfs_filtertype),GFP_KERNEL);
			if (dfs->dfs_radarf[n] == NULL) {
				DFS_DPRINTK(sc,ATH_DEBUG_DFS,
					"%s: cannot allocate memory for radar filter types\n",
					__func__);
				goto bad1;
			}
			OS_MEMZERO(dfs->dfs_radarf[n], sizeof(struct dfs_filtertype));  
		}
                /* Allocate memory for radar table */
		dfs->dfs_radartable = (int8_t **)OS_MALLOC(sc->sc_osdev, 256*sizeof(int8_t *), GFP_KERNEL);
		if (dfs->dfs_radartable == NULL) {
			DFS_DPRINTK(sc, ATH_DEBUG_DFS, "%s: cannot allocate memory for radar table\n",
				__func__);
			goto bad1;
		}
		for (n=0; n<256; n++) {
			dfs->dfs_radartable[n] = OS_MALLOC(sc->sc_osdev, DFS_MAX_RADAR_OVERLAP*sizeof(int8_t),
							 GFP_KERNEL);
			if (dfs->dfs_radartable[n] == NULL) {
				DFS_DPRINTK(sc, ATH_DEBUG_DFS,
					"%s: cannot allocate memory for radar table entry\n",
					__func__);
				goto bad2;
			}
		}
		if (usenol != 1) {
			DFS_DPRINTK(sc, ATH_DEBUG_DFS, " %s: Disabling Channel NOL\n", __func__);
                }
		dfs->dfs_rinfo.rn_use_nol = usenol;

                /* Init the cached extension channel busy for false alarm reduction */
	        dfs->dfs_rinfo.ext_chan_busy_ts = ath_hal_gettsf64(sc->sc_ah);
                dfs->dfs_rinfo.dfs_ext_chan_busy = 0;
                /* Init the Bin5 chirping related data */
                dfs->dfs_rinfo.dfs_bin5_chirp_ts = dfs->dfs_rinfo.ext_chan_busy_ts;
                dfs->dfs_rinfo.dfs_last_bin5_dur = MAX_BIN5_DUR;

                dfs->dfs_b5radars = NULL;
                if ( dfs_init_radar_filters( sc ) ) {
			DFS_DPRINTK(sc, ATH_DEBUG_DFS, 
                            " %s: Radar Filter Intialization Failed \n", 
                            __func__);
                    return 1;
                }
	}
	return 0;
bad2:
	OS_FREE(dfs->dfs_radartable);
	dfs->dfs_radartable = NULL;
bad1:	
        for (n=0; n<DFS_MAX_RADAR_TYPES; n++) {
		if (dfs->dfs_radarf[n] != NULL) {
			OS_FREE(dfs->dfs_radarf[n]);
			dfs->dfs_radarf[n] = NULL;
		}
	}
        if (dfs->pulses) {
		OS_FREE(dfs->pulses);
		dfs->pulses = NULL;
	}
	if (dfs->events) {
		OS_FREE(dfs->events);
		dfs->events = NULL;
	}

	if (sc->sc_dfs) {
		OS_FREE(sc->sc_dfs);
		sc->sc_dfs = NULL;
	}
	return 1;
#undef N
}
示例#9
0
文件: dfs.c 项目: jorneytu/wlan
int dfs_radar_enable(struct ath_softc *sc)
{
	struct ath_dfs *dfs=sc->sc_dfs;
	u_int32_t rfilt;
	HAL_CHANNEL *chan=&sc->sc_curchan;
	struct ath_hal *ah = sc->sc_ah;
	HAL_CHANNEL *ext_ch=ath_hal_get_extension_channel(ah);

	if (dfs == NULL) {
		DFS_DPRINTK(sc, ATH_DEBUG_DFS, "%s: sc_dfs is NULL\n",
			__func__);
		return -EIO;
	}
	rfilt = ath_hal_getrxfilter(ah);
	if ((dfs->dfs_proc_phyerr & (DFS_RADAR_EN | DFS_AR_EN)) &&
	    (sc->sc_opmode == HAL_M_HOSTAP || sc->sc_opmode == HAL_M_IBSS)) {
            	if (chan->privFlags & CHANNEL_DFS) {
			struct dfs_state *rs_pri=NULL, *rs_ext=NULL;
			u_int8_t index_pri, index_ext;
			HAL_PHYERR_PARAM pe;
			dfs->sc_dfs_cac_time = ATH_DFS_WAIT_MS;

                        if (dfs->dfsdomain == DFS_ETSI_DOMAIN) {
                            if(IS_CHANNEL_WEATHER_RADAR(chan->channel)) {
                                dfs->sc_dfs_cac_time = ATH_DFS_WEATHER_CHANNEL_WAIT_MS;
                            } else {
                                 if (ext_ch && IS_CHANNEL_WEATHER_RADAR(ext_ch->channel)) {
                                     dfs->sc_dfs_cac_time = ATH_DFS_WEATHER_CHANNEL_WAIT_MS;
                                 }
                            }
                        }
                        if(dfs->sc_dfs_cac_time != ATH_DFS_WAIT_MS)
                            printk("WARNING!!! 10 minute CAC period as channel is a weather radar channel\n");
			/*
			  Disable radar detection in case we need to setup
			 * a new channel state and radars are somehow being
			 * reported. Avoids locking problem.
			 */

			rfilt = ath_hal_getrxfilter(ah);
			rfilt &= ~HAL_RX_FILTER_PHYRADAR;
			ath_hal_setrxfilter(ah, rfilt);
			/* Enable strong signal fast antenna diversity */
			ath_hal_setcapability(ah, HAL_CAP_DIVERSITY, 
					      HAL_CAP_STRONG_DIV, dfs->dfs_rinfo.rn_fastdivGCval, NULL);
			dfs_reset_alldelaylines(sc);

			rs_pri = dfs_getchanstate(sc, &index_pri, 0);
			if (ext_ch) {
                            rs_ext = dfs_getchanstate(sc, &index_ext, 1);
                            sc->sc_extchan = *ext_ch;
                        }
    			if (rs_pri != NULL && ((ext_ch==NULL)||(rs_ext != NULL))) {
				if (index_pri != dfs->dfs_curchan_radindex)
					dfs_reset_alldelaylines(sc);

				dfs->dfs_curchan_radindex = (int16_t) index_pri;
                                
                                if (rs_ext)
			            dfs->dfs_extchan_radindex = (int16_t) index_ext;

				pe.pe_firpwr = rs_pri->rs_firpwr;
				pe.pe_rrssi = rs_pri->rs_radarrssi;
				pe.pe_height = rs_pri->rs_height;
				pe.pe_prssi = rs_pri->rs_pulserssi;
				pe.pe_inband = rs_pri->rs_inband;
				/* 5413 specific */
				pe.pe_relpwr = rs_pri->rs_relpwr;
				pe.pe_relstep = rs_pri->rs_relstep;
				pe.pe_maxlen = rs_pri->rs_maxlen;


				/* Disable strong signal fast antenna diversity */
				ath_hal_setcapability(ah, HAL_CAP_DIVERSITY,
						      HAL_CAP_STRONG_DIV, 1, NULL);

				ath_hal_enabledfs(sc->sc_ah, &pe);
				rfilt |= HAL_RX_FILTER_PHYRADAR;
				ath_hal_setrxfilter(ah, rfilt);
				DFS_DPRINTK(sc, ATH_DEBUG_DFS, "Enabled radar detection on channel %d\n",
					chan->channel);

                                dfs->dur_multiplier =  (ath_hal_is_fast_clock_enabled(sc->sc_ah) ? (DFS_FAST_CLOCK_MULTIPLIER) : (DFS_NO_FAST_CLOCK_MULTIPLIER));
                    	DFS_DPRINTK(sc, ATH_DEBUG_DFS3,
			"%s: duration multiplier is %d\n", __func__, dfs->dur_multiplier);

				/*
				 * Fast antenna diversity for strong signals disturbs
				 * radar detection of 1-2us pusles. Enable fast diveristy
				 * but disable the strong signal aspect of it
				 */
				if (ath_hal_getcapability(ah, HAL_CAP_DIVERSITY, 1, NULL) == HAL_OK) {
					ath_hal_setcapability(ah, HAL_CAP_DIVERSITY, 
							      HAL_CAP_STRONG_DIV, 0, NULL);
				}
			} else
				DFS_DPRINTK(sc, ATH_DEBUG_DFS, "%s: No more radar states left\n",
					__func__);
		} else {
			if (!(chan->channelFlags & CHANNEL_2GHZ)) {
				/* Enable strong signal fast antenna diversity */
				ath_hal_setcapability(ah, HAL_CAP_DIVERSITY, 
						      HAL_CAP_STRONG_DIV, dfs->dfs_rinfo.rn_fastdivGCval, NULL);
				/* Disable Radar if not 2GHZ channel and not DFS */
				rfilt &= ~HAL_RX_FILTER_PHYRADAR;
				ath_hal_setrxfilter(ah, rfilt);
			}
		}
	} else {
		/* Enable strong signal fast antenna diversity */
		ath_hal_setcapability(ah, HAL_CAP_DIVERSITY, 
				      HAL_CAP_STRONG_DIV, dfs->dfs_rinfo.rn_fastdivGCval, NULL);
		/* Disable Radar if RADAR or AR not enabled */
		rfilt &= ~HAL_RX_FILTER_PHYRADAR;
		ath_hal_setrxfilter(ah, rfilt);
	}
	return 0;
}
示例#10
0
HAL_STATUS ar5416GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
			       a_uint32_t capability, a_uint32_t *result)

{
	return ath_hal_getcapability(ah, type, capability, result);
}
示例#11
0
/*
 * Enable radar detection and set the radar parameters per the
 * values in pe
 */
void
ar9300_enable_dfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
{
    u_int32_t val;
    struct ath_hal_private  *ahp = AH_PRIVATE(ah);
    HAL_CHANNEL_INTERNAL *ichan = ahp->ah_curchan;
    struct ath_hal_9300 *ah9300 = AH9300(ah);
    bool asleep = ah9300->ah_chip_full_sleep;
    int reg_writes = 0;

    if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
        ar9300_set_power_mode(ah, HAL_PM_AWAKE, true);
    }

    val = OS_REG_READ(ah, AR_PHY_RADAR_0);
    val |= AR_PHY_RADAR_0_FFT_ENA | AR_PHY_RADAR_0_ENA;
    if (pe->pe_firpwr != HAL_PHYERR_PARAM_NOVAL) {
        val &= ~AR_PHY_RADAR_0_FIRPWR;
        val |= SM(pe->pe_firpwr, AR_PHY_RADAR_0_FIRPWR);
    }
    if (pe->pe_rrssi != HAL_PHYERR_PARAM_NOVAL) {
        val &= ~AR_PHY_RADAR_0_RRSSI;
        val |= SM(pe->pe_rrssi, AR_PHY_RADAR_0_RRSSI);
    }
    if (pe->pe_height != HAL_PHYERR_PARAM_NOVAL) {
        val &= ~AR_PHY_RADAR_0_HEIGHT;
        val |= SM(pe->pe_height, AR_PHY_RADAR_0_HEIGHT);
    }
    if (pe->pe_prssi != HAL_PHYERR_PARAM_NOVAL) {
        val &= ~AR_PHY_RADAR_0_PRSSI;
        if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
            if (ah->ah_use_cac_prssi) {
                val |= SM(AR9300_DFS_PRSSI_CAC, AR_PHY_RADAR_0_PRSSI);
            } else {
                val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI);
            }
        } else {
            val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI);
        }
    }
    if (pe->pe_inband != HAL_PHYERR_PARAM_NOVAL) {
        val &= ~AR_PHY_RADAR_0_INBAND;
        val |= SM(pe->pe_inband, AR_PHY_RADAR_0_INBAND);
    }
    OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);

    val = OS_REG_READ(ah, AR_PHY_RADAR_1);
    val |= AR_PHY_RADAR_1_MAX_RRSSI | AR_PHY_RADAR_1_BLOCK_CHECK;
    if (pe->pe_maxlen != HAL_PHYERR_PARAM_NOVAL) {
        val &= ~AR_PHY_RADAR_1_MAXLEN;
        val |= SM(pe->pe_maxlen, AR_PHY_RADAR_1_MAXLEN);
    }
    if (pe->pe_relstep != HAL_PHYERR_PARAM_NOVAL) {
        val &= ~AR_PHY_RADAR_1_RELSTEP_THRESH;
        val |= SM(pe->pe_relstep, AR_PHY_RADAR_1_RELSTEP_THRESH);
    }
    if (pe->pe_relpwr != HAL_PHYERR_PARAM_NOVAL) {
        val &= ~AR_PHY_RADAR_1_RELPWR_THRESH;
        val |= SM(pe->pe_relpwr, AR_PHY_RADAR_1_RELPWR_THRESH);
    }
    OS_REG_WRITE(ah, AR_PHY_RADAR_1, val);

    if (ath_hal_getcapability(ah, HAL_CAP_EXT_CHAN_DFS, 0, 0) == HAL_OK) {
        val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);
        if (IS_CHAN_HT40(ichan)) {
            /* Enable extension channel radar detection */
            OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val | AR_PHY_RADAR_EXT_ENA);
        } else {
            /* HT20 mode, disable extension channel radar detect */
            OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA);
        }
    }
    /*
        apply DFS postamble array from INI
        column 0 is register ID, column 1 is  HT20 value, colum2 is HT40 value
    */

    if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_OSPREY_22(ah) || AR_SREV_SCORPION(ah)) {
        REG_WRITE_ARRAY(&ah9300->ah_ini_dfs,IS_CHAN_HT40(ichan)? 2:1, reg_writes);
    }
#ifdef ATH_HAL_DFS_CHIRPING_FIX_APH128
    HDPRINTF(ah, HAL_DBG_DFS,"DFS change the timing value\n");
    if (AR_SREV_AR9580(ah) && IS_CHAN_HT40(ichan)) {
        OS_REG_WRITE(ah, AR_PHY_TIMING6, 0x3140c00a);	
    }
#endif
    if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
        ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, true);
    }
}
示例#12
0
void
ar9300EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
{
    u_int32_t val;
    struct ath_hal_private  *ahp = AH_PRIVATE(ah);
    HAL_CHANNEL_INTERNAL *ichan = ahp->ah_curchan;

    val = OS_REG_READ(ah, AR_PHY_RADAR_0);
    if (pe->pe_firpwr != HAL_PHYERR_PARAM_NOVAL) {
        val &= ~AR_PHY_RADAR_0_FIRPWR;
        val |= SM(pe->pe_firpwr, AR_PHY_RADAR_0_FIRPWR);
    }
    if (pe->pe_rrssi != HAL_PHYERR_PARAM_NOVAL) {
        val &= ~AR_PHY_RADAR_0_RRSSI;
        val |= SM(pe->pe_rrssi, AR_PHY_RADAR_0_RRSSI);
    }
    if (pe->pe_height != HAL_PHYERR_PARAM_NOVAL) {
        val &= ~AR_PHY_RADAR_0_HEIGHT;
        val |= SM(pe->pe_height, AR_PHY_RADAR_0_HEIGHT);
    }
    if (pe->pe_prssi != HAL_PHYERR_PARAM_NOVAL) {
        val &= ~AR_PHY_RADAR_0_PRSSI;

        if (AR_SREV_AR9580(ah)) {
            if (ah->ah_use_cac_prssi) {
                val |= SM(AR9300_DFS_PRSSI_CAC, AR_PHY_RADAR_0_PRSSI);
            } else {
                val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI);
            }
        } else {
            val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI);
        }
    }
    if (pe->pe_inband != HAL_PHYERR_PARAM_NOVAL) {
        val &= ~AR_PHY_RADAR_0_INBAND;
        val |= SM(pe->pe_inband, AR_PHY_RADAR_0_INBAND);
    }

    /*Enable FFT data*/
    val |= AR_PHY_RADAR_0_FFT_ENA;

    OS_REG_WRITE(ah, AR_PHY_RADAR_0, val | AR_PHY_RADAR_0_ENA);

    val = OS_REG_READ(ah, AR_PHY_RADAR_1);
    val |= (AR_PHY_RADAR_1_MAX_RRSSI | AR_PHY_RADAR_1_BLOCK_CHECK);

    if (pe->pe_maxlen != HAL_PHYERR_PARAM_NOVAL) {
        val &= ~AR_PHY_RADAR_1_MAXLEN;
        val |= SM(pe->pe_maxlen, AR_PHY_RADAR_1_MAXLEN);
    }

    OS_REG_WRITE(ah, AR_PHY_RADAR_1, val);

    if (ath_hal_getcapability(ah, HAL_CAP_EXT_CHAN_DFS, 0, 0) == HAL_OK) {
        if (IS_CHAN_HT40(ichan)) {
            /*Enable extension channel radar detection*/
            val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);
            OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val | AR_PHY_RADAR_EXT_ENA);
        } else {
            /*HT20 mode, disable extension channel radar detect*/
            val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);
            OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA);
        }
    }

    if (pe->pe_relstep != HAL_PHYERR_PARAM_NOVAL) {
        val = OS_REG_READ(ah, AR_PHY_RADAR_1);
        val &= ~AR_PHY_RADAR_1_RELSTEP_THRESH;
        val |= SM(pe->pe_relstep, AR_PHY_RADAR_1_RELSTEP_THRESH);
        OS_REG_WRITE(ah, AR_PHY_RADAR_1, val);
    }
    if (pe->pe_relpwr != HAL_PHYERR_PARAM_NOVAL) {
        val = OS_REG_READ(ah, AR_PHY_RADAR_1);
        val &= ~AR_PHY_RADAR_1_RELPWR_THRESH;
        val |= SM(pe->pe_relpwr, AR_PHY_RADAR_1_RELPWR_THRESH);
        OS_REG_WRITE(ah, AR_PHY_RADAR_1, val);
    }
}