コード例 #1
0
ファイル: dfs.c プロジェクト: edwacode/qca-hostap
static
OS_TIMER_FUNC(dfs_testtimer_task)
{
    struct ieee80211com *ic;
    struct ath_dfs *dfs = NULL;

    OS_GET_TIMER_ARG(ic, struct ieee80211com *);
    dfs = (struct ath_dfs *)ic->ic_dfs;

    /* XXX no locking? */
    dfs->ath_dfstest = 0;

    /*
     * Flip the channel back to the original channel.
     * Make sure this is done properly with a CSA.
     */
    DFS_PRINTK("%s: go back to channel %d\n",
        __func__,
        dfs->ath_dfstest_ieeechan);

    /*
     * XXX The mere existence of this method indirection
     *     to a umac function means this code belongs in
     *     the driver, _not_ here.  Please fix this!
     */
    ic->ic_start_csa(ic, dfs->ath_dfstest_ieeechan);
}
コード例 #2
0
ファイル: dfs.c プロジェクト: edwacode/qca-hostap
/*
 * Mark a channel as having interference detected upon it.
 *
 * This adds the interference marker to both the primary and
 * extension channel.
 *
 * XXX TODO: make the NOL and channel interference logic a bit smarter
 * so only the channel with the radar event is marked, rather than
 * both the primary and extension.
 */
static void
dfs_channel_mark_radar(struct ath_dfs *dfs, struct ieee80211_channel *chan)
{
    struct ieee80211_channel_list chan_info;
    int i;

    //chan->ic_flagext |= CHANNEL_INTERFERENCE;

    /*
     * If radar is detected in 40MHz mode, add both the primary and the
     * extension channels to the NOL. chan is the channel data we return
     * to the ath_dev layer which passes it on to the 80211 layer.
     * As we want the AP to change channels and send out a CSA,
     * we always pass back the primary channel data to the ath_dev layer.
     */
    if ((dfs->dfs_rinfo.rn_use_nol == 1) &&
      (dfs->ic->ic_opmode == IEEE80211_M_HOSTAP ||
#if ATH_SUPPORT_DFS && ATH_SUPPORT_STA_DFS
       dfs->ic->ic_opmode == IEEE80211_M_IBSS ||
       ((dfs->ic->ic_opmode == IEEE80211_M_STA) &&
        (ieee80211com_has_cap_ext(dfs->ic,IEEE80211_CEXT_STADFS))))) {
#else
        dfs->ic->ic_opmode == IEEE80211_M_IBSS)) {
#endif
        chan_info.cl_nchans= 0;
        dfs->ic->ic_get_ext_chan_info (dfs->ic, &chan_info);
        
        for (i = 0; i < chan_info.cl_nchans; i++)
        { 
            if (chan_info.cl_channels[i] == NULL) {
                DFS_PRINTK("%s: NULL channel\n", __func__);
            } else {
                chan_info.cl_channels[i]->ic_flagext |= CHANNEL_INTERFERENCE;
                dfs_nol_addchan(dfs, chan_info.cl_channels[i], dfs->ath_dfs_nol_timeout); 
            }
        }
        

        /*
         * Update the umac/driver channels with the new NOL information.
         */
        dfs_nol_update(dfs);
    }
}
コード例 #3
0
ファイル: dfs_nol.c プロジェクト: KHATEEBNSIT/AP
/*
 * Delete the given frequency/chwidth from the NOL.
 */
static void
dfs_nol_delete(struct ath_dfs *dfs, u_int16_t delfreq, u_int16_t delchwidth)
{
    struct dfs_nolelem *nol,**prev_next;

    if (dfs == NULL) {
        DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: sc_dfs is NULL\n", __func__);
        return;
    }

    DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL,
      "%s: remove channel=%d/%d MHz from NOL\n",
      __func__,
      delfreq, delchwidth);
    prev_next = &(dfs->dfs_nol);
    nol = dfs->dfs_nol;
    while (nol != NULL) {
        if (nol->nol_freq == delfreq && nol->nol_chwidth == delchwidth) {
            *prev_next = nol->nol_next;
            DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL,
              "%s removing channel %d/%dMHz from NOL tstamp=%d\n",
                __func__, nol->nol_freq, nol->nol_chwidth,
                (adf_os_ticks_to_msecs(adf_os_ticks()) / 1000));
            OS_CANCEL_TIMER(&nol->nol_timer);
            OS_FREE(nol);
            nol = NULL;
            nol = *prev_next;

            /* Update the NOL counter */
            dfs->dfs_nol_count--;

            /* Be paranoid! */
            if (dfs->dfs_nol_count < 0) {
                DFS_PRINTK("%s: dfs_nol_count < 0; eek!\n", __func__);
                dfs->dfs_nol_count = 0;
            }

        } else {
            prev_next = &(nol->nol_next);
            nol = nol->nol_next;
        }
    }
}
コード例 #4
0
ファイル: dfs_phyerr_tlv.c プロジェクト: KHATEEBNSIT/AP
/*
 * Calculate the channel centre in MHz.
 */
