drivers/net/wireless/ath/ath9k/dfs.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/ath/ath9k/dfs.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ath/ath9k/dfs.c
Extension
.c
Size
10325 bytes
Lines
362
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ath_radar_data {
	u8 pulse_bw_info;
	u8 rssi;
	u8 ext_rssi;
	u8 pulse_length_ext;
	u8 pulse_length_pri;
};

/**** begin: CHIRP ************************************************************/

/* min and max gradients for defined FCC chirping pulses, given by
 * - 20MHz chirp width over a pulse width of  50us
 * -  5MHz chirp width over a pulse width of 100us
 */
static const int BIN_DELTA_MIN		= 1;
static const int BIN_DELTA_MAX		= 10;

/* we need at least 3 deltas / 4 samples for a reliable chirp detection */
#define NUM_DIFFS 3
#define FFT_NUM_SAMPLES		(NUM_DIFFS + 1)

/* Threshold for difference of delta peaks */
static const int MAX_DIFF		= 2;

/* width range to be checked for chirping */
static const int MIN_CHIRP_PULSE_WIDTH	= 20;
static const int MAX_CHIRP_PULSE_WIDTH	= 110;

struct ath9k_dfs_fft_20 {
	u8 bin[28];
	u8 lower_bins[3];
} __packed;
struct ath9k_dfs_fft_40 {
	u8 bin[64];
	u8 lower_bins[3];
	u8 upper_bins[3];
} __packed;

static inline int fft_max_index(u8 *bins)
{
	return (bins[2] & 0xfc) >> 2;
}
static inline int fft_max_magnitude(u8 *bins)
{
	return (bins[0] & 0xc0) >> 6 | bins[1] << 2 | (bins[2] & 0x03) << 10;
}
static inline u8 fft_bitmap_weight(u8 *bins)
{
	return bins[0] & 0x3f;
}

static int ath9k_get_max_index_ht40(struct ath9k_dfs_fft_40 *fft,
				    bool is_ctl, bool is_ext)
{
	const int DFS_UPPER_BIN_OFFSET = 64;
	/* if detected radar on both channels, select the significant one */
	if (is_ctl && is_ext) {
		/* first check whether channels have 'strong' bins */
		is_ctl = fft_bitmap_weight(fft->lower_bins) != 0;
		is_ext = fft_bitmap_weight(fft->upper_bins) != 0;

		/* if still unclear, take higher magnitude */
		if (is_ctl && is_ext) {
			int mag_lower = fft_max_magnitude(fft->lower_bins);
			int mag_upper = fft_max_magnitude(fft->upper_bins);
			if (mag_upper > mag_lower)
				is_ctl = false;
			else
				is_ext = false;
		}
	}
	if (is_ctl)
		return fft_max_index(fft->lower_bins);
	return fft_max_index(fft->upper_bins) + DFS_UPPER_BIN_OFFSET;
}
static bool ath9k_check_chirping(struct ath_softc *sc, u8 *data,
				 int datalen, bool is_ctl, bool is_ext)
{
	int i;
	int max_bin[FFT_NUM_SAMPLES];
	struct ath_hw *ah = sc->sc_ah;
	struct ath_common *common = ath9k_hw_common(ah);
	int prev_delta;

	if (IS_CHAN_HT40(ah->curchan)) {
		struct ath9k_dfs_fft_40 *fft = (struct ath9k_dfs_fft_40 *) data;
		int num_fft_packets = datalen / sizeof(*fft);
		if (num_fft_packets == 0)
			return false;

Annotation

Implementation Notes