Esempio n. 1
0
/*
 * Return the centre frequency for the current operating channel and
 * event.
 *
 * This is for post-Owl 11n chips which report pri/extension channel
 * events.
 */
static inline uint16_t
dfs_get_event_freqcentre(struct ath_dfs *dfs, int is_pri, int is_ext, int is_dc)
{
   struct ieee80211com *ic;
   int chan_offset = 0, chan_width;

   /* Handle edge cases during startup/transition, shouldn't happen! */
   if (dfs == NULL)
      return (0);
   if (dfs->ic == NULL || dfs->ic->ic_curchan == NULL)
      return (0);

   ic = dfs->ic;

   /*
    *
    * For wide channels, DC and ext frequencies need a bit of hand-holding
    * based on whether it's an upper or lower channel.
    */
   chan_width = dfs_get_event_freqwidth(dfs);

   if (IEEE80211_IS_CHAN_11N_HT40PLUS(ic->ic_curchan))
      chan_offset = chan_width;
   else if (IEEE80211_IS_CHAN_11N_HT40MINUS(ic->ic_curchan))
      chan_offset = -chan_width;
   else
      chan_offset = 0;

   /*
    * Check for DC events first - the sowl code may just set all
    * the bits together..
    */
   if (is_dc) {
      /*
       * XXX TODO: Should DC events be considered 40MHz wide here?
       */
      return (ieee80211_chan2freq(ic, ic->ic_curchan) +
          (chan_offset / 2));
   }

   /*
    * For non-wide channels, the centre frequency is just ic_freq.
    * The centre frequency for pri events is still ic_freq.
    */
   if (is_pri) {
      return (ieee80211_chan2freq(ic, ic->ic_curchan));
   }

   if (is_ext) {
      return (ieee80211_chan2freq(ic, ic->ic_curchan) + chan_width);
   }

   /* XXX shouldn't get here */
   return (ieee80211_chan2freq(ic, ic->ic_curchan));
}
Esempio n. 2
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);
}