static int
tlv_calc_freq_info(struct ath_dfs *dfs, struct rx_radar_status *rs)
{
	uint32_t chan_centre;
	uint32_t chan_width;
	int chan_offset;

	/*
	 * For now, just handle up to VHT80 correctly.
	 */
	if (dfs->ic == NULL || dfs->ic->ic_curchan == NULL) {
		DFS_PRINTK("%s: dfs->ic=%p, that or curchan is null?\n",
		    __func__, dfs->ic);
		return (0);
	/*
	 * For now, the only 11ac channel with freq1/freq2 setup is
	 * VHT80.
	 *
	 * XXX should have a flag macro to check this!
	 */
	} else if (IEEE80211_IS_CHAN_11AC_VHT80(dfs->ic->ic_curchan)) {
		/* 11AC, so cfreq1/cfreq2 are setup */

		/*
		 * XXX if it's 80+80 this won't work - need to use seg
		 * appropriately!
		 */

		chan_centre = dfs->ic->ic_ieee2mhz(
		    dfs->ic->ic_curchan->ic_vhtop_ch_freq_seg1,
		    dfs->ic->ic_curchan->ic_flags);
	} else {
		/* HT20/HT40 */

		/*
		 * XXX this is hard-coded - it should be 5 or 10 for
		 * half/quarter appropriately.
		 */
		chan_width = 20;

		/* Grab default channel centre */
		chan_centre = ieee80211_chan2freq(dfs->ic,
		    dfs->ic->ic_curchan);

		/* Calculate offset based on HT40U/HT40D and VHT40U/VHT40D */
		if (IEEE80211_IS_CHAN_11N_HT40PLUS(dfs->ic->ic_curchan) ||
		    dfs->ic->ic_curchan->ic_flags & IEEE80211_CHAN_VHT40PLUS)
			chan_offset = chan_width;
		else if (IEEE80211_IS_CHAN_11N_HT40MINUS(dfs->ic->ic_curchan) ||
		    dfs->ic->ic_curchan->ic_flags & IEEE80211_CHAN_VHT40MINUS)
			chan_offset = -chan_width;
		else
			chan_offset = 0;

		/* Calculate new _real_ channel centre */
		chan_centre += (chan_offset / 2);
	}

	/*
	 * XXX half/quarter rate support!
	 */

	/* Return ev_chan_centre in MHz */
	return (chan_centre);
}
コード例 #5
0
ファイル: dfs_fcc_bin5.c プロジェクト: S5-APQ8084/qcacld-3.0
int dfs_bin5_check(struct ath_dfs *dfs)
{
	struct dfs_bin5radars *br;
	int index[DFS_MAX_B5_SIZE];
	uint32_t n = 0, i = 0, i1 = 0, this = 0, prev = 0, rssi_diff =
		0, width_diff = 0, bursts = 0;
	uint32_t total_diff = 0, average_diff = 0, total_width =
		0, average_width = 0, numevents = 0;
	uint64_t pri;

	if (dfs == NULL) {
		DFS_PRINTK("%s: ic_dfs is NULL\n", __func__);
		return 1;
	}
	for (n = 0; n < dfs->dfs_rinfo.rn_numbin5radars; n++) {
		br = &(dfs->dfs_b5radars[n]);
		DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5,
			    "Num elems = %d\n", br->br_numelems);

		/* find a valid bin 5 pulse and use it as reference */
		for (i1 = 0; i1 < br->br_numelems; i1++) {
			this = ((br->br_firstelem + i1) & DFS_MAX_B5_MASK);
			if ((br->br_elems[this].be_dur >= MIN_BIN5_DUR_MICROSEC)
			    && (br->br_elems[this].be_dur <=
				MAX_BIN5_DUR_MICROSEC)) {
				break;
			}
		}

		prev = this;
		for (i = i1 + 1; i < br->br_numelems; i++) {
			this = ((br->br_firstelem + i) & DFS_MAX_B5_MASK);

			/* first make sure it is a bin 5 pulse by checking the duration */
			if ((br->br_elems[this].be_dur < MIN_BIN5_DUR_MICROSEC)
			    || (br->br_elems[this].be_dur >
				MAX_BIN5_DUR_MICROSEC)) {
				continue;
			}

			/* Rule 1: 1000 <= PRI <= 2000 + some margin */
			if (br->br_elems[this].be_ts >=
			    br->br_elems[prev].be_ts) {
				pri =
					br->br_elems[this].be_ts -
					br->br_elems[prev].be_ts;
			} else {        /* roll over case */
				/* pri = (0xffffffffffffffff - br->br_elems[prev].be_ts) + br->br_elems[this].be_ts; */
				pri = br->br_elems[this].be_ts;
			}
			DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5,
				    " pri=%llu this.ts=%llu this.dur=%d this.rssi=%d prev.ts=%llu\n",
				    (unsigned long long)pri,
				    (unsigned long long)br->br_elems[this].
				    be_ts, (int)br->br_elems[this].be_dur,
				    (int)br->br_elems[this].be_rssi,
				    (unsigned long long)br->br_elems[prev].
				    be_ts);
			if (((pri >= DFS_BIN5_PRI_LOWER_LIMIT) && (pri <= DFS_BIN5_PRI_HIGHER_LIMIT))) {        /* pri: pulse repitition interval in us */
				/* Rule 2: pulse width of the pulses in the burst should be same (+/- margin) */
				if (br->br_elems[this].be_dur >=
				    br->br_elems[prev].be_dur) {
					width_diff =
						br->br_elems[this].be_dur -
						br->br_elems[prev].be_dur;
				} else {
					width_diff =
						br->br_elems[prev].be_dur -
						br->br_elems[this].be_dur;
				}
				if (width_diff <= DFS_BIN5_WIDTH_MARGIN) {
					/* Rule 3: RSSI of the pulses in the burst should be same (+/- margin) */
					if (br->br_elems[this].be_rssi >=
					    br->br_elems[prev].be_rssi) {
						rssi_diff =
							br->br_elems[this].be_rssi -
							br->br_elems[prev].be_rssi;
					} else {
						rssi_diff =
							br->br_elems[prev].be_rssi -
							br->br_elems[this].be_rssi;
					}
					if (rssi_diff <= DFS_BIN5_RSSI_MARGIN) {
						bursts++;
						/* Save the indexes of this pair for later width variance check */
						if (numevents >= 2) {
							/* make sure the event is not duplicated,
							 * possible in a 3 pulse burst */
							if (index[numevents - 1]
							    != prev) {
								index
								[numevents++]
									= prev;
							}
						} else {
							index[numevents++] =
								prev;
						}
						index[numevents++] = this;
					} else {
						DFS_DPRINTK(dfs,
							    ATH_DEBUG_DFS_BIN5,
							    "%s %d Bin5 rssi_diff=%d\n",
							    __func__, __LINE__,
							    rssi_diff);
					}
				} else {
					DFS_DPRINTK(dfs,
						    ATH_DEBUG_DFS_BIN5,
						    "%s %d Bin5 width_diff=%d\n",
						    __func__, __LINE__,
						    width_diff);
				}
			} else if ((pri >= DFS_BIN5_BRI_LOWER_LIMIT) &&
				   (pri <= DFS_BIN5_BRI_UPPER_LIMIT)) {
				/* check pulse width to make sure it is in range of bin 5 */
				/* if ((br->br_elems[this].be_dur >= MIN_BIN5_DUR_MICROSEC) && (br->br_elems[this].be_dur <= MAX_BIN5_DUR_MICROSEC)) { */
				bursts++;
				/* } */
			} else {
				DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5,
					    "%s %d Bin5 PRI check fail pri=%llu\n",
					    __func__, __LINE__,
					    (unsigned long long)pri);
			}
			prev = this;
		}

		DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, "bursts=%u numevents=%u\n",
			    bursts, numevents);
		if (bursts >= br->br_pulse.b5_threshold) {
			if ((br->br_elems[br->br_lastelem].be_ts -
			     br->br_elems[br->br_firstelem].be_ts) < 3000000) {
				return 0;
			} else {
				/*
				 * don't do this check since not all the cases have this kind of burst width variation.
				 *
				   for (i=0; i<bursts; i++){
				   total_width += br->br_elems[index[i]].be_dur;
				   }
				   average_width = total_width/bursts;
				   for (i=0; i<bursts; i++){
				   total_diff += DFS_DIFF(br->br_elems[index[i]].be_dur, average_width);
				   }
				   average_diff = total_diff/bursts;
				   if( average_diff > DFS_BIN5_WIDTH_MARGIN ) {
				   return 1;
				   } else {

				   DFS_DPRINTK(ic, ATH_DEBUG_DFS_BIN5, "bursts=%u numevents=%u total_width=%d average_width=%d total_diff=%d average_diff=%d\n", bursts, numevents, total_width, average_width, total_diff, average_diff);

				   }
				 */
				DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5,
					    "bursts=%u numevents=%u total_width=%d average_width=%d total_diff=%d average_diff=%d\n",
					    bursts, numevents, total_width,
					    average_width, total_diff,
					    average_diff);
				DFS_PRINTK("bin 5 radar detected, bursts=%d\n",
					   bursts);
				return 1;
			}
		}
	}

	return 0;
}
コード例 #6
0
ファイル: dfs.c プロジェクト: edwacode/qca-hostap
/*
 * This is called each time a channel change occurs, to (potentially) enable
 * the radar code.
 */
