|
@@ -65,8 +65,6 @@
|
|
|
#include "csr_api.h"
|
|
|
#include "ol_fw.h"
|
|
|
|
|
|
-#include "dfs.h"
|
|
|
-#include "radar_filters.h"
|
|
|
#include "wma_internal.h"
|
|
|
#include "wma_nan_datapath.h"
|
|
|
#include <cdp_txrx_handle.h>
|
|
@@ -1312,474 +1310,6 @@ QDF_STATUS wma_start_oem_data_req(tp_wma_handle wma_handle,
|
|
|
}
|
|
|
#endif /* FEATURE_OEM_DATA_SUPPORT */
|
|
|
|
|
|
-
|
|
|
-/**
|
|
|
- * wma_unified_dfs_radar_rx_event_handler() - dfs radar rx event handler
|
|
|
- * @handle: wma handle
|
|
|
- * @data: data buffer
|
|
|
- * @datalen: data length
|
|
|
- *
|
|
|
- * WMI handler for WMI_DFS_RADAR_EVENTID
|
|
|
- * This handler is registered for handling
|
|
|
- * filtered DFS Phyerror. This handler is
|
|
|
- * will be invoked only when DFS Phyerr
|
|
|
- * filtering offload is enabled.
|
|
|
- *
|
|
|
- * Return: 1 for Success and 0 for error
|
|
|
- */
|
|
|
-static int wma_unified_dfs_radar_rx_event_handler(void *handle,
|
|
|
- uint8_t *data,
|
|
|
- uint32_t datalen)
|
|
|
-{
|
|
|
- tp_wma_handle wma = (tp_wma_handle) handle;
|
|
|
- struct ieee80211com *ic;
|
|
|
- struct ath_dfs *dfs;
|
|
|
- struct dfs_event *event;
|
|
|
- struct dfs_ieee80211_channel *chan;
|
|
|
- int empty;
|
|
|
- int do_check_chirp = 0;
|
|
|
- int is_hw_chirp = 0;
|
|
|
- int is_sw_chirp = 0;
|
|
|
- int is_pri = 0;
|
|
|
- bool is_ch_dfs = false;
|
|
|
-
|
|
|
- WMI_DFS_RADAR_EVENTID_param_tlvs *param_tlvs;
|
|
|
- wmi_dfs_radar_event_fixed_param *radar_event;
|
|
|
-
|
|
|
- ic = wma->dfs_ic;
|
|
|
- if (NULL == ic) {
|
|
|
- WMA_LOGE("%s: dfs_ic is NULL ", __func__);
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- dfs = (struct ath_dfs *)ic->ic_dfs;
|
|
|
- param_tlvs = (WMI_DFS_RADAR_EVENTID_param_tlvs *) data;
|
|
|
-
|
|
|
- if (NULL == dfs) {
|
|
|
- WMA_LOGE("%s: dfs is NULL ", __func__);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- /*
|
|
|
- * This parameter holds the number
|
|
|
- * of phyerror interrupts to the host
|
|
|
- * after the phyerrors have passed through
|
|
|
- * false detect filters in the firmware.
|
|
|
- */
|
|
|
- dfs->dfs_phyerr_count++;
|
|
|
-
|
|
|
- if (!param_tlvs) {
|
|
|
- WMA_LOGE("%s: Received NULL data from FW", __func__);
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- radar_event = param_tlvs->fixed_param;
|
|
|
-
|
|
|
- qdf_spin_lock_bh(&ic->chan_lock);
|
|
|
- chan = ic->ic_curchan;
|
|
|
- if (ic->disable_phy_err_processing) {
|
|
|
- WMA_LOGD("%s: radar indication done,drop phyerror event",
|
|
|
- __func__);
|
|
|
- qdf_spin_unlock_bh(&ic->chan_lock);
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- if (IEEE80211_IS_CHAN_11AC_VHT160(chan)) {
|
|
|
- is_ch_dfs = true;
|
|
|
- } else if (IEEE80211_IS_CHAN_11AC_VHT80P80(chan)) {
|
|
|
- if (wlan_reg_get_channel_state(wma->pdev, chan->ic_ieee) ==
|
|
|
- CHANNEL_STATE_DFS ||
|
|
|
- wlan_reg_get_channel_state(wma->pdev, chan->ic_ieee_ext -
|
|
|
- WMA_80MHZ_START_CENTER_CH_DIFF) ==
|
|
|
- CHANNEL_STATE_DFS)
|
|
|
- is_ch_dfs = true;
|
|
|
- } else {
|
|
|
- if (wlan_reg_get_channel_state(wma->pdev, chan->ic_ieee) ==
|
|
|
- CHANNEL_STATE_DFS)
|
|
|
- is_ch_dfs = true;
|
|
|
- }
|
|
|
- if (!is_ch_dfs) {
|
|
|
- WMA_LOGE
|
|
|
- ("%s: Invalid DFS Phyerror event. Channel=%d is Non-DFS",
|
|
|
- __func__, chan->ic_ieee);
|
|
|
- qdf_spin_unlock_bh(&ic->chan_lock);
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- qdf_spin_unlock_bh(&ic->chan_lock);
|
|
|
- dfs->ath_dfs_stats.total_phy_errors++;
|
|
|
-
|
|
|
- if (dfs->dfs_caps.ath_chip_is_bb_tlv) {
|
|
|
- do_check_chirp = 1;
|
|
|
- is_pri = 1;
|
|
|
- is_hw_chirp = radar_event->pulse_is_chirp;
|
|
|
-
|
|
|
- if ((uint32_t) dfs->dfs_phyerr_freq_min >
|
|
|
- radar_event->pulse_center_freq) {
|
|
|
- dfs->dfs_phyerr_freq_min =
|
|
|
- (int)radar_event->pulse_center_freq;
|
|
|
- }
|
|
|
-
|
|
|
- if (dfs->dfs_phyerr_freq_max <
|
|
|
- (int)radar_event->pulse_center_freq) {
|
|
|
- dfs->dfs_phyerr_freq_max =
|
|
|
- (int)radar_event->pulse_center_freq;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Now, add the parsed, checked and filtered
|
|
|
- * radar phyerror event radar pulse event list.
|
|
|
- * This event will then be processed by
|
|
|
- * dfs_radar_processevent() to see if the pattern
|
|
|
- * of pulses in radar pulse list match any radar
|
|
|
- * singnature in the current regulatory domain.
|
|
|
- */
|
|
|
-
|
|
|
- ATH_DFSEVENTQ_LOCK(dfs);
|
|
|
- empty = STAILQ_EMPTY(&(dfs->dfs_eventq));
|
|
|
- ATH_DFSEVENTQ_UNLOCK(dfs);
|
|
|
- if (empty) {
|
|
|
- return 0;
|
|
|
- }
|
|
|
- /*
|
|
|
- * Add the event to the list, if there's space.
|
|
|
- */
|
|
|
- ATH_DFSEVENTQ_LOCK(dfs);
|
|
|
- event = STAILQ_FIRST(&(dfs->dfs_eventq));
|
|
|
- if (event == NULL) {
|
|
|
- ATH_DFSEVENTQ_UNLOCK(dfs);
|
|
|
- WMA_LOGE("%s: No more space left for queuing DFS Phyerror events",
|
|
|
- __func__);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- STAILQ_REMOVE_HEAD(&(dfs->dfs_eventq), re_list);
|
|
|
- ATH_DFSEVENTQ_UNLOCK(dfs);
|
|
|
- dfs->dfs_phyerr_queued_count++;
|
|
|
- dfs->dfs_phyerr_w53_counter++;
|
|
|
- event->re_dur = (uint8_t) radar_event->pulse_duration;
|
|
|
- event->re_rssi = radar_event->rssi;
|
|
|
- event->re_ts = radar_event->pulse_detect_ts & DFS_TSMASK;
|
|
|
- event->re_full_ts = (((uint64_t) radar_event->upload_fullts_high) << 32)
|
|
|
- | radar_event->upload_fullts_low;
|
|
|
-
|
|
|
- /*
|
|
|
- * Index of peak magnitude
|
|
|
- */
|
|
|
- event->sidx = radar_event->peak_sidx;
|
|
|
- event->re_flags = 0;
|
|
|
-
|
|
|
- /*
|
|
|
- * Handle chirp flags.
|
|
|
- */
|
|
|
- if (do_check_chirp) {
|
|
|
- event->re_flags |= DFS_EVENT_CHECKCHIRP;
|
|
|
- if (is_hw_chirp) {
|
|
|
- event->re_flags |= DFS_EVENT_HW_CHIRP;
|
|
|
- }
|
|
|
- if (is_sw_chirp) {
|
|
|
- event->re_flags |= DFS_EVENT_SW_CHIRP;
|
|
|
- }
|
|
|
- }
|
|
|
- /*
|
|
|
- * Correctly set which channel is being reported on
|
|
|
- */
|
|
|
- if (is_pri) {
|
|
|
- event->re_chanindex = (uint8_t) dfs->dfs_curchan_radindex;
|
|
|
- } else {
|
|
|
- if (dfs->dfs_extchan_radindex == -1) {
|
|
|
- WMA_LOGI("%s phyerr on ext channel", __func__);
|
|
|
- }
|
|
|
- event->re_chanindex = (uint8_t) dfs->dfs_extchan_radindex;
|
|
|
- WMA_LOGI("%s:New extension channel event is added to queue",
|
|
|
- __func__);
|
|
|
- }
|
|
|
-
|
|
|
- ATH_DFSQ_LOCK(dfs);
|
|
|
-
|
|
|
- STAILQ_INSERT_TAIL(&(dfs->dfs_radarq), event, re_list);
|
|
|
-
|
|
|
- empty = STAILQ_EMPTY(&dfs->dfs_radarq);
|
|
|
-
|
|
|
- ATH_DFSQ_UNLOCK(dfs);
|
|
|
-
|
|
|
- if (!empty && !dfs->ath_radar_tasksched) {
|
|
|
- dfs->ath_radar_tasksched = 1;
|
|
|
- OS_SET_TIMER(&dfs->ath_dfs_task_timer, 0);
|
|
|
- }
|
|
|
-
|
|
|
- return 1;
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * wma_unified_phyerr_rx_event_handler() - phyerr event handler
|
|
|
- * @handle: wma handle
|
|
|
- * @data: data buffer
|
|
|
- * @datalen: buffer length
|
|
|
- *
|
|
|
- * WMI Handler for WMI_PHYERR_EVENTID event from firmware.
|
|
|
- * This handler is currently handling only DFS phy errors.
|
|
|
- * This handler will be invoked only when the DFS phyerror
|
|
|
- * filtering offload is disabled.
|
|
|
- *
|
|
|
- * Return: 1:Success, 0:Failure
|
|
|
- */
|
|
|
-static int wma_unified_phyerr_rx_event_handler(void *handle,
|
|
|
- uint8_t *data, uint32_t datalen)
|
|
|
-{
|
|
|
- tp_wma_handle wma = (tp_wma_handle) handle;
|
|
|
- WMI_PHYERR_EVENTID_param_tlvs *param_tlvs;
|
|
|
- wmi_comb_phyerr_rx_hdr *pe_hdr;
|
|
|
- uint8_t *bufp;
|
|
|
- wmi_single_phyerr_rx_event *ev;
|
|
|
- struct ieee80211com *ic = wma->dfs_ic;
|
|
|
- qdf_size_t n;
|
|
|
- A_UINT64 tsf64 = 0;
|
|
|
- int phy_err_code = 0;
|
|
|
- A_UINT32 phy_err_mask = 0;
|
|
|
- int error = 0;
|
|
|
- tpAniSirGlobal mac_ctx =
|
|
|
- (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE);
|
|
|
- bool enable_log = false;
|
|
|
- int max_dfs_buf_length = 0;
|
|
|
-
|
|
|
- if (NULL == mac_ctx) {
|
|
|
- WMA_LOGE("%s: mac_ctx is NULL", __func__);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- enable_log = mac_ctx->sap.enable_dfs_phy_error_logs;
|
|
|
-
|
|
|
- param_tlvs = (WMI_PHYERR_EVENTID_param_tlvs *) data;
|
|
|
-
|
|
|
- if (!param_tlvs) {
|
|
|
- WMA_LOGE("%s: Received NULL data from FW", __func__);
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- pe_hdr = param_tlvs->hdr;
|
|
|
- if (pe_hdr == NULL) {
|
|
|
- WMA_LOGE("%s: Received Data PE Header is NULL", __func__);
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- /* Ensure it's at least the size of the header */
|
|
|
- if (datalen < sizeof(*pe_hdr)) {
|
|
|
- WMA_LOGE("%s: Expected minimum size %zu, received %d",
|
|
|
- __func__, sizeof(*pe_hdr), datalen);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- /*
|
|
|
- * The max buffer lenght is larger for DFS-3 than DFS-2.
|
|
|
- * So, accordingly use the correct max buffer size.
|
|
|
- */
|
|
|
- if (wma->hw_bd_id != WMI_HWBD_QCA6174)
|
|
|
- max_dfs_buf_length = DFS3_MAX_BUF_LENGTH;
|
|
|
- else
|
|
|
- max_dfs_buf_length = DFS_MAX_BUF_LENGTH;
|
|
|
-
|
|
|
- if (pe_hdr->buf_len > max_dfs_buf_length) {
|
|
|
- WMA_LOGE("%s: Received Invalid Phyerror event buffer length = %d"
|
|
|
- "Maximum allowed buf length = %d", __func__,
|
|
|
- pe_hdr->buf_len, max_dfs_buf_length);
|
|
|
-
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Reconstruct the 64 bit event TSF. This isn't from the MAC, it's
|
|
|
- * at the time the event was sent to us, the TSF value will be
|
|
|
- * in the future.
|
|
|
- */
|
|
|
- tsf64 = pe_hdr->tsf_l32;
|
|
|
- tsf64 |= (((uint64_t) pe_hdr->tsf_u32) << 32);
|
|
|
-
|
|
|
- /*
|
|
|
- * Check the HW board ID to figure out
|
|
|
- * if DFS-3 is supported. In DFS-3
|
|
|
- * phyerror mask indicates the type of
|
|
|
- * phyerror, whereas in DFS-2 phyerrorcode
|
|
|
- * indicates the type of phyerror. If the
|
|
|
- * board is NOT WMI_HWBD_QCA6174, for now
|
|
|
- * assume that it supports DFS-3.
|
|
|
- */
|
|
|
- if (wma->hw_bd_id != WMI_HWBD_QCA6174) {
|
|
|
- phy_err_mask = pe_hdr->rsPhyErrMask0;
|
|
|
- WMA_LOGD("%s: DFS-3 phyerror mask = 0x%x",
|
|
|
- __func__, phy_err_mask);
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Loop over the bufp, extracting out phyerrors
|
|
|
- * wmi_unified_comb_phyerr_rx_event.bufp is a char pointer,
|
|
|
- * which isn't correct here - what we have received here
|
|
|
- * is an array of TLV-style PHY errors.
|
|
|
- */
|
|
|
- n = 0; /* Start just after the header */
|
|
|
- bufp = param_tlvs->bufp;
|
|
|
- while (n < pe_hdr->buf_len) {
|
|
|
- /* ensure there's at least space for the header */
|
|
|
- if ((pe_hdr->buf_len - n) < sizeof(ev->hdr)) {
|
|
|
- WMA_LOGE("%s: Not enough space.(datalen=%d, n=%zu, hdr=%zu bytes",
|
|
|
- __func__, pe_hdr->buf_len, n, sizeof(ev->hdr));
|
|
|
- error = 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- /*
|
|
|
- * Obtain a pointer to the beginning of the current event.
|
|
|
- * data[0] is the beginning of the WMI payload.
|
|
|
- */
|
|
|
- ev = (wmi_single_phyerr_rx_event *) &bufp[n];
|
|
|
-
|
|
|
- /*
|
|
|
- * Sanity check the buffer length of the event against
|
|
|
- * what we currently have.
|
|
|
- * Since buf_len is 32 bits, we check if it overflows
|
|
|
- * a large 32 bit value. It's not 0x7fffffff because
|
|
|
- * we increase n by (buf_len + sizeof(hdr)), which would
|
|
|
- * in itself cause n to overflow.
|
|
|
- * If "int" is 64 bits then this becomes a moot point.
|
|
|
- */
|
|
|
- if (ev->hdr.buf_len > 0x7f000000) {
|
|
|
- WMA_LOGE("%s:buf_len is garbage (0x%x)", __func__,
|
|
|
- ev->hdr.buf_len);
|
|
|
- error = 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- if (n + ev->hdr.buf_len > pe_hdr->buf_len) {
|
|
|
- WMA_LOGE("%s: buf_len exceeds available space n=%zu,"
|
|
|
- "buf_len=%d, datalen=%d",
|
|
|
- __func__, n, ev->hdr.buf_len, pe_hdr->buf_len);
|
|
|
- error = 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- /*
|
|
|
- * If the board id is WMI_HWBD_QCA6174
|
|
|
- * then it supports only DFS-2. So, fetch
|
|
|
- * phyerror code in order to know the type
|
|
|
- * of phyerror.
|
|
|
- */
|
|
|
- if (wma->hw_bd_id == WMI_HWBD_QCA6174) {
|
|
|
- phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr);
|
|
|
- WMA_LOGD("%s: DFS-2 phyerror code = 0x%x",
|
|
|
- __func__, phy_err_code);
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * phy_err_code is set for DFS-2 and phy_err_mask
|
|
|
- * is set for DFS-3. Checking both to support
|
|
|
- * compatability for older platforms.
|
|
|
- * If the phyerror or phyerrmask category matches,
|
|
|
- * pass radar events to the dfs pattern matching code.
|
|
|
- * Don't pass radar events with no buffer payload.
|
|
|
- */
|
|
|
- if (((phy_err_mask & WMI_PHY_ERROR_MASK0_RADAR) ||
|
|
|
- (phy_err_mask & WMI_PHY_ERROR_MASK0_FALSE_RADAR_EXT)) ||
|
|
|
- (phy_err_code == WMA_DFS2_PHYERROR_CODE ||
|
|
|
- phy_err_code == WMA_DFS2_FALSE_RADAR_EXT)) {
|
|
|
- if (ev->hdr.buf_len > 0) {
|
|
|
- /* Calling in to the DFS module to process the phyerr */
|
|
|
- dfs_process_phyerr(ic, &ev->bufp[0],
|
|
|
- ev->hdr.buf_len,
|
|
|
- WMI_UNIFIED_RSSI_COMB_GET
|
|
|
- (&ev->hdr) & 0xff,
|
|
|
- /* Extension RSSI */
|
|
|
- WMI_UNIFIED_RSSI_COMB_GET
|
|
|
- (&ev->hdr) & 0xff,
|
|
|
- ev->hdr.tsf_timestamp,
|
|
|
- tsf64, enable_log);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Advance the buffer pointer to the next PHY error.
|
|
|
- * buflen is the length of this payload, so we need to
|
|
|
- * advance past the current header _AND_ the payload.
|
|
|
- */
|
|
|
- n += sizeof(*ev) + ev->hdr.buf_len;
|
|
|
-
|
|
|
- } /*end while() */
|
|
|
- if (error)
|
|
|
- return 0;
|
|
|
- else
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * wma_register_dfs_event_handler() - register dfs event handler
|
|
|
- * @wma_handle: wma handle
|
|
|
- *
|
|
|
- * Register appropriate dfs phyerror event handler
|
|
|
- * based on phyerror filtering offload is enabled
|
|
|
- * or disabled.
|
|
|
- *
|
|
|
- * Return: none
|
|
|
- */
|
|
|
-void wma_register_dfs_event_handler(tp_wma_handle wma_handle)
|
|
|
-{
|
|
|
- if (NULL == wma_handle) {
|
|
|
- WMA_LOGE("%s:wma_handle is NULL", __func__);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (false == wma_handle->dfs_phyerr_filter_offload) {
|
|
|
- /*
|
|
|
- * Register the wma_unified_phyerr_rx_event_handler
|
|
|
- * for filtering offload disabled case to handle
|
|
|
- * the DFS phyerrors.
|
|
|
- */
|
|
|
- WMA_LOGD("%s:Phyerror Filtering offload is Disabled in ini",
|
|
|
- __func__);
|
|
|
- wmi_unified_register_event_handler(wma_handle->wmi_handle,
|
|
|
- WMI_PHYERR_EVENTID,
|
|
|
- wma_unified_phyerr_rx_event_handler,
|
|
|
- WMA_RX_WORK_CTX);
|
|
|
- WMA_LOGD("%s: WMI_PHYERR_EVENTID event handler registered",
|
|
|
- __func__);
|
|
|
- } else {
|
|
|
- WMA_LOGD("%s:Phyerror Filtering offload is Enabled in ini",
|
|
|
- __func__);
|
|
|
- wmi_unified_register_event_handler(wma_handle->wmi_handle,
|
|
|
- WMI_DFS_RADAR_EVENTID,
|
|
|
- wma_unified_dfs_radar_rx_event_handler,
|
|
|
- WMA_RX_WORK_CTX);
|
|
|
- WMA_LOGD("%s:WMI_DFS_RADAR_EVENTID event handler registered",
|
|
|
- __func__);
|
|
|
- }
|
|
|
-
|
|
|
- return;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * wma_unified_dfs_phyerr_filter_offload_enable() - enable dfs phyerr filter
|
|
|
- * @wma_handle: wma handle
|
|
|
- *
|
|
|
- * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or
|
|
|
- * WMI_DFS_PHYERR_FILTER_DIS_CMDID command
|
|
|
- * to firmware based on phyerr filtering
|
|
|
- * offload status.
|
|
|
- *
|
|
|
- * Return: 1 success, 0 failure
|
|
|
- */
|
|
|
-int
|
|
|
-wma_unified_dfs_phyerr_filter_offload_enable(tp_wma_handle wma_handle)
|
|
|
-{
|
|
|
- int ret;
|
|
|
-
|
|
|
- if (NULL == wma_handle) {
|
|
|
- WMA_LOGE("%s:wma_handle is NULL", __func__);
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- ret = wmi_unified_dfs_phyerr_filter_offload_en_cmd(wma_handle->wmi_handle,
|
|
|
- wma_handle->dfs_phyerr_filter_offload);
|
|
|
- if (ret)
|
|
|
- return QDF_STATUS_E_FAILURE;
|
|
|
-
|
|
|
-
|
|
|
- return QDF_STATUS_SUCCESS;
|
|
|
-}
|
|
|
-
|
|
|
#if !defined(REMOVE_PKT_LOG)
|
|
|
/**
|
|
|
* wma_pktlog_wmi_send_cmd() - send pktlog enable/disable command to target
|
|
@@ -4891,496 +4421,6 @@ end_tdls_peer_state:
|
|
|
}
|
|
|
#endif /* FEATURE_WLAN_TDLS */
|
|
|
|
|
|
-
|
|
|
-/**
|
|
|
- * wma_dfs_attach() - Attach DFS methods to the umac state.
|
|
|
- * @dfs_ic: ieee80211com ptr
|
|
|
- *
|
|
|
- * Return: Return ieee80211com ptr with updated info
|
|
|
- */
|
|
|
-struct ieee80211com *wma_dfs_attach(struct ieee80211com *dfs_ic)
|
|
|
-{
|
|
|
- /*Allocate memory for dfs_ic before passing it up to dfs_attach() */
|
|
|
- dfs_ic = (struct ieee80211com *)
|
|
|
- os_malloc(NULL, sizeof(struct ieee80211com), GFP_ATOMIC);
|
|
|
- if (dfs_ic == NULL) {
|
|
|
- WMA_LOGE("%s:Allocation of dfs_ic failed %zu",
|
|
|
- __func__, sizeof(struct ieee80211com));
|
|
|
- return NULL;
|
|
|
- }
|
|
|
- OS_MEMZERO(dfs_ic, sizeof(struct ieee80211com));
|
|
|
- /* DFS pattern matching hooks */
|
|
|
- dfs_ic->ic_dfs_attach = ol_if_dfs_attach;
|
|
|
- dfs_ic->ic_dfs_disable = ol_if_dfs_disable;
|
|
|
- dfs_ic->ic_find_channel = ieee80211_find_channel;
|
|
|
- dfs_ic->ic_dfs_enable = ol_if_dfs_enable;
|
|
|
- dfs_ic->ic_ieee2mhz = ieee80211_ieee2mhz;
|
|
|
-
|
|
|
- /* Hardware facing hooks */
|
|
|
- dfs_ic->ic_get_ext_busy = ol_if_dfs_get_ext_busy;
|
|
|
- dfs_ic->ic_get_mib_cycle_counts_pct =
|
|
|
- ol_if_dfs_get_mib_cycle_counts_pct;
|
|
|
- dfs_ic->ic_get_TSF64 = ol_if_get_tsf64;
|
|
|
-
|
|
|
- /* NOL related hooks */
|
|
|
- dfs_ic->ic_dfs_usenol = ol_if_dfs_usenol;
|
|
|
- /*
|
|
|
- * Hooks from wma/dfs/ back
|
|
|
- * into the PE/SME
|
|
|
- * and shared DFS code
|
|
|
- */
|
|
|
- dfs_ic->ic_dfs_notify_radar = ieee80211_mark_dfs;
|
|
|
- qdf_spinlock_create(&dfs_ic->chan_lock);
|
|
|
- /* Initializes DFS Data Structures and queues */
|
|
|
- dfs_attach(dfs_ic);
|
|
|
-
|
|
|
- return dfs_ic;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * wma_dfs_detach() - Detach DFS methods
|
|
|
- * @dfs_ic: ieee80211com ptr
|
|
|
- *
|
|
|
- * Return: none
|
|
|
- */
|
|
|
-void wma_dfs_detach(struct ieee80211com *dfs_ic)
|
|
|
-{
|
|
|
- dfs_detach(dfs_ic);
|
|
|
-
|
|
|
- qdf_spinlock_destroy(&dfs_ic->chan_lock);
|
|
|
- if (NULL != dfs_ic->ic_curchan) {
|
|
|
- OS_FREE(dfs_ic->ic_curchan);
|
|
|
- dfs_ic->ic_curchan = NULL;
|
|
|
- }
|
|
|
-
|
|
|
- OS_FREE(dfs_ic);
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * wma_dfs_configure() - configure dfs
|
|
|
- * @ic: ieee80211com ptr
|
|
|
- *
|
|
|
- * Configures Radar Filters during
|
|
|
- * vdev start/channel change/regulatory domain
|
|
|
- * change.This Configuration enables to program
|
|
|
- * the DFS pattern matching module.
|
|
|
- *
|
|
|
- * Return: none
|
|
|
- */
|
|
|
-void wma_dfs_configure(struct ieee80211com *ic)
|
|
|
-{
|
|
|
- struct ath_dfs_radar_tab_info rinfo;
|
|
|
- int dfsdomain;
|
|
|
- int radar_enabled_status = 0;
|
|
|
- if (ic == NULL) {
|
|
|
- WMA_LOGE("%s: DFS ic is Invalid", __func__);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- dfsdomain = ic->current_dfs_regdomain;
|
|
|
-
|
|
|
- /* Fetch current radar patterns from the lmac */
|
|
|
- OS_MEMZERO(&rinfo, sizeof(rinfo));
|
|
|
-
|
|
|
- /*
|
|
|
- * Look up the current DFS
|
|
|
- * regulatory domain and decide
|
|
|
- * which radar pulses to use.
|
|
|
- */
|
|
|
- switch (dfsdomain) {
|
|
|
- case DFS_FCC_REG:
|
|
|
- WMA_LOGI("%s: DFS-FCC domain", __func__);
|
|
|
- rinfo.dfsdomain = DFS_FCC_REG;
|
|
|
- rinfo.dfs_radars = dfs_fcc_radars;
|
|
|
- rinfo.numradars = QDF_ARRAY_SIZE(dfs_fcc_radars);
|
|
|
- rinfo.b5pulses = dfs_fcc_bin5pulses;
|
|
|
- rinfo.numb5radars = QDF_ARRAY_SIZE(dfs_fcc_bin5pulses);
|
|
|
- break;
|
|
|
- case DFS_ETSI_REG:
|
|
|
- WMA_LOGI("%s: DFS-ETSI domain", __func__);
|
|
|
- rinfo.dfsdomain = DFS_ETSI_REG;
|
|
|
- rinfo.dfs_radars = dfs_etsi_radars;
|
|
|
- rinfo.numradars = QDF_ARRAY_SIZE(dfs_etsi_radars);
|
|
|
- rinfo.b5pulses = NULL;
|
|
|
- rinfo.numb5radars = 0;
|
|
|
- break;
|
|
|
- case DFS_MKK_REG:
|
|
|
- WMA_LOGI("%s: DFS-MKK domain", __func__);
|
|
|
- rinfo.dfsdomain = DFS_MKK_REG;
|
|
|
- rinfo.dfs_radars = dfs_mkk4_radars;
|
|
|
- rinfo.numradars = QDF_ARRAY_SIZE(dfs_mkk4_radars);
|
|
|
- rinfo.b5pulses = dfs_jpn_bin5pulses;
|
|
|
- rinfo.numb5radars = QDF_ARRAY_SIZE(dfs_jpn_bin5pulses);
|
|
|
- break;
|
|
|
- case DFS_CN_REG:
|
|
|
- WMA_LOGI("%s: DFS-CN domain", __func__);
|
|
|
- rinfo.dfsdomain = DFS_CN_REG;
|
|
|
- rinfo.dfs_radars = dfs_china_radars;
|
|
|
- rinfo.numradars = QDF_ARRAY_SIZE(dfs_china_radars);
|
|
|
- rinfo.b5pulses = NULL;
|
|
|
- rinfo.numb5radars = 0;
|
|
|
- break;
|
|
|
- case DFS_KR_REG:
|
|
|
- WMA_LOGI("%s: DFS-KR domain", __func__);
|
|
|
- rinfo.dfsdomain = DFS_KR_REG;
|
|
|
- rinfo.dfs_radars = dfs_korea_radars;
|
|
|
- rinfo.numradars = QDF_ARRAY_SIZE(dfs_korea_radars);
|
|
|
- rinfo.b5pulses = NULL;
|
|
|
- rinfo.numb5radars = 0;
|
|
|
- break;
|
|
|
- default:
|
|
|
- WMA_LOGI("%s: DFS-UNINT domain", __func__);
|
|
|
- rinfo.dfsdomain = DFS_UNINIT_REG;
|
|
|
- rinfo.dfs_radars = NULL;
|
|
|
- rinfo.numradars = 0;
|
|
|
- rinfo.b5pulses = NULL;
|
|
|
- rinfo.numb5radars = 0;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- rinfo.dfs_pri_multiplier = ic->dfs_pri_multiplier;
|
|
|
-
|
|
|
- /*
|
|
|
- * Set the regulatory domain,
|
|
|
- * radar pulse table and enable
|
|
|
- * radar events if required.
|
|
|
- * dfs_radar_enable() returns
|
|
|
- * 0 on success and non-zero
|
|
|
- * failure.
|
|
|
- */
|
|
|
- radar_enabled_status = dfs_radar_enable(ic, &rinfo);
|
|
|
- if (radar_enabled_status != DFS_STATUS_SUCCESS) {
|
|
|
- WMA_LOGE("%s[%d]: DFS- Radar Detection Enabling Failed",
|
|
|
- __func__, __LINE__);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * wma_dfs_configure_channel() - configure DFS channel
|
|
|
- * @dfs_ic: ieee80211com ptr
|
|
|
- * @band_center_freq1: center frequency 1
|
|
|
- * @band_center_freq2: center frequency 2
|
|
|
- * (valid only for 11ac vht 80plus80 mode)
|
|
|
- * @ req: vdev start request
|
|
|
- *
|
|
|
- * Set the Channel parameters in to DFS module
|
|
|
- * Also,configure the DFS radar filters for
|
|
|
- * matching the DFS phyerrors.
|
|
|
- *
|
|
|
- * Return: dfs_ieee80211_channel / NULL for error
|
|
|
- */
|
|
|
-struct dfs_ieee80211_channel *wma_dfs_configure_channel(
|
|
|
- struct ieee80211com *dfs_ic,
|
|
|
- uint32_t band_center_freq1,
|
|
|
- uint32_t band_center_freq2,
|
|
|
- struct wma_vdev_start_req
|
|
|
- *req)
|
|
|
-{
|
|
|
- uint8_t ext_channel;
|
|
|
- tp_wma_handle wma;
|
|
|
-
|
|
|
- wma = cds_get_context(QDF_MODULE_ID_WMA);
|
|
|
- if (!wma) {
|
|
|
- WMA_LOGE("%s: DFS- Invalid wma", __func__);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
-
|
|
|
- if (dfs_ic == NULL) {
|
|
|
- WMA_LOGE("%s: DFS ic is Invalid", __func__);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
-
|
|
|
- if (!dfs_ic->ic_curchan) {
|
|
|
- dfs_ic->ic_curchan = (struct dfs_ieee80211_channel *)os_malloc(
|
|
|
- NULL,
|
|
|
- sizeof(struct dfs_ieee80211_channel),
|
|
|
- GFP_ATOMIC);
|
|
|
- if (dfs_ic->ic_curchan == NULL) {
|
|
|
- WMA_LOGE(
|
|
|
- "%s: allocation of dfs_ic->ic_curchan failed %zu",
|
|
|
- __func__, sizeof(struct dfs_ieee80211_channel));
|
|
|
- return NULL;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- OS_MEMZERO(dfs_ic->ic_curchan, sizeof(struct dfs_ieee80211_channel));
|
|
|
-
|
|
|
- dfs_ic->ic_curchan->ic_ieee = req->chan;
|
|
|
- dfs_ic->ic_curchan->ic_freq = cds_chan_to_freq(req->chan);
|
|
|
- dfs_ic->ic_curchan->ic_vhtop_ch_freq_seg1 = band_center_freq1;
|
|
|
- dfs_ic->ic_curchan->ic_vhtop_ch_freq_seg2 = band_center_freq2;
|
|
|
- dfs_ic->ic_curchan->ic_pri_freq_center_freq_mhz_separation =
|
|
|
- dfs_ic->ic_curchan->ic_freq -
|
|
|
- dfs_ic->ic_curchan->ic_vhtop_ch_freq_seg1;
|
|
|
-
|
|
|
- if ((dfs_ic->ic_curchan->ic_ieee >= WMA_11A_CHANNEL_BEGIN) &&
|
|
|
- (dfs_ic->ic_curchan->ic_ieee <= WMA_11A_CHANNEL_END)) {
|
|
|
- dfs_ic->ic_curchan->ic_flags |= IEEE80211_CHAN_5GHZ;
|
|
|
- }
|
|
|
-
|
|
|
- switch (req->chan_width) {
|
|
|
- case CH_WIDTH_20MHZ:
|
|
|
- dfs_ic->ic_curchan->ic_flags |=
|
|
|
- (req->vht_capable ? IEEE80211_CHAN_VHT20 :
|
|
|
- IEEE80211_CHAN_HT20);
|
|
|
- break;
|
|
|
- case CH_WIDTH_40MHZ:
|
|
|
- if (req->chan < req->ch_center_freq_seg0)
|
|
|
- dfs_ic->ic_curchan->ic_flags |=
|
|
|
- (req->vht_capable ?
|
|
|
- IEEE80211_CHAN_VHT40PLUS :
|
|
|
- IEEE80211_CHAN_HT40PLUS);
|
|
|
- else
|
|
|
- dfs_ic->ic_curchan->ic_flags |=
|
|
|
- (req->vht_capable ?
|
|
|
- IEEE80211_CHAN_VHT40MINUS :
|
|
|
- IEEE80211_CHAN_HT40MINUS);
|
|
|
- break;
|
|
|
- case CH_WIDTH_80MHZ:
|
|
|
- dfs_ic->ic_curchan->ic_flags |= IEEE80211_CHAN_VHT80;
|
|
|
- break;
|
|
|
- case CH_WIDTH_80P80MHZ:
|
|
|
- ext_channel = cds_freq_to_chan(band_center_freq2);
|
|
|
- dfs_ic->ic_curchan->ic_flags |=
|
|
|
- IEEE80211_CHAN_VHT80P80;
|
|
|
- dfs_ic->ic_curchan->ic_freq_ext =
|
|
|
- band_center_freq2;
|
|
|
- dfs_ic->ic_curchan->ic_ieee_ext = ext_channel;
|
|
|
-
|
|
|
- /* verify both the 80MHz are DFS bands or not */
|
|
|
- if ((CHANNEL_STATE_DFS ==
|
|
|
- wlan_reg_get_5g_bonded_channel_state(wma->pdev,
|
|
|
- req->chan, CH_WIDTH_80MHZ)) &&
|
|
|
- (CHANNEL_STATE_DFS == wlan_reg_get_5g_bonded_channel_state(
|
|
|
- wma->pdev, ext_channel - WMA_80MHZ_START_CENTER_CH_DIFF,
|
|
|
- CH_WIDTH_80MHZ)))
|
|
|
- dfs_ic->ic_curchan->ic_80p80_both_dfs = true;
|
|
|
- break;
|
|
|
- case CH_WIDTH_160MHZ:
|
|
|
- dfs_ic->ic_curchan->ic_flags |=
|
|
|
- IEEE80211_CHAN_VHT160;
|
|
|
- break;
|
|
|
- default:
|
|
|
- WMA_LOGE(
|
|
|
- "%s: Recieved a wrong channel width %d",
|
|
|
- __func__, req->chan_width);
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- dfs_ic->ic_curchan->ic_flagext |= IEEE80211_CHAN_DFS;
|
|
|
-
|
|
|
- if (req->oper_mode == BSS_OPERATIONAL_MODE_AP) {
|
|
|
- dfs_ic->ic_opmode = IEEE80211_M_HOSTAP;
|
|
|
- dfs_ic->vdev_id = req->vdev_id;
|
|
|
- }
|
|
|
-
|
|
|
- dfs_ic->dfs_pri_multiplier = req->dfs_pri_multiplier;
|
|
|
-
|
|
|
- /*
|
|
|
- * Configuring the DFS with current channel and the radar filters
|
|
|
- */
|
|
|
- wma_dfs_configure(dfs_ic);
|
|
|
- WMA_LOGI("%s: DFS- CHANNEL CONFIGURED", __func__);
|
|
|
- return dfs_ic->ic_curchan;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * wma_set_dfs_region() - set DFS region
|
|
|
- * @wma: wma handle
|
|
|
- *
|
|
|
- * Configure the DFS region for DFS radar filter initialization
|
|
|
- *
|
|
|
- * Return: none
|
|
|
- */
|
|
|
-void wma_set_dfs_region(tp_wma_handle wma, enum dfs_reg dfs_region)
|
|
|
-{
|
|
|
- if (dfs_region >= DFS_UNDEF_REG ||
|
|
|
- dfs_region == DFS_UNINIT_REG)
|
|
|
-
|
|
|
- /* assign DFS_FCC_REGION as default region*/
|
|
|
- wma->dfs_ic->current_dfs_regdomain = DFS_FCC_REG;
|
|
|
- else
|
|
|
- wma->dfs_ic->current_dfs_regdomain = dfs_region;
|
|
|
-
|
|
|
- WMA_LOGI("%s: DFS Region Domain: %d", __func__,
|
|
|
- wma->dfs_ic->current_dfs_regdomain);
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * wma_get_channels() - prepare dfs radar channel list
|
|
|
- * @ichan: channel
|
|
|
- * @chan_list: return channel list
|
|
|
- *
|
|
|
- * Return: return number of channels
|
|
|
- */
|
|
|
-static int wma_get_channels(tp_wma_handle wma,
|
|
|
- struct dfs_ieee80211_channel *ichan,
|
|
|
- struct wma_dfs_radar_channel_list *chan_list)
|
|
|
-{
|
|
|
- uint8_t center_chan = cds_freq_to_chan(ichan->ic_vhtop_ch_freq_seg1);
|
|
|
- int count = 0;
|
|
|
- int start_channel = 0;
|
|
|
- int loop;
|
|
|
-
|
|
|
- chan_list->nchannels = 0;
|
|
|
-
|
|
|
- if (IEEE80211_IS_CHAN_11AC_VHT160(ichan)) {
|
|
|
-
|
|
|
- /*
|
|
|
- * as per the latest draft for BSS bandwidth 160MHz,
|
|
|
- * channel frequency segment 2 represents the center
|
|
|
- * channel frequency.
|
|
|
- */
|
|
|
- if (ichan->ic_vhtop_ch_freq_seg2)
|
|
|
- center_chan =
|
|
|
- cds_freq_to_chan(ichan->ic_vhtop_ch_freq_seg2);
|
|
|
- /*
|
|
|
- * In 160MHz channel width, need to
|
|
|
- * check if each of the 8 20MHz channel
|
|
|
- * is DFS before adding to the NOL list.
|
|
|
- * As it is possible that part of the
|
|
|
- * 160MHz can be Non-DFS channels.
|
|
|
- */
|
|
|
- start_channel = center_chan - WMA_160MHZ_START_CENTER_CH_DIFF;
|
|
|
- for (loop = 0; loop < WMA_DFS_MAX_20M_SUB_CH; loop++) {
|
|
|
- if (wlan_reg_get_channel_state(wma->pdev,
|
|
|
- start_channel +
|
|
|
- (loop * WMA_NEXT_20MHZ_START_CH_DIFF)) ==
|
|
|
- CHANNEL_STATE_DFS) {
|
|
|
- chan_list->channels[count] = start_channel +
|
|
|
- (loop * WMA_NEXT_20MHZ_START_CH_DIFF);
|
|
|
- count++;
|
|
|
- }
|
|
|
- }
|
|
|
- chan_list->nchannels = count;
|
|
|
- } else if (IEEE80211_IS_CHAN_11AC_VHT80P80(ichan)) {
|
|
|
- chan_list->nchannels = 4;
|
|
|
- /*
|
|
|
- * If SAP is operating in 80p80 mode, either
|
|
|
- * one of the two 80 segments or both the 80
|
|
|
- * segments can be DFS channels, so need to
|
|
|
- * identify on which 80 segment radar has
|
|
|
- * been detected and only add those channels
|
|
|
- * to the NOL list. center frequency should be
|
|
|
- * based on the segment id passed as part of
|
|
|
- * channel information in radar indication.
|
|
|
- */
|
|
|
- if (ichan->ic_radar_found_segid == DFS_80P80_SEG1)
|
|
|
- center_chan =
|
|
|
- cds_freq_to_chan(ichan->ic_vhtop_ch_freq_seg2);
|
|
|
- chan_list->channels[0] = center_chan - 6;
|
|
|
- chan_list->channels[1] = center_chan - 2;
|
|
|
- chan_list->channels[2] = center_chan + 2;
|
|
|
- chan_list->channels[3] = center_chan + 6;
|
|
|
- } else if (IEEE80211_IS_CHAN_11AC_VHT80(ichan)) {
|
|
|
- chan_list->nchannels = 4;
|
|
|
- chan_list->channels[0] = center_chan - 6;
|
|
|
- chan_list->channels[1] = center_chan - 2;
|
|
|
- chan_list->channels[2] = center_chan + 2;
|
|
|
- chan_list->channels[3] = center_chan + 6;
|
|
|
- } else if (IEEE80211_IS_CHAN_11N_HT40(ichan) ||
|
|
|
- IEEE80211_IS_CHAN_11AC_VHT40(ichan)) {
|
|
|
- chan_list->nchannels = 2;
|
|
|
- chan_list->channels[0] = center_chan - 2;
|
|
|
- chan_list->channels[1] = center_chan + 2;
|
|
|
- } else {
|
|
|
- chan_list->nchannels = 1;
|
|
|
- chan_list->channels[0] = center_chan;
|
|
|
- }
|
|
|
-
|
|
|
- return chan_list->nchannels;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * wma_dfs_indicate_radar() - Indicate Radar to SAP/HDD
|
|
|
- * @ic: ieee80211com ptr
|
|
|
- * @ichan: ieee 80211 channel
|
|
|
- *
|
|
|
- * Return: 0 for success or error code
|
|
|
- */
|
|
|
-int wma_dfs_indicate_radar(struct ieee80211com *ic,
|
|
|
- struct dfs_ieee80211_channel *ichan)
|
|
|
-{
|
|
|
- tp_wma_handle wma;
|
|
|
- void *hdd_ctx;
|
|
|
- struct wma_dfs_radar_indication *radar_event;
|
|
|
- struct wma_dfs_radar_ind wma_radar_event;
|
|
|
- tpAniSirGlobal pmac = NULL;
|
|
|
- bool indication_status;
|
|
|
-
|
|
|
- wma = cds_get_context(QDF_MODULE_ID_WMA);
|
|
|
- if (wma == NULL) {
|
|
|
- WMA_LOGE("%s: DFS- Invalid wma", __func__);
|
|
|
- return -ENOENT;
|
|
|
- }
|
|
|
-
|
|
|
- hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
|
|
|
- pmac = (tpAniSirGlobal)
|
|
|
- cds_get_context(QDF_MODULE_ID_PE);
|
|
|
-
|
|
|
- if (!pmac) {
|
|
|
- WMA_LOGE("%s: Invalid MAC handle", __func__);
|
|
|
- return -ENOENT;
|
|
|
- }
|
|
|
-
|
|
|
- if (wma->dfs_ic != ic) {
|
|
|
- WMA_LOGE("%s:DFS- Invalid WMA handle", __func__);
|
|
|
- return -ENOENT;
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Do not post multiple Radar events on the same channel.
|
|
|
- * But, when DFS test mode is enabled, allow multiple dfs
|
|
|
- * radar events to be posted on the same channel.
|
|
|
- */
|
|
|
- qdf_spin_lock_bh(&ic->chan_lock);
|
|
|
- if (!pmac->sap.SapDfsInfo.disable_dfs_ch_switch)
|
|
|
- wma->dfs_ic->disable_phy_err_processing = true;
|
|
|
-
|
|
|
- if ((ichan->ic_ieee != (wma->dfs_ic->last_radar_found_chan)) ||
|
|
|
- (pmac->sap.SapDfsInfo.disable_dfs_ch_switch == true)) {
|
|
|
- radar_event = (struct wma_dfs_radar_indication *)
|
|
|
- qdf_mem_malloc(sizeof(struct wma_dfs_radar_indication));
|
|
|
- if (radar_event == NULL) {
|
|
|
- WMA_LOGE(FL("Failed to allocate memory for radar_event"));
|
|
|
- qdf_spin_unlock_bh(&ic->chan_lock);
|
|
|
- return -ENOMEM;
|
|
|
- }
|
|
|
- wma->dfs_ic->last_radar_found_chan = ichan->ic_ieee;
|
|
|
- /* Indicate the radar event to HDD to stop the netif Tx queues */
|
|
|
- wma_radar_event.chan_freq = ichan->ic_freq;
|
|
|
- wma_radar_event.dfs_radar_status = WMA_DFS_RADAR_FOUND;
|
|
|
- indication_status =
|
|
|
- wma->dfs_radar_indication_cb(hdd_ctx, &wma_radar_event);
|
|
|
- if (indication_status == false) {
|
|
|
- WMA_LOGE("%s:Application triggered channel switch in progress!.. drop radar event indiaction to SAP",
|
|
|
- __func__);
|
|
|
- qdf_mem_free(radar_event);
|
|
|
- qdf_spin_unlock_bh(&ic->chan_lock);
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- WMA_LOGE("%s:DFS- RADAR INDICATED TO HDD", __func__);
|
|
|
-
|
|
|
- wma_radar_event.ieee_chan_number = ichan->ic_ieee;
|
|
|
- /*
|
|
|
- * Indicate to the radar event to SAP to
|
|
|
- * select a new channel and set CSA IE
|
|
|
- */
|
|
|
- radar_event->vdev_id = ic->vdev_id;
|
|
|
- wma_get_channels(wma, ichan, &radar_event->chan_list);
|
|
|
- radar_event->dfs_radar_status = WMA_DFS_RADAR_FOUND;
|
|
|
- radar_event->use_nol = ic->ic_dfs_usenol(ic);
|
|
|
- wma_send_msg(wma, WMA_DFS_RADAR_IND, (void *)radar_event, 0);
|
|
|
- WMA_LOGE("%s:DFS- WMA_DFS_RADAR_IND Message Posted", __func__);
|
|
|
- }
|
|
|
- qdf_spin_unlock_bh(&ic->chan_lock);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
#ifdef WLAN_FEATURE_MEMDUMP
|
|
|
/*
|
|
|
* wma_process_fw_mem_dump_req() - Function to request fw memory dump from
|