Пример #1
0
/*
 * Parse the radar summary frame.
 *
 * The frame contents _minus_ the TLV are passed in.
 */
static void
radar_summary_parse(struct ath_dfs *dfs, const char *buf, size_t len,
    struct rx_radar_status *rsu)
{
	uint32_t rs[2];

	/* Drop out if we have < 2 DWORDs available */
	if (len < sizeof(rs)) {
		DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR |
		    ATH_DEBUG_DFS_PHYERR_SUM,
		    "%s: len (%d) < expected (%d)!\n",
		    __func__,
		    len,
		    sizeof(rs));
	}

	/*
	 * Since the TLVs may be unaligned for some reason
	 * we take a private copy into aligned memory.
	 * This enables us to use the HAL-like accessor macros
	 * into the DWORDs to access sub-DWORD fields.
	 */
	OS_MEMCPY(rs, buf, sizeof(rs));

        DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: two 32 bit values are: %08x %08x\n", __func__, rs[0], rs[1]); 
//	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s (p=%p):\n", __func__, buf);

	/* Populate the fields from the summary report */
	rsu->tsf_offset =
	    MS(rs[RADAR_REPORT_PULSE_REG_2], RADAR_REPORT_PULSE_TSF_OFFSET);
	rsu->pulse_duration =
	    MS(rs[RADAR_REPORT_PULSE_REG_2], RADAR_REPORT_PULSE_DUR);
	rsu->is_chirp =
	    MS(rs[RADAR_REPORT_PULSE_REG_1], RADAR_REPORT_PULSE_IS_CHIRP);
	rsu->sidx = sign_extend_32(
	        MS(rs[RADAR_REPORT_PULSE_REG_1], RADAR_REPORT_PULSE_SIDX),
	          10);
	rsu->freq_offset =
	        calc_freq_offset(rsu->sidx, PERE_IS_OVERSAMPLING(dfs));

	/* These are only relevant if the pulse is a chirp */
	rsu->delta_peak = sign_extend_32(
	    MS(rs[RADAR_REPORT_PULSE_REG_1], RADAR_REPORT_PULSE_DELTA_PEAK),
	        6);
	rsu->delta_diff =
	    MS(rs[RADAR_REPORT_PULSE_REG_1], RADAR_REPORT_PULSE_DELTA_DIFF);
}
Пример #2
0
static void
radar_summary_print(struct ath_dfs *dfs, struct rx_radar_status *rsu)
{

	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
	    "    pulsedur=%d\n", rsu->pulse_duration);
	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
	    "    rssi=%d\n", rsu->rssi);
	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
	    "    ischirp=%d\n", rsu->is_chirp);
	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
	    "    sidx=%d\n", rsu->sidx);
	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
	    "    raw tsf=%d\n", rsu->raw_tsf);
	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
	    "    tsf_offset=%d\n", rsu->tsf_offset);
	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
	    "    cooked tsf=%d\n", rsu->raw_tsf - rsu->tsf_offset);
	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
	    "    frequency offset=%d.%d MHz (oversampling=%d)\n",
	    (int) (rsu->freq_offset / 1000),
	    (int) abs(rsu->freq_offset % 1000),
	    PERE_IS_OVERSAMPLING(dfs));
}
Пример #3
0
/*
 * Calculate the centre frequency and low/high range for a radar pulse event.
 *
 * XXX TODO: Handle half/quarter rates correctly!
 * XXX TODO: handle VHT160 correctly!
 * XXX TODO: handle VHT80+80 correctly!
 */
static int
tlv_calc_event_freq_pulse(struct ath_dfs *dfs, struct rx_radar_status *rs,
    uint32_t *freq_centre, uint32_t *freq_lo, uint32_t *freq_hi)
{
	int chan_width;
	int chan_centre;

	/* Fetch the channel centre frequency in MHz */
	chan_centre = tlv_calc_freq_info(dfs, rs);

	/* Convert to KHz */
	chan_centre *= 1000;

	/*
	 * XXX hard-code event width to be 2 * bin size for now;
	 * XXX this needs to take into account the core clock speed
	 * XXX for half/quarter rate mode.
	 */
	if (PERE_IS_OVERSAMPLING(dfs))
		chan_width = (44000 * 2 / 128);
	else
		chan_width = (40000 * 2 / 128);

	/* XXX adjust chan_width for half/quarter rate! */

	/*
	 * Now we can do the math to figure out the correct channel range.
	 */
	(*freq_centre) = (uint32_t) (chan_centre + rs->freq_offset);
	(*freq_lo) = (uint32_t) ((chan_centre + rs->freq_offset)
	    - chan_width);
	(*freq_hi) = (uint32_t) ((chan_centre + rs->freq_offset)
	    + chan_width);

	return (1);
}
Пример #4
0
/*
 * The chirp bandwidth in KHz is defined as:
 *
 * totalBW(KHz) = delta_peak(mean)
 *    * [ (bin resolution in KHz) / (radar_fft_long_period in uS) ]
 *    * pulse_duration (us)
 *
 * The bin resolution depends upon oversampling.
 *
 * For now, we treat the radar_fft_long_period as a hard-coded 8uS.
 */