int dfs_radar_enable(struct ieee80211com *ic,
    struct ath_dfs_radar_tab_info *radar_info, int no_cac)
{
    int                                 is_ext_ch=IEEE80211_IS_CHAN_11N_HT40(ic->ic_curchan);
    int                                 is_fastclk = 0;
    //u_int32_t                        rfilt;
    struct ath_dfs                 *dfs=(struct ath_dfs *)ic->ic_dfs;
    struct ieee80211_channel *chan=ic->ic_curchan, *ext_ch = NULL;
  
	if (dfs == NULL) {
		DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: ic_dfs is NULL\n",
			__func__);
		return -EIO;
	}
	ic->ic_dfs_disable(ic, no_cac);

	/*
	 * Setting country code might change the DFS domain
	 * so initialize the DFS Radar filters
	 */
	dfs_init_radar_filters(ic, radar_info);
#if ATH_SUPPORT_DFS && ATH_SUPPORT_STA_DFS
	if ((ic->ic_opmode == IEEE80211_M_HOSTAP || ic->ic_opmode == IEEE80211_M_IBSS ||
                (ic->ic_opmode == IEEE80211_M_STA && ieee80211com_has_cap_ext(dfs->ic,IEEE80211_CEXT_STADFS)))) {
#else
	if ((ic->ic_opmode == IEEE80211_M_HOSTAP || ic->ic_opmode == IEEE80211_M_IBSS)) {
#endif
            	if (IEEE80211_IS_CHAN_DFS(chan)) {
			struct dfs_state *rs_pri=NULL, *rs_ext=NULL;
			u_int8_t index_pri, index_ext;
#ifdef ATH_ENABLE_AR
    dfs->dfs_proc_phyerr |= DFS_AR_EN;
#endif
    dfs->dfs_proc_phyerr |= DFS_RADAR_EN;
    //printk( "%s[%d]: ==== 0x%08x\n", __func__, __LINE__, dfs->dfs_proc_phyerr);


                   if (is_ext_ch) {
                       ext_ch = ieee80211_get_extchan(ic);
                   }
			dfs_reset_alldelaylines(dfs);

			rs_pri = dfs_getchanstate(dfs, &index_pri, 0);
			if (ext_ch) {
                            rs_ext = dfs_getchanstate(dfs, &index_ext, 1);
                   }
    			if (rs_pri != NULL && ((ext_ch==NULL)||(rs_ext != NULL))) {
				struct ath_dfs_phyerr_param pe;

				OS_MEMSET(&pe, '\0', sizeof(pe));

				if (index_pri != dfs->dfs_curchan_radindex)
					dfs_reset_alldelaylines(dfs);

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

				ath_dfs_phyerr_param_copy(&pe,
				    &rs_pri->rs_param);
				DFS_DPRINTK(dfs, ATH_DEBUG_DFS3,
				    "%s: firpwr=%d, rssi=%d, height=%d, "
				    "prssi=%d, inband=%d, relpwr=%d, "
				    "relstep=%d, maxlen=%d\n",
				    __func__,
				    pe.pe_firpwr,
				    pe.pe_rrssi,
				    pe.pe_height,
				    pe.pe_prssi,
				    pe.pe_inband,
				    pe.pe_relpwr,
				    pe.pe_relstep,
				    pe.pe_maxlen
				    );

#if 0 //Not needed
				/* Disable strong signal fast antenna diversity */
				ath_hal_setcapability(ah, HAL_CAP_DIVERSITY,
						      HAL_CAP_STRONG_DIV, 1, NULL);
#endif
	                    ic->ic_dfs_enable(ic, &is_fastclk, &pe);
				DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "Enabled radar detection on channel %d\n",
					chan->ic_freq);

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

			} else
				DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: No more radar states left\n",
					__func__);
		} 
	} 
	return 0;
}

