/* * 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); }
static void radar_fft_search_report_parse(struct ath_dfs *dfs, const char *buf, size_t len, struct rx_search_fft_report *rsfr) { 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)); rsfr->total_gain_db = MS(rs[SEARCH_FFT_REPORT_REG_1], SEARCH_FFT_REPORT_TOTAL_GAIN_DB); rsfr->base_pwr_db = MS(rs[SEARCH_FFT_REPORT_REG_1], SEARCH_FFT_REPORT_BASE_PWR_DB); rsfr->fft_chn_idx = MS(rs[SEARCH_FFT_REPORT_REG_1], SEARCH_FFT_REPORT_FFT_CHN_IDX); rsfr->peak_sidx = sign_extend_32(MS(rs[SEARCH_FFT_REPORT_REG_1], SEARCH_FFT_REPORT_PEAK_SIDX), 12); rsfr->relpwr_db = MS(rs[SEARCH_FFT_REPORT_REG_2], SEARCH_FFT_REPORT_RELPWR_DB); rsfr->avgpwr_db = MS(rs[SEARCH_FFT_REPORT_REG_2], SEARCH_FFT_REPORT_AVGPWR_DB); rsfr->peak_mag = MS(rs[SEARCH_FFT_REPORT_REG_2], SEARCH_FFT_REPORT_PEAK_MAG); rsfr->num_str_bins_ib = MS(rs[SEARCH_FFT_REPORT_REG_2], SEARCH_FFT_REPORT_NUM_STR_BINS_IB); 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: rsfr->total_gain_db = %d\n", __func__, rsfr->total_gain_db); DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: rsfr->base_pwr_db = %d\n", __func__, rsfr->base_pwr_db); DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: rsfr->fft_chn_idx = %d\n", __func__, rsfr->fft_chn_idx); DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: rsfr->peak_sidx = %d\n", __func__, rsfr->peak_sidx); DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: rsfr->relpwr_db = %d\n", __func__, rsfr->relpwr_db); DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: rsfr->avgpwr_db = %d\n", __func__, rsfr->avgpwr_db); DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: rsfr->peak_mag = %d\n", __func__, rsfr->peak_mag); DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,"%s: rsfr->num_str_bins_ib = %d\n", __func__, rsfr->num_str_bins_ib); }
/* * 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; } }