Пример #1
0
/*
 * 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);
}
Пример #2
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;
   }

}