int
dfs_control(struct ieee80211com *ic, u_int id,
                void *indata, u_int32_t insize,
                void *outdata, u_int32_t *outsize)
{
	int error = 0;
	struct ath_dfs_phyerr_param peout;
	struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs;
	struct dfs_ioctl_params *dfsparams;
    u_int32_t val=0;
#ifndef ATH_DFS_RADAR_DETECTION_ONLY
    struct dfsreq_nolinfo *nol;
    u_int32_t *data = NULL;
#endif /* ATH_DFS_RADAR_DETECTION_ONLY */
    int i;

	if (dfs == NULL) {
                DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s DFS is null\n", __func__);
                /* Enable/Disable DFS can be done prior to attach, So handle here */
	switch (id) {
        case DFS_DISABLE_DETECT:
                ic->ic_dfs_state.ignore_dfs = 1;
                DFS_PRINTK("%s enable detects, ignore_dfs %d\n", 
                    __func__,
		   ic->ic_dfs_state.ignore_dfs ? 1:0);
                break;
        case DFS_ENABLE_DETECT:
                ic->ic_dfs_state.ignore_dfs = 0;
                DFS_PRINTK("%s enable detects, ignore_dfs %d\n", 
                    __func__,
		    ic->ic_dfs_state.ignore_dfs ? 1:0);
                break;
        default:
            error = -EINVAL;
            break;
       }
		goto bad;
	}

      //printk("%s[%d] id =%d\n", __func__, __LINE__, id);
	switch (id) {
	case DFS_SET_THRESH:
		if (insize < sizeof(struct dfs_ioctl_params) || !indata) {
			DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
			    "%s: insize=%d, expected=%d bytes, indata=%p\n",
			    __func__, insize, sizeof(struct dfs_ioctl_params),
			    indata);
			error = -EINVAL;
			break;
		}
		dfsparams = (struct dfs_ioctl_params *) indata;
		if (!dfs_set_thresholds(ic, DFS_PARAM_FIRPWR, dfsparams->dfs_firpwr))
			error = -EINVAL;
		if (!dfs_set_thresholds(ic, DFS_PARAM_RRSSI, dfsparams->dfs_rrssi))
			error = -EINVAL;
		if (!dfs_set_thresholds(ic, DFS_PARAM_HEIGHT, dfsparams->dfs_height))
			error = -EINVAL;
		if (!dfs_set_thresholds(ic, DFS_PARAM_PRSSI, dfsparams->dfs_prssi))
			error = -EINVAL;
		if (!dfs_set_thresholds(ic, DFS_PARAM_INBAND, dfsparams->dfs_inband))
			error = -EINVAL;
		/* 5413 speicfic */
		if (!dfs_set_thresholds(ic, DFS_PARAM_RELPWR, dfsparams->dfs_relpwr))
			error = -EINVAL;
		if (!dfs_set_thresholds(ic, DFS_PARAM_RELSTEP, dfsparams->dfs_relstep))
			error = -EINVAL;
		if (!dfs_set_thresholds(ic, DFS_PARAM_MAXLEN, dfsparams->dfs_maxlen))
			error = -EINVAL;
		break;
	case DFS_GET_THRESH:
		if (!outdata || !outsize || *outsize <sizeof(struct dfs_ioctl_params)) {
			error = -EINVAL;
			break;
		}
		*outsize = sizeof(struct dfs_ioctl_params);
		dfsparams = (struct dfs_ioctl_params *) outdata;

		/*
		 * Fetch the DFS thresholds using the internal representation.
		 */
		(void) dfs_get_thresholds(ic, &peout);

		/*
		 * Convert them to the dfs IOCTL representation.
		 */
		ath_dfs_dfsparam_to_ioctlparam(&peout, dfsparams);
                break;
	case DFS_RADARDETECTS:
		if (!outdata || !outsize || *outsize < sizeof(u_int32_t)) {
			error = -EINVAL;
			break;
		}
		*outsize = sizeof (u_int32_t);
		*((u_int32_t *)outdata) = dfs->ath_dfs_stats.num_radar_detects;
		break;
        case DFS_DISABLE_DETECT:
                dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN;
                dfs->ic->ic_dfs_state.ignore_dfs = 1;
                DFS_PRINTK("%s enable detects, ignore_dfs %d\n", 
                    __func__,
		    dfs->ic->ic_dfs_state.ignore_dfs ? 1:0);
                break;
        case DFS_ENABLE_DETECT:
		dfs->dfs_proc_phyerr |= DFS_RADAR_EN;
                dfs->ic->ic_dfs_state.ignore_dfs = 0;
                DFS_PRINTK("%s enable detects, ignore_dfs %d\n", 
                    __func__,
		    dfs->ic->ic_dfs_state.ignore_dfs ? 1:0);
                break;
        case DFS_DISABLE_FFT:
                //UMACDFS: TODO: val = ath_hal_dfs_config_fft(sc->sc_ah, false);
                DFS_PRINTK("%s TODO disable FFT val=0x%x \n", __func__, val);
                break;
        case DFS_ENABLE_FFT:
                //UMACDFS TODO: val = ath_hal_dfs_config_fft(sc->sc_ah, true);
                DFS_PRINTK("%s TODO enable FFT val=0x%x \n", __func__, val);
                break;
        case DFS_SET_DEBUG_LEVEL:
		if (insize < sizeof(u_int32_t) || !indata) {
			error = -EINVAL;
			break;
		}
		dfs->dfs_debug_mask= *(u_int32_t *)indata;
		DFS_PRINTK("%s debug level now = 0x%x \n",
		    __func__,
		    dfs->dfs_debug_mask);
                if (dfs->dfs_debug_mask & ATH_DEBUG_DFS3) {
                    /* Enable debug Radar Event */
                    dfs->dfs_event_log_on = 1;
                } else {
                    dfs->dfs_event_log_on = 0;
                }
                break;
        case DFS_SET_FALSE_RSSI_THRES:
		if (insize < sizeof(u_int32_t) || !indata) {
			error = -EINVAL;
			break;
		}
		dfs->ath_dfs_false_rssi_thres= *(u_int32_t *)indata;
		DFS_PRINTK("%s false RSSI threshold now = 0x%x \n",
		    __func__,
		    dfs->ath_dfs_false_rssi_thres);
                break;
        case DFS_SET_PEAK_MAG:
		if (insize < sizeof(u_int32_t) || !indata) {
			error = -EINVAL;
			break;
		}
		dfs->ath_dfs_peak_mag= *(u_int32_t *)indata;
		DFS_PRINTK("%s peak_mag now = 0x%x \n",
		    __func__,
		    dfs->ath_dfs_peak_mag);
                break;
	case DFS_GET_CAC_VALID_TIME:
		if (!outdata || !outsize || *outsize < sizeof(u_int32_t)) {
			error = -EINVAL;
			break;
		}
		*outsize = sizeof (u_int32_t);
		*((u_int32_t *)outdata) = dfs->ic->ic_dfs_state.cac_valid_time;
		break;
        case DFS_SET_CAC_VALID_TIME:
		if (insize < sizeof(u_int32_t) || !indata) {
			error = -EINVAL;
			break;
		}
		dfs->ic->ic_dfs_state.cac_valid_time = *(u_int32_t *)indata;
		DFS_PRINTK("%s dfs timeout = %d \n",
		    __func__,
		    dfs->ic->ic_dfs_state.cac_valid_time);
                break;
        case DFS_IGNORE_CAC:
		if (insize < sizeof(u_int32_t) || !indata) {
			error = -EINVAL;
			break;
		}
             if (*(u_int32_t *)indata) {
                 dfs->ic->ic_dfs_state.ignore_cac= 1;
             } else {
                 dfs->ic->ic_dfs_state.ignore_cac= 0;
             }
		DFS_PRINTK("%s ignore cac = 0x%x \n",
		    __func__,
		    dfs->ic->ic_dfs_state.ignore_cac);
                break;
        case DFS_SET_NOL_TIMEOUT:
		if (insize < sizeof(u_int32_t) || !indata) {
			error = -EINVAL;
			break;
		}
             if (*(int *)indata) {
                 dfs->ath_dfs_nol_timeout= *(int *)indata;
             } else {
                 dfs->ath_dfs_nol_timeout= DFS_NOL_TIMEOUT_S;
             }
		DFS_PRINTK("%s nol timeout = %d sec \n",
		    __func__,
		    dfs->ath_dfs_nol_timeout);
                break;
#ifndef ATH_DFS_RADAR_DETECTION_ONLY
    case DFS_MUTE_TIME:
        if (insize < sizeof(u_int32_t) || !indata) {
            error = -EINVAL;
            break;
        }
        data = (u_int32_t *) indata;
        dfs->ath_dfstesttime = *data;
        dfs->ath_dfstesttime *= (1000); //convert sec into ms
        break;
	case DFS_GET_USENOL:
		if (!outdata || !outsize || *outsize < sizeof(u_int32_t)) {
			error = -EINVAL;
			break;
		}
		*outsize = sizeof(u_int32_t);
		*((u_int32_t *)outdata) = dfs->dfs_rinfo.rn_use_nol;
                 printk("%s:#Phyerr=%d, #false detect=%d, #queued=%d\n", __func__,dfs->dfs_phyerr_count, dfs->dfs_phyerr_reject_count, dfs->dfs_phyerr_queued_count);
                 printk("%s:dfs_phyerr_freq_min=%d, dfs_phyerr_freq_max=%d\n", __func__,dfs->dfs_phyerr_freq_min, dfs->dfs_phyerr_freq_max);
                 printk("%s:Total radar events detected=%d, entries in the radar queue follows:\n",  __func__,dfs->dfs_event_log_count);
                 for (i = 0; (i < DFS_EVENT_LOG_SIZE) && (i < dfs->dfs_event_log_count); i++) {
                         //DFS_DPRINTK(sc, ATH_DEBUG_DFS,"ts=%llu diff_ts=%u rssi=%u dur=%u\n", dfs->radar_log[i].ts, dfs->radar_log[i].diff_ts, dfs->radar_log[i].rssi, dfs->radar_log[i].dur);
                         printk("ts=%llu diff_ts=%u rssi=%u dur=%u\n", dfs->radar_log[i].ts, dfs->radar_log[i].diff_ts, dfs->radar_log[i].rssi, dfs->radar_log[i].dur);
                 }
                 dfs->dfs_event_log_count     = 0;
                 dfs->dfs_phyerr_count        = 0;
                 dfs->dfs_phyerr_reject_count = 0;
                 dfs->dfs_phyerr_queued_count = 0;
                dfs->dfs_phyerr_freq_min     = 0x7fffffff;
                dfs->dfs_phyerr_freq_max     = 0;
		break;
	case DFS_SET_USENOL:
		if (insize < sizeof(u_int32_t) || !indata) {
			error = -EINVAL;
			break;
		}
		dfs->dfs_rinfo.rn_use_nol = *(u_int32_t *)indata;
		/* iwpriv markdfs in linux can do the same thing... */
		break;
	case DFS_GET_NOL:
		if (!outdata || !outsize || *outsize < sizeof(struct dfsreq_nolinfo)) {
			error = -EINVAL;
			break;
		}
		*outsize = sizeof(struct dfsreq_nolinfo);
		nol = (struct dfsreq_nolinfo *)outdata;
		dfs_get_nol(dfs, (struct dfsreq_nolelem *)nol->dfs_nol, &nol->ic_nchans);
             dfs_print_nol(dfs);
		break;
	case DFS_SET_NOL:
		if (insize < sizeof(struct dfsreq_nolinfo) || !indata) {
                        error = -EINVAL;
                        break;
                }
                nol = (struct dfsreq_nolinfo *) indata;
		dfs_set_nol(dfs, (struct dfsreq_nolelem *)nol->dfs_nol, nol->ic_nchans);
		break;

    case DFS_SHOW_NOL:
        dfs_print_nol(dfs);
        break;
#if ATH_SUPPORT_DFS && ATH_SUPPORT_STA_DFS
    case DFS_SHOW_NOLHISTORY:
        dfs_print_nolhistory(ic,dfs);
        break;
#endif
    case DFS_BANGRADAR:
 #if 0 //MERGE_TBD       
        if(sc->sc_nostabeacons)
        {
            printk("No radar detection Enabled \n");
            break;
        }
#endif        
        dfs->dfs_bangradar = 1;     
        dfs->ath_radar_tasksched = 1;
        OS_SET_TIMER(&dfs->ath_dfs_task_timer, 0);
        break;
#endif /* ATH_DFS_RADAR_DETECTION_ONLY */
	default:
		error = -EINVAL;
	}