static int
tlv_calc_event_freq_chirp(struct ath_dfs *dfs, struct rx_radar_status *rs,
    uint32_t *freq_centre, uint32_t *freq_lo, uint32_t *freq_hi)
{
	int32_t bin_resolution;		/* KHz * 100 */
	int32_t radar_fft_long_period = 8;	/* microseconds */
	int32_t delta_peak;
	int32_t pulse_duration;
	int32_t total_bw;
	int32_t chan_centre;
	int32_t freq_1, freq_2;

	/*
	 * KHz isn't enough resolution here!
	 * So treat it as deci-hertz (10Hz) and convert back to KHz
	 * later.
	 */
	if (PERE_IS_OVERSAMPLING(dfs))
		bin_resolution = (44000 * 100) / 128;
	else
		bin_resolution = (40000 * 100) / 128;

	delta_peak = rs->delta_peak;
	pulse_duration = rs->pulse_duration;

	total_bw = delta_peak * (bin_resolution / radar_fft_long_period) *
	    pulse_duration;

	DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR | ATH_DEBUG_DFS_PHYERR_SUM,
	    "%s: delta_peak=%d, pulse_duration=%d, bin_resolution=%d.%dKHz, "
	        "radar_fft_long_period=%d, total_bw=%d.%dKHz\n",
	    __func__,
	    delta_peak,
	    pulse_duration,
	    bin_resolution / 1000,
	    bin_resolution % 1000,
	    radar_fft_long_period,
	    total_bw / 100,
	    abs(total_bw % 100));

	    total_bw /= 100;	/* back to KHz */

	/* Grab the channel centre frequency in MHz */
	chan_centre = tlv_calc_freq_info(dfs, rs);

	/* Early abort! */
	if (chan_centre == 0) {
		(*freq_centre) = 0;
		return (0);
	}

	/* Convert to KHz */
	chan_centre *= 1000;

	/*
	 * sidx is the starting frequency; total_bw is a signed value and
	 * for negative chirps (ie, moving down in frequency rather than up)
	 * the end frequency may be less than the start frequency.
	 */
	if (total_bw > 0) {
		freq_1 = chan_centre + rs->freq_offset;
		freq_2 = chan_centre + rs->freq_offset + total_bw;
	} else {
		freq_1 = chan_centre + rs->freq_offset + total_bw;
		freq_2 = chan_centre + rs->freq_offset;
	}

	(*freq_lo) = (uint32_t)(freq_1);
	(*freq_hi) = (uint32_t)(freq_2);
	(*freq_centre) = (uint32_t) (freq_1 + (abs(total_bw) / 2));

	return (1);
}
Пример #5
0
/*
 * Parse the radar summary frame.
 *
 * The frame contents _minus_ the TLV are passed in.
 */
static void
radar_summary_parse(struct ath_dfs *dfs, const char *buf, size_t len,
    struct rx_radar_status *rsu)
{
   uint32_t rs[2];
   int freq_centre, freq;

   /* Drop out if we have < 2 DWORDs available */
   if (len < sizeof(rs)) {
      DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR |
          ATH_DEBUG_DFS_PHYERR_SUM,
          "%s: len (%zu) < expected (%zu)!",
          __func__,
          len,
          sizeof(rs));
   }

   /*
    * Since the TLVs may be unaligned for some reason
    * we take a private copy into aligned memory.
    * This enables us to use the HAL-like accessor macros
    * into the DWORDs to access sub-DWORD fields.
    */
   OS_MEMCPY(rs, buf, sizeof(rs));

        DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: two 32 bit values are: %08x %08x", __func__, rs[0], rs[1]);
// DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s (p=%p):", __func__, buf);

   /* Populate the fields from the summary report */
   rsu->tsf_offset =
       MS(rs[RADAR_REPORT_PULSE_REG_2], RADAR_REPORT_PULSE_TSF_OFFSET);
   rsu->pulse_duration =
       MS(rs[RADAR_REPORT_PULSE_REG_2], RADAR_REPORT_PULSE_DUR);
   rsu->is_chirp =
       MS(rs[RADAR_REPORT_PULSE_REG_1], RADAR_REPORT_PULSE_IS_CHIRP);
   rsu->sidx = sign_extend_32(
           MS(rs[RADAR_REPORT_PULSE_REG_1], RADAR_REPORT_PULSE_SIDX),
             10);
   rsu->freq_offset =
           calc_freq_offset(rsu->sidx, PERE_IS_OVERSAMPLING(dfs));

   /* These are only relevant if the pulse is a chirp */
   rsu->delta_peak = sign_extend_32(
       MS(rs[RADAR_REPORT_PULSE_REG_1], RADAR_REPORT_PULSE_DELTA_PEAK),
           6);
   rsu->delta_diff =
       MS(rs[RADAR_REPORT_PULSE_REG_1], RADAR_REPORT_PULSE_DELTA_DIFF);

   /* WAR for FCC Type 4*/
   /*
    * HW is giving longer pulse duration (in case of VHT80, with traffic)
    * which fails to detect FCC type4 radar pulses. Added a work around to
    * fix the pulse duration and duration delta.
    *
    * IF VHT80
    *   && (primary_channel==30MHz || primary_channel== -30MHz)
    *   && -4 <= pulse_index <= 4
    *   && !chirp
    *   && pulse duration > 20 us
    * THEN
    *   Set pulse duration to 20 us
    */

   freq = ieee80211_chan2freq(dfs->ic, dfs->ic->ic_curchan);
   freq_centre = dfs->ic->ic_curchan->ic_vhtop_ch_freq_seg1;

   if ((IEEE80211_IS_CHAN_11AC_VHT80(dfs->ic->ic_curchan) &&
            (abs(freq - freq_centre) == 30) &&
            !rsu->is_chirp &&
            abs(rsu->sidx) <= 4 &&
            rsu->pulse_duration > 20)){
      rsu->pulse_duration = 20;
   }

}