bad:
	return error;
}
コード例 #7
0
ファイル: dfs.c プロジェクト: edwacode/qca-hostap
int
dfs_attach(struct ieee80211com *ic)
{
    int i, n;
    struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs;
    struct ath_dfs_radar_tab_info radar_info;
#define	N(a)	(sizeof(a)/sizeof(a[0]))

    if (dfs != NULL) {
        DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
          "%s: ic_dfs was not NULL\n",
          __func__);
        return 1;
    }
    if (ic->ic_dfs_state.ignore_dfs) {
        DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
          "%s: ignoring dfs\n",
          __func__);
        return 0;
    }
    dfs = (struct ath_dfs *)OS_MALLOC(ic->ic_osdev, sizeof(struct ath_dfs), GFP_ATOMIC);
    if (dfs == NULL) {
        DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
          "%s: ath_dfs allocation failed\n", __func__);
        return 1;
    }
    OS_MEMZERO(dfs, sizeof (struct ath_dfs));
    ic->ic_dfs = (void *)dfs;
    dfs->ic = ic;
    ic->ic_dfs_debug = dfs_get_debug_info;
#ifndef ATH_DFS_RADAR_DETECTION_ONLY
    dfs->dfs_nol = NULL;
#endif

    /*
     * Zero out radar_info.  It's possible that the attach function won't
     * fetch an initial regulatory configuration; you really do want to
     * ensure that the contents indicates there aren't any filters.
     */
    OS_MEMZERO(&radar_info, sizeof(radar_info));
    ic->ic_dfs_attach(ic, &dfs->dfs_caps, &radar_info);
    dfs_clear_stats(ic);
    dfs->dfs_event_log_on = 0;
    OS_INIT_TIMER(ic->ic_osdev, &(dfs->ath_dfs_task_timer), dfs_task, (void *) (ic));
#ifndef ATH_DFS_RADAR_DETECTION_ONLY
    OS_INIT_TIMER(ic->ic_osdev, &(dfs->ath_dfstesttimer), dfs_testtimer_task,
        (void *) ic);
    dfs->ath_dfs_cac_time = ATH_DFS_WAIT_MS;
    dfs->ath_dfstesttime = ATH_DFS_TEST_RETURN_PERIOD_MS;
#endif
    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(ic->ic_osdev,
                   sizeof(struct dfs_event)*DFS_MAX_EVENTS,
                   GFP_ATOMIC);
    if (dfs->events == NULL) {
        OS_FREE(dfs);
        ic->ic_dfs = NULL;
        DFS_PRINTK("%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(ic->ic_osdev, sizeof(struct dfs_pulseline), GFP_ATOMIC);
    if (dfs->pulses == NULL) {
            OS_FREE(dfs->events);   
            dfs->events = NULL;
            OS_FREE(dfs);
            ic->ic_dfs = NULL;
            DFS_PRINTK("%s: pulse buffer allocation failed\n", __func__);
            return 1;
    }

    dfs->pulses->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK;

            /* Allocate memory for radar filters */
    for (n=0; n<DFS_MAX_RADAR_TYPES; n++) {
    	dfs->dfs_radarf[n] = (struct dfs_filtertype *)OS_MALLOC(ic->ic_osdev, sizeof(struct dfs_filtertype),GFP_ATOMIC);
    	if (dfs->dfs_radarf[n] == NULL) {
    		DFS_PRINTK("%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(ic->ic_osdev, 256*sizeof(int8_t *), GFP_ATOMIC);
    if (dfs->dfs_radartable == NULL) {
    	DFS_PRINTK("%s: cannot allocate memory for radar table\n",
    		__func__);
    	goto bad1;
    }
    for (n=0; n<256; n++) {
    	dfs->dfs_radartable[n] = OS_MALLOC(ic->ic_osdev, DFS_MAX_RADAR_OVERLAP*sizeof(int8_t),
    					 GFP_ATOMIC);
    	if (dfs->dfs_radartable[n] == NULL) {
    		DFS_PRINTK("%s: cannot allocate memory for radar table entry\n",
    			__func__);
    		goto bad2;
    	}
    }

    if (usenol == 0)
        DFS_PRINTK("%s: NOL disabled\n", __func__);
    else if (usenol == 2)
        DFS_PRINTK("%s: NOL disabled; no CSA\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 = ic->ic_get_TSF64(ic);
    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() fails, we can abort here and
     * reconfigure when the first valid channel + radar config
     * is available.
     */
    if ( dfs_init_radar_filters( ic,  &radar_info) ) {
        DFS_PRINTK(" %s: Radar Filter Intialization Failed \n", 
                    __func__);
            return 1;
    }

    dfs->ath_dfs_false_rssi_thres = RSSI_POSSIBLY_FALSE;
    dfs->ath_dfs_peak_mag = SEARCH_FFT_REPORT_PEAK_MAG_THRSH;
    dfs->dfs_phyerr_freq_min     = 0x7fffffff;
    dfs->dfs_phyerr_freq_max     = 0;
    dfs->dfs_phyerr_queued_count = 0;
    dfs->dfs_phyerr_w53_counter  = 0;
    dfs->dfs_pri_multiplier      = 2;

    dfs->ath_dfs_nol_timeout = DFS_NOL_TIMEOUT_S;

    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 (ic->ic_dfs) {
        OS_FREE(ic->ic_dfs);
        ic->ic_dfs = NULL;
    }
    return 1;
#undef N
}
コード例 #8
0
ファイル: dfs_nol.c プロジェクト: KHATEEBNSIT/AP
/*
 * Notify the driver/umac that it should update the channel radar/NOL
 * flags based on the current NOL list.
 */
void
dfs_nol_update(struct ath_dfs *dfs)
{
    struct ieee80211com *ic = dfs->ic;
    struct dfs_nol_chan_entry *dfs_nol;
    struct dfs_nolelem *nol;
    int nlen;

    /*
     * Allocate enough entries to store the NOL.
     *
     * At least on Linux (don't ask why), if you allocate a 0 entry
     * array, the returned pointer is 0x10.  Make sure you're
     * aware of this when you start debugging.
     */
    dfs_nol = (struct dfs_nol_chan_entry *)OS_MALLOC(dfs->ic->ic_osdev,
      sizeof(struct dfs_nol_chan_entry) * dfs->dfs_nol_count,
      GFP_ATOMIC);

    if (dfs_nol == NULL) {
        /*
         * XXX TODO: if this fails, just schedule a task to retry
         * updating the NOL at a later stage.  That way the NOL
         * update _DOES_ happen - hopefully the failure was just
         * temporary.
         */
        DFS_PRINTK("%s: failed to allocate NOL update memory!\n",
            __func__);
        return;
    }


    /* populate the nol array */
    nlen = 0;

    nol = dfs->dfs_nol;
    while (nol != NULL && nlen < dfs->dfs_nol_count) {
        dfs_nol[nlen].nol_chfreq = nol->nol_freq;
        dfs_nol[nlen].nol_chwidth = nol->nol_chwidth;
        dfs_nol[nlen].nol_start_ticks = nol->nol_start_ticks;
        dfs_nol[nlen].nol_timeout_ms = nol->nol_timeout_ms;
        nlen++;
        nol = nol->nol_next;
    }

    /* Be suitably paranoid for now */
    if (nlen != dfs->dfs_nol_count)
        DFS_PRINTK("%s: nlen (%d) != dfs->dfs_nol_count (%d)!\n",
            __func__, nlen, dfs->dfs_nol_count);

    /*
     * Call the driver layer to have it recalculate the NOL flags for
     * each driver/umac channel.
     *
     * If the list is empty, pass NULL instead of dfs_nol.
     *
     * The operating system may have some special representation for
     * "malloc a 0 byte memory region" - for example,
     * Linux 2.6.38-13 (ubuntu) returns 0x10 rather than a valid
     * allocation (and is likely not NULL so the pointer doesn't
     * match NULL checks in any later code.
     */
    ic->ic_dfs_clist_update(ic, DFS_NOL_CLIST_CMD_UPDATE,
      (nlen > 0) ? dfs_nol : NULL, nlen);

    /*
     * .. and we're done.
     */
    OS_FREE(dfs_nol);
}
コード例 #9
0
ファイル: dfs.c プロジェクト: gicho/qcacld-2.0
int
dfs_control(struct ieee80211com *ic, u_int id,
                void *indata, u_int32_t insize,
                void *outdata, u_int32_t *outsize)
{
   int error = 0;
   struct ath_dfs_phyerr_param peout;
   struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs;
   struct dfs_ioctl_params *dfsparams;
    u_int32_t val=0;
#ifndef ATH_DFS_RADAR_DETECTION_ONLY
    struct dfsreq_nolinfo *nol;
    u_int32_t *data = NULL;
#endif /* ATH_DFS_RADAR_DETECTION_ONLY */
    int i;

   if (dfs == NULL) {
      error = -EINVAL;
                DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s DFS is null\n", __func__);
      goto bad;
   }


   switch (id) {
   case DFS_SET_THRESH:
      if (insize < sizeof(struct dfs_ioctl_params) || !indata) {
         DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
             "%s: insize=%d, expected=%zu bytes, indata=%p\n",
             __func__, insize, sizeof(struct dfs_ioctl_params),
             indata);
         error = -EINVAL;
         break;
      }
      dfsparams = (struct dfs_ioctl_params *) indata;
      if (!dfs_set_thresholds(ic, DFS_PARAM_FIRPWR, dfsparams->dfs_firpwr))
         error = -EINVAL;
      if (!dfs_set_thresholds(ic, DFS_PARAM_RRSSI, dfsparams->dfs_rrssi))
         error = -EINVAL;
      if (!dfs_set_thresholds(ic, DFS_PARAM_HEIGHT, dfsparams->dfs_height))
         error = -EINVAL;
      if (!dfs_set_thresholds(ic, DFS_PARAM_PRSSI, dfsparams->dfs_prssi))
         error = -EINVAL;
      if (!dfs_set_thresholds(ic, DFS_PARAM_INBAND, dfsparams->dfs_inband))
         error = -EINVAL;
      /* 5413 speicfic */
      if (!dfs_set_thresholds(ic, DFS_PARAM_RELPWR, dfsparams->dfs_relpwr))
         error = -EINVAL;
      if (!dfs_set_thresholds(ic, DFS_PARAM_RELSTEP, dfsparams->dfs_relstep))
         error = -EINVAL;
      if (!dfs_set_thresholds(ic, DFS_PARAM_MAXLEN, dfsparams->dfs_maxlen))
         error = -EINVAL;
      break;
   case DFS_GET_THRESH:
      if (!outdata || !outsize || *outsize <sizeof(struct dfs_ioctl_params)) {
         error = -EINVAL;
         break;
      }
      *outsize = sizeof(struct dfs_ioctl_params);
      dfsparams = (struct dfs_ioctl_params *) outdata;

      /*
       * Fetch the DFS thresholds using the internal representation.
       */
      (void) dfs_get_thresholds(ic, &peout);

      /*
       * Convert them to the dfs IOCTL representation.
       */
      ath_dfs_dfsparam_to_ioctlparam(&peout, dfsparams);
                break;
   case DFS_RADARDETECTS:
      if (!outdata || !outsize || *outsize < sizeof(u_int32_t)) {
         error = -EINVAL;
         break;
      }
      *outsize = sizeof (u_int32_t);
      *((u_int32_t *)outdata) = dfs->ath_dfs_stats.num_radar_detects;
      break;
        case DFS_DISABLE_DETECT:
                dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN;
                dfs->ic->ic_dfs_state.ignore_dfs = 1;
                DFS_PRINTK("%s enable detects, ignore_dfs %d\n",
                    __func__,
          dfs->ic->ic_dfs_state.ignore_dfs);
                break;
        case DFS_ENABLE_DETECT:
      dfs->dfs_proc_phyerr |= DFS_RADAR_EN;
                dfs->ic->ic_dfs_state.ignore_dfs = 0;
                DFS_PRINTK("%s enable detects, ignore_dfs %d\n",
                    __func__,
          dfs->ic->ic_dfs_state.ignore_dfs);
                break;
        case DFS_DISABLE_FFT:
                //UMACDFS: TODO: val = ath_hal_dfs_config_fft(sc->sc_ah, false);
                DFS_PRINTK("%s TODO disable FFT val=0x%x \n", __func__, val);
                break;
        case DFS_ENABLE_FFT:
                //UMACDFS TODO: val = ath_hal_dfs_config_fft(sc->sc_ah, true);
                DFS_PRINTK("%s TODO enable FFT val=0x%x \n", __func__, val);
                break;
        case DFS_SET_DEBUG_LEVEL:
      if (insize < sizeof(u_int32_t) || !indata) {
         error = -EINVAL;
         break;
      }
      dfs->dfs_debug_mask= *(u_int32_t *)indata;
      DFS_PRINTK("%s debug level now = 0x%x \n",
          __func__,
          dfs->dfs_debug_mask);
                if (dfs->dfs_debug_mask & ATH_DEBUG_DFS3) {
                    /* Enable debug Radar Event */
                    dfs->dfs_event_log_on = 1;
                } else {
                    dfs->dfs_event_log_on = 0;
                }
                break;
        case DFS_SET_FALSE_RSSI_THRES:
      if (insize < sizeof(u_int32_t) || !indata) {
         error = -EINVAL;
         break;
      }
      dfs->ath_dfs_false_rssi_thres= *(u_int32_t *)indata;
      DFS_PRINTK("%s false RSSI threshold now = 0x%x \n",
          __func__,
          dfs->ath_dfs_false_rssi_thres);
                break;
        case DFS_SET_PEAK_MAG:
      if (insize < sizeof(u_int32_t) || !indata) {
         error = -EINVAL;
         break;
      }
      dfs->ath_dfs_peak_mag= *(u_int32_t *)indata;
      DFS_PRINTK("%s peak_mag now = 0x%x \n",
          __func__,
          dfs->ath_dfs_peak_mag);
                break;
        case DFS_IGNORE_CAC:
      if (insize < sizeof(u_int32_t) || !indata) {
         error = -EINVAL;
         break;
      }
             if (*(u_int32_t *)indata) {
                 dfs->ic->ic_dfs_state.ignore_cac= 1;
             } else {
                 dfs->ic->ic_dfs_state.ignore_cac= 0;
             }
      DFS_PRINTK("%s ignore cac = 0x%x \n",
          __func__,
          dfs->ic->ic_dfs_state.ignore_cac);
                break;
        case DFS_SET_NOL_TIMEOUT:
      if (insize < sizeof(u_int32_t) || !indata) {
         error = -EINVAL;
         break;
      }
             if (*(int *)indata) {
                 dfs->ath_dfs_nol_timeout= *(int *)indata;
             } else {
                 dfs->ath_dfs_nol_timeout= DFS_NOL_TIMEOUT_S;
             }
      DFS_PRINTK("%s nol timeout = %d sec \n",
          __func__,
          dfs->ath_dfs_nol_timeout);
                break;
#ifndef ATH_DFS_RADAR_DETECTION_ONLY
    case DFS_MUTE_TIME:
        if (insize < sizeof(u_int32_t) || !indata) {
            error = -EINVAL;
            break;
        }
        data = (u_int32_t *) indata;
        dfs->ath_dfstesttime = *data;
        dfs->ath_dfstesttime *= (1000); //convert sec into ms
        break;
   case DFS_GET_USENOL:
      if (!outdata || !outsize || *outsize < sizeof(u_int32_t)) {
         error = -EINVAL;
         break;
      }
      *outsize = sizeof(u_int32_t);
      *((u_int32_t *)outdata) = dfs->dfs_rinfo.rn_use_nol;



                 for (i = 0; (i < DFS_EVENT_LOG_SIZE) && (i < dfs->dfs_event_log_count); i++) {
                         //DFS_DPRINTK(sc, ATH_DEBUG_DFS,"ts=%llu diff_ts=%u rssi=%u dur=%u\n", dfs->radar_log[i].ts, dfs->radar_log[i].diff_ts, dfs->radar_log[i].rssi, dfs->radar_log[i].dur);

                 }
                 dfs->dfs_event_log_count     = 0;
                 dfs->dfs_phyerr_count        = 0;
                 dfs->dfs_phyerr_reject_count = 0;
                 dfs->dfs_phyerr_queued_count = 0;
                dfs->dfs_phyerr_freq_min     = 0x7fffffff;
                dfs->dfs_phyerr_freq_max     = 0;
      break;
   case DFS_SET_USENOL:
      if (insize < sizeof(u_int32_t) || !indata) {
         error = -EINVAL;
         break;
      }
      dfs->dfs_rinfo.rn_use_nol = *(u_int32_t *)indata;
      /* iwpriv markdfs in linux can do the same thing... */
      break;
   case DFS_GET_NOL:
      if (!outdata || !outsize || *outsize < sizeof(struct dfsreq_nolinfo)) {
         error = -EINVAL;
         break;
      }
      *outsize = sizeof(struct dfsreq_nolinfo);
      nol = (struct dfsreq_nolinfo *)outdata;
      dfs_get_nol(dfs, (struct dfsreq_nolelem *)nol->dfs_nol, &nol->ic_nchans);
             dfs_print_nol(dfs);
      break;
   case DFS_SET_NOL:
      if (insize < sizeof(struct dfsreq_nolinfo) || !indata) {
                        error = -EINVAL;
                        break;
                }
                nol = (struct dfsreq_nolinfo *) indata;
      dfs_set_nol(dfs, (struct dfsreq_nolelem *)nol->dfs_nol, nol->ic_nchans);
      break;

    case DFS_SHOW_NOL:
        dfs_print_nol(dfs);
        break;
    case DFS_BANGRADAR:
 #if 0 //MERGE_TBD
        if(sc->sc_nostabeacons)
        {
            printk("No radar detection Enabled \n");
            break;
        }
#endif
        dfs->dfs_bangradar = 1;
        dfs->ath_radar_tasksched = 1;
        OS_SET_TIMER(&dfs->ath_dfs_task_timer, 0);
        break;
#endif /* ATH_DFS_RADAR_DETECTION_ONLY */
   default:
      error = -EINVAL;
   }
bad:
   return error;
}