summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrakash Dhavali <pdhavali@codeaurora.org>2014-01-24 09:57:22 -0800
committerPrakash Dhavali <pdhavali@codeaurora.org>2014-01-24 09:57:22 -0800
commit5af7cf592cd5ac53c0eef51c5be8182133b74112 (patch)
treea5a0da067325eaa4e7d7438948784aa851602624
parenta9053b62b2fcfebd1c9089c590d2191ea358d43d (diff)
parentdc21a9afb59e0117924f0dcb9187204ed981b8e2 (diff)
Merge remote-tracking branch 'origin/caf/caf-wlan/master'
-rw-r--r--CORE/BAP/src/btampFsm.c2
-rw-r--r--CORE/CLD_TXRX/TLSHIM/tl_shim.c114
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_txrx.c18
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_txrx_types.h23
-rw-r--r--CORE/CLD_TXRX/TXRX/txrx_api.c15
-rw-r--r--CORE/DXE/htt_dxe.c341
-rw-r--r--CORE/DXE/htt_dxe_fw_stats.c50
-rw-r--r--CORE/DXE/htt_dxe_h2t.c71
-rw-r--r--CORE/DXE/htt_dxe_internal.h137
-rw-r--r--CORE/DXE/htt_dxe_rx.c1126
-rw-r--r--CORE/DXE/htt_dxe_t2h.c335
-rw-r--r--CORE/DXE/htt_dxe_tx.c809
-rw-r--r--CORE/DXE/htt_dxe_types.h188
-rw-r--r--CORE/HDD/inc/qc_sap_ioctl.h1
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg.h11
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h16
-rw-r--r--CORE/HDD/inc/wlan_hdd_p2p.h1
-rw-r--r--CORE/HDD/inc/wlan_hdd_tdls.h3
-rw-r--r--CORE/HDD/inc/wlan_hdd_tgt_cfg.h7
-rw-r--r--CORE/HDD/src/test.c10032
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg.c57
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c30
-rw-r--r--CORE/HDD/src/wlan_hdd_early_suspend.c41
-rw-r--r--CORE/HDD/src/wlan_hdd_ftm.c18
-rw-r--r--CORE/HDD/src/wlan_hdd_hostapd.c31
-rw-r--r--CORE/HDD/src/wlan_hdd_ipa.c692
-rw-r--r--CORE/HDD/src/wlan_hdd_main.c198
-rw-r--r--CORE/HDD/src/wlan_hdd_p2p.c90
-rw-r--r--CORE/HDD/src/wlan_hdd_softap_tx_rx.c34
-rw-r--r--CORE/HDD/src/wlan_hdd_tdls.c4
-rw-r--r--CORE/HDD/src/wlan_hdd_tx_rx.c2
-rw-r--r--CORE/HDD/src/wlan_hdd_wext.c509
-rw-r--r--CORE/HDD/src/wlan_hdd_wmm.c8
-rw-r--r--CORE/MAC/inc/aniGlobal.h5
-rw-r--r--CORE/MAC/inc/qwlan_version.h7
-rw-r--r--CORE/MAC/inc/sirApi.h60
-rw-r--r--CORE/MAC/inc/wniApi.h8
-rw-r--r--CORE/MAC/src/include/sirParams.h5
-rw-r--r--CORE/MAC/src/pe/include/limGlobal.h4
-rw-r--r--CORE/MAC/src/pe/include/limSession.h3
-rw-r--r--CORE/MAC/src/pe/lim/limApi.c6
-rw-r--r--CORE/MAC/src/pe/lim/limProcessCfgUpdates.c10
-rw-r--r--CORE/MAC/src/pe/lim/limProcessMessageQueue.c32
-rw-r--r--CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c3
-rw-r--r--CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c34
-rw-r--r--CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c228
-rw-r--r--CORE/MAC/src/pe/lim/limRMC.c1893
-rw-r--r--CORE/MAC/src/pe/lim/limRMC.h113
-rw-r--r--CORE/MAC/src/pe/lim/limSendMessages.c6
-rw-r--r--CORE/MAC/src/pe/lim/limSendSmeRspMessages.c172
-rw-r--r--CORE/MAC/src/pe/lim/limSendSmeRspMessages.h9
-rw-r--r--CORE/MAC/src/pe/lim/limTypes.h1
-rw-r--r--CORE/MAC/src/pe/sch/schBeaconGen.c61
-rw-r--r--CORE/SAP/inc/sapApi.h96
-rw-r--r--CORE/SAP/src/sapApiLinkCntl.c215
-rw-r--r--CORE/SAP/src/sapFsm.c428
-rw-r--r--CORE/SAP/src/sapFsm_ext.h5
-rw-r--r--CORE/SAP/src/sapInternal.h49
-rw-r--r--CORE/SAP/src/sapModule.c181
-rw-r--r--CORE/SERVICES/BMI/bmi.c21
-rw-r--r--CORE/SERVICES/BMI/ol_fw.c93
-rw-r--r--CORE/SERVICES/BMI/ol_fw.h30
-rw-r--r--CORE/SERVICES/COMMON/_ieee80211_common.h8
-rw-r--r--CORE/SERVICES/COMMON/a_osapi.h11
-rw-r--r--CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h7
-rw-r--r--CORE/SERVICES/COMMON/bmi_msg.h8
-rw-r--r--CORE/SERVICES/COMMON/dbglog_id.h79
-rw-r--r--CORE/SERVICES/COMMON/hif.h9
-rw-r--r--CORE/SERVICES/COMMON/htc_api.h1
-rw-r--r--CORE/SERVICES/COMMON/ieee80211_common.h3
-rw-r--r--CORE/SERVICES/COMMON/ol_if_athvar.h15
-rw-r--r--CORE/SERVICES/COMMON/pktlog.h15
-rw-r--r--CORE/SERVICES/COMMON/targaddrs.h11
-rw-r--r--CORE/SERVICES/COMMON/targcfg.h8
-rw-r--r--CORE/SERVICES/COMMON/wdi_event.h15
-rw-r--r--CORE/SERVICES/COMMON/wlan_module_ids.h2
-rw-r--r--CORE/SERVICES/COMMON/wma_api.h3
-rw-r--r--CORE/SERVICES/COMMON/wma_dfs_interface.h216
-rw-r--r--CORE/SERVICES/COMMON/wmi_unified.h88
-rw-r--r--CORE/SERVICES/COMMON/wmi_version.h2
-rw-r--r--CORE/SERVICES/DFS/inc/ath_dfs_structs.h252
-rw-r--r--CORE/SERVICES/DFS/inc/dfs_interface.h184
-rw-r--r--CORE/SERVICES/DFS/inc/radar_filters.h142
-rw-r--r--CORE/SERVICES/DFS/sources64
-rw-r--r--CORE/SERVICES/DFS/src/dfs.c976
-rw-r--r--CORE/SERVICES/DFS/src/dfs.h780
-rw-r--r--CORE/SERVICES/DFS/src/dfs_bindetects.c461
-rw-r--r--CORE/SERVICES/DFS/src/dfs_debug.c157
-rw-r--r--CORE/SERVICES/DFS/src/dfs_fcc_bin5.c829
-rw-r--r--CORE/SERVICES/DFS/src/dfs_init.c380
-rw-r--r--CORE/SERVICES/DFS/src/dfs_ioctl.h133
-rw-r--r--CORE/SERVICES/DFS/src/dfs_ioctl_private.h115
-rw-r--r--CORE/SERVICES/DFS/src/dfs_misc.c261
-rw-r--r--CORE/SERVICES/DFS/src/dfs_nol.c407
-rw-r--r--CORE/SERVICES/DFS/src/dfs_phyerr.h (renamed from CORE/VOSS/src/packet.c)52
-rw-r--r--CORE/SERVICES/DFS/src/dfs_phyerr_tlv.c667
-rw-r--r--CORE/SERVICES/DFS/src/dfs_phyerr_tlv.h223
-rw-r--r--CORE/SERVICES/DFS/src/dfs_process_phyerr.c883
-rw-r--r--CORE/SERVICES/DFS/src/dfs_process_radarevent.c583
-rw-r--r--CORE/SERVICES/DFS/src/dfs_staggered.c296
-rw-r--r--CORE/SERVICES/HIF/PCIe/ar6320def.h2
-rw-r--r--CORE/SERVICES/HIF/PCIe/ar6320v2def.h519
-rw-r--r--CORE/SERVICES/HIF/PCIe/cepci.h8
-rw-r--r--CORE/SERVICES/HIF/PCIe/hif_pci.c52
-rw-r--r--CORE/SERVICES/HIF/PCIe/hif_pci.h1
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.c128
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.h1
-rw-r--r--CORE/SERVICES/HIF/PCIe/regtable.c31
-rw-r--r--CORE/SERVICES/HTC/htc.c8
-rw-r--r--CORE/SERVICES/WMA/regdomain.c24
-rw-r--r--CORE/SERVICES/WMA/wma.c2456
-rw-r--r--CORE/SERVICES/WMA/wma.h126
-rw-r--r--CORE/SERVICES/WMA/wma_dfs_interface.c231
-rw-r--r--CORE/SERVICES/WMA/wma_stub.h6
-rw-r--r--CORE/SERVICES/WMI/wmi_tlv_platform.c15
-rw-r--r--CORE/SME/inc/csrApi.h17
-rw-r--r--CORE/SME/inc/csrInternal.h20
-rw-r--r--CORE/SME/inc/pmcApi.h3
-rw-r--r--CORE/SME/inc/sme_Api.h36
-rw-r--r--CORE/SME/inc/sme_Trace.h6
-rw-r--r--CORE/SME/src/csr/csrApiRoam.c251
-rw-r--r--CORE/SME/src/csr/csrApiScan.c2
-rw-r--r--CORE/SME/src/pmc/pmc.c6
-rw-r--r--CORE/SME/src/pmc/pmcApi.c45
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c273
-rw-r--r--CORE/SME/src/sme_common/sme_Trace.c6
-rw-r--r--CORE/SVC/src/ptt/wlan_ptt_sock_svc.c16
-rw-r--r--CORE/SYS/common/src/wlan_qct_sys.c44
-rw-r--r--CORE/TL/inc/wlan_qct_tl.h33
-rw-r--r--CORE/TL/src/wlan_qct_tl.c4
-rw-r--r--CORE/TL/src/wlan_qct_tl_hosupport.c2
-rw-r--r--CORE/TL/src/wlan_qct_tl_hosupport.h2
-rw-r--r--CORE/UTILS/FWLOG/dbglog_host.c37
-rw-r--r--CORE/VOSS/inc/i_vos_packet.h1
-rw-r--r--CORE/VOSS/inc/packet.h86
-rw-r--r--CORE/VOSS/inc/vos_mq.h12
-rw-r--r--CORE/VOSS/inc/vos_utils.h5
-rw-r--r--CORE/VOSS/inc/wcnss_api.h38
-rw-r--r--CORE/VOSS/src/vos_api.c6
-rw-r--r--CORE/VOSS/src/vos_getBin.c3
-rw-r--r--CORE/VOSS/src/vos_nvitem.c177
-rw-r--r--CORE/VOSS/src/vos_timer.c15
-rw-r--r--CORE/VOSS/src/vos_utils.c142
-rw-r--r--CORE/WDA/inc/legacy/halMsgApi.h2
-rw-r--r--CORE/WDA/inc/wlan_qct_wda.h25
-rw-r--r--CORE/WDA/src/wlan_qct_wda.c2
-rw-r--r--CORE/WDI/CP/inc/wlan_qct_wdi.h2
-rw-r--r--Kbuild38
-rw-r--r--Makefile29
-rw-r--r--firmware_bin/WCNSS_qcom_cfg.ini2
-rw-r--r--tools/fwdebuglog/cld-fwlog-netlink.c22
-rw-r--r--tools/fwdebuglog/cld-fwlog-parser.c265
-rw-r--r--tools/fwdebuglog/cld-fwlog-record.c4
-rw-r--r--tools/fwdebuglog/parser.c439
154 files changed, 15405 insertions, 17459 deletions
diff --git a/CORE/BAP/src/btampFsm.c b/CORE/BAP/src/btampFsm.c
index f6c29373dc70..f052f157e190 100644
--- a/CORE/BAP/src/btampFsm.c
+++ b/CORE/BAP/src/btampFsm.c
@@ -1175,7 +1175,7 @@ regStaWithTl
if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
{
VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
- "%s: WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08lX]",
+ "%s: WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]",
__func__, vosStatus, vosStatus );
}
diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/CORE/CLD_TXRX/TLSHIM/tl_shim.c
index f8f40ea86974..dcce0648fe31 100644
--- a/CORE/CLD_TXRX/TLSHIM/tl_shim.c
+++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.c
@@ -43,6 +43,7 @@
#endif
#include "adf_nbuf.h"
#include "wma_api.h"
+#include "vos_utils.h"
#define ENTER() VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, "Enter:%s", __func__)
@@ -389,13 +390,18 @@ next_nbuf:
#define TLSHIM_TGT_NOISE_FLOOR_DBM (-96)
static int tlshim_mgmt_rx_process(void *context, u_int8_t *data,
- u_int32_t data_len, bool saved_beacon)
+ u_int32_t data_len, bool saved_beacon, u_int32_t vdev_id)
{
void *vos_ctx = vos_get_global_context(VOS_MODULE_ID_TL, NULL);
struct txrx_tl_shim_ctx *tl_shim = vos_get_context(VOS_MODULE_ID_TL,
vos_ctx);
WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs = NULL;
wmi_mgmt_rx_hdr *hdr = NULL;
+#ifdef WLAN_FEATURE_11W
+ struct wma_txrx_node *iface = NULL;
+ tp_wma_handle wma;
+ u_int8_t *efrm, *orig_hdr;
+#endif /* WLAN_FEATURE_11W */
vos_pkt_t *rx_pkt;
adf_nbuf_t wbuf;
@@ -515,20 +521,82 @@ static int tlshim_mgmt_rx_process(void *context, u_int8_t *data,
tl_shim->last_beacon_len = data_len;
}
}
+
+#ifdef WLAN_FEATURE_11W
+ wma = vos_get_context(VOS_MODULE_ID_WDA, vos_ctx);
+ if (wma)
+ iface = &wma->interfaces[vdev_id];
+ if (iface && iface->rmfEnabled && mgt_type == IEEE80211_FC0_TYPE_MGT &&
+ (mgt_subtype == IEEE80211_FC0_SUBTYPE_DISASSOC ||
+ mgt_subtype == IEEE80211_FC0_SUBTYPE_DEAUTH ||
+ mgt_subtype == IEEE80211_FC0_SUBTYPE_ACTION))
+ {
+ if ((wh)->i_fc[1] & IEEE80211_FC1_WEP)
+ {
+ orig_hdr = (u_int8_t*) adf_nbuf_data(wbuf);
+
+ /* Strip privacy headers (and trailer)
+ for a received frame */
+ vos_mem_move(orig_hdr + IEEE80211_CCMP_HEADERLEN,
+ wh, sizeof(*wh));
+ adf_nbuf_pull_head(wbuf, IEEE80211_CCMP_HEADERLEN);
+ adf_nbuf_trim_tail(wbuf, IEEE80211_CCMP_MICLEN);
+
+ rx_pkt->pkt_meta.mpdu_hdr_ptr = adf_nbuf_data(wbuf);
+ rx_pkt->pkt_meta.mpdu_data_ptr =
+ rx_pkt->pkt_meta.mpdu_hdr_ptr +
+ rx_pkt->pkt_meta.mpdu_hdr_len;
+ rx_pkt->pkt_buf = wbuf;
+ }
+ else
+ {
+ if (IEEE80211_IS_BROADCAST(wh->i_addr1) ||
+ IEEE80211_IS_MULTICAST(wh->i_addr1))
+ {
+ efrm = adf_nbuf_data(wbuf) + adf_nbuf_len(wbuf);
+ if (vos_is_mmie_valid(iface->key.key,
+ iface->key.ipn,
+ (u_int8_t *)wh, efrm))
+ {
+ TLSHIM_LOGD("Protected BC/MC frame MMIE"
+ " validation successful");
+
+ /* Remove MMIE */
+ adf_nbuf_trim_tail(wbuf,
+ vos_get_mmie_size());
+ }
+ else
+ {
+ TLSHIM_LOGE("BC/MC MIC error or MMIE"
+ " not present, dropping the frame");
+ vos_pkt_return_packet(rx_pkt);
+ return 0;
+ }
+ }
+ else
+ {
+ TLSHIM_LOGD("Rx unprotected unicast mgmt frame");
+ rx_pkt->pkt_meta.dpuFeedback =
+ DPU_FEEDBACK_UNPROTECTED_ERROR;
+ }
+
+ }
+ }
+#endif /* WLAN_FEATURE_11W */
return tl_shim->mgmt_rx(vos_ctx, rx_pkt);
}
static int tlshim_mgmt_rx_wmi_handler(void *context, u_int8_t *data,
u_int32_t data_len)
{
- return (tlshim_mgmt_rx_process(context, data, data_len, FALSE));
+ return (tlshim_mgmt_rx_process(context, data, data_len, FALSE, 0));
}
#endif
/*
* tlshim_mgmt_roam_event_ind() is called from WMA layer when
* BETTER_AP_FOUND event is received from roam engine.
*/
-int tlshim_mgmt_roam_event_ind(void *context)
+int tlshim_mgmt_roam_event_ind(void *context, u_int32_t vdev_id)
{
void *vos_ctx = vos_get_global_context(VOS_MODULE_ID_TL, NULL);
struct txrx_tl_shim_ctx *tl_shim = vos_get_context(VOS_MODULE_ID_TL,
@@ -536,7 +604,7 @@ int tlshim_mgmt_roam_event_ind(void *context)
VOS_STATUS ret = VOS_STATUS_SUCCESS;
if (tl_shim->last_beacon_data && tl_shim->last_beacon_len)
{
- ret = tlshim_mgmt_rx_process(context, tl_shim->last_beacon_data, tl_shim->last_beacon_len, TRUE);
+ ret = tlshim_mgmt_rx_process(context, tl_shim->last_beacon_data, tl_shim->last_beacon_len, TRUE, vdev_id);
}
return ret;
}
@@ -763,7 +831,19 @@ adf_nbuf_t WLANTL_SendSTA_DataFrame(void *vos_ctx, u_int8_t sta_id,
}
/* Zero out skb's context buffer for the driver to use */
+#ifdef IPA_OFFLOAD
+ if ((NBUF_OWNER_ID(skb) == IPA_NBUF_OWNER_ID)
+ && NBUF_CALLBACK_FN(skb)) {
+ uint32_t skb_owner_id = NBUF_OWNER_ID(skb);
+ __adf_nbuf_callback_fn skb_cb_fn = NBUF_CALLBACK_FN(skb);
+ adf_os_mem_set(skb->cb, 0, sizeof(skb->cb));
+ NBUF_OWNER_ID(skb) = skb_owner_id;
+ NBUF_CALLBACK_FN(skb) = skb_cb_fn;
+ } else
+ adf_os_mem_set(skb->cb, 0, sizeof(skb->cb));
+#else
adf_os_mem_set(skb->cb, 0, sizeof(skb->cb));
+#endif
adf_nbuf_map_single(adf_ctx, skb, ADF_OS_DMA_TO_DEVICE);
if ((tl_shim->ip_checksum_offload) && (skb->protocol == htons(ETH_P_IP))
@@ -782,32 +862,6 @@ adf_nbuf_t WLANTL_SendSTA_DataFrame(void *vos_ctx, u_int8_t sta_id,
return NULL;
}
-#ifdef IPA_OFFLOAD
-adf_nbuf_t WLANTL_SendIPA_DataFrame(void *vos_ctx, void *vdev,
- adf_nbuf_t skb)
-{
- struct txrx_tl_shim_ctx *tl_shim = vos_get_context(VOS_MODULE_ID_TL,
- vos_ctx);
- adf_nbuf_t ret;
-
- ENTER();
-
- if ((tl_shim->ip_checksum_offload) && (skb->protocol == htons(ETH_P_IP))
- && (skb->ip_summed == CHECKSUM_PARTIAL))
- skb->ip_summed = CHECKSUM_COMPLETE;
-
- /* Terminate the (single-element) list of tx frames */
- skb->next = NULL;
- ret = tl_shim->tx((struct ol_txrx_vdev_t *)vdev, skb);
- if (ret) {
- TLSHIM_LOGW("Failed to tx");
- return ret;
- }
-
- return NULL;
-}
-#endif
-
VOS_STATUS WLANTL_ResumeDataTx(void *vos_ctx, u_int8_t *sta_id)
{
return VOS_STATUS_SUCCESS;
diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx.c b/CORE/CLD_TXRX/TXRX/ol_txrx.c
index 182312ff4662..90f55b17d873 100644
--- a/CORE/CLD_TXRX/TXRX/ol_txrx.c
+++ b/CORE/CLD_TXRX/TXRX/ol_txrx.c
@@ -771,6 +771,13 @@ ol_txrx_vdev_attach(
TAILQ_INIT(&vdev->peer_list);
vdev->last_real_peer = NULL;
+ #ifndef CONFIG_QCA_WIFI_ISOC
+ #ifdef QCA_IBSS_SUPPORT
+ vdev->ibss_peer_num = 0;
+ vdev->ibss_peer_heart_beat_timer = 0;
+ #endif
+ #endif
+
#if defined(CONFIG_HL_SUPPORT)
if (ol_cfg_is_high_latency(pdev->ctrl_pdev)) {
u_int8_t i;
@@ -1085,6 +1092,17 @@ ol_txrx_peer_state_update(ol_txrx_pdev_handle pdev, u_int8_t *peer_mac,
struct ol_txrx_peer_t *peer;
peer = ol_txrx_peer_find_hash_find(pdev, peer_mac, 0, 1);
+
+ if (NULL == peer)
+ {
+ TXRX_PRINT(TXRX_PRINT_LEVEL_INFO2, "%s: peer is null for peer_mac"
+ " 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__,
+ peer_mac[0], peer_mac[1], peer_mac[2], peer_mac[3],
+ peer_mac[4], peer_mac[5]);
+ return;
+ }
+
+
/* TODO: Should we send WMI command of the connection state? */
/* avoid multiple auth state change. */
if (peer->state == state) {
diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h
index 23f40c008aa9..7c757b43012e 100644
--- a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h
+++ b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h
@@ -24,21 +24,6 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-/*
- * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
/**
* @file ol_txrx_types.h
@@ -707,6 +692,14 @@ struct ol_txrx_vdev_t {
enum wlan_op_mode opmode;
+#ifndef CONFIG_QCA_WIFI_ISOC
+#ifdef QCA_IBSS_SUPPORT
+ /* ibss mode related */
+ int16_t ibss_peer_num; /* the number of active peers */
+ int16_t ibss_peer_heart_beat_timer; /* for detecting peer departure */
+#endif
+#endif
+
#if defined(CONFIG_HL_SUPPORT)
struct ol_tx_frms_queue_t txqs[OL_TX_VDEV_NUM_QUEUES];
#endif
diff --git a/CORE/CLD_TXRX/TXRX/txrx_api.c b/CORE/CLD_TXRX/TXRX/txrx_api.c
index dbb32fa79588..23840ead0eb7 100644
--- a/CORE/CLD_TXRX/TXRX/txrx_api.c
+++ b/CORE/CLD_TXRX/TXRX/txrx_api.c
@@ -24,21 +24,6 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-/*
- * Copyright (c) 2013 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
/*
* This file has the implementation of TXRX api for HDD<->TXRX and
diff --git a/CORE/DXE/htt_dxe.c b/CORE/DXE/htt_dxe.c
deleted file mode 100644
index bf22d1f40506..000000000000
--- a/CORE/DXE/htt_dxe.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
- *
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file was originally distributed by Qualcomm Atheros, Inc.
- * under proprietary terms before Copyright ownership was assigned
- * to the Linux Foundation.
- */
-
-/**
- * @file htt_dxe.c
- * @brief Provide functions to create+init and destroy a HTT instance.
- * @details
- * This file contains functions for creating a HTT instance; initializing
- * the HTT instance, e.g. by allocating a pool of HTT tx descriptors, and
- * and deleting a HTT instance.
- */
-
-#include <adf_os_mem.h> /* adf_os_mem_alloc */
-#include <adf_os_types.h> /* adf_os_device_t, adf_os_print */
-
-#include <ol_cfg.h> /* ol_cfg_max_vdevs, etc. */
-#include <ol_htt_api.h>
-#include <ol_txrx_htt_api.h> /* ol_tx_target_credit_update */
-
-#include <htt_dxe_types.h>
-#include <htt_dxe_internal.h>
-
-#define htt_dxe_attach htt_attach
-#define htt_dxe_attach_target htt_attach_target
-#define htt_dxe_detach htt_detach
-#define htt_dxe_detach_target htt_detach_target
-#define htt_dxe_vdev_attach htt_vdev_attach
-#define htt_dxe_vdev_detach htt_vdev_detach
-#define htt_dxe_peer_qos_update htt_peer_qos_update
-#define htt_dxe_peer_uapsdmask_update htt_peer_uapsdmask_update
-#define htt_dxe_display htt_display
-
-
-htt_pdev_handle
-htt_dxe_attach(
- ol_txrx_pdev_handle txrx_pdev,
- ol_pdev_handle ctrl_pdev,
- HTC_HANDLE htc_pdev,
- adf_os_device_t osdev,
- int desc_pool_size)
-{
- int i;
- int tx_credit;
- A_STATUS status;
- struct htt_dxe_pdev_t *pdev;
- S_HIFDXE_CALLBACK hif_dxe_cbs = {0};
-
- pdev = adf_os_mem_alloc(osdev, sizeof(*pdev));
- if (!pdev) {
- return NULL;
- }
-
- /*
- * Zero out all pointers within the pdev object, so it will be
- * obvious which pointers have been initialized and which haven't.
- * This allows the htt_dxe_detach function to be used to clean up
- * when the htt_dxe_attach initializations fail halfway through.
- */
- adf_os_mem_zero(pdev, sizeof(*pdev));
-
- pdev->osdev = osdev;
- pdev->ctrl_pdev = ctrl_pdev;
- pdev->txrx_pdev = txrx_pdev;
-
- pdev->vdevs = adf_os_mem_alloc(osdev,
- sizeof(struct htt_dxe_vdev_t) * ol_cfg_max_vdevs(ctrl_pdev));
- if (!pdev->vdevs) {
- goto fail;
- }
- for (i = 0; i < ol_cfg_max_vdevs(ctrl_pdev); i++) {
- pdev->vdevs[i].valid = 0;
- }
-
- pdev->peers = adf_os_mem_alloc(osdev,
- sizeof(struct htt_dxe_peer_t) * (ol_cfg_max_peer_id(ctrl_pdev) + 1));
- if (!pdev->peers) {
- goto fail;
- }
- for (i = 0; i <= ol_cfg_max_peer_id(ctrl_pdev); i++) {
- pdev->peers[i].valid = 0;
- pdev->peers[i].qos_capable = 0; /* default */
- }
-
- if (htt_dxe_tx_attach(pdev, desc_pool_size)) {
- goto fail;
- }
-
- if (htt_dxe_rx_attach(pdev)) {
- goto fail;
- }
-
- adf_os_spinlock_init(&pdev->tx_mutex);
- pdev->tx_mutex_valid = 1;
-
- pdev->hif_dxe_pdev = hif_dxe_attach(osdev);
-
- if (!pdev->hif_dxe_pdev) {
- goto fail;
- }
-
- hif_dxe_cbs.HifTxCompleteCb = htt_dxe_tx_download_done;
- hif_dxe_cbs.HifTxCompleteCtx = pdev;
- hif_dxe_cbs.HifLowResourceCb = htt_dxe_tx_low_rsrc;
- hif_dxe_cbs.HifLowResourceCtx = pdev;
-
- status = hif_dxe_client_registration(pdev->hif_dxe_pdev, &hif_dxe_cbs);
- if (status != A_OK) {
- goto fail;
- }
-
- pdev->dmux_dxe_pdev = dmux_dxe_attach(pdev->osdev);
- if (!pdev->dmux_dxe_pdev) {
- goto fail;
- }
- if ((dmux_dxe_register_callback_rx_data(
- pdev->dmux_dxe_pdev, htt_dxe_rx, (void *) pdev) != A_OK) ||
- (dmux_dxe_register_callback_rx_ctrl(
- pdev->dmux_dxe_pdev, htt_dxe_rx_ctrl, (void *) pdev) != A_OK) ||
- (dmux_dxe_register_callback_msg(
- pdev->dmux_dxe_pdev, htt_dxe_t2h_msg_handler, (void *) pdev)
- != A_OK))
- {
- goto fail;
- }
-
- pdev->cfg.flags.sw_tx_encap = ol_cfg_tx_encap(pdev->ctrl_pdev);
- /*
- * For Riva, don't use HW frame translation.
- * NOTE: for Pronto and Northstar we'll want to enable HW frame
- * translation for certain cases.
- * In particular, if the input frame format is 802.3, we'll enable
- * the HW's frame translation, but if the input frame format is
- * native WiFi (basic 802.11), we'll disable HW frame translation,
- * and rely on SW to add a QoS control field when appropriate.
- */
- pdev->cfg.flags.do_frame_translate = 0; // FOR NOW
-
- /* initialize the txrx credit count */
- /*
- * FOR NOW, consider only the space in the LOW_PRI ring.
- * We eventually want to manage the credit such that we can avoid
- * overflowing the target and thus stalling the DXE download ring.
- * Once this is done, then we don't need separate LOW_PRI vs. HIGH_PRI
- * channels, since there will be a negligible delay to download data
- * through the single channel, since it will never stall.
- */
- tx_credit = hif_dxe_get_resources(
- pdev->hif_dxe_pdev, HIFDXE_CHANNEL_TX_LOW_PRI);
- ol_tx_target_credit_update(pdev->txrx_pdev, tx_credit);
-
- return pdev;
-
-fail:
- htt_dxe_detach(pdev);
- return NULL;
-}
-
-A_STATUS
-htt_dxe_attach_target(htt_pdev_handle pdev)
-{
- A_STATUS status;
- status = hif_dxe_start(pdev->hif_dxe_pdev);
- return status;
-}
-
-void
-htt_dxe_vdev_attach(
- htt_pdev_handle pdev,
- u_int8_t vdev_id,
- enum htt_op_mode op_mode)
-{
- pdev->vdevs[vdev_id].valid = 1;
- pdev->vdevs[vdev_id].op_mode = op_mode;
-}
-
-
-void
-htt_vdev_detach(htt_pdev_handle pdev, u_int8_t vdev_id)
-{
- pdev->vdevs[vdev_id].valid = 0;
-}
-
-void htt_dxe_peer_qos_update(
- struct htt_dxe_pdev_t *pdev, int peer_id, u_int8_t qos_capable)
-{
- struct htt_dxe_peer_t *peer;
-
- HTT_DXE_ASSERT3(peer_id <= ol_cfg_max_peer_id(pdev->ctrl_pdev));
- peer = &pdev->peers[peer_id];
- HTT_DXE_ASSERT2(peer->valid);
- peer->qos_capable = qos_capable;
-}
-
-void htt_dxe_peer_uapsdmask_update(
- struct htt_dxe_pdev_t *pdev, int peer_id, u_int8_t uapsd_mask)
-{
- /* TO be implemented */
- return;
-}
-
-void
-htt_dxe_detach(htt_pdev_handle pdev)
-{
- htt_dxe_rx_detach(pdev);
- htt_dxe_tx_detach(pdev);
- if (pdev->dmux_dxe_pdev) {
- dmux_dxe_detach(pdev->dmux_dxe_pdev);
- }
- if (pdev->hif_dxe_pdev) {
- hif_dxe_detach(pdev->hif_dxe_pdev);
- }
- if (pdev->tx_mutex_valid) {
- adf_os_spinlock_destroy(&pdev->tx_mutex);
- }
- if (pdev->peers) {
- adf_os_mem_free(pdev->peers);
- }
- if (pdev->vdevs) {
- adf_os_mem_free(pdev->vdevs);
- }
- /*
- * Zero out the pdev object before freeing it.
- * This will make it more obvious if anyone tries to use it
- * after it has been freed.
- */
- adf_os_mem_zero(pdev, sizeof(*pdev));
- adf_os_mem_free(pdev);
-}
-
-void
-htt_dxe_detach_target(htt_pdev_handle pdev)
-{
- /* FILL HERE */
- return;
-}
-
-static void
-htt_dxe_vdev_display(
- struct htt_dxe_pdev_t *pdev,
- int vdev_id,
- int indent)
-{
- struct htt_dxe_vdev_t *vdev = &pdev->vdevs[vdev_id];
- adf_os_print(
- "%*sID: %d, op mode: %s, self-peer ID: %d, bcast peer ID: %d\n",
- indent, " ",
- vdev_id,
- (vdev->op_mode == htt_op_mode_ap) ? "AP" :
- (vdev->op_mode == htt_op_mode_sta) ? "STA" :
- (vdev->op_mode == htt_op_mode_ibss) ? "IBSS" :
- "other",
- vdev->self_peer_id, vdev->bcast_peer_id);
-}
-
-static void
-htt_dxe_peer_display(
- struct htt_dxe_pdev_t *pdev,
- int peer_id,
- int indent)
-{
- struct htt_dxe_peer_t *peer = &pdev->peers[peer_id];
- adf_os_print(
- "%*sID: %d, type: %s, QoS capable: %d, robust mgmt: %d\n",
- indent, " ",
- peer_id,
- (peer->type == HTT_ISOC_T2H_PEER_TYPE_ASSOC) ? "real peer" :
- (peer->type == HTT_ISOC_T2H_PEER_TYPE_SELF) ? "self peer" :
- (peer->type == HTT_ISOC_T2H_PEER_TYPE_BCAST) ? "bcast peer" :
- "(other)",
- peer->qos_capable,
- peer->robust_mgmt);
-}
-
-void
-htt_dxe_display(htt_pdev_handle pdev, int indent)
-{
- int i;
- struct htt_dxe_tx_desc_t *sw_desc;
- char *vaddr;
- u_int32_t paddr;
-
- adf_os_print(
- "HTT tx descs: %d bytes each (HW desc), %d total, %d allocated\n",
- pdev->tx_descs.size,
- pdev->tx_descs.pool_elems,
- pdev->tx_descs.alloc_cnt);
- sw_desc = pdev->tx_descs.sw_descs_pool;
- vaddr = pdev->tx_descs.tx_bds.pool_vaddr;
- paddr = pdev->tx_descs.tx_bds.pool_paddr;
- for (i = 0; i < pdev->tx_descs.pool_elems; i++) {
- if (pdev->tx_descs.pool_elems > 10) {
- if (i == 4) {
- adf_os_print(" ...\n");
- }
- if (i >= 4 && i < pdev->tx_descs.pool_elems - 4) {
- continue;
- }
- }
- adf_os_print(" %d: sw desc = %p, hw desc vaddr = %p, paddr = %#x\n",
- i, sw_desc, vaddr, paddr);
- sw_desc++;
- vaddr += pdev->tx_descs.size;
- paddr += pdev->tx_descs.size;
- }
- adf_os_print("HTT vdevs:\n");
- for (i = 0; i < ol_cfg_max_vdevs(pdev->ctrl_pdev); i++) {
- if (pdev->vdevs[i].valid) {
- htt_dxe_vdev_display(pdev, i, indent+4);
- }
- }
- adf_os_print("HTT peers:\n");
- for (i = 0; i <= ol_cfg_max_peer_id(pdev->ctrl_pdev); i++) {
- if (pdev->peers[i].valid) {
- htt_dxe_peer_display(pdev, i, indent+4);
- }
- }
-}
diff --git a/CORE/DXE/htt_dxe_fw_stats.c b/CORE/DXE/htt_dxe_fw_stats.c
deleted file mode 100644
index ba642f2ce590..000000000000
--- a/CORE/DXE/htt_dxe_fw_stats.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
- *
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file was originally distributed by Qualcomm Atheros, Inc.
- * under proprietary terms before Copyright ownership was assigned
- * to the Linux Foundation.
- */
-
-/**
- * @file htt_fw_stats.c
- * @brief Provide functions to process FW status retrieved from FW.
- */
-
-#include <ol_htt_api.h>
-
-void
-htt_t2h_dbg_stats_hdr_parse(
- u_int8_t *stats_info_list,
- enum htt_dbg_stats_type *type,
- enum htt_dbg_stats_status *status,
- int *length,
- u_int8_t **stats_data)
-{
-}
-
-void
-htt_t2h_stats_print(u_int8_t *stats_data, int concise)
-{
-}
-
-
diff --git a/CORE/DXE/htt_dxe_h2t.c b/CORE/DXE/htt_dxe_h2t.c
deleted file mode 100644
index 217c74102022..000000000000
--- a/CORE/DXE/htt_dxe_h2t.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
- *
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file was originally distributed by Qualcomm Atheros, Inc.
- * under proprietary terms before Copyright ownership was assigned
- * to the Linux Foundation.
- */
-
-/**
- * @file htt_dxe_h2t.c
- * @brief Provide dummy functions for host->target HTT messages.
- * @details
- * For the Riva family of targets supported by this hif_dxe module,
- * no host->target HTT messages are required.
- * This file provides dummy versions of the HTT H2T message
- * construction functions called by txrx, just so the txrx code will
- * link successfully.
- */
-
-#include <adf_os_util.h>
-#include <ol_htt_api.h>
-
-int
-htt_h2t_dbg_stats_get(
- struct htt_pdev_t *pdev,
- u_int32_t stats_type_upload_mask,
- u_int32_t stats_type_reset_mask,
- u_int8_t cfg_stat_type,
- u_int32_t cfg_val,
- u_int64_t cookie)
-{
- adf_os_assert(0);
- return 0;
-}
-
-A_STATUS
-htt_h2t_sync_msg(struct htt_pdev_t *pdev, u_int8_t sync_cnt)
-{
- adf_os_assert(0);
- return A_OK;
-}
-
-#if defined(TEMP_AGGR_CFG)
-int
-htt_h2t_aggr_cfg_msg(struct htt_pdev_t *pdev,
- int max_subfrms_ampdu,
- int max_subfrms_amsdu)
-{
- adf_os_assert(0);
- return 0;
-}
-#endif
diff --git a/CORE/DXE/htt_dxe_internal.h b/CORE/DXE/htt_dxe_internal.h
deleted file mode 100644
index 7c048cc9604c..000000000000
--- a/CORE/DXE/htt_dxe_internal.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
- *
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file was originally distributed by Qualcomm Atheros, Inc.
- * under proprietary terms before Copyright ownership was assigned
- * to the Linux Foundation.
- */
-
-#ifndef _HTT_DXE_INTERNAL__H_
-#define _HTT_DXE_INTERNAL__H_
-
-#include <athdefs.h> /* A_STATUS */
-
-#include <adf_nbuf.h> /* adf_nbuf_t */
-
-#include <hif_dxe.h> /* E_HIFDXE_CHANNELTYPE */
-
-#include <htt_dxe_types.h>
-
-
-#define HTT_MAC_ADDR_LEN 6
-
-/*--- utilities ---*/
-
-#ifndef ARRAY_LEN
-#define ARRAY_LEN(x) (sizeof(x)/sizeof(x[0]))
-#endif
-
-
-#ifndef HTT_DXE_ASSERT_LEVEL
-#define HTT_DXE_ASSERT_LEVEL 3
-#endif
-
-#define HTT_DXE_ASSERT_ALWAYS(condition) adf_os_assert_always((condition))
-
-#define HTT_DXE_ASSERT0(condition) adf_os_assert((condition))
-#if HTT_DXE_ASSERT_LEVEL > 0
-#define HTT_DXE_ASSERT1(condition) adf_os_assert((condition))
-#else
-#define HTT_DXE_ASSERT1(condition)
-#endif
-
-#if HTT_DXE_ASSERT_LEVEL > 1
-#define HTT_DXE_ASSERT2(condition) adf_os_assert((condition))
-#else
-#define HTT_DXE_ASSERT2(condition)
-#endif
-
-#if HTT_DXE_ASSERT_LEVEL > 2
-#define HTT_DXE_ASSERT3(condition) adf_os_assert((condition))
-#else
-#define HTT_DXE_ASSERT3(condition)
-#endif
-
-/*--- aliases ---*/
-
-#define htt_dxe_tx_desc_alloc htt_tx_desc_alloc
-#define htt_dxe_tx_desc_free htt_tx_desc_free
-#define htt_dxe_tx_desc_display htt_tx_desc_display
-
-/*--- tx ---*/
-
-A_STATUS
-htt_dxe_tx_attach(struct htt_dxe_pdev_t *pdev, int desc_pool_elems);
-
-void
-htt_dxe_tx_detach(struct htt_pdev_t *pdev);
-
-A_STATUS
-htt_dxe_tx_download_done(
- void *context,
- adf_nbuf_t tx_list,
- E_HIFDXE_CHANNELTYPE chan,
- A_STATUS status);
-
-A_STATUS
-htt_dxe_tx_low_rsrc(
- void *context,
- E_HIFDXE_CHANNELTYPE chan,
- A_BOOL is_low_resource);
-
-/*--- rx ---*/
-
-A_STATUS
-htt_dxe_rx_attach(struct htt_pdev_t *pdev);
-
-void
-htt_dxe_rx_detach(struct htt_dxe_pdev_t *pdev);
-
-void
-htt_dxe_rx(void *context, adf_nbuf_t rx_msdus, E_HIFDXE_CHANNELTYPE chan);
-
-void
-htt_dxe_rx_ctrl(void *context, adf_nbuf_t rx_ctrl_msg);
-
-#if HTT_DXE_RX_LOG
-#define HTT_DXE_RX_REORDER_LOG_INIT htt_dxe_rx_reorder_log_init
-void htt_dxe_rx_reorder_log_init(struct htt_pdev_t *pdev);
-#define HTT_DXE_RX_REORDER_LOG_ADD htt_dxe_rx_reorder_log_add
-void
-htt_dxe_rx_reorder_log_add(
- struct htt_pdev_t *pdev,
- u_int16_t peer_id,
- u_int8_t tid,
- isoc_rx_bd_t *rx_bd);
-
-#else
-#define HTT_DXE_RX_REORDER_LOG_INIT(pdev) /* no-op */
-#define HTT_DXE_RX_REORDER_LOG_ADD(pdev, peer_id, tid, rx_bd) /* no-op */
-#endif /* HTT_DXE_RX_LOG */
-
-/*--- t2h ---*/
-
-void
-htt_dxe_t2h_msg_handler(void *context, adf_nbuf_t htt_t2h_msg);
-
-
-#endif /* _HTT_DXE_INTERNAL__H_ */
diff --git a/CORE/DXE/htt_dxe_rx.c b/CORE/DXE/htt_dxe_rx.c
deleted file mode 100644
index 98c670559f73..000000000000
--- a/CORE/DXE/htt_dxe_rx.c
+++ /dev/null
@@ -1,1126 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
- *
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file was originally distributed by Qualcomm Atheros, Inc.
- * under proprietary terms before Copyright ownership was assigned
- * to the Linux Foundation.
- */
-
-/**
- * @file htt_dxe_rx.c
- * @brief Implement receive aspects of HTT.
- * @details
- * This file contains three categories of HTT rx code:
- * 1. An abstraction of the rx descriptor
- * 2. Functions for providing access to the (series of)
- * rx descriptor(s) and rx frame(s) associated with
- * an rx indication message.
- * 3. Functions for receiving rx callbacks from the underlying
- * dmux_dxe and hif_dxe layers.
- */
-
-/* OS utility / primitive abstraction header files */
-#include <adf_os_mem.h> /* adf_os_mem_alloc,free, etc. */
-#include <adf_os_util.h> /* adf_os_assert */
-#include <adf_os_types.h> /* adf_os_print */
-#include <adf_nbuf.h> /* adf_nbuf_t, etc. */
-
-#include <athdefs.h> /* A_STATUS */
-#include <isoc_hw_desc.h> /* isoc_rx_bd_t, etc. */
-#include <ieee80211.h> /* IEEE80211_FC0_SUBTYPE_BAR, ieee80211_frame */
-#include <enet.h> /* ethernet_hdr_t */
-
-/* API header files to other modules called from this file */
-#include <dmux_dxe_api.h> /* dmux_dxe_attach, etc. */
-#include <htt_isoc.h> /* Rx BD format */
-#include <hif_dxe.h> /* E_HIFDXE_CHANNELTYPE */
-#include <ol_htt_rx_api.h> /* htt_rx_msdu_desc_free */
-#include <ol_txrx_htt_api.h> /* ol_rx_indication_handler */
-
-/* internal header files */
-#include <htt_dxe_types.h> /* htt_dxe_pdev_t, etc */
-#include <htt_dxe_internal.h> /* HTT_DXE_ASSERT */
-
-
-/*
- * If bit 0 of the first byte of the MAC address is set, then the address
- * is multicast or broadcast rather than unicast.
- */
-#define HTT_DXE_IS_MCAST_MAC_ADDR(mac_addr) ((*mac_addr) & 0x1)
-
-static int
-htt_dxe_reorder_opcode_is_flush(isoc_rx_opcode reorder_opcode);
-
-
-#if HTT_DXE_RX_LOG
-#define HTT_DXE_RX_PSEUDO_OPCODE_DELBA 99
-char *htt_dxe_rx_reorder_opcode_str(unsigned reorder_opcode)
-{
- switch (reorder_opcode) {
- case ISOC_RX_OPCODE_INVALID:
- return "invld";
- case ISOC_RX_OPCODE_QUEUECUR_FWDBUF:
- return "QC,FB";
- case ISOC_RX_OPCODE_FWDBUF_FWDCUR:
- return "FB,FC";
- case ISOC_RX_OPCODE_QUEUECUR:
- return " QC ";
- case ISOC_RX_OPCODE_FWDBUF_QUEUECUR:
- return "FB,QC";
- case ISOC_RX_OPCODE_FWDBUF_DROPCUR:
- return "FB,DC";
- case ISOC_RX_OPCODE_FWDALL_DROPCUR:
- return "FA,DC";
- case ISOC_RX_OPCODE_FWDALL_QUEUECUR:
- return "FA,QC";
- case ISOC_RX_OPCODE_TEARDOWN:
- return "trdwn";
- case ISOC_RX_OPCODE_DROPCUR:
- return " DC ";
- case HTT_DXE_RX_PSEUDO_OPCODE_DELBA:
- return "delba";
- default:
- return " n/a ";
- };
-}
-#endif /* HTT_DXE_RX_LOG */
-
-void
-htt_dxe_rx_frm_dump(adf_nbuf_t rx_msdu, int max)
-{
- u_int8_t *data;
- int i;
-
- if (adf_nbuf_len(rx_msdu) < max) {
- max = adf_nbuf_len(rx_msdu);
- }
- adf_os_print("rx frame contents (bytes 0-%d of %d):\n ",
- max - 1, (int) adf_nbuf_len(rx_msdu));
- data = adf_nbuf_data(rx_msdu);
- for (i = 1; max > 0; i++, max--) {
- adf_os_print("0x%02x ", *data++);
- if (i == 12) {
- i = 0;
- adf_os_print("\n ");
- }
- }
- adf_os_print("\n");
-}
-
-
-/*--- rx indication event functions -----------------------------------------*/
-
-static inline isoc_rx_bd_t *
-htt_dxe_rx_nbuf_prep(adf_nbuf_t rx_msdu)
-{
- isoc_rx_bd_t *rx_bd;
-
-
- /* the rx descriptor (Rx BD) is at the front of the rx network buffer */
- rx_bd = (isoc_rx_bd_t *) adf_nbuf_data(rx_msdu);
-
- /* FOR NOW, operate on the Rx BD in its original location.
- * TBD:
- * If the original location is uncacheable, make a copy in regular memory,
- * and operate on that copy?
- */
-
- /*
- * The dmux_dxe code already handled endianness conversion on the Rx BD;
- * no further endianness correction is needed.
- */
-
- /* set the length of the network buffer */
- adf_nbuf_put_tail(rx_msdu, rx_bd->mpdu_header_offset + rx_bd->mpdu_length);
-
- /* advance the data pointer to the L2 header (skip the Rx BD) */
- adf_nbuf_pull_head(rx_msdu, rx_bd->mpdu_header_offset);
-
- //isoc_rx_bd_dump(rx_bd);
- //htt_dxe_rx_frm_dump(rx_msdu, 64);
-
- return rx_bd;
-}
-
-void
-htt_dxe_rx_discard_pending(struct htt_pdev_t *pdev, int chan_idx)
-{
- adf_nbuf_t pending = pdev->rx.pending_amsdus[chan_idx].head;
- while (pending) {
- adf_nbuf_t next = adf_nbuf_next(pending);
- htt_rx_msdu_desc_free(pdev, pending);
- pending = next;
- }
- pdev->rx.pending_amsdus[chan_idx].head =
- pdev->rx.pending_amsdus[chan_idx].tail = NULL;
-}
-
-static inline void
-htt_dxe_rx_pending_append(
- struct htt_dxe_pdev_t *pdev,
- int chan_idx,
- adf_nbuf_t rx_msdu)
-{
- if (!pdev->rx.pending_amsdus[chan_idx].head) {
- pdev->rx.pending_amsdus[chan_idx].head = rx_msdu;
- } else {
- adf_nbuf_set_next(pdev->rx.pending_amsdus[chan_idx].tail, rx_msdu);
- }
- pdev->rx.pending_amsdus[chan_idx].tail = rx_msdu;
-}
-
-#if 1 /* for now, support 2 parallel rx data channels */
-#define HTT_DXE_RX_CHAN(chan) ((chan) == HIFDXE_CHANNEL_RX_LOW_PRI ? 0 : 1)
-#else
-#define HTT_DXE_RX_CHAN(chan) \
- 0; \
- adf_os_assert((chan) == HIFDXE_CHANNEL_RX_LOW_PRI)
-#endif
-
-void
-htt_dxe_rx(void *context, adf_nbuf_t rx_msdu, E_HIFDXE_CHANNELTYPE chan)
-{
- struct htt_pdev_t *pdev = (struct htt_pdev_t *) context;
- int chan_idx;
-
- chan_idx = HTT_DXE_RX_CHAN(chan);
-
- /* the delivery list should start empty and end up empty */
- adf_os_assert(pdev->rx.delivery.head == NULL);
-
- while (rx_msdu) {
- u_int16_t peer_id;
- u_int8_t vdev_id;
- isoc_rx_bd_t *rx_bd;
- adf_nbuf_t next;
- struct htt_dxe_peer_t *peer;
- struct htt_dxe_vdev_t *vdev;
-
- next = adf_nbuf_next(rx_msdu);
- adf_nbuf_set_next(rx_msdu, NULL);
-
- rx_bd = htt_dxe_rx_nbuf_prep(rx_msdu);
-
- HTT_DXE_ASSERT2(
- rx_bd->reorder_opcode != ISOC_RX_OPCODE_TEARDOWN &&
- rx_bd->reorder_opcode != ISOC_RX_OPCODE_DROPCUR &&
- rx_bd->reorder_opcode != ISOC_RX_OPCODE_FWDBUF_DROPCUR &&
- rx_bd->reorder_opcode != ISOC_RX_OPCODE_FWDALL_DROPCUR);
-
- HTT_DXE_ASSERT2(!rx_bd->addr2_invalid);
- peer_id = rx_bd->addr2_index;
- peer = &pdev->peers[peer_id];
- vdev_id = peer->vdev_id;
- vdev = &pdev->vdevs[vdev_id];
-
- /*
- * STA: discard multicasts that are echoes of frames the STA sent.
- */
- if (vdev->op_mode == htt_op_mode_sta &&
- rx_bd->not_unicast &&
- rx_bd->addr3_index == vdev_id)
- {
- rx_bd->sw_flag_discard = 1;
- } else {
- rx_bd->sw_flag_discard = 0;
- }
-
- /*
- * If this is an AP and it has received a frame with a
- * multicast/broadcast destination address, then it needs to
- * transmit this received frame, so that it will be broadcast
- * throughout the BSS (the rx frame was unicast to the AP's RA).
- * This is referred to as "multicast echo".
- */
- if (vdev->op_mode == htt_op_mode_ap) {
- u_int8_t *dest_addr;
- u_int8_t *l2_hdr_ptr;
-
- l2_hdr_ptr = ((u_int8_t *) rx_bd) + rx_bd->mpdu_header_offset;
- if (rx_bd->frame_translate) {
- /* frame is in 802.3 format */
- dest_addr = ((struct ethernet_hdr_t *) l2_hdr_ptr)->dest_addr;
- } else {
- if ((!rx_bd->amsdu) || rx_bd->amsdu_first) {
- /*
- * initial MSDU of an A-MSDU is in 802.11 format;
- * for STA->AP, DA is addr3
- */
- dest_addr =
- ((struct ieee80211_frame *) l2_hdr_ptr)->i_addr3;
- } else {
- /* subsequent MSDUs of an A-MSU are in 802.3 format */
- dest_addr =
- ((struct ethernet_hdr_t *) l2_hdr_ptr)->dest_addr;
- }
- }
- rx_bd->sw_flag_forward =
- HTT_DXE_IS_MCAST_MAC_ADDR(dest_addr) ? 1 : 0;
- } else {
- rx_bd->sw_flag_forward = 0;
- }
-
- /* determine whether this MSDU completes a MPDU / A-MSDU */
- if (!rx_bd->amsdu) {
- /* there should be no old subframes in the pending list */
- if (pdev->rx.pending_amsdus[chan_idx].head) {
- adf_os_print(
- "Error: discarding incomplete A-MSDU "
- "that was followed by non-A-MSDU\n");
- htt_dxe_rx_discard_pending(pdev, chan_idx);
- }
- pdev->rx.delivery.head =
- pdev->rx.delivery.tail = rx_msdu;
- } else {
- /*
- * Sanity checks:
- * If this is the first subframe, then the pending list
- * should be empty.
- * If this is not the first subframe, the pending list
- * should not be empty.
- */
- if (rx_bd->amsdu_first) {
- if (pdev->rx.pending_amsdus[chan_idx].head) {
- adf_os_print(
- "Error: discarding incomplete A-MSDU "
- "that was followed by a new A-MSDU\n");
- htt_dxe_rx_discard_pending(pdev, chan_idx);
- }
- } else {
- if (!pdev->rx.pending_amsdus[chan_idx].head) {
- adf_os_print(
- "Error: discarding non-initial A-MSDU subframe "
- "which had no initial subframe\n");
- htt_rx_msdu_desc_free(pdev, rx_msdu);
- goto loop_end;
- }
- }
-
- htt_dxe_rx_pending_append(pdev, chan_idx, rx_msdu);
-
- if (rx_bd->amsdu_last) {
- /*
- * Move the complete MPDU from the pending location
- * to the delivery location.
- */
- pdev->rx.delivery.head = pdev->rx.pending_amsdus[chan_idx].head;
- pdev->rx.delivery.tail = pdev->rx.pending_amsdus[chan_idx].tail;
- pdev->rx.pending_amsdus[chan_idx].head =
- pdev->rx.pending_amsdus[chan_idx].tail = NULL;
- }
- }
- if (pdev->rx.delivery.head) {
- u_int8_t tid;
- /*
- * Send an rx indication for the completed A-MSDU to txrx.
- * Note that the txrx SW will issue several calls to htt_dxe
- * inside this function call.
- */
- rx_bd = (isoc_rx_bd_t *) adf_nbuf_head(pdev->rx.delivery.head);
-
- /*
- * The TA (transmitter address) specifies which peer sent
- * this data frame.
- * Since we only can receive data frames once we're
- * associated, the peer index based on the TA should always
- * be valid.
- */
- /*
- * There should never be a frame rx from an uninitialized
- * peer object. Do a sanity check that the peer object
- * has been initialized via a PEER_INFO message.
- */
- HTT_DXE_ASSERT2(pdev->peers[peer_id].valid);
-
- /* TID */
- if (rx_bd->frame_type_subtype & IEEE80211_FC0_SUBTYPE_QOS) {
- tid = rx_bd->tid;
- } else {
- tid = rx_bd->not_unicast ? OL_HTT_TID_NON_QOS_MCAST_BCAST :
- OL_HTT_TID_NON_QOS_UNICAST;
- }
- HTT_DXE_RX_REORDER_LOG_ADD(pdev, peer_id, tid, rx_bd);
-
- /* remember which rx ind is being handled */
- pdev->rx.cur.rx_bd = rx_bd;
- pdev->rx.cur.peer_id = peer_id;
- pdev->rx.cur.tid = tid;
- pdev->rx.cur.rx_aggr_enabled =
- ((pdev->peers[peer_id].rx_aggr_enabled_tids_bitmap >> tid) & 0x1);
-
- if (pdev->rx.cur.rx_aggr_enabled &&
- (rx_bd->reorder_opcode == ISOC_RX_OPCODE_INVALID))
- {
- adf_os_print(
- "Error: discarding frame "
- "with reorder_opcode = ISOC_RX_OPCODE_INVALID\n");
- HTT_DXE_ASSERT2(pdev->rx.cur.rx_aggr_enabled && rx_bd->reorder_opcode != ISOC_RX_OPCODE_INVALID);
- htt_rx_msdu_desc_free(pdev, rx_msdu);
- goto loop_end;
- }
-
- ol_rx_indication_handler(
- pdev->txrx_pdev, NULL, peer_id, tid, 1);
- }
-loop_end:
- rx_msdu = next;
- }
-}
-
-void
-htt_dxe_rx_ctrl(void *context, adf_nbuf_t rx_ctrl_msg)
-{
- struct htt_pdev_t *pdev = (struct htt_pdev_t *) context;
-
- /* we expect a single control frame at a time, but iterate just in case */
- while (rx_ctrl_msg) {
- isoc_rx_bd_t *rx_bd;
- adf_nbuf_t next;
- unsigned ctrl_bar_subtype;
- u_int16_t peer_id;
- unsigned idx_start, idx_end;
-
- /* the only control frames we expect are BAR */
- next = adf_nbuf_next(rx_ctrl_msg);
- adf_nbuf_set_next(rx_ctrl_msg, NULL);
-
- rx_bd = (isoc_rx_bd_t *) adf_nbuf_data(rx_ctrl_msg);
-
- if (rx_bd->reorder_opcode != ISOC_RX_OPCODE_FWDBUF_DROPCUR &&
- rx_bd->reorder_opcode != ISOC_RX_OPCODE_FWDALL_DROPCUR)
- {
- adf_os_print("Warning: unexpected rx reorder opcode (%d)",
- rx_bd->reorder_opcode);
- goto loop_end;
- }
-
- ctrl_bar_subtype = IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_BAR;
- if (rx_bd->frame_type_subtype != ctrl_bar_subtype) {
- adf_os_print("Warning: unexpected control frame (%#x)",
- rx_bd->frame_type_subtype);
- goto loop_end;
- }
-
- /*
- * Flush MPDUs queued in the rx reorder array which are not covered
- * by the repositioned block ack window.
- */
- peer_id = rx_bd->addr2_index;
- idx_start = 0xffff; /* start from where the last release left off */
- idx_end = (rx_bd->reorder_opcode == ISOC_RX_OPCODE_FWDBUF_DROPCUR) ?
- rx_bd->reorder_fwd_idx : /* flush only to the specified index */
- 0xffff; /* flush entire reorder array */
-
- HTT_DXE_RX_REORDER_LOG_ADD(pdev, peer_id, rx_bd->tid, rx_bd);
-
- ol_rx_flush_handler(
- pdev->txrx_pdev, peer_id, rx_bd->tid,
- idx_start, idx_end, htt_rx_flush_release);
-
-loop_end:
- htt_rx_desc_frame_free(pdev, rx_ctrl_msg);
- rx_ctrl_msg = next;
- }
-}
-
-/*--- rx indication info functions ------------------------------------------*/
-
-static int
-htt_dxe_reorder_opcode_is_flush(isoc_rx_opcode reorder_opcode)
-{
- switch (reorder_opcode)
- {
- case ISOC_RX_OPCODE_QUEUECUR_FWDBUF:
- case ISOC_RX_OPCODE_QUEUECUR:
- return 0;
- case ISOC_RX_OPCODE_FWDBUF_FWDCUR:
- case ISOC_RX_OPCODE_FWDBUF_QUEUECUR:
- case ISOC_RX_OPCODE_FWDBUF_DROPCUR:
- case ISOC_RX_OPCODE_FWDALL_DROPCUR:
- case ISOC_RX_OPCODE_FWDALL_QUEUECUR:
- return 1;
- default:
- adf_os_print(
- "Warning: %s unexpected opcode (%d)\n", __func__, reorder_opcode);
- return 0;
- };
-}
-
-static int
-htt_dxe_reorder_opcode_is_release(isoc_rx_opcode reorder_opcode)
-{
- switch (reorder_opcode)
- {
- case ISOC_RX_OPCODE_QUEUECUR_FWDBUF:
- case ISOC_RX_OPCODE_FWDBUF_FWDCUR:
- return 1;
- case ISOC_RX_OPCODE_FWDBUF_QUEUECUR:
- case ISOC_RX_OPCODE_QUEUECUR:
- case ISOC_RX_OPCODE_FWDBUF_DROPCUR:
- case ISOC_RX_OPCODE_FWDALL_DROPCUR:
- case ISOC_RX_OPCODE_FWDALL_QUEUECUR:
- return 0;
- default:
- adf_os_print(
- "Warning: %s unexpected opcode (%d)\n", __func__, reorder_opcode);
- return 0;
-
- };
-}
-
-int
-htt_rx_ind_flush(struct htt_pdev_t *pdev, adf_nbuf_t rx_ind_msg)
-{
- /* check whether the current peer-TID has aggregation enabled */
- if (!pdev->rx.cur.rx_aggr_enabled) {
- return 0; /* flush doesn't apply unless aggregation is enabled */
- }
-
- /*
- * The rx opcode specifies whether to flush old MPDUs before processing
- * new ones.
- */
- return htt_dxe_reorder_opcode_is_flush(pdev->rx.cur.rx_bd->reorder_opcode);
-}
-
-void
-htt_rx_ind_flush_seq_num_range(
- struct htt_pdev_t *pdev,
- adf_nbuf_t rx_ind_msg,
- unsigned *seq_num_start,
- unsigned *seq_num_end)
-{
- isoc_rx_opcode reorder_opcode = pdev->rx.cur.rx_bd->reorder_opcode;
-
- /* see if the opcode specifies to release all the queued MPDUs */
- if (/* reorder_opcode == ISOC_RX_OPCODE_FWDALL_DROPCUR || */ // n/a - BAR
- reorder_opcode == ISOC_RX_OPCODE_FWDALL_QUEUECUR) {
- *seq_num_start = 0xffff;
- *seq_num_end = 0xffff;
- return;
- }
-
- /* the range to flush is specified by the reorder_fwd_idx */
- *seq_num_start = 0xffff; /* start from the last-released sequence number */
- *seq_num_end = pdev->rx.cur.rx_bd->reorder_fwd_idx;
-}
-
-int
-htt_rx_ind_release(struct htt_pdev_t *pdev, adf_nbuf_t rx_ind_msg)
-{
- /* check whether the current peer-TID has aggregation enabled */
- if (!pdev->rx.cur.rx_aggr_enabled) {
- return 1; /* release always applies if aggregation is not enabled */
- }
-
- /* the rx opcode specifies whether to release queued MPDUs */
- return
- htt_dxe_reorder_opcode_is_release(pdev->rx.cur.rx_bd->reorder_opcode);
-}
-
-void
-htt_rx_ind_release_seq_num_range(
- struct htt_pdev_t *pdev,
- adf_nbuf_t rx_ind_msg,
- unsigned *seq_num_start,
- unsigned *seq_num_end)
-{
- if (!pdev->rx.cur.rx_aggr_enabled) {
- /*
- * For non-aggregation, rx reorder array has a single element, so
- * the sequence number range is not relevant.
- * Just for clarity, return a well-defined value (0).
- */
- *seq_num_start = 0;
- *seq_num_end = 1;
- return;
- }
-
- /* release up to (but not including) the reorder_fwd_idx */
- *seq_num_start = 0xffff; /* start from the last-released sequence number */
- *seq_num_end = pdev->rx.cur.rx_bd->reorder_fwd_idx;
-}
-
-void
-htt_rx_ind_mpdu_range_info(
- struct htt_pdev_t *pdev,
- adf_nbuf_t rx_ind_msg,
- int mpdu_range_num,
- enum htt_rx_status *status,
- int *mpdu_count)
-{
- *mpdu_count = 1; /* htt_dxe_rx delivers one MPDU at a time */
- *status = htt_rx_status_ok; /* error frames are filtered out by HW */
-}
-
-int16_t
-htt_rx_ind_rssi_dbm(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg)
-{
- /*
- * The RSSIs only come from the rx descriptors (Rx BDs).
- * Return an invalid value to show that there is no separate
- * RSSI provided as a field in the HTT T2H RX_IND message.
- */
- return HTT_RSSI_INVALID;
-}
-
-/*--- rx descriptor field access functions ----------------------------------*/
-/*
- * These functions need to use bit masks and shifts to extract fields
- * from the rx descriptors, rather than directly using the bitfields.
- * For example, use
- * (desc & FIELD_MASK) >> FIELD_LSB
- * rather than
- * desc.field
- * This allows the functions to work correctly on either little-endian
- * machines (no endianness conversion needed) or big-endian machines
- * (endianness conversion provided automatically by the HW DMA's
- * byte-swizzling).
- */
-u_int16_t
-(*htt_rx_mpdu_desc_seq_num)(htt_pdev_handle pdev, void *mpdu_desc);
-u_int16_t
-_htt_rx_mpdu_desc_seq_num(htt_pdev_handle pdev, void *mpdu_desc)
-{
- isoc_rx_bd_t *rx_bd = mpdu_desc;
- return (u_int16_t)rx_bd->current_pkt_seqno;
-}
-
-int
-htt_rx_mpdu_desc_reorder_idx(htt_pdev_handle pdev, void *mpdu_desc)
-{
- isoc_rx_bd_t *rx_bd;
-
- if (!pdev->rx.cur.rx_aggr_enabled) {
- /* no aggregation - rx reorder array only has a single element (0) */
- return 0;
- }
- rx_bd = mpdu_desc;
- return rx_bd->reorder_slot_idx;
-}
-
-void
-(*htt_rx_mpdu_desc_pn)(
- htt_pdev_handle pdev,
- void *mpdu_desc,
- union htt_rx_pn_t *pn,
- int pn_len_bits);
-void
-_htt_rx_mpdu_desc_pn(
- htt_pdev_handle pdev,
- void *mpdu_desc,
- union htt_rx_pn_t *pn,
- int pn_len_bits)
-{
- isoc_rx_bd_t *rx_bd = mpdu_desc;
- u_int32_t iv32;
- u_int16_t iv16;
-
- switch (pn_len_bits) {
- case 24:
- adf_os_print(
- "Error: PN length (%d bits) not implemented\n", pn_len_bits);
- pn->pn24 = 0;
- adf_os_assert(0);
- break;
- case 48:
- /*
- * 48-bit replay counter is created as follows
- * from RX BD 6 byte PMI command:
- * Addr : AES/TKIP
- * 0x38 : pn3/tsc3
- * 0x39 : pn2/tsc2
- * 0x3a : pn1/tsc1
- * 0x3b : pn0/tsc0
- *
- * 0x3c : pn5/tsc5
- * 0x3d : pn4/tsc4
- */
- iv32 = rx_bd->pmi_cmd4to23[4]; /* PN0-3 */
- iv16 = rx_bd->pmi_cmd24to25; /* PN4-5 */
- pn->pn48 = (((u_int64_t)iv16) << 32) | iv32;
- break;
-
- case 128:
- adf_os_print(
- "Error: PN length (%d bits) not implemented\n", pn_len_bits);
- pn->pn128[0] = 0;
- pn->pn128[1] = 0;
- adf_os_assert(0);
- break;
- default:
- adf_os_print(
- "Error: invalid length spec (%d bits) for PN\n", pn_len_bits);
- };
-}
-
-u_int32_t
-htt_rx_mpdu_desc_tsf32(
- htt_pdev_handle pdev,
- void *mpdu_desc)
-{
- isoc_rx_bd_t *rx_bd = mpdu_desc;
- return rx_bd->rx_timestamp;
-}
-
-a_bool_t
-(*htt_rx_msdu_desc_completes_mpdu)(htt_pdev_handle pdev, void *msdu_desc);
-a_bool_t
-_htt_rx_msdu_desc_completes_mpdu(htt_pdev_handle pdev, void *msdu_desc)
-{
- isoc_rx_bd_t *rx_bd = msdu_desc;
-
- if (!rx_bd->amsdu) {
- return A_TRUE;
- } else {
- return rx_bd->amsdu_last ? A_TRUE : A_FALSE;
- }
-}
-
-a_bool_t
-(*htt_rx_mpdu_is_encrypted)(htt_pdev_handle pdev, void *mpdu_desc);
-a_bool_t
-_htt_rx_mpdu_is_encrypted(htt_pdev_handle pdev, void *msdu_desc)
-{
- isoc_rx_bd_t *rx_bd = msdu_desc;
- /* FIXME: Does this flag mean that this RX packet is a encrypted pakcet */
- return rx_bd->dpu_no_encrypt ? A_FALSE : A_TRUE;
-}
-
-a_bool_t
-(*htt_rx_msdu_first_msdu_flag)(htt_pdev_handle pdev, void *msdu_desc);
-a_bool_t
-_htt_rx_msdu_first_msdu_flag(htt_pdev_handle pdev, void *msdu_desc)
-{
- isoc_rx_bd_t *rx_bd = msdu_desc;
- return (a_bool_t)(rx_bd->amsdu_first); // This casts is safe only because
- // amsdu_first is one bit wide
- // and a_bool_t is only 0 or 1
-}
-
-#define HTT_DXE_RSSI_TO_DBM(rssi) rssi /* FIX THIS */
-int16_t
-htt_rx_mpdu_desc_rssi_dbm(htt_pdev_handle pdev, void *mpdu_desc)
-{
- isoc_rx_bd_t *rx_bd = mpdu_desc;
- u_int8_t rssi;
-
- /*
- * * Return the RSSI only for the first MPDU within an A-MPDU, and the
- * * first MSDU within an A-MSDU.
- * */
- if ((rx_bd->rxp_flags_ampdu_flag && ! rx_bd->rxp_flags_first_mpdu) ||
- (rx_bd->amsdu && ! rx_bd->amsdu_first))
- {
- /* not the initial subframe */
- return HTT_RSSI_INVALID;
- }
- /* CHECK THIS - choose whether to use rssi0, rssi1, rssi2, or rssi3 */
- rssi = rx_bd->rssi0;
- if (rssi < rx_bd->rssi1) {
- rssi = rx_bd->rssi1;
- }
- if (rssi < rx_bd->rssi2) {
- rssi = rx_bd->rssi2;
- }
- if (rssi < rx_bd->rssi3) {
- rssi = rx_bd->rssi3;
- }
-
- return HTT_DXE_RSSI_TO_DBM(rssi);
-}
-
-int
-(*htt_rx_msdu_has_wlan_mcast_flag)(htt_pdev_handle pdev, void *msdu_desc);
-int
-_htt_rx_msdu_has_wlan_mcast_flag(htt_pdev_handle pdev, void *msdu_desc)
-{
- isoc_rx_bd_t *rx_bd = msdu_desc;
- /*
- * If this is a standalone MPDU or the initial subframe of an A-MSDU,
- * the frame had a 802.11 MAC header, and based on the RA in the
- * 802.11 header the frame has a valid specification of WLAN multicast
- * vs. unicast.
- */
- return (!rx_bd->amsdu) || (rx_bd->amsdu_first);
-}
-
-a_bool_t
-(*htt_rx_msdu_is_wlan_mcast)(htt_pdev_handle pdev, void *msdu_desc);
-a_bool_t
-_htt_rx_msdu_is_wlan_mcast(htt_pdev_handle pdev, void *msdu_desc)
-{
- isoc_rx_bd_t *rx_bd = msdu_desc;
- return rx_bd->not_unicast ? A_TRUE : A_FALSE;
-}
-
-int
-(*htt_rx_msdu_is_frag)(htt_pdev_handle pdev, void *msdu_desc);
-int
-_htt_rx_msdu_is_frag(htt_pdev_handle pdev, void *msdu_desc)
-{
- return 0;
-}
-
-static inline int
-_htt_rx_msdu_discard(htt_pdev_handle pdev, void *msdu_desc)
-{
- /* check if this frame was flagged as a multicast echo - if so, discard */
- isoc_rx_bd_t *rx_bd = msdu_desc;
- return rx_bd->sw_flag_discard;
-}
-
-int
-htt_rx_msdu_discard(htt_pdev_handle pdev, void *msdu_desc)
-{
- return _htt_rx_msdu_discard(pdev, msdu_desc);
-}
-
-int
-_htt_rx_msdu_forward(htt_pdev_handle pdev, void *msdu_desc)
-{
- /*
- * Check if this frame was flagged for forwarding, due to:
- * 1. AP echo of multicast frames, i.e. transmission of unicast
- * rx frames that carry a multicast DA
- * 2. STA to STA forwarding within an AP (NOT CURRENTLY SUPPORTED)
- */
- isoc_rx_bd_t *rx_bd = msdu_desc;
- return rx_bd->sw_flag_forward;
-}
-
-int
-htt_rx_msdu_forward(htt_pdev_handle pdev, void *msdu_desc)
-{
- return _htt_rx_msdu_forward(pdev, msdu_desc);
-}
-
-int
-htt_rx_msdu_inspect(htt_pdev_handle pdev, void *msdu_desc)
-{
-/* FIX THIS (probably okay as is) */
- return 0;
-}
-
-void
-htt_rx_msdu_actions(
- htt_pdev_handle pdev,
- void *msdu_desc,
- int *discard,
- int *forward,
- int *inspect)
-{
- *discard = _htt_rx_msdu_discard(pdev, msdu_desc);
- *forward = _htt_rx_msdu_forward(pdev, msdu_desc);
-/* FIX THIS (probably okay as is) */
- *inspect = 0;
-}
-
-int
-(*htt_rx_amsdu_pop)(
- htt_pdev_handle pdev,
- adf_nbuf_t rx_ind_msg,
- adf_nbuf_t *head_msdu,
- adf_nbuf_t *tail_msdu);
-int
-_htt_rx_amsdu_pop(
- htt_pdev_handle pdev,
- adf_nbuf_t rx_ind_msg,
- adf_nbuf_t *head_msdu,
- adf_nbuf_t *tail_msdu)
-{
- *head_msdu = pdev->rx.delivery.head;
- *tail_msdu = pdev->rx.delivery.tail;
- return 0;
-}
-
-int
-(*htt_rx_offload_msdu_pop)(
- htt_pdev_handle pdev,
- adf_nbuf_t offload_deliver_msg,
- int *vdev_id,
- int *peer_id,
- int *tid,
- u_int8_t *fw_desc,
- adf_nbuf_t *head_buf,
- adf_nbuf_t *tail_buf);
-
-int
-_htt_rx_offload_msdu_pop(
- htt_pdev_handle pdev,
- adf_nbuf_t offload_deliver_msg,
- int *vdev_id,
- int *peer_id,
- int *tid,
- u_int8_t *fw_desc,
- adf_nbuf_t *head_buf,
- adf_nbuf_t *tail_buf)
-{
- return 0;
-}
-
-
-void *
-(*htt_rx_mpdu_desc_list_next)(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg);
-void *
-_htt_rx_mpdu_desc_list_next(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg)
-{
- adf_nbuf_t rx_msdu;
-
- adf_os_assert(pdev->rx.delivery.head);
- rx_msdu = pdev->rx.delivery.head;
-
- /*
- * If this MPDU is an A-MSDU, then rx.delivery.head points to the
- * head of a linked-list of MSDUs comprising the A-MSDU.
- * Since htt_dxe_rx currently indicates one A-MSDU at a time,
- * there is no further MPDU chained on the rx.delivery list,
- * so just set rx.delivery to NULL.
- * If, for some reason htt_dxe_rx were changed to deliver multiple
- * MPDUs at a time, then this would need to be changed to walk the
- * list of MSDUs until the MSDU with rx_bd->amsdu_last is seen.
- */
- pdev->rx.delivery.head = NULL;
-
- /* the rx netbuf has the Rx BD in its headroom */
- return adf_nbuf_head(rx_msdu);
-}
-
-void *
-(*htt_rx_msdu_desc_retrieve)(htt_pdev_handle pdev, adf_nbuf_t msdu);
-void *
-_htt_rx_msdu_desc_retrieve(htt_pdev_handle pdev, adf_nbuf_t msdu)
-{
- /* the rx netbuf has the Rx BD in its headroom */
- return adf_nbuf_head(msdu);
-}
-
-void
-htt_rx_desc_frame_free(
- htt_pdev_handle htt_pdev,
- adf_nbuf_t msdu)
-{
- adf_nbuf_free(msdu);
-}
-
-void
-htt_rx_msdu_desc_free(htt_pdev_handle htt_pdev, adf_nbuf_t msdu)
-{
-}
-
-void
-htt_rx_msdu_buff_replenish(htt_pdev_handle pdev)
-{
-}
-
-void
-htt_rx_get_vowext_stats(adf_nbuf_t msdu, struct vow_extstats *vowstats)
-{
- /* FIXME: Need to set vowstats correctly */
-}
-
-u_int16_t
-htt_rx_msdu_rx_desc_size_hl(
- htt_pdev_handle pdev,
- void *msdu_desc)
-{
-/* HACK WORKAROUND
- * The HL TXRX SW assumes the rx desc is present at adf_nbuf_data.
- * Until that is fixed, pretend that the descriptor is zero size,
- * so the call to adf_nbuf_pull_head in ol_rx_deliver will have no
- * effect.
- */
-return 0;
-}
-
-adf_nbuf_t
-htt_rx_restitch_mpdu_from_msdus(
- htt_pdev_handle pdev,
- adf_nbuf_t head_msdu,
- struct ieee80211_rx_status *rx_status,
- unsigned clone_not_reqd)
-{
- adf_os_assert(0);
- return NULL;
-}
-
-/*--- setup / tear-down functions -------------------------------------------*/
-
-A_STATUS
-htt_dxe_rx_attach(struct htt_pdev_t *pdev)
-{
- htt_rx_mpdu_desc_seq_num = _htt_rx_mpdu_desc_seq_num;
- htt_rx_msdu_desc_completes_mpdu = _htt_rx_msdu_desc_completes_mpdu;
- htt_rx_msdu_has_wlan_mcast_flag = _htt_rx_msdu_has_wlan_mcast_flag;
- htt_rx_msdu_is_wlan_mcast = _htt_rx_msdu_is_wlan_mcast;
- htt_rx_mpdu_desc_pn = _htt_rx_mpdu_desc_pn;
- htt_rx_amsdu_pop = _htt_rx_amsdu_pop;
- htt_rx_offload_msdu_pop = _htt_rx_offload_msdu_pop;
- htt_rx_mpdu_desc_list_next = _htt_rx_mpdu_desc_list_next;
- htt_rx_msdu_desc_retrieve = _htt_rx_msdu_desc_retrieve;
- htt_rx_msdu_is_frag = _htt_rx_msdu_is_frag;
- htt_rx_mpdu_is_encrypted = _htt_rx_mpdu_is_encrypted;
- htt_rx_msdu_first_msdu_flag = _htt_rx_msdu_first_msdu_flag;
-
- HTT_DXE_RX_REORDER_LOG_INIT(pdev);
-
- /* The pdev object was already set to zero in htt_dxe_attach,
- * so the following explicit inits of pdev->rx fields are not needed.
- * pdev->rx.delivery.head = NULL;
- * pdev->rx.delivery.tail = NULL;
- * adf_os_mem_zero(
- * &pdev->rx.pending_amsdus[0], sizeof(pdev->rx.pending_amsdus));
- */
-
- return A_OK;
-}
-
-void
-htt_dxe_rx_detach(struct htt_dxe_pdev_t *pdev)
-{
-}
-
-
-char *
-htt_rx_mpdu_wifi_hdr_retrieve(htt_pdev_handle pdev, void *mpdu_desc)
-{
- //ToDO: Need to fix this function
- adf_os_print(
- "Error: %s is not implemented\n", __FUNCTION__);
- return NULL;
-}
-
-/*--- debug functions -------------------------------------------------------*/
-
-#if HTT_DXE_RX_LOG
-
-void
-htt_dxe_rx_reorder_log_init(struct htt_pdev_t *pdev)
-{
- pdev->reorder_log.idx = 0;
- pdev->reorder_log.wrap = 1; /* ?? */
- pdev->reorder_log.wrapped = 0;
- pdev->reorder_log.enable = 1;
-}
-
-void
-htt_dxe_rx_reorder_log_add(
- struct htt_pdev_t *pdev,
- u_int16_t peer_id,
- u_int8_t tid,
- isoc_rx_bd_t *rx_bd)
-{
- struct htt_dxe_rx_log_elem_t *log_elem;
-
- if (!pdev->reorder_log.enable ||
- pdev->reorder_log.idx >= HTT_DXE_RX_LOG_LEN)
- {
- return;
- }
- log_elem = &pdev->reorder_log.data[pdev->reorder_log.idx];
-
- log_elem->peer_id = peer_id;
- log_elem->tid = tid;
-
- if (rx_bd) { /* rx frame */
- log_elem->seq_num = rx_bd->current_pkt_seqno;
- log_elem->reorder_opcode = rx_bd->reorder_opcode;
- log_elem->slot_idx = rx_bd->reorder_slot_idx;
- log_elem->fwd_idx = rx_bd->reorder_fwd_idx;
- } else { /* DELBA message */
- log_elem->seq_num = -1;
- log_elem->reorder_opcode = HTT_DXE_RX_PSEUDO_OPCODE_DELBA;
- log_elem->slot_idx = -1;
- log_elem->fwd_idx = -1;
- }
-
- pdev->reorder_log.idx++;
- if (pdev->reorder_log.idx == HTT_DXE_RX_LOG_LEN && pdev->reorder_log.wrap) {
- pdev->reorder_log.idx = 0;
- pdev->reorder_log.wrapped = 1;
- }
-}
-
-#define htt_dxe_rx_reorder_log_print htt_rx_reorder_log_print
-void
-htt_dxe_rx_reorder_log_print(struct htt_pdev_t *pdev)
-{
- int num, idx;
-
- if (pdev->reorder_log.wrapped) {
- idx = pdev->reorder_log.idx;
- num = HTT_DXE_RX_LOG_LEN;
- } else {
- idx = 0;
- num = pdev->reorder_log.idx;
- }
-
- if (num > 0) {
- adf_os_print(
- "htt_dxe_rx reorder log:\n"
- " "
- "peer | | seq | | slot | fwd | flush | release |\n"
- " "
- " id | TID | num | opcode | idx | idx | y? | to | y? | to |\n"
- " "
- "-------------------------------------------------------------\n");
- }
- while (num-- > 0) {
- int is_flush, is_rel, seq_num;
- unsigned reorder_opcode;
- struct htt_dxe_rx_log_elem_t *log_elem;
-
- log_elem = &pdev->reorder_log.data[idx];
-
- seq_num = log_elem->seq_num;
- reorder_opcode = log_elem->reorder_opcode;
- if (reorder_opcode == HTT_DXE_RX_PSEUDO_OPCODE_DELBA) {
- is_flush = 1;
- is_rel = 0;
- } else {
- is_flush = htt_dxe_reorder_opcode_is_flush(reorder_opcode);
- is_rel = htt_dxe_reorder_opcode_is_release(reorder_opcode);
- }
- if (reorder_opcode == ISOC_RX_OPCODE_FWDBUF_DROPCUR ||
- reorder_opcode == ISOC_RX_OPCODE_FWDALL_DROPCUR)
- {
- seq_num = -1;
- }
- adf_os_print(
- " %3d | %2d | %4d | %s | %2d | %2d |"
- " %s | %2d | %s | %2d |\n",
- log_elem->peer_id,
- log_elem->tid,
- seq_num,
- htt_dxe_rx_reorder_opcode_str(reorder_opcode),
- log_elem->slot_idx,
- log_elem->fwd_idx,
- is_flush ? "Y" : "n",
- is_flush ? log_elem->fwd_idx : -1,
- is_rel ? "Y" : "n",
- is_rel ? log_elem->fwd_idx : -1);
- idx++;
- idx &= HTT_DXE_RX_LOG_LEN_MASK;
- }
-}
-
-#endif /* HTT_DXE_RX_LOG */
diff --git a/CORE/DXE/htt_dxe_t2h.c b/CORE/DXE/htt_dxe_t2h.c
deleted file mode 100644
index af67595bf0a9..000000000000
--- a/CORE/DXE/htt_dxe_t2h.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
- *
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file was originally distributed by Qualcomm Atheros, Inc.
- * under proprietary terms before Copyright ownership was assigned
- * to the Linux Foundation.
- */
-
-/**
- * @file htt_dxe_t2h.c
- * @brief Provide functions to process target->host HTT messages.
- * @details
- * This file contains functions related to target->host HTT messages.
- * There are two categories of functions:
- * 1. A function that receives a HTT message from HTC, and dispatches it
- * based on the HTT message type.
- * 2. functions that provide the info elements from specific HTT messages.
- */
-
-#include <htt_isoc.h> /* HTT_ISOC_T2H_MSG_TYPE, etc. */
-#include <adf_os_util.h> /* adf_os_assert */
-#include <adf_nbuf.h> /* adf_nbuf_t */
-
-#include <ol_htt_rx_api.h>
-#include <ol_txrx_htt_api.h> /* htt_tx_status */
-
-#include <ol_cfg.h> /* ol_cfg_max_peer_id */
-
-/* internal header files */
-#include <htt_dxe_types.h>
-#include <htt_dxe_internal.h>
-
-
-/*
- * The HTT_T2H message payload will arrive at the host in big-endian order.
- *
- * Firmware - creates HTT_T2H message in little-endian order.
- * DXE - byteswap while copying. HTT_T2H message now in big-endian order.
- */
-#ifdef BIG_ENDIAN_HOST
-/* big-endian - bytes are naturally in the correct order, no swap needed */
-#define HTT_DXE_T2H_MSG_BYTESWAP(msg, bytes) /* no-op */
-#else
-/* little-endian - byte swap */
-static inline void
-HTT_DXE_T2H_MSG_BYTESWAP(u_int8_t *msg, int bytes)
-{
- isoc_hw_bd_swap_bytes32((char *) msg, bytes);
-}
-#endif /* BIG_ENDIAN_HOST */
-
-
-static u_int8_t *
-htt_t2h_mac_addr_deswizzle(u_int8_t *tgt_mac_addr, u_int8_t *buffer)
-{
-#ifdef BIG_ENDIAN_HOST
- /*
- * The host endianness is opposite of the target endianness.
- * To make u_int32_t elements come out correctly, the target->host
- * upload has swizzled the bytes in each u_int32_t element of the
- * message.
- * For byte-array message fields like the MAC address, this
- * upload swizzling puts the bytes in the wrong order, and needs
- * to be undone.
- */
- buffer[0] = tgt_mac_addr[3];
- buffer[1] = tgt_mac_addr[2];
- buffer[2] = tgt_mac_addr[1];
- buffer[3] = tgt_mac_addr[0];
- buffer[4] = tgt_mac_addr[7];
- buffer[5] = tgt_mac_addr[6];
- return buffer;
-#else
- /*
- * The host endianness matches the target endianness -
- * we can use the mac addr directly from the message buffer.
- */
- return tgt_mac_addr;
-#endif
-}
-
-void
-htt_dxe_t2h_msg_handler(void *context, adf_nbuf_t htt_t2h_msg)
-{
- struct htt_dxe_pdev_t *pdev = (struct htt_dxe_pdev_t *) context;
- enum htt_isoc_t2h_msg_type msg_type;
- isoc_rx_bd_t *rx_bd;
- u_int8_t *msg_addr;
-
- rx_bd = (isoc_rx_bd_t *)adf_nbuf_data(htt_t2h_msg);
- msg_addr = (u_int8_t *)rx_bd + rx_bd->mpdu_data_offset;
-
- /* confirm alignment */
- HTT_DXE_ASSERT3((((unsigned long) msg_addr) & 0x3) == 0);
-
- /* Convert HTT_T2H message from little-endian to host format */
- HTT_DXE_T2H_MSG_BYTESWAP(msg_addr, (rx_bd->mpdu_length + 3) & (~0x3));
-
- msg_type = HTT_ISOC_T2H_MSG_TYPE_GET(msg_addr);
-
- switch (msg_type) {
- case HTT_ISOC_T2H_MSG_TYPE_RX_ADDBA:
- {
- u_int16_t peer_id;
- u_int16_t start_seq_num, reorder_idx;
- u_int8_t tid;
- u_int8_t win_sz;
- u_int8_t status;
-
- peer_id = HTT_ISOC_T2H_ADDBA_PEER_ID_GET(msg_addr);
- tid = HTT_ISOC_T2H_ADDBA_TID_GET(msg_addr);
- start_seq_num = HTT_ISOC_T2H_ADDBA_START_SEQ_NUM_GET(msg_addr);
- win_sz = HTT_ISOC_T2H_ADDBA_WIN_SIZE_GET(msg_addr);
- status = HTT_ISOC_T2H_ADDBA_STATUS_GET(msg_addr);
-
- if (status == htt_isoc_addba_success) {
- /*
- * Remember which peer-TIDs are doing aggregation, to see
- * whether the aggregation-related parts of the Rx BD
- * (reorder_opcode, reorder_slot_idx, reorder_fwd_idx)
- * are valid.
- */
- pdev->peers[peer_id].rx_aggr_enabled_tids_bitmap |= (1 << tid);
- }
- reorder_idx = start_seq_num % win_sz;
- ol_rx_addba_handler(
- pdev->txrx_pdev, peer_id, tid, win_sz, reorder_idx,
- status != htt_isoc_addba_success);
- break;
- }
- case HTT_ISOC_T2H_MSG_TYPE_RX_DELBA:
- {
- u_int16_t peer_id;
- u_int8_t tid;
-
- peer_id = HTT_ISOC_T2H_DELBA_PEER_ID_GET(msg_addr);
- tid = HTT_ISOC_T2H_DELBA_TID_GET(msg_addr);
-
- pdev->peers[peer_id].rx_aggr_enabled_tids_bitmap &= ~(1 << tid);
-
- /*
- * Before deleting the rx reorder array, we need to
- * flush (i.e. release, not drop) any rx MPDUs that are
- * currently waiting in the rx reorder array for missing
- * prior MPDUs to arrive.
- * Now that the rx aggregation is terminated, the missing
- * MPDUs will not arrive, so any waiting MPDUs should be
- * released for the remaining steps of rx processing.
- */
- HTT_DXE_RX_REORDER_LOG_ADD(pdev, peer_id, tid, NULL);
- ol_rx_flush_handler(
- pdev->txrx_pdev, peer_id, tid,
- 0xffff, 0xffff, htt_rx_flush_release);
- ol_rx_delba_handler(pdev->txrx_pdev, peer_id, tid);
-
- break;
- }
- case HTT_ISOC_T2H_MSG_TYPE_PEER_INFO:
- {
- struct htt_dxe_peer_t *peer;
- u_int8_t mac_addr_deswizzle_buf[HTT_MAC_ADDR_LEN];
- u_int8_t *peer_mac_addr;
- u_int16_t peer_id;
- u_int8_t vdev_id;
-
- /* extract fields relevent for txrx */
- peer_id = HTT_ISOC_T2H_PEER_INFO_PEER_ID_GET(msg_addr);
- HTT_DXE_ASSERT3(peer_id <= ol_cfg_max_peer_id(pdev->ctrl_pdev));
- vdev_id = HTT_ISOC_T2H_PEER_INFO_VDEV_ID_GET(msg_addr);
- HTT_DXE_ASSERT3(vdev_id < ol_cfg_max_vdevs(pdev->ctrl_pdev));
- peer_mac_addr = htt_t2h_mac_addr_deswizzle(
- msg_addr + sizeof(u_int32_t) *
- HTT_ISOC_T2H_PEER_INFO_MAC_ADDR_L16_OFFSET32 +
- (HTT_ISOC_T2H_PEER_INFO_MAC_ADDR_L16_S >> 3),
- mac_addr_deswizzle_buf);
-
- /* extract fields relevant just for htt_dxe */
- peer = &pdev->peers[peer_id];
- peer->vdev_id = vdev_id;
- peer->type = HTT_ISOC_T2H_PEER_INFO_PEER_TYPE_GET(msg_addr);
-
- peer->security[HTT_DXE_PEER_KEY_UCAST].id =
- HTT_ISOC_T2H_PEER_INFO_DPU_IDX_GET(msg_addr);
- peer->security[HTT_DXE_PEER_KEY_UCAST].signature =
- HTT_ISOC_T2H_PEER_INFO_DPU_SIG_GET(msg_addr);
-
- peer->security[HTT_DXE_PEER_KEY_MCAST].id =
- HTT_ISOC_T2H_PEER_INFO_BCAST_DPU_IDX_GET(msg_addr);
- peer->security[HTT_DXE_PEER_KEY_MCAST].signature =
- HTT_ISOC_T2H_PEER_INFO_BCAST_DPU_SIG_GET(msg_addr);
-
- peer->security[HTT_DXE_PEER_KEY_MGMT].id =
- HTT_ISOC_T2H_PEER_INFO_MGMT_DPU_IDX_GET(msg_addr);
- peer->security[HTT_DXE_PEER_KEY_MGMT].signature =
- HTT_ISOC_T2H_PEER_INFO_MGMT_DPU_SIG_GET(msg_addr);
-
- /*
- * The qos_capable flag is already set to its default: 0
- * If the peer is found to be QoS capable, then this will
- * be specified through a call to htt_dxe_peer_qos_update.
- */
-
- peer->robust_mgmt =
- HTT_ISOC_T2H_PEER_INFO_RMF_ENABLED_GET(msg_addr);
-
- peer->rx_aggr_enabled_tids_bitmap = 0x0; /* no aggr until ADDBA */
-
- /* if this is a real peer, inform txrx */
- /* peer_info may come multiple times for the same peer.
- we shall only pass it once to upper layer*/
- /* ToDO: We need to check if a peer needs to be updated multiple times
- If not, this check for valid bit is not needed. With other fixes, FW
- only sends one indication per peer.
- */
- if (peer->type == HTT_ISOC_T2H_PEER_TYPE_ASSOC && !peer->valid) {
- /*Assign it here to keep the sequence intact*/
- peer->valid = 1;
- ol_rx_peer_map_handler(
- pdev->txrx_pdev, peer_id, vdev_id, peer_mac_addr,
- 0 /* no tx until PEER_TX_READY is received */);
- } else if (peer->type == HTT_ISOC_T2H_PEER_TYPE_SELF) {
- pdev->vdevs[vdev_id].self_peer_id = peer_id;
- } else if (peer->type == HTT_ISOC_T2H_PEER_TYPE_BCAST) {
- pdev->vdevs[vdev_id].bcast_peer_id = peer_id;
- }
- peer->valid = 1;
- break;
- }
- case HTT_ISOC_T2H_MSG_TYPE_PEER_TX_READY:
- {
- struct htt_dxe_peer_t *peer;
- u_int16_t peer_id;
-
- peer_id = HTT_ISOC_T2H_PEER_TX_READY_PEER_ID_GET(msg_addr);
- HTT_DXE_ASSERT3(peer_id <= ol_cfg_max_peer_id(pdev->ctrl_pdev));
- peer = &pdev->peers[peer_id];
- HTT_DXE_ASSERT3(peer->valid);
-
- /* if this is a real peer, inform txrx */
- if (peer->type == HTT_ISOC_T2H_PEER_TYPE_ASSOC) {
- ol_txrx_peer_tx_ready_handler(pdev->txrx_pdev, peer_id);
- }
- break;
- }
- case HTT_ISOC_T2H_MSG_TYPE_PEER_UNMAP:
- {
- struct htt_dxe_peer_t *peer;
- u_int16_t peer_id;
-
- peer_id = HTT_ISOC_T2H_PEER_UNMAP_PEER_ID_GET(msg_addr);
- HTT_DXE_ASSERT3(peer_id <= ol_cfg_max_peer_id(pdev->ctrl_pdev));
- peer = &pdev->peers[peer_id];
- peer->valid = 0;
- /*
- * Set the qos_capable flag back to its default value (0).
- */
- peer->qos_capable = 0;
-
- /* if this is a real peer, inform txrx */
- if (peer->type == HTT_ISOC_T2H_PEER_TYPE_ASSOC) {
- ol_rx_peer_unmap_handler(pdev->txrx_pdev, peer_id);
- }
- break;
- }
- case HTT_ISOC_T2H_MSG_TYPE_TX_COMPL_IND:
- {
-/* FILL IN HERE */
- break;
- }
- case HTT_ISOC_T2H_MSG_TYPE_SEC_IND:
- {
- u_int16_t peer_id;
- enum htt_sec_type sec_type;
- int is_unicast;
- u_int32_t mic_key[2];
-
- peer_id = HTT_ISOC_T2H_SEC_IND_PEER_ID_GET(msg_addr);
- sec_type = HTT_ISOC_T2H_SEC_IND_SEC_TYPE_GET(msg_addr);
- is_unicast = HTT_ISOC_T2H_SEC_IND_IS_UNICAST_GET(msg_addr);
- mic_key[0] = HTT_ISOC_T2H_SEC_IND_MIC1_GET(msg_addr);
- mic_key[1] = HTT_ISOC_T2H_SEC_IND_MIC2_GET(msg_addr);
-
- adf_os_print("SEC_IND (%d) peer_id %d sec_type %d is_unicast %d\n", msg_type, peer_id,sec_type, is_unicast );
-
- ol_rx_sec_ind_handler(pdev->txrx_pdev, peer_id, sec_type,
- is_unicast, mic_key, NULL);
-
- break;
- }
- default:
- adf_os_print("Error: Unknown HTT_T2H message type = %d\n", msg_type);
- adf_os_assert(0);
- break;
- };
-
- /* Free the indication buffer */
- adf_nbuf_free(htt_t2h_msg);
-}
-
-/*--- target->host HTT message Info Element access methods ------------------*/
-
-/* htt_rx_frag_ind -
- * The fragment indication not relevant for htt_dxe, since defragmentation
- * is handled within the HW.
- * Just provide a dummy function for txrx to link against.
- */
-void
-htt_rx_frag_ind_flush_seq_num_range(
- struct htt_dxe_pdev_t *pdev,
- adf_nbuf_t rx_frag_ind_msg,
- int *seq_num_start,
- int *seq_num_end)
-{
- adf_os_assert(0);
-}
-
diff --git a/CORE/DXE/htt_dxe_tx.c b/CORE/DXE/htt_dxe_tx.c
deleted file mode 100644
index 0a072a3713fd..000000000000
--- a/CORE/DXE/htt_dxe_tx.c
+++ /dev/null
@@ -1,809 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
- *
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file was originally distributed by Qualcomm Atheros, Inc.
- * under proprietary terms before Copyright ownership was assigned
- * to the Linux Foundation.
- */
-
-/**
- * @file htt_dxe_tx.c
- * @brief Implement transmit aspects of HTT.
- * @details
- * This file contains three categories of HTT tx code:
- * 1. An abstraction of the tx descriptor
- * 2. Functions for allocating and freeing HTT tx descriptors.
- * 3. The function that accepts a tx frame from txrx and sends the
- * tx frame to hif_dxe.
- */
-#include <osdep.h> /* u_int32_t, offsetof, etc. */
-#include <adf_os_types.h> /* adf_os_dma_addr_t */
-#include <adf_os_mem.h> /* adf_os_mem_alloc_consistent,free_consistent */
-#include <adf_os_util.h> /* adf_os_likely */
-#include <adf_nbuf.h> /* adf_nbuf_t, etc. */
-
-#include <athdefs.h> /* A_STATUS */
-
-#include <ol_cfg.h> /* ol_cfg_sw_encap_hdr_max_size */
-#include <hif_dxe.h> /* hif_dxe_send */
-#include <isoc_hw_desc.h> /* isoc_tx_bd_t, etc. */
-#include <ol_htt_tx_api.h>
-#include <ol_txrx_htt_api.h> /* ol_tx_download_done_hl_free, etc. */
-
-#include <htt_dxe_internal.h> /* HTT_DXE_ASSERT */
-
-/*--- utilities -------------------------------------------------------------*/
-
-#ifndef ARRAY_LEN
-#define ARRAY_LEN(x) (sizeof(x)/sizeof(x[0]))
-#endif
-
-
-/*--- constants -------------------------------------------------------------*/
-
-enum {
- HTT_DXE_TX_SSN_FILL_HOST = 0,
- HTT_DXE_TX_SSN_FILL_DPU_NON_QOS = 1,
- HTT_DXE_TX_SSN_FILL_DPU_QOS = 2,
-};
-
-enum {
- HTT_DXE_TX_BDRATE_DEFAULT = 0,
- HTT_DXE_TX_BDRATE_BCDATA_FRAME = 1, /* unused */
- HTT_DXE_TX_BDRATE_BCMGMT_FRAME = 2,
- HTT_DXE_TX_BDRATE_CTRL_FRAME = 3,
-};
-
-enum {
- HTT_DXE_ACK_POLICY_ACK = 0,
- HTT_DXE_ACK_POLICY_NO_ACK = 1,
-};
-
-enum {
- HTT_DXE_TX_BTQM_QID0 = 0,
- HTT_DXE_TX_BTQM_QID1 = 1,
- HTT_DXE_TX_BTQM_QID2 = 2,
- HTT_DXE_TX_BTQM_QID3 = 3,
- HTT_DXE_TX_BTQM_QID4 = 4,
- HTT_DXE_TX_BTQM_QID5 = 5,
- HTT_DXE_TX_BTQM_QID6 = 6,
- HTT_DXE_TX_BTQM_QID7 = 7,
- HTT_DXE_TX_BTQM_QID8 = 8,
- HTT_DXE_TX_BTQM_QID9 = 9,
- HTT_DXE_TX_BTQM_QID10 = 10,
-
- HTT_DXE_TX_BTQM_QUEUE_SELF_STA_BCAST_MGMT = HTT_DXE_TX_BTQM_QID10,
- HTT_DXE_TX_BTQM_QUEUE_SELF_STA_UCAST_MGMT = HTT_DXE_TX_BTQM_QID9,
- HTT_DXE_TX_BTQM_QUEUE_SELF_STA_UCAST_DATA = HTT_DXE_TX_BTQM_QID9,
- HTT_DXE_TX_BTQM_QUEUE_TX_NON_QOS = HTT_DXE_TX_BTQM_QID8,
-
-};
-
-enum {
- HTT_DXE_TX_BMUWQ_BTQM_TX_MGMT = 25,
-};
-
-/*--- utility functions -----------------------------------------------------*/
-
-static inline u_int16_t *
-htt_dxe_tx_msdu_id_storage(adf_nbuf_t msdu)
-{
- adf_os_assert(adf_nbuf_headroom(msdu) >= (sizeof(u_int16_t) * 2 - 1));
- return (u_int16_t *) (((adf_os_size_t) (adf_nbuf_head(msdu) + 1)) & ~0x1);
-}
-
-/*
- * The Tx BD is supposed to be in big-endian format.
- * On a little endian host, the Tx BD is produced in the expected format by
- * 1. using the conditionally-compiled Tx BD bitfield defs from
- * isoc_hw_desc.h to make sure the bitfields are at the correct positions
- * within a 32-bit word.
- * 2. Using the HTT_DXE_TX_BD_BYTESWAP function to swap the bytes within each
- * 32-bit word of the Tx BD, so when the Tx BD is stored in little-endian
- * order, the shuffled bytes will end up in big-endian order.
- * (The byte-shuffling will cancel out the little-endian byte ordering
- * that occurs as the 32-bit words are stored into bytes of memory.)
- */
-#ifndef BIG_ENDIAN_HOST
-/* little-endian - swap the bytes */
-static inline void
-HTT_DXE_TX_BD_BYTESWAP(isoc_tx_bd_t *tx_bd)
-{
- isoc_hw_bd_swap_bytes32((char *) tx_bd, sizeof(*tx_bd));
-}
-#else
-/* big-endian - bytes are naturally in the correct order, no swap needed */
-#define HTT_DXE_TX_BD_BYTESWAP(tx_bd) /* no-op */
-#endif /* BIG_ENDIAN_HOST */
-
-/*--- debug functions -------------------------------------------------------*/
-
-#ifdef HTT_DBG
-#define htt_dxe_tx_desc_display htt_tx_desc_display
-void
-htt_tx_desc_display(void *tx_desc)
-{
- struct htt_dxe_tx_desc_t *sw_tx_desc = (struct htt_dxe_tx_desc_t *) desc;
- isoc_tx_bd_dump((isoc_tx_bd_t *) sw_tx_desc->tx_bd_buf);
-}
-#endif
-
-#ifndef HTT_DXE_TX_DEBUG_LEVEL
-#define HTT_DXE_TX_DEBUG_LEVEL 1 /* default */
-#endif
-
-#if defined(HTT_DBG) || HTT_DXE_TX_DEBUG_LEVEL > 1
-
-void HTT_DXE_TX_BD_DUMP(isoc_tx_bd_t *tx_bd)
-{
- isoc_tx_bd_t tmp_tx_bd;
-
- /*
- * Make our own copy of the Tx BD.
- * This is mainly so we can convert the Tx BD back to little-endian
- * format for a printout, if the host is little-endian.
- * A secondary purpose is to do a single block-copy from the
- * real Tx BD in non-cacheable memory into a cacheable location,
- * before reading and printing fields of the struct.
- */
- tmp_tx_bd = *tx_bd;
- /* undo the endianness fix */
- HTT_DXE_TX_BD_BYTESWAP(&tmp_tx_bd);
- isoc_tx_bd_dump(&tmp_tx_bd);
-}
-#else
-#define HTT_DXE_TX_BD_DUMP(tx_bd) /* no-op */
-#endif
-
-/*--- setup / tear-down functions -------------------------------------------*/
-
-A_STATUS
-htt_dxe_tx_attach(struct htt_dxe_pdev_t *pdev, int desc_pool_elems)
-{
- int i, pool_size;
- adf_os_dma_addr_t pool_paddr;
- struct htt_dxe_tx_desc_t *sw_desc;
- char *tx_bd_buf;
-
- pdev->tx_descs.sw_descs_pool = NULL;
- pdev->tx_descs.tx_bds.pool_vaddr = NULL;
-
- /*--- allocate the pool of SW tx descs ---*/
- pool_size = sizeof(struct htt_dxe_tx_desc_t) * desc_pool_elems;
- pdev->tx_descs.sw_descs_pool = adf_os_mem_alloc(pdev->osdev, pool_size);
- if (!pdev->tx_descs.sw_descs_pool) {
- goto fail;
- }
-
- /*--- allocate the pool of HW tx descs ---*/
- pdev->tx_descs.size =
- ol_cfg_sw_encap_hdr_max_size(pdev->ctrl_pdev) +
- sizeof(isoc_tx_bd_t);
- if (pdev->tx_descs.size < sizeof(u_int32_t *)) {
- pdev->tx_descs.size = sizeof(u_int32_t *);
- }
- /*
- * Make sure tx_descs.size is a multiple of 4-bytes.
- * It should be, but round up just to be sure.
- */
- pdev->tx_descs.size = (pdev->tx_descs.size + 3) & (~0x3);
-
- pdev->tx_descs.pool_elems = desc_pool_elems;
- pdev->tx_descs.alloc_cnt = 0;
-
- pool_size = pdev->tx_descs.pool_elems * pdev->tx_descs.size;
-
-/* allocate extra, for alignment padding? */
- pdev->tx_descs.tx_bds.pool_vaddr = adf_os_mem_alloc_consistent(
- pdev->osdev, pool_size, &pool_paddr,
- adf_os_get_dma_mem_context((&pdev->tx_descs), memctx));
- pdev->tx_descs.tx_bds.pool_paddr = pool_paddr;
-
- if (!pdev->tx_descs.tx_bds.pool_vaddr) {
- goto fail;
- }
-
- /*-- link HW descs with SW descs, and link SW descs into a freelist ---*/
- pdev->tx_descs.freelist = NULL;
- tx_bd_buf = pdev->tx_descs.tx_bds.pool_vaddr;
- sw_desc = pdev->tx_descs.sw_descs_pool;
- for (i = 0; i < desc_pool_elems; i++) {
- sw_desc->tx_bd_buf = tx_bd_buf;
- htt_dxe_tx_desc_free(pdev, sw_desc);
-
- sw_desc++;
- tx_bd_buf += pdev->tx_descs.size;
- }
-
- /* program the constant fields within the template Tx BD */
- /* currently, nearly all constant fields need to be set to zero */
- adf_os_mem_zero(&pdev->template_tx_bd, sizeof(pdev->template_tx_bd));
- pdev->template_tx_bd.mpdu_header_offset = sizeof(isoc_tx_bd_t);
-
- /* initialize the Tx BD serial number */
- pdev->tx_bd_sig_serial_num = 0;
-
- return A_OK; /* success */
-
-fail:
- /* clean up any partial inits */
- htt_dxe_tx_detach(pdev);
- return A_ERROR;
-}
-
-void
-htt_dxe_tx_detach(struct htt_dxe_pdev_t *pdev)
-{
- if (pdev->tx_descs.sw_descs_pool) {
- adf_os_mem_free(pdev->tx_descs.sw_descs_pool);
- }
- if (pdev->tx_descs.tx_bds.pool_vaddr) {
- adf_os_mem_free_consistent(
- pdev->osdev,
- pdev->tx_descs.pool_elems * pdev->tx_descs.size, /* pool_size */
- pdev->tx_descs.tx_bds.pool_vaddr,
- pdev->tx_descs.tx_bds.pool_paddr,
- adf_os_get_dma_mem_context((&pdev->tx_descs), memctx));
- }
-}
-
-/*--- descriptor allocation functions ---------------------------------------*/
-
-void *
-htt_dxe_tx_desc_alloc(struct htt_dxe_pdev_t *pdev, u_int32_t *paddr_lo)
-{
- struct htt_dxe_tx_desc_t *sw_desc;
- u_int32_t offset;
-
- sw_desc = pdev->tx_descs.freelist;
- if (! sw_desc) {
- return NULL; /* pool is exhausted */
- }
-
- pdev->tx_descs.freelist = sw_desc->u.next;
- pdev->tx_descs.alloc_cnt++;
-
- offset = (u_int32_t)
- (((char *) sw_desc->tx_bd_buf) -
- ((char *) pdev->tx_descs.tx_bds.pool_vaddr));
- *paddr_lo = ((u_int32_t) pdev->tx_descs.tx_bds.pool_paddr) + offset;
- return (void *) sw_desc;
-}
-
-void
-htt_dxe_tx_desc_free(struct htt_dxe_pdev_t *pdev, void *abstract_desc)
-{
- struct htt_dxe_tx_desc_t *sw_desc;
-
- sw_desc = (struct htt_dxe_tx_desc_t *) abstract_desc;
- sw_desc->u.next = pdev->tx_descs.freelist;
- pdev->tx_descs.freelist = sw_desc;
- pdev->tx_descs.alloc_cnt--;
-}
-
-#define htt_dxe_tx_desc_mpdu_header htt_tx_desc_mpdu_header
-volatile char *
-htt_dxe_tx_desc_mpdu_header(void *abstract_desc, u_int8_t new_l2_hdr_size)
-{
- struct htt_dxe_tx_desc_t *sw_desc;
-
- sw_desc = (struct htt_dxe_tx_desc_t *) abstract_desc;
- sw_desc->u.info.l2_hdr_size = new_l2_hdr_size;
- return sw_desc->tx_bd_buf + sizeof(isoc_tx_bd_t);
-}
-
-
-#ifdef HTT_DBG
-void
-htt_dxe_tx_desc_display(void *tx_desc)
-{
-}
-#endif
-
-/*--- tx descriptor programming functions -----------------------------------*/
-
-static u_int16_t
-htt_dxe_tx_select_peer(
- struct htt_dxe_pdev_t *pdev,
- struct htt_msdu_info_t *msdu_info,
- int is_robust_mgmt)
-{
- struct htt_dxe_vdev_t *vdev;
-
- vdev = &pdev->vdevs[msdu_info->info.vdev_id];
- if (vdev->op_mode == htt_op_mode_sta) {
- if (msdu_info->info.frame_type == htt_frm_type_data) {
- /* use the real peer object */
- return msdu_info->info.peer_id;
- } else if (is_robust_mgmt) {
- /* for robust management, use the real peer object */
- return msdu_info->info.peer_id;
- } else {
- /* regular management - use self-peer */
- return vdev->self_peer_id;
- }
- } else {
- /* AP */
- if (msdu_info->info.is_unicast) {
- if (msdu_info->info.frame_type == htt_frm_type_data) {
- /* use the real peer object */
- return msdu_info->info.peer_id;
- } else {
- /*
- * unicast management -
- * Is there a valid peer? If so, use it.
- * If not (probe-resp or assoc-resp), use the self-peer.
- */
- return msdu_info->info.peer_id == HTT_INVALID_PEER_ID ?
- vdev->self_peer_id : msdu_info->info.peer_id;
- }
- } else {
- /* use broadcast self-STA */
- return vdev->bcast_peer_id;
- }
- }
-}
-
-static u_int8_t
-htt_dxe_tx_tid_translate(u_int8_t ext_tid, int is_mgmt)
-{
- if (is_mgmt) return 7;
- if (ext_tid > 7) return 0;
- return ext_tid;
-}
-
-static inline u_int8_t
-htt_dxe_tx_qos_queue_id(u_int8_t tid)
-{
- static u_int8_t tid_queue_ids[] = {
- HTT_DXE_TX_BTQM_QID0, HTT_DXE_TX_BTQM_QID1,
- HTT_DXE_TX_BTQM_QID2, HTT_DXE_TX_BTQM_QID3,
- HTT_DXE_TX_BTQM_QID4, HTT_DXE_TX_BTQM_QID5,
- HTT_DXE_TX_BTQM_QID6, HTT_DXE_TX_BTQM_QID7 };
- /*
- * Confirm this is a UP TID (0-7), not a regular TID (0-15)
- * or extended TID (0-17).
- */
- adf_os_assert(tid < ARRAY_LEN(tid_queue_ids));
-
- return tid_queue_ids[tid];
-}
-
-enum {
- HTT_DXE_TXBD_SIG_SERIAL_NUM_SHIFT = 0,
- HTT_DXE_TXBD_SIG_TID_SHIFT = 8,
- HTT_DXE_TXBD_SIG_UCAST_SHIFT = 9,
- HTT_DXE_TXBD_SIG_DEST_MAC_ADDR_SHIFT = 16,
-};
-#define HTT_DXE_TXBD_SIG_MGMT_MAGIC 0xbdbdbdbd
-
-/*
- * NOTE: this Tx BD signature computation function is currently not used.
- * Its purpose is to show whether the prior contents of a Tx BD can be
- * reused for a new frame.
- * This optimization is not currently utilized, nor are there plans to
- * utilize it.
- * However, this function is being left in place just in case this
- * optimization is utilized in the future.
- */
-static inline u_int32_t
-htt_dxe_tx_bd_signature(
- struct htt_dxe_pdev_t *pdev,
- u_int8_t *dest_mac_addr,
- u_int8_t tid,
- u_int8_t is_unicast,
- int is_data)
-{
- u_int16_t *dest_mac_addr16 = (u_int16_t *) dest_mac_addr;
- u_int16_t dest_mac_addr_hash16;
-
- if ((!is_data) || (!pdev->cfg.flags.do_frame_translate)) {
- return HTT_DXE_TXBD_SIG_MGMT_MAGIC;
- }
-
- /* confirm dest addr has 2-byte alignment, so the above typecast is safe */
- adf_os_assert(((unsigned) dest_mac_addr & 0x1) == 0);
-
- dest_mac_addr_hash16 =
- dest_mac_addr16[0] ^ dest_mac_addr16[1] ^ dest_mac_addr[2];
- return
- (dest_mac_addr_hash16 << HTT_DXE_TXBD_SIG_DEST_MAC_ADDR_SHIFT) |
- // FIX THIS: update tx_bd_sig_serial_num
- (pdev->tx_bd_sig_serial_num << HTT_DXE_TXBD_SIG_SERIAL_NUM_SHIFT) |
- (tid << HTT_DXE_TXBD_SIG_TID_SHIFT) |
- (is_unicast << HTT_DXE_TXBD_SIG_UCAST_SHIFT);
-}
-
-static void
-htt_dxe_tx_bd_fill(
- struct htt_dxe_pdev_t *pdev,
- struct htt_dxe_tx_desc_t *sw_tx_desc,
- int msdu_len,
- struct htt_msdu_info_t *msdu_info)
-{
- struct htt_dxe_peer_t *peer;
- isoc_tx_bd_t shadow_tx_bd = pdev->template_tx_bd;
- int tid;
- int peer_id;
- int which_key;
- int l2_hdr_size;
- int is_data;
- int is_robust_mgmt;
-
- /*
- * The following Tx BD fields are only used internally within the
- * target. The host does not need to program these fields.
- * adu_feedback
- * dpu_feedback
- * head_pdu_idx
- * tail_pdu_idx
- * pdu_count
- * dxe_h2b_start_timestamp
- * dxe_h2b_end_timestamp
- *
- * The following Tx BD fields are constant, and are copied from the
- * template:
- * fw_tx_complete_intr (value = 0)
- * bd_type (value = 0)
- * mpdu_header_offset (value = sizeof(isoc_tx_bd_t))
- * reserved fields (some of these need to be 0)
- * tx_bd_signature (value = 0)
- * The tx_bd_signature is a reserved field that can be used
- * by the host SW to determine whether the new tx frame is
- * similar enough to the prior tx frame described by this
- * Tx BD to avoid reprogramming the Tx BD from scratch.
- * The htt_dxe module doesn't attempt this optimization.
- */
-
- is_data = msdu_info->info.frame_type == htt_frm_type_data;
- sw_tx_desc->u.info.is_mgmt = !is_data;
- tid = htt_dxe_tx_tid_translate(msdu_info->info.ext_tid, !is_data);
- is_robust_mgmt =
- (!is_data) &&
- /*
- * The peer ID will be HTT_INVALID_PEER_ID if either this is a
- * multicast / broadcast frame, or if this is a unicast frame
- * to an unassociated peer (probe req/resp, assoc req/resp).
- * Thus, it's not necessary to separately check is_unicast.
- */
- (msdu_info->info.peer_id != HTT_INVALID_PEER_ID) &&
- (pdev->peers[msdu_info->info.peer_id].robust_mgmt) &&
- (msdu_info->info.frame_subtype == htt_frm_subtype_mgmt_action ||
- msdu_info->info.frame_subtype == htt_frm_subtype_mgmt_deauth ||
- msdu_info->info.frame_subtype == htt_frm_subtype_mgmt_disassoc);
-
- /*
- * Decide whether to use the peer ID provided by txrx,
- * or use the self or BSS peer.
- */
- peer_id = htt_dxe_tx_select_peer(pdev, msdu_info, is_robust_mgmt);
- peer = &pdev->peers[peer_id];
- /*
- * There should never be a transmission that uses an uninitialized
- * real-peer or self-peer object. Do a sanity check that the peer
- * object has been initialized via a PEER_INFO message.
- */
- HTT_DXE_ASSERT2(peer->valid);
- /*
- * The msdu_info's l3_hdr_offset is always valid, and thus can be used
- * as the l2_hdr_size.
- * For data frames without SW encap, the l3_hdr_offset is the offset
- * within the tx MSDU's netbuf from the start of the L2 header.
- * For data frames with SW encap, the old L2 header has been removed
- * from the netbuf (by pulling the data pointer past the old L2 header),
- * but the l3_hdr_offset still accounts for the new L2 header, even though
- * that new L2 header is stored in a buffer provided by HTT, rather than
- * in the tx netbuf.
- * For management frames, the 802.11 L2 header is present in the netbuf,
- * and the msdu_info's l3_hdr_offset has been set to
- * sizeof(ieee80211_frame).
- */
- l2_hdr_size = msdu_info->info.l3_hdr_offset;
-
- if (adf_os_likely(msdu_info->info.is_unicast)) {
- /*=== unicast data and mgmt ===*/
- // TBD:
- //check consistency with frame hdr ack policy field, if SW tx encap?
- shadow_tx_bd.ack_policy = HTT_DXE_ACK_POLICY_ACK;
- which_key = HTT_DXE_PEER_KEY_UCAST;
-
- if (adf_os_likely(is_data)) {
- shadow_tx_bd.queue_id = (peer->qos_capable) ?
- htt_dxe_tx_qos_queue_id(tid) : HTT_DXE_TX_BTQM_QUEUE_TX_NON_QOS;
- } else {
- /*--- unicast mgmt ---*/
- int is_associated = msdu_info->info.peer_id == HTT_INVALID_PEER_ID;
- shadow_tx_bd.queue_id = (is_associated) ?
- /* regular unicast mgmt frames - expect ack */
- HTT_DXE_TX_BTQM_QUEUE_SELF_STA_UCAST_MGMT :
- /* probe request/response, assoc request/response - no ack */
- HTT_DXE_TX_BTQM_QUEUE_SELF_STA_BCAST_MGMT;
- }
- } else {
- /*=== multicast data and mgmt ===*/
- //TBD:
- //check consistency with frame hdr ack policy field, if SW tx encap?
- shadow_tx_bd.ack_policy = HTT_DXE_ACK_POLICY_NO_ACK;
- if (is_data) {
- /*--- multicast data ---*/
- which_key = HTT_DXE_PEER_KEY_MCAST;
- shadow_tx_bd.queue_id = HTT_DXE_TX_BTQM_QID0;
- } else {
- /*--- multicast mgmt ---*/
- which_key = HTT_DXE_PEER_KEY_MGMT;
- shadow_tx_bd.queue_id = HTT_DXE_TX_BTQM_QUEUE_SELF_STA_BCAST_MGMT;
- }
- }
-
- if (is_data) {
- /*=== multicast and unicast data ===*/
- shadow_tx_bd.bd_seq_num_src = (peer->qos_capable) ?
- HTT_DXE_TX_SSN_FILL_DPU_QOS : HTT_DXE_TX_SSN_FILL_DPU_NON_QOS;
- shadow_tx_bd.bd_rate = HTT_DXE_TX_BDRATE_DEFAULT;
-
- /*
- * riva: no frame translation (tx encap done by SW)
- * pronto + northstar:
- * depending on frame format, enable HW frm translate
- */
- shadow_tx_bd.frame_translate = pdev->cfg.flags.do_frame_translate;
- } else {
- /*=== multicast and unicast mgmt ===*/
- if (is_robust_mgmt) {
- shadow_tx_bd.robust_mgmt = 1;
- /* make sure the "no_encrypt" flag gets turned off */
- msdu_info->action.do_encrypt = 1;
- } else {
- /* besides the robust mgmt case, mgmt frames are not encrypted */
- msdu_info->action.do_encrypt = 0;
- }
- shadow_tx_bd.bd_seq_num_src = HTT_DXE_TX_SSN_FILL_DPU_NON_QOS;
- /*
- * bd_rate:
- * Check if the rate is forced to 6 Mbps (for mgmt frames in the
- * 5 GHz band, or for mgmt frames sent by P2P devices).
- * Otherwise, unicast mgmt frames will go at lower rate
- * (multicast rate). Multicast mgmt frames will go at the
- * STA rate as in AP mode. Buffering has an issue at HW
- * if BD rate is used.
- */
- if (msdu_info->action.use_6mbps) {
- shadow_tx_bd.bd_rate = HTT_DXE_TX_BDRATE_CTRL_FRAME;
- } else {
- shadow_tx_bd.bd_rate = (msdu_info->info.is_unicast) ?
- HTT_DXE_TX_BDRATE_BCMGMT_FRAME : HTT_DXE_TX_BDRATE_DEFAULT;
- }
- /* mgmt frames already have a 802.11 header - no frame translation */
- shadow_tx_bd.frame_translate = 0;
- }
-
- shadow_tx_bd.dpu_no_encrypt = ! msdu_info->action.do_encrypt;
- if(msdu_info->action.do_tx_complete) {
- adf_os_print("*** WARNING: Pronto SW for OTA tx ack is incomplete!\n");
- }
- shadow_tx_bd.tx_complete_intr = msdu_info->action.do_tx_complete;
- shadow_tx_bd.not_unicast = ! msdu_info->info.is_unicast;
- shadow_tx_bd.sta_index = peer_id;
- shadow_tx_bd.tid = tid;
- shadow_tx_bd.mpdu_header_length = l2_hdr_size;
- shadow_tx_bd.mpdu_data_offset = sizeof(isoc_tx_bd_t) + l2_hdr_size;
- shadow_tx_bd.mpdu_length = msdu_len + sw_tx_desc->u.info.l2_hdr_size;
- shadow_tx_bd.dpu_signature = peer->security[which_key].signature;
- shadow_tx_bd.dpu_desc_idx = peer->security[which_key].id;
-
- // FIX THIS
- #if 0
- shadow_tx_bd.dpu_routing_flag = (trigger-enabled frame & U-APSD mode on) ?
- BMUWQ_FW_DPU_TX : HTT_DXE_TX_BMUWQ_BTQM_TX_MGMT;
- #else
- // TEMPORARY: default to HTT_DXE_TX_BMUWQ_BTQM_TX_MGMT
- shadow_tx_bd.dpu_routing_flag = HTT_DXE_TX_BMUWQ_BTQM_TX_MGMT;
- #endif
-
- /* fix endianness */
- HTT_DXE_TX_BD_BYTESWAP(&shadow_tx_bd);
-
- /* signature uses native endianness */
- #if 0 /* using signature to avoid reprogramming Tx BD is not supported */
- shadow_tx_bd.tx_bd_signature = htt_dxe_tx_bd_signature(
- pdev, msdu_info->info.dest_addr, tid, msdu_info->info.is_unicast,
- is_data);
- #endif
-
- adf_os_mem_copy(
- (char *) sw_tx_desc->tx_bd_buf, &shadow_tx_bd, sizeof(shadow_tx_bd));
-}
-
-void htt_tx_desc_set_peer_id(u_int32_t *htt_tx_desc, u_int16_t peer_id)
-{
- /* FILL IN HERE */
- return;
-}
-
-void
-htt_tx_desc_init(
- htt_pdev_handle pdev,
- void *desc,
- u_int32_t htt_tx_desc_paddr_lo,
- u_int16_t msdu_id,
- adf_nbuf_t msdu,
- struct htt_msdu_info_t *msdu_info)
-{
- struct htt_dxe_tx_desc_t *sw_tx_desc = (struct htt_dxe_tx_desc_t *) desc;
- int frag_size;
-
-#if defined(HTT_DBG) || HTT_DXE_TX_DEBUG_LEVEL > 1
- htt_msdu_info_dump(msdu_info);
-#endif
- htt_dxe_tx_bd_fill(pdev, sw_tx_desc, adf_nbuf_len(msdu), msdu_info);
-
- /* store the TID for later so we can determine which frames are mgmt */
- sw_tx_desc->u.info.ext_tid = msdu_info->info.ext_tid;
-
- /* add Tx BD as initial fragment to the netbuf */
- frag_size = sizeof(isoc_tx_bd_t);
- /* account for the L2 encapsulation header, if any */
- frag_size += sw_tx_desc->u.info.l2_hdr_size;
- adf_nbuf_frag_push_head(
- msdu,
- frag_size,
- /*
- * Pass in the address of the SW tx descriptor rather than the
- * virtual address of the Tx BD itself.
- * The underlying layers don't need to use the Tx BD virtual address;
- * they only care about the physical address.
- * If this layer needs need to find the Tx BD, it can use the
- * sw_tx_desc->tx_bd_buf
- * We retrieve this SW tx descriptor pointer later during the tx_send
- * function, e.g. to check whether the frame is data or mgmt.
- */
- (char *) sw_tx_desc, //sw_tx_desc->tx_bd_buf, /* virtual addr */
- htt_tx_desc_paddr_lo/*phy addr LSBs*/, 0 /* phys addr MSBs - n/a */);
-}
-
-/*--- tx send function ------------------------------------------------------*/
-
-#define htt_dxe_tx_send_std htt_tx_send_std
-int
-htt_dxe_tx_send_std(
- struct htt_dxe_pdev_t *pdev,
- adf_nbuf_t msdu,
- u_int16_t msdu_id)
-{
- struct htt_dxe_tx_desc_t *sw_tx_desc;
- u_int16_t *msdu_id_storage;
- int is_mgmt;
- E_HIFDXE_CHANNELTYPE dxe_chan;
-
- /*
- * The HTT tx descriptor was attached as the prefix fragment to the
- * msdu netbuf during the call to htt_tx_desc_init.
- * Retrieve it so we can check whether the frame is data or mgmt.
- */
- sw_tx_desc = (struct htt_dxe_tx_desc_t *) adf_nbuf_get_frag_vaddr(msdu, 0);
-
- is_mgmt = sw_tx_desc->u.info.is_mgmt;
-
- /* for debugging, optionally show Tx BD contents */
- HTT_DXE_TX_BD_DUMP((isoc_tx_bd_t *) sw_tx_desc->tx_bd_buf);
-
- /* store MSDU ID */
- msdu_id_storage = htt_dxe_tx_msdu_id_storage(msdu);
- *msdu_id_storage = msdu_id;
-
- /* send the frame to hif_dxe */
- dxe_chan = (is_mgmt) ?
- HIFDXE_CHANNEL_TX_HIGH_PRI : HIFDXE_CHANNEL_TX_LOW_PRI;
-
- /* FOR NOW, send only one frame at a time */
- adf_nbuf_set_next(msdu, NULL);
-
- return hif_dxe_send(pdev->hif_dxe_pdev, dxe_chan, msdu) != A_OK;
-}
-
-#define htt_dxe_tx_send_nonstd htt_tx_send_nonstd
-int
-htt_dxe_tx_send_nonstd(
- struct htt_dxe_pdev_t *pdev,
- adf_nbuf_t msdu,
- u_int16_t msdu_id,
- enum htt_pkt_type pkt_type)
-{
- /*
- * Since the whole frame gets downloaded, frames with a non-standard
- * L2 header are handled the same as any other frame.
- */
- return htt_dxe_tx_send_std(pdev, msdu, msdu_id);
-}
-
-#define htt_dxe_tx_send_batch htt_tx_send_batch
-adf_nbuf_t
-htt_dxe_tx_send_batch(
- struct htt_dxe_pdev_t *pdev,
- adf_nbuf_t head_msdu,int num_msdus)
-{
- /* FILL IN HERE */
- adf_os_assert(0);
- return NULL;
-}
-
-#define htt_dxe_tx_msdu_credit htt_tx_msdu_credit
-u_int32_t htt_dxe_tx_msdu_credit(adf_nbuf_t msdu)
-{
- /*
- * Credits represent the number of spaces available in the DXE ring.
- * Each frame consumes one DXE descriptor for each of its fragments.
- * Hence, return the number of fragments in the frame.
- */
- return adf_nbuf_get_num_frags(msdu);
-}
-
-/*--- callback functions ----------------------------------------------------*/
-
-A_STATUS
-htt_dxe_tx_download_done(
- void *context,
- adf_nbuf_t msdus,
- E_HIFDXE_CHANNELTYPE chan,
- A_STATUS status)
-{
- struct htt_dxe_pdev_t *pdev = (struct htt_dxe_pdev_t *) context;
- u_int16_t *msdu_id_storage;
- u_int16_t msdu_id;
-
- while (msdus) {
- adf_nbuf_t msdu;
- msdu = msdus;
- msdus = adf_nbuf_next(msdus);
- adf_nbuf_set_next(msdu, NULL);
-
- msdu_id_storage = htt_dxe_tx_msdu_id_storage(msdu);
- msdu_id = *msdu_id_storage;
-
- ol_tx_download_done_hl_retain(pdev->txrx_pdev, A_OK, msdu, msdu_id);
- /*
- * For now, as soon as one frame is downloaded, allow another frame's
- * download to begin, by immediately updating by the full credit.
- */
- ol_tx_target_credit_update(
- pdev->txrx_pdev, htt_dxe_tx_msdu_credit(msdu));
- /*
- * TO DO:
- * Don't give a completion callback here at download completion
- * if this frame is tagged for OTA tx completion.
- */
- ol_tx_completion_handler(
- pdev->txrx_pdev, 1/*num_msdus*/, htt_tx_status_ok, &msdu_id);
- }
-
- return A_OK;
-}
-
-A_STATUS
-htt_dxe_tx_low_rsrc(
- void *context,
- E_HIFDXE_CHANNELTYPE chan,
- A_BOOL is_low_resource)
-{
-/* FILL IN HERE */
- return A_OK;
-}
diff --git a/CORE/DXE/htt_dxe_types.h b/CORE/DXE/htt_dxe_types.h
deleted file mode 100644
index e7e15949f33e..000000000000
--- a/CORE/DXE/htt_dxe_types.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
- *
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file was originally distributed by Qualcomm Atheros, Inc.
- * under proprietary terms before Copyright ownership was assigned
- * to the Linux Foundation.
- */
-
-#ifndef _HTT_DXE_TYPES__H_
-#define _HTT_DXE_TYPES__H_
-
-#include <osdep.h> /* u_int16_t, dma_addr_t */
-#include <adf_os_types.h> /* adf_os_device_t */
-#include <adf_os_lock.h> /* adf_os_spinlock_t */
-//#include <adf_os_timer.h> /* adf_os_timer_t */
-//#include <adf_os_atomic.h>/* adf_os_atomic_inc */
-#include <adf_nbuf.h> /* adf_nbuf_t */
-
-#include <isoc_hw_desc.h> /* isoc_tx_bd_t */
-#include <htt_isoc.h> /* HTT_ISOC_T2H_PEER_TYPE_ENUM */
-
-#include <ol_ctrl_api.h> /* ol_pdev_handle */
-#include <ol_txrx_api.h> /* ol_txrx_pdev_handle */
-#include <dmux_dxe_api.h> /* dmux_dxe_handle */
-#include <hif_dxe.h> /* hif_dxe_handle */
-#include <isoc_hw_desc.h> /* isoc_rx_bd_t */
-#include <ol_htt_api.h> /* enum htt_op_mode */
-
-#define htt_dxe_pdev_t htt_pdev_t
-
-
-struct htt_dxe_pdev_t;
-
-struct htt_dxe_tx_desc_t {
- /*
- * N.B. The union portion of this struct can get clobbered when
- * the struct is stored in a freelist.
- * Any elements that need to be maintained during the time that
- * the struct is unallocated in the freelist must be placed
- * after the union.
- */
- union {
- struct {
- u_int8_t ext_tid;
- u_int8_t l2_hdr_size;
- u_int8_t is_mgmt;
- } info;
- struct htt_dxe_tx_desc_t *next; /* used for freelist */
- } u;
- volatile char *tx_bd_buf;
-};
-
-enum {
- HTT_DXE_PEER_KEY_UCAST,
- HTT_DXE_PEER_KEY_MCAST,
- HTT_DXE_PEER_KEY_MGMT,
-
- HTT_DXE_PEER_NUM_KEYS /* keep this last */
-};
-
-struct htt_dxe_peer_t {
- HTT_ISOC_T2H_PEER_TYPE_ENUM type;
- u_int32_t rx_aggr_enabled_tids_bitmap;
- struct {
- u_int8_t id;
- u_int8_t signature;
- } security[HTT_DXE_PEER_NUM_KEYS];
- u_int8_t vdev_id; /* which vdev does this peer belong to */
- /*
- * For now, store one flag per byte, to allow for fast access
- * when checking these flags from the per-frame transmit functions.
- * To minimize memory, these flags could be packed together, but
- * that would be less CPU-efficient.
- */
- u_int8_t qos_capable;
- u_int8_t robust_mgmt;
- u_int8_t valid;
-};
-
-struct htt_dxe_vdev_t {
- enum htt_op_mode op_mode;
- u_int16_t self_peer_id;
- u_int16_t bcast_peer_id;
- u_int8_t valid;
-};
-
-struct htt_dxe_msdu_list_t {
- adf_nbuf_t head;
- adf_nbuf_t tail;
-};
-
-struct htt_dxe_rx_log_elem_t {
- u_int16_t peer_id;
- int16_t seq_num; /* -1 for n/a */
- u_int8_t tid;
- u_int8_t reorder_opcode;
- int8_t slot_idx; /* -1 for n/a */
- int8_t fwd_idx; /* -1 for n/a */
-};
-
-struct htt_dxe_pdev_t {
- ol_pdev_handle ctrl_pdev;
- ol_txrx_pdev_handle txrx_pdev;
- dmux_dxe_handle dmux_dxe_pdev;
- hif_dxe_handle hif_dxe_pdev;
- adf_os_device_t osdev;
-
- struct htt_dxe_vdev_t *vdevs;
- struct htt_dxe_peer_t *peers;
-
- struct {
- struct {
- u_int8_t sw_tx_encap;
- u_int8_t do_frame_translate;
- } flags;
- } cfg;
-
- struct {
- int size; /* of each HTT tx desc */
- int pool_elems;
- int alloc_cnt;
- struct htt_dxe_tx_desc_t *sw_descs_pool;
- struct {
- char *pool_vaddr;
- u_int32_t pool_paddr;
- } tx_bds;
- struct htt_dxe_tx_desc_t *freelist;
- adf_os_dma_mem_context(memctx);
- } tx_descs;
- isoc_tx_bd_t template_tx_bd;
- u_int32_t tx_bd_sig_serial_num;
-
- adf_os_spinlock_t tx_mutex;
- u_int8_t tx_mutex_valid;
-
- struct {
- struct htt_dxe_msdu_list_t pending_amsdus[2/*low+high pri*/];
- struct htt_dxe_msdu_list_t delivery;
-
- /* cur -
- * temporary context to remember which rx indication
- * is being processed currently
- */
- struct {
- isoc_rx_bd_t *rx_bd;
- u_int8_t peer_id;
- u_int8_t tid;
- u_int8_t rx_aggr_enabled;
- } cur;
- } rx;
-
- #ifdef HTT_DXE_RX_LOG
- #define HTT_DXE_RX_LOG_LEN_LOG2 7 /* log length = 128 */
- #define HTT_DXE_RX_LOG_LEN (1 << HTT_DXE_RX_LOG_LEN_LOG2)
- #define HTT_DXE_RX_LOG_LEN_MASK (HTT_DXE_RX_LOG_LEN - 1)
- struct {
- struct htt_dxe_rx_log_elem_t data[HTT_DXE_RX_LOG_LEN];
- int idx;
- int enable;
- int wrap;
- int wrapped;
- } reorder_log;
- #endif /* HTT_DXE_RX_LOG */
-
-};
-
-
-
-#endif /* _HTT_DXE_TYPES__H_ */
diff --git a/CORE/HDD/inc/qc_sap_ioctl.h b/CORE/HDD/inc/qc_sap_ioctl.h
index c01b727167ed..61ee976e7ec3 100644
--- a/CORE/HDD/inc/qc_sap_ioctl.h
+++ b/CORE/HDD/inc/qc_sap_ioctl.h
@@ -284,6 +284,7 @@ enum {
QCSAP_PARAM_HIDE_SSID = 8,
QCSAP_PARAM_AUTO_CHANNEL = 9,
QCSAP_PARAM_SET_MC_RATE = 10,
+ QCSAP_PARAM_SET_TXRX_FW_STATS=11,
};
int iw_softap_get_channel_list(struct net_device *dev,
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index c2bdb8a8f3a9..ce509c10ca9f 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -50,7 +50,7 @@
#endif
//Number of items that can be configured
-#define MAX_CFG_INI_ITEMS 320
+#define MAX_CFG_INI_ITEMS 512
// Defines for all of the things we read from the configuration (registry).
@@ -1411,6 +1411,11 @@ typedef enum
#define CFG_HT_SMPS_CAP_FEATURE_MAX ( 3 )
#define CFG_HT_SMPS_CAP_FEATURE_DEFAULT ( 3 )
+#define CFG_DISABLE_DFS_CH_SWITCH "gDisableDFSChSwitch"
+#define CFG_DISABLE_DFS_CH_SWITCH_MIN ( 0 )
+#define CFG_DISABLE_DFS_CH_SWITCH_MAX ( 1 )
+#define CFG_DISABLE_DFS_CH_SWITCH_DEFAULT ( 0 )
+
#define CFG_REPORT_MAX_LINK_SPEED "gReportMaxLinkSpeed"
#define CFG_REPORT_MAX_LINK_SPEED_MIN ( eHDD_LINK_SPEED_REPORT_ACTUAL )
#define CFG_REPORT_MAX_LINK_SPEED_MAX ( eHDD_LINK_SPEED_REPORT_MAX_SCALED )
@@ -2113,7 +2118,7 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */
#define CFG_SAP_MAX_NO_PEERS "gSoftApMaxPeers"
#define CFG_SAP_MAX_NO_PEERS_MIN (1)
#define CFG_SAP_MAX_NO_PEERS_MAX (32)
-#define CFG_SAP_MAX_NO_PEERS_DEFAULT (14)
+#define CFG_SAP_MAX_NO_PEERS_DEFAULT (32)
/*---------------------------------------------------------------------------
Type declarations
@@ -2556,6 +2561,7 @@ typedef struct
v_U8_t maxWoWFilters;
v_U8_t wowEnable;
v_U8_t maxNumberOfPeers;
+ v_U8_t disableDFSChSwitch;
} hdd_config_t;
/*---------------------------------------------------------------------------
Function declarations and documenation
@@ -2670,6 +2676,7 @@ static __inline unsigned long utilMin( unsigned long a, unsigned long b )
#if defined (QCA_WIFI_2_0) && \
!defined (QCA_WIFI_ISOC)
void hdd_update_tgt_cfg(void *context, void *param);
+void hdd_dfs_indicate_radar(void *context, void *param);
#endif /* QCA_WIFI_2_0 && !QCA_WIFI_ISOC */
#endif
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 245c104caf49..791ade2d26f7 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -162,7 +162,15 @@
#define WLAN_HDD_PUBLIC_ACTION_FRAME 4
#define WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET 24
+#define WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET 24
#define WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET 30
+#define WLAN_HDD_PUBLIC_ACTION_FRAME_CATEGORY_OFFSET 0
+#define WLAN_HDD_PUBLIC_ACTION_FRAME_ACTION_OFFSET 1
+#define WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_OFFSET 2
+#define WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_TYPE_OFFSET 5
+#define WLAN_HDD_VENDOR_SPECIFIC_ACTION 0x09
+#define WLAN_HDD_WFA_OUI 0x506F9A
+#define WLAN_HDD_WFA_P2P_OUI_TYPE 0x09
#define WLAN_HDD_P2P_SOCIAL_CHANNELS 3
#define WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN 1
@@ -206,7 +214,6 @@
#endif
#define HDD_MAC_ADDR_LEN 6
-#define HDD_ROAM_SCAN_CHANNEL_SWITCH_TIME 3
#define HDD_SESSION_ID_ANY 50 //This should be same as CSR_SESSION_ID_ANY
typedef v_U8_t tWlanHddMacAddr[HDD_MAC_ADDR_LEN];
@@ -430,6 +437,7 @@ typedef struct WLAN_WAPI_KEY WLAN_WAPI_KEY;
typedef struct WLAN_WAPI_KEY *pWLAN_WAPI_KEY;
#define WPA_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0]))
+#define WPA_GET_BE24(a) ((u32) ( (a[0] << 16) | (a[1] <<8) | a[2]))
#define WLAN_EID_WAPI 68
#define WAPI_PSK_AKM_SUITE 0x02721400
#define WAPI_CERT_AKM_SUITE 0x01721400
@@ -525,6 +533,7 @@ typedef struct hdd_remain_on_chan_ctx
unsigned int duration;
u64 cookie;
rem_on_channel_request_type_t rem_on_chan_request;
+ v_U32_t p2pRemOnChanTimeStamp;
}hdd_remain_on_chan_ctx_t;
typedef enum{
@@ -1220,12 +1229,17 @@ struct hdd_context_s
#ifdef QCA_WIFI_2_0
v_U32_t target_type;
v_U32_t target_fw_version;
+ v_U32_t dfs_radar_found;
#endif
struct regulatory reg;
#ifdef FEATURE_WLAN_CH_AVOID
v_U16_t unsafe_channel_count;
v_U16_t unsafe_channel_list[NUM_20MHZ_RF_CHANNELS];
#endif /* FEATURE_WLAN_CH_AVOID */
+
+ v_U8_t max_intf_count;
+ v_U8_t current_intf_count;
+
};
diff --git a/CORE/HDD/inc/wlan_hdd_p2p.h b/CORE/HDD/inc/wlan_hdd_p2p.h
index 49fec6b78cbb..a26f086ec28f 100644
--- a/CORE/HDD/inc/wlan_hdd_p2p.h
+++ b/CORE/HDD/inc/wlan_hdd_p2p.h
@@ -37,6 +37,7 @@
#define WAIT_CANCEL_REM_CHAN 1000
#define WAIT_REM_CHAN_READY 1000
#define WAIT_CHANGE_CHANNEL_FOR_OFFCHANNEL_TX 3000
+#define READY_EVENT_PROPOGATE_TIME 2
#define ACTION_FRAME_DEFAULT_WAIT 200
diff --git a/CORE/HDD/inc/wlan_hdd_tdls.h b/CORE/HDD/inc/wlan_hdd_tdls.h
index 2fa866eda447..254dc3786c10 100644
--- a/CORE/HDD/inc/wlan_hdd_tdls.h
+++ b/CORE/HDD/inc/wlan_hdd_tdls.h
@@ -32,9 +32,6 @@
\brief Linux HDD TDLS include file
-Copyright (c) 2012-2013 Qualcomm Atheros, Inc.
-All Rights Reserved.
-Qualcomm Atheros Confidential and Proprietary.
==========================================================================*/
#define MAX_NUM_TDLS_PEER 3
diff --git a/CORE/HDD/inc/wlan_hdd_tgt_cfg.h b/CORE/HDD/inc/wlan_hdd_tgt_cfg.h
index cc15d790d93e..120905a36547 100644
--- a/CORE/HDD/inc/wlan_hdd_tgt_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_tgt_cfg.h
@@ -91,6 +91,13 @@ struct hdd_tgt_cfg {
#ifdef WLAN_FEATURE_11AC
struct hdd_tgt_vht_cap vht_cap;
#endif
+ v_U8_t max_intf_count;
+};
+
+struct hdd_dfs_radar_ind {
+ u_int8_t ieee_chan_number;
+ u_int32_t chan_freq;
+ u_int32_t dfs_radar_status;
};
#endif /* HDD_TGT_CFG_H */
diff --git a/CORE/HDD/src/test.c b/CORE/HDD/src/test.c
deleted file mode 100644
index 9f895d2a6c61..000000000000
--- a/CORE/HDD/src/test.c
+++ /dev/null
@@ -1,10032 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
- *
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file was originally distributed by Qualcomm Atheros, Inc.
- * under proprietary terms before Copyright ownership was assigned
- * to the Linux Foundation.
- */
-
-/** ------------------------------------------------------------------------ *
- ------------------------------------------------------------------------ *
-
-
- \file wlan_hdd_wext.c
-
- \brief Airgo Linux Wireless Extensions Common Control Plane Types and
- interfaces.
-
- $Id: wlan_hdd_wext.c,v 1.34 2007/04/14 01:49:23 jimz Exp jimz $
-
- Copyright (C) 2007 Airgo Networks, Incorporated
-
- This file defines all of the types that are utilized by the CCP module
- of the "Portable" HDD. This file also includes the underlying Linux
- Wireless Extensions Data types referred to by CCP.
-
- ======================================================================== */
-
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/wireless.h>
-#include <macTrace.h>
-#include <wlan_hdd_includes.h>
-#include <wlan_btc_svc.h>
-#include <wlan_nlink_common.h>
-#ifdef WLAN_BTAMP_FEATURE
-#include <bap_hdd_main.h>
-#endif
-#include <vos_api.h>
-#include <net/arp.h>
-#include "ccmApi.h"
-#include "sirParams.h"
-#include "csrApi.h"
-#include "csrInsideApi.h"
-#if defined WLAN_FEATURE_VOWIFI
-#include "smeRrmInternal.h"
-#endif
-#include <aniGlobal.h>
-#include "dot11f.h"
-#include <wlan_hdd_wowl.h>
-#include <wlan_hdd_cfg.h>
-#include <wlan_hdd_wmm.h>
-#include "utilsApi.h"
-#include "wlan_hdd_p2p.h"
-#ifdef FEATURE_WLAN_TDLS
-#include "wlan_hdd_tdls.h"
-#endif
-
-#ifdef QCA_WIFI_2_0
-#include "ieee80211_common.h"
-#include "ol_if_athvar.h"
-#include "dbglog_host.h"
-#include "wma.h"
-#endif
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-#include <linux/earlysuspend.h>
-#endif
-#include "wlan_hdd_power.h"
-#include "qwlan_version.h"
-#include <vos_power.h>
-#include "wlan_hdd_host_offload.h"
-#include "wlan_hdd_keep_alive.h"
-#ifdef WLAN_FEATURE_PACKET_FILTERING
-#include "wlan_hdd_packet_filtering.h"
-#endif
-
-#include <linux/wireless.h>
-#include <net/cfg80211.h>
-#include "wlan_qct_pal_trace.h"
-#include "wlan_qct_tl.h"
-
-#include "wlan_hdd_misc.h"
-#include "bap_hdd_misc.h"
-
-#include "wlan_hdd_dev_pwr.h"
-#include "qc_sap_ioctl.h"
-#include "sme_Api.h"
-#include "wlan_qct_wda.h"
-#ifdef CONFIG_HAS_EARLYSUSPEND
-extern void hdd_suspend_wlan(struct early_suspend *wlan_suspend);
-extern void hdd_resume_wlan(struct early_suspend *wlan_suspend);
-#endif
-
-#ifdef FEATURE_OEM_DATA_SUPPORT
-#define MAX_OEM_DATA_RSP_LEN 2047
-#endif
-
-#define HDD_FINISH_ULA_TIME_OUT 800
-
-extern int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand);
-int hdd_setBand_helper(struct net_device *dev, tANI_U8* ptr);
-
-static int ioctl_debug;
-module_param(ioctl_debug, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-#define STATS_CONTEXT_MAGIC 0x53544154 //STAT
-#define RSSI_CONTEXT_MAGIC 0x52535349 //RSSI
-#define POWER_CONTEXT_MAGIC 0x504F5752 //POWR
-#define SNR_CONTEXT_MAGIC 0x534E5200 //SNR
-
-/* To Validate Channel against the Frequency and Vice-Versa */
-static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2},
- {2422, 3}, {2427, 4}, {2432, 5}, {2437, 6}, {2442, 7}, {2447, 8},
- {2452, 9}, {2457, 10}, {2462, 11}, {2467 ,12}, {2472, 13},
- {2484, 14}, {4920, 240}, {4940, 244}, {4960, 248}, {4980, 252},
- {5040, 208}, {5060, 212}, {5080, 216}, {5180, 36}, {5200, 40}, {5220, 44},
- {5240, 48}, {5260, 52}, {5280, 56}, {5300, 60}, {5320, 64}, {5500, 100},
- {5520, 104}, {5540, 108}, {5560, 112}, {5580, 116}, {5600, 120},
- {5620, 124}, {5640, 128}, {5660, 132}, {5680, 136}, {5700, 140},
- {5745, 149}, {5765, 153}, {5785, 157}, {5805, 161}, {5825, 165} };
-
-#define FREQ_CHAN_MAP_TABLE_SIZE (sizeof(freq_chan_map)/sizeof(freq_chan_map[0]))
-
-#define RC_2_RATE_IDX(_rc) ((_rc) & 0x7)
-#define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1)
-
-#define RC_2_RATE_IDX_11AC(_rc) ((_rc) & 0xf)
-#define HT_RC_2_STREAMS_11AC(_rc) ((((_rc) & 0x30) >> 4) + 1)
-
-/* Private ioctls and their sub-ioctls */
-#define WLAN_PRIV_SET_INT_GET_NONE (SIOCIWFIRSTPRIV + 0)
-#define WE_SET_11D_STATE 1
-#define WE_WOWL 2
-#define WE_SET_POWER 3
-#define WE_SET_MAX_ASSOC 4
-#define WE_SET_SAP_AUTO_CHANNEL_SELECTION 5
-#define WE_SET_DATA_INACTIVITY_TO 6
-#define WE_SET_MAX_TX_POWER 7
-#define WE_SET_HIGHER_DTIM_TRANSITION 8
-#define WE_SET_TM_LEVEL 9
-#define WE_SET_PHYMODE 10
-#define WE_SET_NSS 11
-#define WE_SET_LDPC 12
-#define WE_SET_TX_STBC 13
-#define WE_SET_RX_STBC 14
-#define WE_SET_SHORT_GI 15
-#define WE_SET_RTSCTS 16
-#define WE_SET_CHWIDTH 17
-#define WE_SET_ANI_EN_DIS 18
-#define WE_SET_ANI_POLL_PERIOD 19
-#define WE_SET_ANI_LISTEN_PERIOD 20
-#define WE_SET_ANI_OFDM_LEVEL 21
-#define WE_SET_ANI_CCK_LEVEL 22
-#define WE_SET_DYNAMIC_BW 23
-#define WE_SET_TX_CHAINMASK 24
-#define WE_SET_RX_CHAINMASK 25
-#define WE_SET_11N_RATE 26
-#define WE_SET_AMPDU 27
-#define WE_SET_AMSDU 28
-#define WE_SET_TXPOW_2G 29
-#define WE_SET_TXPOW_5G 30
-/* Private ioctl for firmware debug log */
-#define WE_DBGLOG_LOG_LEVEL 31
-#define WE_DBGLOG_VAP_ENABLE 32
-#define WE_DBGLOG_VAP_DISABLE 33
-#define WE_DBGLOG_MODULE_ENABLE 34
-#define WE_DBGLOG_MODULE_DISABLE 35
-#define WE_DBGLOG_MOD_LOG_LEVEL 36
-#define WE_DBGLOG_TYPE 37
-#define WE_SET_TXRX_FWSTATS 38
-#define WE_SET_VHT_RATE 39
-#define WE_DBGLOG_REPORT_ENABLE 40
-#define WE_TXRX_FWSTATS_RESET 41
-#define WE_SET_MAX_TX_POWER_2_4 42
-#define WE_SET_MAX_TX_POWER_5_0 43
-#define WE_SET_POWER_GATING 44
-/* Private ioctl for packet powe save */
-#define WE_PPS_PAID_MATCH 45
-#define WE_PPS_GID_MATCH 46
-#define WE_PPS_EARLY_TIM_CLEAR 47
-#define WE_PPS_EARLY_DTIM_CLEAR 48
-#define WE_PPS_EOF_PAD_DELIM 49
-#define WE_PPS_MACADDR_MISMATCH 50
-#define WE_PPS_DELIM_CRC_FAIL 51
-#define WE_PPS_GID_NSTS_ZERO 52
-#define WE_PPS_RSSI_CHECK 53
-#define WE_ENABLE_STRICT_FCC_REG 54
-
-/* Private ioctls and their sub-ioctls */
-#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1)
-#define WE_GET_11D_STATE 1
-#define WE_IBSS_STATUS 2
-#define WE_PMC_STATE 3
-#define WE_GET_WLAN_DBG 4
-#define WE_MODULE_DOWN_IND 5
-#define WE_GET_MAX_ASSOC 6
-#define WE_GET_WDI_DBG 7
-#define WE_GET_SAP_AUTO_CHANNEL_SELECTION 8
-#define WE_GET_CONCURRENCY_MODE 9
-#ifdef QCA_WIFI_2_0
-#define WE_GET_NSS 11
-#define WE_GET_LDPC 12
-#define WE_GET_TX_STBC 13
-#define WE_GET_RX_STBC 14
-#define WE_GET_SHORT_GI 15
-#define WE_GET_RTSCTS 16
-#define WE_GET_CHWIDTH 17
-#define WE_GET_ANI_EN_DIS 18
-#define WE_GET_ANI_POLL_PERIOD 19
-#define WE_GET_ANI_LISTEN_PERIOD 20
-#define WE_GET_ANI_OFDM_LEVEL 21
-#define WE_GET_ANI_CCK_LEVEL 22
-#define WE_GET_DYNAMIC_BW 23
-#define WE_GET_TX_CHAINMASK 24
-#define WE_GET_RX_CHAINMASK 25
-#define WE_GET_11N_RATE 26
-#define WE_GET_AMPDU 27
-#define WE_GET_AMSDU 28
-#define WE_GET_TXPOW_2G 29
-#define WE_GET_TXPOW_5G 30
-#define WE_GET_POWER_GATING 31
-#define WE_GET_PPS_PAID_MATCH 32
-#define WE_GET_PPS_GID_MATCH 33
-#define WE_GET_PPS_EARLY_TIM_CLEAR 34
-#define WE_GET_PPS_EARLY_DTIM_CLEAR 35
-#define WE_GET_PPS_EOF_PAD_DELIM 36
-#define WE_GET_PPS_MACADDR_MISMATCH 37
-#define WE_GET_PPS_DELIM_CRC_FAIL 38
-#define WE_GET_PPS_GID_NSTS_ZERO 39
-#define WE_GET_PPS_RSSI_CHECK 40
-#endif
-
-/* Private ioctls and their sub-ioctls */
-#define WLAN_PRIV_SET_INT_GET_INT (SIOCIWFIRSTPRIV + 2)
-
-/* Private ioctls and their sub-ioctls */
-#define WLAN_PRIV_SET_CHAR_GET_NONE (SIOCIWFIRSTPRIV + 3)
-#define WE_WOWL_ADD_PTRN 1
-#define WE_WOWL_DEL_PTRN 2
-#if defined WLAN_FEATURE_VOWIFI
-#define WE_NEIGHBOR_REPORT_REQUEST 3
-#endif
-#define WE_SET_AP_WPS_IE 4 //This is called in station mode to set probe rsp ie.
-#define WE_SET_CONFIG 5
-
-/* Private ioctls and their sub-ioctls */
-#define WLAN_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV + 4)
-#define WE_SET_WLAN_DBG 1
-#define WE_SET_WDI_DBG 2
-#define WE_SET_SAP_CHANNELS 3
-
-/* Private ioctls and their sub-ioctls */
-#define WLAN_PRIV_GET_CHAR_SET_NONE (SIOCIWFIRSTPRIV + 5)
-#define WE_WLAN_VERSION 1
-#define WE_GET_STATS 2
-#define WE_GET_CFG 3
-#define WE_GET_WMM_STATUS 4
-#define WE_GET_CHANNEL_LIST 5
-#ifdef WLAN_FEATURE_11AC
-#define WE_GET_RSSI 6
-#endif
-#define WE_GET_ROAM_RSSI 7
-#ifdef FEATURE_WLAN_TDLS
-#define WE_GET_TDLS_PEERS 8
-#endif
-#ifdef WLAN_FEATURE_11W
-#define WE_GET_11W_INFO 9
-#endif
-#define WE_GET_STATES 10
-#ifdef FEATURE_CESIUM_PROPRIETARY
-#define WE_GET_IBSS_STA_INFO 11
-#endif
-#ifdef QCA_WIFI_2_0
-#define WE_GET_PHYMODE 12
-#endif
-
-/* Private ioctls and their sub-ioctls */
-#define WLAN_PRIV_SET_NONE_GET_NONE (SIOCIWFIRSTPRIV + 6)
-#define WE_CLEAR_STATS 1
-#define WE_INIT_AP 2
-#define WE_STOP_AP 3
-#define WE_ENABLE_AMP 4
-#define WE_DISABLE_AMP 5
-#define WE_ENABLE_DXE_STALL_DETECT 6
-#define WE_DISPLAY_DXE_SNAP_SHOT 7
-#define WE_SET_REASSOC_TRIGGER 8
-#define WE_DISPLAY_DATAPATH_SNAP_SHOT 9
-#ifdef FEATURE_CESIUM_PROPRIETARY
-#define WE_IBSS_GET_PEER_INFO_ALL 10
-#endif
-#ifdef QCA_WIFI_2_0
-#define WE_DUMP_AGC_START 11
-#define WE_DUMP_AGC 12
-#define WE_DUMP_CHANINFO_START 13
-#define WE_DUMP_CHANINFO 14
-#define WE_DUMP_WATCHDOG 15
-#ifdef DEBUG
-#define WE_SET_FW_CRASH_INJECT 16
-#endif
-#endif
-
-/* Private ioctls and their sub-ioctls */
-#define WLAN_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV + 7)
-#define WE_LOG_DUMP_CMD 1
-
-#define WE_P2P_NOA_CMD 2
-//IOCTL to configure MCC params
-#define WE_MCC_CONFIG_CREDENTIAL 3
-#define WE_MCC_CONFIG_PARAMS 4
-
-#ifdef FEATURE_WLAN_TDLS
-#define WE_TDLS_CONFIG_PARAMS 5
-#endif
-#ifdef FEATURE_CESIUM_PROPRIETARY
-#define WE_IBSS_GET_PEER_INFO 6
-#endif
-#ifdef FEATURE_WLAN_TDLS
-#undef MAX_VAR_ARGS
-#define MAX_VAR_ARGS 10
-#else
-#define MAX_VAR_ARGS 7
-#endif
-
-
-/* Private ioctls (with no sub-ioctls) */
-/* note that they must be odd so that they have "get" semantics */
-#define WLAN_PRIV_ADD_TSPEC (SIOCIWFIRSTPRIV + 9)
-#define WLAN_PRIV_DEL_TSPEC (SIOCIWFIRSTPRIV + 11)
-#define WLAN_PRIV_GET_TSPEC (SIOCIWFIRSTPRIV + 13)
-
-#ifdef FEATURE_WLAN_WAPI
-/* Private ioctls EVEN NO: SET, ODD NO:GET */
-#define WLAN_PRIV_SET_WAPI_MODE (SIOCIWFIRSTPRIV + 8)
-#define WLAN_PRIV_GET_WAPI_MODE (SIOCIWFIRSTPRIV + 16)
-#define WLAN_PRIV_SET_WAPI_ASSOC_INFO (SIOCIWFIRSTPRIV + 10)
-#define WLAN_PRIV_SET_WAPI_KEY (SIOCIWFIRSTPRIV + 12)
-#define WLAN_PRIV_SET_WAPI_BKID (SIOCIWFIRSTPRIV + 14)
-#define WLAN_PRIV_GET_WAPI_BKID (SIOCIWFIRSTPRIV + 15)
-#define WAPI_PSK_AKM_SUITE 0x02721400
-#define WAPI_CERT_AKM_SUITE 0x01721400
-#endif
-
-#ifdef FEATURE_OEM_DATA_SUPPORT
-/* Private ioctls for setting the measurement configuration */
-#define WLAN_PRIV_SET_OEM_DATA_REQ (SIOCIWFIRSTPRIV + 17)
-#define WLAN_PRIV_GET_OEM_DATA_RSP (SIOCIWFIRSTPRIV + 19)
-#endif
-
-#ifdef WLAN_FEATURE_VOWIFI_11R
-#define WLAN_PRIV_SET_FTIES (SIOCIWFIRSTPRIV + 20)
-#endif
-
-/* Private ioctl for setting the host offload feature */
-#define WLAN_PRIV_SET_HOST_OFFLOAD (SIOCIWFIRSTPRIV + 18)
-
-/* Private ioctl to get the statistics */
-#define WLAN_GET_WLAN_STATISTICS (SIOCIWFIRSTPRIV + 21)
-
-/* Private ioctl to set the Keep Alive Params */
-#define WLAN_SET_KEEPALIVE_PARAMS (SIOCIWFIRSTPRIV + 22)
-#ifdef WLAN_FEATURE_PACKET_FILTERING
-/* Private ioctl to set the Packet Filtering Params */
-#define WLAN_SET_PACKET_FILTER_PARAMS (SIOCIWFIRSTPRIV + 23)
-#endif
-
-#ifdef FEATURE_WLAN_SCAN_PNO
-/* Private ioctl to get the statistics */
-#define WLAN_SET_PNO (SIOCIWFIRSTPRIV + 24)
-#endif
-
-#define WLAN_SET_BAND_CONFIG (SIOCIWFIRSTPRIV + 25) /*Don't change this number*/
-
-#define WLAN_PRIV_SET_MCBC_FILTER (SIOCIWFIRSTPRIV + 26)
-#define WLAN_PRIV_CLEAR_MCBC_FILTER (SIOCIWFIRSTPRIV + 27)
-/* Private ioctl to trigger reassociation */
-
-#define WLAN_SET_POWER_PARAMS (SIOCIWFIRSTPRIV + 29)
-#ifdef FEATURE_OEM_DATA_SUPPORT
-#ifdef QCA_WIFI_2_0
-/* Private ioctl to get capability information for OEM Data Request/Response */
-#define WLAN_PRIV_GET_OEM_DATA_CAP (SIOCIWFIRSTPRIV + 30)
-#endif
-#endif
-#define WLAN_GET_LINK_SPEED (SIOCIWFIRSTPRIV + 31)
-
-#define WLAN_STATS_INVALID 0
-#define WLAN_STATS_RETRY_CNT 1
-#define WLAN_STATS_MUL_RETRY_CNT 2
-#define WLAN_STATS_TX_FRM_CNT 3
-#define WLAN_STATS_RX_FRM_CNT 4
-#define WLAN_STATS_FRM_DUP_CNT 5
-#define WLAN_STATS_FAIL_CNT 6
-#define WLAN_STATS_RTS_FAIL_CNT 7
-#define WLAN_STATS_ACK_FAIL_CNT 8
-#define WLAN_STATS_RTS_SUC_CNT 9
-#define WLAN_STATS_RX_DISCARD_CNT 10
-#define WLAN_STATS_RX_ERROR_CNT 11
-#define WLAN_STATS_TX_BYTE_CNT 12
-
-#define WLAN_STATS_RX_BYTE_CNT 13
-#define WLAN_STATS_RX_RATE 14
-#define WLAN_STATS_TX_RATE 15
-
-#define WLAN_STATS_RX_UC_BYTE_CNT 16
-#define WLAN_STATS_RX_MC_BYTE_CNT 17
-#define WLAN_STATS_RX_BC_BYTE_CNT 18
-#define WLAN_STATS_TX_UC_BYTE_CNT 19
-#define WLAN_STATS_TX_MC_BYTE_CNT 20
-#define WLAN_STATS_TX_BC_BYTE_CNT 21
-
-#define FILL_TLV(__p, __type, __size, __val, __tlen) do { \
- if ((__tlen + __size + 2) < WE_MAX_STR_LEN) \
- { \
- *__p++ = __type; \
- *__p++ = __size; \
- memcpy(__p, __val, __size); \
- __p += __size; \
- __tlen += __size + 2; \
- } \
- else \
- { \
- hddLog(VOS_TRACE_LEVEL_ERROR, "FILL_TLV Failed!!!\n"); \
- } \
- } while(0);
-
-#define VERSION_VALUE_MAX_LEN 32
-
-#define TX_PER_TRACKING_DEFAULT_RATIO 5
-#define TX_PER_TRACKING_MAX_RATIO 10
-#define TX_PER_TRACKING_DEFAULT_WATERMARK 5
-
-#define WLAN_ADAPTER 0
-#define P2P_ADAPTER 1
-
-/*MCC Configuration parameters */
-enum {
- MCC_SCHEDULE_TIME_SLICE_CFG_PARAM = 1,
- MCC_MAX_NULL_SEND_TIME_CFG_PARAM,
- MCC_TX_EARLY_STOP_TIME_CFG_PARAM,
- MCC_RX_DRAIN_TIME_CFG_PARAM,
- MCC_CHANNEL_SWITCH_TIME_CFG_PARAM,
- MCC_MIN_CHANNEL_TIME_CFG_PARAM,
- MCC_PARK_BEFORE_TBTT_CFG_PARAM,
- MCC_MIN_AFTER_DTIM_CFG_PARAM,
- MCC_TOO_CLOSE_MARGIN_CFG_PARAM,
-};
-
-int hdd_validate_mcc_config(hdd_adapter_t *pAdapter, v_UINT_t staId,
- v_UINT_t arg1, v_UINT_t arg2, v_UINT_t arg3);
-
-#ifdef WLAN_FEATURE_PACKET_FILTERING
-int wlan_hdd_set_filter(hdd_context_t *pHddCtx, tpPacketFilterCfg pRequest,
- v_U8_t sessionId);
-#endif
-
-/**---------------------------------------------------------------------------
-
- \brief hdd_wlan_get_version() -
-
- This function use to get Wlan Driver, Firmware, & Hardware Version.
-
- \param - pAdapter Pointer to the adapter.
- wrqu - Pointer to IOCTL REQUEST Data.
- extra - Pointer to char
-
- \return - none
-
- --------------------------------------------------------------------------*/
-void hdd_wlan_get_version(hdd_adapter_t *pAdapter, union iwreq_data *wrqu,
- char *extra)
-{
- VOS_STATUS status;
- tSirVersionString wcnss_SW_version;
- tSirVersionString wcnss_HW_version;
- char *pSWversion;
- char *pHWversion;
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
-
- status = sme_GetWcnssSoftwareVersion(hHal, wcnss_SW_version,
- sizeof(wcnss_SW_version));
- if (VOS_IS_STATUS_SUCCESS(status))
- {
- pSWversion = wcnss_SW_version;
- }
- else
- {
- pSWversion = "Unknown";
- }
-
- status = sme_GetWcnssHardwareVersion(hHal, wcnss_HW_version,
- sizeof(wcnss_HW_version));
- if (VOS_IS_STATUS_SUCCESS(status))
- {
- pHWversion = wcnss_HW_version;
- }
- else
- {
- pHWversion = "Unknown";
- }
-
- wrqu->data.length = scnprintf(extra, WE_MAX_STR_LEN,
- "Host SW:%s, FW:%s, HW:%s",
- QWLAN_VERSIONSTR,
- pSWversion,
- pHWversion);
-
- return;
-}
-
-#ifdef FEATURE_CESIUM_PROPRIETARY
-void hdd_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
-{
- hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
- hdd_ibss_peer_info_t *pPeerInfo = (hdd_ibss_peer_info_t *)pPeerInfoRsp;
- hdd_station_ctx_t *pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- v_U8_t i;
-
- if (NULL != pPeerInfo && eHAL_STATUS_SUCCESS == pPeerInfo->status)
- {
- pStaCtx->ibss_peer_info.status = pPeerInfo->status;
- pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numIBSSPeers;
- for (i = 0; i < pPeerInfo->numIBSSPeers; i++)
- {
- memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
- &pPeerInfo->ibssPeerList[i], sizeof(hdd_ibss_peer_info_params_t));
- }
- }
- else
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "%s] PEER_INFO_CMD_STATUS is not SUCCESS\n", __func__);
- }
-
- complete(&pAdapter->ibss_peer_info_comp);
-}
-
-v_MACADDR_t* hdd_wlan_get_ibss_mac_addr_from_staid(hdd_adapter_t *pAdapter, v_U8_t staIdx)
-{
- v_U8_t idx;
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
-
- for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
- {
- if ( 0 != pHddStaCtx->conn_info.staId[ idx ] &&
- staIdx == pHddStaCtx->conn_info.staId[ idx ])
- {
- return (&pHddStaCtx->conn_info.peerMacAddress[ idx ]);
- }
- }
- return NULL;
-}
-
-eHalStatus hdd_wlan_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
-{
- eHalStatus status = eHAL_STATUS_FAILURE;
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- hdd_station_ctx_t *pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- hdd_ibss_peer_info_t *pPeerInfo = &pStaCtx->ibss_peer_info;
-
- status = sme_RequestIBSSPeerInfo(hHal, pAdapter, hdd_get_ibss_peer_info_cb,
- VOS_FALSE, staIdx);
-
- INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
-
- if (eHAL_STATUS_SUCCESS == status)
- {
- status = wait_for_completion_interruptible_timeout
- (&pAdapter->ibss_peer_info_comp,
- msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
- if(!status)
- {
- hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT",
- __func__);
- return status;
- }
-
- /** Print the peer info */
- pr_info("pPeerInfo->numIBSSPeers = %d ", pPeerInfo->numIBSSPeers);
- pr_info("============================================================");
- {
- v_MACADDR_t *macAddr = hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
- staIdx);
- v_U32_t txRateMbps = ((pPeerInfo->ibssPeerList[0].txRate)*500*1000)/1000000;
-
- if (NULL != macAddr)
- {
- pr_info("PEER ADDR :" MAC_ADDRESS_STR " TxRate: %d Mbps RSSI: %d",
- MAC_ADDR_ARRAY(macAddr->bytes),
- (int)txRateMbps, (int)pPeerInfo->ibssPeerList[0].rssi);
- }
- else
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- " ERROR: PEER MAC ADDRESS NOT FOUND ");
- }
- }
- }
- else
- {
- hddLog(VOS_TRACE_LEVEL_WARN,
- "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
- }
-
- return status;
-}
-
-eHalStatus hdd_wlan_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
-{
- eHalStatus status = eHAL_STATUS_FAILURE;
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- hdd_station_ctx_t *pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- hdd_ibss_peer_info_t *pPeerInfo = &pStaCtx->ibss_peer_info;
- int i;
-
- status = sme_RequestIBSSPeerInfo(hHal, pAdapter, hdd_get_ibss_peer_info_cb,
- VOS_TRUE, 0xFF);
- INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
-
- if (eHAL_STATUS_SUCCESS == status)
- {
- status = wait_for_completion_interruptible_timeout
- (&pAdapter->ibss_peer_info_comp,
- msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
- if(!status)
- {
- hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT",
- __func__);
- return status;
- }
-
- /** Print the peer info */
- pr_info("pPeerInfo->numIBSSPeers = %d ", (int)pPeerInfo->numIBSSPeers);
- pr_info("============================================================");
- for (i = 0; i < pPeerInfo->numIBSSPeers; i++)
- {
- v_U8_t staIdx = pPeerInfo->ibssPeerList[i].staIdx;
- v_MACADDR_t *macAddr = hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
- staIdx);
- v_U32_t txRateMbps = ((pPeerInfo->ibssPeerList[0].txRate)*500*1000)/1000000;
-
- pr_info("STAIDX:%d ", (int)pPeerInfo->ibssPeerList[i].staIdx);
- if (NULL != macAddr)
- {
- pr_info(" PEER ADDR :" MAC_ADDRESS_STR " TxRate: %d Mbps RSSI: %d",
- MAC_ADDR_ARRAY(macAddr->bytes),
- (int)txRateMbps, (int)pPeerInfo->ibssPeerList[i].rssi);
- }
- else
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- " ERROR: PEER MAC ADDRESS NOT FOUND ");
- }
- }
- }
- else
- {
- hddLog(VOS_TRACE_LEVEL_WARN,
- "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
- }
-
- return status;
-}
-#endif /* FEATURE_CESIUM_PROPRIETARY */
-
-int hdd_wlan_get_rts_threshold(hdd_adapter_t *pAdapter, union iwreq_data *wrqu)
-{
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- v_U32_t threshold = 0,status = 0;
-
- ENTER();
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "%s:LOGP in Progress. Ignore!!!",__func__);
- return status;
- }
-
- if ( eHAL_STATUS_SUCCESS !=
- ccmCfgGetInt(hHal, WNI_CFG_RTS_THRESHOLD, &threshold) )
- {
- return -EIO;
- }
- wrqu->rts.value = threshold;
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- ("Rts-Threshold=%ld!!\n"), wrqu->rts.value);
-
- EXIT();
-
- return 0;
-}
-
-int hdd_wlan_get_frag_threshold(hdd_adapter_t *pAdapter, union iwreq_data *wrqu)
-{
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- v_U32_t threshold = 0,status = 0;
-
- ENTER();
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "%s:LOGP in Progress. Ignore!!!",__func__);
- return status;
- }
-
- if ( ccmCfgGetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, &threshold)
- != eHAL_STATUS_SUCCESS )
- {
- return -EIO;
- }
- wrqu->frag.value = threshold;
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- ("Frag-Threshold=%ld!!\n"), wrqu->frag.value);
-
- EXIT();
-
- return 0;
-}
-
-int hdd_wlan_get_freq(v_U32_t channel, v_U32_t *pfreq)
-{
- int i;
- if (channel > 0)
- {
- for (i=0; i < FREQ_CHAN_MAP_TABLE_SIZE; i++)
- {
- if (channel == freq_chan_map[i].chan)
- {
- *pfreq = freq_chan_map[i].freq;
- return 1;
- }
- }
- }
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- ("Invalid channel no=%d!!\n"), channel);
- return -EINVAL;
-}
-
-static v_BOOL_t
-hdd_IsAuthTypeRSN( tHalHandle halHandle, eCsrAuthType authType)
-{
- v_BOOL_t rsnType = VOS_FALSE;
- // is the authType supported?
- switch (authType)
- {
- case eCSR_AUTH_TYPE_NONE: //never used
- rsnType = eANI_BOOLEAN_FALSE;
- break;
- // MAC layer authentication types
- case eCSR_AUTH_TYPE_OPEN_SYSTEM:
- rsnType = eANI_BOOLEAN_FALSE;
- break;
- case eCSR_AUTH_TYPE_SHARED_KEY:
- rsnType = eANI_BOOLEAN_FALSE;
- break;
- case eCSR_AUTH_TYPE_AUTOSWITCH:
- rsnType = eANI_BOOLEAN_FALSE;
- break;
-
- // Upper layer authentication types
- case eCSR_AUTH_TYPE_WPA:
- rsnType = eANI_BOOLEAN_TRUE;
- break;
- case eCSR_AUTH_TYPE_WPA_PSK:
- rsnType = eANI_BOOLEAN_TRUE;
- break;
- case eCSR_AUTH_TYPE_WPA_NONE:
- rsnType = eANI_BOOLEAN_TRUE;
- break;
-#ifdef WLAN_FEATURE_VOWIFI_11R
- case eCSR_AUTH_TYPE_FT_RSN:
-#endif
- case eCSR_AUTH_TYPE_RSN:
- rsnType = eANI_BOOLEAN_TRUE;
- break;
-#ifdef WLAN_FEATURE_VOWIFI_11R
- case eCSR_AUTH_TYPE_FT_RSN_PSK:
-#endif
- case eCSR_AUTH_TYPE_RSN_PSK:
-#ifdef WLAN_FEATURE_11W
- case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
-#endif
- rsnType = eANI_BOOLEAN_TRUE;
- break;
- //case eCSR_AUTH_TYPE_FAILED:
- case eCSR_AUTH_TYPE_UNKNOWN:
- rsnType = eANI_BOOLEAN_FALSE;
- break;
- default:
- hddLog(LOGE, FL("%s called with unknown authType - default to Open, None\n"),
- __func__);
- rsnType = eANI_BOOLEAN_FALSE;
- break;
- }
- hddLog(LOGE, FL("%s called with authType: %d, returned: %d\n"),
- __func__, authType, rsnType);
- return rsnType;
-}
-
-static void hdd_GetRssiCB( v_S7_t rssi, tANI_U32 staId, void *pContext )
-{
- struct statsContext *pStatsContext;
- hdd_adapter_t *pAdapter;
-
- if (ioctl_debug)
- {
- pr_info("%s: rssi [%d] STA [%d] pContext [%p]\n",
- __func__, (int)rssi, (int)staId, pContext);
- }
-
- if (NULL == pContext)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Bad param, pContext [%p]",
- __func__, pContext);
- return;
- }
-
- /* there is a race condition that exists between this callback function
- and the caller since the caller could time out either before or
- while this code is executing. we'll assume the timeout hasn't
- occurred, but we'll verify that right before we save our work */
-
- pStatsContext = pContext;
- pAdapter = pStatsContext->pAdapter;
- if ((NULL == pAdapter) || (RSSI_CONTEXT_MAGIC != pStatsContext->magic))
- {
- /* the caller presumably timed out so there is nothing we can do */
- hddLog(VOS_TRACE_LEVEL_WARN,
- "%s: Invalid context, pAdapter [%p] magic [%08x]",
- __func__, pAdapter, pStatsContext->magic);
- if (ioctl_debug)
- {
- pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
- __func__, pAdapter, pStatsContext->magic);
- }
- return;
- }
-
- /* the race is on. caller could have timed out immediately after
- we verified the magic, but if so, caller will wait a short time
- for us to copy over the rssi */
- pAdapter->rssi = rssi;
-
- /* and notify the caller */
- complete(&pStatsContext->completion);
-}
-
-static void hdd_GetSnrCB(tANI_S8 snr, tANI_U32 staId, void *pContext)
-{
- struct statsContext *pStatsContext;
- hdd_adapter_t *pAdapter;
-
- if (ioctl_debug)
- {
- pr_info("%s: snr [%d] STA [%d] pContext [%p]\n",
- __func__, (int)snr, (int)staId, pContext);
- }
-
- if (NULL == pContext)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Bad param, pContext [%p]",
- __func__, pContext);
- return;
- }
-
- /* there is a race condition that exists between this callback function
- * and the caller since the caller could time out either before or
- * while this code is executing. we'll assume the timeout hasn't
- * occurred, but we'll verify that right before we save our work
- */
-
- pStatsContext = pContext;
- pAdapter = pStatsContext->pAdapter;
- if ((NULL == pAdapter) || (SNR_CONTEXT_MAGIC != pStatsContext->magic))
- {
- /* the caller presumably timed out so there is nothing we can do */
- hddLog(VOS_TRACE_LEVEL_WARN,
- "%s: Invalid context, pAdapter [%p] magic [%08x]",
- __func__, pAdapter, pStatsContext->magic);
- if (ioctl_debug)
- {
- pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
- __func__, pAdapter, pStatsContext->magic);
- }
- return;
- }
-
- /* the race is on. caller could have timed out immediately after
- * we verified the magic, but if so, caller will wait a short time
- * for us to copy over the snr
- */
- pAdapter->snr = snr;
-
- /* and notify the caller */
- complete(&pStatsContext->completion);
-}
-
-VOS_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value)
-{
- struct statsContext context;
- hdd_context_t *pHddCtx;
- hdd_station_ctx_t *pHddStaCtx;
- eHalStatus hstatus;
- long lrc;
-
- if (NULL == pAdapter)
- {
- hddLog(VOS_TRACE_LEVEL_WARN,
- "%s: Invalid context, pAdapter", __func__);
- return VOS_STATUS_E_FAULT;
- }
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!",__func__);
- /* return a cached value */
- *rssi_value = pAdapter->rssi;
- return VOS_STATUS_SUCCESS;
- }
-
- pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
-
- init_completion(&context.completion);
- context.pAdapter = pAdapter;
- context.magic = RSSI_CONTEXT_MAGIC;
-
- hstatus = sme_GetRssi(pHddCtx->hHal, hdd_GetRssiCB,
- pHddStaCtx->conn_info.staId[ 0 ],
- pHddStaCtx->conn_info.bssId,
- &context, pHddCtx->pvosContext);
- if (eHAL_STATUS_SUCCESS != hstatus)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Unable to retrieve RSSI",
- __func__);
- /* we'll returned a cached value below */
- }
- else
- {
- /* request was sent -- wait for the response */
- lrc = wait_for_completion_interruptible_timeout(&context.completion,
- msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
- /* either we have a response or we timed out
- either way, first invalidate our magic */
- context.magic = 0;
- if (lrc <= 0)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while retrieving RSSI ",
- __func__, (0 == lrc) ? "timeout" : "interrupt");
- /* there is a race condition such that the callback
- function could be executing at the same time we are. of
- primary concern is if the callback function had already
- verified the "magic" but hasn't yet set the completion
- variable. Since the completion variable is on our
- stack, we'll delay just a bit to make sure the data is
- still valid if that is the case */
- msleep(50);
- /* we'll now returned a cached value below */
- }
- }
- *rssi_value = pAdapter->rssi;
-
- return VOS_STATUS_SUCCESS;
-}
-
-VOS_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, v_S7_t *snr)
-{
- struct statsContext context;
- hdd_context_t *pHddCtx;
- hdd_station_ctx_t *pHddStaCtx;
- eHalStatus hstatus;
- long lrc;
- int valid;
-
- if (NULL == pAdapter)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Invalid context, pAdapter", __func__);
- return VOS_STATUS_E_FAULT;
- }
-
- pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
-
- valid = wlan_hdd_validate_context(pHddCtx);
- if (0 != valid)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
- return VOS_STATUS_E_FAULT;
- }
-
- pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- if (NULL == pHddStaCtx)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is not valid"));
- return VOS_STATUS_E_FAULT;
- }
-
- init_completion(&context.completion);
- context.pAdapter = pAdapter;
- context.magic = SNR_CONTEXT_MAGIC;
-
- hstatus = sme_GetSnr(pHddCtx->hHal, hdd_GetSnrCB,
- pHddStaCtx->conn_info.staId[ 0 ],
- pHddStaCtx->conn_info.bssId,
- &context);
- if (eHAL_STATUS_SUCCESS != hstatus)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Unable to retrieve RSSI",
- __func__);
- /* we'll returned a cached value below */
- }
- else
- {
- /* request was sent -- wait for the response */
- lrc = wait_for_completion_interruptible_timeout(&context.completion,
- msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
- /* either we have a response or we timed out
- * either way, first invalidate our magic
- */
- context.magic = 0;
- if (lrc <= 0)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while retrieving SNR ",
- __func__, (0 == lrc) ? "timeout" : "interrupt");
- /* there is a race condition such that the callback
- * function could be executing at the same time we are. Of
- * primary concern is if the callback function had already
- * verified the "magic" but hasn't yet set the completion
- * variable. Since the completion variable is on our
- * stack, we'll delay just a bit to make sure the data is
- * still valid if that is the case
- */
- msleep(50);
- /* we'll now returned a cached value below */
- }
- }
- *snr = pAdapter->snr;
-
- return VOS_STATUS_SUCCESS;
-}
-#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_CCX || defined(FEATURE_WLAN_LFR)
-
-static void hdd_GetRoamRssiCB( v_S7_t rssi, tANI_U32 staId, void *pContext )
-{
- struct statsContext *pStatsContext;
- hdd_adapter_t *pAdapter;
- if (ioctl_debug)
- {
- pr_info("%s: rssi [%d] STA [%d] pContext [%p]\n",
- __func__, (int)rssi, (int)staId, pContext);
- }
-
- if (NULL == pContext)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Bad param, pContext [%p]",
- __func__, pContext);
- return;
- }
-
- /* there is a race condition that exists between this callback function
- and the caller since the caller could time out either before or
- while this code is executing. we'll assume the timeout hasn't
- occurred, but we'll verify that right before we save our work */
-
- pStatsContext = pContext;
- pAdapter = pStatsContext->pAdapter;
- if ((NULL == pAdapter) || (RSSI_CONTEXT_MAGIC != pStatsContext->magic))
- {
- /* the caller presumably timed out so there is nothing we can do */
- hddLog(VOS_TRACE_LEVEL_WARN,
- "%s: Invalid context, pAdapter [%p] magic [%08x]",
- __func__, pAdapter, pStatsContext->magic);
- if (ioctl_debug)
- {
- pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
- __func__, pAdapter, pStatsContext->magic);
- }
- return;
- }
-
- /* the race is on. caller could have timed out immediately after
- we verified the magic, but if so, caller will wait a short time
- for us to copy over the rssi */
- pAdapter->rssi = rssi;
-
- /* and notify the caller */
- complete(&pStatsContext->completion);
-}
-
-
-
-VOS_STATUS wlan_hdd_get_roam_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value)
-{
- struct statsContext context;
- hdd_context_t *pHddCtx = NULL;
- hdd_station_ctx_t *pHddStaCtx = NULL;
- eHalStatus hstatus;
- long lrc;
-
- if (NULL == pAdapter)
- {
- hddLog(VOS_TRACE_LEVEL_WARN,
- "%s: Invalid context, pAdapter", __func__);
- return VOS_STATUS_E_FAULT;
- }
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!",__func__);
- /* return a cached value */
- *rssi_value = pAdapter->rssi;
- return VOS_STATUS_SUCCESS;
- }
-
- pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
-
- if(eConnectionState_Associated != pHddStaCtx->conn_info.connState)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
- /* return a cached value */
- *rssi_value = 0;
- return VOS_STATUS_SUCCESS;
- }
- init_completion(&context.completion);
- context.pAdapter = pAdapter;
- context.magic = RSSI_CONTEXT_MAGIC;
-
- hstatus = sme_GetRoamRssi(pHddCtx->hHal, hdd_GetRoamRssiCB,
- pHddStaCtx->conn_info.staId[ 0 ],
- pHddStaCtx->conn_info.bssId,
- &context, pHddCtx->pvosContext);
- if (eHAL_STATUS_SUCCESS != hstatus)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Unable to retrieve RSSI",
- __func__);
- /* we'll returned a cached value below */
- }
- else
- {
- /* request was sent -- wait for the response */
- lrc = wait_for_completion_interruptible_timeout(&context.completion,
- msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
- /* either we have a response or we timed out
- either way, first invalidate our magic */
- context.magic = 0;
- if (lrc <= 0)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while retrieving RSSI ",
- __func__, (0 == lrc) ? "timeout" : "interrupt");
- /* there is a race condition such that the callback
- function could be executing at the same time we are. of
- primary concern is if the callback function had already
- verified the "magic" but hasn't yet set the completion
- variable. Since the completion variable is on our
- stack, we'll delay just a bit to make sure the data is
- still valid if that is the case */
- msleep(50);
- /* we'll now returned a cached value below */
- }
- }
- *rssi_value = pAdapter->rssi;
-
- return VOS_STATUS_SUCCESS;
-}
-#endif
-
-
-void hdd_StatisticsCB( void *pStats, void *pContext )
-{
- hdd_adapter_t *pAdapter = (hdd_adapter_t *)pContext;
- hdd_stats_t *pStatsCache = NULL;
- hdd_wext_state_t *pWextState;
- VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
-
- tCsrSummaryStatsInfo *pSummaryStats = NULL;
- tCsrGlobalClassAStatsInfo *pClassAStats = NULL;
- tCsrGlobalClassBStatsInfo *pClassBStats = NULL;
- tCsrGlobalClassCStatsInfo *pClassCStats = NULL;
- tCsrGlobalClassDStatsInfo *pClassDStats = NULL;
- tCsrPerStaStatsInfo *pPerStaStats = NULL;
-
- if (pAdapter!= NULL)
- pStatsCache = &pAdapter->hdd_stats;
-
-
- pSummaryStats = (tCsrSummaryStatsInfo *)pStats;
- pClassAStats = (tCsrGlobalClassAStatsInfo *)( pSummaryStats + 1 );
- pClassBStats = (tCsrGlobalClassBStatsInfo *)( pClassAStats + 1 );
- pClassCStats = (tCsrGlobalClassCStatsInfo *)( pClassBStats + 1 );
- pClassDStats = (tCsrGlobalClassDStatsInfo *)( pClassCStats + 1 );
- pPerStaStats = (tCsrPerStaStatsInfo *)( pClassDStats + 1 );
-
- if (pStatsCache!=NULL)
- {
- // and copy the stats into the cache we keep in the adapter instance structure
- vos_mem_copy( &pStatsCache->summary_stat, pSummaryStats, sizeof( pStatsCache->summary_stat ) );
- vos_mem_copy( &pStatsCache->ClassA_stat, pClassAStats, sizeof( pStatsCache->ClassA_stat ) );
- vos_mem_copy( &pStatsCache->ClassB_stat, pClassBStats, sizeof( pStatsCache->ClassB_stat ) );
- vos_mem_copy( &pStatsCache->ClassC_stat, pClassCStats, sizeof( pStatsCache->ClassC_stat ) );
- vos_mem_copy( &pStatsCache->ClassD_stat, pClassDStats, sizeof( pStatsCache->ClassD_stat ) );
- vos_mem_copy( &pStatsCache->perStaStats, pPerStaStats, sizeof( pStatsCache->perStaStats ) );
- }
-
- if(pAdapter)
- {
- pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
- if(pWextState)
- {
- vos_status = vos_event_set(&pWextState->vosevent);
- if (!VOS_IS_STATUS_SUCCESS(vos_status))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "%s: vos_event_set failed", __func__);
- return;
- }
- }
- }
-}
-
-void ccmCfgSetCallback(tHalHandle halHandle, tANI_S32 result)
-{
- v_CONTEXT_t pVosContext;
- hdd_context_t *pHddCtx;
- VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx );
-#if 0
- hdd_wext_state_t *pWextState;
- v_U32_t roamId;
-#endif
-
- ENTER();
-
- pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS,NULL);
-
- pHddCtx = (hdd_context_t*) vos_get_context(VOS_MODULE_ID_HDD,pVosContext);
- if (NULL == pHddCtx)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid pHddCtx", __func__);
- return;
- }
-#if 0
- pWextState = pAdapter->pWextState;
-#endif
-
- if (WNI_CFG_NEED_RESTART == result || WNI_CFG_NEED_RELOAD == result)
- {
- //TODO Verify is this is really used. If yes need to fix it.
- hdd_reconnect_all_adapters( pHddCtx );
-#if 0
- pAdapter->conn_info.connState = eConnectionState_NotConnected;
- INIT_COMPLETION(pAdapter->disconnect_comp_var);
- vosStatus = sme_RoamDisconnect(halHandle, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
-
- if(VOS_STATUS_SUCCESS == vosStatus)
- wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
- msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
-
- sme_RoamConnect(halHandle,
- pAdapter->sessionId, &(pWextState->roamProfile),
- &roamId);
-#endif
- }
-
- EXIT();
-
-}
-
-void hdd_clearRoamProfileIe( hdd_adapter_t *pAdapter)
-{
- int i = 0;
- hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
-
- /* clear WPA/RSN/WSC IE information in the profile */
- pWextState->roamProfile.nWPAReqIELength = 0;
- pWextState->roamProfile.pWPAReqIE = (tANI_U8 *)NULL;
- pWextState->roamProfile.nRSNReqIELength = 0;
- pWextState->roamProfile.pRSNReqIE = (tANI_U8 *)NULL;
-
-#ifdef FEATURE_WLAN_WAPI
- pWextState->roamProfile.nWAPIReqIELength = 0;
- pWextState->roamProfile.pWAPIReqIE = (tANI_U8 *)NULL;
-#endif
-
- pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
- pWextState->roamProfile.pAddIEScan = (tANI_U8 *)NULL;
- pWextState->roamProfile.nAddIEScanLength = 0;
- pWextState->roamProfile.pAddIEAssoc = (tANI_U8 *)NULL;
- pWextState->roamProfile.nAddIEAssocLength = 0;
-
- pWextState->roamProfile.EncryptionType.numEntries = 1;
- pWextState->roamProfile.EncryptionType.encryptionType[0]
- = eCSR_ENCRYPT_TYPE_NONE;
-
- pWextState->roamProfile.mcEncryptionType.numEntries = 1;
- pWextState->roamProfile.mcEncryptionType.encryptionType[0]
- = eCSR_ENCRYPT_TYPE_NONE;
-
- pWextState->roamProfile.AuthType.numEntries = 1;
- pWextState->roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
-
-#ifdef WLAN_FEATURE_11W
- pWextState->roamProfile.MFPEnabled = eANI_BOOLEAN_FALSE;
- pWextState->roamProfile.MFPRequired = 0;
- pWextState->roamProfile.MFPCapable = 0;
-#endif
-
- pWextState->authKeyMgmt = 0;
-
- for (i=0; i < CSR_MAX_NUM_KEY; i++)
- {
- if (pWextState->roamProfile.Keys.KeyMaterial[i])
- {
- pWextState->roamProfile.Keys.KeyLength[i] = 0;
- }
- }
-#ifdef FEATURE_WLAN_WAPI
- pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_OPEN;
- pAdapter->wapi_info.nWapiMode = 0;
-#endif
-
- vos_mem_zero((void *)(pWextState->req_bssId), WNI_CFG_BSSID_LEN);
-
-}
-
-void wlan_hdd_ula_done_cb(v_VOID_t *callbackContext)
-{
- hdd_adapter_t *pAdapter = (hdd_adapter_t*)callbackContext;
-
- if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "%s: Invalid pAdapter magic", __func__);
- }
- else
- {
- complete(&pAdapter->ula_complete);
- }
-}
-
-VOS_STATUS wlan_hdd_check_ula_done(hdd_adapter_t *pAdapter)
-{
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- VOS_STATUS vos_status;
- unsigned long rc;
-
- if (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated)
- {
- INIT_COMPLETION(pAdapter->ula_complete);
-
- /*To avoid race condition between the set key and the last EAPOL
- packet, notify TL to finish upper layer authentication incase if the
- last EAPOL packet pending in the TL queue.*/
- vos_status = WLANTL_Finish_ULA(wlan_hdd_ula_done_cb, pAdapter);
-
- if ( vos_status != VOS_STATUS_SUCCESS )
- {
- VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "[%4d] WLANTL_Finish_ULA returned ERROR status= %d",
- __LINE__, vos_status );
- return vos_status;
-
- }
-
- rc = wait_for_completion_timeout(&pAdapter->ula_complete,
- msecs_to_jiffies(HDD_FINISH_ULA_TIME_OUT));
- if (0 == rc)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "%s: Timeout waiting for ULA to complete", __func__);
- /* we'll still fall through and return success since the
- * connection may still get established but is just taking
- * too long for us to wait */
- }
- }
- return VOS_STATUS_SUCCESS;
-}
-
-v_U8_t* wlan_hdd_get_vendor_oui_ie_ptr(v_U8_t *oui, v_U8_t oui_size, v_U8_t *ie, int ie_len)
-{
-
- int left = ie_len;
- v_U8_t *ptr = ie;
- v_U8_t elem_id,elem_len;
- v_U8_t eid = 0xDD;
-
- if ( NULL == ie || 0 == ie_len )
- return NULL;
-
- while(left >= 2)
- {
- elem_id = ptr[0];
- elem_len = ptr[1];
- left -= 2;
- if(elem_len > left)
- {
- hddLog(VOS_TRACE_LEVEL_FATAL,
- FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
- eid,elem_len,left);
- return NULL;
- }
- if (elem_id == eid)
- {
- if(memcmp( &ptr[2], oui, oui_size)==0)
- return ptr;
- }
-
- left -= elem_len;
- ptr += (elem_len + 2);
- }
- return NULL;
-}
-
-static int iw_set_commit(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hddLog( LOG1, "In %s\n", __func__);
- /* Do nothing for now */
- return 0;
-}
-
-static int iw_get_name(struct net_device *dev,
- struct iw_request_info *info,
- char *wrqu, char *extra)
-{
-
- ENTER();
- strlcpy(wrqu, "Qcom:802.11n", IFNAMSIZ);
- EXIT();
- return 0;
-}
-
-static int iw_set_mode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_wext_state_t *pWextState;
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tCsrRoamProfile *pRoamProfile;
- eCsrRoamBssType LastBSSType;
- eMib_dot11DesiredBssType connectedBssType;
- hdd_config_t *pConfig;
- struct wireless_dev *wdev;
-
- ENTER();
-
- if (NULL == pAdapter)
- {
- hddLog(VOS_TRACE_LEVEL_WARN,
- "%s: Invalid context, pAdapter", __func__);
- return 0;
- }
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return 0;
- }
-
- pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
- if (pWextState == NULL)
- {
- hddLog(LOGE, "%s ERROR: Data Storage Corruption", __func__);
- return -EINVAL;
- }
-
- wdev = dev->ieee80211_ptr;
- pRoamProfile = &pWextState->roamProfile;
- LastBSSType = pRoamProfile->BSSType;
-
- hddLog(LOG1, "%s Old Bss type = %d", __func__, LastBSSType);
-
- switch (wrqu->mode)
- {
- case IW_MODE_ADHOC:
- hddLog(LOG1, "%s Setting AP Mode as IW_MODE_ADHOC", __func__);
- pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
- // Set the phymode correctly for IBSS.
- pConfig = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
- pWextState->roamProfile.phyMode = hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
- pAdapter->device_mode = WLAN_HDD_IBSS;
- wdev->iftype = NL80211_IFTYPE_ADHOC;
- break;
- case IW_MODE_INFRA:
- hddLog(LOG1, "%s Setting AP Mode as IW_MODE_INFRA", __func__);
- pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
- wdev->iftype = NL80211_IFTYPE_STATION;
- break;
- case IW_MODE_AUTO:
- hddLog(LOG1, "%s Setting AP Mode as IW_MODE_AUTO", __func__);
- pRoamProfile->BSSType = eCSR_BSS_TYPE_ANY;
- break;
- default:
- hddLog(LOG1, "%s Unknown AP Mode value", __func__);
- return -EOPNOTSUPP;
- }
-
- if ( LastBSSType != pRoamProfile->BSSType )
- {
- //the BSS mode changed
- // We need to issue disconnect if connected or in IBSS disconnect state
- if ( hdd_connGetConnectedBssType( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
- ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
- {
- VOS_STATUS vosStatus;
- // need to issue a disconnect to CSR.
- INIT_COMPLETION(pAdapter->disconnect_comp_var);
- vosStatus = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
- pAdapter->sessionId,
- eCSR_DISCONNECT_REASON_IBSS_LEAVE );
- if(VOS_STATUS_SUCCESS == vosStatus)
- wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
- msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
- }
- }
-
- EXIT();
- return 0;
-}
-
-
-static int iw_get_mode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
-
- hdd_wext_state_t *pWextState;
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
-
- hddLog(LOG1, "In %s", __func__);
-
- if (NULL == pAdapter)
- {
- hddLog(VOS_TRACE_LEVEL_WARN,
- "%s: Invalid context, pAdapter", __func__);
- return 0;
- }
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return 0;
- }
-
- pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
- if (pWextState == NULL)
- {
- hddLog(LOGE, "%s ERROR: Data Storage Corruption", __func__);
- return -EINVAL;
- }
-
- switch (pWextState->roamProfile.BSSType)
- {
- case eCSR_BSS_TYPE_INFRASTRUCTURE:
- hddLog(LOG1, "%s returns IW_MODE_INFRA\n", __func__);
- wrqu->mode = IW_MODE_INFRA;
- break;
- case eCSR_BSS_TYPE_IBSS:
- case eCSR_BSS_TYPE_START_IBSS:
- hddLog(LOG1, "%s returns IW_MODE_ADHOC\n", __func__);
- wrqu->mode = IW_MODE_ADHOC;
- break;
- case eCSR_BSS_TYPE_ANY:
- hddLog(LOG1, "%s returns IW_MODE_AUTO\n", __func__);
- wrqu->mode = IW_MODE_AUTO;
- break;
- default:
- hddLog(LOG1, "%s returns APMODE_UNKNOWN\n", __func__);
- break;
- }
-
- return 0;
-}
-
-static int iw_set_freq(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- v_U32_t numChans = 0;
- v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
- v_U32_t indx = 0;
- v_U32_t status = 0;
-
- hdd_wext_state_t *pWextState;
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- tCsrRoamProfile * pRoamProfile;
- ENTER();
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
- return status;
- }
-
- pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
-
- pRoamProfile = &pWextState->roamProfile;
-
- hddLog(LOG1,"setCHANNEL ioctl\n");
-
- /* Link is up then return cant set channel*/
- if(eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState ||
- eConnectionState_Associated == pHddStaCtx->conn_info.connState)
- {
- hddLog( LOGE, "IBSS Associated\n");
- return -EOPNOTSUPP;
- }
-
- /* Settings by Frequency as input */
- if((wrqu->freq.e == 1) && (wrqu->freq.m >= (tANI_U32)2.412e8) &&
- (wrqu->freq.m <= (tANI_U32)5.825e8))
- {
- tANI_U32 freq = wrqu->freq.m / 100000;
-
- while ((indx < FREQ_CHAN_MAP_TABLE_SIZE) && (freq != freq_chan_map[indx].freq))
- indx++;
- if (indx >= FREQ_CHAN_MAP_TABLE_SIZE)
- {
- return -EINVAL;
- }
- wrqu->freq.e = 0;
- wrqu->freq.m = freq_chan_map[indx].chan;
-
- }
-
- if (wrqu->freq.e == 0)
- {
- if((wrqu->freq.m < WNI_CFG_CURRENT_CHANNEL_STAMIN) ||
- (wrqu->freq.m > WNI_CFG_CURRENT_CHANNEL_STAMAX))
- {
- hddLog(LOG1,"%s: Channel [%d] is outside valid range from %d to %d\n",
- __func__, wrqu->freq.m, WNI_CFG_CURRENT_CHANNEL_STAMIN,
- WNI_CFG_CURRENT_CHANNEL_STAMAX);
- return -EINVAL;
- }
-
- numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
-
- if (ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
- validChan, &numChans) != eHAL_STATUS_SUCCESS){
- return -EIO;
- }
-
- for (indx = 0; indx < numChans; indx++) {
- if (wrqu->freq.m == validChan[indx]){
- break;
- }
- }
- }
- else{
-
- return -EINVAL;
- }
-
- if(indx >= numChans)
- {
- return -EINVAL;
- }
-
- /* Set the Operational Channel */
- numChans = pRoamProfile->ChannelInfo.numOfChannels = 1;
- pHddStaCtx->conn_info.operationChannel = wrqu->freq.m;
- pRoamProfile->ChannelInfo.ChannelList = &pHddStaCtx->conn_info.operationChannel;
-
- hddLog(LOG1,"pRoamProfile->operationChannel = %d\n", wrqu->freq.m);
-
- EXIT();
-
- return status;
-}
-
-static int iw_get_freq(struct net_device *dev, struct iw_request_info *info,
- struct iw_freq *fwrq, char *extra)
-{
- v_U32_t status = FALSE, channel = 0, freq = 0;
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tHalHandle hHal;
- hdd_wext_state_t *pWextState;
- tCsrRoamProfile * pRoamProfile;
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
-
- ENTER();
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
- return status;
- }
-
- pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
- hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
-
- pRoamProfile = &pWextState->roamProfile;
-
- if( pHddStaCtx->conn_info.connState== eConnectionState_Associated )
- {
- if (sme_GetOperationChannel(hHal, &channel, pAdapter->sessionId) != eHAL_STATUS_SUCCESS)
- {
- return -EIO;
- }
- else
- {
- status = hdd_wlan_get_freq(channel, &freq);
- if( TRUE == status )
- {
- /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
- * iwlist & iwconfig command shows frequency into proper
- * format (2.412 GHz instead of 246.2 MHz)*/
- fwrq->m = freq;
- fwrq->e = MHZ;
- }
- }
- }
- else
- {
- /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
- * iwlist & iwconfig command shows frequency into proper
- * format (2.412 GHz instead of 246.2 MHz)*/
- fwrq->m = 0;
- fwrq->e = MHZ;
- }
- return 0;
-}
-
-static int iw_get_tx_power(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
-
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
-
- if (pHddCtx->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!",__func__);
- return -EBUSY;
- }
-
- if(eConnectionState_Associated != pHddStaCtx->conn_info.connState)
- {
- wrqu->txpower.value = 0;
- return 0;
- }
- wlan_hdd_get_classAstats(pAdapter);
- wrqu->txpower.value = pAdapter->hdd_stats.ClassA_stat.max_pwr;
-
- return 0;
-}
-
-static int iw_set_tx_power(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
- return 0;
- }
-
- ENTER();
-
- if ( ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL, wrqu->txpower.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS )
- {
- return -EIO;
- }
-
- EXIT();
-
- return 0;
-}
-
-static int iw_get_bitrate(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
- eHalStatus status = eHAL_STATUS_SUCCESS;
- hdd_wext_state_t *pWextState;
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
-
- ENTER();
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
- return status;
- }
-
- if(eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
- wrqu->bitrate.value = 0;
- }
- else {
- status = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_HDD,
- SME_SUMMARY_STATS |
- SME_GLOBAL_CLASSA_STATS |
- SME_GLOBAL_CLASSB_STATS |
- SME_GLOBAL_CLASSC_STATS |
- SME_GLOBAL_CLASSD_STATS |
- SME_PER_STA_STATS,
- hdd_StatisticsCB, 0, FALSE,
- pHddStaCtx->conn_info.staId[0], pAdapter );
-
- if(eHAL_STATUS_SUCCESS != status)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Unable to retrieve statistics",
- __func__);
- return status;
- }
-
- pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
-
- vos_status = vos_wait_single_event(&pWextState->vosevent, WLAN_WAIT_TIME_STATS);
-
- if (!VOS_IS_STATUS_SUCCESS(vos_status))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: SME timeout while retrieving statistics",
- __func__);
- return VOS_STATUS_E_FAILURE;
- }
-
- wrqu->bitrate.value = pAdapter->hdd_stats.ClassA_stat.tx_rate*500*1000;
- }
-
- EXIT();
-
- return vos_status;
-}
-/* ccm call back function */
-
-static int iw_set_bitrate(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_wext_state_t *pWextState;
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- v_U8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN];
- v_U32_t a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
- v_U32_t b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
- v_U32_t i, rate;
- v_U32_t valid_rate = FALSE, active_phy_mode = 0;
-
- ENTER();
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
- return 0;
- }
-
- pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
-
- if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
- {
- return -ENXIO ;
- }
-
- rate = wrqu->bitrate.value;
-
- if (rate == -1)
- {
- rate = WNI_CFG_FIXED_RATE_AUTO;
- valid_rate = TRUE;
- }
- else if (ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
- WNI_CFG_DOT11_MODE, &active_phy_mode) == eHAL_STATUS_SUCCESS)
- {
- if (active_phy_mode == WNI_CFG_DOT11_MODE_11A || active_phy_mode == WNI_CFG_DOT11_MODE_11G
- || active_phy_mode == WNI_CFG_DOT11_MODE_11B)
- {
- if ((ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
- WNI_CFG_SUPPORTED_RATES_11A,
- supp_rates, &a_len) == eHAL_STATUS_SUCCESS) &&
- (ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
- WNI_CFG_SUPPORTED_RATES_11B,
- supp_rates, &b_len) == eHAL_STATUS_SUCCESS))
- {
- for (i = 0; i < (b_len + a_len); ++i)
- {
- /* supported rates returned is double the actual rate so we divide it by 2 */
- if ((supp_rates[i]&0x7F)/2 == rate)
- {
- valid_rate = TRUE;
- rate = i + WNI_CFG_FIXED_RATE_1MBPS;
- break;
- }
- }
- }
- }
- }
- if (valid_rate != TRUE)
- {
- return -EINVAL;
- }
- if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
- WNI_CFG_FIXED_RATE, rate,
- ccmCfgSetCallback,eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
- {
- return -EIO;
- }
- return 0;
-}
-
-
-static int iw_set_genie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
- u_int8_t *genie = (u_int8_t *)extra;
- v_U16_t remLen;
-
- ENTER();
- if(!wrqu->data.length) {
- hdd_clearRoamProfileIe(pAdapter);
- EXIT();
- return 0;
- }
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
- return 0;
- }
-
- remLen = wrqu->data.length;
-
- hddLog(LOG1,"iw_set_genie ioctl IE[0x%X], LEN[%d]\n", genie[0], genie[1]);
-
- /* clear any previous genIE before this call */
- memset( &pWextState->genIE, 0, sizeof(pWextState->genIE) );
-
- while (remLen >= 2)
- {
- v_U16_t eLen = 0;
- v_U8_t elementId;
- elementId = *genie++;
- eLen = *genie++;
- remLen -= 2;
-
- hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
- __func__, elementId, eLen);
-
- switch ( elementId )
- {
- case IE_EID_VENDOR:
- if ((IE_LEN_SIZE+IE_EID_SIZE+IE_VENDOR_OUI_SIZE) > eLen) /* should have at least OUI */
- return -EINVAL;
-
- if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
- {
- v_U16_t curGenIELen = pWextState->genIE.length;
- hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS OUI(%02x %02x %02x %02x) IE(len %d)",
- __func__, genie[0], genie[1], genie[2], genie[3], eLen + 2);
-
- if( SIR_MAC_MAX_IE_LENGTH < (pWextState->genIE.length + eLen) )
- {
- hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. "
- "Need bigger buffer space\n");
- VOS_ASSERT(0);
- return -ENOMEM;
- }
- // save to Additional IE ; it should be accumulated to handle WPS IE + other IE
- memcpy( pWextState->genIE.addIEdata + curGenIELen, genie - 2, eLen + 2);
- pWextState->genIE.length += eLen + 2;
- }
- else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
- {
- hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
- memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
- memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2));
- pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
- pWextState->roamProfile.nWPAReqIELength = eLen + 2;
- }
- else /* any vendorId except WPA IE should be accumulated to genIE */
- {
- v_U16_t curGenIELen = pWextState->genIE.length;
- hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OUI(%02x %02x %02x %02x) IE(len %d)",
- __func__, genie[0], genie[1], genie[2], genie[3], eLen + 2);
-
- if( SIR_MAC_MAX_IE_LENGTH < (pWextState->genIE.length + eLen) )
- {
- hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. "
- "Need bigger buffer space\n");
- VOS_ASSERT(0);
- return -ENOMEM;
- }
- // save to Additional IE ; it should be accumulated to handle WPS IE + other IE
- memcpy( pWextState->genIE.addIEdata + curGenIELen, genie - 2, eLen + 2);
- pWextState->genIE.length += eLen + 2;
- }
- break;
- case DOT11F_EID_RSN:
- hddLog (LOG1, "%s Set RSN IE (len %d)",__func__, eLen+2);
- memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
- memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2));
- pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
- pWextState->roamProfile.nRSNReqIELength = eLen + 2;
- break;
-
- default:
- hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, elementId);
- return 0;
- }
- genie += eLen;
- remLen -= eLen;
- }
- EXIT();
- return 0;
-}
-
-static int iw_get_genie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- hdd_wext_state_t *pWextState;
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- eHalStatus status;
- v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
- v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
-
- ENTER();
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
- return 0;
- }
-
-
- hddLog(LOG1,"getGEN_IE ioctl\n");
-
- pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
-
- if( pHddStaCtx->conn_info.connState == eConnectionState_NotConnected)
- {
- return -ENXIO;
- }
-
- // Return something ONLY if we are associated with an RSN or WPA network
- if ( VOS_TRUE != hdd_IsAuthTypeRSN(WLAN_HDD_GET_HAL_CTX(pAdapter),
- pWextState->roamProfile.negotiatedAuthType))
- {
- return -ENXIO;
- }
-
- // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
- status = csrRoamGetWpaRsnReqIE(WLAN_HDD_GET_HAL_CTX(pAdapter),
- pAdapter->sessionId,
- &length,
- genIeBytes);
- length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
- if (wrqu->data.length < length)
- {
- hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
- return -EFAULT;
- }
- vos_mem_copy( extra, (v_VOID_t*)genIeBytes, wrqu->data.length);
- wrqu->data.length = length;
-
- hddLog(LOG1,"%s: RSN IE of %d bytes returned\n", __func__, wrqu->data.length );
-
- EXIT();
-
- return 0;
-}
-
-static int iw_get_encode(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *dwrq, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
- tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
- int keyId;
- eCsrAuthType authType = eCSR_AUTH_TYPE_NONE;
- int i;
-
- ENTER();
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
- return 0;
- }
-
- keyId = pRoamProfile->Keys.defaultIndex;
-
- if(keyId < 0 || keyId >= MAX_WEP_KEYS)
- {
- hddLog(LOG1,"%s: Invalid keyId : %d\n",__func__,keyId);
- return -EINVAL;
- }
-
- if(pRoamProfile->Keys.KeyLength[keyId] > 0)
- {
- dwrq->flags |= IW_ENCODE_ENABLED;
- dwrq->length = pRoamProfile->Keys.KeyLength[keyId];
- vos_mem_copy(extra,&(pRoamProfile->Keys.KeyMaterial[keyId][0]),pRoamProfile->Keys.KeyLength[keyId]);
-
- dwrq->flags |= (keyId + 1);
-
- }
- else
- {
- dwrq->flags |= IW_ENCODE_DISABLED;
- }
-
- for(i=0; i < MAX_WEP_KEYS; i++)
- {
- if(pRoamProfile->Keys.KeyMaterial[i] == NULL)
- {
- continue;
- }
- else
- {
- break;
- }
- }
-
- if(MAX_WEP_KEYS == i)
- {
- dwrq->flags |= IW_ENCODE_NOKEY;
- }
-
- authType = ((hdd_station_ctx_t*)WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
-
- if(eCSR_AUTH_TYPE_OPEN_SYSTEM == authType)
- {
- dwrq->flags |= IW_ENCODE_OPEN;
- }
- else
- {
- dwrq->flags |= IW_ENCODE_RESTRICTED;
- }
- EXIT();
- return 0;
-}
-
-#define PAE_ROLE_AUTHENTICATOR 1 // =1 for authenticator,
-#define PAE_ROLE_SUPPLICANT 0 // =0 for supplicant
-
-
-/*
- * This function sends a single 'key' to LIM at all time.
- */
-
-static int iw_get_rts_threshold(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- v_U32_t status = 0;
-
- status = hdd_wlan_get_rts_threshold(pAdapter,wrqu);
-
- return status;
-}
-
-static int iw_set_rts_threshold(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
-
- ENTER();
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EAGAIN;
- }
- if ( wrqu->rts.value < WNI_CFG_RTS_THRESHOLD_STAMIN || wrqu->rts.value > WNI_CFG_RTS_THRESHOLD_STAMAX )
- {
- return -EINVAL;
- }
-
- if ( ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD, wrqu->rts.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS )
- {
- return -EIO;
- }
-
- EXIT();
-
- return 0;
-}
-
-static int iw_get_frag_threshold(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- v_U32_t status = 0;
-
- status = hdd_wlan_get_frag_threshold(pAdapter,wrqu);
-
- return status;
-}
-
-static int iw_set_frag_threshold(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
-
- ENTER();
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
- if ( wrqu->frag.value < WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN || wrqu->frag.value > WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX )
- {
- return -EINVAL;
- }
-
- if ( ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, wrqu->frag.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS )
- {
- return -EIO;
- }
-
- EXIT();
-
- return 0;
-}
-
-static int iw_get_power_mode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- ENTER();
- return -EOPNOTSUPP;
-}
-
-static int iw_set_power_mode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- ENTER();
- return -EOPNOTSUPP;
-}
-
-static int iw_get_range(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- struct iw_range *range = (struct iw_range *) extra;
-
- v_U8_t channels[WNI_CFG_VALID_CHANNEL_LIST_LEN];
-
- v_U32_t num_channels = sizeof(channels);
- v_U8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN];
- v_U32_t a_len;
- v_U32_t b_len;
- v_U32_t active_phy_mode = 0;
- v_U8_t index = 0, i;
-
- ENTER();
-
- wrqu->data.length = sizeof(struct iw_range);
- memset(range, 0, sizeof(struct iw_range));
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- /*Get the phy mode*/
- if (ccmCfgGetInt(hHal,
- WNI_CFG_DOT11_MODE, &active_phy_mode) == eHAL_STATUS_SUCCESS)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "active_phy_mode = %ld", active_phy_mode);
-
- if (active_phy_mode == WNI_CFG_DOT11_MODE_11A || active_phy_mode == WNI_CFG_DOT11_MODE_11G)
- {
- /*Get the supported rates for 11G band*/
- a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
- if (ccmCfgGetStr(hHal,
- WNI_CFG_SUPPORTED_RATES_11A,
- supp_rates, &a_len) == eHAL_STATUS_SUCCESS)
- {
- if (a_len > WNI_CFG_SUPPORTED_RATES_11A_LEN)
- {
- a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
- }
- for (i = 0; i < a_len; i++)
- {
- range->bitrate[i] = ((supp_rates[i] & 0x7F) / 2) * 1000000;
- }
- range->num_bitrates = a_len;
- }
- else
- {
- return -EIO;
- }
- }
- else if (active_phy_mode == WNI_CFG_DOT11_MODE_11B)
- {
- /*Get the supported rates for 11B band*/
- b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
- if (ccmCfgGetStr(hHal,
- WNI_CFG_SUPPORTED_RATES_11B,
- supp_rates, &b_len) == eHAL_STATUS_SUCCESS)
- {
- if (b_len > WNI_CFG_SUPPORTED_RATES_11B_LEN)
- {
- b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
- }
- for (i = 0; i < b_len; i++)
- {
- range->bitrate[i] = ((supp_rates[i] & 0x7F) / 2) * 1000000;
- }
- range->num_bitrates = b_len;
- }
- else
- {
- return -EIO;
- }
- }
- }
-
- range->max_rts = WNI_CFG_RTS_THRESHOLD_STAMAX;
- range->min_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN;
- range->max_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX;
-
- range->encoding_size[0] = 5;
- range->encoding_size[1] = 13;
- range->num_encoding_sizes = 2;
- range->max_encoding_tokens = MAX_WEP_KEYS;
-
- // we support through Wireless Extensions 22
- range->we_version_compiled = WIRELESS_EXT;
- range->we_version_source = 22;
-
- /*Supported Channels and Frequencies*/
- if (ccmCfgGetStr((hHal), WNI_CFG_VALID_CHANNEL_LIST, channels, &num_channels) != eHAL_STATUS_SUCCESS)
- {
- return -EIO;
- }
- if (num_channels > IW_MAX_FREQUENCIES)
- {
- num_channels = IW_MAX_FREQUENCIES;
- }
-
- range->num_channels = num_channels;
- range->num_frequency = num_channels;
-
- for (index=0; index < num_channels; index++)
- {
- v_U32_t frq_indx = 0;
-
- range->freq[index].i = channels[index];
- while (frq_indx < FREQ_CHAN_MAP_TABLE_SIZE)
- {
- if(channels[index] == freq_chan_map[frq_indx].chan)
- {
- range->freq[index].m = freq_chan_map[frq_indx].freq * 100000;
- range->freq[index].e = 1;
- break;
- }
- frq_indx++;
- }
- }
-
- /* Event capability (kernel + driver) */
- range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
- IW_EVENT_CAPA_MASK(SIOCGIWAP) |
- IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
- range->event_capa[1] = IW_EVENT_CAPA_K_1;
-
- /*Encryption capability*/
- range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
- IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
-
- /* Txpower capability */
- range->txpower_capa = IW_TXPOW_MWATT;
-
- /*Scanning capability*/
- #if WIRELESS_EXT >= 22
- range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | IW_SCAN_CAPA_CHANNEL;
- #endif
-
- EXIT();
- return 0;
-}
-
-/* Callback function registered with PMC to know status of PMC request */
-static void iw_power_callback_fn (void *pContext, eHalStatus status)
-{
- struct statsContext *pStatsContext;
- hdd_adapter_t *pAdapter;
-
- if (NULL == pContext)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Bad param, pContext [%p]",
- __func__, pContext);
- return;
- }
-
- /* there is a race condition that exists between this callback function
- and the caller since the caller could time out either before or
- while this code is executing. we'll assume the timeout hasn't
- occurred, but we'll verify that right before we save our work */
-
- pStatsContext = (struct statsContext *)pContext;
- pAdapter = pStatsContext->pAdapter;
-
- if ((NULL == pAdapter) || (POWER_CONTEXT_MAGIC != pStatsContext->magic))
- {
- /* the caller presumably timed out so there is nothing we can do */
- hddLog(VOS_TRACE_LEVEL_WARN,
- "%s: Invalid context, pAdapter [%p] magic [%08x]",
- __func__, pAdapter, pStatsContext->magic);
-
- if (ioctl_debug)
- {
- pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
- __func__, pAdapter, pStatsContext->magic);
- }
- return;
- }
-
- /* and notify the caller */
- complete(&pStatsContext->completion);
-}
-
-/* Callback function for tx per hit */
-void hdd_tx_per_hit_cb (void *pCallbackContext)
-{
- hdd_adapter_t *pAdapter = (hdd_adapter_t *)pCallbackContext;
- unsigned char tx_fail[16];
- union iwreq_data wrqu;
-
- if (NULL == pAdapter)
- {
- hddLog(LOGE, "hdd_tx_per_hit_cb: pAdapter is NULL\n");
- return;
- }
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = strlcpy(tx_fail, "TX_FAIL", sizeof(tx_fail));
- wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, tx_fail);
-}
-
-void hdd_GetClassA_statisticsCB(void *pStats, void *pContext)
-{
- struct statsContext *pStatsContext;
- tCsrGlobalClassAStatsInfo *pClassAStats;
- hdd_adapter_t *pAdapter;
-
- if (ioctl_debug)
- {
- pr_info("%s: pStats [%p] pContext [%p]\n",
- __func__, pStats, pContext);
- }
-
- if ((NULL == pStats) || (NULL == pContext))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Bad param, pStats [%p] pContext [%p]",
- __func__, pStats, pContext);
- return;
- }
-
- /* there is a race condition that exists between this callback function
- and the caller since the caller could time out either before or
- while this code is executing. we'll assume the timeout hasn't
- occurred, but we'll verify that right before we save our work */
-
- pClassAStats = pStats;
- pStatsContext = pContext;
- pAdapter = pStatsContext->pAdapter;
- if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
- {
- /* the caller presumably timed out so there is nothing we can do */
- hddLog(VOS_TRACE_LEVEL_WARN,
- "%s: Invalid context, pAdapter [%p] magic [%08x]",
- __func__, pAdapter, pStatsContext->magic);
- if (ioctl_debug)
- {
- pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
- __func__, pAdapter, pStatsContext->magic);
- }
- return;
- }
-
- /* the race is on. caller could have timed out immediately after
- we verified the magic, but if so, caller will wait a short time
- for us to copy over the stats. do so as a struct copy */
- pAdapter->hdd_stats.ClassA_stat = *pClassAStats;
-
- /* and notify the caller */
- complete(&pStatsContext->completion);
-}
-
-VOS_STATUS wlan_hdd_get_classAstats(hdd_adapter_t *pAdapter)
-{
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- eHalStatus hstatus;
- long lrc;
- struct statsContext context;
-
- if (NULL == pAdapter)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Padapter is NULL", __func__);
- return VOS_STATUS_E_FAULT;
- }
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!",__func__);
- return VOS_STATUS_SUCCESS;
- }
-
- /* we are connected
- prepare our callback context */
- init_completion(&context.completion);
- context.pAdapter = pAdapter;
- context.magic = STATS_CONTEXT_MAGIC;
- /* query only for Class A statistics (which include link speed) */
- hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
- eCSR_HDD,
- SME_GLOBAL_CLASSA_STATS,
- hdd_GetClassA_statisticsCB,
- 0, // not periodic
- FALSE, //non-cached results
- pHddStaCtx->conn_info.staId[0],
- &context);
- if (eHAL_STATUS_SUCCESS != hstatus)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Unable to retrieve Class A statistics ",
- __func__);
- /* we'll returned a cached value below */
- }
- else
- {
- /* request was sent -- wait for the response */
- lrc = wait_for_completion_interruptible_timeout(&context.completion,
- msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
- /* either we have a response or we timed out
- either way, first invalidate our magic */
- context.magic = 0;
- if (lrc <= 0)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: SME %s while retrieving Class A statistics",
- __func__, (0 == lrc) ? "timeout" : "interrupt");
- /* there is a race condition such that the callback
- function could be executing at the same time we are. of
- primary concern is if the callback function had already
- verified the "magic" but hasn't yet set the completion
- variable. Since the completion variable is on our
- stack, we'll delay just a bit to make sure the data is
- still valid if that is the case */
- msleep(50);
- }
- }
- return VOS_STATUS_SUCCESS;
-}
-
-static void hdd_get_station_statisticsCB(void *pStats, void *pContext)
-{
- struct statsContext *pStatsContext;
- tCsrSummaryStatsInfo *pSummaryStats;
- tCsrGlobalClassAStatsInfo *pClassAStats;
- hdd_adapter_t *pAdapter;
-
- if (ioctl_debug)
- {
- pr_info("%s: pStats [%p] pContext [%p]\n",
- __func__, pStats, pContext);
- }
-
- if ((NULL == pStats) || (NULL == pContext))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Bad param, pStats [%p] pContext [%p]",
- __func__, pStats, pContext);
- return;
- }
-
- /* there is a race condition that exists between this callback function
- and the caller since the caller could time out either before or
- while this code is executing. we'll assume the timeout hasn't
- occurred, but we'll verify that right before we save our work */
-
- pSummaryStats = (tCsrSummaryStatsInfo *)pStats;
- pClassAStats = (tCsrGlobalClassAStatsInfo *)( pSummaryStats + 1 );
- pStatsContext = pContext;
- pAdapter = pStatsContext->pAdapter;
- if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
- {
- /* the caller presumably timed out so there is nothing we can do */
- hddLog(VOS_TRACE_LEVEL_WARN,
- "%s: Invalid context, pAdapter [%p] magic [%08x]",
- __func__, pAdapter, pStatsContext->magic);
- if (ioctl_debug)
- {
- pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
- __func__, pAdapter, pStatsContext->magic);
- }
- return;
- }
-
- /* the race is on. caller could have timed out immediately after
- we verified the magic, but if so, caller will wait a short time
- for us to copy over the stats. do so as a struct copy */
- pAdapter->hdd_stats.summary_stat = *pSummaryStats;
- pAdapter->hdd_stats.ClassA_stat = *pClassAStats;
-
- /* and notify the caller */
- complete(&pStatsContext->completion);
-}
-
-VOS_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter)
-{
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- eHalStatus hstatus;
- long lrc;
- struct statsContext context;
-
- if (NULL == pAdapter)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Padapter is NULL", __func__);
- return VOS_STATUS_SUCCESS;
- }
-
- /* we are connected
- prepare our callback context */
- init_completion(&context.completion);
- context.pAdapter = pAdapter;
- context.magic = STATS_CONTEXT_MAGIC;
-
- /* query only for Summary & Class A statistics */
- hstatus = sme_GetStatistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
- eCSR_HDD,
- SME_SUMMARY_STATS |
- SME_GLOBAL_CLASSA_STATS,
- hdd_get_station_statisticsCB,
- 0, // not periodic
- FALSE, //non-cached results
- pHddStaCtx->conn_info.staId[0],
- &context);
- if (eHAL_STATUS_SUCCESS != hstatus)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Unable to retrieve statistics",
- __func__);
- /* we'll return with cached values */
- }
- else
- {
- /* request was sent -- wait for the response */
- lrc = wait_for_completion_interruptible_timeout(&context.completion,
- msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
- /* either we have a response or we timed out
- either way, first invalidate our magic */
- context.magic = 0;
- if (lrc <= 0)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: SME %s while retrieving statistics",
- __func__, (0 == lrc) ? "timeout" : "interrupt");
- /* there is a race condition such that the callback
- function could be executing at the same time we are. of
- primary concern is if the callback function had already
- verified the "magic" but hasn't yet set the completion
- variable. Since the completion variable is on our
- stack, we'll delay just a bit to make sure the data is
- still valid if that is the case */
- msleep(50);
- }
- }
- return VOS_STATUS_SUCCESS;
-}
-
-
-/*
- * Support for the LINKSPEED private command
- * Per the WiFi framework the response must be of the form
- * "LinkSpeed xx"
- */
-static int iw_get_linkspeed(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_context_t *pHddCtx;
- char *pLinkSpeed = (char*)extra;
- int len = sizeof(v_U32_t) + 1;
- v_U32_t link_speed = 0;
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- VOS_STATUS status;
- int rc, valid;
-
- pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
-
- valid = wlan_hdd_validate_context(pHddCtx);
-
- if (0 != valid)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
- return valid;
- }
-
- if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
- {
- /* we are not connected so we don't have a classAstats */
- link_speed = 0;
- }
- else
- {
- status = wlan_hdd_get_classAstats(pAdapter);
-
- if (!VOS_IS_STATUS_SUCCESS(status ))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics"));
- return -EINVAL;
- }
-
- /* Unit of link capacity is obtained from the TL API is MbpsX10 */
- WLANTL_GetSTALinkCapacity(WLAN_HDD_GET_CTX(pAdapter)->pvosContext,
- (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
- &link_speed);
-
- link_speed = link_speed / 10;
-
- if (0 == link_speed)
- {
- /* The linkspeed returned by HAL is in units of 500kbps.
- * converting it to mbps.
- * This is required to support legacy firmware which does
- * not return link capacity.
- */
- link_speed = pAdapter->hdd_stats.ClassA_stat.tx_rate/2;
- }
-
- }
-
- wrqu->data.length = len;
- // return the linkspeed in the format required by the WiFi Framework
- rc = snprintf(pLinkSpeed, len, "%u", link_speed);
- if ((rc < 0) || (rc >= len))
- {
- // encoding or length error?
- hddLog(VOS_TRACE_LEVEL_ERROR,FL("Unable to encode link speed"));
- return -EIO;
- }
-
- /* a value is being successfully returned */
- return 0;
-}
-
-
-/*
- * Support for the RSSI & RSSI-APPROX private commands
- * Per the WiFi framework the response must be of the form
- * "<ssid> rssi <xx>"
- * unless we are not associated, in which case the response is
- * "OK"
- */
-static int iw_get_rssi(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- char *cmd = extra;
- int len = wrqu->data.length;
- v_S7_t s7Rssi = 0;
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
- VOS_STATUS vosStatus;
- int rc;
-
- if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
- (0 == ssidlen) || (ssidlen >= len))
- {
- /* we are not connected or our SSID is too long
- so we cannot report an rssi */
- rc = scnprintf(cmd, len, "OK");
- }
- else
- {
- /* we are connected with a valid SSID
- so we can write the SSID into the return buffer
- (note that it is not NUL-terminated) */
- memcpy(cmd, pHddStaCtx->conn_info.SSID.SSID.ssId, ssidlen );
-
- vosStatus = wlan_hdd_get_rssi(pAdapter, &s7Rssi);
-
- if (VOS_STATUS_SUCCESS == vosStatus)
- {
- /* append the rssi to the ssid in the format required by
- the WiFI Framework */
- rc = scnprintf(&cmd[ssidlen], len - ssidlen, " rssi %d", s7Rssi);
- }
- else
- {
- rc = -1;
- }
- }
-
- /* verify that we wrote a valid response */
- if ((rc < 0) || (rc >= len))
- {
- // encoding or length error?
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Unable to encode RSSI, got [%s]",
- __func__, cmd);
- return -EIO;
- }
-
- /* a value is being successfully returned */
- return 0;
-}
-
-/*
- * Support for SoftAP channel range private command
- */
-static int iw_softap_set_channel_range( struct net_device *dev,
- int startChannel,
- int endChannel,
- int band)
-{
- VOS_STATUS status;
- int ret = 0;
- hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
-
-
- status = WLANSAP_SetChannelRange(hHal, startChannel, endChannel, band);
- if (VOS_STATUS_SUCCESS != status)
- {
- ret = -EINVAL;
- }
- pHddCtx->is_dynamic_channel_range_set = 1;
- return ret;
-}
-
-VOS_STATUS wlan_hdd_enter_bmps(hdd_adapter_t *pAdapter, int mode)
-{
- struct statsContext context;
- eHalStatus status;
- hdd_context_t *pHddCtx;
-
- if (NULL == pAdapter)
- {
- hddLog(VOS_TRACE_LEVEL_FATAL, "Adapter NULL");
- return VOS_STATUS_E_FAULT;
- }
-
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "power mode=%d", mode);
- pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- init_completion(&context.completion);
-
- context.pAdapter = pAdapter;
- context.magic = POWER_CONTEXT_MAGIC;
-
- if (DRIVER_POWER_MODE_ACTIVE == mode)
- {
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering "
- "Full Power", __func__);
- status = sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
- iw_power_callback_fn, &context,
- eSME_FULL_PWR_NEEDED_BY_HDD);
- // Enter Full power command received from GUI this means we are disconnected
- // Set PMC remainInPowerActiveTillDHCP flag to disable auto BMPS entry by PMC
- sme_SetDHCPTillPowerActiveFlag(pHddCtx->hHal, TRUE);
- if (eHAL_STATUS_PMC_PENDING == status)
- {
- int lrc = wait_for_completion_interruptible_timeout(
- &context.completion,
- msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
- context.magic = 0;
- if (lrc <= 0)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while requesting fullpower ",
- __func__, (0 == lrc) ? "timeout" : "interrupt");
- /* there is a race condition such that the callback
- function could be executing at the same time we are. of
- primary concern is if the callback function had already
- verified the "magic" but hasn't yet set the completion
- variable. Since the completion variable is on our
- stack, we'll delay just a bit to make sure the data is
- still valid if that is the case */
- msleep(50);
- /* we'll now returned a cached value below */
- }
- }
- }
- else if (DRIVER_POWER_MODE_AUTO == mode)
- {
- if (pHddCtx->cfg_ini->fIsBmpsEnabled)
- {
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering Bmps ",
- __func__);
- // Enter BMPS command received from GUI this means DHCP is completed
- // Clear PMC remainInPowerActiveTillDHCP flag to enable auto BMPS entry
- sme_SetDHCPTillPowerActiveFlag(WLAN_HDD_GET_HAL_CTX(pAdapter),
- FALSE);
- status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter),
- iw_power_callback_fn, &context);
- if (eHAL_STATUS_PMC_PENDING == status)
- {
- int lrc = wait_for_completion_interruptible_timeout(
- &context.completion,
- msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
- context.magic = 0;
- if (lrc <= 0)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while requesting BMPS ",
- __func__, (0 == lrc) ? "timeout" : "interrupt");
- /* there is a race condition such that the callback
- function could be executing at the same time we are. of
- primary concern is if the callback function had already
- verified the "magic" but hasn't yet set the completion
- variable. Since the completion variable is on our
- stack, we'll delay just a bit to make sure the data is
- still valid if that is the case */
- msleep(50);
- /* we'll now returned a cached value below */
- }
- }
- }
- else
- {
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "BMPS is not "
- "enabled in the cfg");
- }
- }
- return VOS_STATUS_SUCCESS;
-}
-
-VOS_STATUS wlan_hdd_set_powersave(hdd_adapter_t *pAdapter, int mode)
-{
- hdd_context_t *pHddCtx;
-
- if (NULL == pAdapter)
- {
- hddLog(VOS_TRACE_LEVEL_FATAL, "Adapter NULL");
- return VOS_STATUS_E_FAULT;
- }
-
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "power mode=%d", mode);
-
- pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
-
- if (DRIVER_POWER_MODE_ACTIVE == mode)
- {
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering "
- "Full Power", __func__);
-
- /*
- * Enter Full power command received from GUI
- * this means we are disconnected
- */
- sme_PsOffloadDisablePowerSave(WLAN_HDD_GET_HAL_CTX(pAdapter),
- pAdapter->sessionId);
- }
- else if (DRIVER_POWER_MODE_AUTO == mode)
- {
- if (pHddCtx->cfg_ini->fIsBmpsEnabled)
- {
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering Bmps ",
- __func__);
-
- /*
- * Enter BMPS command received from GUI
- * this means DHCP is completed
- */
- sme_PsOffloadEnablePowerSave(WLAN_HDD_GET_HAL_CTX(pAdapter),
- pAdapter->sessionId);
- }
- else
- {
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "BMPS is not "
- "enabled in the cfg");
- }
- }
- return VOS_STATUS_SUCCESS;
-}
-
-VOS_STATUS wlan_hdd_exit_lowpower(hdd_context_t *pHddCtx,
- hdd_adapter_t *pAdapter)
-{
- VOS_STATUS vos_Status;
-
- if ((NULL == pAdapter) || (NULL == pHddCtx))
- {
- hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid pointer");
- return VOS_STATUS_E_FAULT;
- }
-
- /**Exit from Deep sleep or standby if we get the driver
- START cmd from android GUI
- */
- if (WLAN_MAP_DRIVER_STOP_TO_STANDBY == pHddCtx->cfg_ini->nEnableDriverStop)
- {
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: WLAN being exit "
- "from Stand by",__func__);
- vos_Status = hdd_exit_standby(pHddCtx);
- }
- else if (eHDD_SUSPEND_DEEP_SLEEP == pHddCtx->hdd_ps_state)
- {
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: WLAN being exit "
- "from deep sleep",__func__);
- vos_Status = hdd_exit_deep_sleep(pHddCtx, pAdapter);
- }
- else
- {
- hddLog(VOS_TRACE_LEVEL_WARN, "%s: Not in standby or deep sleep. "
- "Ignore start cmd %d", __func__, pHddCtx->hdd_ps_state);
- vos_Status = VOS_STATUS_SUCCESS;
- }
-
- return vos_Status;
-}
-
-VOS_STATUS wlan_hdd_enter_lowpower(hdd_context_t *pHddCtx)
-{
- VOS_STATUS vos_Status = VOS_STATUS_E_FAILURE;
-
- if (NULL == pHddCtx)
- {
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "HDD context NULL");
- return VOS_STATUS_E_FAULT;
- }
-
- if (WLAN_MAP_DRIVER_STOP_TO_STANDBY == pHddCtx->cfg_ini->nEnableDriverStop)
- {
- //Execute standby procedure.
- //Executing standby procedure will cause the STA to
- //disassociate first and then the chip will be put into standby.
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Wlan driver entering Stand by mode");
- vos_Status = hdd_enter_standby(pHddCtx);
- }
- else if (WLAN_MAP_DRIVER_STOP_TO_DEEP_SLEEP ==
- pHddCtx->cfg_ini->nEnableDriverStop)
- {
- //Execute deep sleep procedure
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Wlan driver entering "
- "deep sleep mode\n");
- //Deep sleep not supported
- vos_Status = hdd_enter_standby(pHddCtx);
- }
- else
- {
- hddLog(VOS_TRACE_LEVEL_INFO_LOW, "%s: Driver stop is not enabled %d",
- __func__, pHddCtx->cfg_ini->nEnableDriverStop);
- vos_Status = VOS_STATUS_SUCCESS;
- }
-
- return vos_Status;
-}
-
-
-void* wlan_hdd_change_country_code_callback(void *pAdapter)
-{
-
- hdd_adapter_t *call_back_pAdapter = pAdapter;
- complete(&call_back_pAdapter->change_country_code);
-
- return NULL;
-}
-
-static int iw_set_priv(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- char *cmd = extra;
- int cmd_len = wrqu->data.length;
- int ret = 0;
- int status = 0;
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
-
- ENTER();
-
- if (ioctl_debug)
- {
- pr_info("%s: req [%s] len [%d]\n", __func__, cmd, cmd_len);
- }
-
- hddLog(VOS_TRACE_LEVEL_INFO_MED,
- "%s: ***Received %s cmd from Wi-Fi GUI***", __func__, cmd);
-
- if (pHddCtx->isLogpInProgress) {
- if (ioctl_debug)
- {
- pr_info("%s: RESTART in progress\n", __func__);
- }
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!",__func__);
- return status;
- }
-
- if(strncmp(cmd, "CSCAN",5) == 0 )
- {
- status = iw_set_cscan(dev, info, wrqu, extra);
- }
- else if( strcasecmp(cmd, "start") == 0 ) {
-
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Start command\n");
- /*Exit from Deep sleep or standby if we get the driver START cmd from android GUI*/
- status = wlan_hdd_exit_lowpower(pHddCtx, pAdapter);
-
- if(status == VOS_STATUS_SUCCESS)
- {
- union iwreq_data wrqu;
- char buf[10];
-
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = strlcpy(buf, "START", sizeof(buf));
- wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
- }
- else
- {
- hddLog(VOS_TRACE_LEVEL_FATAL, "%s: START CMD Status %d", __func__, status);
- }
- goto done;
- }
- else if( strcasecmp(cmd, "stop") == 0 )
- {
- union iwreq_data wrqu;
- char buf[10];
-
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Stop command\n");
-
- wlan_hdd_enter_lowpower(pHddCtx);
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = strlcpy(buf, "STOP", sizeof(buf));
- wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
- status = VOS_STATUS_SUCCESS;
- goto done;
- }
- else if (strcasecmp(cmd, "macaddr") == 0)
- {
- ret = snprintf(cmd, cmd_len, "Macaddr = " MAC_ADDRESS_STR,
- MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes));
- }
- else if (strcasecmp(cmd, "scan-active") == 0)
- {
- pAdapter->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
- ret = snprintf(cmd, cmd_len, "OK");
- }
- else if (strcasecmp(cmd, "scan-passive") == 0)
- {
- pAdapter->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
- ret = snprintf(cmd, cmd_len, "OK");
- }
- else if( strcasecmp(cmd, "scan-mode") == 0 )
- {
- ret = snprintf(cmd, cmd_len, "ScanMode = %u", pAdapter->scan_info.scan_mode);
- }
- else if( strcasecmp(cmd, "linkspeed") == 0 )
- {
- status = iw_get_linkspeed(dev, info, wrqu, extra);
- }
- else if( strncasecmp(cmd, "COUNTRY", 7) == 0 ) {
- char *country_code;
- long lrc;
-
- country_code = cmd + 8;
-
- init_completion(&pAdapter->change_country_code);
-
- status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
- (void *)(tSmeChangeCountryCallback)wlan_hdd_change_country_code_callback,
- country_code,
- pAdapter,
- pHddCtx->pvosContext,
- eSIR_TRUE,
- eSIR_TRUE);
-
- /* Wait for completion */
- lrc = wait_for_completion_interruptible_timeout(&pAdapter->change_country_code,
- msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
-
- if (lrc <= 0)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while setting country code ",
- __func__, "Timed out");
- }
-
- if( 0 != status )
- {
- VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- "%s: SME Change Country code fail \n",__func__);
- return VOS_STATUS_E_FAILURE;
- }
- }
- else if( strncasecmp(cmd, "rssi", 4) == 0 )
- {
- status = iw_get_rssi(dev, info, wrqu, extra);
- }
- else if( strncasecmp(cmd, "powermode", 9) == 0 ) {
- int mode;
- char *ptr;
-
- if (9 < cmd_len)
- {
- ptr = (char*)(cmd + 9);
-
- }else{
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "CMD LENGTH %d is not correct",cmd_len);
- return VOS_STATUS_E_FAILURE;
- }
-
- if (1 != sscanf(ptr,"%d",&mode))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "powermode input %s is not correct",ptr);
- return VOS_STATUS_E_FAILURE;
- }
-
- if(!pHddCtx->cfg_ini->enablePowersaveOffload)
- wlan_hdd_enter_bmps(pAdapter, mode);
- else
- wlan_hdd_set_powersave(pAdapter, mode);
- }
- else if (strncasecmp(cmd, "getpower", 8) == 0 ) {
- v_U32_t pmc_state;
- v_U16_t value;
-
- pmc_state = pmcGetPmcState(WLAN_HDD_GET_HAL_CTX(pAdapter));
- if(pmc_state == BMPS) {
- value = DRIVER_POWER_MODE_AUTO;
- }
- else {
- value = DRIVER_POWER_MODE_ACTIVE;
- }
- ret = snprintf(cmd, cmd_len, "powermode = %u", value);
- }
- else if( strncasecmp(cmd, "btcoexmode", 10) == 0 ) {
- hddLog( VOS_TRACE_LEVEL_INFO, "btcoexmode\n");
- /*TODO: set the btcoexmode*/
- }
- else if( strcasecmp(cmd, "btcoexstat") == 0 ) {
-
- hddLog(VOS_TRACE_LEVEL_INFO, "BtCoex Status\n");
- /*TODO: Return the btcoex status*/
- }
- else if( strcasecmp(cmd, "rxfilter-start") == 0 ) {
-
- hddLog(VOS_TRACE_LEVEL_INFO, "Rx Data Filter Start command\n");
-
- /*TODO: Enable Rx data Filter*/
- }
- else if( strcasecmp(cmd, "rxfilter-stop") == 0 ) {
-
- hddLog(VOS_TRACE_LEVEL_INFO, "Rx Data Filter Stop command\n");
-
- /*TODO: Disable Rx data Filter*/
- }
- else if( strcasecmp(cmd, "rxfilter-statistics") == 0 ) {
-
- hddLog( VOS_TRACE_LEVEL_INFO, "Rx Data Filter Statistics command\n");
- /*TODO: rxfilter-statistics*/
- }
- else if( strncasecmp(cmd, "rxfilter-add", 12) == 0 ) {
-
- hddLog( VOS_TRACE_LEVEL_INFO, "rxfilter-add\n");
- /*TODO: rxfilter-add*/
- }
- else if( strncasecmp(cmd, "rxfilter-remove",15) == 0 ) {
-
- hddLog( VOS_TRACE_LEVEL_INFO, "rxfilter-remove\n");
- /*TODO: rxfilter-remove*/
- }
-#ifdef FEATURE_WLAN_SCAN_PNO
- else if( strncasecmp(cmd, "pnosetup", 8) == 0 ) {
- hddLog( VOS_TRACE_LEVEL_INFO, "pnosetup");
- /*TODO: support pnosetup*/
- }
- else if( strncasecmp(cmd, "pnoforce", 8) == 0 ) {
- hddLog( VOS_TRACE_LEVEL_INFO, "pnoforce");
- /*TODO: support pnoforce*/
- }
- else if( strncasecmp(cmd, "pno",3) == 0 ) {
-
- hddLog( VOS_TRACE_LEVEL_INFO, "pno\n");
- status = iw_set_pno(dev, info, wrqu, extra, 3);
- return status;
- }
- else if( strncasecmp(cmd, "rssifilter",10) == 0 ) {
-
- hddLog( VOS_TRACE_LEVEL_INFO, "rssifilter\n");
- status = iw_set_rssi_filter(dev, info, wrqu, extra, 10);
- return status;
- }
-#endif /*FEATURE_WLAN_SCAN_PNO*/
- else if( strncasecmp(cmd, "powerparams",11) == 0 ) {
- hddLog( VOS_TRACE_LEVEL_INFO, "powerparams\n");
- status = iw_set_power_params(dev, info, wrqu, extra, 11);
- return status;
- }
- else if( 0 == strncasecmp(cmd, "CONFIG-TX-TRACKING", 18) ) {
- tSirTxPerTrackingParam tTxPerTrackingParam;
- char *ptr;
-
- if (18 < cmd_len)
- {
- ptr = (char*)(cmd + 18);
- }else{
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "CMD LENGTH %d is not correct",cmd_len);
- return VOS_STATUS_E_FAILURE;
- }
-
- if (4 != sscanf(ptr,"%hhu %hhu %hhu %u",
- &(tTxPerTrackingParam.ucTxPerTrackingEnable),
- &(tTxPerTrackingParam.ucTxPerTrackingPeriod),
- &(tTxPerTrackingParam.ucTxPerTrackingRatio),
- &(tTxPerTrackingParam.uTxPerTrackingWatermark)))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "CONFIG-TX-TRACKING %s input is not correct",ptr);
- return VOS_STATUS_E_FAILURE;
- }
-
- // parameters checking
- // period has to be larger than 0
- if (0 == tTxPerTrackingParam.ucTxPerTrackingPeriod)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Period input is not correct");
- return VOS_STATUS_E_FAILURE;
- }
-
- // use default value 5 is the input is not reasonable. in unit of 10%
- if ((tTxPerTrackingParam.ucTxPerTrackingRatio > TX_PER_TRACKING_MAX_RATIO) || (0 == tTxPerTrackingParam.ucTxPerTrackingRatio))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Ratio input is not good. use default 5");
- tTxPerTrackingParam.ucTxPerTrackingRatio = TX_PER_TRACKING_DEFAULT_RATIO;
- }
-
- // default is 5
- if (0 == tTxPerTrackingParam.uTxPerTrackingWatermark)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Tx Packet number input is not good. use default 5");
- tTxPerTrackingParam.uTxPerTrackingWatermark = TX_PER_TRACKING_DEFAULT_WATERMARK;
- }
-
- status = sme_SetTxPerTracking(pHddCtx->hHal, hdd_tx_per_hit_cb, (void*)pAdapter, &tTxPerTrackingParam);
- if(status != eHAL_STATUS_SUCCESS){
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Set Tx PER Tracking Failed!");
- }
- }
- else {
- hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
- __func__, cmd);
- }
-done:
- /* many of the commands write information back into the command
- string using snprintf(). check the return value here in one
- place */
- if ((ret < 0) || (ret >= cmd_len))
- {
- /* there was an encoding error or overflow */
- status = -EIO;
- }
- else if (ret > 0)
- {
- if (copy_to_user(wrqu->data.pointer, cmd, ret))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: failed to copy data to user buffer", __func__);
- return -EFAULT;
- }
- wrqu->data.length = ret;
- }
-
- if (ioctl_debug)
- {
- pr_info("%s: rsp [%s] len [%d] status %d\n",
- __func__, cmd, wrqu->data.length, status);
- }
- return status;
-}
-
-static int iw_set_nick(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- ENTER();
- return 0;
-}
-
-static int iw_get_nick(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- ENTER();
- return 0;
-}
-
-static struct iw_statistics *get_wireless_stats(struct net_device *dev)
-{
- ENTER();
- return NULL;
-}
-
-static int iw_set_encode(struct net_device *dev,struct iw_request_info *info,
- union iwreq_data *wrqu,char *extra)
-
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
- struct iw_point *encoderq = &(wrqu->encoding);
- v_U32_t keyId;
- v_U8_t key_length;
- eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
- v_BOOL_t fKeyPresent = 0;
- int i;
- eHalStatus status = eHAL_STATUS_SUCCESS;
-
-
- ENTER();
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!",__func__);
- return 0;
- }
-
-
- keyId = encoderq->flags & IW_ENCODE_INDEX;
-
- if(keyId)
- {
- if(keyId > MAX_WEP_KEYS)
- {
- return -EINVAL;
- }
-
- fKeyPresent = 1;
- keyId--;
- }
- else
- {
- fKeyPresent = 0;
- }
-
-
- if(wrqu->data.flags & IW_ENCODE_DISABLED)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "****iwconfig wlan0 key off*****\n");
- if(!fKeyPresent) {
-
- for(i=0;i < CSR_MAX_NUM_KEY; i++) {
-
- if(pWextState->roamProfile.Keys.KeyMaterial[i])
- pWextState->roamProfile.Keys.KeyLength[i] = 0;
- }
- }
- pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
- pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
- pWextState->roamProfile.EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
- pWextState->roamProfile.mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
-
- pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
- pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
-
- if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
- {
- INIT_COMPLETION(pAdapter->disconnect_comp_var);
- status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED );
- if(eHAL_STATUS_SUCCESS == status)
- wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
- msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
- }
-
- return status;
-
- }
-
- if (wrqu->data.flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED))
- {
- hddLog(VOS_TRACE_LEVEL_INFO, "iwconfig wlan0 key on");
-
- pHddStaCtx->conn_info.authType = (encoderq->flags & IW_ENCODE_RESTRICTED) ? eCSR_AUTH_TYPE_SHARED_KEY : eCSR_AUTH_TYPE_OPEN_SYSTEM;
-
- }
-
-
- if(wrqu->data.length > 0)
- {
- hddLog(VOS_TRACE_LEVEL_INFO, "%s : wrqu->data.length : %d",__func__,wrqu->data.length);
-
- key_length = wrqu->data.length;
-
- /* IW_ENCODING_TOKEN_MAX is the value that is set for wrqu->data.length by iwconfig.c when 'iwconfig wlan0 key on' is issued.*/
-
- if(5 == key_length)
- {
- hddLog(VOS_TRACE_LEVEL_INFO, "%s: Call with WEP40,key_len=%d",__func__,key_length);
-
- if((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
- {
- encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
- }
- else
- {
- encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
- }
- }
- else if(13 == key_length)
- {
- hddLog(VOS_TRACE_LEVEL_INFO, "%s:Call with WEP104,key_len:%d",__func__,key_length);
-
- if((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
- {
- encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
- }
- else
- {
- encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
- }
- }
- else
- {
- hddLog(VOS_TRACE_LEVEL_WARN, "%s: Invalid WEP key length :%d",
- __func__, key_length);
- return -EINVAL;
- }
-
- pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
- pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
- pWextState->roamProfile.EncryptionType.numEntries = 1;
- pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
- pWextState->roamProfile.mcEncryptionType.numEntries = 1;
- pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
-
- if((eConnectionState_NotConnected == pHddStaCtx->conn_info.connState) &&
- ((eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType) ||
- (eCSR_AUTH_TYPE_SHARED_KEY == pHddStaCtx->conn_info.authType)))
- {
-
- vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[keyId][0],extra,key_length);
-
- pWextState->roamProfile.Keys.KeyLength[keyId] = (v_U8_t)key_length;
- pWextState->roamProfile.Keys.defaultIndex = (v_U8_t)keyId;
-
- return status;
- }
- }
-
- return 0;
-}
-
-static int iw_get_encodeext(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *dwrq,
- char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
- tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
- int keyId;
- eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
- eCsrAuthType authType = eCSR_AUTH_TYPE_NONE;
- int i;
-
- ENTER();
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- keyId = pRoamProfile->Keys.defaultIndex;
-
- if(keyId < 0 || keyId >= MAX_WEP_KEYS)
- {
- hddLog(LOG1,"%s: Invalid keyId : %d\n",__func__,keyId);
- return -EINVAL;
- }
-
- if(pRoamProfile->Keys.KeyLength[keyId] > 0)
- {
- dwrq->flags |= IW_ENCODE_ENABLED;
- dwrq->length = pRoamProfile->Keys.KeyLength[keyId];
- vos_mem_copy(extra, &(pRoamProfile->Keys.KeyMaterial[keyId][0]),
- pRoamProfile->Keys.KeyLength[keyId]);
- }
- else
- {
- dwrq->flags |= IW_ENCODE_DISABLED;
- }
-
- for(i=0; i < MAX_WEP_KEYS; i++)
- {
- if(pRoamProfile->Keys.KeyMaterial[i] == NULL)
- {
- continue;
- }
- else
- {
- break;
- }
- }
-
- if(MAX_WEP_KEYS == i)
- {
- dwrq->flags |= IW_ENCODE_NOKEY;
- }
- else
- {
- dwrq->flags |= IW_ENCODE_ENABLED;
- }
-
- encryptionType = pRoamProfile->EncryptionType.encryptionType[0];
-
- if(eCSR_ENCRYPT_TYPE_NONE == encryptionType)
- {
- dwrq->flags |= IW_ENCODE_DISABLED;
- }
-
- authType = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
-
- if(IW_AUTH_ALG_OPEN_SYSTEM == authType)
- {
- dwrq->flags |= IW_ENCODE_OPEN;
- }
- else
- {
- dwrq->flags |= IW_ENCODE_RESTRICTED;
- }
- EXIT();
- return 0;
-
-}
-
-static int iw_set_encodeext(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
- eHalStatus halStatus= eHAL_STATUS_SUCCESS;
-
- tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
- v_U32_t status = 0;
-
- struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
-
- v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
-
- int key_index;
- struct iw_point *encoding = &wrqu->encoding;
- tCsrRoamSetKey setKey;
- v_U32_t roamId= 0xFF;
- VOS_STATUS vos_status;
-
- ENTER();
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!",__func__);
- return 0;
- }
-
- key_index = encoding->flags & IW_ENCODE_INDEX;
-
- if(key_index > 0) {
-
- /*Convert from 1-based to 0-based keying*/
- key_index--;
- }
- if(!ext->key_len) {
-
- /*Set the encrytion type to NONE*/
- pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
- return status;
- }
-
- if(eConnectionState_NotConnected == pHddStaCtx->conn_info.connState &&
- (IW_ENCODE_ALG_WEP == ext->alg))
- {
- if(IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) {
-
- VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,("Invalid Configuration:%s \n"),__func__);
- return -EINVAL;
- }
- else {
- /*Static wep, update the roam profile with the keys */
- if(ext->key && (ext->key_len <= eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES) &&
- key_index < CSR_MAX_NUM_KEY) {
- vos_mem_copy(&pRoamProfile->Keys.KeyMaterial[key_index][0],ext->key,ext->key_len);
- pRoamProfile->Keys.KeyLength[key_index] = (v_U8_t)ext->key_len;
-
- if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
- pRoamProfile->Keys.defaultIndex = (v_U8_t)key_index;
-
- }
- }
- return status;
- }
-
- vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
-
- setKey.keyId = key_index;
- setKey.keyLength = ext->key_len;
-
- if(ext->key_len <= CSR_MAX_KEY_LEN) {
- vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
- }
-
- if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
- /*Key direction for group is RX only*/
- setKey.keyDirection = eSIR_RX_ONLY;
- vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
- }
- else {
-
- setKey.keyDirection = eSIR_TX_RX;
- vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
- }
-
- /*For supplicant pae role is zero*/
- setKey.paeRole = 0;
-
- switch(ext->alg)
- {
- case IW_ENCODE_ALG_NONE:
- setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
- break;
-
- case IW_ENCODE_ALG_WEP:
- setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
- break;
-
- case IW_ENCODE_ALG_TKIP:
- {
- v_U8_t *pKey = &setKey.Key[0];
-
- setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
-
- vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
-
- /*Supplicant sends the 32bytes key in this order
-
- |--------------|----------|----------|
- | Tk1 |TX-MIC | RX Mic |
- |--------------|----------|----------|
- <---16bytes---><--8bytes--><--8bytes-->
-
- */
- /*Sme expects the 32 bytes key to be in the below order
-
- |--------------|----------|----------|
- | Tk1 |RX-MIC | TX Mic |
- |--------------|----------|----------|
- <---16bytes---><--8bytes--><--8bytes-->
- */
- /* Copy the Temporal Key 1 (TK1) */
- vos_mem_copy(pKey,ext->key,16);
-
- /*Copy the rx mic first*/
- vos_mem_copy(&pKey[16],&ext->key[24],8);
-
- /*Copy the tx mic */
- vos_mem_copy(&pKey[24],&ext->key[16],8);
-
- }
- break;
-
- case IW_ENCODE_ALG_CCMP:
- setKey.encType = eCSR_ENCRYPT_TYPE_AES;
- break;
-
-#ifdef FEATURE_WLAN_CCX
-#define IW_ENCODE_ALG_KRK 6
- case IW_ENCODE_ALG_KRK:
- setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
- break;
-#endif /* FEATURE_WLAN_CCX */
-
- default:
- setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
- break;
- }
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- ("%s:cipher_alg:%d key_len[%d] *pEncryptionType :%d \n"),__func__,(int)ext->alg,(int)ext->key_len,setKey.encType);
-
-#ifdef WLAN_FEATURE_VOWIFI_11R
- /* The supplicant may attempt to set the PTK once pre-authentication
- is done. Save the key in the UMAC and include it in the ADD
- BSS request */
- halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
- if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
- {
- hddLog(VOS_TRACE_LEVEL_INFO_MED,
- "%s: Update PreAuth Key success", __func__);
- return 0;
- }
- else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Update PreAuth Key failed", __func__);
- return -EINVAL;
- }
-#endif /* WLAN_FEATURE_VOWIFI_11R */
-
- pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
-
- vos_status = wlan_hdd_check_ula_done(pAdapter);
- if ( vos_status != VOS_STATUS_SUCCESS )
- {
- VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
- __LINE__, vos_status );
-
- pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
- }
-
- halStatus = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),pAdapter->sessionId, &setKey, &roamId );
-
- if ( halStatus != eHAL_STATUS_SUCCESS )
- {
- VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "[%4d] sme_RoamSetKey returned ERROR status= %d",
- __LINE__, halStatus );
-
- pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
- }
-
- return halStatus;
-}
-
-static int iw_set_retry(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
-
- ENTER();
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- if(wrqu->retry.value < WNI_CFG_LONG_RETRY_LIMIT_STAMIN ||
- wrqu->retry.value > WNI_CFG_LONG_RETRY_LIMIT_STAMAX) {
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("Invalid Retry-Limit=%ld!!\n"),wrqu->retry.value);
-
- return -EINVAL;
- }
-
- if(wrqu->retry.flags & IW_RETRY_LIMIT) {
-
- if((wrqu->retry.flags & IW_RETRY_LONG))
- {
- if ( ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT, wrqu->retry.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS )
- {
- return -EIO;
- }
- }
- else if((wrqu->retry.flags & IW_RETRY_SHORT))
- {
- if ( ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT, wrqu->retry.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS )
- {
- return -EIO;
- }
- }
- }
- else
- {
- return -EOPNOTSUPP;
- }
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("Set Retry-Limit=%ld!!\n"),wrqu->retry.value);
-
- EXIT();
-
- return 0;
-
-}
-
-static int iw_get_retry(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- v_U32_t retry = 0;
-
- ENTER();
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- if((wrqu->retry.flags & IW_RETRY_LONG))
- {
- wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
-
- if ( ccmCfgGetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT, &retry) != eHAL_STATUS_SUCCESS )
- {
- return -EIO;
- }
-
- wrqu->retry.value = retry;
- }
- else if ((wrqu->retry.flags & IW_RETRY_SHORT))
- {
- wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
-
- if ( ccmCfgGetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT, &retry) != eHAL_STATUS_SUCCESS )
- {
- return -EIO;
- }
-
- wrqu->retry.value = retry;
- }
- else {
- return -EOPNOTSUPP;
- }
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("Retry-Limit=%ld!!\n"),retry);
-
- EXIT();
-
- return 0;
-}
-
-static int iw_set_mlme(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- struct iw_mlme *mlme = (struct iw_mlme *)extra;
- eHalStatus status = eHAL_STATUS_SUCCESS;
-
- ENTER();
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!",__func__);
- return 0;
- }
-
- //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
- switch (mlme->cmd) {
- case IW_MLME_DISASSOC:
- case IW_MLME_DEAUTH:
-
- if( pHddStaCtx->conn_info.connState == eConnectionState_Associated )
- {
- eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
-
- if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
- reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
-
- INIT_COMPLETION(pAdapter->disconnect_comp_var);
- status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,reason);
-
- if(eHAL_STATUS_SUCCESS == status)
- wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
- msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
- else
- hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d \n",
- __func__, (int)mlme->cmd, (int)status );
-
- /* Resetting authKeyMgmt */
- (WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->authKeyMgmt = 0;
-
- netif_tx_disable(dev);
- netif_carrier_off(dev);
-
- }
- else
- {
- hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate called but station is not in associated state \n", __func__, (int)mlme->cmd );
- }
- break;
- default:
- hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate \n", __func__, (int)mlme->cmd );
- return -EINVAL;
- }//end of switch
-
- EXIT();
-
- return status;
-
-}
-
-#ifdef QCA_WIFI_2_0
-int process_wma_set_command(int sessid, int paramid,
- int sval, int vpdev)
-{
- int ret = 0;
- vos_msg_t msg = {0};
-
- wda_cli_set_cmd_t *iwcmd = (wda_cli_set_cmd_t *)vos_mem_malloc(
- sizeof(wda_cli_set_cmd_t));
- if (NULL == iwcmd) {
- hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed", __func__);
- return -EINVAL;
- }
- vos_mem_zero((void *)iwcmd, sizeof(wda_cli_set_cmd_t));
- iwcmd->param_value = sval;
- iwcmd->param_vdev_id = sessid;
- iwcmd->param_id = paramid;
- iwcmd->param_vp_dev = vpdev;
- msg.type = WDA_CLI_SET_CMD;
- msg.reserved = 0;
- msg.bodyptr = (void *)iwcmd;
- if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA,
- &msg)) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: "
- "Not able to post wda_cli_set_cmd message to WDA",
- __func__);
- vos_mem_free(iwcmd);
- ret = -EIO;
- }
- return ret;
-}
-#endif
-
-#ifdef QCA_WIFI_2_0
-static int wlan_hdd_update_phymode(struct net_device *net, tHalHandle hal,
- int new_phymode,
- hdd_context_t *phddctx)
-{
- v_BOOL_t band_24 = VOS_FALSE, band_5g = VOS_FALSE;
- v_BOOL_t ch_bond24 = VOS_FALSE, ch_bond5g = VOS_FALSE;
- tSmeConfigParams smeconfig;
- tANI_U32 vhtchanwidth, chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
- eCsrPhyMode phymode = -EIO, old_phymode;
- eCsrBand curr_band = eCSR_BAND_ALL;
-
- old_phymode = sme_GetPhyMode(hal);
-
- if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
- sme_GetCBPhyStateFromCBIniValue(
- phddctx->cfg_ini->nChannelBondingMode24GHz))
- ch_bond24 = VOS_TRUE;
-
- if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
- sme_GetCBPhyStateFromCBIniValue(
- phddctx->cfg_ini->nChannelBondingMode5GHz))
- ch_bond5g = VOS_TRUE;
-
- if (phddctx->cfg_ini->nBandCapability == eCSR_BAND_ALL) {
- band_24 = band_5g = VOS_TRUE;
- } else if (phddctx->cfg_ini->nBandCapability == eCSR_BAND_24) {
- band_24 = VOS_TRUE;
- } else if (phddctx->cfg_ini->nBandCapability == eCSR_BAND_5G) {
- band_5g = VOS_TRUE;
- }
-
- vhtchanwidth = phddctx->cfg_ini->vhtChannelWidth;
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, ("ch_bond24=%d "
- "ch_bond5g=%d band_24=%d band_5g=%d VHT_ch_width=%u"), ch_bond24,
- ch_bond5g, band_24, band_5g, vhtchanwidth);
- switch (new_phymode) {
- case IEEE80211_MODE_11A:
- if (band_5g) {
- sme_SetPhyMode(hal, eCSR_DOT11_MODE_11a);
- if ((hdd_setBand_helper(net, "SETBAND 1") == 0))
- phymode = eCSR_DOT11_MODE_11a;
- else {
- sme_SetPhyMode(hal, old_phymode);
- return -EIO;
- }
- }
- break;
- case IEEE80211_MODE_11B:
- if (band_24) {
- sme_SetPhyMode(hal, eCSR_DOT11_MODE_11b);
- if ((hdd_setBand_helper(net, "SETBAND 2") == 0))
- phymode = eCSR_DOT11_MODE_11b;
- else {
- sme_SetPhyMode(hal, old_phymode);
- return -EIO;
- }
- }
- break;
- case IEEE80211_MODE_11G:
- if (band_24) {
- sme_SetPhyMode(hal, eCSR_DOT11_MODE_11g);
- if ((hdd_setBand_helper(net, "SETBAND 2") == 0))
- phymode = eCSR_DOT11_MODE_11g;
- else {
- sme_SetPhyMode(hal, old_phymode);
- return -EIO;
- }
- }
- break;
- /* UMAC doesnt have option to set MODE_11NA/MODE_11NG as phymode
- * so setting phymode as eCSR_DOT11_MODE_11n and updating the band
- * and channel bonding in configuration to reflect MODE_11NA/MODE_11NG
- */
- case IEEE80211_MODE_11NA_HT20:
- if (band_5g) {
- sme_SetPhyMode(hal, eCSR_DOT11_MODE_11n);
- if ((hdd_setBand_helper(net, "SETBAND 1") == 0)) {
- phymode = eCSR_DOT11_MODE_11n;
- chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
- curr_band = eCSR_BAND_5G;
- } else {
- sme_SetPhyMode(hal, old_phymode);
- return -EIO;
- }
- }
- break;
- case IEEE80211_MODE_11NA_HT40:
- if (band_5g && ch_bond5g) {
- sme_SetPhyMode(hal, eCSR_DOT11_MODE_11n);
- if ((hdd_setBand_helper(net, "SETBAND 1") == 0)) {
- phymode = eCSR_DOT11_MODE_11n;
- chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
- curr_band = eCSR_BAND_5G;
- } else {
- sme_SetPhyMode(hal, old_phymode);
- return -EIO;
- }
- }
- break;
- case IEEE80211_MODE_11NG_HT20:
- if (band_24) {
- sme_SetPhyMode(hal, eCSR_DOT11_MODE_11n);
- if ((hdd_setBand_helper(net, "SETBAND 2") == 0)) {
- phymode = eCSR_DOT11_MODE_11n;
- chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
- curr_band = eCSR_BAND_24;
- } else {
- sme_SetPhyMode(hal, old_phymode);
- return -EIO;
- }
- }
- break;
- case IEEE80211_MODE_11NG_HT40:
- if (band_24 && ch_bond24) {
- sme_SetPhyMode(hal, eCSR_DOT11_MODE_11n);
- if ((hdd_setBand_helper(net, "SETBAND 2") == 0)) {
- phymode = eCSR_DOT11_MODE_11n;
- chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
- curr_band = eCSR_BAND_24;
- } else {
- sme_SetPhyMode(hal, old_phymode);
- return -EIO;
- }
- }
- break;
-#ifdef WLAN_FEATURE_11AC
- case IEEE80211_MODE_11AC_VHT20:
- case IEEE80211_MODE_11AC_VHT40:
- if ((vhtchanwidth == eHT_CHANNEL_WIDTH_20MHZ ||
- vhtchanwidth == eHT_CHANNEL_WIDTH_40MHZ) &&
- band_5g) {
- sme_SetPhyMode(hal, eCSR_DOT11_MODE_11ac);
- if ((hdd_setBand_helper(net, "SETBAND 1") == 0)) {
- phymode = eCSR_DOT11_MODE_11ac;
- } else {
- sme_SetPhyMode(hal, old_phymode);
- return -EIO;
- }
- }
- break;
- case IEEE80211_MODE_11AC_VHT80:
- if ((vhtchanwidth == eHT_CHANNEL_WIDTH_80MHZ) &&
- band_5g) {
- sme_SetPhyMode(hal, eCSR_DOT11_MODE_11ac);
- if ((hdd_setBand_helper(net, "SETBAND 1") == 0)) {
- phymode = eCSR_DOT11_MODE_11ac;
- } else {
- sme_SetPhyMode(hal, old_phymode);
- return -EIO;
- }
- }
- break;
-#endif
- default:
- return -EIO;
- }
-
- if (phymode != -EIO) {
- sme_GetConfigParam(hal, &smeconfig);
- smeconfig.csrConfig.phyMode = phymode;
- if (phymode == eCSR_DOT11_MODE_11n &&
- chwidth == WNI_CFG_CHANNEL_BONDING_MODE_DISABLE) {
- if (curr_band == eCSR_BAND_24)
- smeconfig.csrConfig.channelBondingMode24GHz =
- WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
- else
- smeconfig.csrConfig.channelBondingMode5GHz =
- WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
- } else if (phymode == eCSR_DOT11_MODE_11n &&
- chwidth == WNI_CFG_CHANNEL_BONDING_MODE_ENABLE) {
- if (curr_band == eCSR_BAND_24)
- smeconfig.csrConfig.channelBondingMode24GHz =
- phddctx->cfg_ini->nChannelBondingMode24GHz;
- else
- smeconfig.csrConfig.channelBondingMode5GHz =
- phddctx->cfg_ini->nChannelBondingMode5GHz;
- }
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "SET PHY MODE=%d",
- smeconfig.csrConfig.phyMode);
- sme_UpdateConfig(hal, &smeconfig);
- }
-
- return 0;
-}
-#endif
-/* set param sub-ioctls */
-static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
- tSmeConfigParams smeConfig;
- int *value = (int *)extra;
- int sub_cmd = value[0];
- int set_value = value[1];
- int ret = 0; /* success */
- int enable_pbm, enable_mp;
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
- v_U8_t nEnableSuspendOld;
-#endif
- INIT_COMPLETION(pWextState->completion_var);
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- switch(sub_cmd)
- {
- case WE_SET_11D_STATE:
- {
- if((ENABLE_11D == set_value) || (DISABLE_11D == set_value)) {
-
- memset(&smeConfig, 0x00, sizeof(smeConfig));
- sme_GetConfigParam(hHal, &smeConfig);
- smeConfig.csrConfig.Is11dSupportEnabled = (v_BOOL_t)set_value;
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- ("11D state=%ld!!\n"),
- smeConfig.csrConfig.Is11dSupportEnabled);
-
- sme_UpdateConfig(hHal, &smeConfig);
- }
- else {
- return -EINVAL;
- }
- break;
- }
-
- case WE_WOWL:
- {
- switch (set_value)
- {
- case 0x00:
- hdd_exit_wowl(pAdapter);
- break;
- case 0x01:
- case 0x02:
- case 0x03:
- enable_mp = (set_value & 0x01) ? 1 : 0;
- enable_pbm = (set_value & 0x02) ? 1 : 0;
- hddLog(LOGE, "magic packet ? = %s pattern byte matching ? = %s\n",
- (enable_mp ? "YES":"NO"), (enable_pbm ? "YES":"NO"));
- hdd_enter_wowl(pAdapter, enable_mp, enable_pbm);
- break;
- default:
- hddLog(LOGE, "Invalid arg %d in WE_WOWL IOCTL\n", set_value);
- ret = -EINVAL;
- break;
- }
-
- break;
- }
- case WE_SET_POWER:
- {
- switch (set_value)
- {
- case 0: //Full Power
- {
- struct statsContext context;
- eHalStatus status;
-
- init_completion(&context.completion);
-
- context.pAdapter = pAdapter;
- context.magic = POWER_CONTEXT_MAGIC;
-
- status = sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
- iw_power_callback_fn, &context,
- eSME_FULL_PWR_NEEDED_BY_HDD);
- if(eHAL_STATUS_PMC_PENDING == status)
- {
- int lrc = wait_for_completion_interruptible_timeout(
- &context.completion,
- msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
- context.magic = 0;
- if (lrc <= 0)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while "
- "requesting fullpower ",
- __func__, (0 == lrc) ?
- "timeout" : "interrupt");
- /* there is a race condition such that the callback
- function could be executing at the same time we are. of
- primary concern is if the callback function had already
- verified the "magic" but hasn't yet set the completion
- variable. Since the completion variable is on our
- stack, we'll delay just a bit to make sure the data is
- still valid if that is the case */
- msleep(50);
- /* we'll now returned a cached value below */
- }
- }
- hddLog(LOGE, "iwpriv Full Power completed\n");
- break;
- }
- case 1: //Enable BMPS
- sme_EnablePowerSave(hHal, ePMC_BEACON_MODE_POWER_SAVE);
- break;
- case 2: //Disable BMPS
- sme_DisablePowerSave(hHal, ePMC_BEACON_MODE_POWER_SAVE);
- break;
- case 3: //Request Bmps
- {
- struct statsContext context;
- eHalStatus status;
-
- init_completion(&context.completion);
-
- context.pAdapter = pAdapter;
- context.magic = POWER_CONTEXT_MAGIC;
-
- status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter),
- iw_power_callback_fn, &context);
- if(eHAL_STATUS_PMC_PENDING == status)
- {
- int lrc = wait_for_completion_interruptible_timeout(
- &context.completion,
- msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
- context.magic = 0;
- if (lrc <= 0)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while "
- "requesting BMPS",
- __func__, (0 == lrc) ? "timeout" :
- "interrupt");
- /* there is a race condition such that the callback
- function could be executing at the same time we are. of
- primary concern is if the callback function had already
- verified the "magic" but hasn't yet set the completion
- variable. Since the completion variable is on our
- stack, we'll delay just a bit to make sure the data is
- still valid if that is the case */
- msleep(50);
- /* we'll now returned a cached value below */
- }
- }
- hddLog(LOGE, "iwpriv Request BMPS completed\n");
- break;
- }
- case 4: //Enable IMPS
- sme_EnablePowerSave(hHal, ePMC_IDLE_MODE_POWER_SAVE);
- break;
- case 5: //Disable IMPS
- sme_DisablePowerSave(hHal, ePMC_IDLE_MODE_POWER_SAVE);
- break;
- case 6: //Enable Standby
- sme_EnablePowerSave(hHal, ePMC_STANDBY_MODE_POWER_SAVE);
- break;
- case 7: //Disable Standby
- sme_DisablePowerSave(hHal, ePMC_STANDBY_MODE_POWER_SAVE);
- break;
- case 8: //Request Standby
-#ifdef CONFIG_HAS_EARLYSUSPEND
-#endif
- break;
- case 9: //Start Auto Bmps Timer
- sme_StartAutoBmpsTimer(hHal);
- break;
- case 10://Stop Auto BMPS Timer
- sme_StopAutoBmpsTimer(hHal);
- break;
-#ifdef CONFIG_HAS_EARLYSUSPEND
- case 11://suspend to standby
-#ifdef CONFIG_HAS_EARLYSUSPEND
- nEnableSuspendOld = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend;
- (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = 1;
- (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = nEnableSuspendOld;
-#endif
- break;
- case 12://suspend to deep sleep
-#ifdef CONFIG_HAS_EARLYSUSPEND
- nEnableSuspendOld = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend;
- (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = 2;
- (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = nEnableSuspendOld;
-#endif
- break;
- case 13://resume from suspend
-#ifdef CONFIG_HAS_EARLYSUSPEND
-#endif
- break;
-#endif
- case 14://reset wlan (power down/power up)
- vos_chipReset(NULL, VOS_FALSE, NULL, NULL, VOS_CHIP_RESET_UNKNOWN_EXCEPTION);
- break;
- default:
- hddLog(LOGE, "Invalid arg %d in WE_SET_POWER IOCTL\n", set_value);
- ret = -EINVAL;
- break;
- }
- break;
- }
-
- case WE_SET_MAX_ASSOC:
- {
- if ((WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) ||
- (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value))
- {
- ret = -EINVAL;
- }
- else if ( ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
- set_value, NULL, eANI_BOOLEAN_FALSE)
- != eHAL_STATUS_SUCCESS )
- {
- ret = -EIO;
- }
- break;
- }
-
- case WE_SET_SAP_AUTO_CHANNEL_SELECTION:
- {
- if( 0 == set_value )
- {
- (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->apAutoChannelSelection = 0;
- }
- else if ( 1 == set_value )
- {
- (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->apAutoChannelSelection = 1;
- }
- else
- {
- hddLog(LOGE, "Invalid arg %d in WE_SET_SAP_AUTO_CHANNEL_SELECTION IOCTL\n", set_value);
- ret = -EINVAL;
- }
- break;
- }
-
- case WE_SET_DATA_INACTIVITY_TO:
- {
- if ((set_value < CFG_DATA_INACTIVITY_TIMEOUT_MIN) ||
- (set_value > CFG_DATA_INACTIVITY_TIMEOUT_MAX) ||
- (ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
- WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT,
- set_value,
- NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE))
- {
- hddLog(LOGE,"Failure: Could not pass on "
- "WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT configuration info "
- "to CCM\n");
- ret = -EINVAL;
- }
- break;
- }
- case WE_SET_MAX_TX_POWER:
- {
- tSirMacAddr bssid;
- tSirMacAddr selfMac;
-
- hddLog(VOS_TRACE_LEVEL_INFO, "%s: Setting maximum tx power %d dBm",
- __func__, set_value);
- vos_mem_copy(bssid, pAdapter->macAddressCurrent.bytes,
- VOS_MAC_ADDR_SIZE);
- vos_mem_copy(selfMac, pAdapter->macAddressCurrent.bytes,
- VOS_MAC_ADDR_SIZE);
-
- if( sme_SetMaxTxPower(hHal, bssid, selfMac, set_value) !=
- eHAL_STATUS_SUCCESS )
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
- __func__);
- return -EIO;
- }
-
- break;
- }
- case WE_SET_MAX_TX_POWER_2_4:
- {
- hddLog(VOS_TRACE_LEVEL_INFO,
- "%s: Setting maximum tx power %d dBm for 2.4 GHz band",
- __func__, set_value);
- if (sme_SetMaxTxPowerPerBand(eCSR_BAND_24, set_value) !=
- eHAL_STATUS_SUCCESS)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Setting maximum tx power failed for 2.4 GHz band",
- __func__);
- return -EIO;
- }
-
- break;
- }
- case WE_SET_MAX_TX_POWER_5_0:
- {
- hddLog(VOS_TRACE_LEVEL_INFO,
- "%s: Setting maximum tx power %d dBm for 5.0 GHz band",
- __func__, set_value);
- if (sme_SetMaxTxPowerPerBand(eCSR_BAND_5G, set_value) !=
- eHAL_STATUS_SUCCESS)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Setting maximum tx power failed for 5.0 GHz band",
- __func__);
- return -EIO;
- }
-
- break;
- }
- case WE_SET_HIGHER_DTIM_TRANSITION:
- {
- if(!((set_value == eANI_BOOLEAN_FALSE) ||
- (set_value == eANI_BOOLEAN_TRUE)))
- {
- hddLog(LOGE, "Dynamic DTIM Incorrect data:%d", set_value);
- ret = -EINVAL;
- }
- else
- {
- if(pAdapter->higherDtimTransition != set_value)
- {
- pAdapter->higherDtimTransition = set_value;
- hddLog(LOG1, "%s: higherDtimTransition set to :%d", __func__, pAdapter->higherDtimTransition);
- }
- }
-
- break;
- }
-
- case WE_SET_TM_LEVEL:
- {
-#ifdef QCA_WIFI_ISOC
- hdd_context_t *hddCtxt = WLAN_HDD_GET_CTX(pAdapter);
- hddLog(VOS_TRACE_LEVEL_INFO, "Set Thermal Mitigation Level %d", (int)set_value);
- hddDevTmLevelChangedHandler(hddCtxt->parent_dev, set_value);
-#else
- hddLog(VOS_TRACE_LEVEL_INFO, "Thermal Mitigation Level %d not set for discrete",
- (int)set_value);
-#endif
- break;
- }
-
- case WE_ENABLE_STRICT_FCC_REG:
- {
- hdd_context_t *hddCtxt = WLAN_HDD_GET_CTX(pAdapter);
- struct wiphy *wiphy = NULL;
- long lrc;
- int status;
-
- wiphy = hddCtxt->wiphy;
- if(wiphy == NULL)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy is NULL ", __func__);
- break;
- }
- init_completion(&hddCtxt->wiphy_channel_update_event);
-
- hddCtxt->nEnableStrictRegulatoryForFCC = set_value;
-
- status = regulatory_hint(wiphy, "00");
- if(status < 0)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failure in setting regulatory rule ", __func__);
- break;
- }
-
- /* Wait for completion */
- lrc = wait_for_completion_interruptible_timeout(&hddCtxt->wiphy_channel_update_event,
- msecs_to_jiffies(WLAN_WAIT_TIME_CHANNEL_UPDATE));
- if (lrc <= 0)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while setting strict FCC regulatory rule ",
- __func__, (0 == lrc) ? "Timeout" : "Interrupt");
- return (0 == lrc) ? -ETIMEDOUT : -EINTR;
- }
- hddLog(VOS_TRACE_LEVEL_INFO,"%s: SUCCESS in setting strict FCC regulatory rule", __func__);
-
- break;
- }
-#ifdef QCA_WIFI_2_0
- case WE_SET_PHYMODE:
- {
- hdd_context_t *phddctx = WLAN_HDD_GET_CTX(pAdapter);
-
- ret = wlan_hdd_update_phymode(dev, hHal, set_value, phddctx);
- break;
- }
-
- case WE_SET_NSS:
- {
- hddLog(LOG1, "WMI_VDEV_PARAM_NSS val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_VDEV_PARAM_NSS,
- set_value, VDEV_CMD);
- break;
- }
-
- case WE_SET_LDPC:
- {
- tANI_U32 value;
- union {
- tANI_U16 nCfgValue16;
- tSirMacHTCapabilityInfo htCapInfo;
- }uHTCapabilityInfo;
-
- hddLog(LOG1, "LDPC val %d", set_value);
- /* get the HT capability info*/
- ret = ccmCfgGetInt(hHal, WNI_CFG_HT_CAP_INFO, &value);
- if (eHAL_STATUS_SUCCESS != ret) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "%s: could not get HT capability info",
- __func__);
- return -EIO;
- }
-
- uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
- if ((set_value && (uHTCapabilityInfo.htCapInfo.advCodingCap)) ||
- (!set_value)) {
- ret = sme_UpdateHTConfig(hHal, pAdapter->sessionId,
- WNI_CFG_HT_CAP_INFO_ADVANCE_CODING,
- set_value);
- }
-
- if (ret)
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "Failed to set LDPC value");
-
- break;
- }
-
- case WE_SET_TX_STBC:
- {
- tANI_U32 value;
- union {
- tANI_U16 nCfgValue16;
- tSirMacHTCapabilityInfo htCapInfo;
- }uHTCapabilityInfo;
-
- hddLog(LOG1, "TX_STBC val %d", set_value);
- /* get the HT capability info*/
- ret = ccmCfgGetInt(hHal, WNI_CFG_HT_CAP_INFO, &value);
- if (eHAL_STATUS_SUCCESS != ret) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "%s: could not get HT capability info",
- __func__);
- return -EIO;
- }
-
- uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
- if ((set_value && (uHTCapabilityInfo.htCapInfo.txSTBC)) ||
- (!set_value)) {
- ret = sme_UpdateHTConfig(hHal, pAdapter->sessionId,
- WNI_CFG_HT_CAP_INFO_TX_STBC,
- set_value);
- }
-
- if (ret)
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "Failed to set TX STBC value");
-
- break;
- }
-
- case WE_SET_RX_STBC:
- {
- tANI_U32 value;
- union {
- tANI_U16 nCfgValue16;
- tSirMacHTCapabilityInfo htCapInfo;
- }uHTCapabilityInfo;
-
- hddLog(LOG1, "WMI_VDEV_PARAM_RX_STBC val %d", set_value);
- /* get the HT capability info*/
- ret = ccmCfgGetInt(hHal, WNI_CFG_HT_CAP_INFO, &value);
- if (eHAL_STATUS_SUCCESS != ret) {
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- "%s: could not get HT capability info",
- __func__);
- return -EIO;
- }
-
- uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
- if ((set_value && (uHTCapabilityInfo.htCapInfo.rxSTBC)) ||
- (!set_value)) {
- ret = sme_UpdateHTConfig(hHal, pAdapter->sessionId,
- WNI_CFG_HT_CAP_INFO_RX_STBC,
- (!set_value)? set_value :
- uHTCapabilityInfo.htCapInfo.rxSTBC);
- }
-
- if (ret)
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "Failed to set RX STBC value");
- break;
- }
-
- case WE_SET_SHORT_GI:
- {
- hddLog(LOG1, "WMI_VDEV_PARAM_SGI val %d", set_value);
- ret = sme_UpdateHTConfig(hHal, pAdapter->sessionId,
- WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ,
- set_value);
- if (ret)
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "Failed to set ShortGI value");
- break;
- }
-
- case WE_SET_RTSCTS:
- {
- u_int32_t value;
-
- hddLog(LOG1, "WMI_VDEV_PARAM_ENABLE_RTSCTS val %d", set_value);
- if (set_value == 1)
- value = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->RTSThreshold;
- else if (set_value == 0)
- value = WNI_CFG_RTS_THRESHOLD_STAMAX;
- else
- return -EIO;
-
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_VDEV_PARAM_ENABLE_RTSCTS,
- set_value, VDEV_CMD);
- if (!ret) {
- if (ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD, value,
- ccmCfgSetCallback, eANI_BOOLEAN_TRUE) !=
- eHAL_STATUS_SUCCESS) {
- hddLog(LOGE, "FAILED TO SET RTSCTS");
- return -EIO;
- }
- }
-
- break;
- }
-
- case WE_SET_CHWIDTH:
- {
- bool chwidth;
- hdd_context_t *phddctx = WLAN_HDD_GET_CTX(pAdapter);
- /*updating channel bonding only on 5Ghz*/
- hddLog(LOG1, "WMI_VDEV_PARAM_CHWIDTH val %d", set_value);
- if (set_value > eHT_CHANNEL_WIDTH_80MHZ) {
- hddLog(LOGE, "Invalid channel width 0->20 1->40 2->80");
- return -EINVAL;
- }
-
- if ((WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
- csrConvertCBIniValueToPhyCBState(
- phddctx->cfg_ini->nChannelBondingMode5GHz)))
- chwidth = true;
-
- memset(&smeConfig, 0x00, sizeof(smeConfig));
- sme_GetConfigParam(hHal, &smeConfig);
- switch (set_value) {
- case eHT_CHANNEL_WIDTH_20MHZ:
- smeConfig.csrConfig.channelBondingMode5GHz =
- WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
- break;
- case eHT_CHANNEL_WIDTH_40MHZ:
- if (chwidth)
- smeConfig.csrConfig.channelBondingMode5GHz =
- phddctx->cfg_ini->nChannelBondingMode5GHz;
- else
- return -EINVAL;
-
- break;
-#ifdef WLAN_FEATURE_11AC
- case eHT_CHANNEL_WIDTH_80MHZ:
- if (chwidth)
- smeConfig.csrConfig.channelBondingMode5GHz =
- phddctx->cfg_ini->nChannelBondingMode5GHz;
- else
- return -EINVAL;
-
- break;
-#endif
-
- default:
- return -EINVAL;
- }
-
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_VDEV_PARAM_CHWIDTH,
- set_value, VDEV_CMD);
- if (!ret)
- sme_UpdateConfig(hHal, &smeConfig);
-
- break;
- }
-
- case WE_SET_ANI_EN_DIS:
- {
- hddLog(LOG1, "WMI_PDEV_PARAM_ANI_ENABLE val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_ANI_ENABLE,
- set_value, PDEV_CMD);
- break;
- }
-
- case WE_SET_ANI_POLL_PERIOD:
- {
- hddLog(LOG1, "WMI_PDEV_PARAM_ANI_POLL_PERIOD val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_ANI_POLL_PERIOD,
- set_value, PDEV_CMD);
- break;
- }
-
- case WE_SET_ANI_LISTEN_PERIOD:
- {
- hddLog(LOG1, "WMI_PDEV_PARAM_ANI_LISTEN_PERIOD val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
- set_value, PDEV_CMD);
- break;
- }
-
- case WE_SET_ANI_OFDM_LEVEL:
- {
- hddLog(LOG1, "WMI_PDEV_PARAM_ANI_OFDM_LEVEL val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
- set_value, PDEV_CMD);
- break;
- }
-
- case WE_SET_ANI_CCK_LEVEL:
- {
- hddLog(LOG1, "WMI_PDEV_PARAM_ANI_CCK_LEVEL val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_ANI_CCK_LEVEL,
- set_value, PDEV_CMD);
- break;
- }
-
- case WE_SET_DYNAMIC_BW:
- {
- hddLog(LOG1, "WMI_PDEV_PARAM_DYNAMIC_BW val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_DYNAMIC_BW,
- set_value, PDEV_CMD);
- break;
- }
-
- case WE_SET_11N_RATE:
- {
- u_int8_t preamble, nss, rix;
- hddLog(LOG1, "WMI_VDEV_PARAM_FIXED_RATE val %d", set_value);
-
- rix = RC_2_RATE_IDX(set_value);
- if (set_value & 0x80) {
- preamble = WMI_RATE_PREAMBLE_HT;
- nss = HT_RC_2_STREAMS(set_value) -1;
- } else {
- nss = 0;
- rix = RC_2_RATE_IDX(set_value);
- if (set_value & 0x10) {
- preamble = WMI_RATE_PREAMBLE_CCK;
- rix |= 0x4; /* Enable Short preamble always for CCK */
- } else
- preamble = WMI_RATE_PREAMBLE_OFDM;
- }
-
- hddLog(LOG1, "WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x\
- nss %d", set_value, rix, preamble, nss);
-
- set_value = (preamble << 6) | (nss << 4) | rix;
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_VDEV_PARAM_FIXED_RATE,
- set_value, VDEV_CMD);
- break;
- }
-
- case WE_SET_VHT_RATE:
- {
- u_int8_t preamble, nss, rix;
-
- rix = RC_2_RATE_IDX_11AC(set_value);
- preamble = WMI_RATE_PREAMBLE_VHT;
- nss = HT_RC_2_STREAMS_11AC(set_value) -1;
-
- hddLog(LOG1, "WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x\
- nss %d", set_value, rix, preamble, nss);
-
- set_value = (preamble << 6) | (nss << 4) | rix;
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_VDEV_PARAM_FIXED_RATE,
- set_value, VDEV_CMD);
- break;
- }
-
- case WE_SET_AMPDU:
- {
- hddLog(LOG1, "SET AMPDU val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)GEN_VDEV_PARAM_AMPDU,
- set_value, GEN_CMD);
- break;
- }
-
- case WE_SET_AMSDU:
- {
- hddLog(LOG1, "SET AMSDU val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)GEN_VDEV_PARAM_AMSDU,
- set_value, GEN_CMD);
- break;
- }
-
- case WE_SET_TX_CHAINMASK:
- {
- hddLog(LOG1, "WMI_PDEV_PARAM_TX_CHAIN_MASK val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_TX_CHAIN_MASK,
- set_value, PDEV_CMD);
- break;
- }
-
- case WE_SET_RX_CHAINMASK:
- {
- hddLog(LOG1, "WMI_PDEV_PARAM_RX_CHAIN_MASK val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_RX_CHAIN_MASK,
- set_value, PDEV_CMD);
- break;
- }
-
- case WE_SET_TXPOW_2G:
- {
- hddLog(LOG1, "WMI_PDEV_PARAM_TXPOWER_LIMIT2G val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
- set_value, PDEV_CMD);
- break;
- }
-
- case WE_SET_TXPOW_5G:
- {
- hddLog(LOG1, "WMI_PDEV_PARAM_TXPOWER_LIMIT5G val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
- set_value, PDEV_CMD);
- break;
- }
-
- case WE_SET_POWER_GATING:
- {
- hddLog(LOG1, "WMI_PDEV_PARAM_POWER_GATING_SLEEP val %d",
- set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_POWER_GATING_SLEEP,
- (set_value)? true:false, PDEV_CMD);
- break;
- }
-
- /* Firmware debug log */
- case WE_DBGLOG_LOG_LEVEL:
- {
- hddLog(LOG1, "WE_DBGLOG_LOG_LEVEL val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_DBGLOG_LOG_LEVEL,
- set_value, DBG_CMD);
- break;
- }
-
- case WE_DBGLOG_VAP_ENABLE:
- {
- hddLog(LOG1, "WE_DBGLOG_VAP_ENABLE val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_DBGLOG_VAP_ENABLE,
- set_value, DBG_CMD);
- break;
- }
-
- case WE_DBGLOG_VAP_DISABLE:
- {
- hddLog(LOG1, "WE_DBGLOG_VAP_DISABLE val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_DBGLOG_VAP_DISABLE,
- set_value, DBG_CMD);
- break;
- }
-
- case WE_DBGLOG_MODULE_ENABLE:
- {
- hddLog(LOG1, "WE_DBGLOG_MODULE_ENABLE val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_DBGLOG_MODULE_ENABLE,
- set_value, DBG_CMD);
- break;
- }
-
- case WE_DBGLOG_MODULE_DISABLE:
- {
- hddLog(LOG1, "WE_DBGLOG_MODULE_DISABLE val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_DBGLOG_MODULE_DISABLE,
- set_value, DBG_CMD);
- break;
- }
-
- case WE_DBGLOG_MOD_LOG_LEVEL:
- {
- hddLog(LOG1, "WE_DBGLOG_MOD_LOG_LEVEL val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_DBGLOG_MOD_LOG_LEVEL,
- set_value, DBG_CMD);
- break;
- }
-
- case WE_DBGLOG_TYPE:
- {
- hddLog(LOG1, "WE_DBGLOG_TYPE val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_DBGLOG_TYPE,
- set_value, DBG_CMD);
- break;
- }
- case WE_DBGLOG_REPORT_ENABLE:
- {
- hddLog(LOG1, "WE_DBGLOG_REPORT_ENABLE val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_DBGLOG_REPORT_ENABLE,
- set_value, DBG_CMD);
- break;
- }
-
- case WE_SET_TXRX_FWSTATS:
- {
- hddLog(LOG1, "WE_SET_TXRX_FWSTATS val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID,
- set_value, VDEV_CMD);
- break;
- }
-
- case WE_TXRX_FWSTATS_RESET:
- {
- hddLog(LOG1, "WE_TXRX_FWSTATS_RESET val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMA_VDEV_TXRX_FWSTATS_RESET_CMDID,
- set_value, VDEV_CMD);
- break;
- }
-
- case WE_PPS_PAID_MATCH:
- {
- if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
- return EINVAL;
-
- hddLog(LOG1, "WMI_VDEV_PPS_PAID_MATCH val %d ", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_PAID_MATCH,
- set_value, VDEV_CMD);
- break;
- }
-
- case WE_PPS_GID_MATCH:
- {
- if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
- return EINVAL;
- hddLog(LOG1, "WMI_VDEV_PPS_GID_MATCH val %d ", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_GID_MATCH,
- set_value, VDEV_CMD);
- break;
- }
-
- case WE_PPS_EARLY_TIM_CLEAR:
- {
- if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
- return EINVAL;
- hddLog(LOG1, " WMI_VDEV_PPS_EARLY_TIM_CLEAR val %d ", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_EARLY_TIM_CLEAR,
- set_value, VDEV_CMD);
- break;
- }
-
- case WE_PPS_EARLY_DTIM_CLEAR:
- {
- if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
- return EINVAL;
- hddLog(LOG1, "WMI_VDEV_PPS_EARLY_DTIM_CLEAR val %d", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
- set_value, VDEV_CMD);
- break;
- }
-
- case WE_PPS_EOF_PAD_DELIM:
- {
- if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
- return EINVAL;
- hddLog(LOG1, "WMI_VDEV_PPS_EOF_PAD_DELIM val %d ", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_EOF_PAD_DELIM,
- set_value, VDEV_CMD);
- break;
- }
-
- case WE_PPS_MACADDR_MISMATCH:
- {
- if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
- return EINVAL;
- hddLog(LOG1, "WMI_VDEV_PPS_MACADDR_MISMATCH val %d ", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_MACADDR_MISMATCH,
- set_value, VDEV_CMD);
- break;
- }
-
- case WE_PPS_DELIM_CRC_FAIL:
- {
- if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
- return EINVAL;
- hddLog(LOG1, "WMI_VDEV_PPS_DELIM_CRC_FAIL val %d ", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_DELIM_CRC_FAIL,
- set_value, VDEV_CMD);
- break;
- }
-
-
- case WE_PPS_GID_NSTS_ZERO:
- {
- if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
- return EINVAL;
- hddLog(LOG1, "WMI_VDEV_PPS_GID_NSTS_ZERO val %d ", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_GID_NSTS_ZERO,
- set_value, VDEV_CMD);
- break;
- }
-
-
- case WE_PPS_RSSI_CHECK:
- {
- if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
- return EINVAL;
- hddLog(LOG1, "WMI_VDEV_PPS_RSSI_CHECK val %d ", set_value);
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_RSSI_CHECK,
- set_value, VDEV_CMD);
- break;
- }
-
-#endif
- default:
- {
- hddLog(LOGE, "%s: Invalid sub command %d", __func__, sub_cmd);
- ret = -EINVAL;
- break;
- }
- }
- return ret;
-}
-
-/* set param sub-ioctls */
-static int iw_setchar_getnone(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- VOS_STATUS vstatus;
- int sub_cmd = wrqu->data.flags;
- int ret = 0; /* success */
- hdd_adapter_t *pAdapter = (netdev_priv(dev));
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
-#ifdef WLAN_FEATURE_VOWIFI
- hdd_config_t *pConfig = pHddCtx->cfg_ini;
-#endif /* WLAN_FEATURE_VOWIFI */
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Received length %d", __func__, wrqu->data.length);
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Received data %s", __func__, extra);
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- switch(sub_cmd)
- {
- case WE_WOWL_ADD_PTRN:
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "ADD_PTRN\n");
- hdd_add_wowl_ptrn(pAdapter, extra);
- break;
- case WE_WOWL_DEL_PTRN:
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "DEL_PTRN\n");
- hdd_del_wowl_ptrn(pAdapter, extra);
- break;
-#if defined WLAN_FEATURE_VOWIFI
- case WE_NEIGHBOR_REPORT_REQUEST:
- {
- tRrmNeighborReq neighborReq;
- tRrmNeighborRspCallbackInfo callbackInfo;
-
- if (pConfig->fRrmEnable)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Neighbor Request\n");
- neighborReq.no_ssid = (wrqu->data.length - 1) ? false : true ;
- if( !neighborReq.no_ssid )
- {
- neighborReq.ssid.length = (wrqu->data.length - 1) > 32 ? 32 : (wrqu->data.length - 1) ;
- vos_mem_copy( neighborReq.ssid.ssId, extra, neighborReq.ssid.length );
- }
-
- callbackInfo.neighborRspCallback = NULL;
- callbackInfo.neighborRspCallbackContext = NULL;
- callbackInfo.timeout = 5000; //5 seconds
- sme_NeighborReportRequest( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, &neighborReq, &callbackInfo );
- }
- else
- {
- hddLog(LOGE, "%s: Ignoring neighbor request as RRM is not enabled\n", __func__);
- ret = -EINVAL;
- }
- }
- break;
-#endif
- case WE_SET_AP_WPS_IE:
- hddLog( LOGE, "Received WE_SET_AP_WPS_IE" );
- sme_updateP2pIe( WLAN_HDD_GET_HAL_CTX(pAdapter), extra, wrqu->data.length );
- break;
- case WE_SET_CONFIG:
- vstatus = hdd_execute_config_command(pHddCtx, extra);
- if (VOS_STATUS_SUCCESS != vstatus)
- {
- ret = -EINVAL;
- }
- break;
- default:
- {
- hddLog(LOGE, "%s: Invalid sub command %d", __func__, sub_cmd);
- ret = -EINVAL;
- break;
- }
- }
- return ret;
-}
-
-/* get param sub-ioctls */
-static int iw_setnone_getint(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- int *value = (int *)extra;
- int ret = 0; /* success */
-#ifdef QCA_WIFI_2_0
- hdd_context_t *wmahddCtxt = WLAN_HDD_GET_CTX(pAdapter);
- void *wmapvosContext = wmahddCtxt->pvosContext;
-#endif
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- switch (value[0])
- {
- case WE_GET_11D_STATE:
- {
- tSmeConfigParams smeConfig;
- sme_GetConfigParam(hHal,&smeConfig);
-
- *value = smeConfig.csrConfig.Is11dSupportEnabled;
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("11D state=%ld!!\n"),*value);
-
- break;
- }
-
- case WE_IBSS_STATUS:
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "****Return IBSS Status*****\n");
- break;
-
- case WE_PMC_STATE:
- {
- *value = pmcGetPmcState(hHal);
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("PMC state=%ld!!\n"),*value);
- break;
- }
- case WE_GET_WLAN_DBG:
- {
- vos_trace_display();
- *value = 0;
- break;
- }
- case WE_MODULE_DOWN_IND:
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: sending WLAN_MODULE_DOWN_IND", __func__);
- send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
-#ifdef WLAN_BTAMP_FEATURE
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: Take down AMP PAL", __func__);
- BSL_Deinit(vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
-#endif
- //WLANBAP_Close(vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
-
- *value = 0;
- break;
- }
- case WE_GET_MAX_ASSOC:
- {
- if (ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value) != eHAL_STATUS_SUCCESS)
- {
- ret = -EIO;
- }
- break;
- }
-
- case WE_GET_WDI_DBG:
- {
- wpalTraceDisplay();
- *value = 0;
- break;
- }
-
- case WE_GET_SAP_AUTO_CHANNEL_SELECTION:
- {
- *value = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->apAutoChannelSelection;
- break;
- }
- case WE_GET_CONCURRENCY_MODE:
- {
- *value = hdd_get_concurrency_mode ( );
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("concurrency mode=%d \n"),*value);
- break;
- }
-
-#ifdef QCA_WIFI_2_0
- case WE_GET_NSS:
- {
- hddLog(LOG1, "GET WMI_VDEV_PARAM_NSS");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PARAM_NSS,
- VDEV_CMD);
- break;
- }
-
- case WE_GET_LDPC:
- {
- hddLog(LOG1, "GET WMI_VDEV_PARAM_LDPC");
- *value = sme_GetHTConfig(hHal, pAdapter->sessionId,
- WNI_CFG_HT_CAP_INFO_ADVANCE_CODING);
- break;
- }
-
- case WE_GET_TX_STBC:
- {
- hddLog(LOG1, "GET WMI_VDEV_PARAM_TX_STBC");
- *value = sme_GetHTConfig(hHal, pAdapter->sessionId,
- WNI_CFG_HT_CAP_INFO_TX_STBC);
- break;
- }
-
- case WE_GET_RX_STBC:
- {
- hddLog(LOG1, "GET WMI_VDEV_PARAM_RX_STBC");
- *value = sme_GetHTConfig(hHal, pAdapter->sessionId,
- WNI_CFG_HT_CAP_INFO_RX_STBC);
- break;
- }
-
- case WE_GET_SHORT_GI:
- {
- hddLog(LOG1, "GET WMI_VDEV_PARAM_SGI");
- *value = sme_GetHTConfig(hHal, pAdapter->sessionId,
- WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ);
- break;
- }
-
- case WE_GET_RTSCTS:
- {
- hddLog(LOG1, "GET WMI_VDEV_PARAM_ENABLE_RTSCTS");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PARAM_ENABLE_RTSCTS,
- VDEV_CMD);
- break;
- }
-
- case WE_GET_CHWIDTH:
- {
- hddLog(LOG1, "GET WMI_VDEV_PARAM_CHWIDTH");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PARAM_CHWIDTH,
- VDEV_CMD);
- break;
- }
-
- case WE_GET_ANI_EN_DIS:
- {
- hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_ENABLE");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_ANI_ENABLE,
- PDEV_CMD);
- break;
- }
-
- case WE_GET_ANI_POLL_PERIOD:
- {
- hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_POLL_PERIOD");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_ANI_POLL_PERIOD,
- PDEV_CMD);
- break;
- }
-
- case WE_GET_ANI_LISTEN_PERIOD:
- {
- hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_LISTEN_PERIOD");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
- PDEV_CMD);
- break;
- }
-
- case WE_GET_ANI_OFDM_LEVEL:
- {
- hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_OFDM_LEVEL");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
- PDEV_CMD);
- break;
- }
-
- case WE_GET_ANI_CCK_LEVEL:
- {
- hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_CCK_LEVEL");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_ANI_CCK_LEVEL,
- PDEV_CMD);
- break;
- }
-
- case WE_GET_DYNAMIC_BW:
- {
- hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_CCK_LEVEL");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_DYNAMIC_BW,
- PDEV_CMD);
- break;
- }
-
- case WE_GET_11N_RATE:
- {
- hddLog(LOG1, "GET WMI_VDEV_PARAM_FIXED_RATE");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PARAM_FIXED_RATE,
- VDEV_CMD);
- break;
- }
-
- case WE_GET_AMPDU:
- {
- hddLog(LOG1, "GET AMPDU");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)GEN_VDEV_PARAM_AMPDU,
- GEN_CMD);
- break;
- }
-
- case WE_GET_AMSDU:
- {
- hddLog(LOG1, "GET AMSDU");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)GEN_VDEV_PARAM_AMSDU,
- GEN_CMD);
- break;
- }
-
- case WE_GET_TX_CHAINMASK:
- {
- hddLog(LOG1, "GET WMI_PDEV_PARAM_TX_CHAIN_MASK");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_TX_CHAIN_MASK,
- PDEV_CMD);
- break;
- }
-
- case WE_GET_RX_CHAINMASK:
- {
- hddLog(LOG1, "GET WMI_PDEV_PARAM_RX_CHAIN_MASK");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_RX_CHAIN_MASK,
- PDEV_CMD);
- break;
- }
-
- case WE_GET_TXPOW_2G:
- {
- tANI_U32 txpow2g = 0;
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- hddLog(LOG1, "GET WMI_PDEV_PARAM_TXPOWER_LIMIT2G");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
- PDEV_CMD);
- if ( eHAL_STATUS_SUCCESS != ccmCfgGetInt(hHal,
- WNI_CFG_CURRENT_TX_POWER_LEVEL, &txpow2g) )
- {
- return -EIO;
- }
- hddLog(LOG1, "2G tx_power %d", txpow2g);
- break;
- }
-
- case WE_GET_TXPOW_5G:
- {
- tANI_U32 txpow5g = 0;
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- hddLog(LOG1, "GET WMI_PDEV_PARAM_TXPOWER_LIMIT5G");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
- PDEV_CMD);
- if ( eHAL_STATUS_SUCCESS != ccmCfgGetInt(hHal,
- WNI_CFG_CURRENT_TX_POWER_LEVEL, &txpow5g) )
- {
- return -EIO;
- }
- hddLog(LOG1, "5G tx_power %d", txpow5g);
- break;
- }
-
- case WE_GET_POWER_GATING:
- {
- hddLog(LOG1, "GET WMI_PDEV_PARAM_POWER_GATING_SLEEP");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_PDEV_PARAM_POWER_GATING_SLEEP,
- PDEV_CMD);
- break;
- }
-
-#endif
-
- default:
- {
- hddLog(LOGE, "Invalid IOCTL get_value command %d", value[0]);
- break;
- }
- }
-
- return ret;
-}
-
-/* set param sub-ioctls */
-int iw_set_three_ints_getnone(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- int *value = (int *)extra;
- int sub_cmd = value[0];
- int ret = 0;
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- switch(sub_cmd)
- {
- case WE_SET_WLAN_DBG:
- {
- vos_trace_setValue( value[1], value[2], value[3]);
- break;
- }
- case WE_SET_WDI_DBG:
- {
- wpalTraceSetLevel( value[1], value[2], value[3]);
- break;
- }
- case WE_SET_SAP_CHANNELS:
- {
- ret = iw_softap_set_channel_range( dev, value[1], value[2], value[3]);
- break;
- }
-
-
- default:
- {
- hddLog(LOGE, "Invalid IOCTL command %d", sub_cmd);
- break;
- }
- }
- return ret;
-}
-
-static int iw_get_char_setnone(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- int sub_cmd = wrqu->data.flags;
-#ifdef WLAN_FEATURE_11W
- hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
-#endif
-
- if (NULL == WLAN_HDD_GET_CTX(pAdapter))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "%s: HDD Context is NULL!", __func__);
-
- return -EINVAL;
- }
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- switch(sub_cmd)
- {
- case WE_WLAN_VERSION:
- {
- hdd_wlan_get_version(pAdapter, wrqu, extra);
- break;
- }
-
- case WE_GET_STATS:
- {
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- hdd_tx_rx_stats_t *pStats = &pAdapter->hdd_stats.hddTxRxStats;
- hdd_chip_reset_stats_t *pResetStats = &pHddCtx->hddChipResetStats;
-
- snprintf(extra, WE_MAX_STR_LEN,
- "\nTransmit"
- "\ncalled %u, dropped %u, backpressured %u, queued %u"
- "\n dropped BK %u, BE %u, VI %u, VO %u"
- "\n classified BK %u, BE %u, VI %u, VO %u"
- "\nbackpressured BK %u, BE %u, VI %u, VO %u"
- "\n queued BK %u, BE %u, VI %u, VO %u"
- "\nfetched %u, empty %u, lowres %u, deqerr %u"
- "\ndequeued %u, depressured %u, completed %u, flushed %u"
- "\n fetched BK %u, BE %u, VI %u, VO %u"
- "\n dequeued BK %u, BE %u, VI %u, VO %u"
- "\n depressured BK %u, BE %u, VI %u, VO %u"
- "\n flushed BK %u, BE %u, VI %u, VO %u"
- "\n\nReceive"
- "\nchains %u, packets %u, dropped %u, delivered %u, refused %u"
- "\n\nResetsStats"
- "\n TotalLogp %u Cmd53 %u MutexRead %u MIF-Error %u FW-Heartbeat %u Others %u"
- "\n",
- pStats->txXmitCalled,
- pStats->txXmitDropped,
- pStats->txXmitBackPressured,
- pStats->txXmitQueued,
-
- pStats->txXmitDroppedAC[WLANTL_AC_BK],
- pStats->txXmitDroppedAC[WLANTL_AC_BE],
- pStats->txXmitDroppedAC[WLANTL_AC_VI],
- pStats->txXmitDroppedAC[WLANTL_AC_VO],
-
- pStats->txXmitClassifiedAC[WLANTL_AC_BK],
- pStats->txXmitClassifiedAC[WLANTL_AC_BE],
- pStats->txXmitClassifiedAC[WLANTL_AC_VI],
- pStats->txXmitClassifiedAC[WLANTL_AC_VO],
-
- pStats->txXmitBackPressuredAC[WLANTL_AC_BK],
- pStats->txXmitBackPressuredAC[WLANTL_AC_BE],
- pStats->txXmitBackPressuredAC[WLANTL_AC_VI],
- pStats->txXmitBackPressuredAC[WLANTL_AC_VO],
-
- pStats->txXmitQueuedAC[WLANTL_AC_BK],
- pStats->txXmitQueuedAC[WLANTL_AC_BE],
- pStats->txXmitQueuedAC[WLANTL_AC_VI],
- pStats->txXmitQueuedAC[WLANTL_AC_VO],
-
- pStats->txFetched,
- pStats->txFetchEmpty,
- pStats->txFetchLowResources,
- pStats->txFetchDequeueError,
-
- pStats->txFetchDequeued,
- pStats->txFetchDePressured,
- pStats->txCompleted,
- pStats->txFlushed,
-
- pStats->txFetchedAC[WLANTL_AC_BK],
- pStats->txFetchedAC[WLANTL_AC_BE],
- pStats->txFetchedAC[WLANTL_AC_VI],
- pStats->txFetchedAC[WLANTL_AC_VO],
-
- pStats->txFetchDequeuedAC[WLANTL_AC_BK],
- pStats->txFetchDequeuedAC[WLANTL_AC_BE],
- pStats->txFetchDequeuedAC[WLANTL_AC_VI],
- pStats->txFetchDequeuedAC[WLANTL_AC_VO],
-
- pStats->txFetchDePressuredAC[WLANTL_AC_BK],
- pStats->txFetchDePressuredAC[WLANTL_AC_BE],
- pStats->txFetchDePressuredAC[WLANTL_AC_VI],
- pStats->txFetchDePressuredAC[WLANTL_AC_VO],
-
- pStats->txFlushedAC[WLANTL_AC_BK],
- pStats->txFlushedAC[WLANTL_AC_BE],
- pStats->txFlushedAC[WLANTL_AC_VI],
- pStats->txFlushedAC[WLANTL_AC_VO],
-
- pStats->rxChains,
- pStats->rxPackets,
- pStats->rxDropped,
- pStats->rxDelivered,
- pStats->rxRefused,
-
- pResetStats->totalLogpResets,
- pResetStats->totalCMD53Failures,
- pResetStats->totalMutexReadFailures,
- pResetStats->totalMIFErrorFailures,
- pResetStats->totalFWHearbeatFailures,
- pResetStats->totalUnknownExceptions
- );
- wrqu->data.length = strlen(extra)+1;
- break;
- }
-
-/* The case prints the current state of the HDD, SME, CSR, PE, TL
- *it can be extended for WDI Global State as well.
- *And currently it only checks P2P_CLIENT adapter.
- *P2P_DEVICE and P2P_GO have not been added as of now.
-*/
- case WE_GET_STATES:
- {
- int buf = 0, len = 0;
- int adapter_num = 0;
- int count = 0, check = 1;
-
- tANI_U16 tlState;
- tHalHandle hHal;
- tpAniSirGlobal pMac;
- hdd_station_ctx_t *pHddStaCtx;
-
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
- hdd_adapter_t *useAdapter = NULL;
-
- /* Print wlan0 or p2p0 states based on the adapter_num
- *by using the correct adapter
- */
- while ( adapter_num < 2 )
- {
- if ( WLAN_ADAPTER == adapter_num )
- {
- useAdapter = pAdapter;
- buf = scnprintf(extra + len, WE_MAX_STR_LEN - len,
- "\n\n wlan0 States:-");
- len += buf;
- }
- else if ( P2P_ADAPTER == adapter_num )
- {
- buf = scnprintf(extra + len, WE_MAX_STR_LEN - len,
- "\n\n p2p0 States:-");
- len += buf;
-
- if( !pHddCtx )
- {
- buf = scnprintf(extra + len, WE_MAX_STR_LEN - len,
- "\n pHddCtx is NULL");
- len += buf;
- break;
- }
-
- /*Printing p2p0 states only in the case when the device is
- configured as a p2p_client*/
- useAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
- if ( !useAdapter )
- {
- buf = scnprintf(extra + len, WE_MAX_STR_LEN - len,
- "\n Device not configured as P2P_CLIENT.");
- len += buf;
- break;
- }
- }
-
- hHal = WLAN_HDD_GET_HAL_CTX( useAdapter );
- pMac = PMAC_STRUCT( hHal );
- pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR( useAdapter );
- if( !pHddStaCtx )
- {
- buf = scnprintf(extra + len, WE_MAX_STR_LEN - len,
- "\n pHddStaCtx is NULL");
- len += buf;
- break;
- }
-
- tlState = smeGetTLSTAState(hHal, pHddStaCtx->conn_info.staId[0]);
-
- buf = scnprintf(extra + len, WE_MAX_STR_LEN - len,
- "\n HDD Conn State - %s "
- "\n \n SME State:"
- "\n Neighbour Roam State - %s"
- "\n CSR State - %s"
- "\n CSR Substate - %s"
- "\n \n TL STA %d State: %s",
- macTraceGetHDDWlanConnState(
- pHddStaCtx->conn_info.connState),
- macTraceGetNeighbourRoamState(
- pMac->roam.neighborRoamInfo.neighborRoamState),
- macTraceGetcsrRoamState(
- pMac->roam.curState[useAdapter->sessionId]),
- macTraceGetcsrRoamSubState(
- pMac->roam.curSubState[useAdapter->sessionId]),
- pHddStaCtx->conn_info.staId[0],
- macTraceGetTLState(tlState)
- );
- len += buf;
- adapter_num++;
- }
-
- /* Printing Lim State starting with global lim states */
- buf = scnprintf(extra + len, WE_MAX_STR_LEN - len,
- "\n \n LIM STATES:-"
- "\n Global Sme State - %s "\
- "\n Global mlm State - %s "\
- "\n",
- macTraceGetLimSmeState(pMac->lim.gLimSmeState),
- macTraceGetLimMlmState(pMac->lim.gLimMlmState)
- );
- len += buf;
-
- /*printing the PE Sme and Mlm states for valid lim sessions*/
- while ( check < 3 && count < 255)
- {
- if ( pMac->lim.gpSession[count].valid )
- {
- buf = scnprintf(extra + len, WE_MAX_STR_LEN - len,
- "\n Lim Valid Session %d:-"
- "\n PE Sme State - %s "
- "\n PE Mlm State - %s "
- "\n",
- check,
- macTraceGetLimSmeState(pMac->lim.gpSession[count].limSmeState),
- macTraceGetLimMlmState(pMac->lim.gpSession[count].limMlmState)
- );
-
- len += buf;
- check++;
- }
- count++;
- }
-
- wrqu->data.length = strlen(extra)+1;
- break;
- }
-
- case WE_GET_CFG:
- {
- hdd_cfg_get_config(WLAN_HDD_GET_CTX(pAdapter), extra, WE_MAX_STR_LEN);
- wrqu->data.length = strlen(extra)+1;
- break;
- }
-#ifdef WLAN_FEATURE_11AC
- case WE_GET_RSSI:
- {
- v_S7_t s7Rssi = 0;
- wlan_hdd_get_rssi(pAdapter, &s7Rssi);
- snprintf(extra, WE_MAX_STR_LEN, "rssi=%d",s7Rssi);
- wrqu->data.length = strlen(extra)+1;
- break;
- }
-#endif
-
-#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_CCX || defined(FEATURE_WLAN_LFR)
- case WE_GET_ROAM_RSSI:
- {
- v_S7_t s7Rssi = 0;
- wlan_hdd_get_roam_rssi(pAdapter, &s7Rssi);
- snprintf(extra, WE_MAX_STR_LEN, "rssi=%d", s7Rssi);
- wrqu->data.length = strlen(extra)+1;
- break;
- }
-#endif
- case WE_GET_WMM_STATUS:
- {
- snprintf(extra, WE_MAX_STR_LEN,
- "\nDir: 0=up, 1=down, 3=both\n"
- "|------------------------|\n"
- "|AC | ACM |Admitted| Dir |\n"
- "|------------------------|\n"
- "|VO | %d | %3s | %d |\n"
- "|VI | %d | %3s | %d |\n"
- "|BE | %d | %3s | %d |\n"
- "|BK | %d | %3s | %d |\n"
- "|------------------------|\n",
- pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VO].wmmAcAccessRequired,
- pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VO].wmmAcAccessAllowed?"YES":"NO",
- pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VO].wmmAcTspecInfo.ts_info.direction,
- pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VI].wmmAcAccessRequired,
- pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VI].wmmAcAccessAllowed?"YES":"NO",
- pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VI].wmmAcTspecInfo.ts_info.direction,
- pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BE].wmmAcAccessRequired,
- pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BE].wmmAcAccessAllowed?"YES":"NO",
- pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BE].wmmAcTspecInfo.ts_info.direction,
- pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BK].wmmAcAccessRequired,
- pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BK].wmmAcAccessAllowed?"YES":"NO",
- pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BK].wmmAcTspecInfo.ts_info.direction);
-
-
- wrqu->data.length = strlen(extra)+1;
- break;
- }
- case WE_GET_CHANNEL_LIST:
- {
- VOS_STATUS status;
- v_U8_t i, len;
- char* buf ;
-
- tChannelListInfo channel_list;
-
- status = iw_softap_get_channel_list(dev, info, wrqu, (char *)&channel_list);
- if ( !VOS_IS_STATUS_SUCCESS( status ) )
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, "%s GetChannelList Failed!!!\n",__func__);
- return -EINVAL;
- }
- buf = extra;
-
- /**
- * Maximum channels = WNI_CFG_VALID_CHANNEL_LIST_LEN. Maximum buffer
- * needed = 5 * number of channels. Check ifsufficient
- * buffer is available and then proceed to fill the buffer.
- */
- if(WE_MAX_STR_LEN < (5 * WNI_CFG_VALID_CHANNEL_LIST_LEN))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s Insufficient Buffer to populate channel list\n",
- __func__);
- return -EINVAL;
- }
- len = scnprintf(buf, WE_MAX_STR_LEN, "%u ",
- channel_list.num_channels);
- for(i = 0 ; i < channel_list.num_channels; i++)
- {
- len += scnprintf(buf + len, WE_MAX_STR_LEN - len,
- "%u ", channel_list.channels[i]);
- }
- wrqu->data.length = strlen(extra)+1;
-
- break;
- }
-#ifdef FEATURE_WLAN_TDLS
- case WE_GET_TDLS_PEERS:
- {
- wrqu->data.length = wlan_hdd_tdls_get_all_peers(pAdapter, extra, WE_MAX_STR_LEN)+1;
- break;
- }
-#endif
-#ifdef WLAN_FEATURE_11W
- case WE_GET_11W_INFO:
- {
- hddLog(LOGE, "WE_GET_11W_ENABLED = %d", pWextState->roamProfile.MFPEnabled );
-
- snprintf(extra, WE_MAX_STR_LEN,
- "\n BSSID %02X:%02X:%02X:%02X:%02X:%02X, Is PMF Assoc? %d"
- "\n Number of Unprotected Disassocs %d"
- "\n Number of Unprotected Deauths %d",
- (*pWextState->roamProfile.BSSIDs.bssid)[0], (*pWextState->roamProfile.BSSIDs.bssid)[1],
- (*pWextState->roamProfile.BSSIDs.bssid)[2], (*pWextState->roamProfile.BSSIDs.bssid)[3],
- (*pWextState->roamProfile.BSSIDs.bssid)[4], (*pWextState->roamProfile.BSSIDs.bssid)[5],
- pWextState->roamProfile.MFPEnabled, pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx,
- pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx);
-
- wrqu->data.length = strlen(extra)+1;
- break;
- }
-#endif
-#ifdef FEATURE_CESIUM_PROPRIETARY
- case WE_GET_IBSS_STA_INFO:
- {
- hdd_station_ctx_t *pHddStaCtx =
- WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- int idx = 0;
- int length = 0, buf = 0;
-
- for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++)
- {
- if (0 != pHddStaCtx->conn_info.staId[ idx ])
- {
- buf = snprintf
- (
- (extra + length), WE_MAX_STR_LEN - length,
- "\n%d .%02x:%02x:%02x:%02x:%02x:%02x\n",
- pHddStaCtx->conn_info.staId[ idx ],
- pHddStaCtx->conn_info.peerMacAddress[idx].bytes[0],
- pHddStaCtx->conn_info.peerMacAddress[idx].bytes[1],
- pHddStaCtx->conn_info.peerMacAddress[idx].bytes[2],
- pHddStaCtx->conn_info.peerMacAddress[idx].bytes[3],
- pHddStaCtx->conn_info.peerMacAddress[idx].bytes[4],
- pHddStaCtx->conn_info.peerMacAddress[idx].bytes[5]
- );
- length += buf;
- }
- }
- wrqu->data.length = strlen(extra)+1;
- break;
- }
-#endif
-#ifdef QCA_WIFI_2_0
- case WE_GET_PHYMODE:
- {
- v_BOOL_t ch_bond24 = VOS_FALSE, ch_bond5g = VOS_FALSE;
- hdd_context_t *hddctx = WLAN_HDD_GET_CTX(pAdapter);
- tHalHandle hal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- eCsrPhyMode phymode;
- eCsrBand currBand;
- tSmeConfigParams smeconfig;
-
- sme_GetConfigParam(hal, &smeconfig);
- if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
- smeconfig.csrConfig.channelBondingMode24GHz)
- ch_bond24 = VOS_TRUE;
-
- if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
- smeconfig.csrConfig.channelBondingMode5GHz)
- ch_bond5g = VOS_TRUE;
-
- phymode = sme_GetPhyMode(hal);
- if ((eHAL_STATUS_SUCCESS != sme_GetFreqBand(hal, &currBand))) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "%s: Failed to get current band config",
- __func__);
- return -EIO;
- }
-
-
- switch (phymode) {
- case eCSR_DOT11_MODE_AUTO:
- snprintf(extra, WE_MAX_STR_LEN, "AUTO MODE");
- break;
- case eCSR_DOT11_MODE_TAURUS:
- case eCSR_DOT11_MODE_POLARIS:
- case eCSR_DOT11_MODE_TAURUS_ONLY:
- case eCSR_DOT11_MODE_TITAN:
- case eCSR_DOT11_MODE_11n:
- case eCSR_DOT11_MODE_11n_ONLY:
- if (currBand == eCSR_BAND_24) {
- if (ch_bond24)
- snprintf(extra, WE_MAX_STR_LEN, "11NGHT40");
- else
- snprintf(extra, WE_MAX_STR_LEN, "11NGHT20");
- }
- else if(currBand == eCSR_BAND_5G) {
- if (ch_bond5g)
- snprintf(extra, WE_MAX_STR_LEN, "11NAHT40");
- else
- snprintf(extra, WE_MAX_STR_LEN, "11NAHT20");
- } else {
- snprintf(extra, WE_MAX_STR_LEN, "11N");
- }
- break;
- case eCSR_DOT11_MODE_abg:
- snprintf(extra, WE_MAX_STR_LEN, "11ABG");
- break;
- case eCSR_DOT11_MODE_11a:
- case eCSR_DOT11_MODE_11a_ONLY:
- snprintf(extra, WE_MAX_STR_LEN, "11A");
- break;
- case eCSR_DOT11_MODE_11b:
- case eCSR_DOT11_MODE_11b_ONLY:
- snprintf(extra, WE_MAX_STR_LEN, "11B");
- break;
- case eCSR_DOT11_MODE_11g:
- case eCSR_DOT11_MODE_11g_ONLY:
- snprintf(extra, WE_MAX_STR_LEN, "11G");
- break;
-#ifdef WLAN_FEATURE_11AC
- case eCSR_DOT11_MODE_11ac:
- case eCSR_DOT11_MODE_11ac_ONLY:
- if (hddctx->cfg_ini->vhtChannelWidth ==
- eHT_CHANNEL_WIDTH_20MHZ)
- snprintf(extra, WE_MAX_STR_LEN, "11ACVHT20");
- else if (hddctx->cfg_ini->vhtChannelWidth ==
- eHT_CHANNEL_WIDTH_40MHZ)
- snprintf(extra, WE_MAX_STR_LEN, "11ACVHT40");
- else if (hddctx->cfg_ini->vhtChannelWidth ==
- eHT_CHANNEL_WIDTH_80MHZ)
- snprintf(extra, WE_MAX_STR_LEN, "11ACVHT80");
- else if (hddctx->cfg_ini->vhtChannelWidth ==
- eHT_CHANNEL_WIDTH_160MHZ)
- snprintf(extra, WE_MAX_STR_LEN, "11ACVHT160");
- break;
-#endif
- }
-
- wrqu->data.length = strlen(extra)+1;
- break;
- }
-#endif
- default:
- {
- hddLog(LOGE, "Invalid IOCTL command %d", sub_cmd);
- break;
- }
- }
-
- return 0;
-}
-
-/* action sub-ioctls */
-static int iw_setnone_getnone(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- int sub_cmd = wrqu->data.flags;
- int ret = 0; /* success */
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- switch (sub_cmd)
- {
- case WE_CLEAR_STATS:
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: clearing", __func__);
- memset(&pAdapter->stats, 0, sizeof(pAdapter->stats));
- memset(&pAdapter->hdd_stats, 0, sizeof(pAdapter->hdd_stats));
- break;
- }
- case WE_INIT_AP:
- {
- pr_info("Init AP trigger\n");
- hdd_open_adapter( WLAN_HDD_GET_CTX(pAdapter), WLAN_HDD_SOFTAP, "softap.%d",
- wlan_hdd_get_intf_addr( WLAN_HDD_GET_CTX(pAdapter) ),TRUE);
- break;
- }
-#ifdef FEATURE_CESIUM_PROPRIETARY
- case WE_IBSS_GET_PEER_INFO_ALL:
- {
- hdd_wlan_get_ibss_peer_info_all(pAdapter);
- break;
- }
-#endif
- case WE_STOP_AP:
- {
- /*FIX ME: Need to be revisited if multiple SAPs to be supported */
- /* As Soft AP mode has been changed to STA already with killing of Hostapd,
- * this is a dead code and need to find the adpater by name rather than mode */
- hdd_adapter_t* pAdapter_to_stop =
- hdd_get_adapter_by_name(WLAN_HDD_GET_CTX(pAdapter), "softap.0");
- if( pAdapter_to_stop )
- {
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
-
- pr_info("Stopping AP mode\n");
-
- if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
- {
- /* EXIT BMPS as fw cannot handle DEL_STA when its in BMPS */
- wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
- }
-
- /*Make sure that pAdapter cleaned properly*/
- hdd_stop_adapter( pHddCtx, pAdapter_to_stop );
- hdd_deinit_adapter( pHddCtx, pAdapter_to_stop );
- memset(&pAdapter_to_stop->sessionCtx, 0, sizeof(pAdapter_to_stop->sessionCtx));
-
- wlan_hdd_release_intf_addr(WLAN_HDD_GET_CTX(pAdapter),
- pAdapter_to_stop->macAddressCurrent.bytes);
- hdd_close_adapter(WLAN_HDD_GET_CTX(pAdapter), pAdapter_to_stop,
- TRUE);
-
- if (FALSE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
- {
- /* put the device back into BMPS */
- wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
- }
- }
- else
- {
- printk(KERN_ERR"SAP adapter not found to stop it!\n");
- }
-
- break;
- }
-#ifdef WLAN_BTAMP_FEATURE
- case WE_ENABLE_AMP:
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: enabling AMP", __func__);
- WLANBAP_RegisterWithHCI(pAdapter);
- break;
- }
- case WE_DISABLE_AMP:
- {
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
- VOS_STATUS status;
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
-
- pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
- status = WLANBAP_StopAmp();
- if(VOS_STATUS_SUCCESS != status )
- {
- pHddCtx->isAmpAllowed = VOS_TRUE;
- hddLog(VOS_TRACE_LEVEL_FATAL,
- "%s: Failed to stop AMP", __func__);
- }
- else
- {
- //a state m/c implementation in PAL is TBD to avoid this delay
- msleep(500);
- pHddCtx->isAmpAllowed = VOS_FALSE;
- WLANBAP_DeregisterFromHCI();
- }
-
- break;
- }
- case WE_GET_PPS_PAID_MATCH:
- {
- hddLog(LOG1, "GET WMI_VDEV_PPS_PAID_MATCH");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_PAID_MATCH,
- VDEV_CMD);
- break;
- }
- case WE_GET_PPS_GID_MATCH:
- {
- hddLog(LOG1, "GET WMI_VDEV_PPS_GID_MATCH");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_GID_MATCH,
- VDEV_CMD);
- break;
- }
- case WE_GET_PPS_EARLY_TIM_CLEAR:
- {
- hddLog(LOG1, "GET WMI_VDEV_PPS_EARLY_TIM_CLEAR");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_EARLY_TIM_CLEAR,
- VDEV_CMD);
- break;
- }
- case WE_GET_PPS_EARLY_DTIM_CLEAR:
- {
- hddLog(LOG1, "GET WMI_VDEV_PPS_EARLY_DTIM_CLEAR");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
- VDEV_CMD);
- break;
- }
- case WE_GET_PPS_EOF_PAD_DELIM:
- {
- hddLog(LOG1, "GET WMI_VDEV_PPS_EOF_PAD_DELIM");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_EOF_PAD_DELIM,
- VDEV_CMD);
- break;
- }
- case WE_GET_PPS_MACADDR_MISMATCH:
- {
- hddLog(LOG1, "GET WMI_VDEV_PPS_MACADDR_MISMATCH");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_MACADDR_MISMATCH,
- VDEV_CMD);
- break;
- }
- case WE_GET_PPS_DELIM_CRC_FAIL:
- {
- hddLog(LOG1, "GET WMI_VDEV_PPS_DELIM_CRC_FAIL");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_DELIM_CRC_FAIL,
- VDEV_CMD);
- break;
- }
- case WE_GET_PPS_GID_NSTS_ZERO:
- {
- hddLog(LOG1, "GET WMI_VDEV_PPS_GID_NSTS_ZERO");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_GID_NSTS_ZERO,
- VDEV_CMD);
- break;
- }
- case WE_GET_PPS_RSSI_CHECK:
- {
-
- hddLog(LOG1, "GET WMI_VDEV_PPS_RSSI_CHECK");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_RSSI_CHECK,
- VDEV_CMD);
- break;
- }
-#endif
-
- case WE_ENABLE_DXE_STALL_DETECT:
- {
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- sme_transportDebug(hHal, VOS_FALSE, VOS_TRUE);
- break;
- }
- case WE_DISPLAY_DXE_SNAP_SHOT:
- {
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- sme_transportDebug(hHal, VOS_TRUE, VOS_FALSE);
- break;
- }
- case WE_DISPLAY_DATAPATH_SNAP_SHOT:
- {
- hddLog(LOGE, "%s: called %d",__func__, sub_cmd);
- hdd_wmm_tx_snapshot(pAdapter);
- WLANTL_TLDebugMessage(VOS_TRUE);
- break;
- }
- case WE_SET_REASSOC_TRIGGER:
- {
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tpAniSirGlobal pMac = WLAN_HDD_GET_HAL_CTX(pAdapter);
- v_U32_t roamId = 0;
- tCsrRoamModifyProfileFields modProfileFields;
- sme_GetModifyProfileFields(pMac, pAdapter->sessionId, &modProfileFields);
- sme_RoamReassoc(pMac, pAdapter->sessionId, NULL, modProfileFields, &roamId, 1);
- return 0;
- }
-
-#ifdef QCA_WIFI_2_0
- case WE_DUMP_AGC_START:
- {
- hddLog(LOG1, "WE_DUMP_AGC_START");
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)GEN_PARAM_DUMP_AGC_START,
- 0, GEN_CMD);
- break;
- }
- case WE_DUMP_AGC:
- {
- hddLog(LOG1, "WE_DUMP_AGC");
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)GEN_PARAM_DUMP_AGC,
- 0, GEN_CMD);
- break;
- }
-
- case WE_DUMP_CHANINFO_START:
- {
- hddLog(LOG1, "WE_DUMP_CHANINFO_START");
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)GEN_PARAM_DUMP_CHANINFO_START,
- 0, GEN_CMD);
- break;
- }
- case WE_DUMP_CHANINFO:
- {
- hddLog(LOG1, "WE_DUMP_CHANINFO_START");
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)GEN_PARAM_DUMP_CHANINFO,
- 0, GEN_CMD);
- break;
- }
- case WE_DUMP_WATCHDOG:
- {
- hddLog(LOG1, "WE_DUMP_WATCHDOG");
- ret = process_wma_set_command((int)pAdapter->sessionId,
- (int)GEN_PARAM_DUMP_WATCHDOG,
- 0, GEN_CMD);
- break;
- }
-#ifdef DEBUG
- case WE_SET_FW_CRASH_INJECT:
- {
- hddLog(LOGE, "WE_FW_CRASH_INJECT");
- ret = process_wma_set_command((int) pAdapter->sessionId,
- (int) GEN_PARAM_CRASH_INJECT,
- 0, GEN_CMD);
- break;
- }
-#endif
-#endif
- default:
- {
- hddLog(LOGE, "%s: unknown ioctl %d", __func__, sub_cmd);
- break;
- }
- }
-
- return ret;
-}
-
-void hdd_wmm_tx_snapshot(hdd_adapter_t *pAdapter)
-{
- /*
- * Function to display HDD WMM information
- * for Tx Queues.
- * Prints globala as well as per client depending
- * whether the clients are registered or not.
- */
- int i = 0, j = 0;
- for ( i=0; i< NUM_TX_QUEUES; i++)
- {
- spin_lock_bh(&pAdapter->wmm_tx_queue[i].lock);
- hddLog(LOGE, "HDD WMM TxQueue Info For AC: %d Count: %d PrevAdress:0x%x, NextAddress:0x%x",
- i, pAdapter->wmm_tx_queue[i].count,
- pAdapter->wmm_tx_queue[i].anchor.prev, pAdapter->wmm_tx_queue[i].anchor.next);
- spin_unlock_bh(&pAdapter->wmm_tx_queue[i].lock);
- }
-
- for(i =0; i<WLAN_MAX_STA_COUNT; i++)
- {
- if(pAdapter->aStaInfo[i].isUsed)
- {
- hddLog(LOGE, "******STAIndex: %d*********", i);
- for ( j=0; j< NUM_TX_QUEUES; j++)
- {
- spin_lock_bh(&pAdapter->aStaInfo[i].wmm_tx_queue[j].lock);
- hddLog(LOGE, "HDD TxQueue Info For AC: %d Count: %d PrevAdress:0x%x, NextAddress:0x%x",
- j, pAdapter->aStaInfo[i].wmm_tx_queue[j].count,
- pAdapter->aStaInfo[i].wmm_tx_queue[j].anchor.prev,
- pAdapter->aStaInfo[i].wmm_tx_queue[j].anchor.next);
- spin_unlock_bh(&pAdapter->aStaInfo[i].wmm_tx_queue[j].lock);
- }
- }
- }
-
-}
-int iw_set_var_ints_getnone(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- int sub_cmd = wrqu->data.flags;
- int *value = (int*)extra;
- int apps_args[MAX_VAR_ARGS] = {0};
- int num_args = wrqu->data.length;
- hdd_station_ctx_t *pStaCtx = NULL ;
- hdd_ap_ctx_t *pAPCtx = NULL;
- int cmd = 0;
- int staId = 0;
-
- hddLog(LOG1, "%s: Received length %d", __func__, wrqu->data.length);
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- if (num_args > MAX_VAR_ARGS)
- {
- num_args = MAX_VAR_ARGS;
- }
- vos_mem_copy(apps_args, value, (sizeof(int)) * num_args);
-
- if(( sub_cmd == WE_MCC_CONFIG_CREDENTIAL ) ||
- (sub_cmd == WE_MCC_CONFIG_PARAMS ))
- {
- if(( pAdapter->device_mode == WLAN_HDD_INFRA_STATION )||
- ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT ))
- {
- pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- staId = pStaCtx->conn_info.staId[0];
- }
- else if (( pAdapter->device_mode == WLAN_HDD_P2P_GO ) ||
- ( pAdapter->device_mode == WLAN_HDD_SOFTAP ))
- {
- pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
- staId = pAPCtx->uBCStaId;
- }
- else
- {
- hddLog(LOGE, "%s: Device mode %d not recognised", __FUNCTION__, pAdapter->device_mode);
- return 0;
- }
- }
-
- switch (sub_cmd)
- {
- case WE_LOG_DUMP_CMD:
- {
- hddLog(LOG1, "%s: LOG_DUMP %d arg1 %d arg2 %d arg3 %d arg4 %d",
- __func__, apps_args[0], apps_args[1], apps_args[2],
- apps_args[3], apps_args[4]);
-
- logPrintf(hHal, apps_args[0], apps_args[1], apps_args[2],
- apps_args[3], apps_args[4]);
-
- }
- break;
-#ifdef FEATURE_CESIUM_PROPRIETARY
- case WE_IBSS_GET_PEER_INFO:
- {
- pr_info ( "Station ID = %d\n",apps_args[0]);
- hdd_wlan_get_ibss_peer_info(pAdapter, apps_args[0]);
- }
- break;
-#endif
-
- case WE_P2P_NOA_CMD:
- {
- p2p_app_setP2pPs_t p2pNoA;
-
- p2pNoA.opp_ps = apps_args[0];
- p2pNoA.ctWindow = apps_args[1];
- p2pNoA.duration = apps_args[2];
- p2pNoA.interval = apps_args[3];
- p2pNoA.count = apps_args[4];
- p2pNoA.single_noa_duration = apps_args[5];
- p2pNoA.psSelection = apps_args[6];
-
- hddLog(LOG1, "%s: P2P_NOA_ATTR:oppPS %d ctWindow %d duration %d "
- "interval %d count %d single noa duration %d PsSelection %x",
- __func__, apps_args[0], apps_args[1], apps_args[2],
- apps_args[3], apps_args[4], apps_args[5], apps_args[6]);
-
- hdd_setP2pPs(dev, &p2pNoA);
-
- }
- break;
-
- case WE_MCC_CONFIG_CREDENTIAL :
- {
- cmd = 287; //Command should be updated if there is any change
- // in the Riva dump command
- if((apps_args[0] >= 40 ) && (apps_args[0] <= 160 ))
- {
- logPrintf(hHal, cmd, staId, apps_args[0], apps_args[1], apps_args[2]);
- }
- else
- {
- hddLog(LOGE, "%s : Enter valid MccCredential value between MIN :40 and MAX:160\n", __func__);
- return 0;
- }
- }
- break;
-
- case WE_MCC_CONFIG_PARAMS :
- {
- cmd = 288; //command Should be updated if there is any change
- // in the Riva dump command
- hdd_validate_mcc_config(pAdapter, staId, apps_args[0], apps_args[1],apps_args[2]);
- }
- break;
-
-#ifdef FEATURE_WLAN_TDLS
- case WE_TDLS_CONFIG_PARAMS :
- {
- tdls_config_params_t tdlsParams;
-
- tdlsParams.tdls = apps_args[0];
- tdlsParams.tx_period_t = apps_args[1];
- tdlsParams.tx_packet_n = apps_args[2];
- tdlsParams.discovery_period_t = apps_args[3];
- tdlsParams.discovery_tries_n = apps_args[4];
- tdlsParams.idle_timeout_t = apps_args[5];
- tdlsParams.idle_packet_n = apps_args[6];
- tdlsParams.rssi_hysteresis = apps_args[7];
- tdlsParams.rssi_trigger_threshold = apps_args[8];
- tdlsParams.rssi_teardown_threshold = apps_args[9];
-
- wlan_hdd_tdls_set_params(dev, &tdlsParams);
- }
- break;
-#endif
- default:
- {
- hddLog(LOGE, "Invalid IOCTL command %d", sub_cmd );
- }
- break;
- }
-
- return 0;
-}
-
-
-static int iw_add_tspec(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *)extra;
- int params[HDD_WLAN_WMM_PARAM_COUNT];
- sme_QosWmmTspecInfo tSpec;
- v_U32_t handle;
-
- // make sure the application is sufficiently priviledged
- // note that the kernel will do this for "set" ioctls, but since
- // this ioctl wants to return status to user space it must be
- // defined as a "get" ioctl
- if (!capable(CAP_NET_ADMIN))
- {
- return -EPERM;
- }
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- // we must be associated in order to add a tspec
- if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
- {
- *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
- return 0;
- }
-
- // since we are defined to be a "get" ioctl, and since the number
- // of params exceeds the number of params that wireless extensions
- // will pass down in the iwreq_data, we must copy the "set" params
- // from user space ourselves
- if (copy_from_user(&params, wrqu->data.pointer, sizeof(params)))
- {
- // hmmm, can't get them
- return -EIO;
- }
-
- // clear the tspec
- memset(&tSpec, 0, sizeof(tSpec));
-
- // validate the handle
- handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
- if (HDD_WMM_HANDLE_IMPLICIT == handle)
- {
- // that one is reserved
- *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
- return 0;
- }
-
- // validate the TID
- if (params[HDD_WLAN_WMM_PARAM_TID] > 7)
- {
- // out of range
- *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
- return 0;
- }
- tSpec.ts_info.tid = params[HDD_WLAN_WMM_PARAM_TID];
-
- // validate the direction
- switch (params[HDD_WLAN_WMM_PARAM_DIRECTION])
- {
- case HDD_WLAN_WMM_DIRECTION_UPSTREAM:
- tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_UPLINK;
- break;
-
- case HDD_WLAN_WMM_DIRECTION_DOWNSTREAM:
- tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_DOWNLINK;
- break;
-
- case HDD_WLAN_WMM_DIRECTION_BIDIRECTIONAL:
- tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_BOTH;
- break;
-
- default:
- // unknown
- *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
- return 0;
- }
-
- tSpec.ts_info.psb = params[HDD_WLAN_WMM_PARAM_APSD];
-
- // validate the user priority
- if (params[HDD_WLAN_WMM_PARAM_USER_PRIORITY] >= SME_QOS_WMM_UP_MAX)
- {
- // out of range
- *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
- return 0;
- }
- tSpec.ts_info.up = params[HDD_WLAN_WMM_PARAM_USER_PRIORITY];
- if(0 > tSpec.ts_info.up || SME_QOS_WMM_UP_MAX < tSpec.ts_info.up)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,"***ts_info.up out of bounds***");
- return 0;
- }
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
- "%s:TS_INFO PSB %d UP %d !!!", __func__,
- tSpec.ts_info.psb, tSpec.ts_info.up);
-
- tSpec.nominal_msdu_size = params[HDD_WLAN_WMM_PARAM_NOMINAL_MSDU_SIZE];
- tSpec.maximum_msdu_size = params[HDD_WLAN_WMM_PARAM_MAXIMUM_MSDU_SIZE];
- tSpec.min_data_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_DATA_RATE];
- tSpec.mean_data_rate = params[HDD_WLAN_WMM_PARAM_MEAN_DATA_RATE];
- tSpec.peak_data_rate = params[HDD_WLAN_WMM_PARAM_PEAK_DATA_RATE];
- tSpec.max_burst_size = params[HDD_WLAN_WMM_PARAM_MAX_BURST_SIZE];
- tSpec.min_phy_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_PHY_RATE];
- tSpec.surplus_bw_allowance = params[HDD_WLAN_WMM_PARAM_SURPLUS_BANDWIDTH_ALLOWANCE];
- tSpec.min_service_interval = params[HDD_WLAN_WMM_PARAM_SERVICE_INTERVAL];
- tSpec.max_service_interval = params[HDD_WLAN_WMM_PARAM_MAX_SERVICE_INTERVAL];
- tSpec.suspension_interval = params[HDD_WLAN_WMM_PARAM_SUSPENSION_INTERVAL];
- tSpec.inactivity_interval = params[HDD_WLAN_WMM_PARAM_INACTIVITY_INTERVAL];
-
- tSpec.ts_info.burst_size_defn = params[HDD_WLAN_WMM_PARAM_BURST_SIZE_DEFN];
-
- // validate the ts info ack policy
- switch (params[HDD_WLAN_WMM_PARAM_ACK_POLICY])
- {
- case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
- tSpec.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
- break;
-
- case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
- tSpec.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
- break;
-
- default:
- // unknown
- *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
- return 0;
- }
-
- *pStatus = hdd_wmm_addts(pAdapter, handle, &tSpec);
- return 0;
-}
-
-
-static int iw_del_tspec(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- int *params = (int *)extra;
- hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *)extra;
- v_U32_t handle;
-
- // make sure the application is sufficiently priviledged
- // note that the kernel will do this for "set" ioctls, but since
- // this ioctl wants to return status to user space it must be
- // defined as a "get" ioctl
- if (!capable(CAP_NET_ADMIN))
- {
- return -EPERM;
- }
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- // although we are defined to be a "get" ioctl, the params we require
- // will fit in the iwreq_data, therefore unlike iw_add_tspec() there
- // is no need to copy the params from user space
-
- // validate the handle
- handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
- if (HDD_WMM_HANDLE_IMPLICIT == handle)
- {
- // that one is reserved
- *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
- return 0;
- }
-
- *pStatus = hdd_wmm_delts(pAdapter, handle);
- return 0;
-}
-
-
-static int iw_get_tspec(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- int *params = (int *)extra;
- hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *)extra;
- v_U32_t handle;
-
- // although we are defined to be a "get" ioctl, the params we require
- // will fit in the iwreq_data, therefore unlike iw_add_tspec() there
- // is no need to copy the params from user space
-
- // validate the handle
- handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
- if (HDD_WMM_HANDLE_IMPLICIT == handle)
- {
- // that one is reserved
- *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
- return 0;
- }
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- *pStatus = hdd_wmm_checkts(pAdapter, handle);
- return 0;
-}
-
-
-#ifdef FEATURE_WLAN_WAPI
-static int iw_qcom_set_wapi_mode(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
-
- WAPI_FUNCTION_MODE *pWapiMode = (WAPI_FUNCTION_MODE *)extra;
-
- hddLog(LOG1, "The function iw_qcom_set_wapi_mode called");
- hddLog(LOG1, "%s: Received data %s", __func__, extra);
- hddLog(LOG1, "%s: Received length %d", __func__, wrqu->data.length);
- hddLog(LOG1, "%s: Input Data (wreq) WAPI Mode:%02d", __func__, pWapiMode->wapiMode);
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- if(WZC_ORIGINAL == pWapiMode->wapiMode) {
- hddLog(LOG1, "%s: WAPI Mode Set to OFF", __func__);
- /* Set Encryption mode to defualt , this allows next successfull non-WAPI Association */
- pRoamProfile->EncryptionType.numEntries = 1;
- pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
- pRoamProfile->mcEncryptionType.numEntries = 1;
- pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
-
- pRoamProfile->AuthType.numEntries = 1;
- pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
- pRoamProfile->AuthType.authType[0] = pHddStaCtx->conn_info.authType;
- }
- else if(WAPI_EXTENTION == pWapiMode->wapiMode) {
- hddLog(LOG1, "%s: WAPI Mode Set to ON", __func__);
- }
- else
- return -EINVAL;
-
- pAdapter->wapi_info.nWapiMode = pWapiMode->wapiMode;
-
- return 0;
-}
-
-static int iw_qcom_get_wapi_mode(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- WAPI_FUNCTION_MODE *pWapiMode = (WAPI_FUNCTION_MODE *)(extra);
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
- hddLog(LOG1, "The function iw_qcom_get_wapi_mode called");
-
- pWapiMode->wapiMode = pAdapter->wapi_info.nWapiMode;
- hddLog(LOG1, "%s: GET WAPI Mode Value:%02d", __func__, pWapiMode->wapiMode);
- printk("\nGET WAPI MODE:%d",pWapiMode->wapiMode);
- return 0;
-}
-
-static int iw_qcom_set_wapi_assoc_info(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
-// WAPI_AssocInfo *pWapiAssocInfo = (WAPI_AssocInfo *)(wrqu->data.pointer);
- WAPI_AssocInfo *pWapiAssocInfo = (WAPI_AssocInfo *)(extra);
- int i = 0, j = 0;
- hddLog(LOG1, "The function iw_qcom_set_wapi_assoc_info called");
- hddLog(LOG1, "%s: Received length %d", __func__, wrqu->data.length);
- hddLog(LOG1, "%s: Received data %s", __func__, (char*)extra);
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
- VOS_ASSERT(pWapiAssocInfo);
-
- hddLog(LOG1, "%s: INPUT DATA:\nElement ID:0x%02x Length:0x%02x Version:0x%04x\n",__func__,pWapiAssocInfo->elementID,pWapiAssocInfo->length,pWapiAssocInfo->version);
- hddLog(LOG1,"%s: akm Suite Cnt:0x%04x",__func__,pWapiAssocInfo->akmSuiteCount);
- for(i =0 ; i < 16 ; i++)
- hddLog(LOG1,"akm suite[%02d]:0x%08lx",i,pWapiAssocInfo->akmSuite[i]);
-
- hddLog(LOG1,"%s: Unicast Suite Cnt:0x%04x",__func__,pWapiAssocInfo->unicastSuiteCount);
- for(i =0 ; i < 16 ; i++)
- hddLog(LOG1, "Unicast suite[%02d]:0x%08lx",i,pWapiAssocInfo->unicastSuite[i]);
-
- hddLog(LOG1,"%s: Multicast suite:0x%08lx Wapi capa:0x%04x",__func__,pWapiAssocInfo->multicastSuite,pWapiAssocInfo->wapiCability);
- hddLog(LOG1, "%s: BKID Cnt:0x%04x\n",__func__,pWapiAssocInfo->bkidCount);
- for(i = 0 ; i < 16 ; i++) {
- hddLog(LOG1, "BKID List[%02d].bkid:0x",i);
- for(j = 0 ; j < 16 ; j++)
- hddLog(LOG1,"%02x",pWapiAssocInfo->bkidList[i].bkid[j]);
- }
-
- /* We are not using the entire IE as provided by the supplicant.
- * This is being calculated by SME. This is the same as in the
- * case of WPA. Only the auth mode information needs to be
- * extracted here*/
- if ( pWapiAssocInfo->akmSuite[0] == WAPI_PSK_AKM_SUITE ) {
- hddLog(LOG1, "%s: WAPI AUTH MODE SET TO PSK",__func__);
- pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
- }
-
- if ( pWapiAssocInfo->akmSuite[0] == WAPI_CERT_AKM_SUITE) {
- hddLog(LOG1, "%s: WAPI AUTH MODE SET TO CERTIFICATE",__func__);
- pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
- }
- return 0;
-}
-
-static int iw_qcom_set_wapi_key(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- eHalStatus halStatus = eHAL_STATUS_SUCCESS;
- tANI_U32 roamId = 0xFF;
- tANI_U8 *pKeyPtr = NULL;
- v_BOOL_t isConnected = TRUE;
- tCsrRoamSetKey setKey;
- int i = 0;
- WLAN_WAPI_KEY *pWapiKey = (WLAN_WAPI_KEY *)(extra);
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- hddLog(LOG1, "The function iw_qcom_set_wapi_key called ");
- hddLog(LOG1, "%s: Received length %d", __func__, wrqu->data.length);
- hddLog(LOG1, "%s: Received data %s", __func__, (char*)extra);
-
- hddLog(LOG1,":%s: INPUT DATA:\nKey Type:0x%02x Key Direction:0x%02x KEY ID:0x%02x\n", __func__, pWapiKey->keyType, pWapiKey->keyDirection, pWapiKey->keyId);
- hddLog(LOG1,"Add Index:0x");
- for(i =0 ; i < 12 ; i++)
- hddLog(LOG1,"%02x",pWapiKey->addrIndex[i]);
-
- hddLog(LOG1,"\n%s: WAPI ENCRYPTION KEY LENGTH:0x%04x", __func__,pWapiKey->wpiekLen);
- hddLog(LOG1, "WAPI ENCRYPTION KEY:0x");
- for(i =0 ; i < 16 ; i++)
- hddLog(LOG1,"%02x",pWapiKey->wpiek[i]);
-
- hddLog(LOG1,"\n%s: WAPI INTEGRITY CHECK KEY LENGTH:0x%04x", __func__,pWapiKey->wpickLen);
- hddLog(LOG1,"WAPI INTEGRITY CHECK KEY:0x");
- for(i =0 ; i < 16 ; i++)
- hddLog(LOG1,"%02x",pWapiKey->wpick[i]);
-
- hddLog(LOG1,"\nWAPI PN NUMBER:0x");
- for(i = 0 ; i < 16 ; i++)
- hddLog(LOG1,"%02x",pWapiKey->pn[i]);
-
- // Clear the setkey memory
- vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
- // Store Key ID
- setKey.keyId = (unsigned char)( pWapiKey->keyId );
- // SET WAPI Encryption
- setKey.encType = eCSR_ENCRYPT_TYPE_WPI;
- // Key Directionn both TX and RX
- setKey.keyDirection = eSIR_TX_RX; // Do WE NEED to update this based on Key Type as GRP/UNICAST??
- // the PAE role
- setKey.paeRole = 0 ;
-
- switch ( pWapiKey->keyType )
- {
- case PAIRWISE_KEY:
- {
- isConnected = hdd_connIsConnected(pHddStaCtx);
- vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
- break;
- }
- case GROUP_KEY:
- {
- vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
- break;
- }
- default:
- {
- //Any other option is invalid.
- VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "[%4d] %s() failed to Set Key. Invalid key type %d", __LINE__,__func__ , -1 );
-
- hddLog(LOGE," %s: Error WAPI Key Add Type",__func__);
- halStatus = !eHAL_STATUS_SUCCESS; // NEED TO UPDATE THIS WITH CORRECT VALUE
- break; // NEED RETURN FROM HERE ????
- }
- }
-
- // Concatenating the Encryption Key (EK) and the MIC key (CK): EK followed by CK
- setKey.keyLength = (v_U16_t)((pWapiKey->wpiekLen)+(pWapiKey->wpickLen));
- pKeyPtr = setKey.Key;
- memcpy( pKeyPtr, pWapiKey->wpiek, pWapiKey->wpiekLen );
- pKeyPtr += pWapiKey->wpiekLen;
- memcpy( pKeyPtr, pWapiKey->wpick, pWapiKey->wpickLen );
-
- // Set the new key with SME.
- pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
-
- if ( isConnected ) {
- halStatus = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, &setKey, &roamId );
- if ( halStatus != eHAL_STATUS_SUCCESS )
- {
- VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "[%4d] sme_RoamSetKey returned ERROR status= %d", __LINE__, halStatus );
-
- pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
- }
- }
-#if 0 /// NEED TO CHECK ON THIS
- else
- {
- // Store the keys in the adapter to be moved to the profile & passed to
- // SME in the ConnectRequest if we are not yet in connected state.
- memcpy( &pAdapter->setKey[ setKey.keyId ], &setKey, sizeof( setKey ) );
- pAdapter->fKeySet[ setKey.keyId ] = TRUE;
-
- VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
- " Saving key [idx= %d] to apply when moving to connected state ",
- setKey.keyId );
-
- }
-#endif
- return halStatus;
-}
-
-static int iw_qcom_set_wapi_bkid(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
-#ifdef WLAN_DEBUG
- int i = 0;
- WLAN_BKID_LIST *pBkid = ( WLAN_BKID_LIST *) extra;
-#endif
-
- hddLog(LOG1, "The function iw_qcom_set_wapi_bkid called");
- hddLog(LOG1, "%s: Received length %d", __func__, wrqu->data.length);
- hddLog(LOG1, "%s: Received data %s", __func__, (char*)extra);
-
- hddLog(LOG1,"%s: INPUT DATA:\n BKID Length:0x%08lx\n", __func__,pBkid->length);
- hddLog(LOG1,"%s: BKID Cnt:0x%04lx",pBkid->BKIDCount);
-
- hddLog(LOG1,"BKID KEY LIST[0]:0x");
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
-#ifdef WLAN_DEBUG
- for(i =0 ; i < 16 ; i++)
- hddLog(LOG1,"%02x",pBkid->BKID[0].bkid[i]);
-#endif
-
- return 0;
-}
-
-static int iw_qcom_get_wapi_bkid(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- /* Yet to implement this function, 19th April 2010 */
- hddLog(LOG1, "The function iw_qcom_get_wapi_bkid called ");
-
- return 0;
-}
-#endif /* FEATURE_WLAN_WAPI */
-
-#ifdef WLAN_FEATURE_VOWIFI_11R
-//
-//
-// Each time the supplicant has the auth_request or reassoc request
-// IEs ready. This is pushed to the driver. The driver will inturn use
-// it to send out the auth req and reassoc req for 11r FT Assoc.
-//
-static int iw_set_fties(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- //v_CONTEXT_t pVosContext;
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
- if (!wrqu->data.length)
- {
- hddLog(LOGE, FL("called with 0 length IEs\n"));
- return -EINVAL;
- }
- if (wrqu->data.pointer == NULL)
- {
- hddLog(LOGE, FL("called with NULL IE\n"));
- return -EINVAL;
- }
-
- // Added for debug on reception of Re-assoc Req.
- if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
- {
- hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
- wrqu->data.length);
- hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
- }
-
-#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
- hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__, wrqu->data.length);
-#endif
-
- // Pass the received FT IEs to SME
- sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, extra,
- wrqu->data.length);
-
- return 0;
-}
-#endif
-
-static int iw_set_dynamic_mcbc_filter(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tpRcvFltMcAddrList pRequest = (tpRcvFltMcAddrList)extra;
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- tpSirWlanSetRxpFilters wlanRxpFilterParam;
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- tpSirRcvFltMcAddrList mc_addr_list_ptr;
- int idx;
- eHalStatus ret_val;
-
- if (pHddCtx->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
- if ((HDD_MULTICAST_FILTER_LIST == pRequest->mcastBcastFilterSetting) ||
- (HDD_MULTICAST_FILTER_LIST_CLEAR == pRequest->mcastBcastFilterSetting))
- {
-#ifdef WLAN_FEATURE_PACKET_FILTERING
-
- mc_addr_list_ptr = vos_mem_malloc(sizeof(tSirRcvFltMcAddrList));
- if (NULL == mc_addr_list_ptr)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: vos_mem_alloc failed", __func__);
- return -ENOMEM;
- }
-
- mc_addr_list_ptr->ulMulticastAddrCnt = pRequest->mcast_addr_cnt;
-
- if (mc_addr_list_ptr->ulMulticastAddrCnt > HDD_MAX_NUM_MULTICAST_ADDRESS)
- mc_addr_list_ptr->ulMulticastAddrCnt = HDD_MAX_NUM_MULTICAST_ADDRESS;
-
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s MC Addr List Cnt %d", __func__,
- mc_addr_list_ptr->ulMulticastAddrCnt);
-
- for (idx = 0; idx < mc_addr_list_ptr->ulMulticastAddrCnt; idx++)
- {
- memcpy(&mc_addr_list_ptr->multicastAddr[idx],
- pRequest->multicastAddr[idx], HDD_WLAN_MAC_ADDR_LEN);
-
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s MC Addr for Idx %d ="MAC_ADDRESS_STR, __func__,
- idx, MAC_ADDR_ARRAY(mc_addr_list_ptr->multicastAddr[idx]));
- }
-
- if (HDD_MULTICAST_FILTER_LIST_CLEAR == pRequest->mcastBcastFilterSetting)
- mc_addr_list_ptr->action = 1; //clear
- else
- mc_addr_list_ptr->action = 0; //set
-
- ret_val = sme_8023MulticastList(hHal, pAdapter->sessionId, mc_addr_list_ptr);
- vos_mem_free(mc_addr_list_ptr);
- if (eHAL_STATUS_SUCCESS != ret_val)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to Set MC Address List",
- __func__);
- return -EINVAL;
- }
-#endif //WLAN_FEATURE_PACKET_FILTERING
- }
- else
- {
-
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
- "%s: Set MC BC Filter Config request: %d suspend %d",
- __func__, pRequest->mcastBcastFilterSetting,
- pHddCtx->hdd_wlan_suspended);
-
- pHddCtx->configuredMcastBcastFilter = pRequest->mcastBcastFilterSetting;
-
- if (pHddCtx->hdd_wlan_suspended)
- {
- wlanRxpFilterParam = vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
- if (NULL == wlanRxpFilterParam)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: vos_mem_alloc failed", __func__);
- return -EINVAL;
- }
-
- wlanRxpFilterParam->configuredMcstBcstFilterSetting =
- pRequest->mcastBcastFilterSetting;
- wlanRxpFilterParam->setMcstBcstFilter = TRUE;
-
- hdd_conf_hostoffload(pAdapter, TRUE);
- wlanRxpFilterParam->configuredMcstBcstFilterSetting =
- pHddCtx->configuredMcastBcastFilter;
-
- hddLog(VOS_TRACE_LEVEL_INFO, "%s:MC/BC changed Req %d Set %d En %d",
- __func__,
- pHddCtx->configuredMcastBcastFilter,
- wlanRxpFilterParam->configuredMcstBcstFilterSetting,
- wlanRxpFilterParam->setMcstBcstFilter);
-
- if (eHAL_STATUS_SUCCESS !=
- sme_ConfigureRxpFilter(WLAN_HDD_GET_HAL_CTX(pAdapter),
- wlanRxpFilterParam))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Failure to execute set HW MC/BC Filter request",
- __func__);
- vos_mem_free(wlanRxpFilterParam);
- return -EINVAL;
- }
-
- }
- }
-
- return 0;
-}
-
-static int iw_clear_dynamic_mcbc_filter(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- tpSirWlanSetRxpFilters wlanRxpFilterParam;
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: ", __func__);
-
- //Reset the filter to INI value as we have to clear the dynamic filter
- pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
-
- //Configure FW with new setting
- if (pHddCtx->hdd_wlan_suspended)
- {
- wlanRxpFilterParam = vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
- if (NULL == wlanRxpFilterParam)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: vos_mem_alloc failed", __func__);
- return -EINVAL;
- }
-
- wlanRxpFilterParam->configuredMcstBcstFilterSetting =
- pHddCtx->configuredMcastBcastFilter;
- wlanRxpFilterParam->setMcstBcstFilter = TRUE;
-
- hdd_conf_hostoffload(pAdapter, TRUE);
- wlanRxpFilterParam->configuredMcstBcstFilterSetting =
- pHddCtx->configuredMcastBcastFilter;
-
- if (eHAL_STATUS_SUCCESS !=
- sme_ConfigureRxpFilter(WLAN_HDD_GET_HAL_CTX(pAdapter),
- wlanRxpFilterParam))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Failure to execute set HW MC/BC Filter request",
- __func__);
- vos_mem_free(wlanRxpFilterParam);
- return -EINVAL;
- }
- }
- return 0;
-}
-
-static int iw_set_host_offload(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tpHostOffloadRequest pRequest = (tpHostOffloadRequest) extra;
- tSirHostOffloadReq offloadRequest;
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- /* Debug display of request components. */
- switch (pRequest->offloadType)
- {
- case WLAN_IPV4_ARP_REPLY_OFFLOAD:
- hddLog(VOS_TRACE_LEVEL_WARN, "%s: Host offload request: ARP reply", __func__);
- switch (pRequest->enableOrDisable)
- {
- case WLAN_OFFLOAD_DISABLE:
- hddLog(VOS_TRACE_LEVEL_WARN, " disable");
- break;
- case WLAN_OFFLOAD_ARP_AND_BC_FILTER_ENABLE:
- hddLog(VOS_TRACE_LEVEL_WARN, " BC Filtering enable");
- case WLAN_OFFLOAD_ENABLE:
- hddLog(VOS_TRACE_LEVEL_WARN, " ARP offload enable");
- hddLog(VOS_TRACE_LEVEL_WARN, " IP address: %d.%d.%d.%d",
- pRequest->params.hostIpv4Addr[0], pRequest->params.hostIpv4Addr[1],
- pRequest->params.hostIpv4Addr[2], pRequest->params.hostIpv4Addr[3]);
- }
- break;
-
- case WLAN_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD:
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Host offload request: neighbor discovery\n",
- __func__);
- switch (pRequest->enableOrDisable)
- {
- case WLAN_OFFLOAD_DISABLE:
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, " disable");
- break;
- case WLAN_OFFLOAD_ENABLE:
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, " enable");
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, " IP address: %x:%x:%x:%x:%x:%x:%x:%x",
- *(v_U16_t *)(pRequest->params.hostIpv6Addr),
- *(v_U16_t *)(pRequest->params.hostIpv6Addr + 2),
- *(v_U16_t *)(pRequest->params.hostIpv6Addr + 4),
- *(v_U16_t *)(pRequest->params.hostIpv6Addr + 6),
- *(v_U16_t *)(pRequest->params.hostIpv6Addr + 8),
- *(v_U16_t *)(pRequest->params.hostIpv6Addr + 10),
- *(v_U16_t *)(pRequest->params.hostIpv6Addr + 12),
- *(v_U16_t *)(pRequest->params.hostIpv6Addr + 14));
- }
- }
-
- /* Execute offload request. The reason that we can copy the request information
- from the ioctl structure to the SME structure is that they are laid out
- exactly the same. Otherwise, each piece of information would have to be
- copied individually. */
- memcpy(&offloadRequest, pRequest, wrqu->data.length);
- if (eHAL_STATUS_SUCCESS != sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
- pAdapter->sessionId, &offloadRequest))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute host offload request\n",
- __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int iw_set_keepalive_params(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tpKeepAliveRequest pRequest = (tpKeepAliveRequest) extra;
- tSirKeepAliveReq keepaliveRequest;
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return 0;
- }
-
- /* Debug display of request components. */
- hddLog(VOS_TRACE_LEVEL_INFO,
- "%s: Set Keep Alive Request : TimePeriod %d size %zu",
- __func__, pRequest->timePeriod, sizeof(tKeepAliveRequest));
-
- switch (pRequest->packetType)
- {
- case WLAN_KEEP_ALIVE_NULL_PKT:
- hddLog(VOS_TRACE_LEVEL_WARN, "%s: Keep Alive Request: Tx NULL", __func__);
- break;
-
- case WLAN_KEEP_ALIVE_UNSOLICIT_ARP_RSP:
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Keep Alive Request: Tx UnSolicited ARP RSP\n",
- __func__);
-
- hddLog(VOS_TRACE_LEVEL_WARN, " Host IP address: %d.%d.%d.%d",
- pRequest->hostIpv4Addr[0], pRequest->hostIpv4Addr[1],
- pRequest->hostIpv4Addr[2], pRequest->hostIpv4Addr[3]);
-
- hddLog(VOS_TRACE_LEVEL_WARN, " Dest IP address: %d.%d.%d.%d",
- pRequest->destIpv4Addr[0], pRequest->destIpv4Addr[1],
- pRequest->destIpv4Addr[2], pRequest->destIpv4Addr[3]);
-
- hddLog(VOS_TRACE_LEVEL_WARN, " Dest MAC address: %d:%d:%d:%d:%d:%d",
- pRequest->destMacAddr[0], pRequest->destMacAddr[1],
- pRequest->destMacAddr[2], pRequest->destMacAddr[3],
- pRequest->destMacAddr[4], pRequest->destMacAddr[5]);
- break;
- }
-
- /* Execute keep alive request. The reason that we can copy the request information
- from the ioctl structure to the SME structure is that they are laid out
- exactly the same. Otherwise, each piece of information would have to be
- copied individually. */
- memcpy(&keepaliveRequest, pRequest, wrqu->data.length);
-
- hddLog(VOS_TRACE_LEVEL_ERROR, "set Keep: TP before SME %d\n", keepaliveRequest.timePeriod);
-
- if (eHAL_STATUS_SUCCESS != sme_SetKeepAlive(WLAN_HDD_GET_HAL_CTX(pAdapter),
- pAdapter->sessionId, &keepaliveRequest))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute Keep Alive\n",
- __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-#ifdef WLAN_FEATURE_PACKET_FILTERING
-int wlan_hdd_set_filter(hdd_context_t *pHddCtx, tpPacketFilterCfg pRequest,
- tANI_U8 sessionId)
-{
- tSirRcvPktFilterCfgType packetFilterSetReq = {0};
- tSirRcvFltPktClearParam packetFilterClrReq = {0};
- int i=0;
-
- if (pHddCtx->cfg_ini->disablePacketFilter)
- {
- hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Packet Filtering Disabled. Returning ",
- __func__ );
- return 0;
- }
- if (pHddCtx->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
- /* Debug display of request components. */
- hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Packet Filter Request : FA %d params %d",
- __func__, pRequest->filterAction, pRequest->numParams);
-
- switch (pRequest->filterAction)
- {
- case HDD_RCV_FILTER_SET:
- hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set Packet Filter Request for Id: %d",
- __func__, pRequest->filterId);
-
- packetFilterSetReq.filterId = pRequest->filterId;
- if ( pRequest->numParams >= HDD_MAX_CMP_PER_PACKET_FILTER)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Number of Params exceed Max limit %d\n",
- __func__, pRequest->numParams);
- return -EINVAL;
- }
- packetFilterSetReq.numFieldParams = pRequest->numParams;
- packetFilterSetReq.coalesceTime = 0;
- packetFilterSetReq.filterType = 1;
- for (i=0; i < pRequest->numParams; i++)
- {
- packetFilterSetReq.paramsData[i].protocolLayer = pRequest->paramsData[i].protocolLayer;
- packetFilterSetReq.paramsData[i].cmpFlag = pRequest->paramsData[i].cmpFlag;
- packetFilterSetReq.paramsData[i].dataOffset = pRequest->paramsData[i].dataOffset;
- packetFilterSetReq.paramsData[i].dataLength = pRequest->paramsData[i].dataLength;
- packetFilterSetReq.paramsData[i].reserved = 0;
-
- hddLog(VOS_TRACE_LEVEL_INFO, "Proto %d Comp Flag %d Filter Type %d\n",
- pRequest->paramsData[i].protocolLayer, pRequest->paramsData[i].cmpFlag,
- packetFilterSetReq.filterType);
-
- hddLog(VOS_TRACE_LEVEL_INFO, "Data Offset %d Data Len %d\n",
- pRequest->paramsData[i].dataOffset, pRequest->paramsData[i].dataLength);
-
- memcpy(&packetFilterSetReq.paramsData[i].compareData,
- pRequest->paramsData[i].compareData, pRequest->paramsData[i].dataLength);
- memcpy(&packetFilterSetReq.paramsData[i].dataMask,
- pRequest->paramsData[i].dataMask, pRequest->paramsData[i].dataLength);
-
- hddLog(VOS_TRACE_LEVEL_INFO, "CData %d CData %d CData %d CData %d CData %d CData %d\n",
- pRequest->paramsData[i].compareData[0], pRequest->paramsData[i].compareData[1],
- pRequest->paramsData[i].compareData[2], pRequest->paramsData[i].compareData[3],
- pRequest->paramsData[i].compareData[4], pRequest->paramsData[i].compareData[5]);
-
- hddLog(VOS_TRACE_LEVEL_INFO, "MData %d MData %d MData %d MData %d MData %d MData %d\n",
- pRequest->paramsData[i].dataMask[0], pRequest->paramsData[i].dataMask[1],
- pRequest->paramsData[i].dataMask[2], pRequest->paramsData[i].dataMask[3],
- pRequest->paramsData[i].dataMask[4], pRequest->paramsData[i].dataMask[5]);
- }
-
- if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal, &packetFilterSetReq, sessionId))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute Set Filter\n",
- __func__);
- return -EINVAL;
- }
-
- break;
-
- case HDD_RCV_FILTER_CLEAR:
-
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Clear Packet Filter Request for Id: %d\n",
- __func__, pRequest->filterId);
- packetFilterClrReq.filterId = pRequest->filterId;
- if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterClearFilter(pHddCtx->hHal, &packetFilterClrReq, sessionId))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute Clear Filter\n",
- __func__);
- return -EINVAL;
- }
- break;
-
- default :
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Packet Filter Request: Invalid %d\n",
- __func__, pRequest->filterAction);
- return -EINVAL;
- }
- return 0;
-}
-
-int wlan_hdd_setIPv6Filter(hdd_context_t *pHddCtx, tANI_U8 filterType,
- tANI_U8 sessionId)
-{
- tSirRcvPktFilterCfgType packetFilterSetReq = {0};
- tSirRcvFltPktClearParam packetFilterClrReq = {0};
-
- if (NULL == pHddCtx)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, FL(" NULL HDD Context Passed"));
- return -EINVAL;
- }
-
- if (pHddCtx->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- if (pHddCtx->cfg_ini->disablePacketFilter)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Packet Filtering Disabled. Returning ",
- __func__ );
- return -EINVAL;
- }
-
- switch (filterType)
- {
- /* For setting IPV6 MC and UC Filter we need to configure
- * 2 filters, one for MC and one for UC.
- * The Filter ID shouldn't be swapped, which results in making
- * UC Filter ineffective.
- * We have Hardcode all the values
- *
- * Reason for a seperate UC filter is because, driver need to
- * specify the FW that the specific filter is for unicast
- * otherwise FW will not pass the unicast frames by default
- * through the filter. This is required to avoid any performance
- * hits when no unicast filter is set and only MC/BC are set.
- * The way driver informs host is by using the MAC protocol
- * layer, CMP flag set to MAX, CMP Data set to 1.
- */
-
- case HDD_FILTER_IPV6_MC_UC:
- /* Setting IPV6 MC Filter below
- */
- packetFilterSetReq.filterType = HDD_RCV_FILTER_SET;
- packetFilterSetReq.filterId = HDD_FILTER_ID_IPV6_MC;
- packetFilterSetReq.numFieldParams = 2;
- packetFilterSetReq.paramsData[0].protocolLayer =
- HDD_FILTER_PROTO_TYPE_MAC;
- packetFilterSetReq.paramsData[0].cmpFlag =
- HDD_FILTER_CMP_TYPE_NOT_EQUAL;
- packetFilterSetReq.paramsData[0].dataOffset =
- WLAN_HDD_80211_FRM_DA_OFFSET;
- packetFilterSetReq.paramsData[0].dataLength = 1;
- packetFilterSetReq.paramsData[0].compareData[0] =
- HDD_IPV6_MC_CMP_DATA;
-
- packetFilterSetReq.paramsData[1].protocolLayer =
- HDD_FILTER_PROTO_TYPE_ARP;
- packetFilterSetReq.paramsData[1].cmpFlag =
- HDD_FILTER_CMP_TYPE_NOT_EQUAL;
- packetFilterSetReq.paramsData[1].dataOffset = ETH_ALEN;
- packetFilterSetReq.paramsData[1].dataLength = 2;
- packetFilterSetReq.paramsData[1].compareData[0] =
- HDD_IPV6_CMP_DATA_0;
- packetFilterSetReq.paramsData[1].compareData[1] =
- HDD_IPV6_CMP_DATA_1;
-
-
- if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal,
- &packetFilterSetReq, sessionId))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Failure to execute Set IPv6 Mulicast Filter",
- __func__);
- return -EINVAL;
- }
-
- memset( &packetFilterSetReq, 0, sizeof(tSirRcvPktFilterCfgType));
-
- /*
- * Setting IPV6 UC Filter below
- */
- packetFilterSetReq.filterType = HDD_RCV_FILTER_SET;
- packetFilterSetReq.filterId = HDD_FILTER_ID_IPV6_UC;
- packetFilterSetReq.numFieldParams = 2;
- packetFilterSetReq.paramsData[0].protocolLayer =
- HDD_FILTER_PROTO_TYPE_MAC;
- packetFilterSetReq.paramsData[0].cmpFlag =
- HDD_FILTER_CMP_TYPE_MAX;
- packetFilterSetReq.paramsData[0].dataOffset = 0;
- packetFilterSetReq.paramsData[0].dataLength = 1;
- packetFilterSetReq.paramsData[0].compareData[0] =
- HDD_IPV6_UC_CMP_DATA;
-
- packetFilterSetReq.paramsData[1].protocolLayer =
- HDD_FILTER_PROTO_TYPE_ARP;
- packetFilterSetReq.paramsData[1].cmpFlag =
- HDD_FILTER_CMP_TYPE_NOT_EQUAL;
- packetFilterSetReq.paramsData[1].dataOffset = ETH_ALEN;
- packetFilterSetReq.paramsData[1].dataLength = 2;
- packetFilterSetReq.paramsData[1].compareData[0] =
- HDD_IPV6_CMP_DATA_0;
- packetFilterSetReq.paramsData[1].compareData[1] =
- HDD_IPV6_CMP_DATA_1;
-
- if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal,
- &packetFilterSetReq, sessionId))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Failure to execute Set IPv6 Unicast Filter",
- __func__);
- return -EINVAL;
- }
-
- break;
-
- case HDD_FILTER_IPV6_MC:
- /*
- * IPV6 UC Filter might be already set,
- * clear the UC Filter. As the Filter
- * IDs are static, we can directly clear it.
- */
- packetFilterSetReq.filterType = HDD_RCV_FILTER_SET;
- packetFilterClrReq.filterId = HDD_FILTER_ID_IPV6_UC;
- if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterClearFilter(pHddCtx->hHal,
- &packetFilterClrReq, sessionId))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Failure to execute Clear IPv6 Unicast Filter",
- __func__);
- return -EINVAL;
- }
-
- /*
- * Setting IPV6 MC Filter below
- */
- packetFilterSetReq.filterId = HDD_FILTER_ID_IPV6_MC;
- packetFilterSetReq.numFieldParams = 2;
- packetFilterSetReq.paramsData[0].protocolLayer =
- HDD_FILTER_PROTO_TYPE_MAC;
- packetFilterSetReq.paramsData[0].cmpFlag =
- HDD_FILTER_CMP_TYPE_NOT_EQUAL;
- packetFilterSetReq.paramsData[0].dataOffset =
- WLAN_HDD_80211_FRM_DA_OFFSET;
- packetFilterSetReq.paramsData[0].dataLength = 1;
- packetFilterSetReq.paramsData[0].compareData[0] =
- HDD_IPV6_MC_CMP_DATA;
-
- packetFilterSetReq.paramsData[1].protocolLayer =
- HDD_FILTER_PROTO_TYPE_ARP;
- packetFilterSetReq.paramsData[1].cmpFlag =
- HDD_FILTER_CMP_TYPE_NOT_EQUAL;
- packetFilterSetReq.paramsData[1].dataOffset = ETH_ALEN;
- packetFilterSetReq.paramsData[1].dataLength = 2;
- packetFilterSetReq.paramsData[1].compareData[0] =
- HDD_IPV6_CMP_DATA_0;
- packetFilterSetReq.paramsData[1].compareData[1] =
- HDD_IPV6_CMP_DATA_1;
-
-
- if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal,
- &packetFilterSetReq, sessionId))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Failure to execute Set IPv6 Multicast Filter",
- __func__);
- return -EINVAL;
- }
- break;
-
- default :
- hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
- "%s: Packet Filter Request: Invalid",
- __func__);
- return -EINVAL;
- }
- return 0;
-}
-
-void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, v_U8_t set)
-{
- v_U8_t i;
- tpSirRcvFltMcAddrList pMulticastAddrs = NULL;
- tHalHandle hHal = NULL;
- hdd_context_t* pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
-
- if (NULL == pHddCtx)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD CTX is NULL"));
- return;
- }
-
- hHal = pHddCtx->hHal;
-
- if (NULL == hHal)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, FL("HAL Handle is NULL"));
- return;
- }
-
- /* Check if INI is enabled or not, other wise just return
- */
- if (pHddCtx->cfg_ini->fEnableMCAddrList)
- {
- pMulticastAddrs = vos_mem_malloc(sizeof(tSirRcvFltMcAddrList));
- if (NULL == pMulticastAddrs)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, FL("Could not allocate Memory"));
- return;
- }
-
- if (set)
- {
- /* Following pre-conditions should be satisfied before wei
- * configure the MC address list.
- */
- if (((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
- (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
- && pAdapter->mc_addr_list.mc_cnt
- && (eConnectionState_Associated ==
- (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
- {
- pMulticastAddrs->ulMulticastAddrCnt =
- pAdapter->mc_addr_list.mc_cnt;
- for (i = 0; i < pAdapter->mc_addr_list.mc_cnt; i++)
- {
- memcpy(&(pMulticastAddrs->multicastAddr[i][0]),
- &(pAdapter->mc_addr_list.addr[i][0]),
- sizeof(pAdapter->mc_addr_list.addr[i]));
- hddLog(VOS_TRACE_LEVEL_INFO,
- "%s: %s multicast filter: addr ="
- MAC_ADDRESS_STR,
- __func__, set ? "setting" : "clearing",
- MAC_ADDR_ARRAY(pMulticastAddrs->multicastAddr[i]));
- }
- /* Set multicast filter */
- sme_8023MulticastList(hHal, pAdapter->sessionId,
- pMulticastAddrs);
- }
- }
- else
- {
- /* Need to clear only if it was previously configured
- */
- if (pAdapter->mc_addr_list.isFilterApplied)
- {
- pMulticastAddrs->ulMulticastAddrCnt = 0;
- sme_8023MulticastList(hHal, pAdapter->sessionId,
- pMulticastAddrs);
- }
-
- }
- pAdapter->mc_addr_list.isFilterApplied = set ? TRUE : FALSE;
- vos_mem_free(pMulticastAddrs);
- }
- else
- {
- hddLog(VOS_TRACE_LEVEL_INFO,
- FL("gMCAddrListEnable is not enabled in INI"));
- }
- return;
-}
-
-static int iw_set_packet_filter_params(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tpPacketFilterCfg pRequest = (tpPacketFilterCfg) extra;
-
- return wlan_hdd_set_filter(WLAN_HDD_GET_CTX(pAdapter), pRequest, pAdapter->sessionId);
-}
-#endif
-static int iw_get_statistics(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
-
- VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
- eHalStatus status = eHAL_STATUS_SUCCESS;
- hdd_wext_state_t *pWextState;
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- char *p = extra;
- int tlen = 0;
- tCsrSummaryStatsInfo *pStats = &(pAdapter->hdd_stats.summary_stat);
-
- tCsrGlobalClassAStatsInfo *aStats = &(pAdapter->hdd_stats.ClassA_stat);
- tCsrGlobalClassDStatsInfo *dStats = &(pAdapter->hdd_stats.ClassD_stat);
-
- ENTER();
-
- if (pHddCtx->isLogpInProgress) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
- return -EINVAL;
- }
-
- if (eConnectionState_Associated != (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) {
-
- wrqu->txpower.value = 0;
- }
- else {
- status = sme_GetStatistics( pHddCtx->hHal, eCSR_HDD,
- SME_SUMMARY_STATS |
- SME_GLOBAL_CLASSA_STATS |
- SME_GLOBAL_CLASSB_STATS |
- SME_GLOBAL_CLASSC_STATS |
- SME_GLOBAL_CLASSD_STATS |
- SME_PER_STA_STATS,
- hdd_StatisticsCB, 0, FALSE,
- (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], pAdapter );
-
- if (eHAL_STATUS_SUCCESS != status)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: Unable to retrieve SME statistics",
- __func__);
- return -EINVAL;
- }
-
- pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
-
- vos_status = vos_wait_single_event(&pWextState->vosevent, WLAN_WAIT_TIME_STATS);
- if (!VOS_IS_STATUS_SUCCESS(vos_status))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: SME timeout while retrieving statistics",
- __func__);
- /*Remove the SME statistics list by passing NULL in callback argument*/
- status = sme_GetStatistics( pHddCtx->hHal, eCSR_HDD,
- SME_SUMMARY_STATS |
- SME_GLOBAL_CLASSA_STATS |
- SME_GLOBAL_CLASSB_STATS |
- SME_GLOBAL_CLASSC_STATS |
- SME_GLOBAL_CLASSD_STATS |
- SME_PER_STA_STATS,
- NULL, 0, FALSE,
- (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], pAdapter );
-
- return -EINVAL;
- }
- FILL_TLV(p, (tANI_U8)WLAN_STATS_RETRY_CNT,
- (tANI_U8) sizeof (pStats->retry_cnt),
- (char*) &(pStats->retry_cnt[0]),
- tlen);
-
- FILL_TLV(p, (tANI_U8)WLAN_STATS_MUL_RETRY_CNT,
- (tANI_U8) sizeof (pStats->multiple_retry_cnt),
- (char*) &(pStats->multiple_retry_cnt[0]),
- tlen);
-
- FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_FRM_CNT,
- (tANI_U8) sizeof (pStats->tx_frm_cnt),
- (char*) &(pStats->tx_frm_cnt[0]),
- tlen);
-
- FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_FRM_CNT,
- (tANI_U8) sizeof (pStats->rx_frm_cnt),
- (char*) &(pStats->rx_frm_cnt),
- tlen);
-
- FILL_TLV(p, (tANI_U8)WLAN_STATS_FRM_DUP_CNT,
- (tANI_U8) sizeof (pStats->frm_dup_cnt),
- (char*) &(pStats->frm_dup_cnt),
- tlen);
-
- FILL_TLV(p, (tANI_U8)WLAN_STATS_FAIL_CNT,
- (tANI_U8) sizeof (pStats->fail_cnt),
- (char*) &(pStats->fail_cnt[0]),
- tlen);
-
- FILL_TLV(p, (tANI_U8)WLAN_STATS_RTS_FAIL_CNT,
- (tANI_U8) sizeof (pStats->rts_fail_cnt),
- (char*) &(pStats->rts_fail_cnt),
- tlen);
-
- FILL_TLV(p, (tANI_U8)WLAN_STATS_ACK_FAIL_CNT,
- (tANI_U8) sizeof (pStats->ack_fail_cnt),
- (char*) &(pStats->ack_fail_cnt),
- tlen);
-
- FILL_TLV(p, (tANI_U8)WLAN_STATS_RTS_SUC_CNT,
- (tANI_U8) sizeof (pStats->rts_succ_cnt),
- (char*) &(pStats->rts_succ_cnt),
- tlen);
-
- FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_DISCARD_CNT,
- (tANI_U8) sizeof (pStats->rx_discard_cnt),
- (char*) &(pStats->rx_discard_cnt),
- tlen);
-
- FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_ERROR_CNT,
- (tANI_U8) sizeof (pStats->rx_error_cnt),
- (char*) &(pStats->rx_error_cnt),
- tlen);
-
- FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_BYTE_CNT,
- (tANI_U8) sizeof (dStats->tx_uc_byte_cnt[0]),
- (char*) &(dStats->tx_uc_byte_cnt[0]),
- tlen);
-
- FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_BYTE_CNT,
- (tANI_U8) sizeof (dStats->rx_byte_cnt),
- (char*) &(dStats->rx_byte_cnt),
- tlen);
-
- FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_RATE,
- (tANI_U8) sizeof (dStats->rx_rate),
- (char*) &(dStats->rx_rate),
- tlen);
-
- /* Transmit rate, in units of 500 kbit/sec */
- FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_RATE,
- (tANI_U8) sizeof (aStats->tx_rate),
- (char*) &(aStats->tx_rate),
- tlen);
-
- FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_UC_BYTE_CNT,
- (tANI_U8) sizeof (dStats->rx_uc_byte_cnt[0]),
- (char*) &(dStats->rx_uc_byte_cnt[0]),
- tlen);
- FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_MC_BYTE_CNT,
- (tANI_U8) sizeof (dStats->rx_mc_byte_cnt),
- (char*) &(dStats->rx_mc_byte_cnt),
- tlen);
- FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_BC_BYTE_CNT,
- (tANI_U8) sizeof (dStats->rx_bc_byte_cnt),
- (char*) &(dStats->rx_bc_byte_cnt),
- tlen);
- FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_UC_BYTE_CNT,
- (tANI_U8) sizeof (dStats->tx_uc_byte_cnt[0]),
- (char*) &(dStats->tx_uc_byte_cnt[0]),
- tlen);
- FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_MC_BYTE_CNT,
- (tANI_U8) sizeof (dStats->tx_mc_byte_cnt),
- (char*) &(dStats->tx_mc_byte_cnt),
- tlen);
- FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_BC_BYTE_CNT,
- (tANI_U8) sizeof (dStats->tx_bc_byte_cnt),
- (char*) &(dStats->tx_bc_byte_cnt),
- tlen);
-
- wrqu->data.length = tlen;
-
- }
-
- EXIT();
-
- return 0;
-}
-
-
-#ifdef FEATURE_WLAN_SCAN_PNO
-
-/*Max Len for PNO notification*/
-#define MAX_PNO_NOTIFY_LEN 100
-void found_pref_network_cb (void *callbackContext,
- tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
-{
- hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
- union iwreq_data wrqu;
- char buf[MAX_PNO_NOTIFY_LEN+1];
-
- hddLog(VOS_TRACE_LEVEL_WARN, "A preferred network was found: %s with rssi: -%d",
- pPrefNetworkFoundInd->ssId.ssId, pPrefNetworkFoundInd->rssi);
-
- // create the event
- memset(&wrqu, 0, sizeof(wrqu));
- memset(buf, 0, sizeof(buf));
-
- snprintf(buf, MAX_PNO_NOTIFY_LEN, "QCOM: Found preferred network: %s with RSSI of -%u",
- pPrefNetworkFoundInd->ssId.ssId,
- (unsigned int)pPrefNetworkFoundInd->rssi);
-
- wrqu.data.pointer = buf;
- wrqu.data.length = strlen(buf);
-
- // send the event
-
- wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
-
-}
-
-
-/*string based input*/
-VOS_STATUS iw_set_pno(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra, int nOffset)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- /* pnoRequest is a large struct, so we make it static to avoid stack
- overflow. This API is only invoked via ioctl, so it is
- serialized by the kernel rtnl_lock and hence does not need to be
- reentrant */
- static tSirPNOScanReq pnoRequest;
- char *ptr;
- v_U8_t i,j, ucParams, ucMode;
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "PNO data len %d data %s",
- wrqu->data.length,
- extra);
-
- if (wrqu->data.length <= nOffset )
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "PNO input is not correct");
- return VOS_STATUS_E_FAILURE;
- }
-
- pnoRequest.enable = 0;
- pnoRequest.ucNetworksCount = 0;
- /*-----------------------------------------------------------------------
- Input is string based and expected to be like this:
-
- <enabled> <netw_count>
- for each network:
- <ssid_len> <ssid> <authentication> <encryption>
- <ch_num> <channel_list optional> <bcast_type> <rssi_threshold>
- <scan_timers> <scan_time> <scan_repeat> <scan_time> <scan_repeat>
-
- e.g:
- 1 2 4 test 0 0 3 1 6 11 2 40 5 test2 4 4 6 1 2 3 4 5 6 1 0 2 5 2 300 0
-
- this translates into:
- -----------------------------
- enable PNO
- look for 2 networks:
- test - with authentication type 0 and encryption type 0,
- that can be found on 3 channels: 1 6 and 11 ,
- SSID bcast type is unknown (directed probe will be sent if AP not found)
- and must meet -40dBm RSSI
-
- test2 - with auth and enrytption type 4/4
- that can be found on 6 channels 1, 2, 3, 4, 5 and 6
- bcast type is non-bcast (directed probe will be sent)
- and must not meet any RSSI threshold
-
- scan every 5 seconds 2 times, scan every 300 seconds until stopped
- -----------------------------------------------------------------------*/
- ptr = extra + nOffset;
-
- if (1 != sscanf(ptr,"%hhu%n", &(pnoRequest.enable), &nOffset))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "PNO enable input is not valid %s",ptr);
- return VOS_STATUS_E_FAILURE;
- }
-
- if ( 0 == pnoRequest.enable )
- {
- /*Disable PNO*/
- memset(&pnoRequest, 0, sizeof(pnoRequest));
- sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter), &pnoRequest,
- pAdapter->sessionId,
- found_pref_network_cb, pAdapter);
- return VOS_STATUS_SUCCESS;
- }
-
- ptr += nOffset;
-
- if (1 != sscanf(ptr,"%hhu %n", &(pnoRequest.ucNetworksCount), &nOffset))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "PNO count input not valid %s",ptr);
- return VOS_STATUS_E_FAILURE;
-
- }
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "PNO enable %d networks count %d offset %d",
- pnoRequest.enable,
- pnoRequest.ucNetworksCount,
- nOffset);
-
- /* Parameters checking:
- ucNetworksCount has to be larger than 0*/
- if (( 0 == pnoRequest.ucNetworksCount ) ||
- ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Network input is not correct");
- return VOS_STATUS_E_FAILURE;
- }
-
- ptr += nOffset;
-
- for ( i = 0; i < pnoRequest.ucNetworksCount; i++ )
- {
-
- pnoRequest.aNetworks[i].ssId.length = 0;
-
- ucParams = sscanf(ptr,"%hhu %n",
- &(pnoRequest.aNetworks[i].ssId.length),&nOffset);
-
- if (1 != ucParams)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "PNO ssid length input is not valid %s",ptr);
- return VOS_STATUS_E_FAILURE;
- }
-
- if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
- ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "SSID Len %d is not correct for network %d",
- pnoRequest.aNetworks[i].ssId.length, i);
- return VOS_STATUS_E_FAILURE;
- }
-
- /*Advance to SSID*/
- ptr += nOffset;
-
- memcpy(pnoRequest.aNetworks[i].ssId.ssId, ptr,
- pnoRequest.aNetworks[i].ssId.length);
- ptr += pnoRequest.aNetworks[i].ssId.length;
-
- ucParams = sscanf(ptr,"%u %u %hhu %n",
- &(pnoRequest.aNetworks[i].authentication),
- &(pnoRequest.aNetworks[i].encryption),
- &(pnoRequest.aNetworks[i].ucChannelCount),
- &nOffset);
-
- if ( 3 != ucParams )
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
- "Incorrect cmd %s",ptr);
- return VOS_STATUS_E_FAILURE;
- }
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "PNO len %d ssid 0x%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx"
- "auth %d encry %d channel count %d offset %d",
- pnoRequest.aNetworks[i].ssId.length,
- *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[0]),
- *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[4]),
- *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[8]),
- *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[12]),
- *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[16]),
- *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[20]),
- *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[24]),
- *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[28]),
- pnoRequest.aNetworks[i].authentication,
- pnoRequest.aNetworks[i].encryption,
- pnoRequest.aNetworks[i].ucChannelCount,
- nOffset );
-
- /*Advance to channel list*/
- ptr += nOffset;
-
- if (SIR_PNO_MAX_NETW_CHANNELS < pnoRequest.aNetworks[i].ucChannelCount)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
- "Incorrect number of channels");
- return VOS_STATUS_E_FAILURE;
- }
-
- if ( 0 != pnoRequest.aNetworks[i].ucChannelCount)
- {
- for ( j = 0; j < pnoRequest.aNetworks[i].ucChannelCount; j++)
- {
- if (1 != sscanf(ptr,"%hhu %n",
- &(pnoRequest.aNetworks[i].aChannels[j]),
- &nOffset))
- { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "PNO network channel input is not valid %s",ptr);
- return VOS_STATUS_E_FAILURE;
- }
- /*Advance to next channel number*/
- ptr += nOffset;
- }
- }
-
- if (1 != sscanf(ptr,"%u %n",
- &(pnoRequest.aNetworks[i].bcastNetwType),
- &nOffset))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "PNO broadcast network type input is not valid %s",ptr);
- return VOS_STATUS_E_FAILURE;
- }
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "PNO bcastNetwType %d offset %d",
- pnoRequest.aNetworks[i].bcastNetwType,
- nOffset );
-
- /*Advance to rssi Threshold*/
- ptr += nOffset;
-
- if (1 != sscanf(ptr,"%d %n",
- &(pnoRequest.aNetworks[i].rssiThreshold),
- &nOffset))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "PNO rssi threshold input is not valid %s",ptr);
- return VOS_STATUS_E_FAILURE;
- }
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "PNO rssi %d offset %d",
- pnoRequest.aNetworks[i].rssiThreshold,
- nOffset );
- /*Advance to next network*/
- ptr += nOffset;
- }/*For ucNetworkCount*/
-
- ucParams = sscanf(ptr,"%hhu %n",
- &(pnoRequest.scanTimers.ucScanTimersCount),
- &nOffset);
-
- /*Read the scan timers*/
- if (( 1 == ucParams ) && ( pnoRequest.scanTimers.ucScanTimersCount > 0 ))
- {
- ptr += nOffset;
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "Scan timer count %d offset %d",
- pnoRequest.scanTimers.ucScanTimersCount,
- nOffset );
-
- if ( SIR_PNO_MAX_SCAN_TIMERS < pnoRequest.scanTimers.ucScanTimersCount )
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "Incorrect cmd - too many scan timers");
- return VOS_STATUS_E_FAILURE;
- }
-
- for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++ )
- {
- ucParams = sscanf(ptr,"%u %u %n",
- &(pnoRequest.scanTimers.aTimerValues[i].uTimerValue),
- &( pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat),
- &nOffset);
-
- if (2 != ucParams)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "Incorrect cmd - diff params then expected %d", ucParams);
- return VOS_STATUS_E_FAILURE;
- }
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "PNO Timer value %d Timer repeat %d offset %d",
- pnoRequest.scanTimers.aTimerValues[i].uTimerValue,
- pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat,
- nOffset );
-
- ptr += nOffset;
- }
-
- }
- else
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "No scan timers provided param count %d scan timers %d",
- ucParams, pnoRequest.scanTimers.ucScanTimersCount );
-
- /*Scan timers defaults to 5 minutes*/
- pnoRequest.scanTimers.ucScanTimersCount = 1;
- pnoRequest.scanTimers.aTimerValues[0].uTimerValue = 60;
- pnoRequest.scanTimers.aTimerValues[0].uTimerRepeat = 0;
- }
-
- ucParams = sscanf(ptr,"%hhu %n",&(ucMode), &nOffset);
-
- pnoRequest.modePNO = ucMode;
- /*for LA we just expose suspend option*/
- if (( 1 != ucParams )||( ucMode >= SIR_PNO_MODE_MAX ))
- {
- pnoRequest.modePNO = SIR_PNO_MODE_ON_SUSPEND;
- }
-
- sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter), &pnoRequest,
- pAdapter->sessionId,
- found_pref_network_cb, pAdapter);
-
- return VOS_STATUS_SUCCESS;
-}/*iw_set_pno*/
-
-VOS_STATUS iw_set_rssi_filter(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra, int nOffset)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- v_U8_t rssiThreshold = 0;
- v_U8_t nRead;
-
- nRead = sscanf(extra + nOffset,"%hhu",
- &rssiThreshold);
-
- if ( 1 != nRead )
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
- "Incorrect format");
- return VOS_STATUS_E_FAILURE;
- }
-
- sme_SetRSSIFilter(WLAN_HDD_GET_HAL_CTX(pAdapter), rssiThreshold);
- return VOS_STATUS_SUCCESS;
-}
-
-
-static int iw_set_pno_priv(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "Set PNO Private");
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
- return iw_set_pno(dev,info,wrqu,extra,0);
-}
-#endif /*FEATURE_WLAN_SCAN_PNO*/
-
-//Common function to SetBand
-int hdd_setBand_helper(struct net_device *dev, tANI_U8* ptr)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- tANI_U8 band = 0;
- eCsrBand currBand = eCSR_BAND_MAX;
-
- band = ptr[WLAN_HDD_UI_SET_BAND_VALUE_OFFSET] - '0'; /*convert the band value from ascii to integer*/
-
- switch(band)
- {
- case WLAN_HDD_UI_BAND_AUTO:
- band = eCSR_BAND_ALL;
- break;
- case WLAN_HDD_UI_BAND_5_GHZ:
- band = eCSR_BAND_5G;
- break;
- case WLAN_HDD_UI_BAND_2_4_GHZ:
- band = eCSR_BAND_24;
- break;
- default:
- band = eCSR_BAND_MAX;
- }
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: change band to %u",
- __func__, band);
-
- if (band == eCSR_BAND_MAX)
- {
- /* Received change band request with invalid band value */
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "%s: Invalid band value %u", __func__, band);
- return -EIO;
- }
-
- if ( (band == eCSR_BAND_24 && pHddCtx->cfg_ini->nBandCapability==2) ||
- (band == eCSR_BAND_5G && pHddCtx->cfg_ini->nBandCapability==1) ||
- (band == eCSR_BAND_ALL && pHddCtx->cfg_ini->nBandCapability!=0))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "%s: band value %u violate INI settings %u", __func__,
- band, pHddCtx->cfg_ini->nBandCapability);
- return -EIO;
- }
-
- if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &currBand))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "%s: Failed to get current band config",
- __func__);
- return -EIO;
- }
-
- if (currBand != band)
- {
- /* Change band request received.
- * Abort pending scan requests, flush the existing scan results,
- * and change the band capability
- */
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "%s: Current band value = %u, new setting %u ",
- __func__, currBand, band);
-
- if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
- {
- hdd_station_ctx_t *pHddStaCtx = &(pAdapter)->sessionCtx.station;
- eHalStatus status = eHAL_STATUS_SUCCESS;
- long lrc;
-
- /* STA already connected on current band, So issue disconnect first,
- * then change the band*/
-
- hddLog(VOS_TRACE_LEVEL_INFO,
- "%s STA connected in band %u, Changing band to %u, Issuing Disconnect",
- __func__, csrGetCurrentBand(hHal), band);
-
- pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
- INIT_COMPLETION(pAdapter->disconnect_comp_var);
-
- status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
- pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
-
- if ( eHAL_STATUS_SUCCESS != status)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s csrRoamDisconnect failure, returned %d \n",
- __func__, (int)status );
- return -EINVAL;
- }
-
- lrc = wait_for_completion_interruptible_timeout(
- &pAdapter->disconnect_comp_var,
- msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
-
- if (lrc <= 0) {
-
- hddLog(VOS_TRACE_LEVEL_ERROR,"%s: %s while waiting for csrRoamDisconnect ",
- __func__, (0 == lrc) ? "Timeout" : "Interrupt");
-
- return (0 == lrc) ? -ETIMEDOUT : -EINTR;
- }
- }
-
- hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId);
- sme_ScanFlushResult(hHal, pAdapter->sessionId);
-#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
- sme_UpdateBgScanConfigIniChannelList(hHal, (eCsrBand) band);
-#endif
- if (eHAL_STATUS_SUCCESS != sme_SetFreqBand(hHal, (eCsrBand)band))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s: failed to set the band value to %u ",
- __func__, band);
- return -EINVAL;
- }
- wlan_hdd_cfg80211_update_band(pHddCtx->wiphy, (eCsrBand)band);
- }
- return 0;
-}
-
-static int iw_set_band_config(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tANI_U8 *ptr = extra;
- int ret = 0;
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: ", __func__);
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- if (memcmp(ptr, "SETBAND ", 8) == 0)
- {
- /* Change band request received */
- ret = hdd_setBand_helper(dev, ptr);
- return ret;
-
- }
- return 0;
-}
-
-static int iw_set_power_params_priv(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "Set power params Private");
- return iw_set_power_params(dev,info,wrqu,extra,0);
-}
-
-
-
-/*string based input*/
-VOS_STATUS iw_set_power_params(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra, int nOffset)
-{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tSirSetPowerParamsReq powerRequest;
- char *ptr;
- v_U8_t ucType;
- v_U32_t uTotalSize, uValue;
- /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "Power Params data len %d data %s",
- wrqu->data.length,
- extra);
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EBUSY;
- }
-
- if (wrqu->data.length <= nOffset )
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "set power param input is not correct");
- return VOS_STATUS_E_FAILURE;
- }
-
- uTotalSize = wrqu->data.length - nOffset;
-
- /*-----------------------------------------------------------------------
- Input is string based and expected to be like this:
-
- <param_type> <param_value> <param_type> <param_value> ...
-
- e.g:
- 1 2 2 3 3 0 4 1 5 1
-
- e.g. setting just a few:
- 1 2 4 1
-
- parameter types:
- -----------------------------
- 1 - Ignore DTIM
- 2 - Listen Interval
- 3 - Broadcast Multicas Filter
- 4 - Beacon Early Termination
- 5 - Beacon Early Termination Interval
- -----------------------------------------------------------------------*/
- powerRequest.uIgnoreDTIM = SIR_NOCHANGE_POWER_VALUE;
- powerRequest.uListenInterval = SIR_NOCHANGE_POWER_VALUE;
- powerRequest.uBcastMcastFilter = SIR_NOCHANGE_POWER_VALUE;
- powerRequest.uEnableBET = SIR_NOCHANGE_POWER_VALUE;
- powerRequest.uBETInterval = SIR_NOCHANGE_POWER_VALUE;
-
- ptr = extra + nOffset;
-
- while ( uTotalSize )
- {
- if (1 != sscanf(ptr,"%hhu %n", &(ucType), &nOffset))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "Invalid input parameter type %s",ptr);
- return VOS_STATUS_E_FAILURE;
- }
-
- uTotalSize -= nOffset;
-
- if (!uTotalSize)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "Invalid input parameter type : %d with no value at offset %d",
- ucType, nOffset);
- return VOS_STATUS_E_FAILURE;
- }
-
- ptr += nOffset;
-
- if (1 != sscanf(ptr,"%u %n", &(uValue), &nOffset))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "Invalid input parameter value %s",ptr);
- return VOS_STATUS_E_FAILURE;
- }
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "Power request parameter %d value %d offset %d",
- ucType, uValue, nOffset);
-
- switch (ucType)
- {
- case eSIR_IGNORE_DTIM:
- powerRequest.uIgnoreDTIM = uValue;
- break;
- case eSIR_LISTEN_INTERVAL:
- powerRequest.uListenInterval = uValue;
- break;
- case eSIR_MCAST_BCAST_FILTER:
- powerRequest.uBcastMcastFilter = uValue;
- break;
- case eSIR_ENABLE_BET:
- powerRequest.uEnableBET = uValue;
- break;
- case eSIR_BET_INTERVAL:
- powerRequest.uBETInterval = uValue;
- break;
- default:
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "Invalid input parameter type : %d with value: %d at offset %d",
- ucType, uValue, nOffset);
- return VOS_STATUS_E_FAILURE;
- }
-
- uTotalSize -= nOffset;
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "Power request parameter %d Total size",
- uTotalSize);
- ptr += nOffset;
- /* This is added for dynamic Tele LI enable (0xF1) /disable (0xF0)*/
- if(!(uTotalSize - nOffset) &&
- (powerRequest.uListenInterval != SIR_NOCHANGE_POWER_VALUE))
- {
- uTotalSize = 0;
- }
-
- }/*Go for as long as we have a valid string*/
-
- /* put the device into full power*/
- wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
-
- /* Apply the power save params*/
- sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE);
-
- /* put the device back to power save*/
- wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
-
- return VOS_STATUS_SUCCESS;
-}/*iw_set_power_params*/
-
-
-// Define the Wireless Extensions to the Linux Network Device structure
-// A number of these routines are NULL (meaning they are not implemented.)
-
-static const iw_handler we_handler[] =
-{
- (iw_handler) iw_set_commit, /* SIOCSIWCOMMIT */
- (iw_handler) iw_get_name, /* SIOCGIWNAME */
- (iw_handler) NULL, /* SIOCSIWNWID */
- (iw_handler) NULL, /* SIOCGIWNWID */
- (iw_handler) iw_set_freq, /* SIOCSIWFREQ */
- (iw_handler) iw_get_freq, /* SIOCGIWFREQ */
- (iw_handler) iw_set_mode, /* SIOCSIWMODE */
- (iw_handler) iw_get_mode, /* SIOCGIWMODE */
- (iw_handler) NULL, /* SIOCSIWSENS */
- (iw_handler) NULL, /* SIOCGIWSENS */
- (iw_handler) NULL, /* SIOCSIWRANGE */
- (iw_handler) iw_get_range, /* SIOCGIWRANGE */
- (iw_handler) iw_set_priv, /* SIOCSIWPRIV */
- (iw_handler) NULL, /* SIOCGIWPRIV */
- (iw_handler) NULL, /* SIOCSIWSTATS */
- (iw_handler) NULL, /* SIOCGIWSTATS */
- iw_handler_set_spy, /* SIOCSIWSPY */
- iw_handler_get_spy, /* SIOCGIWSPY */
- iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
- iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
- (iw_handler) iw_set_ap_address, /* SIOCSIWAP */
- (iw_handler) iw_get_ap_address, /* SIOCGIWAP */
- (iw_handler) iw_set_mlme, /* SIOCSIWMLME */
- (iw_handler) NULL, /* SIOCGIWAPLIST */
- (iw_handler) iw_set_scan, /* SIOCSIWSCAN */
- (iw_handler) iw_get_scan, /* SIOCGIWSCAN */
- (iw_handler) iw_set_essid, /* SIOCSIWESSID */
- (iw_handler) iw_get_essid, /* SIOCGIWESSID */
- (iw_handler) iw_set_nick, /* SIOCSIWNICKN */
- (iw_handler) iw_get_nick, /* SIOCGIWNICKN */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) iw_set_bitrate, /* SIOCSIWRATE */
- (iw_handler) iw_get_bitrate, /* SIOCGIWRATE */
- (iw_handler) iw_set_rts_threshold,/* SIOCSIWRTS */
- (iw_handler) iw_get_rts_threshold,/* SIOCGIWRTS */
- (iw_handler) iw_set_frag_threshold, /* SIOCSIWFRAG */
- (iw_handler) iw_get_frag_threshold, /* SIOCGIWFRAG */
- (iw_handler) iw_set_tx_power, /* SIOCSIWTXPOW */
- (iw_handler) iw_get_tx_power, /* SIOCGIWTXPOW */
- (iw_handler) iw_set_retry, /* SIOCSIWRETRY */
- (iw_handler) iw_get_retry, /* SIOCGIWRETRY */
- (iw_handler) iw_set_encode, /* SIOCSIWENCODE */
- (iw_handler) iw_get_encode, /* SIOCGIWENCODE */
- (iw_handler) iw_set_power_mode, /* SIOCSIWPOWER */
- (iw_handler) iw_get_power_mode, /* SIOCGIWPOWER */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) iw_set_genie, /* SIOCSIWGENIE */
- (iw_handler) iw_get_genie, /* SIOCGIWGENIE */
- (iw_handler) iw_set_auth, /* SIOCSIWAUTH */
- (iw_handler) iw_get_auth, /* SIOCGIWAUTH */
- (iw_handler) iw_set_encodeext, /* SIOCSIWENCODEEXT */
- (iw_handler) iw_get_encodeext, /* SIOCGIWENCODEEXT */
- (iw_handler) NULL, /* SIOCSIWPMKSA */
-};
-
-static const iw_handler we_private[] = {
-
- [WLAN_PRIV_SET_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_setint_getnone, //set priv ioctl
- [WLAN_PRIV_SET_NONE_GET_INT - SIOCIWFIRSTPRIV] = iw_setnone_getint, //get priv ioctl
- [WLAN_PRIV_SET_CHAR_GET_NONE - SIOCIWFIRSTPRIV] = iw_setchar_getnone, //get priv ioctl
- [WLAN_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
- [WLAN_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] = iw_get_char_setnone,
- [WLAN_PRIV_SET_NONE_GET_NONE - SIOCIWFIRSTPRIV] = iw_setnone_getnone, //action priv ioctl
- [WLAN_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
- [WLAN_PRIV_ADD_TSPEC - SIOCIWFIRSTPRIV] = iw_add_tspec,
- [WLAN_PRIV_DEL_TSPEC - SIOCIWFIRSTPRIV] = iw_del_tspec,
- [WLAN_PRIV_GET_TSPEC - SIOCIWFIRSTPRIV] = iw_get_tspec,
-#ifdef FEATURE_OEM_DATA_SUPPORT
- [WLAN_PRIV_SET_OEM_DATA_REQ - SIOCIWFIRSTPRIV] = iw_set_oem_data_req, //oem data req Specifc
- [WLAN_PRIV_GET_OEM_DATA_RSP - SIOCIWFIRSTPRIV] = iw_get_oem_data_rsp, //oem data req Specifc
-#endif
-
-#ifdef FEATURE_WLAN_WAPI
- [WLAN_PRIV_SET_WAPI_MODE - SIOCIWFIRSTPRIV] = iw_qcom_set_wapi_mode,
- [WLAN_PRIV_GET_WAPI_MODE - SIOCIWFIRSTPRIV] = iw_qcom_get_wapi_mode,
- [WLAN_PRIV_SET_WAPI_ASSOC_INFO - SIOCIWFIRSTPRIV] = iw_qcom_set_wapi_assoc_info,
- [WLAN_PRIV_SET_WAPI_KEY - SIOCIWFIRSTPRIV] = iw_qcom_set_wapi_key,
- [WLAN_PRIV_SET_WAPI_BKID - SIOCIWFIRSTPRIV] = iw_qcom_set_wapi_bkid,
- [WLAN_PRIV_GET_WAPI_BKID - SIOCIWFIRSTPRIV] = iw_qcom_get_wapi_bkid,
-#endif /* FEATURE_WLAN_WAPI */
-#ifdef WLAN_FEATURE_VOWIFI_11R
- [WLAN_PRIV_SET_FTIES - SIOCIWFIRSTPRIV] = iw_set_fties,
-#endif
- [WLAN_PRIV_SET_HOST_OFFLOAD - SIOCIWFIRSTPRIV] = iw_set_host_offload,
- [WLAN_GET_WLAN_STATISTICS - SIOCIWFIRSTPRIV] = iw_get_statistics,
- [WLAN_SET_KEEPALIVE_PARAMS - SIOCIWFIRSTPRIV] = iw_set_keepalive_params
-#ifdef WLAN_FEATURE_PACKET_FILTERING
- ,
- [WLAN_SET_PACKET_FILTER_PARAMS - SIOCIWFIRSTPRIV] = iw_set_packet_filter_params
-#endif
-#ifdef FEATURE_WLAN_SCAN_PNO
- ,
- [WLAN_SET_PNO - SIOCIWFIRSTPRIV] = iw_set_pno_priv
-#endif
- ,
- [WLAN_SET_BAND_CONFIG - SIOCIWFIRSTPRIV] = iw_set_band_config,
- [WLAN_PRIV_SET_MCBC_FILTER - SIOCIWFIRSTPRIV] = iw_set_dynamic_mcbc_filter,
- [WLAN_PRIV_CLEAR_MCBC_FILTER - SIOCIWFIRSTPRIV] = iw_clear_dynamic_mcbc_filter,
- [WLAN_SET_POWER_PARAMS - SIOCIWFIRSTPRIV] = iw_set_power_params_priv,
-#ifdef FEATURE_OEM_DATA_SUPPORT
-#ifdef QCA_WIFI_2_0
- [WLAN_PRIV_GET_OEM_DATA_CAP - SIOCIWFIRSTPRIV] = iw_get_oem_data_cap,
-#endif
-#endif
- [WLAN_GET_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_linkspeed,
-};
-
-/*Maximum command length can be only 15 */
-static const struct iw_priv_args we_private_args[] = {
-
- { WE_ENABLE_STRICT_FCC_REG,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "setStrictFCCreg" },
-
- /* handlers for main ioctl */
- { WLAN_PRIV_SET_INT_GET_NONE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "" },
-
- /* handlers for sub-ioctl */
- { WE_SET_11D_STATE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "set11Dstate" },
-
- { WE_WOWL,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "wowl" },
-
- { WE_SET_POWER,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "setPower" },
-
- { WE_SET_MAX_ASSOC,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "setMaxAssoc" },
-
- { WE_SET_SAP_AUTO_CHANNEL_SELECTION,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "setAutoChannel" },
-
- { WE_SET_DATA_INACTIVITY_TO,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "inactivityTO" },
-
- { WE_SET_MAX_TX_POWER,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "setMaxTxPower" },
-
- { WE_SET_MAX_TX_POWER_2_4,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "setTxMaxPower2G" },
-
- { WE_SET_MAX_TX_POWER_5_0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "setTxMaxPower5G" },
-
- /* SAP has TxMax whereas STA has MaxTx, adding TxMax for STA
- * as well to keep same syntax as in SAP. Now onwards, STA
- * will support both */
- { WE_SET_MAX_TX_POWER,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "setTxMaxPower" },
-
- /* set Higher DTIM Transition (DTIM1 to DTIM3)
- * 1 = enable and 0 = disable */
- {
- WE_SET_HIGHER_DTIM_TRANSITION,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "setHDtimTransn" },
-
- { WE_SET_TM_LEVEL,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "setTmLevel" },
-
-#ifdef QCA_WIFI_2_0
- { WE_SET_PHYMODE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "setphymode" },
-
- { WE_SET_NSS,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "nss" },
-
- { WE_SET_LDPC,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "ldpc" },
-
- { WE_SET_TX_STBC,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "tx_stbc" },
-
- { WE_SET_RX_STBC,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "rx_stbc" },
-
- { WE_SET_SHORT_GI,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "shortgi" },
-
- { WE_SET_RTSCTS,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "enablertscts" },
-
- { WE_SET_CHWIDTH,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "chwidth" },
-
- { WE_SET_ANI_EN_DIS,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "anienable" },
-
- { WE_SET_ANI_POLL_PERIOD,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "aniplen" },
-
- { WE_SET_ANI_LISTEN_PERIOD,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "anilislen" },
-
- { WE_SET_ANI_OFDM_LEVEL,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "aniofdmlvl" },
-
- { WE_SET_ANI_CCK_LEVEL,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "aniccklvl" },
-
- { WE_SET_DYNAMIC_BW,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "cwmenable" },
-
- { WE_SET_TX_CHAINMASK,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "txchainmask" },
-
- { WE_SET_RX_CHAINMASK,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "rxchainmask" },
-
- { WE_SET_11N_RATE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "set11NRates" },
-
- { WE_SET_VHT_RATE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "set11ACRates" },
-
- { WE_SET_AMPDU,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "ampdu" },
-
- { WE_SET_AMSDU,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "amsdu" },
-
- { WE_SET_TXPOW_2G,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "txpow2g" },
-
- { WE_SET_TXPOW_5G,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "txpow5g" },
-
- { WE_SET_POWER_GATING,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "pwrgating" },
-
- /* Sub-cmds DBGLOG specific commands */
- { WE_DBGLOG_LOG_LEVEL ,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "dl_loglevel" },
-
- { WE_DBGLOG_VAP_ENABLE ,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "dl_vapon" },
-
- { WE_DBGLOG_VAP_DISABLE ,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "dl_vapoff" },
-
- { WE_DBGLOG_MODULE_ENABLE ,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "dl_modon" },
-
- { WE_DBGLOG_MODULE_DISABLE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "dl_modoff" },
-
- { WE_DBGLOG_MOD_LOG_LEVEL,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "dl_mod_loglevel" },
-
- { WE_DBGLOG_TYPE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "dl_type" },
- { WE_DBGLOG_REPORT_ENABLE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "dl_report" },
-
- { WE_SET_TXRX_FWSTATS,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "txrx_fw_stats" },
-
- { WE_TXRX_FWSTATS_RESET,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "txrx_fw_st_rst" },
-
- { WE_PPS_PAID_MATCH,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0, "paid_match" },
-
-
- { WE_PPS_GID_MATCH,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0, "gid_match" },
-
-
- { WE_PPS_EARLY_TIM_CLEAR,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0, "tim_clear" },
-
-
- { WE_PPS_EARLY_DTIM_CLEAR,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0, "dtim_clear" },
-
-
- { WE_PPS_EOF_PAD_DELIM,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0, "eof_delim" },
-
-
- { WE_PPS_MACADDR_MISMATCH,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0, "mac_match" },
-
-
- { WE_PPS_DELIM_CRC_FAIL,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0, "delim_fail" },
-
-
- { WE_PPS_GID_NSTS_ZERO,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0, "nsts_zero" },
-
-
- { WE_PPS_RSSI_CHECK,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0, "rssi_chk" },
-#endif
-
- { WLAN_PRIV_SET_NONE_GET_INT,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "" },
-
- /* handlers for sub-ioctl */
- { WE_GET_11D_STATE,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get11Dstate" },
-
- { WE_IBSS_STATUS,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "getAdhocStatus" },
-
- { WE_PMC_STATE,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "pmcState" },
-
- { WE_GET_WLAN_DBG,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "getwlandbg" },
-
- { WE_MODULE_DOWN_IND,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "moduleDownInd" },
-
- { WE_GET_MAX_ASSOC,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "getMaxAssoc" },
-
- { WE_GET_WDI_DBG,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "getwdidbg" },
-
- { WE_GET_SAP_AUTO_CHANNEL_SELECTION,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "getAutoChannel" },
-
- { WE_GET_CONCURRENCY_MODE,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "getconcurrency" },
-
-#ifdef QCA_WIFI_2_0
- { WE_GET_NSS,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_nss" },
-
- { WE_GET_LDPC,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_ldpc" },
-
- { WE_GET_TX_STBC,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_tx_stbc" },
-
- { WE_GET_RX_STBC,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_rx_stbc" },
-
- { WE_GET_SHORT_GI,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_shortgi" },
-
- { WE_GET_RTSCTS,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_rtscts" },
-
- { WE_GET_CHWIDTH,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_chwidth" },
-
- { WE_GET_ANI_EN_DIS,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_anienable" },
-
- { WE_GET_ANI_POLL_PERIOD,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_aniplen" },
-
- { WE_GET_ANI_LISTEN_PERIOD,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_anilislen" },
-
- { WE_GET_ANI_OFDM_LEVEL,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_aniofdmlvl" },
-
- { WE_GET_ANI_CCK_LEVEL,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_aniccklvl" },
-
- { WE_GET_DYNAMIC_BW,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_cwmenable" },
-
- { WE_GET_TX_CHAINMASK,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_txchainmask" },
-
- { WE_GET_RX_CHAINMASK,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_rxchainmask" },
-
- { WE_GET_11N_RATE,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_11nrate" },
-
- { WE_GET_AMPDU,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_ampdu" },
-
- { WE_GET_AMSDU,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_amsdu" },
-
- { WE_GET_TXPOW_2G,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_txpow2g" },
-
- { WE_GET_TXPOW_5G,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_txpow5g" },
-
- { WE_GET_POWER_GATING,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_pwrgating" },
-
- { WE_GET_PPS_PAID_MATCH,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_paid_match"},
-
-
- { WE_GET_PPS_GID_MATCH,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_gid_match"},
-
-
- { WE_GET_PPS_EARLY_TIM_CLEAR,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_tim_clear"},
-
-
- { WE_GET_PPS_EARLY_DTIM_CLEAR,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_dtim_clear"},
-
-
- { WE_GET_PPS_EOF_PAD_DELIM,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_eof_delim"},
-
-
- { WE_GET_PPS_MACADDR_MISMATCH,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_mac_match"},
-
-
- { WE_GET_PPS_DELIM_CRC_FAIL,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_delim_fail"},
-
-
- { WE_GET_PPS_GID_NSTS_ZERO,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_nsts_zero"},
-
-
- { WE_GET_PPS_RSSI_CHECK,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_rssi_chk"},
-#endif
-
- /* handlers for main ioctl */
- { WLAN_PRIV_SET_CHAR_GET_NONE,
- IW_PRIV_TYPE_CHAR| 512,
- 0,
- "" },
-
- /* handlers for sub-ioctl */
- { WE_WOWL_ADD_PTRN,
- IW_PRIV_TYPE_CHAR| 512,
- 0,
- "wowlAddPtrn" },
-
- { WE_WOWL_DEL_PTRN,
- IW_PRIV_TYPE_CHAR| 512,
- 0,
- "wowlDelPtrn" },
-
-#if defined WLAN_FEATURE_VOWIFI
- /* handlers for sub-ioctl */
- { WE_NEIGHBOR_REPORT_REQUEST,
- IW_PRIV_TYPE_CHAR | 512,
- 0,
- "neighbor" },
-#endif
- { WE_SET_AP_WPS_IE,
- IW_PRIV_TYPE_CHAR| 512,
- 0,
- "set_ap_wps_ie" },
-
- { WE_SET_CONFIG,
- IW_PRIV_TYPE_CHAR| 512,
- 0,
- "setConfig" },
-
- /* handlers for main ioctl */
- { WLAN_PRIV_SET_THREE_INT_GET_NONE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
- 0,
- "" },
-
- /* handlers for sub-ioctl */
- { WE_SET_WLAN_DBG,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
- 0,
- "setwlandbg" },
-
- { WE_SET_WDI_DBG,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
- 0,
- "setwdidbg" },
-
- { WE_SET_SAP_CHANNELS,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
- 0,
- "setsapchannels" },
-
- /* handlers for main ioctl */
- { WLAN_PRIV_GET_CHAR_SET_NONE,
- 0,
- IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
- "" },
-
- /* handlers for sub-ioctl */
- { WE_WLAN_VERSION,
- 0,
- IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
- "version" },
- { WE_GET_STATS,
- 0,
- IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
- "getStats" },
- { WE_GET_STATES,
- 0,
- IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
- "getHostStates" },
- { WE_GET_CFG,
- 0,
- IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
- "getConfig" },
-#ifdef WLAN_FEATURE_11AC
- { WE_GET_RSSI,
- 0,
- IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
- "getRSSI" },
-#endif
-#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_CCX || defined(FEATURE_WLAN_LFR)
- { WE_GET_ROAM_RSSI,
- 0,
- IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
- "getRoamRSSI" },
-#endif
- { WE_GET_WMM_STATUS,
- 0,
- IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
- "getWmmStatus" },
- {
- WE_GET_CHANNEL_LIST,
- 0,
- IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
- "getChannelList" },
-#ifdef FEATURE_WLAN_TDLS
- {
- WE_GET_TDLS_PEERS,
- 0,
- IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
- "getTdlsPeers" },
-#endif
-#ifdef WLAN_FEATURE_11W
- {
- WE_GET_11W_INFO,
- 0,
- IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
- "getPMFInfo" },
-#endif
-#ifdef FEATURE_CESIUM_PROPRIETARY
- {
- WE_GET_IBSS_STA_INFO,
- 0,
- IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
- "getIbssSTAs" },
-#endif
-#ifdef QCA_WIFI_2_0
- { WE_GET_PHYMODE,
- 0,
- IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
- "getphymode" },
-#endif
-
- /* handlers for main ioctl */
- { WLAN_PRIV_SET_NONE_GET_NONE,
- 0,
- 0,
- "" },
-
- /* handlers for sub-ioctl */
- { WE_CLEAR_STATS,
- 0,
- 0,
- "clearStats" },
- { WE_INIT_AP,
- 0,
- 0,
- "initAP" },
-#ifdef FEATURE_CESIUM_PROPRIETARY
- {
- WE_IBSS_GET_PEER_INFO_ALL,
- 0,
- 0,
- "ibssPeerInfoAll" },
-#endif
- { WE_STOP_AP,
- 0,
- 0,
- "exitAP" },
- { WE_ENABLE_AMP,
- 0,
- 0,
- "enableAMP" },
- { WE_DISABLE_AMP,
- 0,
- 0,
- "disableAMP" },
- { WE_ENABLE_DXE_STALL_DETECT,
- 0,
- 0,
- "dxeStallDetect" },
- { WE_DISPLAY_DXE_SNAP_SHOT,
- 0,
- 0,
- "dxeSnapshot" },
- { WE_DISPLAY_DATAPATH_SNAP_SHOT,
- 0,
- 0,
- "dataSnapshot"},
- {
- WE_SET_REASSOC_TRIGGER,
- 0,
- 0,
- "reassoc" },
-#ifdef QCA_WIFI_2_0
- { WE_DUMP_AGC_START,
- 0,
- 0,
- "dump_agc_start" },
-
- { WE_DUMP_AGC,
- 0,
- 0,
- "dump_agc" },
-
- { WE_DUMP_CHANINFO_START,
- 0,
- 0,
- "dump_chninfo_en" },
-
- { WE_DUMP_CHANINFO,
- 0,
- 0,
- "dump_chninfo" },
-
- { WE_DUMP_WATCHDOG,
- 0,
- 0,
- "dump_watchdog" },
-#ifdef DEBUG
- { WE_SET_FW_CRASH_INJECT,
- 0,
- 0,
- "crash_inject" },
-#endif
-#endif
- /* handlers for main ioctl */
- { WLAN_PRIV_SET_VAR_INT_GET_NONE,
- IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
- 0,
- "" },
-
- /* handlers for sub-ioctl */
- { WE_LOG_DUMP_CMD,
- IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
- 0,
- "dump" },
-#ifdef FEATURE_CESIUM_PROPRIETARY
- { WE_IBSS_GET_PEER_INFO,
- IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
- 0,
- "ibssPeerInfo" },
-#endif
- /* handlers for sub ioctl */
- {
- WE_MCC_CONFIG_CREDENTIAL,
- IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
- 0,
- "setMccCrdnl" },
-
- /* handlers for sub ioctl */
- {
- WE_MCC_CONFIG_PARAMS,
- IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
- 0,
- "setMccConfig" },
-
-#ifdef FEATURE_WLAN_TDLS
- /* handlers for sub ioctl */
- {
- WE_TDLS_CONFIG_PARAMS,
- IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
- 0,
- "setTdlsConfig" },
-#endif
-
- /* handlers for main ioctl */
- { WLAN_PRIV_ADD_TSPEC,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | HDD_WLAN_WMM_PARAM_COUNT,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "addTspec" },
-
- /* handlers for main ioctl */
- { WLAN_PRIV_DEL_TSPEC,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "delTspec" },
-
- /* handlers for main ioctl */
- { WLAN_PRIV_GET_TSPEC,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "getTspec" },
-
-#ifdef FEATURE_OEM_DATA_SUPPORT
- /* handlers for main ioctl - OEM DATA */
- {
- WLAN_PRIV_SET_OEM_DATA_REQ,
- IW_PRIV_TYPE_BYTE | sizeof(struct iw_oem_data_req) | IW_PRIV_SIZE_FIXED,
- 0,
- "set_oem_data_req" },
-
- /* handlers for main ioctl - OEM DATA */
- {
- WLAN_PRIV_GET_OEM_DATA_RSP,
- 0,
- IW_PRIV_TYPE_BYTE | MAX_OEM_DATA_RSP_LEN,
- "get_oem_data_rsp" },
-#endif
-
-#ifdef FEATURE_WLAN_WAPI
- /* handlers for main ioctl SET_WAPI_MODE */
- { WLAN_PRIV_SET_WAPI_MODE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0,
- "SET_WAPI_MODE" },
-
- /* handlers for main ioctl GET_WAPI_MODE */
- { WLAN_PRIV_GET_WAPI_MODE,
- 0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "GET_WAPI_MODE" },
-
- /* handlers for main ioctl SET_ASSOC_INFO */
- { WLAN_PRIV_SET_WAPI_ASSOC_INFO,
- IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 400,
- 0,
- "SET_WAPI_ASSOC" },
-
- /* handlers for main ioctl SET_WAPI_KEY */
- { WLAN_PRIV_SET_WAPI_KEY,
- IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 71,
- 0,
- "SET_WAPI_KEY" },
-
- /* handlers for main ioctl SET_WAPI_BKID */
- { WLAN_PRIV_SET_WAPI_BKID,
- IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 24,
- 0,
- "SET_WAPI_BKID" },
-
- /* handlers for main ioctl GET_WAPI_BKID */
- { WLAN_PRIV_GET_WAPI_BKID,
- 0,
- IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 24,
- "GET_WAPI_BKID" },
-#endif /* FEATURE_WLAN_WAPI */
-
- /* handlers for main ioctl - host offload */
- {
- WLAN_PRIV_SET_HOST_OFFLOAD,
- IW_PRIV_TYPE_BYTE | sizeof(tHostOffloadRequest),
- 0,
- "setHostOffload" },
-
- {
- WLAN_GET_WLAN_STATISTICS,
- 0,
- IW_PRIV_TYPE_BYTE | WE_MAX_STR_LEN,
- "getWlanStats" },
-
- {
- WLAN_SET_KEEPALIVE_PARAMS,
- IW_PRIV_TYPE_BYTE | WE_MAX_STR_LEN,
- 0,
- "setKeepAlive" },
-#ifdef WLAN_FEATURE_PACKET_FILTERING
- {
- WLAN_SET_PACKET_FILTER_PARAMS,
- IW_PRIV_TYPE_BYTE | sizeof(tPacketFilterCfg),
- 0,
- "setPktFilter" },
-#endif
-#ifdef FEATURE_WLAN_SCAN_PNO
- {
- WLAN_SET_PNO,
- IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
- 0,
- "setpno" },
-#endif
- {
- WLAN_SET_BAND_CONFIG,
- IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
- 0,
- "SETBAND" },
- /* handlers for dynamic MC BC ioctl */
- {
- WLAN_PRIV_SET_MCBC_FILTER,
- IW_PRIV_TYPE_BYTE | sizeof(tRcvFltMcAddrList),
- 0,
- "setMCBCFilter" },
- {
- WLAN_PRIV_CLEAR_MCBC_FILTER,
- 0,
- 0,
- "clearMCBCFilter" },
- {
- WLAN_SET_POWER_PARAMS,
- IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
- 0,
- "setpowerparams" },
-#ifdef FEATURE_OEM_DATA_SUPPORT
-#ifdef QCA_WIFI_2_0
- {
- WLAN_PRIV_GET_OEM_DATA_CAP,
- 0,
- IW_PRIV_TYPE_BYTE | sizeof(struct iw_oem_data_cap),
- "getOemDataCap" },
-#endif
-#endif
- {
- WLAN_GET_LINK_SPEED,
- IW_PRIV_TYPE_CHAR | 18,
- IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
-};
-
-
-
-const struct iw_handler_def we_handler_def = {
- .num_standard = sizeof(we_handler) / sizeof(we_handler[0]),
- .num_private = sizeof(we_private) / sizeof(we_private[0]),
- .num_private_args = sizeof(we_private_args) / sizeof(we_private_args[0]),
-
- .standard = (iw_handler *)we_handler,
- .private = (iw_handler *)we_private,
- .private_args = we_private_args,
- .get_wireless_stats = get_wireless_stats,
-};
-
-int hdd_validate_mcc_config(hdd_adapter_t *pAdapter, v_UINT_t staId, v_UINT_t arg1, v_UINT_t arg2, v_UINT_t arg3)
-{
- v_U32_t cmd = 288; //Command to RIVA
- hdd_context_t *pHddCtx = NULL;
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
- pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- /*
- *configMccParam : specify the bit which needs to be modified
- *allowed to update based on wlan_qcom_cfg.ini
- * configuration
- * Bit 0 : SCHEDULE_TIME_SLICE MIN : 5 MAX : 20
- * Bit 1 : MAX_NULL_SEND_TIME MIN : 1 MAX : 10
- * Bit 2 : TX_EARLY_STOP_TIME MIN : 1 MAX : 10
- * Bit 3 : RX_DRAIN_TIME MIN : 1 MAX : 10
- * Bit 4 : CHANNEL_SWITCH_TIME MIN : 1 MAX : 20
- * Bit 5 : MIN_CHANNEL_TIME MIN : 5 MAX : 20
- * Bit 6 : PARK_BEFORE_TBTT MIN : 1 MAX : 5
- * Bit 7 : MIN_AFTER_DTIM MIN : 5 MAX : 15
- * Bit 8 : TOO_CLOSE_MARGIN MIN : 1 MAX : 3
- * Bit 9 : Reserved
- */
- switch (arg1)
- {
- //Update MCC SCHEDULE_TIME_SLICE parameter
- case MCC_SCHEDULE_TIME_SLICE_CFG_PARAM :
- if( pHddCtx->cfg_ini->configMccParam & 0x0001)
- {
- if((arg2 >= 5) && (arg2 <= 20))
- {
- logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
- }
- else
- {
- hddLog(LOGE, "%s : Enter a valid MCC configuration value\n",__FUNCTION__);
- return 0;
- }
- }
- break;
-
- //Update MCC MAX_NULL_SEND_TIME parameter
- case MCC_MAX_NULL_SEND_TIME_CFG_PARAM :
- if( pHddCtx->cfg_ini->configMccParam & 0x0002)
- {
- if((arg2 >= 1) && (arg2 <= 10))
- {
- logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
- }
- else
- {
- hddLog(LOGE, "%s : Enter a valid MCC configuration value\n",__FUNCTION__);
- return 0;
- }
- }
- break;
-
- //Update MCC TX_EARLY_STOP_TIME parameter
- case MCC_TX_EARLY_STOP_TIME_CFG_PARAM :
- if( pHddCtx->cfg_ini->configMccParam & 0x0004)
- {
- if((arg2 >= 1) && (arg2 <= 10))
- {
- logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
- }
- else
- {
- hddLog(LOGE, "%s : Enter a valid MCC configuration value\n",__FUNCTION__);
- return 0;
- }
- }
- break;
-
- //Update MCC RX_DRAIN_TIME parameter
- case MCC_RX_DRAIN_TIME_CFG_PARAM :
- if( pHddCtx->cfg_ini->configMccParam & 0x0008)
- {
- if((arg2 >= 1) && (arg2 <= 10))
- {
- logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
- }
- else
- {
- hddLog(LOGE, "%s : Enter a valid MCC configuration value\n",__FUNCTION__);
- return 0;
- }
- }
- break;
-
- //Update MCC CHANNEL_SWITCH_TIME parameter
- case MCC_CHANNEL_SWITCH_TIME_CFG_PARAM :
- if( pHddCtx->cfg_ini->configMccParam & 0x0010)
- {
- if((arg2 >= 1) && (arg2 <= 20))
- {
- logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
- }
- else
- {
- hddLog(LOGE, "%s : Enter a valid MCC configuration value\n",__FUNCTION__);
- return 0;
- }
- }
- break;
-
- //Update MCC MIN_CHANNEL_TIME parameter
- case MCC_MIN_CHANNEL_TIME_CFG_PARAM :
- if( pHddCtx->cfg_ini->configMccParam & 0x0020)
- {
- if((arg2 >= 5) && (arg2 <= 20))
- {
- logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
- }
- else
- {
- hddLog(LOGE, "%s : Enter a valid MCC configuration value\n",__FUNCTION__);
- return 0;
- }
- }
- break;
-
- //Update MCC PARK_BEFORE_TBTT parameter
- case MCC_PARK_BEFORE_TBTT_CFG_PARAM :
- if( pHddCtx->cfg_ini->configMccParam & 0x0040)
- {
- if((arg2 >= 1) && (arg2 <= 5))
- {
- logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
- }
- else
- {
- hddLog(LOGE, "%s : Enter a valid MCC configuration value\n",__FUNCTION__);
- return 0;
- }
- }
- break;
-
- //Update MCC MIN_AFTER_DTIM parameter
- case MCC_MIN_AFTER_DTIM_CFG_PARAM :
- if( pHddCtx->cfg_ini->configMccParam & 0x0080)
- {
- if((arg2 >= 5) && (arg2 <= 15))
- {
- logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
- }
- else
- {
- hddLog(LOGE, "%s : Enter a valid MCC configuration value\n",__FUNCTION__);
- return 0;
- }
- }
- break;
-
- //Update MCC TOO_CLOSE_MARGIN parameter
- case MCC_TOO_CLOSE_MARGIN_CFG_PARAM :
- if( pHddCtx->cfg_ini->configMccParam & 0x0100)
- {
- if((arg2 >= 1) && (arg2 <= 3))
- {
- logPrintf(hHal, cmd, staId, arg1, arg2, arg3);
- }
- else
- {
- hddLog(LOGE, "%s : Enter a valid MCC configuration value\n",__FUNCTION__);
- return 0;
- }
- }
- break;
-
- default :
- hddLog(LOGE, "%s : Uknown / Not allowed to configure parameter : %d\n",
- __FUNCTION__,arg1);
- break;
- }
- return 0;
-}
-
-int hdd_set_wext(hdd_adapter_t *pAdapter)
-{
- hdd_wext_state_t *pwextBuf;
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
-
- pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
-
- // Now configure the roaming profile links. To SSID and bssid.
- pwextBuf->roamProfile.SSIDs.numOfSSIDs = 0;
- pwextBuf->roamProfile.SSIDs.SSIDList = &pHddStaCtx->conn_info.SSID;
-
- pwextBuf->roamProfile.BSSIDs.numOfBSSIDs = 0;
- pwextBuf->roamProfile.BSSIDs.bssid = &pHddStaCtx->conn_info.bssId;
-
- /*Set the numOfChannels to zero to scan all the channels*/
- pwextBuf->roamProfile.ChannelInfo.numOfChannels = 0;
- pwextBuf->roamProfile.ChannelInfo.ChannelList = NULL;
-
- /* Default is no encryption */
- pwextBuf->roamProfile.EncryptionType.numEntries = 1;
- pwextBuf->roamProfile.EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
-
- pwextBuf->roamProfile.mcEncryptionType.numEntries = 1;
- pwextBuf->roamProfile.mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
-
- pwextBuf->roamProfile.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
-
- /* Default is no authentication */
- pwextBuf->roamProfile.AuthType.numEntries = 1;
- pwextBuf->roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
-
- pwextBuf->roamProfile.phyMode = eCSR_DOT11_MODE_TAURUS;
- pwextBuf->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
-
- /*Set the default scan mode*/
- pAdapter->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
-
- hdd_clearRoamProfileIe(pAdapter);
-
- return VOS_STATUS_SUCCESS;
-
- }
-
-int hdd_register_wext(struct net_device *dev)
- {
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
- VOS_STATUS status;
-
- ENTER();
-
- // Zero the memory. This zeros the profile structure.
- memset(pwextBuf, 0,sizeof(hdd_wext_state_t));
-
- init_completion(&(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->completion_var);
-
-
- status = hdd_set_wext(pAdapter);
-
- if(!VOS_IS_STATUS_SUCCESS(status)) {
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_wext failed!!\n"));
- return eHAL_STATUS_FAILURE;
- }
-
- if (!VOS_IS_STATUS_SUCCESS(vos_event_init(&pwextBuf->vosevent)))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos event init failed!!\n"));
- return eHAL_STATUS_FAILURE;
- }
-
- if (!VOS_IS_STATUS_SUCCESS(vos_event_init(&pwextBuf->scanevent)))
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD scan event init failed!!\n"));
- return eHAL_STATUS_FAILURE;
- }
-
- // Register as a wireless device
- dev->wireless_handlers = (struct iw_handler_def *)&we_handler_def;
-
- EXIT();
- return 0;
-}
-
-int hdd_UnregisterWext(struct net_device *dev)
-{
-#if 0
- hdd_wext_state_t *wextBuf;
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
-
- ENTER();
- // Set up the pointer to the Wireless Extensions state structure
- wextBuf = pAdapter->pWextState;
-
- // De-allocate the Wireless Extensions state structure
- kfree(wextBuf);
-
- // Clear out the pointer to the Wireless Extensions state structure
- pAdapter->pWextState = NULL;
-
- EXIT();
-#endif
- dev->wireless_handlers = NULL;
- return 0;
-}
-
-
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 9892d527c5dd..7c2922b45d67 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -119,22 +119,6 @@ static void cbNotifySetRoamScanNProbes(hdd_context_t *pHddCtx, unsigned long Not
static void cbNotifySetRoamScanHomeAwayTime(hdd_context_t *pHddCtx, unsigned long NotifyId)
{
- tANI_U16 scanChannelMaxTime = 0;
-
- /* Home Away Time should be atleast equal to (MaxDwell time + (2*RFS)),
- * where RFS is the RF Switching time. It is twice RFS to consider the
- * time to go off channel and return to the home channel. */
-
- scanChannelMaxTime = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
- if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime < (scanChannelMaxTime + (2 * HDD_ROAM_SCAN_CHANNEL_SWITCH_TIME)))
- {
- VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
- "%s: Invalid config, Home away time(%d) is less than (twice RF switching time + channel max time)(%d)"
- " Hence enforcing home away time to disable (0)",
- __func__, pHddCtx->cfg_ini->nRoamScanHomeAwayTime, (scanChannelMaxTime + (2 * HDD_ROAM_SCAN_CHANNEL_SWITCH_TIME)));
- pHddCtx->cfg_ini->nRoamScanHomeAwayTime = 0;
- }
-
sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->nRoamScanHomeAwayTime, eANI_BOOLEAN_TRUE);
}
#endif
@@ -207,22 +191,6 @@ static void cbNotifySetNeighborScanMinChanTime(hdd_context_t *pHddCtx, unsigned
static void cbNotifySetNeighborScanMaxChanTime(hdd_context_t *pHddCtx, unsigned long NotifyId)
{
- tANI_U16 homeAwayTime = 0;
-
- /* Home Away Time should be atleast equal to (MaxDwell time + (2*RFS)),
- * where RFS is the RF Switching time. It is twice RFS to consider the
- * time to go off channel and return to the home channel. */
- homeAwayTime = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
- if (homeAwayTime < (pHddCtx->cfg_ini->nNeighborScanMaxChanTime + (2 * HDD_ROAM_SCAN_CHANNEL_SWITCH_TIME)))
- {
- VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
- "%s: Invalid config, Home away time(%d) is less than (twice RF switching time + channel max time)(%d)"
- " Hence enforcing home away time to disable (0)",
- __func__, homeAwayTime, (pHddCtx->cfg_ini->nNeighborScanMaxChanTime + (2 * HDD_ROAM_SCAN_CHANNEL_SWITCH_TIME)));
- homeAwayTime = 0;
- pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
- sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_FALSE);
- }
sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->nNeighborScanMaxChanTime);
}
#endif
@@ -2450,6 +2418,13 @@ REG_VARIABLE( CFG_HT_SMPS_CAP_FEATURE, WLAN_PARAM_Integer,
CFG_HT_SMPS_CAP_FEATURE_MIN,
CFG_HT_SMPS_CAP_FEATURE_MAX ),
+REG_VARIABLE( CFG_DISABLE_DFS_CH_SWITCH, WLAN_PARAM_Integer,
+ hdd_config_t, disableDFSChSwitch,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_DISABLE_DFS_CH_SWITCH_DEFAULT,
+ CFG_DISABLE_DFS_CH_SWITCH_MIN,
+ CFG_DISABLE_DFS_CH_SWITCH_MAX ),
+
REG_VARIABLE( CFG_ENABLE_FIRST_SCAN_2G_ONLY_NAME, WLAN_PARAM_Integer,
hdd_config_t, enableFirstScan2GOnly,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
@@ -4489,7 +4464,7 @@ v_BOOL_t hdd_update_config_dat( hdd_context_t *pHddCtx )
temp = (temp & 0xFFF3) | (pConfig->vhtTxMCS2x2 << 2);
VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
- "vhtRxMCS2x2 - %x temp - %lu enable2x2 %d\n",
+ "vhtRxMCS2x2 - %x temp - %u enable2x2 %d\n",
pConfig->vhtRxMCS2x2, temp, pConfig->enable2x2);
if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_TX_MCS_MAP,
@@ -4604,7 +4579,12 @@ v_BOOL_t hdd_update_config_dat( hdd_context_t *pHddCtx )
}
else
{
+#ifndef QCA_WIFI_2_0
val = WNI_CFG_ASSOC_STA_LIMIT_STADEF;
+#else
+ val = pConfig->maxNumberOfPeers;
+#endif
+
}
if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ASSOC_STA_LIMIT, val,
NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
@@ -4841,15 +4821,6 @@ VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx )
smeConfig.csrConfig.nRoamIntraBand = pConfig->nRoamIntraBand;
smeConfig.csrConfig.nProbes = pConfig->nProbes;
- if (pConfig->nRoamScanHomeAwayTime < (pConfig->nNeighborScanMaxChanTime + (2 * HDD_ROAM_SCAN_CHANNEL_SWITCH_TIME)))
- {
- VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
- "%s: Invalid config, Home away time(%d) is less than twice RF switching time + channel max time(%d)"
- " Hence enforcing home away time to disable (0)",
- __func__, pConfig->nRoamScanHomeAwayTime,
- (pConfig->nNeighborScanMaxChanTime + (2 * HDD_ROAM_SCAN_CHANNEL_SWITCH_TIME)));
- pConfig->nRoamScanHomeAwayTime = 0;
- }
smeConfig.csrConfig.nRoamScanHomeAwayTime = pConfig->nRoamScanHomeAwayTime;
#endif
smeConfig.csrConfig.fFirstScanOnly2GChnl = pConfig->enableFirstScan2GOnly;
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 6bfa05319375..acdfd9a8ceaf 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -531,7 +531,8 @@ enum wlan_hdd_tm_attr
WLAN_HDD_TM_ATTR_INVALID = 0,
WLAN_HDD_TM_ATTR_CMD = 1,
WLAN_HDD_TM_ATTR_DATA = 2,
- WLAN_HDD_TM_ATTR_TYPE = 3,
+ WLAN_HDD_TM_ATTR_STREAM_ID = 3,
+ WLAN_HDD_TM_ATTR_TYPE = 4,
/* keep last */
WLAN_HDD_TM_ATTR_AFTER_LAST,
WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
@@ -712,6 +713,10 @@ int wlan_hdd_cfg80211_init(struct device *dev,
}
#endif/*FEATURE_WLAN_SCAN_PNO*/
+#if defined(QCA_WIFI_2_0) && defined (QCA_WIFI_FTM) && !defined(QCA_WIFI_ISOC)
+ if (vos_get_conparam() != VOS_FTM_MODE) {
+#endif
+
#ifdef CONFIG_ENABLE_LINUX_REG
/* even with WIPHY_FLAG_CUSTOM_REGULATORY,
driver can still register regulatory callback and
@@ -724,6 +729,10 @@ int wlan_hdd_cfg80211_init(struct device *dev,
wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
#endif
+#if defined(QCA_WIFI_2_0) && defined (QCA_WIFI_FTM) && !defined(QCA_WIFI_ISOC)
+ }
+#endif
+
wiphy->max_scan_ssids = MAX_SCAN_SSID;
wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
@@ -1818,10 +1827,12 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
struct qc_mac_acl_entry *acl_entry = NULL;
v_SINT_t i;
+ hdd_config_t *iniConfig;
hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
ENTER();
+ iniConfig = pHddCtx->cfg_ini;
pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
@@ -1832,6 +1843,8 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
+ pConfig->disableDFSChSwitch = iniConfig->disableDFSChSwitch;
+
//channel is already set in the set_channel Call back
//pConfig->channel = pCommitConfig->channel;
@@ -5490,6 +5503,21 @@ int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
eConnectionState_Connecting);
+ /* After 8-way handshake supplicant should give the scan command
+ * in that it update the additional IEs, But because of scan
+ * enhancements, the supplicant is not issuing the scan command now.
+ * So the unicast frames which are sent from the host are not having
+ * the additional IEs. If it is P2P CLIENT and there is no additional
+ * IE present in roamProfile, then use the addtional IE form scan_info
+ */
+
+ if ((pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) &&
+ (!pRoamProfile->pAddIEScan))
+ {
+ pRoamProfile->pAddIEScan = &pAdapter->scan_info.scanAddIE.addIEdata[0];
+ pRoamProfile->nAddIEScanLength = pAdapter->scan_info.scanAddIE.length;
+ }
+
status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
pAdapter->sessionId, pRoamProfile, &roamId);
diff --git a/CORE/HDD/src/wlan_hdd_early_suspend.c b/CORE/HDD/src/wlan_hdd_early_suspend.c
index a0f507b3ead0..4badb4ae5543 100644
--- a/CORE/HDD/src/wlan_hdd_early_suspend.c
+++ b/CORE/HDD/src/wlan_hdd_early_suspend.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1707,7 +1707,7 @@ VOS_STATUS hdd_wlan_re_init(void *hif_sc)
adf_ctx = vos_mem_malloc(sizeof(adf_os_device_t));
if (!adf_ctx) {
- hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to allocate adf_ctx");
+ hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to allocate adf_ctx", __func__);
goto err_re_init;
}
vos_mem_zero(adf_ctx, sizeof(adf_os_device_t));
@@ -1720,6 +1720,25 @@ VOS_STATUS hdd_wlan_re_init(void *hif_sc)
/* The driver should always be initialized in STA mode after SSR */
hdd_set_conparam(0);
+#ifdef CONFIG_ENABLE_LINUX_REG
+ vosStatus = vos_nv_open();
+ if (!VOS_IS_STATUS_SUCCESS(vosStatus))
+ {
+ /* NV module cannot be initialized */
+ hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_nv_open failed", __func__);
+ goto err_re_init;
+ }
+#ifdef QCA_WIFI_ISOC
+ vosStatus = vos_init_wiphy_from_nv_bin();
+ if (!VOS_IS_STATUS_SUCCESS(vosStatus))
+ {
+ /* NV module cannot be initialized */
+ hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_init_wiphy failed", __func__);
+ goto err_re_init;
+ }
+#endif
+#endif
+
/* Re-open VOSS, it is a re-open b'se control transport was never closed. */
vosStatus = vos_open(&pVosContext, 0);
if (!VOS_IS_STATUS_SUCCESS(vosStatus))
@@ -1764,6 +1783,24 @@ VOS_STATUS hdd_wlan_re_init(void *hif_sc)
goto err_vosclose;
}
+#ifdef CONFIG_ENABLE_LINUX_REG
+#ifndef QCA_WIFI_ISOC
+ /* initialize the NV module. This is required so that
+ we can initialize the channel information in wiphy
+ from the NV.bin data. The channel information in
+ wiphy needs to be initialized before wiphy registration */
+
+ vosStatus = vos_init_wiphy_from_eeprom();
+ if (!VOS_IS_STATUS_SUCCESS(vosStatus))
+ {
+ /* NV module cannot be initialized */
+ hddLog(VOS_TRACE_LEVEL_FATAL,
+ "%s: vos_init_wiphy_from_eeprom failed", __func__);
+ goto err_vosclose;
+ }
+#endif
+#endif
+
vosStatus = hdd_set_sme_chan_list(pHddCtx);
if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
hddLog(VOS_TRACE_LEVEL_FATAL,
diff --git a/CORE/HDD/src/wlan_hdd_ftm.c b/CORE/HDD/src/wlan_hdd_ftm.c
index c5257e8cee61..9bcf52d99110 100644
--- a/CORE/HDD/src/wlan_hdd_ftm.c
+++ b/CORE/HDD/src/wlan_hdd_ftm.c
@@ -80,6 +80,7 @@
#include "ol_fw.h"
#include "testmode.h"
#include "wlan_hdd_cfg80211.h"
+#include "if_pci.h"
#endif
#define RXMODE_DISABLE_ALL 0
@@ -562,8 +563,14 @@ static VOS_STATUS wlan_ftm_vos_open( v_CONTEXT_t pVosContext, v_SIZE_t hddContex
macOpenParms.powersaveOffloadEnabled =
pHddCtx->cfg_ini->enablePowersaveOffload;
+#ifndef QCA_WIFI_ISOC
+ vStatus = WDA_open(gpVosContext, gpVosContext->pHDDContext,
+ NULL, NULL,
+ &macOpenParms);
+#else
vStatus = WDA_open(gpVosContext, gpVosContext->pHDDContext,
NULL, &macOpenParms);
+#endif
if (!VOS_IS_STATUS_SUCCESS(vStatus))
{
/* Critical Error ... Cannot proceed further */
@@ -622,6 +629,7 @@ static VOS_STATUS wlan_ftm_vos_open( v_CONTEXT_t pVosContext, v_SIZE_t hddContex
goto err_nv_close;
}
+#ifndef QCA_WIFI_FTM
/* Now proceed to open the SME */
vStatus = sme_Open(gpVosContext->pMACContext);
if (!VOS_IS_STATUS_SUCCESS(vStatus))
@@ -641,8 +649,13 @@ static VOS_STATUS wlan_ftm_vos_open( v_CONTEXT_t pVosContext, v_SIZE_t hddContex
"%s: VOSS successfully Opened", __func__);
return VOS_STATUS_SUCCESS;
}
+#else
+ return VOS_STATUS_SUCCESS;
+#endif
+#ifndef QCA_WIFI_FTM
err_mac_close:
+#endif
macClose(gpVosContext->pMACContext);
err_nv_close:
@@ -701,6 +714,7 @@ static VOS_STATUS wlan_ftm_vos_close( v_CONTEXT_t vosContext )
VOS_STATUS vosStatus;
pVosContextType gpVosContext = (pVosContextType)vosContext;
+#ifndef QCA_WIFI_FTM
vosStatus = sme_Close(((pVosContextType)vosContext)->pMACContext);
if (!VOS_IS_STATUS_SUCCESS(vosStatus))
{
@@ -708,6 +722,7 @@ static VOS_STATUS wlan_ftm_vos_close( v_CONTEXT_t vosContext )
"%s: Failed to close BAL",__func__);
VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
}
+#endif
vosStatus = macClose( ((pVosContextType)vosContext)->pMACContext);
if (!VOS_IS_STATUS_SUCCESS(vosStatus))
@@ -744,13 +759,14 @@ static VOS_STATUS wlan_ftm_vos_close( v_CONTEXT_t vosContext )
VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
}
-#if defined(QCA_WIFI_2_0) && defined(QCA_WIFI_FTM)
+#if defined(QCA_WIFI_2_0) && defined(QCA_WIFI_FTM) && !defined(QCA_WIFI_ISOC)
if (gpVosContext->htc_ctx)
{
HTCStop(gpVosContext->htc_ctx);
HTCDestroy(gpVosContext->htc_ctx);
gpVosContext->htc_ctx = NULL;
}
+ hif_disable_isr(gpVosContext->pHIFContext);
#endif
vos_mq_deinit(&((pVosContextType)vosContext)->freeVosMq);
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 93e4edab15db..d86b142aceff 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -555,6 +555,18 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa
pHddApCtx->wepKey[i].keyLength = 0;
}
}
+
+ // We should restart OS transmit queues if we came here after
+ // radar detection and channel change
+ if (VOS_TRUE == pHddCtx->dfs_radar_found)
+ {
+ pHddCtx->dfs_radar_found = VOS_FALSE;
+ if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
+ {
+ netif_tx_start_all_queues(dev);
+ }
+ }
+
//Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled
startBssEvent = "SOFTAP.enabled";
memset(&we_custom_start_event, '\0', sizeof(we_custom_start_event));
@@ -859,6 +871,11 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa
hdd_stop_p2p_link(pHostapdAdapter, usrDataForCallback);
return VOS_STATUS_SUCCESS;
+ case eSAP_CHANNEL_CHANGE_EVENT:
+ hddLog(LOG1, FL("Received eSAP_CHANNEL_CHANGE_EVENT event\n"));
+ /* TODO Need to indicate operating channel change to hostapd */
+ return VOS_STATUS_SUCCESS;
+
default:
hddLog(LOG1,"SAP message is not handled\n");
goto stopbss;
@@ -1140,6 +1157,14 @@ static iw_softap_setparam(struct net_device *dev,
}
#ifdef QCA_WIFI_2_0
+ case QCSAP_PARAM_SET_TXRX_FW_STATS:
+ {
+ hddLog(LOG1, "QCSAP_PARAM_SET_TXRX_FW_STATS val %d", set_value);
+ ret = process_wma_set_command((int)pHostapdAdapter->sessionId,
+ (int)WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID,
+ set_value, VDEV_CMD);
+ break;
+ }
/* Firmware debug log */
case QCSAP_DBGLOG_LOG_LEVEL:
{
@@ -3005,7 +3030,8 @@ static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter,
0, // not periodic
FALSE, //non-cached results
staid,
- &context);
+ &context,
+ pAdapter->sessionId );
if (eHAL_STATUS_SUCCESS != hstatus)
{
hddLog(VOS_TRACE_LEVEL_ERROR,
@@ -3213,6 +3239,9 @@ static const struct iw_priv_args hostapd_private_args[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" },
{ QCSAP_PARAM_SET_MC_RATE,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" },
+ { QCSAP_PARAM_SET_TXRX_FW_STATS,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "txrx_fw_stats" },
+
#ifdef QCA_WIFI_2_0
/* Sub-cmds DBGLOG specific commands */
diff --git a/CORE/HDD/src/wlan_hdd_ipa.c b/CORE/HDD/src/wlan_hdd_ipa.c
index 2b4e5b301738..4c065c248275 100644
--- a/CORE/HDD/src/wlan_hdd_ipa.c
+++ b/CORE/HDD/src/wlan_hdd_ipa.c
@@ -47,68 +47,65 @@ Include Files
#include <linux/skbuff.h>
#include <linux/list.h>
#include <linux/debugfs.h>
-#include <wlan_hdd_softap_tx_rx.h>
-
-#include "vos_sched.h"
-#include "wlan_qct_tl.h"
-#include "ol_txrx_peer_find.h"
-#include "tl_shim.h"
#define HDD_IPA_DESC_BUFFER_RATIO 4
#define HDD_IPA_IPV4_NAME_EXT "_ipv4"
#define HDD_IPA_IPV6_NAME_EXT "_ipv6"
#define HDD_IPA_RX_INACTIVITY_MSEC_DELAY 2000
-#define HDD_IPA_WLAN_HDR_ONLY_LEN 4
+
+const uint8_t ipa_set_tx_hdr[] = {
+/*IPA-WLAN HDR */
+ 0x00, 0x00, /* Reserved */
+#define HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET 2
+#define HDD_IPA_WLAN_HDR_DEV_TYPE_MASK 0x80
+#define HDD_IPA_WLAN_HDR_DEV_TYPE_AP 0x80
+#define HDD_IPA_WLAN_HDR_DEV_TYPE_STA 0x00
+#define HDD_IPA_WLAN_HDR_DEV_ID_MASK 0x7F
#define HDD_IPA_WLAN_HDR_STA_ID_OFFSET 3
-#define HDD_IPA_WLAN_HDR_DES_MAC_OFFSET 0
-
-struct llc_snap_hdr {
- uint8_t dsap;
- uint8_t ssap;
- uint8_t resv[4];
- __be16 eth_type;
-} __packed;
-
-struct ipa_tx_hdr {
- struct ethhdr eth;
- struct llc_snap_hdr llc_snap;
-} __packed;
-
-/* For Tx pipes, use 802.3 Header format */
-struct ipa_tx_hdr ipa_set_tx_hdr = {
- {
- {0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc}, /* Des_MAC filled by IPA */
- {0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff}, /* Src. MAC filled by IPA */
- 0x00 /* length can be zero */
- },
- {
+ 0x00, 0x00,
+ /* dev_id and sta_id filled by wlan*/
+
+ /* 802.3 header - 14 bytes*/
+#define HDD_IPA_WLAN_HDR_DES_MAC_OFFSET 4
+ 0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc,
+ /* Des_MAC filled by IPA */
+#define HDD_IPA_WLAN_HDR_SRC_MAC_OFFSET 10
+ 0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff,
+ /* Src. MAC filled by IPA */
+ 0x00, 0x00,
+ /* length can be zero */
+
+ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00,
/* LLC SNAP header 8 bytes */
- 0xaa, 0xaa,
- {0x03, 0x00, 0x00, 0x00},
- 0x0008 /* type value(2 bytes) ,filled by wlan */
- /* 0x0800 - IPV4, 0x86dd - IPV6 */
- }
+#define HDD_IPA_WLAN_TX_HDR_IP_VER_OFFSET 24
+ 0x08, 0x00
+ /* type value(2 bytes) ,filled by wlan */
+ /* 0x0800 - IPV4, 0x86dd - IPV6 */
};
-struct ipa_rx_hdr {
- uint8_t hdr[HDD_IPA_WLAN_HDR_ONLY_LEN];
- struct ethhdr eth;
-} __packed;
-
-/* For Rx pipe, use Ethernet-II Header format */
-struct ipa_rx_hdr ipa_set_rx_hdr = {
- {0x00, 0x00, 0x00, 0x00}, /* 4 bytes header */
- {
- {0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc}, /* Des_MAC filled by IPA */
- {0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff}, /* Src. MAC filled by IPA */
- 0x0008 /* type value(2 bytes) ,filled by wlan */
- /* 0x0800 - IPV4, 0x86dd - IPV6 */
- }
+// For Rx pipe, use Ethernet-II Header format
+const uint8_t ipa_set_rx_hdr[] = {
+ 0x00, 0x00, /* Reserved */
+ 0x00, 0x00,
+ /* dev_id and sta_id filled by wlan*/
+
+ /* 802.3 header - 14 bytes*/
+ 0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc,
+ /* Des_MAC filled by IPA */
+ 0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff,
+ /* Src. MAC filled by IPA */
+#define HDD_IPA_WLAN_RX_HDR_IP_VER_OFFSET 16
+ 0x08, 0x00
+ /* type value(2 bytes) ,filled by wlan */
+ /* 0x0800 - IPV4, 0x86dd - IPV6 */
};
+
#define HDD_IPA_WLAN_TX_HDR_LEN sizeof(ipa_set_tx_hdr)
#define HDD_IPA_WLAN_RX_HDR_LEN sizeof(ipa_set_rx_hdr)
+#define HDD_IPA_WLAN_HDR_ONLY_LEN 4
+#define HDD_IPA_MAX_TX_PIPE_MAP 8
#define HDD_IPA_WLAN_HDR_PARTIAL 1
#define HDD_IPA_LOG(LVL, fmt, args...) VOS_TRACE(VOS_MODULE_ID_HDD, LVL, \
@@ -122,9 +119,10 @@ enum hdd_ipa_rm_state {
};
enum hdd_ipa_pipe_index {
- HDD_IPA_TX_WLAN0_PIPE,
- HDD_IPA_TX_WLAN1_PIPE,
- HDD_IPA_TX_WLAN2_PIPE,
+ HDD_IPA_TX_VI_PIPE,
+ HDD_IPA_TX_VO_PIPE,
+ HDD_IPA_TX_BE_PIPE,
+ HDD_IPA_TX_BK_PIPE,
HDD_IPA_RX_PIPE,
HDD_IPA_MAX_PIPE
};
@@ -134,22 +132,38 @@ enum hdd_ipa_ip_ver {
HDD_IPA_IPV6 = 2
};
-#define HDD_IPA_WLAN_MAX_STA_ID 255
-
-uint8_t wlan_sta_id_2_hdd_pipe_id[HDD_IPA_WLAN_MAX_STA_ID] = {0xFF};
-
-uint8_t hdd_pipe_id_2_ipa_client_id[HDD_IPA_MAX_PIPE] = {
+uint8_t hdd_ipa_pipe_client[HDD_IPA_MAX_PIPE] = {
IPA_CLIENT_WLAN1_CONS,
IPA_CLIENT_WLAN2_CONS,
IPA_CLIENT_WLAN3_CONS,
+ IPA_CLIENT_WLAN4_CONS,
IPA_CLIENT_WLAN1_PROD
};
-uint8_t ipa_client_id_2_hdd_pipe_id[IPA_CLIENT_MAX] = {
- [IPA_CLIENT_WLAN1_CONS] = HDD_IPA_TX_WLAN0_PIPE,
- [IPA_CLIENT_WLAN2_CONS] = HDD_IPA_TX_WLAN1_PIPE,
- [IPA_CLIENT_WLAN3_CONS] = HDD_IPA_TX_WLAN2_PIPE,
- [IPA_CLIENT_WLAN1_PROD] = HDD_IPA_RX_PIPE
+uint8_t hdd_ipa_pipe_client_AC[] = {
+ HDD_LINUX_AC_VI,
+ HDD_LINUX_AC_VO,
+ HDD_LINUX_AC_BE,
+ HDD_LINUX_AC_BK
+};
+
+static struct hdd_ipa_tx_pipe_map{
+ uint8_t tos_value;
+ enum ipa_client_type client;
+ uint8_t ac;
+} hdd_ipa_tx_pipe_map_info[HDD_IPA_MAX_TX_PIPE_MAP] = {
+ /* BK */
+ {1, IPA_CLIENT_WLAN1_CONS, HDD_LINUX_AC_BK},
+ {2, IPA_CLIENT_WLAN1_CONS, HDD_LINUX_AC_BK},
+ /* BE */
+ {0, IPA_CLIENT_WLAN2_CONS, HDD_LINUX_AC_BE},
+ {3, IPA_CLIENT_WLAN2_CONS, HDD_LINUX_AC_BE},
+ /* VI */
+ {4, IPA_CLIENT_WLAN3_CONS, HDD_LINUX_AC_VI},
+ {5, IPA_CLIENT_WLAN3_CONS, HDD_LINUX_AC_VI},
+ /* VO */
+ {6, IPA_CLIENT_WLAN4_CONS, HDD_LINUX_AC_VO},
+ {7, IPA_CLIENT_WLAN4_CONS, HDD_LINUX_AC_VO},
};
struct hdd_ipa_sys_pipe {
@@ -171,8 +185,6 @@ struct hdd_ipa_priv {
struct list_head free_desc_head;
struct list_head pend_desc_head;
- struct ol_txrx_vdev_t *pipe_to_vdev[HDD_IPA_MAX_PIPE];
-
hdd_context_t *hdd_ctx;
struct dentry *debugfs_dir;
@@ -189,6 +201,7 @@ struct hdd_ipa_priv {
uint64_t rx_ipa_hw_maxed_out;
+ uint64_t tx_ipa_recv;
uint64_t freeq_empty;
uint64_t freeq_cnt;
@@ -211,11 +224,7 @@ struct hdd_ipa_priv {
uint64_t rx_ipa_dh_reclaim;
uint64_t rx_ipa_dh_not_used;
#endif
- uint64_t ipa_lb_cnt;
- uint64_t tx_ipa_recv;
- uint64_t tx_comp_cnt;
- uint64_t tx_dp_err_cnt;
- } stats;
+ }stats;
};
enum hdd_ipa_evt {
@@ -247,13 +256,13 @@ static inline void *hdd_ipa_kzalloc(uint32_t size)
return data;
}
-static inline struct ipa_tx_data_desc *hdd_ipa_get_desc_from_freeq(void)
+static inline struct ipa_tx_data_desc * hdd_ipa_get_desc_from_freeq(void)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
struct ipa_tx_data_desc *desc = NULL;
spin_lock_bh(&ghdd_ipa->q_lock);
- if (!list_empty(&ghdd_ipa->free_desc_head)) {
+ if(!list_empty(&ghdd_ipa->free_desc_head)) {
desc = list_first_entry(&ghdd_ipa->free_desc_head, struct ipa_tx_data_desc, link);
list_del(&desc->link);
hdd_ipa->stats.freeq_cnt--;
@@ -408,9 +417,7 @@ void hdd_ipa_send_skb_to_network(adf_nbuf_t skb, hdd_adapter_t *adap_dev)
{
if (!adap_dev || (adap_dev &&
adap_dev->magic != WLAN_HDD_ADAPTER_MAGIC)) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid adapter: adap=0x%x",
- adap_dev);
-
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid sta_id");
adf_nbuf_free(skb);
return;
}
@@ -431,10 +438,8 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head,
int send_desc_cnt)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
- struct ipa_tx_data_desc *send_desc, *desc, *tmp;
+ struct ipa_tx_data_desc *send_desc;
uint32_t cur_send_cnt = 0;
- adf_nbuf_t buf;
-
#ifndef HDD_IPA_USE_IPA_RM_TIMER
if (hdd_ipa->rm_timer_on) {
del_timer(&hdd_ipa->rm_timer);
@@ -475,42 +480,12 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head,
cur_send_cnt = send_desc_cnt;
}
hdd_ipa->stats.rx_ipa_sent_desc_cnt += cur_send_cnt;
-
-#ifdef HDD_IPA_EXTRA_DP_COUNTERS
- hdd_ipa->stats.rx_ipa_dh_sent++; /* for desc head */
-#endif
spin_unlock_bh(&hdd_ipa->q_lock);
- if (ipa_tx_dp_mul(hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE],
- send_desc_head) != 0) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ipa_tx_dp_mul failed!!! (cur_send_cnt=%d)", cur_send_cnt);
- hdd_ipa->stats.tx_dp_err_cnt++;
- spin_lock_bh(&hdd_ipa->q_lock);
-
- list_for_each_entry_safe(desc, tmp,
- &send_desc_head->link, link) {
- list_del(&desc->link);
- buf = desc->priv;
- adf_nbuf_free(buf);
- desc->priv = NULL;
- desc->pyld_buffer = NULL;
- desc->pyld_len = 0;
- list_add_tail(&desc->link, &hdd_ipa->free_desc_head);
- hdd_ipa->stats.freeq_cnt++;
-#ifdef HDD_IPA_EXTRA_DP_COUNTERS
- hdd_ipa->stats.freeq_reclaim++;
-#endif
- hdd_ipa->pending_desc_cnt--;
- }
-
- /* return anchor node */
- list_add_tail(&send_desc_head->link, &hdd_ipa->free_desc_head);
- hdd_ipa->stats.freeq_cnt++;
#ifdef HDD_IPA_EXTRA_DP_COUNTERS
- hdd_ipa->stats.rx_ipa_dh_reclaim++;
- hdd_ipa->stats.freeq_reclaim++;
+ hdd_ipa->stats.rx_ipa_dh_sent++; //for desc head
#endif
- spin_unlock_bh(&hdd_ipa->q_lock);
- }
+ ipa_tx_dp_mul(hdd_ipa_pipe_client[HDD_IPA_RX_PIPE],
+ send_desc_head);
} else {
#ifdef HDD_IPA_EXTRA_DP_COUNTERS
hdd_ipa->stats.rx_ipa_hw_max_qued += send_desc_cnt;
@@ -533,6 +508,12 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head,
static int hdd_ipa_is_ip_pkt(void *data, uint8_t ip_ver)
{
struct ethhdr *eth = (struct ethhdr *)data;
+ struct llc_snap_hdr {
+ uint8_t dsap;
+ uint8_t ssap;
+ uint8_t resv[4];
+ __be16 eth_type;
+ } __packed;
struct llc_snap_hdr *ls_hdr;
uint16_t eth_type;
int ret = 0;
@@ -542,14 +523,16 @@ static int hdd_ipa_is_ip_pkt(void *data, uint8_t ip_ver)
/* Non Ethernet II framing format */
ls_hdr = (struct llc_snap_hdr *)((uint8_t *)data +
sizeof(struct ethhdr));
-
- if (((ls_hdr->dsap == 0xAA) && (ls_hdr->ssap == 0xAA)) ||
- ((ls_hdr->dsap == 0xAB) && (ls_hdr->ssap == 0xAB)))
- eth_type = be16_to_cpu(ls_hdr->eth_type);
+ /* TODO Is this needed
+ if ((ls_hdr->dsap == 0xAA && ls_hdr->ssap == 0xAA) ||
+ (ls_hdr->dsap == 0xAB && ls_hdr->ssap == 0xAB))
+ */
+ eth_type = be16_to_cpu(ls_hdr->eth_type);
}
- if (((eth_type == ETH_P_IP) && (ip_ver == HDD_IPA_IPV4)) ||
- ((eth_type == ETH_P_IPV6) && (ip_ver == HDD_IPA_IPV6)))
+ if ((eth_type == ETH_P_IP) && (ip_ver == HDD_IPA_IPV4))
+ ret = 1;
+ else if ((eth_type == ETH_P_IPV6) && (ip_ver == HDD_IPA_IPV6))
ret = 1;
if (ret != 1)
@@ -567,7 +550,7 @@ static void hdd_ipa_process_evt(int evt, void *priv)
*done_desc_head, *done_desc, *tmp;
hdd_adapter_t *adap_dev = NULL;
adf_nbuf_t buf, next_buf;
- uint8_t cur_cnt = 0;
+ uint8_t dev_id, cur_cnt = 0, iftype;
switch (evt) {
case HDD_IPA_RXT_EVT:
@@ -588,6 +571,8 @@ static void hdd_ipa_process_evt(int evt, void *priv)
}
return;
}
+ dev_id = adap_dev->dev->ifindex;
+ iftype = adap_dev->wdev.iftype;
/* send_desc_head is a anchor node */
send_desc_head = hdd_ipa_get_desc_from_freeq();
if (!send_desc_head) {
@@ -640,8 +625,19 @@ static void hdd_ipa_process_evt(int evt, void *priv)
}
skb_push(buf, HDD_IPA_WLAN_HDR_ONLY_LEN);
- /* vos_mem_zero(((struct ipa_rx_hdr *)(buf->data))->hdr, HDD_IPA_WLAN_HDR_ONLY_LEN); */
- ((struct ipa_rx_hdr *)(buf->data))->hdr[HDD_IPA_WLAN_HDR_STA_ID_OFFSET] = rxt->sta_id;
+ memset(buf->data, 0, HDD_IPA_WLAN_HDR_ONLY_LEN);
+ buf->data[HDD_IPA_WLAN_HDR_STA_ID_OFFSET] = rxt->sta_id;
+ buf->data[HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET] |=
+ dev_id & HDD_IPA_WLAN_HDR_DEV_ID_MASK;
+ if (iftype == NL80211_IFTYPE_AP ||
+ iftype == NL80211_IFTYPE_P2P_GO) {
+ buf->data[HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET] |=
+ HDD_IPA_WLAN_HDR_DEV_TYPE_AP;
+ } else {
+ buf->data[HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET] |=
+ HDD_IPA_WLAN_HDR_DEV_TYPE_STA;
+ }
+
send_desc = hdd_ipa_get_desc_from_freeq();
if (send_desc) {
send_desc->priv = buf;
@@ -701,7 +697,7 @@ static void hdd_ipa_process_evt(int evt, void *priv)
HDD_IPA_RM_GRANT_PENDING);
hdd_ipa_rm_request(hdd_ipa);
}
- /* hdd_ipa_rm_request can immediately grant so check again. */
+ //hdd_ipa_rm_request can immediately grant so check again.
if (atomic_read(&hdd_ipa->rm_state)
== HDD_IPA_RM_GRANT_PENDING) {
spin_lock_bh(&hdd_ipa->q_lock);
@@ -710,11 +706,6 @@ static void hdd_ipa_process_evt(int evt, void *priv)
/* return anchor node */
list_add_tail(&send_desc_head->link,
&hdd_ipa->free_desc_head);
- hdd_ipa->stats.freeq_cnt++;
-#ifdef HDD_IPA_EXTRA_DP_COUNTERS
- hdd_ipa->stats.rx_ipa_dh_reclaim++;
- hdd_ipa->stats.freeq_reclaim++;
-#endif
spin_unlock_bh(&hdd_ipa->q_lock);
#ifdef HDD_IPA_EXTRA_DP_COUNTERS
hdd_ipa->stats.rx_ipa_rm_qued += cur_cnt;
@@ -800,7 +791,6 @@ VOS_STATUS hdd_ipa_process_rxt(v_VOID_t *vosContext, adf_nbuf_t rx_buf_list,
rxt.sta_id = sta_id;
rxt.rx_buf_list = rx_buf_list;
-
hdd_ipa_process_evt(HDD_IPA_RXT_EVT, &rxt);
return VOS_STATUS_SUCCESS;
@@ -814,174 +804,88 @@ void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
uint8_t client;
struct ipa_tx_data_desc *done_desc_head;
adf_nbuf_t skb;
- uint8_t sta_id;
+ uint8_t sta_id, dev_id;
hdd_adapter_t *adap_dev=NULL;
client = *((uint8_t *)priv);
- if (client != hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE]) {
+ if (client != hdd_ipa_pipe_client[HDD_IPA_RX_PIPE]) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
"w2i cb wrong pipe: %d %x %x",
client, priv,
- &hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE]);
+ &hdd_ipa_pipe_client[HDD_IPA_RX_PIPE]);
return;
}
switch (evt) {
case IPA_RECEIVE:
skb = (adf_nbuf_t) data;
- sta_id = ((struct ipa_rx_hdr *)(skb->data))->hdr[HDD_IPA_WLAN_HDR_STA_ID_OFFSET];
-
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "w2i -- skb:0x%p: %02x %02x %02x %02x %02x %02x %02x %02x", skb,
- skb->data[0], skb->data[1], skb->data[2], skb->data[3],
- skb->data[4], skb->data[5], skb->data[6], skb->data[7]);
-
- skb_pull(skb, HDD_IPA_WLAN_HDR_ONLY_LEN);
-
+ sta_id = skb->data[HDD_IPA_WLAN_HDR_STA_ID_OFFSET];
+ dev_id = skb->data[HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET];
if (sta_id < ARRAY_SIZE(hdd_ipa->hdd_ctx->sta_to_adapter)) {
adap_dev = hdd_ipa->hdd_ctx->sta_to_adapter[sta_id];
} else {
HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
- "w2i cb: wrong sta_id: %d", sta_id);
+ "w2i cb: wrong sta_id: %d", sta_id);
}
-
+ skb_pull(skb, HDD_IPA_WLAN_HDR_ONLY_LEN);
hdd_ipa->stats.rx_ipa_excep++;
hdd_ipa_send_skb_to_network(skb, adap_dev);
break;
case IPA_WRITE_DONE:
done_desc_head = (struct ipa_tx_data_desc *)data;
hdd_ipa_w2i_write_done_handler(done_desc_head);
- break;
- default:
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
- "w2i cb wrong event: 0x%x", evt);
- return;
+ break;
}
}
void hdd_ipa_nbuf_cb(adf_nbuf_t skb)
{
- struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
-
- /* TX COMP counter at frame free location. */
- hdd_ipa->stats.tx_comp_cnt++;
-
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "0x%p", NBUF_OWNER_PRIV_DATA(skb));
- ipa_free_skb((struct ipa_rx_data *) NBUF_OWNER_PRIV_DATA(skb));
+ ipa_free_skb(skb);
}
-#ifdef WLAN_TX_MUL
-void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
+void hdd_ipa_tx_process(adf_nbuf_t skb, uint8_t ac)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
- struct ipa_rx_data_mul *ipa_tx_desc;
- adf_nbuf_t skb;
- uint8_t client, pipe_id;
-
- if (evt == IPA_RECEIVE) {
- client = *((uint8_t *)priv);
- struct list_head *head = (struct list_head *)data;
-
- pipe_id = ipa_client_id_2_hdd_pipe_id[client];
-
- if (hdd_ipa->pipe_to_vdev[pipe_id] == NULL) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail (vdev=NULL)");
- /* TODO: need to free ipa_desc and skb here */
- return;
- }
-
- list_for_each_entry(ipa_tx_desc, head, link) {
- if (ipa_tx_desc->dd == NULL)
- break;
-
- /* TX frame Counter at HDD CB function called by IPA loopback, to push lower layer.*/
- hdd_ipa->stats.tx_ipa_recv++;
-
- skb = ipa_tx_desc->dd->skb;
-
- /* skb->dev = ipa_client_id_2_hdd_pipe_id[client]; */
- adf_os_mem_set(skb->cb, 0, sizeof(skb->cb));
- NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID;
- NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb;
- NBUF_MAPPED_PADDR_LO(skb) = ipa_tx_desc->dd->dma_addr;
-
- NBUF_OWNER_PRIV_DATA(skb) = (unsigned long)ipa_tx_desc->dd;
-
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "skb:0x%p: %02x %02x %02x %02x %02x %02x %02x %02x", skb,
- skb->data[0], skb->data[1], skb->data[2], skb->data[3],
- skb->data[4], skb->data[5], skb->data[6], skb->data[7]);
-
- skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext, hdd_ipa->pipe_to_vdev[pipe_id],
- ipa_tx_desc->dd->skb);
- if (skb) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail");
- ipa_free_skb(ipa_tx_desc->dd);
- continue;
- }
- }
- ipa_free_desc(data);
+ uint8_t sta_id;
+ hdd_adapter_t *adap_dev;
- } else {
- /* HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "i2w cb wrong evt: %d", evt);
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Testing hack code data path"); */
- skb = (adf_nbuf_t) data;
- dev_kfree_skb_any(skb);
+ skb->queue_mapping = ac;
+ sta_id = skb->data[HDD_IPA_WLAN_HDR_STA_ID_OFFSET];
+ adap_dev = hdd_ipa->hdd_ctx->sta_to_adapter[sta_id];
+ if (!adap_dev
+ || (adap_dev && adap_dev->magic != WLAN_HDD_ADAPTER_MAGIC)) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid sta_id %d", sta_id);
+ ipa_free_skb(skb);
+ return;
}
+ skb->dev = adap_dev->dev;
+ NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID;
+ NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb;
+ skb_pull(skb, HDD_IPA_WLAN_HDR_ONLY_LEN);
+ (adap_dev->dev->netdev_ops->ndo_start_xmit)(skb, adap_dev->dev);
}
-#else
-
void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
- struct ipa_rx_data *ipa_tx_desc;
adf_nbuf_t skb;
- uint8_t client, pipe_id;
+ uint8_t client;
+ uint8_t i, ac = HDD_LINUX_AC_BE;
if (evt == IPA_RECEIVE) {
- /* TX frame Counter at HDD CB function called by IPA loopback, to push lower layer */
- hdd_ipa->stats.tx_ipa_recv++;
-
client = *((uint8_t *)priv);
- ipa_tx_desc = (struct ipa_rx_data *)data;
- skb = ipa_tx_desc->skb;
-
- adf_os_mem_set(skb->cb, 0, sizeof(skb->cb));
- NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID;
- NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb;
- NBUF_MAPPED_PADDR_LO(skb) = ipa_tx_desc->dma_addr;
-
- NBUF_OWNER_PRIV_DATA(skb) = data;
-
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "0x%p", NBUF_OWNER_PRIV_DATA(skb));
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "skb:0x%p: %02x %02x %02x %02x %02x %02x %02x %02x", skb,
- skb->data[0], skb->data[1], skb->data[2], skb->data[3],
- skb->data[4], skb->data[5], skb->data[6], skb->data[7]);
-
- pipe_id = ipa_client_id_2_hdd_pipe_id[client];
-
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "client=%d, pipe_to_vdev[%d]=0x%x", client, pipe_id, hdd_ipa->pipe_to_vdev[pipe_id]);
-
- if (hdd_ipa->pipe_to_vdev[pipe_id] == NULL) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail (pipe_to_vdev[%d]=NULL)", pipe_id);
- ipa_free_skb(ipa_tx_desc);
- return;
- }
-
- skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext, hdd_ipa->pipe_to_vdev[pipe_id],
- ipa_tx_desc->skb);
- if (skb) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail");
- ipa_free_skb(ipa_tx_desc);
- return;
- }
- } else {
- /* HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "i2w cb wrong evt: %d", evt);
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Testing hack code data path"); */
skb = (adf_nbuf_t) data;
- dev_kfree_skb_any(skb);
- }
+ for (i = 0; i < HDD_IPA_MAX_TX_PIPE_MAP; i++) {
+ if (client == hdd_ipa_tx_pipe_map_info[i].client) {
+ ac = hdd_ipa_tx_pipe_map_info[i].ac;
+ break;
+ }
+ }
+ hdd_ipa->stats.tx_ipa_recv++;
+ hdd_ipa_tx_process(skb, ac);
+ } else
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "i2w cb wrong evt: %d", evt);
}
-#endif
static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa)
{
@@ -992,9 +896,9 @@ static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa)
for (i = 0; i < HDD_IPA_RX_PIPE; i++) {
ipa = &hdd_ipa->sys_pipe[i].ipa_sys_params;
- ipa->client = hdd_pipe_id_2_ipa_client_id[i];
+ ipa->client = hdd_ipa_pipe_client[i];
ipa->desc_fifo_sz = hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize;
- ipa->priv = &hdd_pipe_id_2_ipa_client_id[i];
+ ipa->priv = &hdd_ipa_pipe_client[i];
ipa->notify = hdd_ipa_i2w_cb;
ipa->ipa_ep_cfg.hdr.hdr_len = HDD_IPA_WLAN_TX_HDR_LEN;
@@ -1010,9 +914,9 @@ static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa)
ipa = &hdd_ipa->sys_pipe[HDD_IPA_RX_PIPE].ipa_sys_params;
- ipa->client = hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE];
- ipa->desc_fifo_sz = hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize + sizeof(struct sps_iovec); /* To make sure total # of desc is 1 less than the desc FIFO size */
- ipa->priv = &hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE];
+ ipa->client = hdd_ipa_pipe_client[HDD_IPA_RX_PIPE];
+ ipa->desc_fifo_sz = hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize;
+ ipa->priv = &hdd_ipa_pipe_client[HDD_IPA_RX_PIPE];
ipa->notify = hdd_ipa_w2i_cb;
ipa->ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT;
@@ -1048,8 +952,10 @@ void hdd_ipa_teardown_sys_pipe(struct hdd_ipa_priv *hdd_ipa)
}
}
-int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t sta_id, const char *ifname)
+int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t iftype,
+ uint8_t sta_id, const char *ifname)
{
+#define HDD_IPA_TOS_MASK 0xE0
struct ipa_tx_intf tx_intf;
struct ipa_rx_intf rx_intf;
struct ipa_ioc_tx_intf_prop *tx_prop = NULL;
@@ -1058,21 +964,23 @@ int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t sta_id, con
char ipv4_hdr_name[IPA_RESOURCE_NAME_MAX];
char ipv6_hdr_name[IPA_RESOURCE_NAME_MAX];
- int ip_max = HDD_IPA_IPV4;
+ int i, j, ip_max = HDD_IPA_IPV4;
int ret = 0;
if (hdd_ipa_is_ipv6_enabled(hdd_ipa))
ip_max = HDD_IPA_IPV6;
/* Allocate TX properties for TOS categories, 1 each for IPv4 & IPv6 */
- tx_prop = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_tx_intf_prop) * ip_max);
+ tx_prop = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_tx_intf_prop) *
+ HDD_IPA_MAX_TX_PIPE_MAP * ip_max);
if (!tx_prop) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ENOMEM");
goto register_interface_fail;
}
/* Allocate RX properties, 1 each for IPv4 & IPv6 */
- rx_prop = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_rx_intf_prop) * ip_max);
+ rx_prop = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_rx_intf_prop)
+ * ip_max);
if (!rx_prop) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ENOMEM");
goto register_interface_fail;
@@ -1082,28 +990,72 @@ int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t sta_id, con
snprintf(ipv4_hdr_name, IPA_RESOURCE_NAME_MAX, "%s%s",
ifname, HDD_IPA_IPV4_NAME_EXT);
- snprintf(ipv6_hdr_name, IPA_RESOURCE_NAME_MAX, "%s%s",
- ifname, HDD_IPA_IPV6_NAME_EXT);
-
rx_prop[IPA_IP_v4].ip = IPA_IP_v4;
- rx_prop[IPA_IP_v4].src_pipe = IPA_CLIENT_WLAN1_PROD;
- rx_intf.num_props++;
if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) {
+ snprintf(ipv6_hdr_name, IPA_RESOURCE_NAME_MAX, "%s%s",
+ ifname, HDD_IPA_IPV6_NAME_EXT);
rx_prop[IPA_IP_v6].ip = IPA_IP_v6;
- rx_prop[IPA_IP_v6].src_pipe = IPA_CLIENT_WLAN1_PROD;
- rx_intf.num_props++;
}
-
- tx_prop[IPA_IP_v4].ip = IPA_IP_v4;
- tx_prop[IPA_IP_v4].dst_pipe = hdd_pipe_id_2_ipa_client_id[wlan_sta_id_2_hdd_pipe_id[sta_id]];
- strlcpy(tx_prop[IPA_IP_v4].hdr_name, ipv4_hdr_name, IPA_RESOURCE_NAME_MAX);
- tx_intf.num_props++;
- if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) {
- tx_prop[IPA_IP_v6].ip = IPA_IP_v6;
- tx_prop[IPA_IP_v6].dst_pipe = hdd_pipe_id_2_ipa_client_id[wlan_sta_id_2_hdd_pipe_id[sta_id]];
- strlcpy(tx_prop[IPA_IP_v6].hdr_name, ipv6_hdr_name,
- IPA_RESOURCE_NAME_MAX);
+ /*
+ TOS value: 1, 2 - > Maps to BK pipe [WLAN1_CONS]
+ TOS value: 0, 3 - > Maps to BE pipe [WLAN2_CONS]
+ TOS value: 4, 5 - > Maps to VI pipe [WLAN3_CONS]
+ TOS Value: 6, 7 - > Maps to VO pipe [WLAN4_CONS]
+ */
+
+ /*
+ IP-TOS - 8bits
+ : DSCP(6-bits) ECN(2-bits)
+ : DSCP - P2 P1 P0 X X X
+ where (P2 P1 P0) form 802.1D
+ So shifting tos_value by 5 bits before passing to IPA. Also IPA
+ required mask to be set for 3 MSB bits.
+ */
+
+ for (i = 0; i < HDD_IPA_MAX_TX_PIPE_MAP; i++) {
+ tx_prop[i].ip = IPA_IP_v4;
+ tx_prop[i].attrib.attrib_mask = IPA_FLT_TOS_MASKED;
+ tx_prop[i].attrib.tos_value =
+ hdd_ipa_tx_pipe_map_info[i].tos_value << 5;
+ tx_prop[i].attrib.tos_mask = HDD_IPA_TOS_MASK;
+ tx_prop[i].dst_pipe = hdd_ipa_tx_pipe_map_info[i].client;
+ strlcpy(tx_prop[i].hdr_name, ipv4_hdr_name,
+ IPA_RESOURCE_NAME_MAX);
tx_intf.num_props++;
+ if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) {
+ j = i + HDD_IPA_MAX_TX_PIPE_MAP;
+
+ tx_prop[j].ip = IPA_IP_v6;
+ tx_prop[j].attrib.attrib_mask = IPA_FLT_TOS_MASKED;
+ tx_prop[j].attrib.tos_value =
+ hdd_ipa_tx_pipe_map_info[i].tos_value << 5;
+ tx_prop[j].attrib.tos_mask = HDD_IPA_TOS_MASK;
+ tx_prop[j].dst_pipe =
+ hdd_ipa_tx_pipe_map_info[i].client;
+ strlcpy(tx_prop[j].hdr_name, ipv6_hdr_name,
+ IPA_RESOURCE_NAME_MAX);
+ tx_intf.num_props++;
+ }
+ }
+
+ for (i = 0; i < ip_max; i++) {
+ rx_prop[i].attrib.attrib_mask = IPA_FLT_META_DATA;
+ if (iftype == NL80211_IFTYPE_AP ||
+ iftype == NL80211_IFTYPE_P2P_GO) {
+ rx_prop[i].attrib.meta_data =
+ HDD_IPA_WLAN_HDR_DEV_TYPE_AP
+ << ((HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET-1) * 8);
+ } else {
+ rx_prop[i].attrib.meta_data =
+ HDD_IPA_WLAN_HDR_DEV_TYPE_STA
+ << ((HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET-1) * 8);
+ }
+ rx_prop[i].attrib.meta_data_mask =
+ HDD_IPA_WLAN_HDR_DEV_TYPE_MASK
+ << ((HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET-1) * 8);
+ rx_prop[i].src_pipe = IPA_CLIENT_WLAN1_PROD;
+
+ rx_intf.num_props++;
}
tx_intf.prop = tx_prop;
@@ -1118,15 +1070,14 @@ register_interface_fail:
return ret;
}
-static int hdd_ipa_add_header_info(enum ipa_wlan_event type, uint8_t sta_id, uint8_t *mac_addr)
+static int hdd_ipa_add_header_info(uint8_t sta_id, uint8_t *mac_addr)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
+ uint8_t dev_id, wlan_iftype;
char *ifname;
struct ipa_ioc_add_hdr *ipahdr = NULL;
- int i, ret = -EINVAL;
+ int ret = -EINVAL;
hdd_adapter_t *adap_dev;
- struct ol_txrx_pdev_t *pdev;
- struct ol_txrx_vdev_t *vdev;
adap_dev = hdd_ipa->hdd_ctx->sta_to_adapter[sta_id];
if (!adap_dev) {
@@ -1134,40 +1085,12 @@ static int hdd_ipa_add_header_info(enum ipa_wlan_event type, uint8_t sta_id, uin
goto add_header_info_ctx_fail;
}
+ dev_id = adap_dev->dev->ifindex;
+ wlan_iftype = adap_dev->wdev.iftype;
ifname = adap_dev->dev->name;
- for (i = 0; i < HDD_IPA_MAX_PIPE; i++)
- hdd_ipa->pipe_to_vdev[i] = NULL;
-
- if (wlan_sta_id_2_hdd_pipe_id[sta_id] == 0xFF) {
- switch (type) {
- case WLAN_AP_CONNECT:
- wlan_sta_id_2_hdd_pipe_id[sta_id] = HDD_IPA_TX_WLAN0_PIPE; /* TODO: need to expand to AP+AP */
- break;
- case WLAN_STA_CONNECT:
- /* Register pipe_to_vdev for STA mode */
- pdev = ((pVosContextType)(WLAN_HDD_GET_CTX(adap_dev)->pvosContext))->pdev_txrx_ctx;
- /* find the "vdev" this STA interface belongs to */
- TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
- if (adf_os_mem_cmp(mac_addr, vdev->mac_addr.raw, IEEE80211_ADDR_LEN) == 0) {
- hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN2_PIPE] = vdev;
- break;
- }
- }
-
- wlan_sta_id_2_hdd_pipe_id[sta_id] = HDD_IPA_TX_WLAN2_PIPE; /* STA Mode */
- break;
- default:
- break;
- }
- }
-
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, " wlan_sta_id_2_hdd_pipe_id[%d]: %d",
- sta_id, wlan_sta_id_2_hdd_pipe_id[sta_id]);
-
-
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ifindex: %d Add Partial hdr: %s, %p\n",
- sta_id, ifname, mac_addr);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Mode: %d Add Partial hdr: %s, %p\n",
+ wlan_iftype, ifname, mac_addr);
if (ifname == NULL) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ifname NULL");
goto add_header_info_ctx_fail;
@@ -1184,19 +1107,29 @@ static int hdd_ipa_add_header_info(enum ipa_wlan_event type, uint8_t sta_id, uin
ipahdr->commit = 0;
ipahdr->num_hdrs = 1;
/* Set the Source MAC */
- memcpy(ipahdr->hdr[0].hdr, (uint8_t *)&ipa_set_tx_hdr, HDD_IPA_WLAN_TX_HDR_LEN);
- memcpy((uint8_t *)(((struct ipa_tx_hdr *)(ipahdr->hdr[0].hdr))->eth.h_source), mac_addr,
+ memcpy(ipahdr->hdr[0].hdr, ipa_set_tx_hdr, HDD_IPA_WLAN_TX_HDR_LEN);
+ memcpy(&ipahdr->hdr[0].hdr[HDD_IPA_WLAN_HDR_SRC_MAC_OFFSET], mac_addr,
ETH_ALEN);
+ /* Check the interface is AP OR STA mode, and set the station ID */
+ ipahdr->hdr[0].hdr[HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET] |=
+ dev_id & HDD_IPA_WLAN_HDR_DEV_ID_MASK;
+ ipahdr->hdr[0].hdr[HDD_IPA_WLAN_HDR_STA_ID_OFFSET] = sta_id;
+ if (wlan_iftype == NL80211_IFTYPE_AP ||
+ wlan_iftype == NL80211_IFTYPE_P2P_GO) {
+ ipahdr->hdr[0].hdr[HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET] |=
+ HDD_IPA_WLAN_HDR_DEV_TYPE_AP;
+ } else {
+ ipahdr->hdr[0].hdr[HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET] |=
+ HDD_IPA_WLAN_HDR_DEV_TYPE_STA;
+ }
+
snprintf(ipahdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
ifname, HDD_IPA_IPV4_NAME_EXT);
ipahdr->hdr[0].hdr_len = HDD_IPA_WLAN_TX_HDR_LEN;
ipahdr->hdr[0].is_partial = HDD_IPA_WLAN_HDR_PARTIAL;
ipahdr->hdr[0].hdr_hdl = 0;
- /* Set the type to IPV4 in the header*/
- ((struct ipa_tx_hdr *)(ipahdr->hdr[0].hdr))->llc_snap.eth_type = cpu_to_be16(ETH_P_IP);
-
ret = ipa_add_hdr(ipahdr);
if (ret) {
@@ -1211,7 +1144,8 @@ static int hdd_ipa_add_header_info(enum ipa_wlan_event type, uint8_t sta_id, uin
snprintf(ipahdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
ifname, HDD_IPA_IPV6_NAME_EXT);
/* Set the type to IPV6 in the header*/
- ((struct ipa_tx_hdr *)(ipahdr->hdr[0].hdr))->llc_snap.eth_type = cpu_to_be16(ETH_P_IPV6);
+ ipahdr->hdr[0].hdr[HDD_IPA_WLAN_TX_HDR_IP_VER_OFFSET] = 0x86;
+ ipahdr->hdr[0].hdr[HDD_IPA_WLAN_TX_HDR_IP_VER_OFFSET + 1] = 0xdd;
ret = ipa_add_hdr(ipahdr);
if (ret) {
@@ -1224,7 +1158,7 @@ static int hdd_ipa_add_header_info(enum ipa_wlan_event type, uint8_t sta_id, uin
ipahdr->hdr[0].name, ipahdr->hdr[0].hdr_hdl);
}
/* Configure the TX and RX pipes filter rules */
- ret = hdd_ipa_register_interface(hdd_ipa, sta_id, ifname);
+ ret = hdd_ipa_register_interface(hdd_ipa, wlan_iftype, sta_id, ifname);
add_header_info_fail:
adf_os_mem_free(ipahdr);
@@ -1272,8 +1206,6 @@ void hdd_ipa_clean_hdr(hdd_adapter_t *adap_dev, uint8_t sta_id)
int ret;
char name_ipa[IPA_RESOURCE_NAME_MAX];
- wlan_sta_id_2_hdd_pipe_id[sta_id] = 0xFF;
-
/* Remove the headers */
snprintf(name_ipa, IPA_RESOURCE_NAME_MAX, "%s%s",
adap_dev->dev->name, HDD_IPA_IPV4_NAME_EXT);
@@ -1301,7 +1233,6 @@ static void hdd_ipa_msg_free_fn(void *buff, uint32_t len, uint32_t type)
int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id,
enum ipa_wlan_event type, uint8_t *mac_addr)
{
- struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
hdd_adapter_t *adap_dev = Adapter;
struct ipa_msg_meta meta;
struct ipa_wlan_msg *msg;
@@ -1320,7 +1251,7 @@ int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id,
__stringify(WLAN_STA_DISCONNECT),
__stringify(WLAN_CLIENT_CONNECT_EX),
};
- struct ol_txrx_peer_t *peer;
+
HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: %s evt, MAC: %pM sta_id: %d",
adap_dev->dev->name, hdd_ipa_event_name[type],
@@ -1334,42 +1265,33 @@ int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id,
switch (type) {
case WLAN_STA_CONNECT:
case WLAN_AP_CONNECT:
- hdd_ipa_add_header_info(type, sta_id, mac_addr);
+ hdd_ipa_add_header_info(sta_id, mac_addr);
break;
case WLAN_STA_DISCONNECT:
- hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN2_PIPE] = NULL;
case WLAN_AP_DISCONNECT:
hdd_ipa_clean_hdr(adap_dev, sta_id);
break;
case WLAN_CLIENT_CONNECT_EX:
- /* Register pipe map to txrx_vdev into hdd_ipa */
- peer = ol_txrx_peer_find_by_local_id(((pVosContextType)(WLAN_HDD_GET_CTX(adap_dev))->pvosContext)->pdev_txrx_ctx, sta_id);
- if (!peer) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid peer");
- return -EINVAL;
- }
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%d %d", adap_dev->dev->ifindex, sta_id);
- if (hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN0_PIPE] == NULL) {
- hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN0_PIPE] = peer->vdev; /* TODO: need to expand to AP+AP */
- }
-
meta.msg_type = type;
meta.msg_len = (sizeof(struct ipa_wlan_msg_ex) +
- sizeof(struct ipa_wlan_hdr_attrib_val));
+ sizeof(struct ipa_wlan_hdr_attrib_val) * 2);
msg_ex = hdd_ipa_kzalloc (meta.msg_len);
if (msg_ex == NULL) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ENOMEM");
return -ENOMEM;
}
strlcpy(msg_ex->name, adap_dev->dev->name, IPA_RESOURCE_NAME_MAX);
- msg_ex->num_of_attribs = 1;
+ msg_ex->num_of_attribs = 2;
msg_ex->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR;
msg_ex->attribs[0].offset = HDD_IPA_WLAN_HDR_DES_MAC_OFFSET;
memcpy(msg_ex->attribs[0].u.mac_addr, mac_addr,
IPA_MAC_ADDR_SIZE);
+ msg_ex->attribs[1].attrib_type = WLAN_HDR_ATTRIB_STA_ID;
+ msg_ex->attribs[1].offset = HDD_IPA_WLAN_HDR_STA_ID_OFFSET;
+ msg_ex->attribs[1].u.sta_id = sta_id;
ret = ipa_send_msg(&meta, msg_ex, hdd_ipa_msg_free_fn);
if (ret) {
@@ -1380,9 +1302,6 @@ int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id,
}
return 0;
case WLAN_CLIENT_DISCONNECT:
- /* TODO: need to expand to AP+AP */
- /* This will remove the vdev for rest of the connected clients */
- //hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN0_PIPE] = NULL;
break;
default:
@@ -1418,7 +1337,7 @@ static int hdd_ipa_rx_pipe_desc_alloc(void)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
uint32_t i, max_desc_cnt;
- int ret = 0;
+ int ret =0;
struct ipa_tx_data_desc *tmp_desc;
hdd_ipa->hw_desc_cnt = IPA_NUM_OF_FIFO_DESC(
@@ -1541,6 +1460,11 @@ static ssize_t hdd_ipa_debugfs_read_ipa_stats(struct file *file,
"RXT 5 skb:", hdd_ipa->stats.rxt_5);
len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n",
"RXT > 5 skb:", hdd_ipa->stats.rxt_6);
+#endif
+ len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n",
+ "IPA TX Recieve:", hdd_ipa->stats.tx_ipa_recv);
+
+#ifdef HDD_IPA_EXTRA_DP_COUNTERS
len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
"Free Queue use:", hdd_ipa->stats.freeq_use);
len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
@@ -1550,14 +1474,7 @@ static ssize_t hdd_ipa_debugfs_read_ipa_stats(struct file *file,
"Free Queue Empty:", hdd_ipa->stats.freeq_empty);
len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n",
"Free Queue cnt:", hdd_ipa->stats.freeq_cnt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n",
- "IPA LB Count:", hdd_ipa->stats.ipa_lb_cnt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n",
- "IPA TX Recieve:", hdd_ipa->stats.tx_ipa_recv);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n",
- "TX COMP Count:", hdd_ipa->stats.tx_comp_cnt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n",
- "TX DP Err Count:", hdd_ipa->stats.tx_dp_err_cnt);
+
if (len > buf_len)
len = buf_len;
@@ -1568,10 +1485,10 @@ static ssize_t hdd_ipa_debugfs_read_ipa_stats(struct file *file,
}
static const struct file_operations fops_ipa_stats = {
- .read = hdd_ipa_debugfs_read_ipa_stats,
- .open = simple_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
+ .read = hdd_ipa_debugfs_read_ipa_stats,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
};
@@ -1580,7 +1497,7 @@ int hdd_ipa_debugfs_init(struct hdd_ipa_priv *hdd_ipa)
#ifdef WLAN_OPEN_SOURCE
hdd_ipa->debugfs_dir = debugfs_create_dir("cld",
hdd_ipa->hdd_ctx->wiphy->debugfsdir);
- if (!hdd_ipa->debugfs_dir)
+ if(!hdd_ipa->debugfs_dir)
return -ENOMEM;
debugfs_create_file("ipa-stats", S_IRUSR, hdd_ipa->debugfs_dir,
@@ -1600,13 +1517,10 @@ int hdd_ipa_debugfs_init(struct hdd_ipa_priv *hdd_ipa)
VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx)
{
struct hdd_ipa_priv *hdd_ipa = NULL;
- int ret, i;
+ int ret;
if (!hdd_ipa_is_enabled(hdd_ctx))
return 0;
- for (i = 0; i < HDD_IPA_WLAN_MAX_STA_ID; i++)
- wlan_sta_id_2_hdd_pipe_id[i] = 0xFF;
-
hdd_ipa = hdd_ipa_kzalloc(sizeof(struct hdd_ipa_priv));
if (!hdd_ipa) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "ENOMEM");
@@ -1671,68 +1585,6 @@ VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx)
return VOS_STATUS_SUCCESS;
}
-#if 0
-/**
-* hdd_ipa_start_xmit() - This is a hack code for IPA loopback test
-*/
-int hdd_ipa_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
- hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
- uint8_t sta_id;
- struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
-
- v_MACADDR_t *pDestMacAddress = (v_MACADDR_t *)skb->data;
-
- if (vos_is_macaddr_broadcast(pDestMacAddress) ||
- vos_is_macaddr_group(pDestMacAddress)) {
- /* The BC/MC station ID is assigned during BSS starting phase.
- SAP will return the station ID used for BC/MC traffic. */
- sta_id = pHddApCtx->uBCStaId;
- hdd_softap_hard_start_xmit(skb, dev);
- return NETDEV_TX_OK;
- } else {
- sta_id = *(uint8_t *)(((uint8_t *)(skb->data)) - 1);
- if (sta_id == HDD_WLAN_INVALID_STA_ID) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN,
- "Failed to find right station");
- goto drop_pkt;
- } else if (FALSE == pAdapter->aStaInfo[sta_id].isUsed) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN,
- "STA %d is unregistered", sta_id);
- goto drop_pkt;
- }
-
- if ((WLANTL_STA_CONNECTED !=
- pAdapter->aStaInfo[sta_id].tlSTAState) &&
- (WLANTL_STA_AUTHENTICATED !=
- pAdapter->aStaInfo[sta_id].tlSTAState)) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN,
- "Station not connected yet");
- goto drop_pkt;
- } else if (WLANTL_STA_CONNECTED ==
- pAdapter->aStaInfo[sta_id].tlSTAState) {
- if (ntohs(skb->protocol) !=
- HDD_ETHERTYPE_802_1_X) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN,
- "NON-EAPOL packet in no-Auth state");
- goto drop_pkt;
- }
- }
- }
- if (hdd_ipa_is_ip_pkt(skb->data, HDD_IPA_IPV4)) {
- /* TX frame Counter at HDD entry from kernel network stack, before give frame to IPA Loopback */
- hdd_ipa->stats.ipa_lb_cnt++;
- ipa_tx_dp(IPA_CLIENT_WLAN1_CONS, skb, NULL);
- } else {
- hdd_softap_hard_start_xmit(skb, dev);
- }
-
- return NETDEV_TX_OK;
-drop_pkt:
- kfree_skb(skb);
- return NETDEV_TX_OK;
-}
#endif
-#endif
+
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 0a4fcff7999a..500f73ad0f30 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -180,6 +180,7 @@ static VOS_STATUS hdd_parse_ccx_beacon_req(tANI_U8 *pValue,
* Maximum buffer size used for returning the data back to user space
*/
#define WLAN_MAX_BUF_SIZE 1024
+#define WLAN_PRIV_DATA_MAX_LEN 4096
/*
* Driver miracast parameters 0-Disabled
@@ -726,6 +727,11 @@ hdd_extract_assigned_int_from_str
{
return NULL;
}
+
+ if (tempInt < 0)
+ {
+ tempInt = 0;
+ }
*pOutPtr = tempInt;
pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
@@ -1760,7 +1766,8 @@ int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
goto exit;
}
- if (priv_data.total_len <= 0)
+ if (priv_data.total_len <= 0 ||
+ priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
"%s:invalid priv_data.total_len(%d)!!!", __func__,
@@ -2556,7 +2563,6 @@ int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
tANI_U8 *value = command;
tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
- tANI_U16 homeAwayTime = 0;
/* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
value = value + 19;
@@ -2590,21 +2596,6 @@ int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
"%s: Received Command to change channel max time = %d", __func__, maxTime);
pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
-
- /* Home Away Time should be atleast equal to (MaxDwell time + (2*RFS)),
- * where RFS is the RF Switching time. It is twice RFS to consider the
- * time to go off channel and return to the home channel. */
- homeAwayTime = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
- if (homeAwayTime < (maxTime + (2 * HDD_ROAM_SCAN_CHANNEL_SWITCH_TIME)))
- {
- VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
- "%s: Invalid config, Home away time(%d) is less than (twice RF switching time + channel max time)(%d)"
- " Hence enforcing home away time to disable (0)",
- __func__, homeAwayTime, (maxTime + (2 * HDD_ROAM_SCAN_CHANNEL_SWITCH_TIME)));
- homeAwayTime = 0;
- pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
- sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_FALSE);
- }
sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
}
else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
@@ -2793,7 +2784,6 @@ int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
tANI_U8 *value = command;
tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
- tANI_U16 scanChannelMaxTime = 0;
/* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
/* input value is in units of msec */
@@ -2826,20 +2816,6 @@ int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
"%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
-
- /* Home Away Time should be atleast equal to (MaxDwell time + (2*RFS)),
- * where RFS is the RF Switching time. It is twice RFS to consider the
- * time to go off channel and return to the home channel. */
- scanChannelMaxTime = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
- if (homeAwayTime < (scanChannelMaxTime + (2 * HDD_ROAM_SCAN_CHANNEL_SWITCH_TIME)))
- {
- VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
- "%s: Invalid config, Home away time(%d) is less than (twice RF switching time + channel max time)(%d)"
- " Hence enforcing home away time to disable (0)",
- __func__, homeAwayTime, (scanChannelMaxTime + (2 * HDD_ROAM_SCAN_CHANNEL_SWITCH_TIME)));
- homeAwayTime = 0;
- }
-
if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
{
pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
@@ -3443,8 +3419,9 @@ int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
goto exit;
}
- if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
- (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode))
+ if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
+ (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
+ (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
{
VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"Received WLS_BATCHING_VERSION command in invalid mode %d "
@@ -3953,7 +3930,7 @@ static VOS_STATUS hdd_parse_ccx_beacon_req(tANI_U8 *pValue,
if ('\0' == *inPtr) return -EINVAL;
/*getting the first argument ie measurement token*/
- v = sscanf(inPtr, "%32s ", buf);
+ v = sscanf(inPtr, "%31s ", buf);
if (1 != v) return -EINVAL;
v = kstrtos32(buf, 10, &tempInt);
@@ -3979,7 +3956,7 @@ static VOS_STATUS hdd_parse_ccx_beacon_req(tANI_U8 *pValue,
/*no ie data after the number of ie fields argument and spaces*/
if ( '\0' == *inPtr ) return -EINVAL;
- v = sscanf(inPtr, "%32s ", buf);
+ v = sscanf(inPtr, "%31s ", buf);
if (1 != v) return -EINVAL;
v = kstrtos32(buf, 10, &tempInt);
@@ -4710,6 +4687,8 @@ void hdd_update_tgt_cfg(void *context, void *param)
hdd_ctx->target_fw_version = cfg->target_fw_version;
+ hdd_ctx->max_intf_count = cfg->max_intf_count;
+
hdd_update_tgt_services(hdd_ctx, &cfg->services);
hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
@@ -4718,6 +4697,53 @@ void hdd_update_tgt_cfg(void *context, void *param)
hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap);
#endif /* #ifdef WLAN_FEATURE_11AC */
}
+
+/* This function is invoked when a radar in found on the
+ * SAP current operating channel and Data Tx from netif
+ * has to be stopped to honor the DFS regulations.
+ * Actions: Stop the netif Tx queues,Indicate Radar present
+ * in HDD context for future usage.
+ */
+void hdd_dfs_indicate_radar(void *context, void *param)
+{
+ hdd_context_t *pHddCtx= (hdd_context_t *)context;
+ struct hdd_dfs_radar_ind *hdd_radar_event =
+ (struct hdd_dfs_radar_ind*)param;
+ hdd_adapter_list_node_t *pAdapterNode = NULL,
+ *pNext = NULL;
+ hdd_adapter_t *pAdapter;
+ VOS_STATUS status;
+
+ if (pHddCtx == NULL)
+ {
+ return;
+ }
+ if (hdd_radar_event == NULL)
+ {
+ return;
+ }
+
+ if (VOS_TRUE == hdd_radar_event->dfs_radar_status)
+ {
+ pHddCtx->dfs_radar_found = VOS_TRUE;
+
+ status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
+ while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
+ {
+ pAdapter = pAdapterNode->pAdapter;
+ if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
+ {
+ netif_tx_stop_all_queues(pAdapter->dev);
+ return;
+ }
+ else
+ {
+ status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
+ pAdapterNode = pNext;
+ }
+ }
+ }
+}
#endif /* QCA_WIFI_2_0 && !QCA_WIFI_ISOC */
/**---------------------------------------------------------------------------
@@ -4748,8 +4774,8 @@ VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApB
int v = 0;
tANI_U8 tempBuf[32];
tANI_U8 tempByte = 0;
- /* 12 hexa decimal digits and 5 ':' */
- tANI_U8 macAddress[17];
+ /* 12 hexa decimal digits, 5 ':' and '\0' */
+ tANI_U8 macAddress[18];
inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
@@ -4804,7 +4830,7 @@ VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApB
}
/*getting the next argument ie the channel number */
- v = sscanf(inPtr, "%32s ", tempBuf);
+ v = sscanf(inPtr, "%31s ", tempBuf);
if (1 != v) return -EINVAL;
v = kstrtos32(tempBuf, 10, &tempInt);
@@ -4827,11 +4853,11 @@ VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApB
}
/*getting the next argument ie the dwell time */
- v = sscanf(inPtr, "%32s ", tempBuf);
+ v = sscanf(inPtr, "%31s ", tempBuf);
if (1 != v) return -EINVAL;
v = kstrtos32(tempBuf, 10, &tempInt);
- if ( v < 0 || tempInt <= 0) return -EINVAL;
+ if ( v < 0 || tempInt < 0) return -EINVAL;
*pDwellTime = tempInt;
@@ -4942,7 +4968,7 @@ VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8
}
/*getting the first argument ie the number of channels*/
- v = sscanf(inPtr, "%32s ", buf);
+ v = sscanf(inPtr, "%31s ", buf);
if (1 != v) return -EINVAL;
v = kstrtos32(buf, 10, &tempInt);
@@ -4993,7 +5019,7 @@ VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8
}
}
- v = sscanf(inPtr, "%32s ", buf);
+ v = sscanf(inPtr, "%31s ", buf);
if (1 != v) return -EINVAL;
v = kstrtos32(buf, 10, &tempInt);
@@ -5035,8 +5061,8 @@ VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
int tempInt;
int v = 0;
tANI_U8 tempBuf[32];
- /* 12 hexa decimal digits and 5 ':' */
- tANI_U8 macAddress[17];
+ /* 12 hexa decimal digits, 5 ':' and '\0' */
+ tANI_U8 macAddress[18];
inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
@@ -5091,7 +5117,7 @@ VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
}
/*getting the next argument ie the channel number */
- v = sscanf(inPtr, "%32s ", tempBuf);
+ v = sscanf(inPtr, "%31s ", tempBuf);
if (1 != v) return -EINVAL;
v = kstrtos32(tempBuf, 10, &tempInt);
@@ -5223,7 +5249,6 @@ v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
}
else
{
- separator = -1;
/* Invalid MAC found */
return 0;
}
@@ -6495,6 +6520,16 @@ hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d\n",__func__,iface_name,session_type);
+ if (pHddCtx->current_intf_count >= pHddCtx->max_intf_count){
+ /* Max limit reached on the number of vdevs configured by the host.
+ * Return error
+ */
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: Unable to add virtual intf: currentVdevCnt=%d,hostConfiguredVdevCnt=%d",
+ __func__,pHddCtx->current_intf_count, pHddCtx->max_intf_count);
+ return NULL;
+ }
+
/*
* If Powersave Offload is enabled
* Fw will take care incase of concurrency
@@ -6695,6 +6730,10 @@ hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
goto err_free_netdev;
}
+
+ /* Adapter successfully added. Increment the vdev count */
+ pHddCtx->current_intf_count++;
+
}
return pAdapter;
@@ -6760,6 +6799,10 @@ VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
hdd_remove_adapter( pHddCtx, pAdapterNode );
vos_mem_free( pAdapterNode );
+ /* Adapter removed. Decrement vdev count */
+ if (pHddCtx->current_intf_count != 0)
+ pHddCtx->current_intf_count--;
+
#ifdef FEATURE_WLAN_TDLS
mutex_unlock(&pHddCtx->tdls_lock);
#endif
@@ -8511,8 +8554,8 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc)
adf_ctx = vos_mem_malloc(sizeof(*adf_ctx));
if (!adf_ctx) {
- hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to allocate adf_ctx");
- goto err_free_hdd_context;
+ hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to allocate adf_ctx", __func__);
+ goto err_free_hdd_context;
}
vos_mem_zero(adf_ctx, sizeof(*adf_ctx));
#ifdef QCA_WIFI_ISOC
@@ -8547,6 +8590,9 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc)
goto err_config;
}
+ pHddCtx->current_intf_count=0;
+ pHddCtx->max_intf_count = WLAN_MAX_INTERFACES;
+
#ifndef QCA_WIFI_2_0
pHddCtx->cfg_ini->maxWoWFilters = WOWL_MAX_PTRNS_ALLOWED;
#endif
@@ -8720,6 +8766,19 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc)
goto err_vosclose;
}
+ if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
+ {
+ pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
+ hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
+ __func__, enable_dfs_chan_scan);
+ }
+ if (0 == enable_11d || 1 == enable_11d)
+ {
+ pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
+ hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
+ __func__, enable_11d);
+ }
+
/* Note that the vos_preStart() sequence triggers the cfg download.
The cfg download must occur before we update the SME config
since the SME config operation must access the cfg database */
@@ -8743,19 +8802,6 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc)
the INI file and from NV before vOSS has been started so that
the final contents are available to send down to the cCPU */
- if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
- {
- pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
- hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
- __func__, enable_dfs_chan_scan);
- }
- if (0 == enable_11d || 1 == enable_11d)
- {
- pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
- hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
- __func__, enable_11d);
- }
-
// Apply the cfg.ini to cfg.dat
if (FALSE == hdd_update_config_dat(pHddCtx))
{
@@ -8973,24 +9019,32 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc)
if (country_code)
{
eHalStatus ret;
+
+ INIT_COMPLETION(pAdapter->change_country_code);
hdd_checkandupdate_dfssetting(pAdapter, country_code);
#ifndef CONFIG_ENABLE_LINUX_REG
hdd_checkandupdate_phymode(pAdapter, country_code);
#endif
- ret = sme_ChangeCountryCode(pHddCtx->hHal, NULL,
- country_code,
- pAdapter, pHddCtx->pvosContext,
- eSIR_TRUE, eSIR_TRUE);
+ ret = sme_ChangeCountryCode(pHddCtx->hHal,
+ (void *)(tSmeChangeCountryCallback)
+ wlan_hdd_change_country_code_callback,
+ country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
if (eHAL_STATUS_SUCCESS == ret)
{
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- "%s: SME Change Country code from module param fail ret=%d",
- __func__, ret);
+ ret = wait_for_completion_interruptible_timeout(
+ &pAdapter->change_country_code,
+ msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
+ if (0 >= ret)
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: SME while setting country code timed out", __func__);
+ }
}
else
{
- hddLog(VOS_TRACE_LEVEL_INFO, "%s: module country code set to %c%c",
- __func__, country_code[0], country_code[1]);
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: SME Change Country code from module param fail ret=%d", __func__, ret);
+ ret = -EINVAL;
}
}
diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c
index 1e4a7deded7a..71ae70988494 100644
--- a/CORE/HDD/src/wlan_hdd_p2p.c
+++ b/CORE/HDD/src/wlan_hdd_p2p.c
@@ -99,18 +99,42 @@ static void hdd_sendMgmtFrameOverMonitorIface( hdd_adapter_t *pMonAdapter,
tANI_U32 nFrameLength,
tANI_U8* pbFrames,
tANI_U8 frameType );
-#ifdef QCA_WIFI_2_0
-static bool hdd_p2p_is_action_type_rsp( tActionFrmType actionFrmType )
+
+static bool hdd_p2p_is_action_type_rsp( const u8 *buf )
{
- if ( actionFrmType != WLAN_HDD_GO_NEG_REQ &&
- actionFrmType != WLAN_HDD_INVITATION_REQ &&
- actionFrmType != WLAN_HDD_DEV_DIS_REQ &&
- actionFrmType != WLAN_HDD_PROV_DIS_REQ )
- return TRUE;
- else
- return FALSE;
+ tActionFrmType actionFrmType;
+ const u8 *ouiPtr;
+
+ if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_CATEGORY_OFFSET] !=
+ WLAN_HDD_PUBLIC_ACTION_FRAME ) {
+ return VOS_FALSE;
+ }
+
+ if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_ACTION_OFFSET] !=
+ WLAN_HDD_VENDOR_SPECIFIC_ACTION ) {
+ return VOS_FALSE;
+ }
+
+ ouiPtr = &buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_OFFSET];
+
+ if ( WPA_GET_BE24(ouiPtr) != WLAN_HDD_WFA_OUI ) {
+ return VOS_FALSE;
+ }
+
+ if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_TYPE_OFFSET] !=
+ WLAN_HDD_WFA_P2P_OUI_TYPE ) {
+ return VOS_FALSE;
+ }
+
+ actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
+ if ( actionFrmType != WLAN_HDD_INVITATION_REQ &&
+ actionFrmType != WLAN_HDD_GO_NEG_REQ &&
+ actionFrmType != WLAN_HDD_DEV_DIS_REQ &&
+ actionFrmType != WLAN_HDD_PROV_DIS_REQ )
+ return VOS_TRUE;
+ else
+ return VOS_FALSE;
}
-#endif
eHalStatus wlan_hdd_remain_on_channel_callback( tHalHandle hHal, void* pCtx,
eHalStatus status )
@@ -129,12 +153,9 @@ eHalStatus wlan_hdd_remain_on_channel_callback( tHalHandle hHal, void* pCtx,
hddLog( LOG1, "Received remain on channel rsp");
cfgState->remain_on_chan_ctx = NULL;
-#ifdef QCA_WIFI_2_0
+
if( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request &&
!pAdapter->internalCancelRemainOnChReq )
-#else
- if( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request )
-#endif
{
if( cfgState->buf )
{
@@ -155,9 +176,7 @@ eHalStatus wlan_hdd_remain_on_channel_callback( tHalHandle hHal, void* pCtx,
#endif
GFP_KERNEL);
}
-#ifdef QCA_WIFI_2_0
pAdapter->internalCancelRemainOnChReq = VOS_FALSE;
-#endif
if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
@@ -431,6 +450,11 @@ void hdd_remainChanReadyHandler( hdd_adapter_t *pAdapter )
if( pRemainChanCtx != NULL )
{
+ // Removing READY_EVENT_PROPOGATE_TIME from current time which gives
+ // more accurate Remain on Channel start time.
+ pRemainChanCtx->p2pRemOnChanTimeStamp =
+ vos_timer_get_system_time() - READY_EVENT_PROPOGATE_TIME;
+
if( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request )
{
cfg80211_ready_on_channel(
@@ -719,32 +743,46 @@ int wlan_hdd_action( struct wiphy *wiphy, struct net_device *dev,
if( offchan && wait)
{
int status;
+ tANI_U32 current_time = vos_timer_get_system_time();
// In case of P2P Client mode if we are already
// on the same channel then send the frame directly
-#ifdef QCA_WIFI_2_0
//For remain on channel we issue a passive scan to firmware
//but currently there is no provision for dynamically extending
//the dwell time therefore cancelling the ongoing remain on channel
//and requesting for new one.
//The below logic will be extended for request type action frames if
//needed in future.
- if ( (type == SIR_MAC_MGMT_FRAME) &&
+ if ((type == SIR_MAC_MGMT_FRAME) &&
(subType == SIR_MAC_MGMT_ACTION) &&
- (buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] ==
- WLAN_HDD_PUBLIC_ACTION_FRAME) ) {
+ hdd_p2p_is_action_type_rsp(&buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET]) &&
+ cfgState->remain_on_chan_ctx &&
+ cfgState->current_freq == chan->center_freq ) {
+
+ // In case of P2P Client mode if we are already
+ // on the same channel then send the frame directly only if
+ // there is enough remain on channel time left.
+ // If remain on channel time is about to expire in next 50ms
+ // then dont send frame without a fresh remain on channel as this may
+ // cause a race condition with lim remain_on_channel_timer which might
+ // expire by the time the action frame reaches lim layer.
+
+ // Check remaining time of RoC only in case of GO NEG CNF.
+
actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
- if ( actionFrmType < MAX_P2P_ACTION_FRAME_TYPE &&
- hdd_p2p_is_action_type_rsp(actionFrmType) &&
- cfgState->remain_on_chan_ctx &&
- cfgState->current_freq == chan->center_freq ) {
+
+ if ((actionFrmType != WLAN_HDD_GO_NEG_CNF) ||
+ ((current_time - cfgState->remain_on_chan_ctx->p2pRemOnChanTimeStamp) >
+ (cfgState->remain_on_chan_ctx->duration - 50 )))
+ {
+ hddLog(LOG1,"action frame: Extending the RoC\n");
status = wlan_hdd_check_remain_on_channel(pAdapter);
if ( !status )
pAdapter->internalCancelRemainOnChReq = VOS_TRUE;
}
}
-#endif
+
if((cfgState->remain_on_chan_ctx != NULL) &&
(cfgState->current_freq == chan->center_freq)
)
@@ -1291,7 +1329,7 @@ int wlan_hdd_add_virtual_intf( struct wiphy *wiphy, char *name,
{
hddLog(VOS_TRACE_LEVEL_ERROR,"%s: hdd_open_adapter failed",__func__);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
- return NULL;
+ return ERR_PTR(-ENOSPC);
#else
return -EINVAL;
#endif
diff --git a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
index e909b2d69f33..7d269b724701 100644
--- a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
@@ -1103,13 +1103,28 @@ VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext,
return VOS_STATUS_E_FAILURE;
}
- pAdapter = pHddCtx->sta_to_adapter[*pStaId];
- if( NULL == pAdapter )
+ STAId = *pStaId;
+ if (STAId >= WLAN_MAX_STA_COUNT)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid STAId %d passed by TL", __func__, STAId);
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ pAdapter = pHddCtx->sta_to_adapter[STAId];
+ if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
{
VOS_ASSERT(0);
return VOS_STATUS_E_FAILURE;
}
+ if (FALSE == pAdapter->aStaInfo[STAId].isUsed )
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
+ "%s: Unregistered STAId %d passed by TL", __func__, STAId);
+ return VOS_STATUS_E_FAILURE;
+ }
+
/* Monitor traffic */
if ( pHddCtx->cfg_ini->enableTrafficMonitor )
{
@@ -1132,21 +1147,6 @@ VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext,
++pAdapter->hdd_stats.hddTxRxStats.txFetched;
- STAId = *pStaId;
- if (STAId >= WLAN_MAX_STA_COUNT)
- {
- VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
- "%s: Invalid STAId %d passed by TL", __func__, STAId);
- return VOS_STATUS_E_FAILURE;
- }
-
- if (FALSE == pAdapter->aStaInfo[STAId].isUsed )
- {
- VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
- "%s: Unregistered STAId %d passed by TL", __func__, STAId);
- return VOS_STATUS_E_FAILURE;
- }
-
*ppVosPacket = NULL;
//Make sure the AC being asked for is sane
diff --git a/CORE/HDD/src/wlan_hdd_tdls.c b/CORE/HDD/src/wlan_hdd_tdls.c
index 7e9c5e6d2a20..f8f7e6cd42de 100644
--- a/CORE/HDD/src/wlan_hdd_tdls.c
+++ b/CORE/HDD/src/wlan_hdd_tdls.c
@@ -30,10 +30,6 @@
\brief WLAN Host Device Driver implementation for TDLS
- Copyright (c) 2012-2013 Qualcomm Atheros, Inc.
- All Rights Reserved.
- Qualcomm Atheros Confidential and Proprietary.
-
========================================================================*/
#include <wlan_hdd_includes.h>
diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c
index f57be8db267c..f9fcd0a9b4c9 100644
--- a/CORE/HDD/src/wlan_hdd_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_tx_rx.c
@@ -1304,7 +1304,7 @@ VOS_STATUS hdd_tx_fetch_packet_cbk( v_VOID_t *vosContext,
}
pAdapter = pHddCtx->sta_to_adapter[*pStaId];
- if( NULL == pAdapter )
+ if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
{
VOS_ASSERT(0);
return VOS_STATUS_E_FAILURE;
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index c092193455f6..e2c9a60dd69d 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -203,6 +203,15 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2},
#define WE_PPS_GID_NSTS_ZERO 52
#define WE_PPS_RSSI_CHECK 53
#define WE_ENABLE_STRICT_FCC_REG 54
+#define WE_SET_HTSMPS 55
+/* Private ioctl for QPower */
+#define WE_SET_QPOWER_MAX_PSPOLL_COUNT 56
+#define WE_SET_QPOWER_MAX_TX_BEFORE_WAKE 57
+#define WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL 58
+#define WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL 59
+
+#define WE_SET_BURST_ENABLE 60
+#define WE_SET_BURST_DUR 61
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1)
@@ -246,6 +255,14 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2},
#define WE_GET_PPS_DELIM_CRC_FAIL 38
#define WE_GET_PPS_GID_NSTS_ZERO 39
#define WE_GET_PPS_RSSI_CHECK 40
+/* Private ioctl for QPower */
+#define WE_GET_QPOWER_MAX_PSPOLL_COUNT 41
+#define WE_GET_QPOWER_MAX_TX_BEFORE_WAKE 42
+#define WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL 43
+#define WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL 44
+
+#define WE_GET_BURST_ENABLE 45
+#define WE_GET_BURST_DUR 46
#endif
/* Private ioctls and their sub-ioctls */
@@ -261,6 +278,8 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2},
#define WE_SET_AP_WPS_IE 4 //This is called in station mode to set probe rsp ie.
#define WE_SET_CONFIG 5
+#define WLAN_PRIV_SET_CHAR_GET_NONE_BUFF_MAX 512
+
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV + 4)
#define WE_SET_WLAN_DBG 1
@@ -396,6 +415,10 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2},
#endif
#define WLAN_GET_LINK_SPEED (SIOCIWFIRSTPRIV + 31)
+/* Private ioctls and their sub-ioctls */
+#define WLAN_PRIV_SET_TWO_INT_GET_NONE (SIOCIWFIRSTPRIV + 28)
+#define WE_SET_SMPS_PARAM 1
+
#define WLAN_STATS_INVALID 0
#define WLAN_STATS_RETRY_CNT 1
#define WLAN_STATS_MUL_RETRY_CNT 2
@@ -1662,7 +1685,8 @@ static int iw_get_bitrate(struct net_device *dev,
SME_GLOBAL_CLASSD_STATS |
SME_PER_STA_STATS,
hdd_StatisticsCB, 0, FALSE,
- pHddStaCtx->conn_info.staId[0], pAdapter );
+ pHddStaCtx->conn_info.staId[0], pAdapter,
+ pAdapter->sessionId );
if(eHAL_STATUS_SUCCESS != status)
{
@@ -2400,7 +2424,8 @@ VOS_STATUS wlan_hdd_get_classAstats(hdd_adapter_t *pAdapter)
0, // not periodic
FALSE, //non-cached results
pHddStaCtx->conn_info.staId[0],
- &context);
+ &context,
+ pAdapter->sessionId );
if (eHAL_STATUS_SUCCESS != hstatus)
{
hddLog(VOS_TRACE_LEVEL_ERROR,
@@ -2516,7 +2541,8 @@ VOS_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter)
0, // not periodic
FALSE, //non-cached results
pHddStaCtx->conn_info.staId[0],
- &context);
+ &context,
+ pAdapter->sessionId);
if (eHAL_STATUS_SUCCESS != hstatus)
{
hddLog(VOS_TRACE_LEVEL_ERROR,
@@ -4819,6 +4845,31 @@ static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *inf
break;
}
+ case WE_SET_BURST_ENABLE:
+ {
+ hddLog(LOG1, "SET Burst enable val %d", set_value);
+ if ((set_value == 0) || (set_value == 1)) {
+ ret = process_wma_set_command((int)pAdapter->sessionId,
+ (int)WMI_PDEV_PARAM_BURST_ENABLE,
+ set_value, PDEV_CMD);
+ }
+ else
+ ret = -EINVAL;
+ break;
+ }
+ case WE_SET_BURST_DUR:
+ {
+ hddLog(LOG1, "SET Burst duration val %d", set_value);
+ if ((set_value > 0) && (set_value <= 8192)) {
+ ret = process_wma_set_command((int)pAdapter->sessionId,
+ (int)WMI_PDEV_PARAM_BURST_DUR,
+ set_value, PDEV_CMD);
+ }
+ else
+ ret = -EINVAL;
+ break;
+ }
+
case WE_SET_TX_CHAINMASK:
{
hddLog(LOG1, "WMI_PDEV_PARAM_TX_CHAIN_MASK val %d", set_value);
@@ -4963,7 +5014,7 @@ static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *inf
hddLog(LOG1, "WMI_VDEV_PPS_PAID_MATCH val %d ", set_value);
ret = process_wma_set_command((int)pAdapter->sessionId,
(int)WMI_VDEV_PPS_PAID_MATCH,
- set_value, VDEV_CMD);
+ set_value, PPS_CMD);
break;
}
@@ -4974,7 +5025,7 @@ static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *inf
hddLog(LOG1, "WMI_VDEV_PPS_GID_MATCH val %d ", set_value);
ret = process_wma_set_command((int)pAdapter->sessionId,
(int)WMI_VDEV_PPS_GID_MATCH,
- set_value, VDEV_CMD);
+ set_value, PPS_CMD);
break;
}
@@ -4985,7 +5036,7 @@ static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *inf
hddLog(LOG1, " WMI_VDEV_PPS_EARLY_TIM_CLEAR val %d ", set_value);
ret = process_wma_set_command((int)pAdapter->sessionId,
(int)WMI_VDEV_PPS_EARLY_TIM_CLEAR,
- set_value, VDEV_CMD);
+ set_value, PPS_CMD);
break;
}
@@ -4996,7 +5047,7 @@ static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *inf
hddLog(LOG1, "WMI_VDEV_PPS_EARLY_DTIM_CLEAR val %d", set_value);
ret = process_wma_set_command((int)pAdapter->sessionId,
(int)WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
- set_value, VDEV_CMD);
+ set_value, PPS_CMD);
break;
}
@@ -5007,7 +5058,7 @@ static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *inf
hddLog(LOG1, "WMI_VDEV_PPS_EOF_PAD_DELIM val %d ", set_value);
ret = process_wma_set_command((int)pAdapter->sessionId,
(int)WMI_VDEV_PPS_EOF_PAD_DELIM,
- set_value, VDEV_CMD);
+ set_value, PPS_CMD);
break;
}
@@ -5018,7 +5069,7 @@ static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *inf
hddLog(LOG1, "WMI_VDEV_PPS_MACADDR_MISMATCH val %d ", set_value);
ret = process_wma_set_command((int)pAdapter->sessionId,
(int)WMI_VDEV_PPS_MACADDR_MISMATCH,
- set_value, VDEV_CMD);
+ set_value, PPS_CMD);
break;
}
@@ -5029,7 +5080,7 @@ static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *inf
hddLog(LOG1, "WMI_VDEV_PPS_DELIM_CRC_FAIL val %d ", set_value);
ret = process_wma_set_command((int)pAdapter->sessionId,
(int)WMI_VDEV_PPS_DELIM_CRC_FAIL,
- set_value, VDEV_CMD);
+ set_value, PPS_CMD);
break;
}
@@ -5041,7 +5092,7 @@ static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *inf
hddLog(LOG1, "WMI_VDEV_PPS_GID_NSTS_ZERO val %d ", set_value);
ret = process_wma_set_command((int)pAdapter->sessionId,
(int)WMI_VDEV_PPS_GID_NSTS_ZERO,
- set_value, VDEV_CMD);
+ set_value, PPS_CMD);
break;
}
@@ -5053,7 +5104,57 @@ static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *inf
hddLog(LOG1, "WMI_VDEV_PPS_RSSI_CHECK val %d ", set_value);
ret = process_wma_set_command((int)pAdapter->sessionId,
(int)WMI_VDEV_PPS_RSSI_CHECK,
- set_value, VDEV_CMD);
+ set_value, PPS_CMD);
+ break;
+ }
+
+ case WE_SET_HTSMPS:
+ {
+ hddLog(LOG1, "WE_SET_HTSMPS val %d", set_value);
+ ret = process_wma_set_command((int)pAdapter->sessionId,
+ (int)WMI_STA_SMPS_FORCE_MODE_CMDID,
+ set_value, VDEV_CMD);
+ break;
+ }
+
+
+ case WE_SET_QPOWER_MAX_PSPOLL_COUNT:
+ {
+ hddLog(LOG1, "WE_SET_QPOWER_MAX_PSPOLL_COUNT val %d",
+ set_value);
+ ret = process_wma_set_command((int)pAdapter->sessionId,
+ (int)WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
+ set_value, QPOWER_CMD);
+ break;
+ }
+
+ case WE_SET_QPOWER_MAX_TX_BEFORE_WAKE:
+ {
+ hddLog(LOG1, "WE_SET_QPOWER_MAX_TX_BEFORE_WAKE val %d",
+ set_value);
+ ret = process_wma_set_command((int)pAdapter->sessionId,
+ (int)WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
+ set_value, QPOWER_CMD);
+ break;
+ }
+
+ case WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
+ {
+ hddLog(LOG1, "WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL val %d",
+ set_value);
+ ret = process_wma_set_command((int)pAdapter->sessionId,
+ (int)WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
+ set_value, QPOWER_CMD);
+ break;
+ }
+
+ case WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
+ {
+ hddLog(LOG1, "WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL val %d",
+ set_value);
+ ret = process_wma_set_command((int)pAdapter->sessionId,
+ (int)WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
+ set_value, QPOWER_CMD);
break;
}
@@ -5080,9 +5181,7 @@ static int iw_setchar_getnone(struct net_device *dev, struct iw_request_info *in
#ifdef WLAN_FEATURE_VOWIFI
hdd_config_t *pConfig = pHddCtx->cfg_ini;
#endif /* WLAN_FEATURE_VOWIFI */
-
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Received length %d", __func__, wrqu->data.length);
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Received data %s", __func__, extra);
+ char usr_buf[WLAN_PRIV_SET_CHAR_GET_NONE_BUFF_MAX];
if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
{
@@ -5091,15 +5190,32 @@ static int iw_setchar_getnone(struct net_device *dev, struct iw_request_info *in
return -EBUSY;
}
+ if (wrqu->data.length > WLAN_PRIV_SET_CHAR_GET_NONE_BUFF_MAX)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
+ "%s: Length of user data is too big", __func__);
+ return -E2BIG;
+ }
+
+ if (copy_from_user(&usr_buf, wrqu->data.pointer, wrqu->data.length))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
+ "%s: Copy from user failed", __func__);
+ return -EFAULT;
+ }
+
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Received length %d", __func__, wrqu->data.length);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Received data %s", __func__, usr_buf);
+
switch(sub_cmd)
{
case WE_WOWL_ADD_PTRN:
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "ADD_PTRN\n");
- hdd_add_wowl_ptrn(pAdapter, extra);
+ hdd_add_wowl_ptrn(pAdapter, usr_buf);
break;
case WE_WOWL_DEL_PTRN:
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "DEL_PTRN\n");
- hdd_del_wowl_ptrn(pAdapter, extra);
+ hdd_del_wowl_ptrn(pAdapter, usr_buf);
break;
#if defined WLAN_FEATURE_VOWIFI
case WE_NEIGHBOR_REPORT_REQUEST:
@@ -5114,7 +5230,7 @@ static int iw_setchar_getnone(struct net_device *dev, struct iw_request_info *in
if( !neighborReq.no_ssid )
{
neighborReq.ssid.length = (wrqu->data.length - 1) > 32 ? 32 : (wrqu->data.length - 1) ;
- vos_mem_copy( neighborReq.ssid.ssId, extra, neighborReq.ssid.length );
+ vos_mem_copy( neighborReq.ssid.ssId, usr_buf, neighborReq.ssid.length );
}
callbackInfo.neighborRspCallback = NULL;
@@ -5132,10 +5248,10 @@ static int iw_setchar_getnone(struct net_device *dev, struct iw_request_info *in
#endif
case WE_SET_AP_WPS_IE:
hddLog( LOGE, "Received WE_SET_AP_WPS_IE" );
- sme_updateP2pIe( WLAN_HDD_GET_HAL_CTX(pAdapter), extra, wrqu->data.length );
+ sme_updateP2pIe( WLAN_HDD_GET_HAL_CTX(pAdapter), &usr_buf, wrqu->data.length );
break;
case WE_SET_CONFIG:
- vstatus = hdd_execute_config_command(pHddCtx, extra);
+ vstatus = hdd_execute_config_command(pHddCtx, usr_buf);
if (VOS_STATUS_SUCCESS != vstatus)
{
ret = -EINVAL;
@@ -5396,6 +5512,25 @@ static int iw_setnone_getint(struct net_device *dev, struct iw_request_info *inf
break;
}
+ case WE_GET_BURST_ENABLE:
+ {
+ hddLog(LOG1, "GET Burst enable value");
+ *value = wma_cli_get_command(wmapvosContext,
+ (int)pAdapter->sessionId,
+ (int)WMI_PDEV_PARAM_BURST_ENABLE,
+ PDEV_CMD);
+ break;
+ }
+ case WE_GET_BURST_DUR:
+ {
+ hddLog(LOG1, "GET Burst Duration value");
+ *value = wma_cli_get_command(wmapvosContext,
+ (int)pAdapter->sessionId,
+ (int)WMI_PDEV_PARAM_BURST_DUR,
+ PDEV_CMD);
+ break;
+ }
+
case WE_GET_TX_CHAINMASK:
{
hddLog(LOG1, "GET WMI_PDEV_PARAM_TX_CHAIN_MASK");
@@ -5462,6 +5597,137 @@ static int iw_setnone_getint(struct net_device *dev, struct iw_request_info *inf
break;
}
+ case WE_GET_PPS_PAID_MATCH:
+ {
+ hddLog(LOG1, "GET WMI_VDEV_PPS_PAID_MATCH");
+ *value = wma_cli_get_command(wmapvosContext,
+ (int)pAdapter->sessionId,
+ (int)WMI_VDEV_PPS_PAID_MATCH,
+ PPS_CMD);
+ break;
+ }
+
+ case WE_GET_PPS_GID_MATCH:
+ {
+ hddLog(LOG1, "GET WMI_VDEV_PPS_GID_MATCH");
+ *value = wma_cli_get_command(wmapvosContext,
+ (int)pAdapter->sessionId,
+ (int)WMI_VDEV_PPS_GID_MATCH,
+ PPS_CMD);
+ break;
+ }
+
+ case WE_GET_PPS_EARLY_TIM_CLEAR:
+ {
+ hddLog(LOG1, "GET WMI_VDEV_PPS_EARLY_TIM_CLEAR");
+ *value = wma_cli_get_command(wmapvosContext,
+ (int)pAdapter->sessionId,
+ (int)WMI_VDEV_PPS_EARLY_TIM_CLEAR,
+ PPS_CMD);
+ break;
+ }
+
+ case WE_GET_PPS_EARLY_DTIM_CLEAR:
+ {
+ hddLog(LOG1, "GET WMI_VDEV_PPS_EARLY_DTIM_CLEAR");
+ *value = wma_cli_get_command(wmapvosContext,
+ (int)pAdapter->sessionId,
+ (int)WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
+ PPS_CMD);
+ break;
+ }
+
+ case WE_GET_PPS_EOF_PAD_DELIM:
+ {
+ hddLog(LOG1, "GET WMI_VDEV_PPS_EOF_PAD_DELIM");
+ *value = wma_cli_get_command(wmapvosContext,
+ (int)pAdapter->sessionId,
+ (int)WMI_VDEV_PPS_EOF_PAD_DELIM,
+ PPS_CMD);
+ break;
+ }
+
+ case WE_GET_PPS_MACADDR_MISMATCH:
+ {
+ hddLog(LOG1, "GET WMI_VDEV_PPS_MACADDR_MISMATCH");
+ *value = wma_cli_get_command(wmapvosContext,
+ (int)pAdapter->sessionId,
+ (int)WMI_VDEV_PPS_MACADDR_MISMATCH,
+ PPS_CMD);
+ break;
+ }
+
+ case WE_GET_PPS_DELIM_CRC_FAIL:
+ {
+ hddLog(LOG1, "GET WMI_VDEV_PPS_DELIM_CRC_FAIL");
+ *value = wma_cli_get_command(wmapvosContext,
+ (int)pAdapter->sessionId,
+ (int)WMI_VDEV_PPS_DELIM_CRC_FAIL,
+ PPS_CMD);
+ break;
+ }
+
+ case WE_GET_PPS_GID_NSTS_ZERO:
+ {
+ hddLog(LOG1, "GET WMI_VDEV_PPS_GID_NSTS_ZERO");
+ *value = wma_cli_get_command(wmapvosContext,
+ (int)pAdapter->sessionId,
+ (int)WMI_VDEV_PPS_GID_NSTS_ZERO,
+ PPS_CMD);
+ break;
+ }
+
+ case WE_GET_PPS_RSSI_CHECK:
+ {
+
+ hddLog(LOG1, "GET WMI_VDEV_PPS_RSSI_CHECK");
+ *value = wma_cli_get_command(wmapvosContext,
+ (int)pAdapter->sessionId,
+ (int)WMI_VDEV_PPS_RSSI_CHECK,
+ PPS_CMD);
+ break;
+ }
+
+ case WE_GET_QPOWER_MAX_PSPOLL_COUNT:
+ {
+ hddLog(LOG1, "WE_GET_QPOWER_MAX_PSPOLL_COUNT");
+ *value = wma_cli_get_command(wmapvosContext,
+ (int)pAdapter->sessionId,
+ (int)WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
+ QPOWER_CMD);
+ break;
+ }
+
+ case WE_GET_QPOWER_MAX_TX_BEFORE_WAKE:
+ {
+ hddLog(LOG1, "WE_GET_QPOWER_MAX_TX_BEFORE_WAKE");
+ *value = wma_cli_get_command(wmapvosContext,
+ (int)pAdapter->sessionId,
+ (int)WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
+ QPOWER_CMD);
+ break;
+ }
+
+ case WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
+ {
+ hddLog(LOG1, "WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL");
+ *value = wma_cli_get_command(wmapvosContext,
+ (int)pAdapter->sessionId,
+ (int)WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
+ QPOWER_CMD);
+ break;
+ }
+
+ case WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
+ {
+ hddLog(LOG1, "WE_GET_QPOWER_MAX_PSPOLL_COUNT");
+ *value = wma_cli_get_command(wmapvosContext,
+ (int)pAdapter->sessionId,
+ (int)WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
+ QPOWER_CMD);
+ break;
+ }
+
#endif
default:
@@ -6101,90 +6367,7 @@ static int iw_setnone_getnone(struct net_device *dev, struct iw_request_info *in
break;
}
- case WE_GET_PPS_PAID_MATCH:
- {
- hddLog(LOG1, "GET WMI_VDEV_PPS_PAID_MATCH");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_PAID_MATCH,
- VDEV_CMD);
- break;
- }
- case WE_GET_PPS_GID_MATCH:
- {
- hddLog(LOG1, "GET WMI_VDEV_PPS_GID_MATCH");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_GID_MATCH,
- VDEV_CMD);
- break;
- }
- case WE_GET_PPS_EARLY_TIM_CLEAR:
- {
- hddLog(LOG1, "GET WMI_VDEV_PPS_EARLY_TIM_CLEAR");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_EARLY_TIM_CLEAR,
- VDEV_CMD);
- break;
- }
- case WE_GET_PPS_EARLY_DTIM_CLEAR:
- {
- hddLog(LOG1, "GET WMI_VDEV_PPS_EARLY_DTIM_CLEAR");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
- VDEV_CMD);
- break;
- }
- case WE_GET_PPS_EOF_PAD_DELIM:
- {
- hddLog(LOG1, "GET WMI_VDEV_PPS_EOF_PAD_DELIM");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_EOF_PAD_DELIM,
- VDEV_CMD);
- break;
- }
- case WE_GET_PPS_MACADDR_MISMATCH:
- {
- hddLog(LOG1, "GET WMI_VDEV_PPS_MACADDR_MISMATCH");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_MACADDR_MISMATCH,
- VDEV_CMD);
- break;
- }
- case WE_GET_PPS_DELIM_CRC_FAIL:
- {
- hddLog(LOG1, "GET WMI_VDEV_PPS_DELIM_CRC_FAIL");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_DELIM_CRC_FAIL,
- VDEV_CMD);
- break;
- }
- case WE_GET_PPS_GID_NSTS_ZERO:
- {
- hddLog(LOG1, "GET WMI_VDEV_PPS_GID_NSTS_ZERO");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_GID_NSTS_ZERO,
- VDEV_CMD);
- break;
- }
- case WE_GET_PPS_RSSI_CHECK:
- {
-
- hddLog(LOG1, "GET WMI_VDEV_PPS_RSSI_CHECK");
- *value = wma_cli_get_command(wmapvosContext,
- (int)pAdapter->sessionId,
- (int)WMI_VDEV_PPS_RSSI_CHECK,
- VDEV_CMD);
- break;
- }
#endif
-
case WE_ENABLE_DXE_STALL_DETECT:
{
tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
@@ -7720,7 +7903,9 @@ static int iw_get_statistics(struct net_device *dev,
SME_GLOBAL_CLASSD_STATS |
SME_PER_STA_STATS,
hdd_StatisticsCB, 0, FALSE,
- (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], pAdapter );
+ (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
+ pAdapter,
+ pAdapter->sessionId );
if (eHAL_STATUS_SUCCESS != status)
{
@@ -7747,7 +7932,9 @@ static int iw_get_statistics(struct net_device *dev,
SME_GLOBAL_CLASSD_STATS |
SME_PER_STA_STATS,
NULL, 0, FALSE,
- (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], pAdapter );
+ (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
+ pAdapter,
+ pAdapter->sessionId );
return -EINVAL;
}
@@ -8337,9 +8524,6 @@ int hdd_setBand_helper(struct net_device *dev, tANI_U8* ptr)
hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId);
sme_ScanFlushResult(hHal, pAdapter->sessionId);
-#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
- sme_UpdateBgScanConfigIniChannelList(hHal, (eCsrBand) band);
-#endif
if (eHAL_STATUS_SUCCESS != sme_SetFreqBand(hHal, (eCsrBand)band))
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
@@ -8530,6 +8714,41 @@ VOS_STATUS iw_set_power_params(struct net_device *dev, struct iw_request_info *i
return VOS_STATUS_SUCCESS;
}/*iw_set_power_params*/
+int iw_set_two_ints_getnone(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ int *value = (int *)extra;
+ int sub_cmd = value[0];
+ int ret = 0;
+
+ if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
+ "%s:LOGP in Progress. Ignore!!!", __func__);
+ return -EBUSY;
+ }
+
+ switch(sub_cmd)
+ {
+ case WE_SET_SMPS_PARAM:
+ {
+ hddLog(LOG1, "WE_SET_SMPS_PARAM val %d %d", value[1], value[2]);
+ ret = process_wma_set_command((int)pAdapter->sessionId,
+ (int)WMI_STA_SMPS_PARAM_CMDID,
+ value[1] << WMA_SMPS_PARAM_VALUE_S | value[2], VDEV_CMD);
+ break;
+ }
+
+ default:
+ {
+ hddLog(LOGE, "Invalid IOCTL command %d", sub_cmd);
+ break;
+ }
+ }
+ return ret;
+}
+
// Define the Wireless Extensions to the Linux Network Device structure
// A number of these routines are NULL (meaning they are not implemented.)
@@ -8643,6 +8862,7 @@ static const iw_handler we_private[] = {
#endif
#endif
[WLAN_GET_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_linkspeed,
+ [WLAN_PRIV_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_two_ints_getnone,
};
/*Maximum command length can be only 15 */
@@ -8827,6 +9047,16 @@ static const struct iw_priv_args we_private_args[] = {
0,
"amsdu" },
+ { WE_SET_BURST_ENABLE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0,
+ "burst_enable" },
+
+ { WE_SET_BURST_DUR,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0,
+ "burst_dur" },
+
{ WE_SET_TXPOW_2G,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
0,
@@ -8935,6 +9165,28 @@ static const struct iw_priv_args we_private_args[] = {
{ WE_PPS_RSSI_CHECK,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
0, "rssi_chk" },
+
+ { WE_SET_HTSMPS,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "htsmps" },
+
+
+ { WE_SET_QPOWER_MAX_PSPOLL_COUNT,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "set_qpspollcnt" },
+
+ { WE_SET_QPOWER_MAX_TX_BEFORE_WAKE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "set_qtxwake" },
+
+ { WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "set_qwakeintv" },
+
+ { WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "set_qnodatapoll" },
+
#endif
{ WLAN_PRIV_SET_NONE_GET_INT,
@@ -9079,6 +9331,16 @@ static const struct iw_priv_args we_private_args[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"get_amsdu" },
+ { WE_GET_BURST_ENABLE,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_burst_en" },
+
+ { WE_GET_BURST_DUR,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_burst_dur" },
+
{ WE_GET_TXPOW_2G,
0,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
@@ -9146,6 +9408,27 @@ static const struct iw_priv_args we_private_args[] = {
0,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"get_rssi_chk"},
+
+ { WE_GET_QPOWER_MAX_PSPOLL_COUNT,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_qpspollcnt"},
+
+ { WE_GET_QPOWER_MAX_TX_BEFORE_WAKE,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_qtxwake"},
+
+ { WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_qwakeintv"},
+
+ { WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
+ 0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_qnodatapoll"},
+
#endif
/* handlers for main ioctl */
@@ -9517,6 +9800,16 @@ static const struct iw_priv_args we_private_args[] = {
WLAN_GET_LINK_SPEED,
IW_PRIV_TYPE_CHAR | 18,
IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" },
+
+ /* handlers for main ioctl */
+ { WLAN_PRIV_SET_TWO_INT_GET_NONE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+ 0,
+ "" },
+ { WE_SET_SMPS_PARAM,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+ 0, "set_smps_param" },
+
};
diff --git a/CORE/HDD/src/wlan_hdd_wmm.c b/CORE/HDD/src/wlan_hdd_wmm.c
index c809e8686ec4..ff0bede2fbae 100644
--- a/CORE/HDD/src/wlan_hdd_wmm.c
+++ b/CORE/HDD/src/wlan_hdd_wmm.c
@@ -181,7 +181,9 @@ static void hdd_wmm_enable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
}
// are we in the appropriate power save modes?
- if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_BEACON_MODE_POWER_SAVE))
+ if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter),
+ pAdapter->sessionId,
+ ePMC_BEACON_MODE_POWER_SAVE))
{
VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
"%s: BMPS is not enabled",
@@ -189,7 +191,9 @@ static void hdd_wmm_enable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
return;
}
- if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_UAPSD_MODE_POWER_SAVE))
+ if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter),
+ pAdapter->sessionId,
+ ePMC_UAPSD_MODE_POWER_SAVE))
{
VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
"%s: U-APSD is not enabled",
diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h
index 152ca3253eab..5b637bd24d36 100644
--- a/CORE/MAC/inc/aniGlobal.h
+++ b/CORE/MAC/inc/aniGlobal.h
@@ -248,6 +248,7 @@ typedef struct sLimTimers
* for a period of time on a particular DFS channel
*/
TX_TIMER gLimActiveToPassiveChannelTimer;
+
//********************TIMER SECTION ENDS**************************************************
// ALL THE FIELDS BELOW THIS CAN BE ZEROED OUT in limInitialize
//****************************************************************************************
@@ -911,6 +912,10 @@ tLimMlmOemDataRsp *gpLimMlmOemDataRsp;
tSirDFSChannelList dfschannelList;
tANI_U8 deauthMsgCnt;
tANI_U8 gLimIbssStaLimit;
+
+ /* Number of channel switch IEs sent so far */
+ tANI_U8 gLimDfsChanSwTxCount;
+ tANI_U8 gLimDfsTargetChanNum;
} tAniSirLim, *tpAniSirLim;
typedef struct sLimMgmtFrameRegistration
diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h
index 96e6baa38e77..a7005395ecaa 100644
--- a/CORE/MAC/inc/qwlan_version.h
+++ b/CORE/MAC/inc/qwlan_version.h
@@ -24,6 +24,7 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
+
#ifndef QWLAN_VERSION_H
#define QWLAN_VERSION_H
/*===========================================================================
@@ -40,9 +41,9 @@ BRIEF DESCRIPTION:
#define QWLAN_VERSION_MAJOR 4
#define QWLAN_VERSION_MINOR 0
#define QWLAN_VERSION_PATCH 0
-#define QWLAN_VERSION_EXTRA "D"
-#define QWLAN_VERSION_BUILD 68
+#define QWLAN_VERSION_EXTRA ""
+#define QWLAN_VERSION_BUILD 72
-#define QWLAN_VERSIONSTR "4.0.0.68D"
+#define QWLAN_VERSIONSTR "4.0.0.72"
#endif /* QWLAN_VERSION_H */
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 1e612e8f808d..a2750c146f2e 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -2102,6 +2102,7 @@ typedef struct sAniGetPEStatsReq
tANI_U16 msgLen; // length of the entire request
tANI_U32 staId; // Per STA stats request must contain valid
tANI_U32 statsMask; // categories of stats requested. look at ePEStatsMask
+ tANI_U8 sessionId;
} tAniGetPEStatsReq, *tpAniGetPEStatsReq;
/*
@@ -4736,4 +4737,63 @@ typedef struct sSirChAvoidIndType
} tSirChAvoidIndType;
#endif /* FEATURE_WLAN_CH_AVOID */
+typedef struct sSirSmeDfsEventInd
+{
+ tANI_U32 sessionId;
+ tANI_U8 ieee_chan_number;
+ tANI_U32 chan_freq;
+ tANI_U32 dfs_radar_status;
+ int use_nol;
+}tSirSmeDfsEventInd, *tpSirSmeDfsEventInd;
+
+typedef struct sSirChanChangeRequest
+{
+ tANI_U16 messageType;
+ tANI_U16 messageLen;
+ tANI_U8 sessionId;
+ tANI_U8 targetChannel;
+}tSirChanChangeRequest, *tpSirChanChangeRequest;
+
+typedef struct sSirChanChangeResponse
+{
+ tANI_U8 sessionId;
+ tANI_U8 newChannelNumber;
+ tANI_U8 channelChangeStatus;
+ ePhyChanBondState secondaryChannelOffset;
+}tSirChanChangeResponse, *tpSirChanChangeResponse;
+
+typedef struct sSirStartBeaconIndication
+{
+ tANI_U16 messageType;
+ tANI_U16 messageLen;
+ tANI_U8 sessionId;
+ tANI_U8 beaconStartStatus;
+}tSirStartBeaconIndication, *tpSirStartBeaconIndication;
+
+/* Message format for requesting channel switch announcement to lower layers */
+typedef struct sSirDfsCsaIeRequest
+{
+ tANI_U16 msgType;
+ tANI_U16 msgLen;
+ tANI_U8 sessionId;
+ tANI_U8 targetChannel;
+ tANI_U8 csaIeRequired;
+}tSirDfsCsaIeRequest, *tpSirDfsCsaIeRequest;
+
+/* Indication from lower layer indicating the completion of first beacon send
+ * after the beacon template update
+ */
+typedef struct sSirFirstBeaconTxCompleteInd
+{
+ tANI_U16 messageType; // eWNI_SME_MISSED_BEACON_IND
+ tANI_U16 length;
+ tANI_U8 bssIdx;
+}tSirFirstBeaconTxCompleteInd, *tpSirFirstBeaconTxCompleteInd;
+
+typedef struct sSirSmeCSAIeTxCompleteRsp
+{
+ tANI_U8 sessionId;
+ tANI_U8 chanSwIeTxStatus;
+}tSirSmeCSAIeTxCompleteRsp, *tpSirSmeCSAIeTxCompleteRsp;
+
#endif /* __SIR_API_H */
diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h
index 68fa22a30b46..87d5e5b1d0f8 100644
--- a/CORE/MAC/inc/wniApi.h
+++ b/CORE/MAC/inc/wniApi.h
@@ -380,6 +380,14 @@ enum eWniMsgTypes
#ifdef FEATURE_WLAN_CH_AVOID
eWNI_SME_CH_AVOID_IND,
#endif /* FEATURE_WLAN_CH_AVOID */
+ /* DFS EVENTS */
+ eWNI_SME_DFS_RADAR_FOUND, //RADAR found indication from DFS
+ eWNI_SME_CHANNEL_CHANGE_REQ,//Channel Change Request from SAP
+ eWNI_SME_CHANNEL_CHANGE_RSP,// Channel Change Response from WMA
+ eWNI_SME_START_BEACON_REQ,//Start Beacon Transmission.
+ eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ, //Transmit CSA IE in beacons
+ eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND, //To indicate completion of CSA IE
+ //update in beacons/probe rsp
eWNI_SME_MSG_TYPES_END
};
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index 33ed8bed778a..f12920f14a66 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -634,6 +634,10 @@ typedef struct sSirMbMsgP2p
#endif
#endif
+/* Handling of beacon tx indication from FW */
+#define SIR_HAL_BEACON_TX_SUCCESS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 242)
+#define SIR_HAL_DFS_RADAR_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 243)
+
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
// CFG message types
@@ -737,6 +741,7 @@ typedef struct sSirMbMsgP2p
#define SIR_LIM_TDLS_LINK_SETUP_CNF_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x2B)
#endif
#define SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE (SIR_LIM_TIMEOUT_MSG_START + 0x2C)
+
#define SIR_LIM_MSG_TYPES_END (SIR_LIM_MSG_TYPES_BEGIN+0xFF)
// SCH message types
diff --git a/CORE/MAC/src/pe/include/limGlobal.h b/CORE/MAC/src/pe/include/limGlobal.h
index 5613a15cc73b..d3f134597e20 100644
--- a/CORE/MAC/src/pe/include/limGlobal.h
+++ b/CORE/MAC/src/pe/include/limGlobal.h
@@ -87,6 +87,8 @@
#define IS_5G_BAND(__rfBand) ((__rfBand & 0x3) == 0x2)
#define IS_24G_BAND(__rfBand) ((__rfBand & 0x3) == 0x1)
+#define LIM_MAX_CSA_IE_UPDATES ( 5 )
+
// enums exported by LIM are as follows
/// System role definition
@@ -575,7 +577,7 @@ typedef struct sLimChannelSwitchInfo
tLimChannelSwitchState state;
tANI_U8 primaryChannel;
ePhyChanBondState secondarySubBand;
- tANI_U32 switchCount;
+ tANI_S8 switchCount;
tANI_U32 switchTimeoutValue;
tANI_U8 switchMode;
} tLimChannelSwitchInfo, *tpLimChannelSwitchInfo;
diff --git a/CORE/MAC/src/pe/include/limSession.h b/CORE/MAC/src/pe/include/limSession.h
index bc7109ca03c5..33089ff0ce3e 100644
--- a/CORE/MAC/src/pe/include/limSession.h
+++ b/CORE/MAC/src/pe/include/limSession.h
@@ -413,6 +413,9 @@ typedef struct sPESession // Added to Support BT-AMP
tANI_U8 smpsMode;
tANI_U8 chainMask;
+
+ /* Flag to indicate Chan Sw announcement is required */
+ tANI_U8 dfsIncludeChanSwIe;
}tPESession, *tpPESession;
#define LIM_MAX_ACTIVE_SESSIONS 4
diff --git a/CORE/MAC/src/pe/lim/limApi.c b/CORE/MAC/src/pe/lim/limApi.c
index 9e339bd6c335..1b0bbbac2c88 100644
--- a/CORE/MAC/src/pe/lim/limApi.c
+++ b/CORE/MAC/src/pe/lim/limApi.c
@@ -354,9 +354,13 @@ static void __limInitAssocVars(tpAniSirGlobal pMac)
{
limLog( pMac, LOGP, FL( "cfg get assoc sta limit failed" ));
}
+#ifdef QCA_WIFI_2_0
+ /* This +1 is done because of peerIdx assign logic in limAssignPeerIdx */
+ pMac->lim.gLimAssocStaLimit = val + 1;
+#else
pMac->lim.gLimAssocStaLimit = val;
+#endif
pMac->lim.gLimIbssStaLimit = val;
-
// Place holder for current authentication request
// being handled
pMac->lim.gpLimMlmAuthReq = NULL;
diff --git a/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c b/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c
index f87d74690d5b..6955b3546aa1 100644
--- a/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c
+++ b/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c
@@ -596,7 +596,12 @@ limHandleCFGparamUpdate(tpAniSirGlobal pMac, tANI_U32 cfgId)
limLog( pMac, LOGE, FL( "Unable to get WNI_CFG_ASSOC_STA_LIMIT" ));
break;
}
+#ifdef QCA_WIFI_2_0
+ /* This +1 is done becuse of peerIdx assign logic in limAssignPeerIdx */
+ pMac->lim.gLimAssocStaLimit = (tANI_U16)val1 + 1;
+#else
pMac->lim.gLimAssocStaLimit = (tANI_U16)val1;
+#endif
break;
case WNI_CFG_DEL_ALL_RX_BA_SESSIONS_2_4_G_BTC:
@@ -781,7 +786,12 @@ limUpdateConfig(tpAniSirGlobal pMac,tpPESession psessionEntry)
}
val = WNI_CFG_ASSOC_STA_LIMIT_STADEF;
}
+#ifdef QCA_WIFI_2_0
+ /* This +1 is done becuse of peerIdx assign logic in limAssignPeerIdx */
+ pMac->lim.gLimAssocStaLimit =(tANI_U16) val + 1;
+#else
pMac->lim.gLimAssocStaLimit = (tANI_U16)val;
+#endif
#if defined WLAN_FEATURE_VOWIFI
rrmUpdateConfig( pMac, psessionEntry );
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index 42ef0936b4db..35d1665f1260 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -1762,6 +1762,7 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
case SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT:
limHandleUpdateOlbcCache(pMac);
break;
+
#if 0
case SIR_LIM_WPS_OVERLAP_TIMEOUT:
limProcessWPSOverlapTimeout(pMac);
@@ -2066,6 +2067,37 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
break;
}
+ case WDA_DFS_RADAR_IND:
+ limSendSmeDfsEventNotify(pMac, limMsg->type,
+ (void *)limMsg->bodyptr);
+ /* limmsg->bodyptr will be freed up by SME/CSR */
+ break;
+
+ case WDA_DFS_BEACON_TX_SUCCESS_IND:
+ limProcessBeaconTxSuccessInd(pMac, limMsg->type,
+ (void *)limMsg->bodyptr);
+ vos_mem_free((v_VOID_t*)limMsg->bodyptr);
+ limMsg->bodyptr = NULL;
+ break;
+
+ case eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ:
+ limProcessSmeReqMessages(pMac, limMsg);
+ vos_mem_free((v_VOID_t*)limMsg->bodyptr);
+ limMsg->bodyptr = NULL;
+ break;
+
+ case eWNI_SME_CHANNEL_CHANGE_REQ:
+ limProcessSmeReqMessages(pMac, limMsg);
+ vos_mem_free((v_VOID_t*)limMsg->bodyptr);
+ limMsg->bodyptr = NULL;
+ break;
+
+ case eWNI_SME_START_BEACON_REQ:
+ limProcessSmeReqMessages(pMac, limMsg);
+ vos_mem_free((v_VOID_t*)limMsg->bodyptr);
+ limMsg->bodyptr = NULL;
+ break;
+
default:
vos_mem_free((v_VOID_t*)limMsg->bodyptr);
limMsg->bodyptr = NULL;
diff --git a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
index fd9b6267e6e2..bd1e82d9f0f9 100644
--- a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
@@ -1718,7 +1718,8 @@ limMlmAddBss (
pAddBssParams->halPersona=psessionEntry->pePersona; //pass on the session persona to hal
- pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled;
+ pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled ||
+ limIsconnectedOnDFSChannel(pMlmStartReq->channelNumber);
#if defined WLAN_FEATURE_VOWIFI_11R
pAddBssParams->extSetStaKeyParamValid = 0;
diff --git a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
index 2fafc8383623..771fc0857ce4 100644
--- a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
@@ -345,6 +345,7 @@ limProcessMlmStartCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
tLimMlmStartCnf *pLimMlmStartCnf;
tANI_U8 smesessionId;
tANI_U16 smetransactionId;
+ tANI_U8 channelId;
if(pMsgBuf == NULL)
{
@@ -410,8 +411,21 @@ limProcessMlmStartCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
smesessionId,smetransactionId);
if (((tLimMlmStartCnf *) pMsgBuf)->resultCode == eSIR_SME_SUCCESS)
{
- //Configure beacon and send beacons to HAL
- limSendBeaconInd(pMac, psessionEntry);
+ channelId = psessionEntry->pLimStartBssReq->channelId;
+
+ // We should start beacon transmission only if the channel
+ // on which we are operating is non-DFS until the channel
+ // availability check is done. The PE will receive an explicit
+ // request from upper layers to start the beacon transmission
+
+
+ if ( (eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole) ||
+ ((eLIM_AP_ROLE == psessionEntry->limSystemRole) &&
+ (vos_nv_getChannelEnabledState(channelId) != NV_CHANNEL_DFS)) )
+ {
+ //Configure beacon and send beacons to HAL
+ limSendBeaconInd(pMac, psessionEntry);
+ }
}
}
@@ -3703,6 +3717,7 @@ void limProcessSwitchChannelRsp(tpAniSirGlobal pMac, void *body)
pChnlParams = (tpSwitchChannelParams) body;
status = pChnlParams->status;
peSessionId = pChnlParams->peSessionId;
+
if((psessionEntry = peFindSessionBySessionId(pMac, peSessionId))== NULL)
{
vos_mem_free(body);
@@ -3714,7 +3729,6 @@ void limProcessSwitchChannelRsp(tpAniSirGlobal pMac, void *body)
//Store this value to use in TPC report IE.
rrmCacheMgmtTxPower( pMac, pChnlParams->txMgmtPower, psessionEntry );
#endif
- vos_mem_free(body);
channelChangeReasonCode = psessionEntry->channelChangeReasonCode;
// initialize it back to invalid id
psessionEntry->chainMask = pChnlParams->chainMask;
@@ -3742,9 +3756,23 @@ void limProcessSwitchChannelRsp(tpAniSirGlobal pMac, void *body)
pMac->lim.gpchangeChannelCallback(pMac, status, pMac->lim.gpchangeChannelData, psessionEntry);
}
break;
+ case LIM_SWITCH_CHANNEL_SAP_DFS:
+ {
+ /* Note: This event code specific to SAP mode
+ * When SAP session issues channel change as performing
+ * DFS, we will come here. Other sessions, for e.g. P2P
+ * will have to define their own event code and channel
+ * switch handler. This is required since the SME may
+ * require completely different information for P2P unlike
+ * SAP.
+ */
+ limSendSmeAPChannelSwitchResp(pMac, psessionEntry, pChnlParams);
+ }
+ break;
default:
break;
}
+ vos_mem_free(body);
}
/**
* limProcessStartScanRsp()
diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index 2280d94cb328..45b62e18b086 100644
--- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -100,6 +100,12 @@ static void __limProcessSmeDisassocCnf(tpAniSirGlobal, tANI_U32 *);
static void __limProcessSmeDeauthReq(tpAniSirGlobal, tANI_U32 *);
static void __limProcessSmeSetContextReq(tpAniSirGlobal, tANI_U32 *);
static tANI_BOOLEAN __limProcessSmeStopBssReq(tpAniSirGlobal, tpSirMsgQ pMsg);
+static void limProcessSmeChannelChangeRequest(tpAniSirGlobal pMac,
+ tANI_U32 *pMsg);
+static void limProcessSmeStartBeaconReq(tpAniSirGlobal pMac,
+ tANI_U32 *pMsg);
+static void limProcessSmeDfsCacIndication(tpAniSirGlobal pMac, tANI_U32 *pMsg);
+static void limProcessSmeDfsCsaIeRequest(tpAniSirGlobal pMac, tANI_U32 *pMsg);
void __limProcessSmeAssocCnfNew(tpAniSirGlobal, tANI_U32, tANI_U32 *);
@@ -5738,6 +5744,19 @@ limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
limSendSetTxPowerReq(pMac, pMsgBuf);
break ;
+
+ case eWNI_SME_CHANNEL_CHANGE_REQ:
+ limProcessSmeChannelChangeRequest(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_START_BEACON_REQ:
+ limProcessSmeStartBeaconReq(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ:
+ limProcessSmeDfsCsaIeRequest(pMac, pMsgBuf);
+ break;
+
default:
vos_mem_free((v_VOID_t*)pMsg->bodyptr);
pMsg->bodyptr = NULL;
@@ -5746,3 +5765,212 @@ limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
return bufConsumed;
} /*** end limProcessSmeReqMessages() ***/
+
+/**
+ * limProcessSmeStartBeaconReq()
+ *
+ *FUNCTION:
+ * This function is called by limProcessMessageQueue(). This
+ * function processes SME request messages from HDD or upper layer
+ * application.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates the SME message type
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return Boolean - TRUE - if pMsgBuf is consumed and can be freed.
+ * FALSE - if pMsgBuf is not to be freed.
+ */
+static void
+limProcessSmeStartBeaconReq(tpAniSirGlobal pMac, tANI_U32 * pMsg)
+{
+ tpSirStartBeaconIndication pBeaconStartInd;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId; //PE sessionID
+
+ if( pMsg == NULL )
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ pBeaconStartInd = (tpSirStartBeaconIndication)pMsg;
+ sessionId = pBeaconStartInd->sessionId;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac, sessionId)) == NULL)
+ {
+ limLog(pMac, LOGW, "Session does not exist for given sessionId %d",
+ pBeaconStartInd->sessionId);
+ return;
+ }
+
+ if (pBeaconStartInd->beaconStartStatus == VOS_TRUE)
+ {
+ /*
+ * Currently this Indication comes from SAP
+ * to start Beacon Tx on a DFS channel
+ * since beaconing has to be done on DFS
+ * channel only after CAC WAIT is completed.
+ * On a DFS Channel LIM does not start beacon
+ * Tx right after the WDA_ADD_BSS_RSP.
+ */
+ limApplyConfiguration(pMac,psessionEntry);
+ limSendBeaconInd(pMac, psessionEntry);
+ }
+ else
+ {
+ limLog(pMac, LOGE,FL("Invalid Beacon Start Indication"));
+ return;
+ }
+}
+
+static void
+limProcessSmeChannelChangeRequest(tpAniSirGlobal pMac, tANI_U32 *pMsg)
+{
+ tpSirChanChangeRequest pChannelChangeReq;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId; //PE sessionID
+ tPowerdBm maxTxPwr;
+ if( pMsg == NULL )
+ {
+ limLog(pMac, LOGE,FL("pMsg is NULL"));
+ return;
+ }
+ pChannelChangeReq = (tpSirChanChangeRequest)pMsg;
+ sessionId = pChannelChangeReq->sessionId;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac, sessionId)) == NULL)
+ {
+ limLog(pMac, LOGW, "Session does not exist for given sessionId %d",
+ pChannelChangeReq->sessionId);
+ return;
+ }
+
+ if (eLIM_AP_ROLE == psessionEntry->limSystemRole)
+ psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_SAP_DFS;
+ else
+ psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_OPERATION;
+
+ maxTxPwr = cfgGetRegulatoryMaxTransmitPower( pMac,
+ pChannelChangeReq->targetChannel );
+
+ if (pChannelChangeReq->messageType == eWNI_SME_CHANNEL_CHANGE_REQ
+ &&
+ maxTxPwr != WDA_MAX_TXPOWER_INVALID)
+ {
+ /*
+ * Issue a set channel request with
+ * with channel bonding mode as
+ * PHY_SINGLE_CHANNEL_CENTERED
+ * TODO:Handle the channel bonding mode
+ * 40Mhz and 80Mhz Channel width for SAP
+ * channel change.
+ */
+
+ /* Store the New Channel Params in psessionEntry */
+ if (psessionEntry->currentOperChannel !=
+ pChannelChangeReq->targetChannel)
+ {
+ limLog(pMac, LOGW,FL("switch old chnl %d --> new chnl %d "),
+ psessionEntry->currentOperChannel,
+ pChannelChangeReq->targetChannel);
+
+ limSetChannel(pMac, pChannelChangeReq->targetChannel,
+ PHY_SINGLE_CHANNEL_CENTERED,
+ maxTxPwr,
+ psessionEntry->peSessionId);
+
+ psessionEntry->currentOperChannel =
+ pChannelChangeReq->targetChannel;
+
+ /*
+ *TODO:As of now the supported Channel width
+ * is only 20Mhz. AP Channel Bonding Mode for
+ * 40 Mhz and 80Mhz is pending implementation.
+ */
+ psessionEntry->htSecondaryChannelOffset =
+ PHY_SINGLE_CHANNEL_CENTERED;
+ psessionEntry->htSupportedChannelWidthSet =
+ WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ psessionEntry->htRecommendedTxWidthSet =
+ psessionEntry->htSupportedChannelWidthSet;
+ }
+
+ }
+ else
+ {
+ limLog(pMac, LOGE,FL("Invalid Request/maxTxPwr"));
+ }
+}
+
+/**
+ * limProcessSmeDfsCsaIeRequest()
+ *
+ *FUNCTION:
+ * This function is called by limProcessMessageQueue(). This
+ * function processes SME request messages from HDD or upper layer
+ * application.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ */
+static void
+limProcessSmeDfsCsaIeRequest(tpAniSirGlobal pMac, tANI_U32 *pMsg)
+{
+
+ tpSirDfsCsaIeRequest pDfsCsaIeRequest = (tSirDfsCsaIeRequest *)pMsg;
+ //tANI_U8 sessionId = pDfsCsaIeRequest->sessionId;
+ tpPESession psessionEntry;
+ int i;
+
+ if ( pMsg == NULL )
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ for (i=0; i<pMac->lim.maxBssId; i++)
+ {
+ psessionEntry = peFindSessionBySessionId(pMac, i);
+ if (psessionEntry && psessionEntry->valid &&
+ eLIM_AP_ROLE == psessionEntry->limSystemRole)
+ {
+ break;
+ }
+ }
+
+ /* target channel */
+ psessionEntry->gLimChannelSwitch.primaryChannel =
+ pDfsCsaIeRequest->targetChannel;
+
+ /* Channel switch announcement needs to be included in beacon */
+ psessionEntry->dfsIncludeChanSwIe = VOS_TRUE;
+ psessionEntry->gLimChannelSwitch.switchCount = LIM_MAX_CSA_IE_UPDATES;
+
+ /* Send CSA IE request from here */
+ if (schSetFixedBeaconFields(pMac, psessionEntry) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to set CSA IE in beacon"));)
+ return;
+ }
+
+ /* First beacon update request is sent here, the remaining updates are
+ * done when the FW responds back after sending the first beacon after
+ * the template update
+ */
+ limSendBeaconInd(pMac, psessionEntry);
+ psessionEntry->gLimChannelSwitch.switchCount--;
+
+ return;
+}
diff --git a/CORE/MAC/src/pe/lim/limRMC.c b/CORE/MAC/src/pe/lim/limRMC.c
deleted file mode 100644
index b5d5f5b21dc3..000000000000
--- a/CORE/MAC/src/pe/lim/limRMC.c
+++ /dev/null
@@ -1,1893 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
- *
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file was originally distributed by Qualcomm Atheros, Inc.
- * under proprietary terms before Copyright ownership was assigned
- * to the Linux Foundation.
- */
-
-/*
- * This file limRMC.c contains the code
- * for processing Leader-based Protocol messages to support Reliable multicast
- *
- */
-#include "wniApi.h"
-#include "wniCfgSta.h"
-#include "cfgApi.h"
-#include "sirApi.h"
-#include "schApi.h"
-#include "utilsApi.h"
-#include "limUtils.h"
-#include "limTimerUtils.h"
-#include "limSendMessages.h"
-#include "limSendMessages.h"
-#include "limSession.h"
-#include "limSessionUtils.h"
-#include "wlan_qct_wda.h"
-#include "wlan_qct_tli.h"
-#include "limRMC.h"
-
-/**
- * DOC: Leader Based Protocol for Reliable Multicast
- *
- * This protocol proposes to achieve reliability in multicast transmissions
- * by having a selected multicast receiver respond with 802.11 ACKs.
- * This is designed for a peer to peer application that uses the underlying
- * IBSS network. The STAs in the IBSS network perform the following different
- * roles to support this protocol -
- *
- * 1) Multicast Transmitter:
- * A node that delivers MCAST packets to every nodes and performs Reliable
- * Multicast algorithm as a transmitter.
- * 2) Multicast Receiver:
- * All nodes that receive MCAST packets
- * 3) Multicast Receiver Leader:
- * A node that receives MCAST packets and performs a Reliable Multicast
- * algorithm by sending ACK to transmitter for every multicast frame
- * received. Multicast Receiver Leader is appointed by the Multicast
- * Transmitter.
- *
- * The implementation in this file supports the roles of both Multicast
- * Transmitter and the Multicast Receiver Leader.
- *
- * The firmware performs the Leader Selection algorithm and provides a candidate
- * list. The implementation in this file, sends vendor specific 802.11 Action
- * frame to notify the selected Multicast leader.
- *
- * The leader sets up its data path to send 802.11 ACKs for any received
- * Multicast frames belonging to the specified Multicast Group. It then sends an
- * Action frame to the transmitter to acknowledge that it has accepted the
- * Leader role.
- *
- * On receiving an acknowledgement from the leader, the transmitter sets up its
- * data path to expect 802.11 ACKs for Multicast transmissions.
- *
- * The function limProcessRMCMessages handles messages from HDD to enable or
- * disable this protocol for a Multicast Group. It handles 802.11 Action frame
- * receive events for this protocol. It also responds to firmware generated
- * indications and events.
- */
-
-#if defined WLAN_FEATURE_RELIABLE_MCAST
-
-/*
- * RMC utility routines
- */
-
-/**
- * __rmcGroupHashFunction()
- *
- *FUNCTION:
- * This function is called during scan hash entry operations
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- * NA
- *
- *NOTE:
- * NA
- *
- * @param transmitter - address of multicast transmitter
- *
- * @return Hash index
- */
-
-static tANI_U8
-__rmcGroupHashFunction(tSirMacAddr transmitter)
-{
- tANI_U16 hash;
-
- /*
- * Generate a hash using transmitter address
- */
- hash = transmitter[0] + transmitter[1] + transmitter[2] +
- transmitter[3] + transmitter[4] + transmitter[5];
-
- return hash & (RMC_MCAST_GROUPS_HASH_SIZE - 1);
-}
-
-/**
- * __rmcGroupLookupHashEntry()
- *
- *FUNCTION:
- * This function is called to lookup RMC group entries
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- * Should be called with lkRmcLock held.
- *
- *NOTE:
- * NA
- *
- * @param groupAddr - multicast group address
- * transmitter - address of multicast transmitter
- * role - transmitter or leader
- *
- * @return pointer to tLimRmcGroupContext
- */
-
-static tLimRmcGroupContext *
-__rmcGroupLookupHashEntry(tpAniSirGlobal pMac, tSirMacAddr transmitter)
-{
- tANI_U8 index;
- tLimRmcGroupContext *entry;
-
- index = __rmcGroupHashFunction(transmitter);
-
- /* Pick the correct hash table based on role */
- entry = pMac->rmcContext.rmcGroupRxHashTable[index];
-
- PELOG1(limLog(pMac, LOG1, FL("RMC: Hash Lookup:[%d] transmitter "
- MAC_ADDRESS_STR ), index,
- MAC_ADDR_ARRAY(transmitter));)
- while (entry)
- {
- if (vos_mem_compare(transmitter, entry->transmitter,
- sizeof(v_MACADDR_t)))
- {
- return entry;
- }
-
- entry = entry->next;
- }
-
- return NULL;
-}
-
-/**
- * __rmcGroupInsertHashEntry()
- *
- *FUNCTION:
- * This function is called to insert RMC group entry
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- * Should be called with lkRmcLock held.
- *
- *NOTE:
- * NA
- *
- * @param transmitter - address of multicast transmitter
- *
- * @return pointer to tLimRmcGroupContext
- */
-static tLimRmcGroupContext *
-__rmcGroupInsertHashEntry(tpAniSirGlobal pMac, tSirMacAddr transmitter)
-{
- tANI_U8 index;
- tLimRmcGroupContext *entry;
- tLimRmcGroupContext **head;
-
- index = __rmcGroupHashFunction(transmitter);
-
- PELOG1(limLog(pMac, LOG1, FL("RMC: Hash Insert:[%d] group " MAC_ADDRESS_STR
- " transmitter " MAC_ADDRESS_STR), index,
- MAC_ADDR_ARRAY(mcastGroupAddr),
- MAC_ADDR_ARRAY(transmitter));)
-
- head = &pMac->rmcContext.rmcGroupRxHashTable[index];
-
- entry = __rmcGroupLookupHashEntry(pMac, transmitter);
-
- if (entry)
- {
- /* If the entry exists, return it at the end */
- PELOGE(limLog(pMac, LOGE, FL("RMC: Hash Insert:"
- MAC_ADDRESS_STR "exists"), MAC_ADDR_ARRAY(transmitter));)
- }
- else
- {
- entry = (tLimRmcGroupContext *)vos_mem_malloc(sizeof(*entry));
-
- PELOG1(limLog(pMac, LOG1, FL("RMC: Hash Insert:new entry %p"), entry);)
-
- if (entry)
- {
- vos_mem_copy(entry->transmitter, transmitter, sizeof(tSirMacAddr));
- entry->isLeader = eRMC_IS_NOT_A_LEADER;
-
- /* chain this entry */
- entry->next = *head;
- *head = entry;
- }
- else
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Hash Insert:" MAC_ADDRESS_STR
- " alloc failed"), MAC_ADDR_ARRAY(transmitter));)
- }
- }
-
- return entry;
-}
-
-/**
- * __rmcGroupDeleteHashEntry()
- *
- *FUNCTION:
- * This function is called to delete a RMC group entry
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- * Should be called with lkRmcLock held.
- *
- *NOTE:
- * Make sure (for the transmitter role) that the entry is
- * not in the Pending Response queue.
- *
- * @param transmitter - address of multicast transmitter
- *
- * @return status
- */
-static tSirRetStatus
-__rmcGroupDeleteHashEntry(tpAniSirGlobal pMac, tSirMacAddr transmitter)
-{
- tSirRetStatus status = eSIR_FAILURE;
- tANI_U8 index;
- tLimRmcGroupContext *entry, *prev, **head;
-
- index = __rmcGroupHashFunction(transmitter);
-
- head = &pMac->rmcContext.rmcGroupRxHashTable[index];
- entry = *head;
- prev = NULL;
-
- while (entry)
- {
- if (vos_mem_compare(transmitter, entry->transmitter,
- sizeof(v_MACADDR_t)))
- {
- if (*head == entry)
- {
- *head = entry->next;
- }
- else
- {
- prev->next = entry->next;
- }
-
- PELOG1(limLog(pMac, LOG1, FL("RMC: Hash Delete: entry %p "
- " transmitter " MAC_ADDRESS_STR), entry
- MAC_ADDR_ARRAY(transmitter));)
-
- /* free the group entry */
- vos_mem_free(entry);
-
- status = eSIR_SUCCESS;
- break;
- }
-
- prev = entry;
- entry = entry->next;
- }
-
- return status;
-}
-
-/**
- * __rmcGroupDeleteAllEntries()
- *
- *FUNCTION:
- * This function is called to delete all RMC group entries
- * for either transmitter or leader, depending on the parameter.
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- * Should be called with lkRmcLock held.
- *
- *NOTE:
- *
- * @param pMac
- * role - transmitter or leader
- * @return
- */
-static void
-__rmcGroupDeleteAllEntries(tpAniSirGlobal pMac)
-{
- tLimRmcGroupContext *entry, **head;
- int index;
-
- PELOG1(limLog(pMac, LOG1, FL("RMC: Hash_Delete_All"),);)
-
- for (index = 0; index < RMC_MCAST_GROUPS_HASH_SIZE; index++)
- {
- head = &pMac->rmcContext.rmcGroupRxHashTable[index];
-
- entry = *head;
-
- while (entry)
- {
- *head = entry->next;
- /* free the group entry */
- vos_mem_free(entry);
- entry = *head;
- }
- }
-}
-
-/* End RMC utility routines */
-
-/**
- * \brief Send WDA_RMC_LEADER_REQ to HAL, in order
- * to request for a Multicast Leader selection.
- *
- * \sa __limPostMsgLeaderReq
- *
- * \param pMac The global tpAniSirGlobal object
- *
- * \param cmd SUGGEST leader or BECOME leader
- *
- * \param mcastGroup Multicast Group address
- *
- * \param mcastTransmitter Multicast Transmitter address
-
- * \return none
- *
- */
-static void
-__limPostMsgLeaderReq ( tpAniSirGlobal pMac,
- tANI_U8 cmd,
- tSirMacAddr mcastTransmitter)
-{
- tSirMsgQ msg;
- tSirRmcLeaderReq *pLeaderReq;
-
- pLeaderReq = vos_mem_malloc(sizeof(*pLeaderReq));
- if (NULL == pLeaderReq)
- {
- limLog(pMac, LOGE, FL("AllocateMemory() failed"));
- return;
- }
-
- pLeaderReq->cmd = cmd;
-
- vos_mem_copy(pLeaderReq->mcastTransmitter, mcastTransmitter,
- sizeof(tSirMacAddr));
-
- /* Initialize black list */
- vos_mem_zero(pLeaderReq->blacklist, sizeof(pLeaderReq->blacklist));
-
- /*
- * If there are a list of STA receivers that we do not want to be
- * considered for Leader, send it here.
- */
- if (eRMC_SUGGEST_LEADER_CMD == cmd)
- {
- /* TODO - Set the black list. */
- }
-
- msg.type = WDA_RMC_LEADER_REQ;
- msg.bodyptr = pLeaderReq;
- msg.bodyval = 0;
-
- MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type));
- if (eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
- {
- vos_mem_free(pLeaderReq);
- limLog(pMac, LOGE, FL("wdaPostCtrlMsg() failed"));
- }
-
- return;
-}
-
-/**
- * \brief Send WDA_RMC_UPDATE_IND to HAL, in order
- * to request for a Multicast Leader selection.
- *
- * \sa __limPostMsgUpdateInd
- *
- * \param pMac The global tpAniSirGlobal object
- *
- * \param indication Accepted or Cancelled
- *
- * \param role Leader or Transmitter
- *
- * \param mcastGroup Multicast Group address
- *
- * \param mcastTransmitter Multicast Transmitter address
- *
- * \param mcastLeader Multicast Leader address
- *
- * \return none
- *
- */
-static void
-__limPostMsgUpdateInd ( tpAniSirGlobal pMac,
- tANI_U8 indication,
- tANI_U8 role,
- tSirMacAddr mcastTransmitter,
- tSirMacAddr mcastLeader)
-{
- tSirMsgQ msg;
- tSirRmcUpdateInd *pUpdateInd;
-
- pUpdateInd = vos_mem_malloc(sizeof(*pUpdateInd));
- if ( NULL == pUpdateInd )
- {
- limLog(pMac, LOGE, FL("AllocateMemory() failed"));
- return;
- }
-
- vos_mem_zero(pUpdateInd, sizeof(*pUpdateInd));
-
- pUpdateInd->indication = indication;
- pUpdateInd->role = role;
-
- vos_mem_copy(pUpdateInd->mcastTransmitter,
- mcastTransmitter, sizeof(tSirMacAddr));
-
- vos_mem_copy(pUpdateInd->mcastLeader,
- mcastLeader, sizeof(tSirMacAddr));
-
- msg.type = WDA_RMC_UPDATE_IND;
- msg.bodyptr = pUpdateInd;
- msg.bodyval = 0;
-
- MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type));
- if (eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
- {
- vos_mem_free(pUpdateInd);
- limLog(pMac, LOGE, FL("wdaPostCtrlMsg() failed"));
- }
-
- return;
-}
-
-static char *
-__limLeaderMessageToString(eRmcMessageType msgType)
-{
- switch (msgType)
- {
- default:
- return "Invalid";
- case eLIM_RMC_ENABLE_REQ:
- return "RMC_ENABLE_REQ";
- case eLIM_RMC_DISABLE_REQ:
- return "RMC_DISABLE_REQ";
- case eLIM_RMC_LEADER_SELECT_RESP:
- return "RMC_LEADER_SELECT_RESP";
- case eLIM_RMC_LEADER_PICK_NEW:
- return "RMC_LEADER_PICK_NEW";
- case eLIM_RMC_OTA_LEADER_INFORM_ACK:
- return "RMC_OTA_LEADER_INFORM_ACK";
- case eLIM_RMC_OTA_LEADER_INFORM_SELECTED:
- return "RMC_OTA_LEADER_INFORM_SELECTED";
- case eLIM_RMC_BECOME_LEADER_RESP:
- return "RMC_BECOME_LEADER_RESP";
- case eLIM_RMC_OTA_LEADER_INFORM_CANCELLED:
- return "RMC_OTA_LEADER_INFORM_CANCELLED";
- }
-}
-
-static char *
-__limLeaderStateToString(eRmcLeaderState state)
-{
- switch (state)
- {
- default:
- return "Invalid";
- case eRMC_IS_NOT_A_LEADER:
- return "Device Not a Leader";
- case eRMC_LEADER_PENDING:
- return "Pending firmware resp";
- case eRMC_IS_A_LEADER:
- return "Device is Leader";
- }
-}
-
-static char *
-__limMcastTxStateToString(eRmcMcastTxState state)
-{
- switch (state)
- {
- default:
- return "Invalid";
- case eRMC_LEADER_NOT_SELECTED:
- return "Not Selected";
- case eRMC_LEADER_ENABLE_REQUESTED:
- return "Enable Requested";
- case eRMC_LEADER_OTA_REQUEST_SENT:
- return "OTA Request Sent";
- case eRMC_LEADER_ACTIVE:
- return "Active";
- }
-}
-
-/**
- * __rmcLeaderSelectTimerHandler()
- *
- *FUNCTION:
- * This function is called upon timer expiry.
- *
- *LOGIC: This function handles unacked LEADER_INFORM messages.
- * If a leader fails to respond, it tries the next one in
- * the list. If all potential leaders are exhausted, the
- * multicast group is removed.
- *
- *ASSUMPTIONS:
- * NA
- *
- *NOTE:
- * Only one entry is processed for every invocation if this routine.
- * This allows us to use a single timer and makes sure we do not
- * timeout a request too early.
- *
- * @param param - Message corresponding to the timer that expired
- *
- * @return None
- */
-
-void
-__rmcLeaderSelectTimerHandler(void *pMacGlobal, tANI_U32 param)
-{
- tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
- tSirMacAddr zeroMacAddr = { 0, 0, 0, 0, 0, 0 };
- tSirRetStatus status;
- tSirRMCInfo RMC;
- tpPESession psessionEntry;
- tANI_U32 cfgValue;
-
- /*
- * This API relies on a single active IBSS session.
- */
- psessionEntry = limIsIBSSSessionActive(pMac);
- if (NULL == psessionEntry)
- {
- PELOGE(limLog(pMac, LOGE,
- FL("RMC:__rmcLeaderSelectTimerHandler:No active IBSS"));)
- return;
- }
-
- if (wlan_cfgGetInt(pMac, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
- &cfgValue) != eSIR_SUCCESS)
- {
- /**
- * Could not get Action Period Frequency value
- * from CFG. Log error.
- */
- limLog(pMac, LOGE, FL("could not retrieve ActionPeriodFrequency"));
- }
-
- cfgValue = SYS_MS_TO_TICKS(cfgValue);
-
- if (pMac->rmcContext.rmcTimerValInTicks != cfgValue)
- {
- limLog(pMac, LOG1, FL("RMC LeaderSelect timer value changed"));
- if (tx_timer_change(&pMac->rmcContext.gRmcLeaderSelectTimer,
- cfgValue, 0) != TX_SUCCESS)
- {
- limLog(pMac, LOGE,
- FL("Unable to change LeaderSelect Timer val"));
- }
- pMac->rmcContext.rmcTimerValInTicks = cfgValue;
- }
-
- /*
- * If we are in the scanning state then we need to return
- * from this function without any further processing
- */
- if (eLIM_HAL_SCANNING_STATE == pMac->lim.gLimHalScanState)
- {
- limLog(pMac, LOG1, FL("In scanning state, can't send action frm"));
- if (tx_timer_activate(&pMac->rmcContext.gRmcLeaderSelectTimer) !=
- TX_SUCCESS)
- {
- limLog(pMac, LOGE, FL("In scanning state, "
- "couldn't activate RMC LeaderSelect timer"));
- }
- return;
- }
-
- /* Acquire RMC lock */
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE,
- FL("__rmcLeaderSelectTimerHandler lock acquire failed"));
- if (tx_timer_activate(&pMac->rmcContext.gRmcLeaderSelectTimer)!= TX_SUCCESS)
- {
- limLog(pMac, LOGE, FL("could not activate RMC LeaderSelect timer"));
- }
- return;
- }
-
- vos_mem_copy(&RMC.mcastLeader, &pMac->rmcContext.leader,
- sizeof(tSirMacAddr));
-
- if (VOS_FALSE == vos_mem_compare(&zeroMacAddr,
- &pMac->rmcContext.leader, sizeof(tSirMacAddr)))
- {
- limLog(pMac, LOG1,
- FL("RMC Periodic Leader_Select Leader " MAC_ADDRESS_STR),
- MAC_ADDR_ARRAY(pMac->rmcContext.leader));
- /*
- * Re-arm timer
- */
- if (tx_timer_activate(&pMac->rmcContext.gRmcLeaderSelectTimer)!=
- TX_SUCCESS)
- {
- limLog(pMac, LOGE, FL("could not activate RMC Response timer"));
- }
-
- /* Release RMC lock */
- if (!VOS_IS_STATUS_SUCCESS
- (vos_lock_release(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE,
- FL("RMC: __rmcLeaderSelectTimerHandler lock release failed"));
- }
- }
- else
- {
- limLog(pMac, LOGE,
- FL("RMC Deactivating timer because no leader was selected"));
-
- /* Release RMC lock */
- if (!VOS_IS_STATUS_SUCCESS
- (vos_lock_release(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE,
- FL("RMC: __rmcLeaderSelectTimerHandler lock release failed"));
- }
-
- return;
- }
-
- /*
- * Handle periodic transmission of Leader_Select Action frame.
- */
-
- RMC.dialogToken = 0;
- RMC.action = SIR_MAC_RMC_LEADER_INFORM_SELECTED;
-
- status = limSendRMCActionFrame(pMac,
- SIR_MAC_RMC_MCAST_ADDRESS,
- &RMC,
- psessionEntry);
-
- if (eSIR_FAILURE == status)
- {
- PELOGE(limLog(pMac, LOGE,
- FL("RMC:__rmcLeaderSelectTimerHandler Action frame send failed"));)
- }
-
- return;
-}
-
-/**
- * __limProcessRMCEnableRequest()
- *
- *FUNCTION:
- * This function is called to processes eLIM_RMC_ENABLE_REQ
- * message from SME.
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- *
- *NOTE:
- *
- * @param pMac Pointer to Global MAC structure
- * @param pMsgBuf A pointer to the RMC message buffer
- *
- * @return None
- */
-static void
-__limProcessRMCEnableRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
-{
- tSirSetRMCReq *setRmcReq = (tSirSetRMCReq *)pMsgBuf;
- tpPESession psessionEntry;
-
- if (!setRmcReq)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Enable:NULL message") );)
- return;
- }
-
- /*Enable RMC*/
- pMac->rmcContext.rmcEnabled = TRUE;
-
- /*
- * This API relies on a single active IBSS session.
- */
- psessionEntry = limIsIBSSSessionActive(pMac);
- if (NULL == psessionEntry)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC:Enable RMC request no active IBSS"));)
- pMac->rmcContext.state = eRMC_LEADER_NOT_SELECTED;
- return;
- }
-
- /* Send LBP_LEADER_REQ to f/w */
- __limPostMsgLeaderReq(pMac, eRMC_SUGGEST_LEADER_CMD,
- setRmcReq->mcastTransmitter);
-
- pMac->rmcContext.state = eRMC_LEADER_ENABLE_REQUESTED;
-}
-
-/**
- * __limProcessRMCDisableRequest()
- *
- *FUNCTION:
- * This function is called to processes eLIM_RMC_DISABLE_REQ
- * message from SME.
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- *
- *NOTE:
- *
- * @param pMac Pointer to Global MAC structure
- * @param pMsgBuf A pointer to the RMC message buffer
- *
- * @return None
- */
-static void
-__limProcessRMCDisableRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
-{
- tpPESession psessionEntry;
- tSirRMCInfo RMC;
- tSirSetRMCReq *setRmcReq = (tSirSetRMCReq *)pMsgBuf;
- tSirRetStatus status;
- v_PVOID_t pvosGCtx;
- VOS_STATUS vos_status;
- v_MACADDR_t vosMcastTransmitter;
-
- /*Disable RMC*/
- pMac->rmcContext.rmcEnabled = FALSE;
-
- /*
- * This API relies on a single active IBSS session.
- */
- psessionEntry = limIsIBSSSessionActive(pMac);
- if (NULL == psessionEntry)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Disable:No active IBSS"));)
- return;
- }
-
- if (!setRmcReq)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Disable:NULL message") );)
- return;
- }
-
- /* Cancel pending timer */
- tx_timer_deactivate(&pMac->rmcContext.gRmcLeaderSelectTimer);
-
- vosMcastTransmitter.bytes[0] = psessionEntry->selfMacAddr[0];
- vosMcastTransmitter.bytes[1] = psessionEntry->selfMacAddr[1];
- vosMcastTransmitter.bytes[2] = psessionEntry->selfMacAddr[2];
- vosMcastTransmitter.bytes[3] = psessionEntry->selfMacAddr[3];
- vosMcastTransmitter.bytes[4] = psessionEntry->selfMacAddr[4];
- vosMcastTransmitter.bytes[5] = psessionEntry->selfMacAddr[5];
-
- /* Disable RMC in TL */
- pvosGCtx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac);
- vos_status = WLANTL_DisableReliableMcast(pvosGCtx, &vosMcastTransmitter);
-
- if (VOS_STATUS_SUCCESS != vos_status)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC:Disable: TL disable failed"));)
- }
-
- if (pMac->rmcContext.state == eRMC_LEADER_ACTIVE)
- {
- /*
- * Send Leader_Inform_Cancelled Action frame to the Leader.
- */
- RMC.dialogToken = 0;
- RMC.action = SIR_MAC_RMC_LEADER_INFORM_CANCELLED;
- vos_mem_copy(&RMC.mcastLeader, &pMac->rmcContext.leader, sizeof(tSirMacAddr));
-
- status = limSendRMCActionFrame(pMac, pMac->rmcContext.leader,
- &RMC, psessionEntry);
- if (eSIR_FAILURE == status)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC:Disable: Action frame send failed"));)
- }
-
- pMac->rmcContext.state = eRMC_LEADER_NOT_SELECTED;
- }
-
- /* send LBP_UPDATE_IND */
- __limPostMsgUpdateInd(pMac, eRMC_LEADER_CANCELLED, eRMC_TRANSMITTER_ROLE,
- setRmcReq->mcastTransmitter, pMac->rmcContext.leader);
-
- vos_mem_zero(pMac->rmcContext.leader, sizeof(tSirMacAddr));
-
-}
-
-/**
- * __limProcessRMCLeaderSelectResponse()
- *
- *FUNCTION:
- * This function is called to processes eLIM_RMC_LEADER_SELECT_RESP
- * message from the firmware.
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- *
- *NOTE:
- *
- * @param pMac Pointer to Global MAC structure
- * @param pMsgBuf A pointer to the RMC message buffer
- *
- * @return None
- */
-static void
-__limProcessRMCLeaderSelectResponse(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
-{
- tSirRmcLeaderSelectInd *pRmcLeaderSelectInd;
- tpPESession psessionEntry;
- tSirRetStatus status;
- v_PVOID_t pvosGCtx;
- VOS_STATUS vos_status;
- v_MACADDR_t vosMcastTransmitter;
- tSirRMCInfo RMC;
-
- if (NULL == pMsgBuf)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Leader_Select_Resp:NULL message"));)
- return;
- }
-
- /*
- * This API relies on a single active IBSS session.
- */
- psessionEntry = limIsIBSSSessionActive(pMac);
- if (NULL == psessionEntry)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC:Leader_Select_Resp:No active IBSS"));)
- pMac->rmcContext.state = eRMC_LEADER_NOT_SELECTED;
- return;
- }
-
- pRmcLeaderSelectInd = (tSirRmcLeaderSelectInd *)pMsgBuf;
-
- if (pMac->rmcContext.state != eRMC_LEADER_ENABLE_REQUESTED)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Leader_Select_Resp:Bad state %s"),
- __limMcastTxStateToString(pMac->rmcContext.state) );)
- return;
- }
-
- if (pRmcLeaderSelectInd->status)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC:Leader_Select_Resp:FW Status %d"),
- pRmcLeaderSelectInd->status);)
- pMac->rmcContext.state = eRMC_LEADER_NOT_SELECTED;
- return;
- }
-
- /* Acquire RMC lock */
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE, FL("RMC:Leader_Select_Resp:lock acquire failed"));
- pMac->rmcContext.state = eRMC_LEADER_NOT_SELECTED;
- return;
- }
-
- /* Cache the current leader */
- vos_mem_copy(&pMac->rmcContext.leader, &pRmcLeaderSelectInd->leader[0],
- sizeof(tSirMacAddr));
-
- /* Release RMC lock */
- if (!VOS_IS_STATUS_SUCCESS
- (vos_lock_release(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE, FL("RMC: Leader_Select_Resp: lock release failed"));
- }
-
- RMC.dialogToken = 0;
- RMC.action = SIR_MAC_RMC_LEADER_INFORM_SELECTED;
- vos_mem_copy(&RMC.mcastLeader, &pRmcLeaderSelectInd->leader[0],
- sizeof(tSirMacAddr));
-
- PELOG1(limLog(pMac, LOG1, FL("RMC: Leader_Select :leader " MAC_ADDRESS_STR),
- MAC_ADDR_ARRAY(pRmcLeaderSelectInd->leader[0]));)
-
- /*
- * Send Leader_Inform Action frame to the candidate leader.
- * Candidate leader is at leader_index.
- */
- status = limSendRMCActionFrame(pMac,
- SIR_MAC_RMC_MCAST_ADDRESS,
- &RMC,
- psessionEntry);
-
- if (eSIR_FAILURE == status)
- {
- PELOGE(limLog(pMac, LOGE,
- FL("RMC: Leader_Select_Resp: Action send failed"));)
- }
-
- /* send LBP_UPDATE_IND */
- __limPostMsgUpdateInd(pMac, eRMC_LEADER_ACCEPTED, eRMC_TRANSMITTER_ROLE,
- psessionEntry->selfMacAddr, pMac->rmcContext.leader);
-
- vosMcastTransmitter.bytes[0] = psessionEntry->selfMacAddr[0];
- vosMcastTransmitter.bytes[1] = psessionEntry->selfMacAddr[1];
- vosMcastTransmitter.bytes[2] = psessionEntry->selfMacAddr[2];
- vosMcastTransmitter.bytes[3] = psessionEntry->selfMacAddr[3];
- vosMcastTransmitter.bytes[4] = psessionEntry->selfMacAddr[4];
- vosMcastTransmitter.bytes[5] = psessionEntry->selfMacAddr[5];
-
- /* Enable TL */
- pvosGCtx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac);
- vos_status = WLANTL_EnableReliableMcast(pvosGCtx, &vosMcastTransmitter);
-
- /* Set leader state to Active. */
- pMac->rmcContext.state = eRMC_LEADER_ACTIVE;
-
- /* Start timer to send periodic Leader_Select */
- if (tx_timer_activate(&pMac->rmcContext.gRmcLeaderSelectTimer)!= TX_SUCCESS)
- {
- limLog(pMac, LOGE,
- FL("Leader_Select_Resp:Activate RMC Response timer failed"));
- }
-}
-
-/**
- * __limProcessRMCLeaderPickNew()
- *
- *FUNCTION:
- * This function is called to processes eLIM_RMC_LEADER_PICK_NEW
- * message from the firmware.
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- *
- *NOTE:
- *
- * @param pMac Pointer to Global MAC structure
- * @param pMsgBuf A pointer to the RMC message buffer
- *
- * @return None
- */
-static void
-__limProcessRMCLeaderPickNew(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
-{
- tSirRmcUpdateInd *pRmcUpdateInd;
- tpPESession psessionEntry;
- tSirRetStatus status;
- tSirRMCInfo RMC;
- v_PVOID_t pvosGCtx;
- VOS_STATUS vos_status;
- v_MACADDR_t vosMcastTransmitter;
- tSirMacAddr zeroMacAddr = { 0, 0, 0, 0, 0, 0 };
-
- if (NULL == pMsgBuf)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Leader_Pick_New:NULL message"));)
- return;
- }
-
- /*
- * This API relies on a single active IBSS session.
- */
- psessionEntry = limIsIBSSSessionActive(pMac);
- if (NULL == psessionEntry)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Leader_Pick_New:No active IBSS"));)
- return;
- }
-
- pvosGCtx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac);
-
- pRmcUpdateInd = (tSirRmcUpdateInd *)pMsgBuf;
-
- /* Acquire RMC lock */
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE, FL("RMC:Leader_Pick_New:lock acquire failed"));
- return;
- }
-
-
- /* Fill out Action frame parameters */
- RMC.dialogToken = 0;
-
- /*
- * Check the multicast Leader address sent by firmware.
- * Prepare to send Leader_Inform_Cancel only if this address
- * is valid.
- */
- if (VOS_FALSE == vos_mem_compare(&zeroMacAddr,
- &pRmcUpdateInd->mcastLeader,
- sizeof(tSirMacAddr)))
- {
-
- vos_mem_copy(&RMC.mcastLeader, &pRmcUpdateInd->mcastLeader,
- sizeof(tSirMacAddr));
-
- /*
- * Send Leader_Inform_Cancelled Action frame to the current leader.
- */
- RMC.action = SIR_MAC_RMC_LEADER_INFORM_CANCELLED;
- status = limSendRMCActionFrame(pMac,
- pRmcUpdateInd->mcastLeader,
- &RMC, psessionEntry);
- if (eSIR_FAILURE == status)
- {
- PELOGE(limLog(pMac, LOGE,
- FL("RMC:Leader_Pick_New: Inform_Cancel Action send failed"));)
- goto done;
- }
-
- vosMcastTransmitter.bytes[0] = psessionEntry->selfMacAddr[0];
- vosMcastTransmitter.bytes[1] = psessionEntry->selfMacAddr[1];
- vosMcastTransmitter.bytes[2] = psessionEntry->selfMacAddr[2];
- vosMcastTransmitter.bytes[3] = psessionEntry->selfMacAddr[3];
- vosMcastTransmitter.bytes[4] = psessionEntry->selfMacAddr[4];
- vosMcastTransmitter.bytes[5] = psessionEntry->selfMacAddr[5];
-
- /* Disable RMC in TL */
- vos_status = WLANTL_DisableReliableMcast(pvosGCtx, &vosMcastTransmitter);
-
- if (VOS_STATUS_SUCCESS != vos_status)
- {
- PELOGE(limLog(pMac, LOGE,
- FL("RMC:Leader_Pick_New: TL disable failed"));)
- }
- }
-
- /*
- * Cache the leader list for this multicast group
- * If no leader list was given, this will essentially zero out
- * the list.
- */
- vos_mem_copy(pMac->rmcContext.leader, pRmcUpdateInd->leader[0],
- sizeof(tSirMacAddr));
-
- pMac->rmcContext.state = eRMC_LEADER_NOT_SELECTED;
-
- /*
- * Verify that the Pick_New indication has any candidate leaders.
- */
- if (VOS_TRUE == vos_mem_compare(&zeroMacAddr,
- pMac->rmcContext.leader,
- sizeof(tSirMacAddr)))
- {
- PELOGE(limLog(pMac, LOGE,
- FL("RMC:Leader_Pick_New: No candidate leaders available"));)
- goto done;
- }
-
- /*
- * Send Leader_Inform Action frame to the new candidate leader.
- */
-
- RMC.action = SIR_MAC_RMC_LEADER_INFORM_SELECTED;
- vos_mem_copy(&RMC.mcastLeader, &pMac->rmcContext.leader,
- sizeof(tSirMacAddr));
- status = limSendRMCActionFrame(pMac, SIR_MAC_RMC_MCAST_ADDRESS,
- &RMC, psessionEntry);
- if (eSIR_FAILURE == status)
- {
- PELOGE(limLog(pMac, LOGE,
- FL("RMC:Leader_Pick_New: Inform_Selected Action send failed"));)
- goto done;
- }
-
- /* send LBP_UPDATE_IND */
- __limPostMsgUpdateInd(pMac, eRMC_LEADER_ACCEPTED, eRMC_TRANSMITTER_ROLE,
- psessionEntry->selfMacAddr, pMac->rmcContext.leader);
-
- vosMcastTransmitter.bytes[0] = psessionEntry->selfMacAddr[0];
- vosMcastTransmitter.bytes[1] = psessionEntry->selfMacAddr[1];
- vosMcastTransmitter.bytes[2] = psessionEntry->selfMacAddr[2];
- vosMcastTransmitter.bytes[3] = psessionEntry->selfMacAddr[3];
- vosMcastTransmitter.bytes[4] = psessionEntry->selfMacAddr[4];
- vosMcastTransmitter.bytes[5] = psessionEntry->selfMacAddr[5];
-
- /* Enable TL */
- vos_status = WLANTL_EnableReliableMcast(pvosGCtx, &vosMcastTransmitter);
-
- if (VOS_STATUS_SUCCESS != vos_status)
- {
- PELOGE(limLog(pMac, LOGE,
- FL("RMC:Leader_Pick_New: TL enable failed"));)
- goto done;
- }
-
- /* Set leader state to Active. */
- pMac->rmcContext.state = eRMC_LEADER_ACTIVE;
-
- /* Start timer to send periodic Leader_Select */
- if (tx_timer_activate(&pMac->rmcContext.gRmcLeaderSelectTimer)!= TX_SUCCESS)
- {
- limLog(pMac, LOGE,
- FL("Leader_Pick_New:Activate RMC Response timer failed"));
- }
-
-done:
- /* Release RMC lock */
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE,
- FL("RMC: Leader_Pick_New: lock release failed"));
- }
-}
-
-/**
- * __limProcessRMCLeaderInformSelected()
- *
- *FUNCTION:
- * This function is called to processes eLIM_RMC_OTA_LEADER_INFORM_SELECTED
- * message from the "Leader Inform" Action frame from the
- * multicast transmitter.
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- *
- *NOTE:
- *
- * @param pMac Pointer to Global MAC structure
- * @param pMsgBuf A pointer to the RMC message buffer
- *
- * @return None
- */
-static void
-__limProcessRMCLeaderInformSelected(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
-{
- tpSirMacMgmtHdr pHdr;
- tANI_U8 *pFrameData;
- tANI_U32 frameLen;
- tLimRmcGroupContext *entry;
- tpPESession psessionEntry;
- tSirRetStatus status;
-
- if (!pMsgBuf)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Leader_Inform:NULL msg"));)
- return;
- }
-
- /*
- * This API relies on a single active IBSS session.
- */
- psessionEntry = limIsIBSSSessionActive(pMac);
- if (NULL == psessionEntry)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC:Become_Leader_Resp:No active IBSS"));)
- return;
- }
-
- /*
- * Get the frame header
- */
- pHdr = WDA_GET_RX_MAC_HEADER((tANI_U8 *)pMsgBuf);
-
- frameLen = WDA_GET_RX_PAYLOAD_LEN((tANI_U8 *)pMsgBuf);
- if (frameLen < sizeof(tSirMacOxygenNetworkFrameHdr))
- {
- PELOGE(limLog(pMac, LOGE,
- FL("RMC: Leader_Inform:Bad length %d "), frameLen);)
- return;
- }
-
- pFrameData = WDA_GET_RX_MPDU_DATA((tANI_U8 *)pMsgBuf) +
- sizeof(tSirMacOxygenNetworkFrameHdr);
-
- if (!pFrameData)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Leader_Inform:NULL data"));)
- return;
- }
-
- /* Acquire RMC lock */
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE, FL("RMC:Become_Leader_Resp:lock acquire failed"));
- return;
- }
-
- /*
- * Check if this transmitter exists in our database.
- */
- entry = __rmcGroupLookupHashEntry(pMac, pHdr->sa);
-
- /*
- * Check if we are being advertised as the leader.
- * The leader address is from the Action frame payload.
- */
- if (VOS_FALSE == vos_mem_compare(pFrameData, psessionEntry->selfMacAddr,
- sizeof(tSirMacAddr)))
- {
- /*
- * If we were the leader for this transmitter, tell the firmware
- * that we are not any more. This is a implicit Leader_Cancel.
- */
- if (entry)
- {
- PELOG1(limLog(pMac, LOG1,
- FL("RMC: Leader_Inform: Leader Cancelled"));)
- /* send LBP_UPDATE_IND */
- __limPostMsgUpdateInd(pMac, eRMC_LEADER_CANCELLED,
- eRMC_LEADER_ROLE, pHdr->sa, psessionEntry->selfMacAddr);
-
- /*
- * Delete hash entry for this Group address.
- */
- status = __rmcGroupDeleteHashEntry(pMac, pHdr->sa);
- if (eSIR_FAILURE == status)
- {
- PELOGE(limLog(pMac, LOGE,
- FL("RMC: Leader_Inform:hash delete failed"));)
- }
- }
- }
- else
- {
- /*
- * If we have been selected as the new leader for this transmitter,
- * add it to your database. If we are already in the database, there
- * is nothing to do.
- */
- if (NULL == entry)
- {
- /* Add the transmitter address to the hash */
- entry = __rmcGroupInsertHashEntry(pMac, pHdr->sa);
- if (entry)
- {
- if (entry->isLeader != eRMC_LEADER_PENDING)
- {
- /* Send LBP_LEADER_REQ to f/w */
- __limPostMsgLeaderReq(pMac, eRMC_BECOME_LEADER_CMD,
- pHdr->sa);
- entry->isLeader = eRMC_LEADER_PENDING;
- }
- }
- else
- {
- PELOGE(limLog(pMac, LOGE,
- FL("RMC: Leader_Inform:Hash insert failed"));)
- }
-
- }
- }
-
- /* Release RMC lock */
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE,
- FL("RMC: Leader_Inform: lock release failed"));
- }
-
-}
-
-/**
- * __limProcessRMCBecomeLeaderResp()
- *
- *FUNCTION:
- * This function is called to processes eLIM_RMC_BECOME_LEADER_RESP
- * message from the firmware.
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- *
- *NOTE:
- *
- * @param pMac Pointer to Global MAC structure
- * @param pMsgBuf A pointer to the RMC message buffer
- *
- * @return None
- */
-static void
-__limProcessRMCBecomeLeaderResp(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
-{
- tSirRmcBecomeLeaderInd *pRmcBecomeLeaderInd;
- tLimRmcGroupContext *entry;
- tSirRetStatus status = eSIR_SUCCESS;
-
- if (NULL == pMsgBuf)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Become_Leader_Resp:NULL message"));)
- return;
- }
-
- pRmcBecomeLeaderInd = (tSirRmcBecomeLeaderInd *)pMsgBuf;
-
- /* Acquire RMC lock */
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE, FL("RMC:Become_Leader_Resp:lock acquire failed"));
- return;
- }
-
- /*
- * Find the entry for this Group Address.
- */
- entry = __rmcGroupLookupHashEntry(pMac,
- pRmcBecomeLeaderInd->mcastTransmitter);
- if (NULL == entry)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Become_Leader_Resp: No entry"));)
- goto done;
- }
-
- if (pRmcBecomeLeaderInd->status)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC:Become_Leader_Resp:FW Status %d"),
- pRmcBecomeLeaderInd->status);)
- status = eSIR_FAILURE;
- goto done;
- }
-
- if (entry->isLeader != eRMC_LEADER_PENDING)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Become_Leader_Resp:Bad state: %s"),
- __limLeaderStateToString(entry->isLeader) );)
- status = eSIR_FAILURE;
- goto done;
- }
-
- entry->isLeader = eRMC_IS_A_LEADER;
-
-done:
- if (eSIR_FAILURE == status)
- {
- status = __rmcGroupDeleteHashEntry(pMac,
- pRmcBecomeLeaderInd->mcastTransmitter);
- if (eSIR_FAILURE == status)
- {
- PELOGE(limLog(pMac, LOGE,
- FL("RMC: Become_Leader_Resp:hash delete failed"));)
- }
- }
-
- /* Release RMC lock */
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE,
- FL("RMC: Become_Leader_Resp: lock release failed"));
- }
-
- return;
-}
-
-/**
- * __limProcessRMCLeaderInformCancelled()
- *
- *FUNCTION:
- * This function is called to processes eLIM_RMC_OTA_LEADER_INFORM_CANCELLED
- * message from the "Leader Inform Cancelled" Action frame from the
- * multicast transmitter.
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- *
- *NOTE:
- *
- * @param pMac Pointer to Global MAC structure
- * @param pMsgBuf A pointer to the RMC message buffer
- *
- * @return None
- */
-static void
-__limProcessRMCLeaderInformCancelled(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
-{
- tpSirMacMgmtHdr pHdr;
- tANI_U8 *pFrameData;
- tANI_U32 frameLen;
- tSirRetStatus status;
- tLimRmcGroupContext *entry;
- tpPESession psessionEntry;
-
- if (!pMsgBuf)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Leader_Inform_Cancel:NULL msg"));)
- return;
- }
-
- /*
- * This API relies on a single active IBSS session.
- */
- psessionEntry = limIsIBSSSessionActive(pMac);
- if (NULL == psessionEntry)
- {
- PELOGE(limLog(pMac, LOGE,
- FL("RMC:Leader_Inform_Cancel:No active IBSS"));)
- return;
- }
-
- pHdr = WDA_GET_RX_MAC_HEADER((tANI_U8 *)pMsgBuf);
-
- frameLen = WDA_GET_RX_PAYLOAD_LEN((tANI_U8 *)pMsgBuf);
- if (frameLen < sizeof(tSirMacOxygenNetworkFrameHdr))
- {
- PELOGE(limLog(pMac, LOGE,
- FL("RMC: Leader_Inform:Bad length %d "), frameLen);)
- return;
- }
-
- pFrameData = WDA_GET_RX_MPDU_DATA((tANI_U8 *)pMsgBuf) +
- sizeof(tSirMacOxygenNetworkFrameHdr);
-
- if (!pFrameData)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Leader_Inform_Cancel:NULL data"));)
- return;
- }
-
- /* Acquire RMC lock */
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE, FL("RMC:Leader_Inform_Cancel lock acquire failed"));
- return;
- }
-
- /*
- * Find the entry for this Group Address.
- */
- entry = __rmcGroupLookupHashEntry(pMac, pHdr->sa);
- if (NULL == entry)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Leader_Inform_Cancel: No entry"));)
- goto done;
- }
-
- /* send LBP_UPDATE_END */
- __limPostMsgUpdateInd(pMac, eRMC_LEADER_CANCELLED,
- eRMC_LEADER_ROLE, pHdr->sa, psessionEntry->selfMacAddr);
-
- /*
- * Delete hash entry for this Group address.
- */
- status = __rmcGroupDeleteHashEntry(pMac, pHdr->sa);
- if (eSIR_FAILURE == status)
- {
- PELOGE(limLog(pMac, LOGE,
- FL("RMC: Leader_Inform_Cancel:hash delete failed"));)
- }
-
-done:
- /* Release RMC lock */
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE,
- FL("RMC: Leader_Inform_Cancel: lock release failed"));
- }
- return;
-}
-
-/**
- * limProcessRMCMessages()
- *
- *FUNCTION:
- * This function is called to processes various RMC messages.
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- *
- *NOTE:
- *
- * @param pMac Pointer to Global MAC structure
- * @param msgType Indicates the RMC message type
- * @param *pMsgBuf A pointer to the RMC message buffer
- *
- * @return None
- */
-void
-limProcessRMCMessages(tpAniSirGlobal pMac, eRmcMessageType msgType,
- tANI_U32 *pMsgBuf)
-{
-
- if (pMsgBuf == NULL)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: Buffer is Pointing to NULL"));)
- return;
- }
-
- limLog(pMac, LOG1, FL("RMC: limProcessRMCMessages: %s"),
- __limLeaderMessageToString(msgType));
-
- switch (msgType)
- {
- /*
- * Begin - messages processed by RMC multicast transmitter.
- */
- case eLIM_RMC_ENABLE_REQ:
- __limProcessRMCEnableRequest(pMac, pMsgBuf);
- break;
-
- case eLIM_RMC_DISABLE_REQ:
- __limProcessRMCDisableRequest(pMac, pMsgBuf);
- break;
-
- case eLIM_RMC_LEADER_SELECT_RESP:
- __limProcessRMCLeaderSelectResponse(pMac, pMsgBuf);
- break;
-
- case eLIM_RMC_LEADER_PICK_NEW:
- __limProcessRMCLeaderPickNew(pMac, pMsgBuf);
- break;
-
- /*
- * End - messages processed by RMC multicast transmitter.
- */
-
- /*
- * Begin - messages processed by RMC Leader (receiver).
- */
- case eLIM_RMC_OTA_LEADER_INFORM_SELECTED:
- __limProcessRMCLeaderInformSelected(pMac, pMsgBuf);
- break;
-
- case eLIM_RMC_BECOME_LEADER_RESP:
- __limProcessRMCBecomeLeaderResp(pMac, pMsgBuf);
- break;
-
- case eLIM_RMC_OTA_LEADER_INFORM_CANCELLED:
- __limProcessRMCLeaderInformCancelled(pMac, pMsgBuf);
- break;
-
- /*
- * End - messages processed by RMC Leader (receiver).
- */
-
- default:
- break;
- } // switch (msgType)
- return;
-} /*** end limProcessRMCMessages() ***/
-
-/**
- * limRmcInit()
- *
- *FUNCTION:
- * This function is called to initialize RMC module.
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- *
- *NOTE:
- *
- * @param pMac Pointer to Global MAC structure
- *
- * @return None
- */
-void
-limRmcInit(tpAniSirGlobal pMac)
-{
- tANI_U32 cfgValue;
-
- if (wlan_cfgGetInt(pMac, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
- &cfgValue) != eSIR_SUCCESS)
- {
- /**
- * Could not get Action Period Frequency value
- * from CFG. Log error.
- */
- limLog(pMac, LOGP, FL("could not retrieve ActionPeriodFrequency"));
- }
-
- cfgValue = SYS_MS_TO_TICKS(cfgValue);
-
- vos_mem_zero(&pMac->rmcContext, sizeof(pMac->rmcContext));
-
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_init(&pMac->rmcContext.lkRmcLock)))
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC lock init failed!"));)
- }
-
- if (tx_timer_create(&pMac->rmcContext.gRmcLeaderSelectTimer,
- "RMC RSP TIMEOUT",
- __rmcLeaderSelectTimerHandler,
- 0 /* param */,
- cfgValue, 0,
- TX_NO_ACTIVATE) != TX_SUCCESS)
- {
- /* Could not create RMC response timer. */
- limLog(pMac, LOGE, FL("could not create RMC response timer"));
- }
-
- pMac->rmcContext.rmcTimerValInTicks = cfgValue;
-}
-
-/**
- * limRmcCleanup()
- *
- *FUNCTION:
- * This function is called to clean up RMC module.
- *
- *LOGIC:
- *
- *ASSUMPTIONS: limRmcIbssDelete should have been called before this.
- *
- *NOTE:
- *
- * @param pMac Pointer to Global MAC structure
- *
- * @return None
- */
-void
-limRmcCleanup(tpAniSirGlobal pMac)
-{
- /* Delete all entries from Leader database. */
- limRmcIbssDelete(pMac);
-
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_destroy(&pMac->rmcContext.lkRmcLock)))
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC lock destroy failed!"));)
- }
-
- tx_timer_delete(&pMac->rmcContext.gRmcLeaderSelectTimer);
-}
-
-/**
- * limRmcTransmitterDelete()
- *
- *FUNCTION:
- * This function is called on a Leader to handle deletion of the transmitter.
- * It is called when the IBSS module wants to delete a peer. If the peer
- * exists in our database, we delete the entries associated with this peer.
- *LOGIC:
- *
- *ASSUMPTIONS:
- *
- *NOTE:
- *
- * @param pMac Pointer to Global MAC structure
- * transmitter Address of the transmitter
- * @return None
- */
-void
-limRmcTransmitterDelete(tpAniSirGlobal pMac, tSirMacAddr transmitter)
-{
- /* Acquire RMC lock */
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE,
- FL("RMC: limRMCTransmitterDelete lock acquire failed"));
- return;
- }
-
- /* Delete this transmitter from Leader database. */
- __rmcGroupDeleteHashEntry(pMac, transmitter);
-
- /* Release RMC lock */
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE,
- FL("RMC: limRMCTransmitterDelete lock release failed"));
- }
-
- limLog(pMac, LOG1, FL("RMC: limRmcTransmitterDelete complete"));
-}
-
-/**
- * limRmcIbssDelete()
- *
- *FUNCTION:
- * This function is called when the IBSS is being deleted for either
- * transmitter or leader STA.
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- *
- *NOTE:
- *
- * @param pMac Pointer to Global MAC structure
- *
- * @return None
- */
-void
-limRmcIbssDelete(tpAniSirGlobal pMac)
-{
- tpPESession psessionEntry;
- tSirMacAddr zeroMacAddr = { 0, 0, 0, 0, 0, 0 };
-
- /*
- * This API relies on a single active IBSS session.
- */
- psessionEntry = limIsIBSSSessionActive(pMac);
- if (NULL == psessionEntry)
- {
- PELOGE(limLog(pMac, LOGE, FL("RMC: limRmcIbssDelete:No active IBSS"));)
- return;
- }
-
- if (VOS_FALSE == vos_mem_compare(&zeroMacAddr,
- &pMac->rmcContext.leader, sizeof(tSirMacAddr)))
- {
- /* send LBP_UPDATE_IND */
- __limPostMsgUpdateInd(pMac, eRMC_LEADER_CANCELLED,
- eRMC_TRANSMITTER_ROLE, psessionEntry->selfMacAddr,
- pMac->rmcContext.leader);
- }
-
- /* Acquire RMC lock */
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE,
- FL("RMC: limRmcIbssDelete lock acquire failed"));
- return;
- }
-
- /* Cancel pending timer */
- tx_timer_deactivate(&pMac->rmcContext.gRmcLeaderSelectTimer);
-
- /* Delete all entries from Leader database. */
- __rmcGroupDeleteAllEntries(pMac);
-
- /* Release RMC lock */
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE,
- FL("RMC: limRmcIbssDelete lock release failed"));
- }
-
- limLog(pMac, LOG1, FL("RMC: limRmcIbssDelete complete"));
-}
-
-/**
- * limRmcDumpStatus()
- *
- *FUNCTION:
- * This function is called to display RMC status for transmitter and leader.
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- *
- *NOTE:
- *
- * @param pMac Pointer to Global MAC structure
- *
- * @return char * Pointer to buffer with RMC information.
- */
-void
-limRmcDumpStatus(tpAniSirGlobal pMac)
-{
- tLimRmcGroupContext *entry;
- int index, count;
-
- /* Acquire RMC lock */
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE,
- FL("RMC: limRmcDumpStatus lock acquire failed"));
- return;
- }
-
-
- limLog(pMac, LOGE, FL(" ----- RMC Transmitter Information ----- \n"));
- limLog(pMac, LOGE,
- FL(" Leader Address | RMC State \n"));
-
- if (pMac->rmcContext.state != eRMC_LEADER_NOT_SELECTED)
- {
- limLog(pMac,LOGE, FL( MAC_ADDRESS_STR " | %s\n"),
- MAC_ADDR_ARRAY(pMac->rmcContext.leader),
- __limMcastTxStateToString(pMac->rmcContext.state));
- }
-
- limLog( pMac,LOGE, FL(" ----- RMC Leader Information ----- \n"));
- limLog( pMac,LOGE, FL(" Transmitter Address\n"));
-
- count = 0;
- for (index = 0; index < RMC_MCAST_GROUPS_HASH_SIZE; index++)
- {
- entry = pMac->rmcContext.rmcGroupRxHashTable[index];
-
- while (entry)
- {
- count++;
- limLog( pMac,LOGE, FL("%d. " MAC_ADDRESS_STR " \n"),
- count, MAC_ADDR_ARRAY(entry->transmitter));
- entry = entry->next;
- }
- }
-
- /* Release RMC lock */
- if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
- {
- limLog(pMac, LOGE,
- FL("RMC: limRmcDumpStatus lock release failed"));
- }
-
- return;
-
-}
-
-/**
- * limRmcTriggerLeaderSelection()
- *
- *FUNCTION:
- * This function is called to RMC leader selection in FW
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- *
- *NOTE:
- *
- * @param pMac Pointer to Global MAC structure
- *
- * @param macAddr Input mac address
- *
- * @return : VOS_STATUS_SUCCESS if RMC state machine allows leader selection and
- leader selection is triggered in FW
- VOS_STATUS_E_FAILURE if RMC state machine does not allow leader
- selection in its current state
- */
-VOS_STATUS
-limRmcTriggerLeaderSelection(tpAniSirGlobal pMac, tSirMacAddr macAddr)
-{
- /*Trigger LBP leader selection in FW*/
- if ((TRUE == pMac->rmcContext.rmcEnabled) &&
- (eRMC_LEADER_NOT_SELECTED == pMac->rmcContext.state))
- {
- limLog(pMac, LOG1,
- FL("Leader selection trigerred in FW"));
-
- __limPostMsgLeaderReq(pMac, eRMC_SUGGEST_LEADER_CMD, macAddr);
-
- pMac->rmcContext.state = eRMC_LEADER_ENABLE_REQUESTED;
-
- return VOS_STATUS_SUCCESS;
- }
- else
- {
- limLog(pMac, LOG1,
- FL("Could not trigger leader selection: RMC state %d rmcEnabled %d"),
- pMac->rmcContext.state, pMac->rmcContext.rmcEnabled);
-
- return VOS_STATUS_E_FAILURE;
- }
-}
-
-#endif /* WLAN_FEATURE_RELIABLE_MCAST */
diff --git a/CORE/MAC/src/pe/lim/limRMC.h b/CORE/MAC/src/pe/lim/limRMC.h
deleted file mode 100644
index ce156cef0916..000000000000
--- a/CORE/MAC/src/pe/lim/limRMC.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2013 Qualcomm Atheros, Inc.
- * All Rights Reserved.
- * Qualcomm Atheros Confidential and Proprietary.
- *
- * Date: 08/15/13
- * History:-
- * Date Modified by Modification Information
- * --------------------------------------------------------------------
- */
-#ifndef __LIM_RMC_H
-#define __LIM_RMC_H
-
-#if defined WLAN_FEATURE_RELIABLE_MCAST
-
-typedef enum {
- eLIM_RMC_ENABLE_REQ = 0,
- eLIM_RMC_DISABLE_REQ = 1,
- eLIM_RMC_BECOME_LEADER_RESP = 2,
- eLIM_RMC_LEADER_SELECT_RESP = 3,
- eLIM_RMC_LEADER_PICK_NEW = 4,
- eLIM_RMC_OTA_LEADER_INFORM_CANCELLED = 5,
- eLIM_RMC_OTA_LEADER_INFORM_ACK = 6,
- eLIM_RMC_OTA_LEADER_INFORM_SELECTED = 7,
-} eRmcMessageType;
-
-typedef enum {
- eRMC_LEADER_NOT_SELECTED = 0,
- eRMC_LEADER_ENABLE_REQUESTED = 1,
- eRMC_LEADER_OTA_REQUEST_SENT = 2,
- eRMC_LEADER_ACTIVE = 3,
-} eRmcMcastTxState;
-
-typedef enum {
- eRMC_IS_NOT_A_LEADER = 0,
- eRMC_LEADER_PENDING = 1,
- eRMC_IS_A_LEADER = 2,
-} eRmcLeaderState;
-
-enum {
- eRMC_SUGGEST_LEADER_CMD = 0,
- eRMC_BECOME_LEADER_CMD = 1,
-};
-
-/* tLbpUpdateIndType */
-enum {
- eRMC_LEADER_ACCEPTED = 0, //Host-->FW
- eRMC_LEADER_CANCELLED = 1, //Host-->FW
- eRMC_LEADER_PICK_NEW = 2, //FW-->Host
-};
-
-/* tLbpRoleType; */
-typedef enum
-{
- eRMC_LEADER_ROLE,
- eRMC_TRANSMITTER_ROLE,
-} eRmcRole;
-
-#define RMC_MCAST_GROUPS_HASH_SIZE 32
-
-typedef struct sLimRmcGroupContext
-{
- tSirMacAddr transmitter;
- eRmcLeaderState isLeader;
- struct sLimRmcGroupContext *next;
-} tLimRmcGroupContext, *tpLimRmcGroupContext;
-
-typedef struct sLimRmcContext
-{
- tANI_BOOLEAN rmcEnabled;
- tSirMacAddr leader;
- eRmcMcastTxState state;
- TX_TIMER gRmcLeaderSelectTimer;
- tANI_U32 rmcTimerValInTicks;
- vos_lock_t lkRmcLock;
- tLimRmcGroupContext *rmcGroupRxHashTable[RMC_MCAST_GROUPS_HASH_SIZE];
-} tLimRmcContext, *tpLimRmcContext;
-
-
-void limRmcInit(tpAniSirGlobal pMac);
-void limRmcCleanup(tpAniSirGlobal pMac);
-void limRmcTransmitterDelete(tpAniSirGlobal pMac, tSirMacAddr transmitter);
-void limRmcIbssDelete(tpAniSirGlobal pMac);
-void limRmcDumpStatus(tpAniSirGlobal pMac);
-
-/**
- * limRmcTriggerLeaderSelection()
- *
- *FUNCTION:
- * This function is called to RMC leader selection in FW
- *
- *LOGIC:
- *
- *ASSUMPTIONS:
- *
- *NOTE:
- *
- * @param pMac Pointer to Global MAC structure
- *
- * @param macAddr Input MAC addres
- *
- * @return : VOS_STATUS_SUCCESS if RMC state machine allows leader selection and
- leader selection is triggered in FW
- VOS_STATUS_E_FAILURE if RMC state machine does not allow leader
- selection in its current state
- */
-VOS_STATUS
-limRmcTriggerLeaderSelection(tpAniSirGlobal pMac, tSirMacAddr macAddr);
-
-
-#endif /* WLAN_FEATURE_RELIABLE_MCAST */
-
-#endif /* __LIM_RMC_H */
diff --git a/CORE/MAC/src/pe/lim/limSendMessages.c b/CORE/MAC/src/pe/lim/limSendMessages.c
index 9b54b09b4e3a..5a946d24fd63 100644
--- a/CORE/MAC/src/pe/lim/limSendMessages.c
+++ b/CORE/MAC/src/pe/lim/limSendMessages.c
@@ -255,6 +255,12 @@ tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac,
#endif
vos_mem_copy( pChnlParams->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr) );
pChnlParams->peSessionId = peSessionId;
+
+ /*Set DFS flag for DFS channel*/
+ if (vos_nv_getChannelEnabledState(chnlNumber) == NV_CHANNEL_DFS)
+ pChnlParams->isDfsChannel= VOS_TRUE;
+ else
+ pChnlParams->isDfsChannel = VOS_FALSE;
//we need to defer the message until we get the response back from WDA.
SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
diff --git a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
index d849d8a1ed41..960917d8aec9 100644
--- a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
+++ b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
@@ -2916,6 +2916,7 @@ void limSendSmeMaxAssocExceededNtf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
return;
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+
/** -----------------------------------------------------------------
\brief limSendSmeCandidateFoundInd() - sends
eWNI_SME_CANDIDATE_FOUND_IND
@@ -2957,3 +2958,174 @@ limSendSmeCandidateFoundInd(tpAniSirGlobal pMac, tANI_U8 sessionId)
} /*** end limSendSmeCandidateFoundInd() ***/
#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+
+/** -----------------------------------------------------------------
+ \brief limSendSmeDfsEventNotify() - sends
+ eWNI_SME_DFS_RADAR_FOUND
+ After receiving WMI_PHYERR_EVENTID indication frame from FW, this
+ function sends a eWNI_SME_DFS_RADAR_FOUND to SME to notify
+ that a RADAR is found on current operating channel and SAP-
+ has to move to a new channel.
+ \param pMac - global mac structure
+ \param msgType - message type received from lower layer
+ \param event - event data received from lower layer
+ \return none
+ \sa
+----------------------------------------------------------------- */
+void
+limSendSmeDfsEventNotify(tpAniSirGlobal pMac, tANI_U16 msgType, void *event)
+{
+ tSirMsgQ mmhMsg;
+ mmhMsg.type = eWNI_SME_DFS_RADAR_FOUND;
+ mmhMsg.bodyptr = event;
+ mmhMsg.bodyval = 0;
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+ return;
+}
+
+
+/*--------------------------------------------------------------------------
+ \brief limSendDfsChanSwIEUpdate()
+ This timer handler updates the channel switch IE in beacon template
+
+ \param pMac - pointer to global adapter context
+ \return - channel to scan from valid session else zero.
+ \sa
+ --------------------------------------------------------------------------*/
+static void
+limSendDfsChanSwIEUpdate(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ limLog(pMac, LOG1, FL("DFS Channel Switch update timer expired"));
+
+ /* Update the beacon template and send to FW */
+ if (schSetFixedBeaconFields(pMac, psessionEntry) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to set CSA IE in beacon"));)
+ return;
+ }
+
+ /* Send update beacon template message */
+ limSendBeaconInd(pMac, psessionEntry);
+
+ return;
+}
+
+
+/** -----------------------------------------------------------------
+ \brief limSendSmeAPChannelSwitchResp() - sends
+ eWNI_SME_CHANNEL_CHANGE_RSP
+ After receiving WDA_SWITCH_CHANNEL_RSP indication this
+ function sends a eWNI_SME_CHANNEL_CHANGE_RSP to SME to notify
+ that the Channel change has been done to the specified target
+ channel in the Channel change request
+ \param pMac - global mac structure
+ \param psessionEntry - session info
+ \param pChnlParams - Channel switch params
+--------------------------------------------------------------------*/
+void
+limSendSmeAPChannelSwitchResp(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tpSwitchChannelParams pChnlParams)
+{
+ tSirMsgQ mmhMsg;
+ tpSwitchChannelParams pSmeSwithChnlParams;
+
+ pSmeSwithChnlParams = (tSwitchChannelParams *)
+ vos_mem_malloc(sizeof(tSwitchChannelParams));
+ if (NULL == pSmeSwithChnlParams)
+ {
+ limLog(pMac, LOGP,
+ FL("AllocateMemory failed for pSmeSwithChnlParams\n"));
+ return;
+ }
+
+ vos_mem_set((v_VOID_t*)pSmeSwithChnlParams,
+ sizeof(tSwitchChannelParams), 0);
+
+ vos_mem_copy(pSmeSwithChnlParams, pChnlParams,
+ sizeof(tSwitchChannelParams));
+
+ mmhMsg.type = eWNI_SME_CHANNEL_CHANGE_RSP;
+ mmhMsg.bodyptr = (void *)pSmeSwithChnlParams;
+ mmhMsg.bodyval = 0;
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+
+ return;
+}
+
+/** -----------------------------------------------------------------
+ \brief limProcessBeaconTxSuccessInd() - This function is used
+ explicitely to handle successful beacon transmission indication
+ from the FW. This is a generic event generated by the FW afer the
+ first beacon is sent out after the beacon template update by the
+ host
+ \param pMac - global mac structure
+ \param psessionEntry - session info
+ \return none
+ \sa
+----------------------------------------------------------------- */
+void
+limProcessBeaconTxSuccessInd(tpAniSirGlobal pMac, tANI_U16 msgType, void *event)
+{
+ /* Currently, this event is used only for DFS channel switch announcement
+ * IE update in the template. If required to be used for other IE updates
+ * add appropriate code by introducing a state variable
+ */
+ tpPESession psessionEntry;
+ tSirMsgQ mmhMsg;
+ tSirSmeCSAIeTxCompleteRsp *pChanSwTxResponse;
+ tANI_U8 length = sizeof(tSirSmeCSAIeTxCompleteRsp);
+ tpSirFirstBeaconTxCompleteInd pBcnTxInd =
+ (tSirFirstBeaconTxCompleteInd *)event;
+
+ if((psessionEntry =
+ peFindSessionByBssIdx(pMac, pBcnTxInd->bssIdx))== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID"));
+ return;
+ }
+
+ if (eLIM_AP_ROLE == psessionEntry->limSystemRole &&
+ VOS_TRUE == psessionEntry->dfsIncludeChanSwIe)
+ {
+ /* Start a timer to send next CSA IE update */
+ if (--psessionEntry->gLimChannelSwitch.switchCount >= 0)
+ {
+ /* Start a timer of timeout less than 100ms, to give enough
+ * time for template update and transmission
+ */
+ limSendDfsChanSwIEUpdate(pMac, psessionEntry);
+ }
+ else
+ {
+ /* Done with CSA IE update, send response back to SME */
+ psessionEntry->gLimChannelSwitch.switchCount = 0;
+ psessionEntry->dfsIncludeChanSwIe = VOS_FALSE;
+
+ /* Reset CSA IE parameters in beacon/probe responses */
+ limSendDfsChanSwIEUpdate(pMac, psessionEntry);
+
+ pChanSwTxResponse = (tSirSmeCSAIeTxCompleteRsp *)
+ vos_mem_malloc(length);
+
+ if (NULL == pChanSwTxResponse)
+ {
+ limLog(pMac, LOGP,
+ FL("AllocateMemory failed for tSirSmeCSAIeTxCompleteRsp"));
+ return;
+ }
+
+ vos_mem_set((void*)pChanSwTxResponse, length, 0);
+ pChanSwTxResponse->sessionId = psessionEntry->smeSessionId;
+ pChanSwTxResponse->chanSwIeTxStatus = VOS_STATUS_SUCCESS;
+
+ mmhMsg.type = eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND;
+ mmhMsg.bodyptr = pChanSwTxResponse;
+ mmhMsg.bodyval = 0;
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+ }
+ }
+
+ return;
+}
+
diff --git a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h
index 6e2602aa4598..958e28fb34f5 100644
--- a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h
+++ b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h
@@ -123,5 +123,14 @@ void limSendSmeTdlsEventNotify(tpAniSirGlobal pMac, tANI_U16 msgType,
#endif
#endif
+void limSendSmeDfsEventNotify(tpAniSirGlobal pMac, tANI_U16 msgType,
+ void *event);
+void limSendSmeAPChannelSwitchResp(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tpSwitchChannelParams pChnlParams);
+void
+limProcessBeaconTxSuccessInd(tpAniSirGlobal pMac, tANI_U16 msgType,
+ void *event);
+
#endif /* __LIM_SEND_SME_RSP_H */
diff --git a/CORE/MAC/src/pe/lim/limTypes.h b/CORE/MAC/src/pe/lim/limTypes.h
index bbe0c71e0d1f..bb7e1d1c8cf9 100644
--- a/CORE/MAC/src/pe/lim/limTypes.h
+++ b/CORE/MAC/src/pe/lim/limTypes.h
@@ -161,6 +161,7 @@ enum eChannelChangeReasonCodes
LIM_SWITCH_CHANNEL_REASSOC,
LIM_SWITCH_CHANNEL_JOIN,
LIM_SWITCH_CHANNEL_OPERATION, // Generic change channel
+ LIM_SWITCH_CHANNEL_SAP_DFS, // DFS channel change
};
typedef struct sLimAuthRspTimeout
diff --git a/CORE/MAC/src/pe/sch/schBeaconGen.c b/CORE/MAC/src/pe/sch/schBeaconGen.c
index 50fa74e776c4..f015d7f39b80 100644
--- a/CORE/MAC/src/pe/sch/schBeaconGen.c
+++ b/CORE/MAC/src/pe/sch/schBeaconGen.c
@@ -64,7 +64,7 @@ const tANI_U8 P2pOui[] = {0x50, 0x6F, 0x9A, 0x9};
tSirRetStatus schGetP2pIeOffset(tANI_U8 *pExtraIe, tANI_U32 extraIeLen, tANI_U16 *pP2pIeOffset)
{
- tSirRetStatus status = eSIR_FAILURE;
+ tSirRetStatus status = eSIR_FAILURE;
*pP2pIeOffset = 0;
// Extra IE is not present
@@ -87,7 +87,7 @@ tSirRetStatus schGetP2pIeOffset(tANI_U8 *pExtraIe, tANI_U32 extraIeLen, tANI_U16
(*pP2pIeOffset)++;
pExtraIe++;
- }while(--extraIeLen > 0);
+ }while(--extraIeLen > 0);
return status;
}
@@ -99,7 +99,7 @@ tSirRetStatus schAppendAddnIE(tpAniSirGlobal pMac, tpPESession psessionEntry,
tSirRetStatus status = eSIR_FAILURE;
tANI_U32 present, len;
tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN];
-
+
if((status = wlan_cfgGetInt(pMac, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
&present)) != eSIR_SUCCESS)
{
@@ -117,10 +117,10 @@ tSirRetStatus schAppendAddnIE(tpAniSirGlobal pMac, tpPESession psessionEntry,
return status;
}
- if(len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
+ if(len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
((len + *nBytes) <= maxBeaconSize))
{
- if((status = wlan_cfgGetStr(pMac,
+ if((status = wlan_cfgGetStr(pMac,
WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0], &len))
== eSIR_SUCCESS)
{
@@ -230,7 +230,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn
for (i=0; i<6; i++)
mac->da[i] = 0xff;
-
+
/* Knocking out Global pMac update */
/* limGetMyMacAddr(pMac, mac->sa); */
/* limGetBssid(pMac, mac->bssId); */
@@ -271,7 +271,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn
offset = sizeof( tAniBeaconStruct );
ptr = pMac->sch.schObject.gSchBeaconFrameBegin + offset;
- if((psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ if((psessionEntry->limSystemRole == eLIM_AP_ROLE)
&& (psessionEntry->proxyProbeRspEn))
{
/* Initialize the default IE bitmap to zero */
@@ -312,7 +312,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn
* Initialize the 'new' fields at the end of the beacon
*/
-
+
PopulateDot11fCountry( pMac, &pBcn2->Country, psessionEntry);
if(pBcn1->Capabilities.qos)
{
@@ -323,6 +323,33 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn
{
PopulateDot11fPowerConstraints( pMac, &pBcn2->PowerConstraints );
PopulateDot11fTPCReport( pMac, &pBcn2->TPCReport, psessionEntry);
+
+ /* Need to insert channel switch announcement here */
+ if ((psessionEntry->limSystemRole == eLIM_AP_ROLE ||
+ psessionEntry->limSystemRole == eLIM_P2P_DEVICE_GO) &&
+ psessionEntry->dfsIncludeChanSwIe == VOS_TRUE)
+ {
+ /* Channel switch announcement only if radar is detected
+ * and SAP has instructed to announce channel switch IEs
+ * in beacon and probe responses
+ */
+ PopulateDot11fChanSwitchAnn(pMac, &pBcn2->ChanSwitchAnn,
+ psessionEntry);
+
+ /* TODO: depending the CB mode, extended channel switch announcement
+ * need to be called
+ */
+ /*PopulateDot11fExtChanSwitchAnn(pMac, &pBcn2->ExtChanSwitchAnn,
+ psessionEntry);*/
+#ifdef WLAN_FEATURE_11AC
+ /* TODO: If in 11AC mode, wider bw channel switch announcement needs
+ * to be called
+ */
+ /*PopulateDot11fWiderBWChanSwitchAnn(pMac, &pBcn2->WiderBWChanSwitchAnn,
+ psessionEntry);*/
+#endif
+
+ }
}
@@ -336,7 +363,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn
}
#ifdef WLAN_FEATURE_11AC
if(psessionEntry->vhtCapability)
- {
+ {
schLog( pMac, LOGW, FL("Populate VHT IEs in Beacon"));
PopulateDot11fVHTCaps( pMac, psessionEntry, &pBcn2->VHTCaps );
PopulateDot11fVHTOperation( pMac, &pBcn2->VHTOperation);
@@ -350,7 +377,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn
PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
&pBcn2->ExtSuppRates, psessionEntry );
-
+
if( psessionEntry->pLimStartBssReq != NULL )
{
PopulateDot11fWPA( pMac, &psessionEntry->pLimStartBssReq->rsnIE,
@@ -367,7 +394,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn
{
if(psessionEntry->wps_state != SAP_WPS_DISABLED)
{
- PopulateDot11fBeaconWPSIEs( pMac, &pBcn2->WscBeacon, psessionEntry);
+ PopulateDot11fBeaconWPSIEs( pMac, &pBcn2->WscBeacon, psessionEntry);
}
}
else
@@ -395,7 +422,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn
}
}
- if((psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ if((psessionEntry->limSystemRole == eLIM_AP_ROLE)
&& (psessionEntry->proxyProbeRspEn))
{
/* Can be efficiently updated whenever new IE added in Probe response in future */
@@ -447,7 +474,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn
extraIeOffset = nBytes;
//TODO: Append additional IE here.
- schAppendAddnIE(pMac, psessionEntry,
+ schAppendAddnIE(pMac, psessionEntry,
pMac->sch.schObject.gSchBeaconFrameEnd + nBytes,
SCH_MAX_BEACON_SIZE, &nBytes);
@@ -461,7 +488,7 @@ tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEn
if(eSIR_SUCCESS == status)
{
//Update the P2P Ie Offset
- pMac->sch.schObject.p2pIeOffset =
+ pMac->sch.schObject.p2pIeOffset =
pMac->sch.schObject.gSchBeaconOffsetBegin + TIM_IE_SIZE +
extraIeOffset + p2pIeOffset;
}
@@ -696,7 +723,7 @@ void writeBeaconToMemory(tpAniSirGlobal pMac, tANI_U16 size, tANI_U16 length, tp
for (i=0; i < pMac->sch.schObject.gSchBeaconOffsetEnd; i++)
pMac->sch.schObject.gSchBeaconFrameBegin[size++] = pMac->sch.schObject.gSchBeaconFrameEnd[i];
}
-
+
// Update the beacon length
pBeacon = (tpAniBeaconStruct) pMac->sch.schObject.gSchBeaconFrameBegin;
// Do not include the beaconLength indicator itself
@@ -765,8 +792,8 @@ schProcessPreBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
{
PELOGE(schLog(pMac, LOGE, FL("session lookup fails"));)
goto end;
- }
-
+ }
+
// If SME is not in normal mode, no need to generate beacon
diff --git a/CORE/SAP/inc/sapApi.h b/CORE/SAP/inc/sapApi.h
index 13db475cebdd..ccbbcabcf157 100644
--- a/CORE/SAP/inc/sapApi.h
+++ b/CORE/SAP/inc/sapApi.h
@@ -192,6 +192,7 @@ typedef enum {
eSAP_MAC_TRIG_STOP_BSS_EVENT,
eSAP_UNKNOWN_STA_JOIN, /* Event send when a STA in neither white list or black list tries to associate in softap mode */
eSAP_MAX_ASSOC_EXCEEDED, /* Event send when a new STA is rejected association since softAP max assoc limit has reached */
+ eSAP_CHANNEL_CHANGE_EVENT,
} eSapHddEvent;
typedef enum {
@@ -363,9 +364,11 @@ typedef struct sap_MaxAssocExceededEvent_s {
v_MACADDR_t macaddr;
} tSap_MaxAssocExceededEvent;
-
-/*
- This struct will be filled in and passed to tpWLAN_SAPEventCB that is provided during WLANSAP_StartBss call
+typedef struct sap_OperatingChannelChangeEvent_s {
+ tANI_U8 operatingChannel;
+} tSap_OperatingChannelChangeEvent;
+/*
+ This struct will be filled in and passed to tpWLAN_SAPEventCB that is provided during WLANSAP_StartBss call
The event id corresponding to structure in the union is defined in comment next to the structure
*/
@@ -387,6 +390,7 @@ typedef struct sap_Event_s {
tSap_SendActionCnf sapActionCnf; /* eSAP_SEND_ACTION_CNF */
tSap_UnknownSTAJoinEvent sapUnknownSTAJoin; /* eSAP_UNKNOWN_STA_JOIN */
tSap_MaxAssocExceededEvent sapMaxAssocExceeded; /* eSAP_MAX_ASSOC_EXCEEDED */
+ tSap_OperatingChannelChangeEvent sapChannelChange; /* eSAP_CHANNEL_CHANGE_EVENT */
} sapevt;
} tSap_Event, *tpSap_Event;
@@ -437,7 +441,7 @@ typedef struct sap_Config {
v_U32_t ap_table_expiration_time;
v_U32_t ht_op_mode_fixed;
tVOS_CON_MODE persona; /*Tells us which persona it is GO or AP for now*/
-
+ v_U8_t disableDFSChSwitch;
} tsap_Config_t;
typedef enum {
@@ -565,6 +569,7 @@ typedef struct sap_SoftapStats_s {
int sapSetPreferredChannel(tANI_U8* ptr);
void sapCleanupChannelList(void);
+void sapCleanupAllChannelList(void);
/*==========================================================================
FUNCTION WLANSAP_Set_WpsIe
@@ -1536,6 +1541,89 @@ VOS_STATUS WLANSAP_RegisterMgmtFrame( v_PVOID_t pvosGCtx, tANI_U16 frameType,
VOS_STATUS WLANSAP_DeRegisterMgmtFrame( v_PVOID_t pvosGCtx, tANI_U16 frameType,
tANI_U8* matchData, tANI_U16 matchLen );
+/*==========================================================================
+
+ FUNCTION WLANSAP_ChannelChangeRequest
+ DESCRIPTION
+ This API is used to send an Indication to SME/PE to change the
+ current operating channel to a different target channel.
+
+ The Channel change will be issued by SAP under the following
+ scenarios.
+ 1. A radar indication is received during SAP CAC WAIT STATE and
+ channel change is required.
+ 2. A radar indication is received during SAP STARTED STATE and
+ channel change is required.
+
+ DEPENDENCIES
+ NA.
+
+PARAMETERS
+
+IN
+ pvosGCtx: Pointer to vos global context structure
+ TargetChannel: New target channel for channel change.
+
+RETURN VALUE
+ The VOS_STATUS code associated with performing the operation
+
+VOS_STATUS_SUCCESS: Success
+
+SIDE EFFECTS
+============================================================================*/
+VOS_STATUS WLANSAP_ChannelChangeRequest(v_PVOID_t pvosGCtx, tANI_U8 tArgetChannel);
+
+/*==========================================================================
+
+ FUNCTION WLANSAP_StartBeaconReq
+ DESCRIPTION
+ This API is used to send an Indication to SME/PE to start
+ beaconing on the current operating channel.
+
+ Brief:When SAP is started on DFS channel and when ADD BSS RESP is received
+ LIM temporarily holds off Beaconing for SAP to do CAC WAIT. When
+ CAC WAIT is done SAP resumes the Beacon Tx by sending a start beacon
+ request to LIM.
+
+ DEPENDENCIES
+ NA.
+
+PARAMETERS
+
+IN
+ pvosGCtx: Pointer to vos global context structure
+
+RETURN VALUE
+ The VOS_STATUS code associated with performing the operation
+
+VOS_STATUS_SUCCESS: Success
+
+SIDE EFFECTS
+============================================================================*/
+VOS_STATUS WLANSAP_StartBeaconReq(v_PVOID_t pSapCtx);
+
+/*==========================================================================
+ FUNCTION WLANSAP_DfsSendCSAIeRequest
+
+ DESCRIPTION
+ This API is used to send channel switch announcement request to PE
+ DEPENDENCIES
+ NA.
+
+ PARAMETERS
+ IN
+ sapContext: Pointer to vos global context structure
+
+ RETURN VALUE
+ The VOS_STATUS code associated with performing the operation
+
+ VOS_STATUS_SUCCESS: Success
+
+ SIDE EFFECTS
+============================================================================*/
+VOS_STATUS
+WLANSAP_DfsSendCSAIeRequest(v_PVOID_t pSapCtx);
+
#ifdef __cplusplus
}
diff --git a/CORE/SAP/src/sapApiLinkCntl.c b/CORE/SAP/src/sapApiLinkCntl.c
index 2a87dbd22d69..7b4a18a91f62 100644
--- a/CORE/SAP/src/sapApiLinkCntl.c
+++ b/CORE/SAP/src/sapApiLinkCntl.c
@@ -409,7 +409,24 @@ WLANSAP_RoamCallback
(v_PVOID_t) eSAP_STATUS_SUCCESS );
break;
- default:
+ case eCSR_ROAM_DFS_RADAR_IND:
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
+ "In %s, Received Radar Indication", __func__);
+ sapContext->SapDfsInfo.target_channel =
+ sapIndicateRadar(sapContext, &pCsrRoamInfo->dfs_event);
+ break;
+
+ case eCSR_ROAM_DFS_CHAN_SW_NOTIFY:
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
+ "In %s, Received Chan Sw Update Notification", __func__);
+ break;
+
+ case eCSR_ROAM_SET_CHANNEL_RSP:
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
+ "In %s, Received set channel response", __func__);
+ break;
+
+ default:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, CSR roamStatus not handled roamStatus = %s (%d)\n",
__func__, get_eRoamCmdStatus_str(roamStatus), roamStatus);
break;
@@ -559,13 +576,16 @@ WLANSAP_RoamCallback
case eCSR_ROAM_RESULT_INFRA_STARTED:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)\n",
__func__, "eCSR_ROAM_RESULT_INFRA_STARTED", roamResult);
- /* Fill in the event structure */
+
+ /* In the current implementation, hostapd is not aware that
+ * drive will support DFS. Hence, driver should inform
+ * eSAP_MAC_START_BSS_SUCCESS to upper layers and then perform
+ * CAC underneath
+ */
sapEvent.event = eSAP_MAC_START_BSS_SUCCESS;
sapEvent.params = pCsrRoamInfo;
sapEvent.u1 = roamStatus;
sapEvent.u2 = roamResult;
-
- /* Handle event */
vosStatus = sapFsm(sapContext, &sapEvent);
if(!VOS_IS_STATUS_SUCCESS(vosStatus))
{
@@ -636,6 +656,193 @@ WLANSAP_RoamCallback
}
break;
+
+ case eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND:
+ if (eSAP_DFS_CAC_WAIT == sapContext->sapsMachine)
+ {
+ if (VOS_TRUE == sapContext->SapDfsInfo.sap_radar_found_status)
+ {
+ /*
+ * If Radar is found, while in DFS CAC WAIT State then
+ * post stop and destroy the CAC timer and post a
+ * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND to sapFsm.
+ */
+ vos_timer_stop(&sapContext->SapDfsInfo.sap_dfs_cac_timer);
+ vos_timer_destroy(&sapContext->SapDfsInfo.sap_dfs_cac_timer);
+ sapContext->SapDfsInfo.is_dfs_cac_timer_running = 0;
+
+ sapEvent.event = eSAP_DFS_CHANNEL_CAC_RADAR_FOUND;
+ sapEvent.params = 0;
+ sapEvent.u1 = 0;
+ sapEvent.u2 = 0;
+ vosStatus = sapFsm(sapContext, &sapEvent);
+ if(!VOS_IS_STATUS_SUCCESS(vosStatus))
+ {
+ halStatus = eHAL_STATUS_FAILURE;
+ }
+ }
+ }
+ else if(eSAP_STARTED == sapContext->sapsMachine)
+ {
+ /* Radar found on the operating channel in STARTED state,
+ * new operating channel has already been selected. Send
+ * request to SME-->PE for sending CSA IE
+ */
+ sapEvent.event = eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START;
+ sapEvent.params = 0;
+ sapEvent.u1 = 0;
+ sapEvent.u2 = 0;
+ vosStatus = sapFsm(sapContext, &sapEvent);
+ if(!VOS_IS_STATUS_SUCCESS(vosStatus))
+ {
+ halStatus = eHAL_STATUS_FAILURE;
+ }
+ }
+ else
+ {
+ /* Further actions to be taken here */
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN,
+ "In %s, eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND received in"
+ "(%d) state\n", __func__, sapContext->sapsMachine);
+ }
+ break;
+
+ case eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS:
+ case eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_FAILURE:
+ {
+ eCsrPhyMode phyMode =
+ sapConvertSapPhyModeToCsrPhyMode(sapContext->csrRoamProfile.phyMode);
+ tHalHandle hHal =
+ (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, sapContext->pvosGCtx);
+
+ /* Both success and failure cases are handled intentionally handled
+ * together. Irrespective of whether the channel switch IE was
+ * sent out successfully or not, SAP should still vacate the
+ * channel immediately
+ */
+ if (eSAP_STARTED == sapContext->sapsMachine)
+ {
+ VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
+ "In %s, from state %s => %s",
+ __func__, "eSAP_STARTED", "eSAP_DISCONNECTING");
+
+ /* SAP to be moved to DISCONNECTING state */
+ sapContext->sapsMachine = eSAP_DISCONNECTING;
+
+ /* The associated stations have been informed to move
+ * to a different channel. However, the AP may not always
+ * select the advertised channel for operation if the radar
+ * is seen. In that case, the stations will experience link-loss
+ * and return back through scanning if they wish to
+ */
+
+ /* Send channel change request
+ * From spec it is required that the AP should continue to
+ * operate in the same mode as it is operating currently.
+ * For e.g. 20/40/80 MHz operation
+ */
+ if (sapContext->SapDfsInfo.target_channel)
+ {
+ sme_SelectCBMode(hHal, phyMode,
+ sapContext->SapDfsInfo.target_channel);
+ }
+
+ /* Send channel switch request */
+ sapEvent.event = eWNI_SME_CHANNEL_CHANGE_REQ;
+ sapEvent.params = 0;
+ sapEvent.u1 = 0;
+ sapEvent.u2 = 0;
+
+ /* Handle event */
+ vosStatus = sapFsm(sapContext, &sapEvent);
+ if(!VOS_IS_STATUS_SUCCESS(vosStatus))
+ {
+ halStatus = eHAL_STATUS_FAILURE;
+ }
+ }
+ else
+ {
+ /* Further actions to be taken here */
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN,
+ "In %s, eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND received in"
+ "(%d) state\n", __func__, sapContext->sapsMachine);
+ }
+ break;
+ }
+ case eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS:
+ {
+ /* Channel change is successful. If the new channel is a DFS
+ * channel, then we will to perform channel availability check
+ * for 60 seconds
+ */
+ sapContext->channel =
+ sapContext->SapDfsInfo.target_channel;
+
+ /* Identify if this is channel change in radar detected state */
+ if (VOS_TRUE == sapContext->SapDfsInfo.sap_radar_found_status &&
+ eSAP_DISCONNECTING == sapContext->sapsMachine)
+ {
+ /* check if currently selected channel is a DFS channel */
+ if (NV_CHANNEL_DFS ==
+ vos_nv_getChannelEnabledState(sapContext->channel))
+ {
+ sapContext->sapsMachine = eSAP_DISCONNECTED;
+
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
+ "In %s, from state %s => %s", __func__,
+ "eSAP_DISCONNECTING", "DISCONNECTED");
+
+ /* DFS Channel */
+ sapEvent.event = eSAP_DFS_CHANNEL_CAC_START;
+ sapEvent.params = pCsrRoamInfo;
+ sapEvent.u1 = 0;
+ sapEvent.u2 = 0;
+ }
+ else
+ {
+ /* non-DFS channel */
+ sapContext->sapsMachine = eSAP_STARTING;
+
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
+ "In %s, from state %s => %s", __func__,
+ "eSAP_DISCONNECTING", "eSAP_STARTING");
+
+ sapContext->SapDfsInfo.sap_radar_found_status = VOS_FALSE;
+ sapEvent.event = eSAP_MAC_START_BSS_SUCCESS;
+ sapEvent.params = pCsrRoamInfo;
+ sapEvent.u1 = eCSR_ROAM_INFRA_IND;
+ sapEvent.u2 = eCSR_ROAM_RESULT_INFRA_STARTED;
+ }
+
+ /* Handle the event */
+ vosStatus = sapFsm(sapContext, &sapEvent);
+ if(!VOS_IS_STATUS_SUCCESS(vosStatus))
+ {
+ halStatus = eHAL_STATUS_FAILURE;
+ }
+
+ }
+ else
+ {
+ /* We may have a requirment in the future for SAP to perform
+ * channel change, hence leaving this here
+ */
+ }
+
+ break;
+ }
+ case eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE:
+ {
+ /* This is much more serious issue, we have to vacate the
+ * channel due to the presence of radar but our channel change
+ * failed, stop the BSS operation completely and inform hostapd
+ */
+ sapContext->sapsMachine = eSAP_DISCONNECTED;
+
+ /* Inform cfg80211 and hostapd that BSS is not alive anymore */
+ }
+ break;
+
default:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, CSR roamResult = %s (%d) not handled\n",
__func__,get_eCsrRoamResult_str(roamResult),roamResult);
diff --git a/CORE/SAP/src/sapFsm.c b/CORE/SAP/src/sapFsm.c
index ddba2f0b2e69..7664e054c79e 100644
--- a/CORE/SAP/src/sapFsm.c
+++ b/CORE/SAP/src/sapFsm.c
@@ -93,6 +93,48 @@
static VOS_STATUS sapGetChannelList(ptSapContext sapContext, v_U8_t **channelList,
v_U8_t *numberOfChannels);
#endif
+
+/*==========================================================================
+ FUNCTION sapGet5GHzChannelList
+
+ DESCRIPTION
+ Function for initializing list of 2.4/5 Ghz [NON-DFS/DFS] available
+ channels in the current regulatory domain.
+
+ DEPENDENCIES
+ NA.
+
+ PARAMETERS
+
+ IN
+ sapContext: SAP Context
+
+ RETURN VALUE
+ NA
+
+ SIDE EFFECTS
+============================================================================*/
+static VOS_STATUS sapGet5GHzChannelList(ptSapContext sapContext);
+
+/*==========================================================================
+ FUNCTION sapStartDfsCacTimer
+
+ DESCRIPTION
+ Function to start the DFS CAC timer when SAP is started on DFS Channel
+ DEPENDENCIES
+ NA.
+
+ PARAMETERS
+
+ IN
+ sapContext: SAP Context
+ RETURN VALUE
+ DFS Timer start status
+ SIDE EFFECTS
+============================================================================*/
+
+int sapStartDfsCacTimer(ptSapContext sapContext);
+
/*----------------------------------------------------------------------------
* Externalized Function Definitions
* -------------------------------------------------------------------------*/
@@ -727,6 +769,14 @@ sapSignalHDDevent
(v_PVOID_t)pCsrRoamInfo->peerMac, sizeof(v_MACADDR_t));
break;
+ case eSAP_CHANNEL_CHANGE_EVENT:
+ VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
+ "In %s, SAP event callback event = %s",
+ __func__, "eSAP_CHANNEL_CHANGE_EVENT");
+ sapApAppEvent.sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT;
+ sapApAppEvent.sapevt.sapChannelChange.operatingChannel =
+ sapContext->SapDfsInfo.target_channel;
+
default:
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, SAP Unknown callback event = %d",
__func__,sapHddevent);
@@ -829,6 +879,18 @@ sapFsm
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s",
__func__, "eSAP_DISCONNECTED", "eSAP_CH_SELECT");
}
+ if (msg == eSAP_DFS_CHANNEL_CAC_START)
+ {
+ /* No need of state check here, caller is expected to perform
+ * the checks before sending the event
+ */
+ sapContext->sapsMachine = eSAP_DFS_CAC_WAIT;
+
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ "ENTERTRED eSAP_DISCONNECTED-->eSAP_DFS_CAC_WAIT\n");
+
+ sapStartDfsCacTimer(sapContext);
+ }
else
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, in state %s, event msg %d",
@@ -881,6 +943,90 @@ sapFsm
}
break;
+ case eSAP_DFS_CAC_WAIT:
+ if (msg == eSAP_DFS_CHANNEL_CAC_START)
+ {
+ VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s",
+ __func__, "eSAP_CH_SELECT", "eSAP_DFS_CAC_WAIT");
+ sapStartDfsCacTimer(sapContext);
+ }
+ else if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND)
+ {
+ /* Radar found while performing channel availability
+ * check, need to switch the channel again
+ */
+ eCsrPhyMode phyMode =
+ sapConvertSapPhyModeToCsrPhyMode(sapContext->csrRoamProfile.phyMode);
+ tHalHandle hHal =
+ (tHalHandle)vos_get_context(VOS_MODULE_ID_SME, sapContext->pvosGCtx);
+
+ /* SAP to be moved to DISCONNECTING state */
+ sapContext->sapsMachine = eSAP_DISCONNECTING;
+
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ "ENTERTRED CAC WAIT STATE-->eSAP_DISCONNECTING\n");
+
+ if (sapContext->SapDfsInfo.target_channel)
+ {
+ sme_SelectCBMode(hHal, phyMode,
+ sapContext->SapDfsInfo.target_channel);
+ }
+
+ /*
+ * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND:
+ * A Radar is found on current DFS Channel
+ * while in CAC WAIT period So, do a channel switch
+ * to randomly selected target channel.
+ * Send the Channel change message to SME/PE.
+ * sap_radar_found_status is set to 1
+ */
+
+ WLANSAP_ChannelChangeRequest((v_PVOID_t)sapContext,
+ sapContext->SapDfsInfo.target_channel);
+ }
+ else if (msg == eSAP_DFS_CHANNEL_CAC_END)
+ {
+ /*
+ * eSAP_DFS_CHANNEL_CAC_END:
+ * CAC Period elapsed and there was no radar
+ * found so, SAP can continue beaconing.
+ * sap_radar_found_status is set to 0
+ */
+ sapContext->SapDfsInfo.sap_radar_found_status = VOS_FALSE;
+
+ /* Start beaconing on the new channel */
+ WLANSAP_StartBeaconReq((v_PVOID_t)sapContext);
+
+ /* Transition from eSAP_STARTING to eSAP_STARTED
+ * (both without substates)
+ */
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
+ "In %s, from state channel = %d %s => %s",
+ __func__,sapContext->channel, "eSAP_STARTING",
+ "eSAP_STARTED");
+
+ sapContext->sapsMachine = eSAP_STARTED;
+
+ /*Action code for transition */
+ vosStatus = sapSignalHDDevent(sapContext, roamInfo,
+ eSAP_START_BSS_EVENT,
+ (v_PVOID_t)eSAP_STATUS_SUCCESS);
+
+ /* Transition from eSAP_STARTING to eSAP_STARTED
+ * (both without substates)
+ */
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
+ "In %s, from state %s => %s",
+ __func__, "eSAP_DFS_CAC_WAIT", "eSAP_STARTED");
+ }
+ else
+ {
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
+ "In %s, in state %s, invalid event msg %d",
+ __func__, "eSAP_DFS_CAC_WAIT", msg);
+ }
+ break;
+
case eSAP_STARTING:
if (msg == eSAP_MAC_START_BSS_SUCCESS )
{
@@ -889,12 +1035,30 @@ sapFsm
__func__,sapContext->channel, "eSAP_STARTING", "eSAP_STARTED");
sapContext->sapsMachine = eSAP_STARTED;
+
/*Action code for transition */
vosStatus = sapSignalHDDevent( sapContext, roamInfo, eSAP_START_BSS_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS);
/* Transition from eSAP_STARTING to eSAP_STARTED (both without substates) */
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s",
__func__, "eSAP_STARTING", "eSAP_STARTED");
+
+ /* The upper layers have been informed that AP is up and
+ * running, however, the AP is still not beaconing, until
+ * CAC is done if the operating channel is DFS
+ */
+ if (vos_nv_getChannelEnabledState(sapContext->channel) == NV_CHANNEL_DFS)
+ {
+ /* Move the device in CAC_WAIT_STATE */
+ sapContext->sapsMachine = eSAP_DFS_CAC_WAIT;
+
+ /* TODO: Need to stop the OS transmit queues, so that no traffic
+ * can flow down the stack
+ */
+
+ /* Start CAC wait timer */
+ sapStartDfsCacTimer(sapContext);
+ }
}
else if (msg == eSAP_MAC_START_FAILS)
{
@@ -938,6 +1102,23 @@ sapFsm
}
}
}
+ else if (msg == eSAP_OPERATING_CHANNEL_CHANGED)
+ {
+ /* The operating channel has changed, update hostapd */
+ sapContext->channel =
+ (tANI_U8)sapContext->SapDfsInfo.target_channel;
+
+ sapContext->sapsMachine = eSAP_STARTED;
+
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
+ "In %s, from state %s => %s",
+ __func__, "eSAP_STARTING", "eSAP_STARTED");
+
+ /* Indicate change in the state to upper layers */
+ vosStatus = sapSignalHDDevent(sapContext, roamInfo,
+ eSAP_START_BSS_EVENT,
+ (v_PVOID_t)eSAP_STATUS_SUCCESS);
+ }
else
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
@@ -956,6 +1137,17 @@ sapFsm
sapContext->sapsMachine = eSAP_DISCONNECTING;
vosStatus = sapGotoDisconnecting(sapContext);
}
+ else if (eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START == msg)
+ {
+ /* Radar is seen on the current operating channel
+ * send CSA IE for all associated stations
+ */
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
+ "In %s, Send CSA IE Request", __func__);
+
+ /* Request for CSA IE transmission */
+ WLANSAP_DfsSendCSAIeRequest(sapContext);
+ }
else
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, in state %s, invalid event msg %d",
@@ -997,6 +1189,19 @@ sapFsm
}
}
}
+ else if (msg == eWNI_SME_CHANNEL_CHANGE_REQ)
+ {
+ /* Most likely, radar has been detected and SAP wants to
+ * change the channel
+ */
+ vosStatus =
+ WLANSAP_ChannelChangeRequest((v_PVOID_t)sapContext,
+ sapContext->SapDfsInfo.target_channel);
+
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ "In %s, Sending DFS eWNI_SME_CHANNEL_CHANGE_REQ",
+ __func__);
+ }
else
{
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
@@ -1016,6 +1221,7 @@ sapconvertToCsrProfile(tsap_Config_t *pconfig_params, eCsrRoamBssType bssType, t
profile->BSSType = eCSR_BSS_TYPE_INFRA_AP;
profile->SSIDs.numOfSSIDs = 1;
profile->csrPersona = pconfig_params->persona;
+ profile->disableDFSChSwitch = pconfig_params->disableDFSChSwitch;
vos_mem_zero(profile->SSIDs.SSIDList[0].SSID.ssId,
sizeof(profile->SSIDs.SSIDList[0].SSID.ssId));
@@ -1449,3 +1655,225 @@ static VOS_STATUS sapGetChannelList(ptSapContext sapContext,
return VOS_STATUS_SUCCESS;
}
#endif
+
+/*
+ * Function for initializing list of 2.4/5 Ghz [NON-DFS/DFS]
+ * available channels in the current regulatory domain.
+ */
+static VOS_STATUS sapGet5GHzChannelList(ptSapContext sapContext)
+{
+ v_U8_t count = 0;
+ int i;
+ if (NULL == sapContext)
+ {
+ VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
+ "Invalid sapContext pointer on sapGetChannelList");
+ return VOS_STATUS_E_FAULT;
+ }
+
+ sapContext->SapAllChnlList.channelList =
+ (v_U8_t *)vos_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN);
+ if (NULL == sapContext->SapAllChnlList.channelList)
+ {
+ VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
+ " Memory Allocation failed sapGetChannelList");
+ return VOS_STATUS_E_FAULT;
+ }
+
+ for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ )
+ {
+ if( regChannels[i].enabled == NV_CHANNEL_ENABLE ||
+ regChannels[i].enabled == NV_CHANNEL_DFS )
+ {
+ sapContext->SapAllChnlList.channelList[count] =
+ rfChannels[i].channelNum;
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
+ "%s[%d] CHANNEL = %d",__func__, __LINE__,
+ sapContext->SapAllChnlList.channelList[count]);
+ count++;
+ }
+ }
+
+ sapContext->SapAllChnlList.numChannel = count;
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
+ "%s[%d] NUMBER OF CHANNELS count = %d"
+ "sapContext->SapAllChnlList.numChannel = %d",
+ __func__,__LINE__,count,sapContext->SapAllChnlList.numChannel);
+ return VOS_STATUS_SUCCESS;
+}
+
+/*
+ * This function randomly selects the channel to switch after the detection
+ * of radar
+ * param sapContext - sap context
+ * dfs_event - Dfs information from DFS
+ * return - channel to which AP wishes to switch
+ */
+v_U8_t sapIndicateRadar(ptSapContext sapContext,tSirSmeDfsEventInd *dfs_event)
+{
+ v_U8_t available_chan_idx[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+ int available_chan_count, numGChannels = 0, numAChannels = 0;
+ v_U8_t total_num_channels = 0;
+ v_U8_t target_channel = 0;
+ int i;
+
+ if (NULL == sapContext || NULL == dfs_event)
+ {
+ /* Invalid sap context of dfs event passed */
+ return 0;
+ }
+
+ if (!dfs_event->dfs_radar_status)
+ {
+ /*dfs status does not indicate a radar on the channel-- False Alarm*/
+ return 0;
+ }
+
+ /* set the Radar Found flag in SapDfsInfo */
+ sapContext->SapDfsInfo.sap_radar_found_status = VOS_TRUE;
+
+ /* We need to generate Channel Switch IE if the radar is found in the
+ * operating state
+ */
+ if (eSAP_STARTED == sapContext->sapsMachine)
+ sapContext->SapDfsInfo.csaIERequired = VOS_TRUE;
+
+ if (sapContext->csrRoamProfile.disableDFSChSwitch)
+ {
+ return sapContext->channel;
+ }
+
+ sapGet5GHzChannelList(sapContext);
+ total_num_channels = sapContext->SapAllChnlList.numChannel;
+
+ /*
+ * Find how many G channels are present in the channel list
+ */
+ for(i = 0; i < RF_CHAN_14; i++ )
+ {
+ if( regChannels[i].enabled )
+ {
+ numGChannels++;
+ }
+ }
+ numAChannels = (total_num_channels - numGChannels);
+
+ /*
+ * (1) skip static turbo channel as it will require STA to be in
+ * static turbo to work.
+ * (2) skip channel which's marked with radar detction
+ * (3) WAR: we allow user to config not to use any DFS channel
+ * (4) When we pick a channel, skip excluded 11D channels
+ * (5) Create the available channel list with the above rules
+ */
+
+ for(i = 0, available_chan_count = 0; i<= total_num_channels; i++)
+ {
+ if (sapContext->SapAllChnlList.channelList[i] ==
+ dfs_event->ieee_chan_number)
+ {
+ continue;//skip the channel on which radar is found
+ }
+ available_chan_idx[available_chan_count++] =
+ sapContext->SapAllChnlList.channelList[i];
+ }
+
+ if(available_chan_count)
+ {
+ v_U32_t random_byte = 0;
+
+ /* logic to generate a random index */
+ get_random_bytes(&random_byte,1);
+ i = (random_byte + jiffies) % available_chan_count;
+
+ /*
+ * Pick the channel from the random index
+ * in available_chan_idx list
+ */
+ target_channel = (available_chan_idx[i]);
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,
+ "%s[%d]: Target channel Index = %d target_channel = %d",
+ __func__,__LINE__, i, target_channel);
+ return target_channel;
+ }
+
+ return 0;
+}
+
+/*
+ * CAC timer callback function.
+ * Post eSAP_DFS_CHANNEL_CAC_END event to sapFsm().
+ */
+void sapDfsCacTimerCallback(void *data)
+{
+ ptSapContext sapContext = (ptSapContext)data;
+ tWLAN_SAPEvent sapEvent;
+
+ /* Check to ensure that SAP is in DFS WAIT state*/
+ if (sapContext->sapsMachine == eSAP_DFS_CAC_WAIT)
+ {
+ vos_timer_destroy(&sapContext->SapDfsInfo.sap_dfs_cac_timer);
+ sapContext->SapDfsInfo.is_dfs_cac_timer_running = 0;
+ /*
+ * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sapFsm
+ */
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
+ "%s[%d]: Sending eSAP_DFS_CHANNEL_CAC_END for target_channel = %d",
+ __func__,__LINE__, sapContext->SapDfsInfo.target_channel);
+ sapEvent.event = eSAP_DFS_CHANNEL_CAC_END;
+ sapEvent.params = 0;
+ sapEvent.u1 = 0;
+ sapEvent.u2 = 0;
+ }
+ else if (sapContext->sapsMachine == eSAP_DFS_CAC_WAIT)
+ {
+ vos_timer_destroy(&sapContext->SapDfsInfo.sap_dfs_cac_timer);
+ sapContext->SapDfsInfo.is_dfs_cac_timer_running = 0;
+
+ /*
+ * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sapFsm
+ */
+ sapEvent.event = eSAP_DFS_CHANNEL_CAC_END;
+ sapEvent.params = 0;
+ sapEvent.u1 = 0;
+ sapEvent.u2 = 0;
+ }
+
+ sapFsm(sapContext, &sapEvent);
+}
+
+/*
+ * Function to start the DFS CAC Timer
+ * when SAP is started on a DFS channel
+ */
+int sapStartDfsCacTimer(ptSapContext sapContext)
+{
+ VOS_STATUS status;
+ if (sapContext == NULL)
+ {
+ return 0;
+ }
+ if (sapContext->SapDfsInfo.ignore_cac)
+ {
+ /*
+ * If User has set to ignore the CAC
+ * so, continue without CAC Timer.
+ */
+ return 2;
+ }
+ vos_timer_init(&sapContext->SapDfsInfo.sap_dfs_cac_timer,
+ VOS_TIMER_TYPE_SW,
+ sapDfsCacTimerCallback, (v_PVOID_t)sapContext);
+
+ /*Start the CAC timer for 60 Seconds*/
+ status = vos_timer_start(&sapContext->SapDfsInfo.sap_dfs_cac_timer, 60000);
+ if (status == VOS_STATUS_SUCCESS)
+ {
+ sapContext->SapDfsInfo.is_dfs_cac_timer_running = VOS_TRUE;
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
diff --git a/CORE/SAP/src/sapFsm_ext.h b/CORE/SAP/src/sapFsm_ext.h
index 5535732b235c..315e0e91eea5 100644
--- a/CORE/SAP/src/sapFsm_ext.h
+++ b/CORE/SAP/src/sapFsm_ext.h
@@ -50,6 +50,11 @@ typedef enum
eSAP_MAC_START_FAILS,
eSAP_HDD_STOP_INFRA_BSS,
eSAP_WRITE_REMOTE_AMP_ASSOC,
+ eSAP_DFS_CHANNEL_CAC_START,
+ eSAP_DFS_CHANNEL_CAC_RADAR_FOUND,
+ eSAP_DFS_CHANNEL_CAC_END,
+ eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START,
+ eSAP_OPERATING_CHANNEL_CHANGED,
eSAP_NO_MSG
}eSapMsg_t;
diff --git a/CORE/SAP/src/sapInternal.h b/CORE/SAP/src/sapInternal.h
index aa23a9ba40aa..248614ac45b0 100644
--- a/CORE/SAP/src/sapInternal.h
+++ b/CORE/SAP/src/sapInternal.h
@@ -121,6 +121,7 @@ typedef struct sSapContext tSapContext;
typedef enum {
eSAP_DISCONNECTED,
eSAP_CH_SELECT,
+ eSAP_DFS_CAC_WAIT,
eSAP_STARTING,
eSAP_STARTED,
eSAP_DISCONNECTING
@@ -137,6 +138,25 @@ typedef struct sSapQosCfg {
v_U8_t WmmIsEnabled;
} tSapQosCfg;
+typedef struct sSapDfsInfo {
+ vos_timer_t sap_dfs_cac_timer;
+ v_U8_t sap_radar_found_status;
+ v_U8_t is_dfs_cac_timer_running;
+
+ /*
+ * New channel to move to when a Radar is
+ * detected on current Channel
+ */
+ v_U8_t target_channel;
+ v_U8_t last_radar_found_channel;
+ v_U8_t ignore_cac;
+
+ /* Requests for Channel Switch Announcement IE
+ * generation and transmission
+ */
+ v_U8_t csaIERequired;
+}tSapDfsInfo;
+
typedef struct sSapContext {
vos_lock_t SapGlobalLock;
@@ -208,6 +228,18 @@ typedef struct sSapContext {
// session to scan
tANI_BOOLEAN isScanSessionOpen;
+ /*
+ * This list of channels will hold 5Ghz enabled,DFS in the
+ * Current RegDomain.This list will be used to select a channel,
+ * for SAP to start including any DFS channel and also to select
+ * any random channel[5Ghz-(NON-DFS/DFS)],if SAP is operating
+ * on a DFS channel and a RADAR is detected on the channel.
+ */
+ tSapChannelListInfo SapAllChnlList;
+
+ //Information Required for SAP DFS Master mode
+ tSapDfsInfo SapDfsInfo;
+
} *ptSapContext;
@@ -772,6 +804,23 @@ eCsrPhyMode sapConvertSapPhyModeToCsrPhyMode( eSapPhyMode sapPhyMode );
void sapUpdateUnsafeChannelList(void);
#endif /* FEATURE_WLAN_CH_AVOID */
+/*---------------------------------------------------------------------------
+FUNCTION sapIndicateRadar
+
+DESCRIPTION Function to implement actions on Radar Detection when SAP is on
+ DFS Channel
+
+DEPENDENCIES PARAMETERS
+IN sapContext : Sap Context which hold SapDfsInfo
+ dfs_event : Event from DFS Module
+
+RETURN VALUE : Target Channel For SAP to Move on to when Radar is Detected.
+
+SIDE EFFECTS
+---------------------------------------------------------------------------*/
+v_U8_t
+sapIndicateRadar(ptSapContext sapContext,tSirSmeDfsEventInd *dfs_event);
+
#ifdef __cplusplus
}
#endif
diff --git a/CORE/SAP/src/sapModule.c b/CORE/SAP/src/sapModule.c
index b644747209af..e94f3eb53a54 100644
--- a/CORE/SAP/src/sapModule.c
+++ b/CORE/SAP/src/sapModule.c
@@ -2363,3 +2363,184 @@ VOS_STATUS WLANSAP_DeRegisterMgmtFrame( v_PVOID_t pvosGCtx, tANI_U16 frameType,
return VOS_STATUS_E_FAULT;
}
+
+/*==========================================================================
+ FUNCTION WLANSAP_ChannelChangeRequest
+
+ DESCRIPTION
+ This API is used to send an Indication to SME/PE to change the
+ current operating channel to a different target channel.
+
+ The Channel change will be issued by SAP under the following
+ scenarios.
+ 1. A radar indication is received during SAP CAC WAIT STATE and
+ channel change is required.
+ 2. A radar indication is received during SAP STARTED STATE and
+ channel change is required.
+ DEPENDENCIES
+ NA.
+
+ PARAMETERS
+ IN
+ sapContext: Pointer to vos global context structure
+
+ RETURN VALUE
+ The VOS_STATUS code associated with performing the operation
+
+ VOS_STATUS_SUCCESS: Success
+
+ SIDE EFFECTS
+============================================================================*/
+VOS_STATUS
+WLANSAP_ChannelChangeRequest(v_PVOID_t pSapCtx, tANI_U8 tArgetChannel)
+{
+ ptSapContext sapContext = NULL;
+ eHalStatus halStatus = eHAL_STATUS_FAILURE;
+ v_PVOID_t hHal = NULL;
+ sapContext = (ptSapContext)pSapCtx;
+
+ if ( NULL == sapContext )
+ {
+ VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid SAP pointer from pvosGCtx", __func__);
+ return VOS_STATUS_E_FAULT;
+ }
+
+ hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
+ if (NULL == hHal)
+ {
+ VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid HAL pointer from pvosGCtx", __func__);
+ return VOS_STATUS_E_FAULT;
+ }
+
+ halStatus = sme_RoamChannelChangeReq( hHal,
+ sapContext->sessionId, tArgetChannel);
+
+ if (halStatus == eHAL_STATUS_SUCCESS)
+ {
+ return VOS_STATUS_SUCCESS;
+ }
+ return VOS_STATUS_E_FAULT;
+}
+
+/*==========================================================================
+
+ FUNCTION WLANSAP_StartBeaconReq
+ DESCRIPTION
+ This API is used to send an Indication to SME/PE to start
+ beaconing on the current operating channel.
+
+ Brief:When SAP is started on DFS channel and when ADD BSS RESP is received
+ LIM temporarily holds off Beaconing for SAP to do CAC WAIT. When
+ CAC WAIT is done SAP resumes the Beacon Tx by sending a start beacon
+ request to LIM.
+
+ DEPENDENCIES
+ NA.
+
+PARAMETERS
+
+IN
+ pvosGCtx: Pointer to vos global context structure
+
+RETURN VALUE
+ The VOS_STATUS code associated with performing the operation
+
+VOS_STATUS_SUCCESS: Success
+
+SIDE EFFECTS
+============================================================================*/
+VOS_STATUS WLANSAP_StartBeaconReq(v_PVOID_t pSapCtx)
+{
+ ptSapContext sapContext = NULL;
+ eHalStatus halStatus = eHAL_STATUS_FAILURE;
+ v_PVOID_t hHal = NULL;
+ tANI_U8 dfsCacWaitStatus = 0;
+ sapContext = (ptSapContext)pSapCtx;
+
+ if ( NULL == sapContext )
+ {
+ VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid SAP pointer from pvosGCtx", __func__);
+ return VOS_STATUS_E_FAULT;
+ }
+
+ hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
+ if (NULL == hHal)
+ {
+ VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid HAL pointer from pvosGCtx", __func__);
+ return VOS_STATUS_E_FAULT;
+ }
+
+ /* No Radar was found during CAC WAIT, So start Beaconing */
+ if (sapContext->SapDfsInfo.sap_radar_found_status == VOS_FALSE)
+ {
+ /* CAC Wait done without any Radar Detection */
+ dfsCacWaitStatus = VOS_TRUE;
+ halStatus = sme_RoamStartBeaconReq( hHal,
+ sapContext->sessionId, dfsCacWaitStatus);
+ if (halStatus == eHAL_STATUS_SUCCESS)
+ {
+ return VOS_STATUS_SUCCESS;
+ }
+ return VOS_STATUS_E_FAULT;
+ }
+
+ return VOS_STATUS_E_FAULT;
+}
+
+
+/*==========================================================================
+ FUNCTION WLANSAP_DfsSendCSAIeRequest
+
+ DESCRIPTION
+ This API is used to send channel switch announcement request to PE
+ DEPENDENCIES
+ NA.
+
+ PARAMETERS
+ IN
+ sapContext: Pointer to vos global context structure
+
+ RETURN VALUE
+ The VOS_STATUS code associated with performing the operation
+
+ VOS_STATUS_SUCCESS: Success
+
+ SIDE EFFECTS
+============================================================================*/
+VOS_STATUS
+WLANSAP_DfsSendCSAIeRequest(v_PVOID_t pSapCtx)
+{
+ ptSapContext sapContext = NULL;
+ eHalStatus halStatus = eHAL_STATUS_FAILURE;
+ v_PVOID_t hHal = NULL;
+ sapContext = (ptSapContext)pSapCtx;
+
+ if ( NULL == sapContext )
+ {
+ VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid SAP pointer from pvosGCtx", __func__);
+ return VOS_STATUS_E_FAULT;
+ }
+
+ hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
+ if (NULL == hHal)
+ {
+ VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid HAL pointer from pvosGCtx", __func__);
+ return VOS_STATUS_E_FAULT;
+ }
+
+ halStatus = sme_RoamCsaIeRequest(hHal, sapContext->sessionId,
+ sapContext->SapDfsInfo.target_channel,
+ sapContext->SapDfsInfo.csaIERequired);
+ if (halStatus == eHAL_STATUS_SUCCESS)
+ {
+ return VOS_STATUS_SUCCESS;
+ }
+
+ return VOS_STATUS_E_FAULT;
+}
diff --git a/CORE/SERVICES/BMI/bmi.c b/CORE/SERVICES/BMI/bmi.c
index 3835ff498b14..505bd0a17f25 100644
--- a/CORE/SERVICES/BMI/bmi.c
+++ b/CORE/SERVICES/BMI/bmi.c
@@ -24,26 +24,7 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-/*
- * Copyright (c) 2013 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-//------------------------------------------------------------------------------
-// <copyright file="bmi.c" company="Atheros">
-// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
-// $ATH_LICENSE_HOSTSDK0_C$
-//------------------------------------------------------------------------------
+
//==============================================================================
//
// Author(s): ="Atheros"
diff --git a/CORE/SERVICES/BMI/ol_fw.c b/CORE/SERVICES/BMI/ol_fw.c
index a22f2836d1b6..d3baacee8310 100644
--- a/CORE/SERVICES/BMI/ol_fw.c
+++ b/CORE/SERVICES/BMI/ol_fw.c
@@ -24,21 +24,7 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-/*
- * Copyright (c) 2013 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
+
#include <linux/firmware.h>
#include "ol_if_athvar.h"
#include "ol_fw.h"
@@ -495,6 +481,7 @@ u_int32_t host_interest_item_address(u_int32_t target_type, u_int32_t item_offse
case TARGET_TYPE_AR9888:
return (AR9888_HOST_INTEREST_ADDRESS + item_offset);
case TARGET_TYPE_AR6320:
+ case TARGET_TYPE_AR6320V2:
return (AR6320_HOST_INTEREST_ADDRESS + item_offset);
}
}
@@ -507,6 +494,21 @@ static void ramdump_work_handler(struct work_struct *ramdump)
void __iomem *ramdump_base;
unsigned long address;
unsigned long size;
+ u_int32_t host_interest_address;
+
+ if (!ramdump_scn) {
+ printk("No RAM dump will be collected since ramdump_scn is NULL!\n");
+ goto out;
+ }
+
+ if (HIFDiagReadMem(ramdump_scn->hif_hdl,
+ host_interest_item_address(ramdump_scn->target_type,
+ offsetof(struct host_interest_s, hi_failure_state)),
+ (A_UCHAR*) &host_interest_address, sizeof(u_int32_t)) != A_OK) {
+ printk("HifDiagReadiMem FW Dump Area Pointer failed!\n");
+ goto out;
+ }
+ printk("Host interest item address: 0x%08X\n", host_interest_address);
/* Get RAM dump memory address and size */
if (cnss_get_ramdump_mem(&address, &size)) {
@@ -521,16 +523,11 @@ static void ramdump_work_handler(struct work_struct *ramdump)
goto out;
}
- if (ramdump_scn) {
- ol_target_coredump(ramdump_scn, ramdump_base, TOTAL_DUMP_SIZE);
+ ol_target_coredump(ramdump_scn, ramdump_base, TOTAL_DUMP_SIZE);
+ iounmap(ramdump_base);
- printk("%s: RAM dump collecting completed!\n", __func__);
- msleep(500);
- } else {
- printk("No RAM dump will be collected since ramdump_scn is NULL!\n");
- }
-
- iounmap(ramdump_base);
+ printk("%s: RAM dump collecting completed!\n", __func__);
+ msleep(500);
out:
/* Notify SSR framework the target has crashed. */
@@ -552,7 +549,6 @@ void ol_target_failure(void *instance, A_STATUS status)
A_UINT32 reg_dump_values[REGISTER_DUMP_LEN_MAX];
A_UINT32 reg_dump_cnt = 0;
A_UINT32 i;
-#endif
A_UINT32 dbglog_hdr_address;
struct dbglog_hdr_s dbglog_hdr;
struct dbglog_buf_s dbglog_buf;
@@ -561,6 +557,7 @@ void ol_target_failure(void *instance, A_STATUS status)
A_UINT8 *dbglog_data;
void *vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL);
tp_wma_handle wma = vos_get_context(VOS_MODULE_ID_WDA, vos_context);
+#endif
if (OL_TRGET_STATUS_RESET == scn->target_status) {
printk("Target is already asserted, ignore!\n");
@@ -597,7 +594,6 @@ void ol_target_failure(void *instance, A_STATUS status)
for (i = 0; i < reg_dump_cnt; i++) {
printk("[%02d] : 0x%08X\n", i, reg_dump_values[i]);
}
-#endif
if (HIFDiagReadMem(scn->hif_hdl,
host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_dbglog_hdr)),
@@ -656,6 +652,7 @@ void ol_target_failure(void *instance, A_STATUS status)
adf_os_mem_free(dbglog_data);
}
+#endif
#if defined(QCA_WIFI_2_0) && !defined(QCA_WIFI_ISOC) && defined(CONFIG_CNSS)
/* Collect the RAM dump through a workqueue */
@@ -972,49 +969,29 @@ void ol_target_coredump(void *inst, void *memoryBlock, u_int32_t blockLength)
struct ol_softc *scn = (struct ol_softc *)inst;
char *bufferLoc = memoryBlock;
int result = 0;
- u_int32_t reg_dump_area = 0;
u_int32_t amountRead = 0;
u_int32_t sectionCount = 0;
u_int32_t pos = 0;
u_int32_t readLen = 0;
/*
- * SECTION = REGISTER
- * START = Vary in target type
- * LENGTH = 0x6c000
- *
* SECTION = DRAM
- * START = 0x400000
- * LENGTH = 0x50000
+ * START = 0x00400000
+ * LENGTH = 0x00070000
*
* SECTION = IRAM
- * START = 0x980000
- * LENGTH = 0x38000
- *
+ * START = 0x00980000
+ * LENGTH = 0x00038000
*/
- if (HIFDiagReadMem(scn->hif_hdl,
- host_interest_item_address(scn->target_type,
- offsetof(struct host_interest_s, hi_failure_state)),
- (A_UCHAR*) &reg_dump_area, sizeof(u_int32_t)) != A_OK) {
- printk("HifDiagReadiMem FW Dump Area Pointer failed!\n");
- return;
- }
- printk("Host interest item address: 0x%08X\n", reg_dump_area);
-
- while ((sectionCount < 3) && (amountRead < blockLength)) {
+ while ((sectionCount < 2) && (amountRead < blockLength)) {
switch (sectionCount) {
case 0:
- /* REGISTER SECTION */
- pos = reg_dump_area;
- readLen = REGISTER_SIZE;
- break;
- case 1:
/* DRAM SECTION */
pos = DRAM_LOCATION;
readLen = DRAM_SIZE;
break;
- case 2:
+ case 1:
/* IRAM SECTION */
pos = IRAM_LOCATION;
readLen = IRAM_SIZE;
@@ -1044,18 +1021,20 @@ u_int8_t ol_get_number_of_peers_supported(struct ol_softc *scn)
u_int8_t max_no_of_peers = 0;
switch (scn->target_version) {
- case AR6320_REV1_3_VERSION:
- if(scn->max_no_of_peers > MAX_SUPPORTED_PEERS_REV1_3)
- max_no_of_peers = MAX_SUPPORTED_PEERS_REV1_3;
+ case AR6320_REV1_1_VERSION:
+ if(scn->max_no_of_peers > MAX_SUPPORTED_PEERS_REV1_1)
+ max_no_of_peers = MAX_SUPPORTED_PEERS_REV1_1;
else
max_no_of_peers = scn->max_no_of_peers;
break;
+
default:
- if(scn->max_no_of_peers > MAX_SUPPORTED_PEERS_REV1_1)
- max_no_of_peers = MAX_SUPPORTED_PEERS_REV1_1;
+ if(scn->max_no_of_peers > MAX_SUPPORTED_PEERS_REV1_3)
+ max_no_of_peers = MAX_SUPPORTED_PEERS_REV1_3;
else
max_no_of_peers = scn->max_no_of_peers;
break;
+
}
return max_no_of_peers;
}
diff --git a/CORE/SERVICES/BMI/ol_fw.h b/CORE/SERVICES/BMI/ol_fw.h
index 6a61db8634ac..8d25b9704596 100644
--- a/CORE/SERVICES/BMI/ol_fw.h
+++ b/CORE/SERVICES/BMI/ol_fw.h
@@ -24,21 +24,7 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-/*
- * Copyright (c) 2013 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
+
#ifndef _OL_FW_H_
#define _OL_FW_H_
@@ -64,17 +50,17 @@
#define PEER_DEFAULT_STATS_UPDATE_PERIOD 500
#if defined(QCA_WIFI_2_0) && !defined(QCA_WIFI_ISOC)
-#define REGISTER_LOCATION 0x4000
-#define REGISTER_SIZE 0x6c000
+#define REGISTER_LOCATION 0x00000000
+#define REGISTER_SIZE 0x00000800
-#define DRAM_LOCATION 0x400000
-#define DRAM_SIZE 0x50000
+#define DRAM_LOCATION 0x00400000
+#define DRAM_SIZE 0x00070000
-#define IRAM_LOCATION 0x980000
-#define IRAM_SIZE 0x38000
+#define IRAM_LOCATION 0x00980000
+#define IRAM_SIZE 0x00038000
#define TOTAL_DUMP_SIZE REGISTER_SIZE + DRAM_SIZE + IRAM_SIZE
-#define PCIE_READ_LIMIT 0x5000
+#define PCIE_READ_LIMIT 0x00005000
void ol_target_coredump(void *instance, void* memoryBlock,
u_int32_t blockLength);
diff --git a/CORE/SERVICES/COMMON/_ieee80211_common.h b/CORE/SERVICES/COMMON/_ieee80211_common.h
index 3476ff53959a..df7ba5aecac4 100644
--- a/CORE/SERVICES/COMMON/_ieee80211_common.h
+++ b/CORE/SERVICES/COMMON/_ieee80211_common.h
@@ -194,7 +194,7 @@ enum ieee80211_scanmode {
#define IEEE80211_CHAN_PASSIVE 0x00000200 /* Only passive scan allowed */
#define IEEE80211_CHAN_DYN 0x00000400 /* Dynamic CCK-OFDM channel */
#define IEEE80211_CHAN_GFSK 0x00000800 /* GFSK channel (FHSS PHY) */
-#define IEEE80211_CHAN_RADAR 0x00001000 /* Radar found on channel */
+#define IEEE80211_CHAN_RADAR_DFS 0x00001000 /* Radar found on channel */
#define IEEE80211_CHAN_STURBO 0x00002000 /* 11a static turbo channel only */
#define IEEE80211_CHAN_HALF 0x00004000 /* Half rate channel */
#define IEEE80211_CHAN_QUARTER 0x00008000 /* Quarter rate channel */
@@ -411,11 +411,11 @@ enum ieee80211_scanmode {
(((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT80) == IEEE80211_CHAN_11AC_VHT80)
#define IEEE80211_IS_CHAN_RADAR(_c) \
- (((_c)->ic_flags & IEEE80211_CHAN_RADAR) == IEEE80211_CHAN_RADAR)
+ (((_c)->ic_flags & IEEE80211_CHAN_RADAR_DFS) == IEEE80211_CHAN_RADAR_DFS)
#define IEEE80211_CHAN_SET_RADAR(_c) \
- ((_c)->ic_flags |= IEEE80211_CHAN_RADAR)
+ ((_c)->ic_flags |= IEEE80211_CHAN_RADAR_DFS)
#define IEEE80211_CHAN_CLR_RADAR(_c) \
- ((_c)->ic_flags &= ~IEEE80211_CHAN_RADAR)
+ ((_c)->ic_flags &= ~IEEE80211_CHAN_RADAR_DFS)
#define IEEE80211_CHAN_SET_DISALLOW_ADHOC(_c) \
((_c)->ic_flagext |= IEEE80211_CHAN_DISALLOW_ADHOC)
#define IEEE80211_CHAN_SET_DISALLOW_HOSTAP(_c) \
diff --git a/CORE/SERVICES/COMMON/a_osapi.h b/CORE/SERVICES/COMMON/a_osapi.h
index a345780b6bdc..7524243faad7 100644
--- a/CORE/SERVICES/COMMON/a_osapi.h
+++ b/CORE/SERVICES/COMMON/a_osapi.h
@@ -24,16 +24,7 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-/*
- * Copyright (c) 2013 Qualcomm Atheros, Inc..
- * All Rights Reserved.
- * Qualcomm Atheros Confidential and Proprietary.
- */
- //------------------------------------------------------------------------------
-// <copyright file="a_osapi.h" company="Atheros">
-// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
-// $ATH_LICENSE_HOSTSDK0_C$
-//------------------------------------------------------------------------------
+
//==============================================================================
// This file contains the definitions of the basic atheros data types.
// It is used to map the data types in atheros files to a platform specific
diff --git a/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h b/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h
index 3998c534d839..d209ded62380 100644
--- a/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h
+++ b/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h
@@ -104,16 +104,9 @@ struct cvg_nbuf_cb {
} extra_frags;
uint32_t owner_id;
__adf_nbuf_callback_fn adf_nbuf_callback_fn;
-#ifdef IPA_OFFLOAD
- unsigned long priv_data;
-#endif
};
#define NBUF_OWNER_ID(skb) \
(((struct cvg_nbuf_cb *)((skb)->cb))->owner_id)
-#ifdef IPA_OFFLOAD
-#define NBUF_OWNER_PRIV_DATA(skb) \
- (((struct cvg_nbuf_cb *)((skb)->cb))->priv_data)
-#endif
#define NBUF_CALLBACK_FN(skb) \
(((struct cvg_nbuf_cb *)((skb)->cb))->adf_nbuf_callback_fn)
#define NBUF_CALLBACK_FN_EXEC(skb) \
diff --git a/CORE/SERVICES/COMMON/bmi_msg.h b/CORE/SERVICES/COMMON/bmi_msg.h
index 169d21c43c46..0d125418bcb8 100644
--- a/CORE/SERVICES/COMMON/bmi_msg.h
+++ b/CORE/SERVICES/COMMON/bmi_msg.h
@@ -24,13 +24,6 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2012 Atheros Corporation. All rights reserved.
-// $ATH_LICENSE_HOSTSDK0_C$
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
#ifndef __BMI_MSG_H__
#define __BMI_MSG_H__
@@ -256,6 +249,7 @@ PREPACK struct bmi_target_info {
#define TARGET_TYPE_AR9888 7
#define TARGET_TYPE_AR6320 8
#define TARGET_TYPE_AR900B 9
+#define TARGET_TYPE_AR6320V2 10
/* For attach Peregrine 2.0 board target_reg_tbl only */
#define TARGET_TYPE_AR9888V2 10
diff --git a/CORE/SERVICES/COMMON/dbglog_id.h b/CORE/SERVICES/COMMON/dbglog_id.h
index e3280e0baeb1..0cbfe9baf8b8 100644
--- a/CORE/SERVICES/COMMON/dbglog_id.h
+++ b/CORE/SERVICES/COMMON/dbglog_id.h
@@ -24,19 +24,6 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-/*
- * Copyright (c) 2004-2010, 2013 Qualcomm Atheros, Inc..
- * All Rights Reserved.
- * Qualcomm Atheros Confidential and Proprietary.
- */
-//------------------------------------------------------------------------------
-// <copyright file="dbglog_id.h" company="Atheros">
-// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
-// $ATH_LICENSE_HOSTSDK0_C$
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
#ifndef _DBGLOG_ID_H_
#define _DBGLOG_ID_H_
@@ -217,7 +204,8 @@ extern "C" {
#define RESMGR_DYN_SCH_HOME_CH_QUOTA 57
#define RESMGR_OCS_REG_RECAL_QUOTA_NOTIF 58
#define RESMGR_OCS_DEREG_RECAL_QUOTA_NOTIF 59
-#define RESMGR_DEFINITION_END 60
+#define RESMGR_DYN_SCH_CH_STATS_END 60
+#define RESMGR_DEFINITION_END 61
/* RESMGR CHNMGR debug ids */
#define RESMGR_CHMGR_DEFINITION_START 0
@@ -250,7 +238,8 @@ extern "C" {
#define VDEV_MGR_VDEV_PAUSE_DELAY_UPDATE 16
#define VDEV_MGR_VDEV_PAUSE_FAIL 17
#define VDEV_MGR_GEN_PERIODIC_NOA 18
-#define VDEV_MGR_DEFINITION_END 19
+#define VDEV_MGR_OFF_CHAN_GO_CH_REQ_SETUP 19
+#define VDEV_MGR_DEFINITION_END 20
/* WHAL debug identifier definitions */
#define WHAL_DBGID_DEFINITION_START 0
@@ -539,7 +528,24 @@ extern "C" {
#define COEX_MWS_ERROR 236
#define COEX_MWS_ANT_DIVERSITY 237
-#define COEX_DEBUG_ID_END 238
+#define COEX_P2P_GO 238
+#define COEX_P2P_CLIENT 239
+#define COEX_SCC_1 240
+#define COEX_SCC_2 241
+#define COEX_MCC_1 242
+#define COEX_MCC_2 243
+#define COEX_TRF_SHAPE_NOA 244
+#define COEX_NOA_ONESHOT 245
+#define COEX_NOA_PERIODIC 246
+#define COEX_LE_1 247
+#define COEX_LE_2 248
+#define COEX_ANT_1 249
+#define COEX_ANT_2 250
+#define COEX_ENTER_NOA 251
+#define COEX_EXIT_NOA 252
+#define COEX_BT_SCAN_PROTECT 253
+
+#define COEX_DEBUG_ID_END 254
#define SCAN_START_COMMAND_FAILED 0
#define SCAN_STOP_COMMAND_FAILED 1
@@ -684,7 +690,10 @@ extern "C" {
#define OFFLOADMGR_NO_REG_DATA_HANDLERS 3
#define OFFLOADMGR_NO_REG_EVENT_HANDLERS 4
#define OFFLOADMGR_REG_OFFLOAD_FAILED 5
-#define OFFLOADMGR_DBGID_DEFINITION_END 6
+#define OFFLOADMGR_DEREG_OFFLOAD_FAILED 6
+#define OFFLOADMGR_ENTER_FAILED 7
+#define OFFLOADMGR_EXIT_FAILED 8
+#define OFFLOADMGR_DBGID_DEFINITION_END 9
/*Resource Debug IDs*/
#define RESOURCE_DBGID_DEFINITION_START 0
@@ -739,7 +748,8 @@ extern "C" {
#define P2P_GO_GET_NOA_INFO 35
#define P2P_GO_ADD_ONE_SHOT_NOA 36
#define P2P_GO_GET_NOA_IE 37
-#define P2P_DBGID_DEFINITION_END 38
+#define P2P_GO_BCN_TX_COMP 38
+#define P2P_DBGID_DEFINITION_END 39
//CSA modules DBGIDs
@@ -772,7 +782,9 @@ extern "C" {
#define WLAN_CHATTER_MC_FILTER_DEL 10
#define WLAN_CHATTER_MC_FILTER_ALLOW 11
#define WLAN_CHATTER_MC_FILTER_DROP 12
-#define WLAN_CHATTER_DBGID_DEFINITION_END 13
+#define WLAN_CHATTER_COALESCING_FILTER_ADD 13
+#define WLAN_CHATTER_COALESCING_FILTER_DEL 14
+#define WLAN_CHATTER_DBGID_DEFINITION_END 15
#define WOW_DBGID_DEFINITION_START 0
#define WOW_ENABLE_CMDID 1
@@ -925,10 +937,37 @@ extern "C" {
#define WLAN_HB_DBGID_TCP_TX 14
#define WLAN_HB_DBGID_DEFINITION_END 15
-/* Thermal Manager DBGIDs */
+/* Thermal Manager DBGIDs*/
#define THERMAL_MGR_NEW_THRESH 0
#define THERMAL_MGR_THRESH_CROSSED 1
+/* WLAN PHYERR DFS(parse/filter) DBGIDs */
+#define WLAN_PHYERR_DFS_DBGID_DEFINITION_START 0
+#define WLAN_PHYERR_DFS_PHYERR_INFO_CHAN_BUFLEN 1
+#define WLAN_PHYERR_DFS_PHYERR_INFO_PPDU 2
+#define WLAN_PHYERR_DFS_DBDID_RADAR_SUMMARY 3
+#define WLAN_PHYERR_DFS_DBDID_SEARCH_FFT 4
+#define WLAN_PHTERR_DFS_DBDID_FILTER_STATUS 5
+
+/* RMC DBGIDs */
+#define RMC_DBGID_DEFINITION_START 0
+#define RMC_SM_INIT_ERR 1
+#define RMC_VDEV_ALLOC_ERR 2
+#define RMC_CREATE_INSTANCE 3
+#define RMC_DELETE_INSTANCE 4
+#define RMC_NEW_PRI_LEADER 5
+#define RMC_NEW_SEC_LEADER 6
+#define RMC_NO_LDR_CHANGE 7
+#define RMC_LDR_INFORM_SENT 8
+#define RMC_PEER_ADD 9
+#define RMC_PEER_DELETE 10
+#define RMC_PEER_UNKNOWN 11
+#define RMC_PRI_LDR_RSSI_UPDATE 12
+#define RMC_SEC_LDR_RSSI_UPDATE 13
+#define RMC_SET_MODE 14
+#define RMC_SET_ACTION_PERIOD 15
+#define RMC_DBGID_DEFINITION_END 16
+
#ifdef __cplusplus
}
#endif
diff --git a/CORE/SERVICES/COMMON/hif.h b/CORE/SERVICES/COMMON/hif.h
index 4de405463595..4a6142bb5073 100644
--- a/CORE/SERVICES/COMMON/hif.h
+++ b/CORE/SERVICES/COMMON/hif.h
@@ -24,11 +24,7 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-//------------------------------------------------------------------------------
-// <copyright file="hif.h" company="Atheros">
-// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
-// $ATH_LICENSE_HOSTSDK0_C$
-//------------------------------------------------------------------------------
+
//==============================================================================
// HIF specific declarations and prototypes
//
@@ -59,6 +55,7 @@ typedef void __iomem *A_target_id_t;
#define HIF_TYPE_AR6004 5
#define HIF_TYPE_AR9888 6
#define HIF_TYPE_AR6320 7
+#define HIF_TYPE_AR6320V2 8
/* For attaching Peregrine 2.0 board host_reg_tbl only */
#define HIF_TYPE_AR9888V2 8
@@ -645,6 +642,8 @@ extern void HIFTargetSleepStateAdjust(A_target_id_t targid, A_BOOL sleep_ok, A_B
extern void
HIFSetTargetSleep(HIF_DEVICE *hif_device, A_BOOL sleep_ok, A_BOOL wait_for_it);
extern A_BOOL HIFTargetForcedAwake(A_target_id_t targid);
+extern void
+HIFCancelDeferredTargetSleep(HIF_DEVICE *hif_device);
#define A_TARGET_ID(hifDevice) HIFGetTargetId(hifDevice)
diff --git a/CORE/SERVICES/COMMON/htc_api.h b/CORE/SERVICES/COMMON/htc_api.h
index 1770f6c06b0d..d3f4b79bd8b3 100644
--- a/CORE/SERVICES/COMMON/htc_api.h
+++ b/CORE/SERVICES/COMMON/htc_api.h
@@ -685,4 +685,5 @@ struct s_htc_msg{
void *htc_get_targetdef(HTC_HANDLE htc_handle);
void HTCSetTargetToSleep(void *context);
+void HTCCancelDeferredTargetSleep(void *context);
#endif /* _HTC_API_H_ */
diff --git a/CORE/SERVICES/COMMON/ieee80211_common.h b/CORE/SERVICES/COMMON/ieee80211_common.h
index c8c6c244461e..8927feb11753 100644
--- a/CORE/SERVICES/COMMON/ieee80211_common.h
+++ b/CORE/SERVICES/COMMON/ieee80211_common.h
@@ -1862,6 +1862,9 @@ enum {
#define IEEE80211_WEP_EXTIVLEN 4 /* extended IV length */
#define IEEE80211_WEP_MICLEN 8 /* trailing MIC */
+#define IEEE80211_CCMP_HEADERLEN 8
+#define IEEE80211_CCMP_MICLEN 8
+
#define IEEE80211_CRC_LEN 4
#define IEEE80211_8021Q_HEADER_LEN 4
diff --git a/CORE/SERVICES/COMMON/ol_if_athvar.h b/CORE/SERVICES/COMMON/ol_if_athvar.h
index ab76392231c8..55ad6e469135 100644
--- a/CORE/SERVICES/COMMON/ol_if_athvar.h
+++ b/CORE/SERVICES/COMMON/ol_if_athvar.h
@@ -24,21 +24,6 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-/*
- * Copyright (c) 2010-2013 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
/*
* Defintions for the Atheros Wireless LAN controller driver.
diff --git a/CORE/SERVICES/COMMON/pktlog.h b/CORE/SERVICES/COMMON/pktlog.h
index fdd1fe68416c..f4dd030bca56 100644
--- a/CORE/SERVICES/COMMON/pktlog.h
+++ b/CORE/SERVICES/COMMON/pktlog.h
@@ -24,21 +24,6 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-/*
- * Copyright (c) 2012-2013 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
#ifndef _PKTLOG_
#define _PKTLOG_
diff --git a/CORE/SERVICES/COMMON/targaddrs.h b/CORE/SERVICES/COMMON/targaddrs.h
index a91787530b6a..4c2b032c3cab 100644
--- a/CORE/SERVICES/COMMON/targaddrs.h
+++ b/CORE/SERVICES/COMMON/targaddrs.h
@@ -24,14 +24,6 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-//------------------------------------------------------------------------------
-// <copyright file="targaddrs.h" company="Atheros">
-// Copyright (c) 2010 Atheros Corporation. All rights reserved.
-// $ATH_LICENSE_HOSTSDK0_C$
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
#ifndef __TARGADDRS_H__
#define __TARGADDRS_H__
@@ -608,8 +600,9 @@ PREPACK64 struct host_interest_s {
(((TargetType) == TARGET_TYPE_AR6006) ? AR6006_HOST_INTEREST_ITEM_ADDRESS(item) : \
(((TargetType) == TARGET_TYPE_AR9888) ? AR9888_HOST_INTEREST_ITEM_ADDRESS(item) : \
(((TargetType) == TARGET_TYPE_AR6320) ? AR6320_HOST_INTEREST_ITEM_ADDRESS(item) : \
+ (((TargetType) == TARGET_TYPE_AR6320V2) ? AR6320_HOST_INTEREST_ITEM_ADDRESS(item) : \
(((TargetType) == TARGET_TYPE_AR900B) ? AR900B_HOST_INTEREST_ITEM_ADDRESS(item) : \
- 0)))))))
+ 0))))))))
#define AR6002_BOARD_DATA_SZ 768
#define AR6002_BOARD_EXT_DATA_SZ 0
diff --git a/CORE/SERVICES/COMMON/targcfg.h b/CORE/SERVICES/COMMON/targcfg.h
index 7b51511d4774..5d930c99a880 100644
--- a/CORE/SERVICES/COMMON/targcfg.h
+++ b/CORE/SERVICES/COMMON/targcfg.h
@@ -24,14 +24,6 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-//------------------------------------------------------------------------------
-// <copyright file="wmi_unified.h" company="Atheros">
-// Copyright (c) 2004-2010 Qualcomm Atheros Inc. All rights reserved.
-// $ATH_LICENSE_HOSTSDK0_C$
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
#ifndef __TARGCFG_H__
#define __TARGCFG_H__
diff --git a/CORE/SERVICES/COMMON/wdi_event.h b/CORE/SERVICES/COMMON/wdi_event.h
index 690bbe4417c6..b1d0d600e3f0 100644
--- a/CORE/SERVICES/COMMON/wdi_event.h
+++ b/CORE/SERVICES/COMMON/wdi_event.h
@@ -24,21 +24,6 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-/*
- * Copyright (c) 2012-2013 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
#ifndef _WDI_EVENT_H_
#define _WDI_EVENT_H_
diff --git a/CORE/SERVICES/COMMON/wlan_module_ids.h b/CORE/SERVICES/COMMON/wlan_module_ids.h
index f4973fb0aa15..ee1b102a2c96 100644
--- a/CORE/SERVICES/COMMON/wlan_module_ids.h
+++ b/CORE/SERVICES/COMMON/wlan_module_ids.h
@@ -78,6 +78,8 @@ typedef enum {
WLAN_MODULE_TXBF,
WLAN_MODULE_BATCH_SCAN,
WLAN_MODULE_THERMAL_MGR,
+ WLAN_MODULE_PHYERR_DFS,
+ WLAN_MODULE_RMC,
WLAN_MODULE_ID_MAX,
WLAN_MODULE_ID_INVALID = WLAN_MODULE_ID_MAX,
} WLAN_MODULE_ID;
diff --git a/CORE/SERVICES/COMMON/wma_api.h b/CORE/SERVICES/COMMON/wma_api.h
index 9675af9adfe6..e6b12588e10c 100644
--- a/CORE/SERVICES/COMMON/wma_api.h
+++ b/CORE/SERVICES/COMMON/wma_api.h
@@ -81,6 +81,7 @@ typedef enum {
#define GEN_CMD 3
#define DBG_CMD 4
#define PPS_CMD 5
+#define QPOWER_CMD 6
#ifdef QCA_WIFI_ISOC
VOS_STATUS wma_nv_download_start(v_VOID_t *vos_context);
@@ -115,6 +116,8 @@ eHalStatus wma_set_htconfig(tANI_U8 vdev_id, tANI_U16 ht_capab, int value);
eHalStatus WMA_SetRegDomain(void * clientCtxt, v_REGDOMAIN_t regId,
tAniBool sendRegHint);
+VOS_STATUS WMA_GetWcnssSoftwareVersion(v_PVOID_t pvosGCtx, tANI_U8 *pVersion,
+ tANI_U32 versionBufferSize);
#ifndef QCA_WIFI_ISOC
int wma_suspend_target(WMA_HANDLE handle, int disable_target_intr);
void wma_target_suspend_complete(void *context);
diff --git a/CORE/SERVICES/COMMON/wma_dfs_interface.h b/CORE/SERVICES/COMMON/wma_dfs_interface.h
new file mode 100644
index 000000000000..6d3d6da91839
--- /dev/null
+++ b/CORE/SERVICES/COMMON/wma_dfs_interface.h
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#include "ath_dfs_structs.h"
+#include "_ieee80211_common.h"
+
+#define IEEE80211_CHAN_MAX 255
+
+/* channel attributes */
+
+/* Turbo channel */
+#define IEEE80211_CHAN_TURBO 0x00000010
+/* CCK channel */
+#define IEEE80211_CHAN_CCK 0x00000020
+/* OFDM channel */
+#define IEEE80211_CHAN_OFDM 0x00000040
+/* 2 GHz spectrum channel. */
+#define IEEE80211_CHAN_2GHZ 0x00000080
+/* 5 GHz spectrum channel */
+#define IEEE80211_CHAN_5GHZ 0x00000100
+/* Only passive scan allowed */
+#define IEEE80211_CHAN_PASSIVE 0x00000200
+/* Dynamic CCK-OFDM channel */
+#define IEEE80211_CHAN_DYN 0x00000400
+/* GFSK channel (FHSS PHY) */
+#define IEEE80211_CHAN_GFSK 0x00000800
+/* Radar found on channel */
+#define IEEE80211_CHAN_RADAR 0x00001000
+/* 11a static turbo channel only */
+#define IEEE80211_CHAN_STURBO 0x00002000
+/* Half rate channel */
+#define IEEE80211_CHAN_HALF 0x00004000
+/* Quarter rate channel */
+#define IEEE80211_CHAN_QUARTER 0x00008000
+/* HT 20 channel */
+#define IEEE80211_CHAN_HT20 0x00010000
+/* HT 40 with extension channel above */
+#define IEEE80211_CHAN_HT40PLUS 0x00020000
+/* HT 40 with extension channel below */
+#define IEEE80211_CHAN_HT40MINUS 0x00040000
+/* HT 40 Intolerant */
+#define IEEE80211_CHAN_HT40INTOL 0x00080000
+/* VHT 20 channel */
+#define IEEE80211_CHAN_VHT20 0x00100000
+/* VHT 40 with extension channel above */
+#define IEEE80211_CHAN_VHT40PLUS 0x00200000
+/* VHT 40 with extension channel below */
+#define IEEE80211_CHAN_VHT40MINUS 0x00400000
+/* VHT 80 channel */
+#define IEEE80211_CHAN_VHT80 0x00800000
+
+/* token for ``any channel'' */
+#define IEEE80211_CHAN_ANY (-1)
+#define IEEE80211_CHAN_ANYC \
+ ((struct ieee80211_channel *) IEEE80211_CHAN_ANY)
+
+
+#define IEEE80211_IS_CHAN_11N_HT40MINUS(_c) \
+ (((_c)->ic_flags & IEEE80211_CHAN_HT40MINUS) != 0)
+#define IEEE80211_IS_CHAN_11N_HT40PLUS(_c) \
+ (((_c)->ic_flags & IEEE80211_CHAN_HT40PLUS) != 0)
+#define IEEE80211_CHAN_11AC_VHT80 \
+ (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_VHT80)
+
+
+#define IEEE80211_IS_CHAN_11AC_VHT80(_c) \
+ (((_c)->ic_flags & IEEE80211_CHAN_11AC_VHT80) == \
+ IEEE80211_CHAN_11AC_VHT80)
+#define CHANNEL_108G \
+ (IEEE80211_CHAN_2GHZ|IEEE80211_CHAN_OFDM|IEEE80211_CHAN_TURBO)
+
+/*
+ * Software use: channel interference
+ * used for as AR as well as RADAR
+ * interference detection
+*/
+#define CHANNEL_INTERFERENCE 0x01
+/* In case of VHT160, we can have 8 20Mhz channels */
+#define IEE80211_MAX_20M_SUB_CH 8
+
+struct ieee80211_channel
+{
+ u_int32_t ic_freq; /* setting in Mhz */
+ u_int32_t ic_flags; /* see below */
+ u_int8_t ic_flagext; /* see below */
+ u_int8_t ic_ieee; /* IEEE channel number */
+
+ /* maximum regulatory tx power in dBm */
+ int8_t ic_maxregpower;
+
+ int8_t ic_maxpower; /* maximum tx power in dBm */
+ int8_t ic_minpower; /* minimum tx power in dBm */
+ u_int8_t ic_regClassId; /* regClassId of this channel */
+ u_int8_t ic_antennamax; /* antenna gain max from regulatory */
+ u_int32_t ic_vhtop_ch_freq_seg1; /* Channel Center frequency */
+
+ /* Channel Center frequency applicable*/
+ u_int32_t ic_vhtop_ch_freq_seg2;
+};
+
+struct ieee80211_channel_list
+{
+ int cl_nchans;
+ struct ieee80211_channel *cl_channels[IEE80211_MAX_20M_SUB_CH];
+};
+
+struct ieee80211_dfs_state
+{
+ int nol_event[IEEE80211_CHAN_MAX];
+ os_timer_t nol_timer; /* NOL list processing */
+ os_timer_t cac_timer; /* CAC timer */
+ int cureps; /* current events/second */
+ const struct ieee80211_channel *lastchan; /* chan w/ last radar event */
+ struct ieee80211_channel *newchan; /* chan selected next */
+ /* overridden cac timeout */
+ int cac_timeout_override;
+ int8_t enable:1,
+ cac_timer_running:1,
+ ignore_dfs:1,
+ ignore_cac:1;
+};
+
+typedef struct ieee80211com
+{
+ void (*ic_start_csa)(struct ieee80211com *ic,u_int8_t ieeeChan);
+ void (*ic_get_ext_chan_info)(struct ieee80211com *ic,
+ struct ieee80211_channel_list *chan);
+ enum ieee80211_opmode ic_opmode; /* operation mode */
+ struct ieee80211_channel *(*ic_find_channel)(struct ieee80211com *ic,
+ int freq, u_int32_t flags);
+ u_int64_t (*ic_get_TSF64)(struct ieee80211com *ic);
+ unsigned int (*ic_ieee2mhz)(u_int chan, u_int flags);
+ struct ieee80211_channel ic_channels[IEEE80211_CHAN_MAX+1];
+ /* Number of Channels according to the Regulatory domain channels */
+ int ic_nchans;
+ struct ieee80211_channel *ic_curchan; /* current channel */
+ u_int8_t ic_isdfsregdomain; /* operating in DFS domain ? */
+ int (*ic_get_dfsdomain)(struct ieee80211com *);
+ u_int16_t (*ic_dfs_usenol)(struct ieee80211com *ic);
+ u_int16_t (*ic_dfs_isdfsregdomain)(struct ieee80211com *ic);
+ int (*ic_dfs_attached)(struct ieee80211com *ic);
+ void *ic_dfs;
+ struct ieee80211_dfs_state ic_dfs_state;
+ int (*ic_dfs_attach)(struct ieee80211com *ic,
+ void *pCap, void *radar_info);
+ int (*ic_dfs_detach)(struct ieee80211com *ic);
+ int (*ic_dfs_enable)(struct ieee80211com *ic, int *is_fastclk, void *);
+ int (*ic_dfs_disable)(struct ieee80211com *ic);
+ int (*ic_get_ext_busy)(struct ieee80211com *ic);
+ int (*ic_get_mib_cycle_counts_pct)(struct ieee80211com *ic,
+ u_int32_t *rxc_pcnt, u_int32_t *rxf_pcnt, u_int32_t *txf_pcnt);
+ int (*ic_dfs_get_thresholds)(struct ieee80211com *ic,void *pe);
+
+ int (*ic_dfs_debug)(struct ieee80211com *ic, int type, void *data);
+ /*
+ * Update the channel list with the current set of DFS
+ * NOL entries.
+ *
+ * + 'cmd' indicates what to do; for now it should just
+ * be DFS_NOL_CLIST_CMD_UPDATE which will update all
+ * channels, given the _entire_ NOL. (Rather than
+ * the earlier behaviour with clist_update, which
+ * was to either add or remove a set of channel
+ * entries.)
+ */
+ void (*ic_dfs_clist_update)(struct ieee80211com *ic, int cmd,
+ struct dfs_nol_chan_entry *, int nentries);
+ void (*ic_dfs_notify_radar)(struct ieee80211com *ic,
+ struct ieee80211_channel *chan);
+ void (*ic_dfs_unmark_radar)(struct ieee80211com *ic,
+ struct ieee80211_channel *chan);
+ int (*ic_dfs_control)(struct ieee80211com *ic,
+ u_int id, void *indata, u_int32_t insize,
+ void *outdata, u_int32_t *outsize);
+ HAL_DFS_DOMAIN current_dfs_regdomain;
+ u_int8_t vdev_id;
+ u_int8_t last_radar_found_chan;
+} IEEE80211COM, *PIEEE80211COM;
+
+/*
+ * Convert channel to frequency value.
+ */
+static INLINE u_int
+ieee80211_chan2freq(struct ieee80211com *ic,
+ const struct ieee80211_channel *c)
+{
+ if (c == NULL)
+ {
+ return 0;
+ }
+ return (c == IEEE80211_CHAN_ANYC ? IEEE80211_CHAN_ANY : c->ic_freq);
+}
diff --git a/CORE/SERVICES/COMMON/wmi_unified.h b/CORE/SERVICES/COMMON/wmi_unified.h
index 27f578c36dfc..594d6679dabe 100644
--- a/CORE/SERVICES/COMMON/wmi_unified.h
+++ b/CORE/SERVICES/COMMON/wmi_unified.h
@@ -331,7 +331,10 @@ typedef enum {
WMI_PDEV_DFS_ENABLE_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_DFS),
/** disable DFS (radar detection)*/
WMI_PDEV_DFS_DISABLE_CMDID,
-
+ /** enable DFS phyerr/parse filter offload */
+ WMI_DFS_PHYERR_FILTER_ENA_CMDID,
+ /** enable DFS phyerr/parse filter offload */
+ WMI_DFS_PHYERR_FILTER_DIS_CMDID,
/* Roaming specific commands */
/** set roam scan mode */
@@ -572,10 +575,6 @@ typedef enum {
/** Plumb routing table for multihop forwarding offload */
WMI_MHF_OFFLOAD_PLUMB_ROUTING_TBL_CMDID,
- /** enable DFS phyerr/parse filter offload */
- WMI_DFS_PHYERR_FILTER_ENA_CMDID,
- /** enable DFS phyerr/parse filter offload */
- WMI_DFS_PHYERR_FILTER_DIS_CMDID,
/*location scan commands*/
/*start batch scan*/
WMI_BATCH_SCAN_ENABLE_CMDID = WMI_CMD_GRP_START_ID(WMI_GRP_LOCATION_SCAN),
@@ -611,6 +610,9 @@ typedef enum {
/** traffic pause event */
WMI_TX_PAUSE_EVENTID,
+ /** DFS radar event */
+ WMI_DFS_RADAR_EVENTID,
+
/* VDEV specific events */
/** VDEV started event in response to VDEV_START request */
WMI_VDEV_START_RESP_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_VDEV),
@@ -757,9 +759,6 @@ typedef enum {
/* TDLS Event */
WMI_TDLS_PEER_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_TDLS),
- /** DFS radar event */
- WMI_DFS_RADAR_EVENTID,
-
/*location scan event*/
/*report the firmware's capability of batch scan*/
WMI_BATCH_SCAN_ENABLED_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_LOCATION_SCAN),
@@ -916,7 +915,7 @@ WMI_CHANNEL_CHANGE_CAUSE_CSA,
#define WMI_VHT_CAP_SU_BFORMER 0x00000800
#define WMI_VHT_CAP_SU_BFORMEE 0x00001000
#define WMI_VHT_CAP_MU_BFORMER 0x00080000
-#define WMI_VHT_CAP MU_BFORMEE 0x00100000
+#define WMI_VHT_CAP_MU_BFORMEE 0x00100000
/* These macros should be used when we wish to advertise STBC support for
* only 1SS or 2SS or 3SS. */
@@ -959,6 +958,13 @@ typedef struct _wmi_abi_version {
* maximum number of memroy requests allowed from FW.
*/
#define WMI_MAX_MEM_REQS 16
+
+/* !!NOTE!!:
+ * This HW_BD_INFO_SIZE cannot be changed without breaking compatibility.
+ * Please don't change it.
+ */
+#define HW_BD_INFO_SIZE 5
+
/**
* The following struct holds optional payload for
* wmi_service_ready_event_fixed_param,e.g., 11ac pass some of the
@@ -995,6 +1001,13 @@ typedef struct {
* setup.
*/
A_UINT32 max_num_scan_channels;
+
+ /* Hardware board specific ID. Values defined in enum WMI_HWBOARD_ID.
+ * Default 0 means tha hw_bd_info[] is invalid(legacy board).
+ */
+ A_UINT32 hw_bd_id;
+ A_UINT32 hw_bd_info[HW_BD_INFO_SIZE]; /* Board specific information. Invalid if hw_hd_id is zero. */
+
/* The TLVs for hal_reg_capabilities, wmi_service_bitmap and mem_reqs[] will follow this TLV.
* HAL_REG_CAPABILITIES hal_reg_capabilities;
* A_UINT32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE];
@@ -1002,6 +1015,48 @@ typedef struct {
*/
} wmi_service_ready_event_fixed_param;
+typedef enum {
+ WMI_HWBD_NONE = 0, /* No hw board information is given */
+ WMI_HWBD_QCA6174 = 1, /* Rome(AR6320) */
+ WMI_HWBD_QCA2582 = 2, /* Killer 1525*/
+} WMI_HWBD_ID;
+
+#define ATH_BD_DATA_REV_MASK 0x000000FF
+#define ATH_BD_DATA_REV_SHIFT 0
+
+#define ATH_BD_DATA_PROJ_ID_MASK 0x0000FF00
+#define ATH_BD_DATA_PROJ_ID_SHIFT 8
+
+#define ATH_BD_DATA_CUST_ID_MASK 0x00FF0000
+#define ATH_BD_DATA_CUST_ID_SHIFT 16
+
+#define ATH_BD_DATA_REF_DESIGN_ID_MASK 0xFF000000
+#define ATH_BD_DATA_REF_DESIGN_ID_SHIFT 24
+
+#define SET_BD_DATA_REV(bd_data_ver, value) \
+ ((bd_data_ver) &= ~ATH_BD_DATA_REV_MASK, (bd_data_ver) |= ((value) << ATH_BD_DATA_REV_SHIFT))
+
+#define GET_BD_DATA_REV(bd_data_ver) \
+ (((bd_data_ver) & ATH_BD_DATA_REV_MASK) >> ATH_BD_DATA_REV_SHIFT)
+
+#define SET_BD_DATA_PROJ_ID(bd_data_ver, value) \
+ ((bd_data_ver) &= ~ATH_BD_DATA_PROJ_ID_MASK, (bd_data_ver) |= ((value) << ATH_BD_DATA_PROJ_ID_SHIFT))
+
+#define GET_BD_DATA_PROJ_ID(bd_data_ver) \
+ (((bd_data_ver) & ATH_BD_DATA_PROJ_ID_MASK) >> ATH_BD_DATA_PROJ_ID_SHIFT)
+
+#define SET_BD_DATA_CUST_ID(bd_data_ver, value) \
+ ((bd_data_ver) &= ~ATH_BD_DATA_CUST_ID_MASK, (bd_data_ver) |= ((value) << ATH_BD_DATA_CUST_ID_SHIFT))
+
+#define GET_BD_DATA_CUST_ID(bd_data_ver) \
+ (((bd_data_ver) & ATH_BD_DATA_CUST_ID_MASK) >> ATH_BD_DATA_CUST_ID_SHIFT)
+
+#define SET_BD_DATA_REF_DESIGN_ID(bd_data_ver, value) \
+ ((bd_data_ver) &= ~ATH_BD_DATA_REF_DESIGN_ID_MASK, (bd_data_ver) |= ((value) << ATH_BD_DATA_REF_DESIGN_ID_SHIFT))
+
+#define GET_BD_DATA_REF_DESIGN_ID(bd_data_ver) \
+ (((bd_data_ver) & ATH_BD_DATA_REF_DESIGN_ID_MASK) >> ATH_BD_DATA_REF_DESIGN_ID_SHIFT)
+
#ifdef ROME_LTE_COEX_FREQ_AVOID
typedef struct {
A_UINT32 start_freq; //start frequency, not channel center freq
@@ -3205,6 +3260,17 @@ typedef struct {
* Number of TX frames before the entering the Active state
*/
WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE = 7,
+
+ /**
+ * QPower SPEC PSPOLL interval
+ */
+ WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL = 8,
+
+ /**
+ * Max SPEC PSPOLL to be sent when the PSPOLL response has
+ * no-data bit set
+ */
+ WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL = 9,
};
typedef struct {
@@ -3782,6 +3848,7 @@ typedef struct {
#define WMI_PEER_PMF 0x08000000 /* Robust Management Frame Protection enabled */
/** CAUTION TODO: Place holder for WLAN_PEER_F_PS_PRESEND_REQUIRED = 0x10000000. Need to be clean up */
#define WMI_PEER_IS_P2P_CAPABLE 0x20000000 /* P2P capable peer */
+#define WMI_PEER_SAFEMODE_EN 0x80000000 /* Fips Mode Enabled */
/**
* Peer rate capabilities.
@@ -5410,7 +5477,9 @@ typedef struct {
A_UINT32 tlv_header; /* TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_gtk_rekey_fail_event_fixed_param */
/** Reserved for future use */
A_UINT32 reserved0;
+ A_UINT32 vdev_id;
} wmi_gtk_rekey_fail_event_fixed_param;
+
enum wmm_ac_downgrade_policy {
WMM_AC_DOWNGRADE_DEPRIO,
WMM_AC_DOWNGRADE_DROP,
@@ -5685,7 +5754,6 @@ typedef struct {
typedef struct {
/** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_resmgr_adaptive_ocs_enable_disable_cmd_fixed_param */
A_UINT32 tlv_header;
- A_UINT32 reserved0;
/** 1: enable fw based adaptive ocs,
* 0: disable fw based adaptive ocs
*/
diff --git a/CORE/SERVICES/COMMON/wmi_version.h b/CORE/SERVICES/COMMON/wmi_version.h
index 628dee99277a..04d63e61281d 100644
--- a/CORE/SERVICES/COMMON/wmi_version.h
+++ b/CORE/SERVICES/COMMON/wmi_version.h
@@ -35,7 +35,7 @@
#define __WMI_VER_MINOR_ 0
/** WMI revision number has to be incremented when there is a
* change that may or may not break compatibility. */
-#define __WMI_REVISION_ 30
+#define __WMI_REVISION_ 31
/** The Version Namespace should not be normally changed. Only
* host and firmware of the same WMI namespace will work
diff --git a/CORE/SERVICES/DFS/inc/ath_dfs_structs.h b/CORE/SERVICES/DFS/inc/ath_dfs_structs.h
new file mode 100644
index 000000000000..d85ba50fcd54
--- /dev/null
+++ b/CORE/SERVICES/DFS/inc/ath_dfs_structs.h
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ ath_dfs_structs.h
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+
+
+#ifndef _DFS__STRUCTS_H_
+#define _DFS__STRUCTS_H_
+#include <adf_os_mem.h>
+
+#ifdef ANDROID
+#include <linux/string.h>
+#endif
+
+/*
+ * For the dfs_nol_clist_update() method - this is the
+ * update command.
+ */
+enum {
+ DFS_NOL_CLIST_CMD_NONE = 0x0,
+ DFS_NOL_CLIST_CMD_UPDATE = 0x1,
+};
+
+struct ath_dfs_caps {
+ u_int32_t
+ ath_dfs_ext_chan_ok:1, /* Can radar be detected on the extension chan? */
+ ath_dfs_combined_rssi_ok:1, /* Can use combined radar RSSI? */
+ /* the following flag is used to indicate if radar detection scheme */
+ /* should use enhanced chirping detection algorithm. This flag also */
+ /* determines if certain radar data should be discarded to minimize */
+ /* false detection of radar. */
+ ath_dfs_use_enhancement:1,
+ ath_strong_signal_diversiry:1,
+ ath_chip_is_bb_tlv:1;
+
+ /*
+ * goes with ath_strong_signal_diversiry:
+ * If we have fast diversity capability, read off
+ * Strong Signal fast diversity count set in the ini
+ * file, and store so we can restore the value when
+ * radar is disabled
+ */
+ u_int32_t ath_fastdiv_val;
+};
+
+/*
+ * These are defined in the HAL for now, and must be migrated outside
+ * of there in order to be used by the new partial offload data path.
+ */
+
+struct dfs_pulse {
+ u_int32_t rp_numpulses; /* Num of pulses in radar burst */
+ u_int32_t rp_pulsedur; /* Duration of each pulse in usecs */
+ u_int32_t rp_pulsefreq; /* Frequency of pulses in burst */
+ u_int32_t rp_max_pulsefreq; /* Frequency of pulses in burst */
+ u_int32_t rp_patterntype; /* fixed or variable pattern type*/
+ u_int32_t rp_pulsevar; /* Time variation of pulse duration for
+ matched filter (single-sided) in usecs */
+ u_int32_t rp_threshold; /* Threshold for MF output to indicateC
+ radar match */
+ u_int32_t rp_mindur; /* Min pulse duration to be considered for
+ this pulse type */
+ u_int32_t rp_maxdur; /* Max pusle duration to be considered for
+ this pulse type */
+ u_int32_t rp_rssithresh; /* Minimum rssi to be considered a radar pulse */
+ u_int32_t rp_meanoffset; /* Offset for timing adjustment */
+ int32_t rp_rssimargin; /* rssi threshold margin. In Turbo Mode HW reports rssi 3dBm */
+ /* lower than in non TURBO mode. This will be used to offset that diff.*/
+ u_int32_t rp_ignore_pri_window;
+ u_int32_t rp_pulseid; /* Unique ID for identifying filter */
+};
+
+struct dfs_staggered_pulse {
+ u_int32_t rp_numpulses; /* Num of pulses in radar burst */
+ u_int32_t rp_pulsedur; /* Duration of each pulse in usecs */
+ u_int32_t rp_min_pulsefreq; /* Frequency of pulses in burst */
+ u_int32_t rp_max_pulsefreq; /* Frequency of pulses in burst */
+ u_int32_t rp_patterntype; /* fixed or variable pattern type*/
+ u_int32_t rp_pulsevar; /* Time variation of pulse duration for
+ matched filter (single-sided) in usecs */
+ u_int32_t rp_threshold; /* Thershold for MF output to indicateC
+ radar match */
+ u_int32_t rp_mindur; /* Min pulse duration to be considered for
+ this pulse type */
+ u_int32_t rp_maxdur; /* Max pusle duration to be considered for
+ this pulse type */
+ u_int32_t rp_rssithresh; /* Minimum rssi to be considered a radar pulse */
+ u_int32_t rp_meanoffset; /* Offset for timing adjustment */
+ int32_t rp_rssimargin; /* rssi threshold margin. In Turbo Mode HW reports rssi 3dBm */
+ /* lower than in non TURBO mode. This will be used to offset that diff.*/
+ u_int32_t rp_pulseid; /* Unique ID for identifying filter */
+};
+
+struct dfs_bin5pulse {
+ u_int32_t b5_threshold; /* Number of bin5 pulses to indicate detection */
+ u_int32_t b5_mindur; /* Min duration for a bin5 pulse */
+ u_int32_t b5_maxdur; /* Max duration for a bin5 pulse */
+ u_int32_t b5_timewindow; /* Window over which to count bin5 pulses */
+ u_int32_t b5_rssithresh; /* Min rssi to be considered a pulse */
+ u_int32_t b5_rssimargin; /* rssi threshold margin. In Turbo Mode HW reports rssi 3dB */
+};
+
+/*
+ * DFS NOL representation.
+ *
+ * This is used to represent the DFS NOL information between the
+ * NOL code in lmac/dfs/dfs_nol.c and any driver layer wishing
+ * to use it.
+ */
+struct dfs_nol_chan_entry {
+ u_int32_t nol_chfreq; /* Centre frequency, MHz */
+ u_int32_t nol_chwidth; /* Width, MHz */
+ unsigned long nol_start_ticks; /* start ticks, OS specific */
+ u_int32_t nol_timeout_ms; /* timeout, mS */
+};
+
+//HAL_PHYERR_PARAM;
+
+/*
+ * This represents the general case of the radar PHY configuration,
+ * across all chips.
+ *
+ * It's then up to each chip layer to translate to/from this
+ * (eg to HAL_PHYERR_PARAM for the HAL case.)
+ */
+
+#define ATH_DFS_PHYERR_PARAM_NOVAL 0xFFFF
+#define ATH_DFS_PHYERR_PARAM_ENABLE 0x8000
+
+struct ath_dfs_phyerr_param {
+ int32_t pe_firpwr; /* FIR pwr out threshold */
+ int32_t pe_rrssi; /* Radar rssi thresh */
+ int32_t pe_height; /* Pulse height thresh */
+ int32_t pe_prssi; /* Pulse rssi thresh */
+ int32_t pe_inband; /* Inband thresh */
+
+ /* The following params are only for AR5413 and later */
+ /*
+ * Relative power threshold in 0.5dB steps
+ */
+ u_int32_t pe_relpwr;
+
+ /*
+ * Pulse Relative step threshold in 0.5dB steps
+ */
+ u_int32_t pe_relstep;
+
+ /*
+ * Max length of radar sign in 0.8us units
+ */
+ u_int32_t pe_maxlen;
+
+ /*
+ * Use the average in-band power measured over 128 cycles
+ */
+ bool pe_usefir128;
+
+ /*
+ * Enable to block radar check if pkt detect is done via OFDM
+ * weak signal detect or pkt is detected immediately after tx
+ * to rx transition
+ */
+ bool pe_blockradar;
+
+ /*
+ * Enable to use the max rssi instead of the last rssi during
+ * fine gain changes for radar detection
+ */
+ bool pe_enmaxrssi;
+};
+
+static inline void ath_dfs_phyerr_param_copy(struct ath_dfs_phyerr_param *dst,
+ struct ath_dfs_phyerr_param *src)
+{
+ adf_os_mem_copy(dst, src, sizeof(*dst));
+}
+
+static inline void ath_dfs_phyerr_init_noval(struct ath_dfs_phyerr_param *pe)
+{
+ pe->pe_firpwr = ATH_DFS_PHYERR_PARAM_NOVAL;
+ pe->pe_rrssi = ATH_DFS_PHYERR_PARAM_NOVAL;
+ pe->pe_height = ATH_DFS_PHYERR_PARAM_NOVAL;
+ pe->pe_prssi = ATH_DFS_PHYERR_PARAM_NOVAL;
+ pe->pe_inband = ATH_DFS_PHYERR_PARAM_NOVAL;
+ pe->pe_relpwr = ATH_DFS_PHYERR_PARAM_NOVAL;
+ pe->pe_relstep = ATH_DFS_PHYERR_PARAM_NOVAL;
+ pe->pe_maxlen = ATH_DFS_PHYERR_PARAM_NOVAL;
+
+ /* XXX what about usefir128, blockradar, enmaxrssi? */
+}
+
+struct ath_dfs_radar_tab_info {
+ u_int32_t dfsdomain;
+ int numradars;
+ struct dfs_pulse *dfs_radars;
+ int numb5radars;
+ struct dfs_bin5pulse *b5pulses;
+ struct ath_dfs_phyerr_param dfs_defaultparams;
+};
+#endif /* _DFS__STRUCTS_H_ */
diff --git a/CORE/SERVICES/DFS/inc/dfs_interface.h b/CORE/SERVICES/DFS/inc/dfs_interface.h
new file mode 100644
index 000000000000..bd13f9eaec45
--- /dev/null
+++ b/CORE/SERVICES/DFS/inc/dfs_interface.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ dfs_interface.h
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+#ifndef _DFS__INTERFACE_H_
+#define _DFS__INTERFACE_H_
+
+/*
+ * These are the only functions exported to the upper (device) layer.
+ */
+
+/*
+ * EXPORT_SYMBOL(dfs_attach);
+ * EXPORT_SYMBOL(dfs_detach);
+ * EXPORT_SYMBOL(dfs_radar_enable);
+ * EXPORT_SYMBOL(dfs_process_phyerr);
+ * EXPORT_SYMBOL(dfs_control);
+ * EXPORT_SYMBOL(dfs_clear_stats);
+ * EXPORT_SYMBOL(dfs_usenol);
+ * EXPORT_SYMBOL(dfs_isdfsregdomain);
+ */
+
+/*
+ * These are exported but not currently defined here; these should be
+ * evaluated.
+ *
+ * EXPORT_SYMBOL(dfs_process_ar_event); -- legacy adaptive radio processing
+ * EXPORT_SYMBOL(ath_ar_disable);
+ * EXPORT_SYMBOL(ath_ar_enable);
+ * EXPORT_SYMBOL(dfs_get_thresholds);
+ * EXPORT_SYMBOL(dfs_init_radar_filters);
+ * EXPORT_SYMBOL(dfs_getchanstate);
+ */
+
+
+u_int16_t dfs_isdfsregdomain(struct ieee80211com *ic);
+int dfs_attach(struct ieee80211com *ic);
+void dfs_detach(struct ieee80211com *ic);
+int dfs_radar_enable(struct ieee80211com *ic,
+ struct ath_dfs_radar_tab_info *ri);
+int dfs_radar_disable(struct ieee80211com *ic);
+extern void dfs_process_phyerr(struct ieee80211com *ic, void *buf, u_int16_t datalen, u_int8_t rssi,
+ u_int8_t ext_rssi, u_int32_t rs_tstamp, u_int64_t fulltsf);
+int dfs_control(struct ieee80211com *ic, u_int id, void *indata, u_int32_t insize,
+ void *outdata, u_int32_t *outsize);
+void dfs_clear_stats(struct ieee80211com *ic);
+#if 0
+/* The following are for FCC Bin 1-4 pulses */
+struct dfs_pulse dfs_fcc_radars[] = {
+ // FCC TYPE 1
+ // {18, 1, 325, 1930, 0, 6, 7, 0, 1, 18, 0, 3, 0}, // 518 to 3066
+ {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0},
+ {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0},
+
+ // FCC TYPE 6
+ // {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1}, // 333 +/- 7 us
+ {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1},
+
+ // FCC TYPE 2
+ {23, 5, 4347, 6666, 0, 18, 11, 0, 7, 22, 0, 3, 0, 2},
+
+ // FCC TYPE 3
+ {18, 10, 2000, 5000, 0, 23, 8, 6, 13, 22, 0, 3, 0, 5},
+
+ // FCC TYPE 4
+ {16, 15, 2000, 5000, 0, 25, 7, 11, 23, 22, 0, 3, 0, 11},
+};
+
+struct dfs_pulse dfs_mkk4_radars[] = {
+ /* following two filters are specific to Japan/MKK4 */
+// {18, 1, 720, 720, 1, 6, 6, 0, 1, 18, 0, 3, 17}, // 1389 +/- 6 us
+// {18, 4, 250, 250, 1, 10, 5, 1, 6, 18, 0, 3, 18}, // 4000 +/- 6 us
+// {18, 5, 260, 260, 1, 10, 6, 1, 6, 18, 0, 3, 19}, // 3846 +/- 7 us
+ {18, 1, 720, 720, 0, 6, 6, 0, 1, 18, 0, 3, 0, 17}, // 1389 +/- 6 us
+ {18, 4, 250, 250, 0, 10, 5, 1, 6, 18, 0, 3, 0, 18}, // 4000 +/- 6 us
+ {18, 5, 260, 260, 0, 10, 6, 1, 6, 18, 0, 3, 1, 19}, // 3846 +/- 7 us
+
+ /* following filters are common to both FCC and JAPAN */
+
+ // FCC TYPE 1
+ // {18, 1, 325, 1930, 0, 6, 7, 0, 1, 18, 0, 3, 0}, // 518 to 3066
+ {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0},
+ {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0},
+
+ // FCC TYPE 6
+ // {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1}, // 333 +/- 7 us
+ {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1},
+
+ // FCC TYPE 2
+ {23, 5, 4347, 6666, 0, 18, 11, 0, 7, 22, 0, 3, 0, 2},
+
+ // FCC TYPE 3
+ {18, 10, 2000, 5000, 0, 23, 8, 6, 13, 22, 0, 3, 0, 5},
+
+ // FCC TYPE 4
+ {16, 15, 2000, 5000, 0, 25, 7, 11, 23, 22, 0, 3, 0, 11},
+};
+
+struct dfs_bin5pulse dfs_fcc_bin5pulses[] = {
+ {4, 28, 105, 12, 22, 5},
+};
+
+struct dfs_bin5pulse dfs_jpn_bin5pulses[] = {
+ {5, 28, 105, 12, 22, 5},
+};
+struct dfs_pulse dfs_etsi_radars[] = {
+
+ /* TYPE staggered pulse */
+ /* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */
+ {30, 2, 300, 400, 2, 30, 3, 0, 5, 15, 0, 0, 1, 31}, /* Type 5*/
+ /* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */
+ {30, 2, 400, 1200, 2, 30, 7, 0, 5, 15, 0, 0, 0, 32}, /* Type 6 */
+
+ /* constant PRF based */
+ /* 0.8-5us, 200 300 PRF, 10 pulses */
+ {10, 5, 200, 400, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33}, /* Type 1 */
+ {10, 5, 400, 600, 0, 24, 5, 0, 8, 15, 0, 0, 2, 37}, /* Type 1 */
+ {10, 5, 600, 800, 0, 24, 5, 0, 8, 15, 0, 0, 2, 38}, /* Type 1 */
+ {10, 5, 800, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 39}, /* Type 1 */
+// {10, 5, 200, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33},
+
+ /* 0.8-15us, 200-1600 PRF, 15 pulses */
+ {15, 15, 200, 1600, 0, 24, 8, 0, 18, 24, 0, 0, 0, 34}, /* Type 2 */
+
+ /* 0.8-15us, 2300-4000 PRF, 25 pulses*/
+ {25, 15, 2300, 4000, 0, 24, 10, 0, 18, 24, 0, 0, 0, 35}, /* Type 3 */
+
+ /* 20-30us, 2000-4000 PRF, 20 pulses*/
+ {20, 30, 2000, 4000, 0, 24, 6, 19, 33, 24, 0, 0, 0, 36}, /* Type 4 */
+};
+#endif
+#endif /* _DFS__INTERFACE_H_ */
diff --git a/CORE/SERVICES/DFS/inc/radar_filters.h b/CORE/SERVICES/DFS/inc/radar_filters.h
new file mode 100644
index 000000000000..33ca999f47fe
--- /dev/null
+++ b/CORE/SERVICES/DFS/inc/radar_filters.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ radar_filters.h
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+
+
+
+
+struct dfs_pulse dfs_fcc_radars[] = {
+ // FCC TYPE 1
+ // {18, 1, 325, 1930, 0, 6, 7, 0, 1, 18, 0, 3, 0}, // 518 to 3066
+ {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0},
+ {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0},
+
+ // FCC TYPE 6
+ // {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1}, // 333 +/- 7 us
+ {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1},
+
+ // FCC TYPE 2
+ {23, 5, 4347, 6666, 0, 18, 11, 0, 7, 22, 0, 3, 0, 2},
+
+ // FCC TYPE 3
+ {18, 10, 2000, 5000, 0, 23, 8, 6, 13, 22, 0, 3, 0, 5},
+
+ // FCC TYPE 4
+ {16, 15, 2000, 5000, 0, 25, 7, 11, 23, 22, 0, 3, 0, 11},
+};
+
+struct dfs_pulse dfs_mkk4_radars[] = {
+ /* following two filters are specific to Japan/MKK4 */
+// {18, 1, 720, 720, 1, 6, 6, 0, 1, 18, 0, 3, 17}, // 1389 +/- 6 us
+// {18, 4, 250, 250, 1, 10, 5, 1, 6, 18, 0, 3, 18}, // 4000 +/- 6 us
+// {18, 5, 260, 260, 1, 10, 6, 1, 6, 18, 0, 3, 19}, // 3846 +/- 7 us
+ {18, 1, 720, 720, 0, 6, 6, 0, 1, 18, 0, 3, 0, 17}, // 1389 +/- 6 us
+ {18, 4, 250, 250, 0, 10, 5, 1, 6, 18, 0, 3, 0, 18}, // 4000 +/- 6 us
+ {18, 5, 260, 260, 0, 10, 6, 1, 6, 18, 0, 3, 1, 19}, // 3846 +/- 7 us
+
+ /* following filters are common to both FCC and JAPAN */
+
+ // FCC TYPE 1
+ // {18, 1, 325, 1930, 0, 6, 7, 0, 1, 18, 0, 3, 0}, // 518 to 3066
+ {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 0},
+ {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0},
+
+ // FCC TYPE 6
+ // {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1}, // 333 +/- 7 us
+ {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1, 1},
+
+ // FCC TYPE 2
+ {23, 5, 4347, 6666, 0, 18, 11, 0, 7, 22, 0, 3, 0, 2},
+
+ // FCC TYPE 3
+ {18, 10, 2000, 5000, 0, 23, 8, 6, 13, 22, 0, 3, 0, 5},
+
+ // FCC TYPE 4
+ {16, 15, 2000, 5000, 0, 25, 7, 11, 23, 22, 0, 3, 0, 11},
+};
+
+struct dfs_bin5pulse dfs_fcc_bin5pulses[] = {
+ {4, 28, 105, 12, 22, 5},
+};
+
+struct dfs_bin5pulse dfs_jpn_bin5pulses[] = {
+ {5, 28, 105, 12, 22, 5},
+};
+struct dfs_pulse dfs_etsi_radars[] = {
+
+ /* TYPE staggered pulse */
+ /* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */
+ {30, 2, 300, 400, 2, 30, 3, 0, 5, 15, 0, 0, 1, 31}, /* Type 5*/
+ /* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */
+ {30, 2, 400, 1200, 2, 30, 7, 0, 5, 15, 0, 0, 0, 32}, /* Type 6 */
+
+ /* constant PRF based */
+ /* 0.8-5us, 200 300 PRF, 10 pulses */
+ {10, 5, 200, 400, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33}, /* Type 1 */
+ {10, 5, 400, 600, 0, 24, 5, 0, 8, 15, 0, 0, 2, 37}, /* Type 1 */
+ {10, 5, 600, 800, 0, 24, 5, 0, 8, 15, 0, 0, 2, 38}, /* Type 1 */
+ {10, 5, 800, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 39}, /* Type 1 */
+// {10, 5, 200, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33},
+
+ /* 0.8-15us, 200-1600 PRF, 15 pulses */
+ {15, 15, 200, 1600, 0, 24, 8, 0, 18, 24, 0, 0, 0, 34}, /* Type 2 */
+
+ /* 0.8-15us, 2300-4000 PRF, 25 pulses*/
+ {25, 15, 2300, 4000, 0, 24, 10, 0, 18, 24, 0, 0, 0, 35}, /* Type 3 */
+
+ /* 20-30us, 2000-4000 PRF, 20 pulses*/
+ {20, 30, 2000, 4000, 0, 24, 6, 19, 33, 24, 0, 0, 0, 36}, /* Type 4 */
+};
diff --git a/CORE/SERVICES/DFS/sources b/CORE/SERVICES/DFS/sources
new file mode 100644
index 000000000000..cf81004d198a
--- /dev/null
+++ b/CORE/SERVICES/DFS/sources
@@ -0,0 +1,64 @@
+#
+# sources file for DFS module
+#
+LMAC=..
+TOP=$(LMAC)\..
+INC=$(TOP)\include
+HAL=$(TOP)\hal
+ATH=$(LMAC)\ath_dev
+
+!IFDEF BUILD_UMAC
+MP=$(TOP)\os\win_nwf
+INC_MP=$(MP)\include
+IF_ATH=$(TOP)\umac\if_lmac
+!ELSE
+MP=$(TOP)\winvista
+INC_MP=$(INC)\winvista
+IF_ATH=$(TOP)\if_ath_net80211
+!ENDIF
+
+!include $(INC_MP)\sources.inc
+
+TARGETNAME=ath_dfs
+TARGETPATH=$(TOP)\lib
+TARGETTYPE=LIBRARY
+
+!IFDEF BUILD_HTC
+# Put htc include dirs at the head of the list.
+# This ensures that the htc/adf header files will preempt any
+# header files of the same names from the regular adf directories.
+INCLUDES= $(INCLUDES) \
+ $(TOP)\htc\inc; \
+ $(TOP)\htc\adf\include; \
+ $(TOP)\htc\adf\winvista\nbuf; \
+ $(TOP)\htc\adf\winvista\include;
+!ENDIF
+
+INCLUDES= $(INCLUDES) \
+ $(TOP); \
+ $(ATH); \
+ $(ATH_DFS); \
+ $(TOP)\ath\winvista; \
+ $(TOP)\ath\winvista; \
+ $(HAL); \
+ $(HAL)\winvista; \
+ $(IF_ATH); \
+ $(INC); \
+ $(INC_MP); \
+ $(SDXROOT)\net\inc; \
+ $(DDK_INC_PATH)
+
+SOURCES=$(SOURCES) \
+ dfs_staggered.c \
+ dfs_bindetects.c \
+ dfs_misc.c \
+ dfs_debug.c \
+ dfs_process_radarevent.c \
+ dfs_process_phyerr.c \
+ dfs_nol.c \
+ dfs_ar.c \
+ dfs_fcc_bin5.c \
+ dfs_init.c \
+ dfs.c
+
+
diff --git a/CORE/SERVICES/DFS/src/dfs.c b/CORE/SERVICES/DFS/src/dfs.c
new file mode 100644
index 000000000000..9e2cf985ec35
--- /dev/null
+++ b/CORE/SERVICES/DFS/src/dfs.c
@@ -0,0 +1,976 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ dfs.c
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+
+#include <osdep.h>
+
+#ifndef ATH_SUPPORT_DFS
+#define ATH_SUPPORT_DFS 1
+#include "sys/queue.h"
+
+//#include "if_athioctl.h"
+//#include "if_athvar.h"
+#include "dfs_ioctl.h"
+#include "dfs.h"
+
+int domainoverride=DFS_UNINIT_DOMAIN;
+
+/*
+ ** channel switch announcement (CSA)
+ ** usenol=1 (default) make CSA and switch to a new channel on radar detect
+ ** usenol=0, make CSA with next channel same as current on radar detect
+ ** usenol=2, no CSA and stay on the same channel on radar detect
+ **/
+
+int usenol=1;
+u_int32_t dfs_debug_level=ATH_DEBUG_DFS;
+
+/*
+ * Mark a channel as having interference detected upon it.
+ *
+ * This adds the interference marker to both the primary and
+ * extension channel.
+ *
+ * XXX TODO: make the NOL and channel interference logic a bit smarter
+ * so only the channel with the radar event is marked, rather than
+ * both the primary and extension.
+ */
+static void
+dfs_channel_mark_radar(struct ath_dfs *dfs, struct ieee80211_channel *chan)
+{
+ struct ieee80211_channel_list chan_info;
+ int i;
+
+ //chan->ic_flagext |= CHANNEL_INTERFERENCE;
+
+ /*
+ * If radar is detected in 40MHz mode, add both the primary and the
+ * extension channels to the NOL. chan is the channel data we return
+ * to the ath_dev layer which passes it on to the 80211 layer.
+ * As we want the AP to change channels and send out a CSA,
+ * we always pass back the primary channel data to the ath_dev layer.
+ */
+ if ((dfs->dfs_rinfo.rn_use_nol == 1) &&
+ (dfs->ic->ic_opmode == IEEE80211_M_HOSTAP ||
+ dfs->ic->ic_opmode == IEEE80211_M_IBSS)) {
+ chan_info.cl_nchans= 0;
+ dfs->ic->ic_get_ext_chan_info (dfs->ic, &chan_info);
+
+ for (i = 0; i < chan_info.cl_nchans; i++)
+ {
+ if (chan_info.cl_channels[i] == NULL) {
+ DFS_PRINTK("%s: NULL channel\n", __func__);
+ } else {
+ chan_info.cl_channels[i]->ic_flagext |= CHANNEL_INTERFERENCE;
+ dfs_nol_addchan(dfs, chan_info.cl_channels[i], dfs->ath_dfs_nol_timeout);
+ }
+ }
+
+
+ /*
+ * Update the umac/driver channels with the new NOL information.
+ */
+ dfs_nol_update(dfs);
+ }
+}
+
+
+static OS_TIMER_FUNC(dfs_task)
+{
+ struct ieee80211com *ic;
+ struct ath_dfs *dfs = NULL;
+
+ OS_GET_TIMER_ARG(ic, struct ieee80211com *);
+ dfs = (struct ath_dfs *)ic->ic_dfs;
+ /*
+ * XXX no locking?!
+ */
+ if (dfs_process_radarevent(dfs, ic->ic_curchan)) {
+#ifndef ATH_DFS_RADAR_DETECTION_ONLY
+
+ /*
+ * This marks the channel (and the extension channel, if HT40) as
+ * having seen a radar event. It marks CHAN_INTERFERENCE and
+ * will add it to the local NOL implementation.
+ *
+ * This is only done for 'usenol=1', as the other two modes
+ * don't do radar notification or CAC/CSA/NOL; it just notes
+ * there was a radar.
+ */
+
+ if (dfs->dfs_rinfo.rn_use_nol == 1) {
+ //dfs_channel_mark_radar(dfs, ic->ic_curchan);
+ }
+#endif /* ATH_DFS_RADAR_DETECTION_ONLY */
+
+ /*
+ * This calls into the umac DFS code, which sets the umac related
+ * radar flags and begins the channel change machinery.
+ *
+ * XXX TODO: the umac NOL code isn't used, but IEEE80211_CHAN_RADAR
+ * still gets set. Since the umac NOL code isn't used, that flag
+ * is never cleared. This needs to be fixed. See EV 105776.
+ */
+ if (dfs->dfs_rinfo.rn_use_nol == 1) {
+ ic->ic_dfs_notify_radar(ic, ic->ic_curchan);
+ } else if (dfs->dfs_rinfo.rn_use_nol == 0) {
+ /*
+ * For the test mode, don't do a CSA here; but setup the
+ * test timer so we get a CSA _back_ to the original channel.
+ */
+ OS_CANCEL_TIMER(&dfs->ath_dfstesttimer);
+ dfs->ath_dfstest = 1;
+ dfs->ath_dfstest_ieeechan = ic->ic_curchan->ic_ieee;
+ dfs->ath_dfstesttime = 1; /* 1ms */
+ OS_SET_TIMER(&dfs->ath_dfstesttimer, dfs->ath_dfstesttime);
+ }
+ }
+ dfs->ath_radar_tasksched = 0;
+}
+
+static
+OS_TIMER_FUNC(dfs_testtimer_task)
+{
+ struct ieee80211com *ic;
+ struct ath_dfs *dfs = NULL;
+
+ OS_GET_TIMER_ARG(ic, struct ieee80211com *);
+ dfs = (struct ath_dfs *)ic->ic_dfs;
+
+ /* XXX no locking? */
+ dfs->ath_dfstest = 0;
+
+ /*
+ * Flip the channel back to the original channel.
+ * Make sure this is done properly with a CSA.
+ */
+ DFS_PRINTK("%s: go back to channel %d\n",
+ __func__,
+ dfs->ath_dfstest_ieeechan);
+
+ /*
+ * XXX The mere existence of this method indirection
+ * to a umac function means this code belongs in
+ * the driver, _not_ here. Please fix this!
+ */
+ ic->ic_start_csa(ic, dfs->ath_dfstest_ieeechan);
+}
+
+
+static int dfs_get_debug_info(struct ieee80211com *ic, int type, void *data)
+{
+ struct ath_dfs *dfs=(struct ath_dfs *)ic->ic_dfs;
+ if (data) {
+ *(u_int32_t *)data = dfs->dfs_proc_phyerr;
+ }
+ return (int)dfs->dfs_proc_phyerr;
+}
+
+
+int
+dfs_attach(struct ieee80211com *ic)
+{
+ int i, n;
+ struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs;
+ struct ath_dfs_radar_tab_info radar_info;
+#define N(a) (sizeof(a)/sizeof(a[0]))
+
+ if (dfs != NULL) {
+ /*DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
+ "%s: ic_dfs was not NULL\n",
+ __func__);
+ */
+ return 1;
+ }
+
+ dfs = (struct ath_dfs *)OS_MALLOC(NULL, sizeof(struct ath_dfs), GFP_ATOMIC);
+
+
+ if (dfs == NULL) {
+ /*DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
+ "%s: ath_dfs allocation failed\n", __func__);*/
+ return 1;
+ }
+
+ OS_MEMZERO(dfs, sizeof (struct ath_dfs));
+
+ ic->ic_dfs = (void *)dfs;
+
+ dfs->ic = ic;
+
+ ic->ic_dfs_debug = dfs_get_debug_info;
+#ifndef ATH_DFS_RADAR_DETECTION_ONLY
+ dfs->dfs_nol = NULL;
+#endif
+
+ /*
+ * Zero out radar_info. It's possible that the attach function won't
+ * fetch an initial regulatory configuration; you really do want to
+ * ensure that the contents indicates there aren't any filters.
+ */
+ OS_MEMZERO(&radar_info, sizeof(radar_info));
+ ic->ic_dfs_attach(ic, &dfs->dfs_caps, &radar_info);
+ dfs_clear_stats(ic);
+ dfs->dfs_event_log_on = 0;
+ OS_INIT_TIMER(NULL, &(dfs->ath_dfs_task_timer), dfs_task, (void *) (ic));
+#ifndef ATH_DFS_RADAR_DETECTION_ONLY
+ OS_INIT_TIMER(NULL, &(dfs->ath_dfstesttimer), dfs_testtimer_task,
+ (void *) ic);
+ dfs->ath_dfs_cac_time = ATH_DFS_WAIT_MS;
+ dfs->ath_dfstesttime = ATH_DFS_TEST_RETURN_PERIOD_MS;
+#endif
+ ATH_DFSQ_LOCK_INIT(dfs);
+ STAILQ_INIT(&dfs->dfs_radarq);
+ ATH_ARQ_LOCK_INIT(dfs);
+ STAILQ_INIT(&dfs->dfs_arq);
+ STAILQ_INIT(&(dfs->dfs_eventq));
+ ATH_DFSEVENTQ_LOCK_INIT(dfs);
+ dfs->events = (struct dfs_event *)OS_MALLOC(NULL,
+ sizeof(struct dfs_event)*DFS_MAX_EVENTS,
+ GFP_ATOMIC);
+ if (dfs->events == NULL) {
+ OS_FREE(dfs);
+ ic->ic_dfs = NULL;
+ DFS_PRINTK("%s: events allocation failed\n", __func__);
+ return 1;
+ }
+ for (i = 0; i < DFS_MAX_EVENTS; i++) {
+ STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), &dfs->events[i], re_list);
+ }
+
+ dfs->pulses = (struct dfs_pulseline *)OS_MALLOC(NULL, sizeof(struct dfs_pulseline), GFP_ATOMIC);
+ if (dfs->pulses == NULL) {
+ OS_FREE(dfs->events);
+ dfs->events = NULL;
+ OS_FREE(dfs);
+ ic->ic_dfs = NULL;
+ DFS_PRINTK("%s: pulse buffer allocation failed\n", __func__);
+ return 1;
+ }
+
+ dfs->pulses->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK;
+
+ /* Allocate memory for radar filters */
+ for (n=0; n<DFS_MAX_RADAR_TYPES; n++) {
+ dfs->dfs_radarf[n] = (struct dfs_filtertype *)OS_MALLOC(NULL, sizeof(struct dfs_filtertype),GFP_ATOMIC);
+ if (dfs->dfs_radarf[n] == NULL) {
+ DFS_PRINTK("%s: cannot allocate memory for radar filter types\n",
+ __func__);
+ goto bad1;
+ }
+ OS_MEMZERO(dfs->dfs_radarf[n], sizeof(struct dfs_filtertype));
+ }
+ /* Allocate memory for radar table */
+ dfs->dfs_radartable = (int8_t **)OS_MALLOC(NULL, 256*sizeof(int8_t *), GFP_ATOMIC);
+ if (dfs->dfs_radartable == NULL) {
+ DFS_PRINTK("%s: cannot allocate memory for radar table\n",
+ __func__);
+ goto bad1;
+ }
+ for (n=0; n<256; n++) {
+ dfs->dfs_radartable[n] = OS_MALLOC(NULL, DFS_MAX_RADAR_OVERLAP*sizeof(int8_t),
+ GFP_ATOMIC);
+ if (dfs->dfs_radartable[n] == NULL) {
+ DFS_PRINTK("%s: cannot allocate memory for radar table entry\n",
+ __func__);
+ goto bad2;
+ }
+ }
+
+ if (usenol == 0)
+ DFS_PRINTK("%s: NOL disabled\n", __func__);
+ else if (usenol == 2)
+ DFS_PRINTK("%s: NOL disabled; no CSA\n", __func__);
+
+ dfs->dfs_rinfo.rn_use_nol = usenol;
+
+ /* Init the cached extension channel busy for false alarm reduction */
+ dfs->dfs_rinfo.ext_chan_busy_ts = ic->ic_get_TSF64(ic);
+ dfs->dfs_rinfo.dfs_ext_chan_busy = 0;
+ /* Init the Bin5 chirping related data */
+ dfs->dfs_rinfo.dfs_bin5_chirp_ts = dfs->dfs_rinfo.ext_chan_busy_ts;
+ dfs->dfs_rinfo.dfs_last_bin5_dur = MAX_BIN5_DUR;
+ dfs->dfs_b5radars = NULL;
+
+ /*
+ * If dfs_init_radar_filters() fails, we can abort here and
+ * reconfigure when the first valid channel + radar config
+ * is available.
+ */
+ if ( dfs_init_radar_filters( ic, &radar_info) ) {
+ DFS_PRINTK(" %s: Radar Filter Intialization Failed \n",
+ __func__);
+ return 1;
+ }
+
+ dfs->ath_dfs_false_rssi_thres = RSSI_POSSIBLY_FALSE;
+ dfs->ath_dfs_peak_mag = SEARCH_FFT_REPORT_PEAK_MAG_THRSH;
+ dfs->dfs_phyerr_freq_min = 0x7fffffff;
+ dfs->dfs_phyerr_freq_max = 0;
+ dfs->dfs_phyerr_queued_count = 0;
+ dfs->dfs_phyerr_w53_counter = 0;
+ dfs->dfs_pri_multiplier = 2;
+
+ dfs->ath_dfs_nol_timeout = DFS_NOL_TIMEOUT_S;
+ return 0;
+
+bad2:
+ OS_FREE(dfs->dfs_radartable);
+ dfs->dfs_radartable = NULL;
+bad1:
+ for (n=0; n<DFS_MAX_RADAR_TYPES; n++) {
+ if (dfs->dfs_radarf[n] != NULL) {
+ OS_FREE(dfs->dfs_radarf[n]);
+ dfs->dfs_radarf[n] = NULL;
+ }
+ }
+ if (dfs->pulses) {
+ OS_FREE(dfs->pulses);
+ dfs->pulses = NULL;
+ }
+ if (dfs->events) {
+ OS_FREE(dfs->events);
+ dfs->events = NULL;
+ }
+
+ if (ic->ic_dfs) {
+ OS_FREE(ic->ic_dfs);
+ ic->ic_dfs = NULL;
+ }
+ return 1;
+#undef N
+}
+
+void
+dfs_detach(struct ieee80211com *ic)
+{
+ struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs;
+ int n, empty;
+
+ if (dfs == NULL) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s: ic_dfs is NULL\n", __func__);
+ return;
+ }
+
+ /* Bug 29099 make sure all outstanding timers are cancelled*/
+
+ if (dfs->ath_radar_tasksched) {
+ OS_CANCEL_TIMER(&dfs->ath_dfs_task_timer);
+ dfs->ath_radar_tasksched = 0;
+ }
+
+ if (dfs->ath_dfstest) {
+ OS_CANCEL_TIMER(&dfs->ath_dfstesttimer);
+ dfs->ath_dfstest = 0;
+ }
+
+#if 0
+#ifndef ATH_DFS_RADAR_DETECTION_ONLY
+ if (dfs->ic_dfswait) {
+ OS_CANCEL_TIMER(&dfs->ic_dfswaittimer);
+ dfs->ath_dfswait = 0;
+ }
+
+ OS_CANCEL_TIMER(&dfs->sc_dfs_war_timer);
+ if (dfs->dfs_nol != NULL) {
+ struct dfs_nolelem *nol, *next;
+ nol = dfs->dfs_nol;
+ /* Bug 29099 - each NOL element has its own timer, cancel it and
+ free the element*/
+ while (nol != NULL) {
+ OS_CANCEL_TIMER(&nol->nol_timer);
+ next = nol->nol_next;
+ OS_FREE(nol);
+ nol = next;
+ }
+ dfs->dfs_nol = NULL;
+ }
+#endif
+#endif
+ /* Return radar events to free q*/
+ dfs_reset_radarq(dfs);
+ dfs_reset_alldelaylines(dfs);
+
+ /* Free up pulse log*/
+ if (dfs->pulses != NULL) {
+ OS_FREE(dfs->pulses);
+ dfs->pulses = NULL;
+ }
+
+ for (n=0; n<DFS_MAX_RADAR_TYPES;n++) {
+ if (dfs->dfs_radarf[n] != NULL) {
+ OS_FREE(dfs->dfs_radarf[n]);
+ dfs->dfs_radarf[n] = NULL;
+ }
+ }
+
+
+ if (dfs->dfs_radartable != NULL) {
+ for (n=0; n<256; n++) {
+ if (dfs->dfs_radartable[n] != NULL) {
+ OS_FREE(dfs->dfs_radartable[n]);
+ dfs->dfs_radartable[n] = NULL;
+ }
+ }
+ OS_FREE(dfs->dfs_radartable);
+ dfs->dfs_radartable = NULL;
+#ifndef ATH_DFS_RADAR_DETECTION_ONLY
+ dfs->ath_dfs_isdfsregdomain = 0;
+#endif
+ }
+
+ if (dfs->dfs_b5radars != NULL) {
+ OS_FREE(dfs->dfs_b5radars);
+ dfs->dfs_b5radars=NULL;
+ }
+
+/* Commenting out since all the ar functions are obsolete and
+ * the function definition has been removed as part of dfs_ar.c
+ * dfs_reset_ar(dfs);
+ */
+ ATH_ARQ_LOCK(dfs);
+ empty = STAILQ_EMPTY(&(dfs->dfs_arq));
+ ATH_ARQ_UNLOCK(dfs);
+ if (!empty) {
+/*
+ * Commenting out since all the ar functions are obsolete and
+ * the function definition has been removed as part of dfs_ar.c
+ *
+ * dfs_reset_arq(dfs);
+ */
+ }
+ if (dfs->events != NULL) {
+ OS_FREE(dfs->events);
+ dfs->events = NULL;
+ }
+ dfs_nol_timer_cleanup(dfs);
+ OS_FREE(dfs);
+
+ /* XXX? */
+ ic->ic_dfs = NULL;
+}
+/*
+ * This is called each time a channel change occurs, to (potentially) enable
+ * the radar code.
+ */
+int dfs_radar_disable(struct ieee80211com *ic)
+{
+ struct ath_dfs *dfs=(struct ath_dfs *)ic->ic_dfs;
+#ifdef ATH_ENABLE_AR
+ dfs->dfs_proc_phyerr &= ~DFS_AR_EN;
+#endif
+ dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN;
+ return 0;
+}
+/*
+ * This is called each time a channel change occurs, to (potentially) enable
+ * the radar code.
+ */
+int dfs_radar_enable(struct ieee80211com *ic,
+ struct ath_dfs_radar_tab_info *radar_info)
+{
+ int is_ext_ch;
+ int is_fastclk = 0;
+ //u_int32_t rfilt;
+ struct ath_dfs *dfs;
+ struct dfs_state *rs_pri, *rs_ext;
+ struct ieee80211_channel *chan=ic->ic_curchan, *ext_ch = NULL;
+ is_ext_ch=IEEE80211_IS_CHAN_11N_HT40(ic->ic_curchan);
+ dfs=(struct ath_dfs *)ic->ic_dfs;
+ rs_pri = NULL;
+ rs_ext = NULL;
+#if 0
+ int i;
+#endif
+ if (dfs == NULL) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: ic_dfs is NULL\n",
+ __func__);
+
+ return -EIO;
+ }
+ ic->ic_dfs_disable(ic);
+
+ /*
+ * Setting country code might change the DFS domain
+ * so initialize the DFS Radar filters
+ */
+ dfs_init_radar_filters(ic, radar_info);
+
+ if ((ic->ic_opmode == IEEE80211_M_HOSTAP || ic->ic_opmode == IEEE80211_M_IBSS)) {
+
+ if (IEEE80211_IS_CHAN_DFS(chan)) {
+
+ u_int8_t index_pri, index_ext;
+#ifdef ATH_ENABLE_AR
+ dfs->dfs_proc_phyerr |= DFS_AR_EN;
+#endif
+ dfs->dfs_proc_phyerr |= DFS_RADAR_EN;
+
+
+
+ if (is_ext_ch) {
+ ext_ch = ieee80211_get_extchan(ic);
+ }
+ dfs_reset_alldelaylines(dfs);
+
+ rs_pri = dfs_getchanstate(dfs, &index_pri, 0);
+ if (ext_ch) {
+ rs_ext = dfs_getchanstate(dfs, &index_ext, 1);
+ }
+ if (rs_pri != NULL && ((ext_ch==NULL)||(rs_ext != NULL))) {
+ struct ath_dfs_phyerr_param pe;
+
+ OS_MEMSET(&pe, '\0', sizeof(pe));
+
+ if (index_pri != dfs->dfs_curchan_radindex)
+ dfs_reset_alldelaylines(dfs);
+
+ dfs->dfs_curchan_radindex = (int16_t) index_pri;
+
+ if (rs_ext)
+ dfs->dfs_extchan_radindex = (int16_t) index_ext;
+
+ ath_dfs_phyerr_param_copy(&pe,
+ &rs_pri->rs_param);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS3,
+ "%s: firpwr=%d, rssi=%d, height=%d, "
+ "prssi=%d, inband=%d, relpwr=%d, "
+ "relstep=%d, maxlen=%d\n",
+ __func__,
+ pe.pe_firpwr,
+ pe.pe_rrssi,
+ pe.pe_height,
+ pe.pe_prssi,
+ pe.pe_inband,
+ pe.pe_relpwr,
+ pe.pe_relstep,
+ pe.pe_maxlen
+ );
+
+#if 0 //Not needed
+ /* Disable strong signal fast antenna diversity */
+ ath_hal_setcapability(ah, HAL_CAP_DIVERSITY,
+ HAL_CAP_STRONG_DIV, 1, NULL);
+#endif
+ ic->ic_dfs_enable(ic, &is_fastclk, &pe);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "Enabled radar detection on channel %d\n",
+ chan->ic_freq);
+ dfs->dur_multiplier =
+ is_fastclk ? DFS_FAST_CLOCK_MULTIPLIER : DFS_NO_FAST_CLOCK_MULTIPLIER;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS3,
+ "%s: duration multiplier is %d\n", __func__, dfs->dur_multiplier);
+ } else
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: No more radar states left\n",
+ __func__);
+ }
+ }
+
+ return 0;
+}
+
+int
+dfs_control(struct ieee80211com *ic, u_int id,
+ void *indata, u_int32_t insize,
+ void *outdata, u_int32_t *outsize)
+{
+ int error = 0;
+ struct ath_dfs_phyerr_param peout;
+ struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs;
+ struct dfs_ioctl_params *dfsparams;
+ u_int32_t val=0;
+#ifndef ATH_DFS_RADAR_DETECTION_ONLY
+ struct dfsreq_nolinfo *nol;
+ u_int32_t *data = NULL;
+#endif /* ATH_DFS_RADAR_DETECTION_ONLY */
+ int i;
+
+ if (dfs == NULL) {
+ error = -EINVAL;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s DFS is null\n", __func__);
+ goto bad;
+ }
+
+
+ switch (id) {
+ case DFS_SET_THRESH:
+ if (insize < sizeof(struct dfs_ioctl_params) || !indata) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
+ "%s: insize=%d, expected=%d bytes, indata=%p\n",
+ __func__, insize, sizeof(struct dfs_ioctl_params),
+ indata);
+ error = -EINVAL;
+ break;
+ }
+ dfsparams = (struct dfs_ioctl_params *) indata;
+ if (!dfs_set_thresholds(ic, DFS_PARAM_FIRPWR, dfsparams->dfs_firpwr))
+ error = -EINVAL;
+ if (!dfs_set_thresholds(ic, DFS_PARAM_RRSSI, dfsparams->dfs_rrssi))
+ error = -EINVAL;
+ if (!dfs_set_thresholds(ic, DFS_PARAM_HEIGHT, dfsparams->dfs_height))
+ error = -EINVAL;
+ if (!dfs_set_thresholds(ic, DFS_PARAM_PRSSI, dfsparams->dfs_prssi))
+ error = -EINVAL;
+ if (!dfs_set_thresholds(ic, DFS_PARAM_INBAND, dfsparams->dfs_inband))
+ error = -EINVAL;
+ /* 5413 speicfic */
+ if (!dfs_set_thresholds(ic, DFS_PARAM_RELPWR, dfsparams->dfs_relpwr))
+ error = -EINVAL;
+ if (!dfs_set_thresholds(ic, DFS_PARAM_RELSTEP, dfsparams->dfs_relstep))
+ error = -EINVAL;
+ if (!dfs_set_thresholds(ic, DFS_PARAM_MAXLEN, dfsparams->dfs_maxlen))
+ error = -EINVAL;
+ break;
+ case DFS_GET_THRESH:
+ if (!outdata || !outsize || *outsize <sizeof(struct dfs_ioctl_params)) {
+ error = -EINVAL;
+ break;
+ }
+ *outsize = sizeof(struct dfs_ioctl_params);
+ dfsparams = (struct dfs_ioctl_params *) outdata;
+
+ /*
+ * Fetch the DFS thresholds using the internal representation.
+ */
+ (void) dfs_get_thresholds(ic, &peout);
+
+ /*
+ * Convert them to the dfs IOCTL representation.
+ */
+ ath_dfs_dfsparam_to_ioctlparam(&peout, dfsparams);
+ break;
+ case DFS_RADARDETECTS:
+ if (!outdata || !outsize || *outsize < sizeof(u_int32_t)) {
+ error = -EINVAL;
+ break;
+ }
+ *outsize = sizeof (u_int32_t);
+ *((u_int32_t *)outdata) = dfs->ath_dfs_stats.num_radar_detects;
+ break;
+ case DFS_DISABLE_DETECT:
+ dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN;
+ dfs->ic->ic_dfs_state.ignore_dfs = 1;
+ DFS_PRINTK("%s enable detects, ignore_dfs %d\n",
+ __func__,
+ dfs->ic->ic_dfs_state.ignore_dfs);
+ break;
+ case DFS_ENABLE_DETECT:
+ dfs->dfs_proc_phyerr |= DFS_RADAR_EN;
+ dfs->ic->ic_dfs_state.ignore_dfs = 0;
+ DFS_PRINTK("%s enable detects, ignore_dfs %d\n",
+ __func__,
+ dfs->ic->ic_dfs_state.ignore_dfs);
+ break;
+ case DFS_DISABLE_FFT:
+ //UMACDFS: TODO: val = ath_hal_dfs_config_fft(sc->sc_ah, false);
+ DFS_PRINTK("%s TODO disable FFT val=0x%x \n", __func__, val);
+ break;
+ case DFS_ENABLE_FFT:
+ //UMACDFS TODO: val = ath_hal_dfs_config_fft(sc->sc_ah, true);
+ DFS_PRINTK("%s TODO enable FFT val=0x%x \n", __func__, val);
+ break;
+ case DFS_SET_DEBUG_LEVEL:
+ if (insize < sizeof(u_int32_t) || !indata) {
+ error = -EINVAL;
+ break;
+ }
+ dfs->dfs_debug_mask= *(u_int32_t *)indata;
+ DFS_PRINTK("%s debug level now = 0x%x \n",
+ __func__,
+ dfs->dfs_debug_mask);
+ if (dfs->dfs_debug_mask & ATH_DEBUG_DFS3) {
+ /* Enable debug Radar Event */
+ dfs->dfs_event_log_on = 1;
+ } else {
+ dfs->dfs_event_log_on = 0;
+ }
+ break;
+ case DFS_SET_FALSE_RSSI_THRES:
+ if (insize < sizeof(u_int32_t) || !indata) {
+ error = -EINVAL;
+ break;
+ }
+ dfs->ath_dfs_false_rssi_thres= *(u_int32_t *)indata;
+ DFS_PRINTK("%s false RSSI threshold now = 0x%x \n",
+ __func__,
+ dfs->ath_dfs_false_rssi_thres);
+ break;
+ case DFS_SET_PEAK_MAG:
+ if (insize < sizeof(u_int32_t) || !indata) {
+ error = -EINVAL;
+ break;
+ }
+ dfs->ath_dfs_peak_mag= *(u_int32_t *)indata;
+ DFS_PRINTK("%s peak_mag now = 0x%x \n",
+ __func__,
+ dfs->ath_dfs_peak_mag);
+ break;
+ case DFS_IGNORE_CAC:
+ if (insize < sizeof(u_int32_t) || !indata) {
+ error = -EINVAL;
+ break;
+ }
+ if (*(u_int32_t *)indata) {
+ dfs->ic->ic_dfs_state.ignore_cac= 1;
+ } else {
+ dfs->ic->ic_dfs_state.ignore_cac= 0;
+ }
+ DFS_PRINTK("%s ignore cac = 0x%x \n",
+ __func__,
+ dfs->ic->ic_dfs_state.ignore_cac);
+ break;
+ case DFS_SET_NOL_TIMEOUT:
+ if (insize < sizeof(u_int32_t) || !indata) {
+ error = -EINVAL;
+ break;
+ }
+ if (*(int *)indata) {
+ dfs->ath_dfs_nol_timeout= *(int *)indata;
+ } else {
+ dfs->ath_dfs_nol_timeout= DFS_NOL_TIMEOUT_S;
+ }
+ DFS_PRINTK("%s nol timeout = %d sec \n",
+ __func__,
+ dfs->ath_dfs_nol_timeout);
+ break;
+#ifndef ATH_DFS_RADAR_DETECTION_ONLY
+ case DFS_MUTE_TIME:
+ if (insize < sizeof(u_int32_t) || !indata) {
+ error = -EINVAL;
+ break;
+ }
+ data = (u_int32_t *) indata;
+ dfs->ath_dfstesttime = *data;
+ dfs->ath_dfstesttime *= (1000); //convert sec into ms
+ break;
+ case DFS_GET_USENOL:
+ if (!outdata || !outsize || *outsize < sizeof(u_int32_t)) {
+ error = -EINVAL;
+ break;
+ }
+ *outsize = sizeof(u_int32_t);
+ *((u_int32_t *)outdata) = dfs->dfs_rinfo.rn_use_nol;
+
+
+
+ for (i = 0; (i < DFS_EVENT_LOG_SIZE) && (i < dfs->dfs_event_log_count); i++) {
+ //DFS_DPRINTK(sc, ATH_DEBUG_DFS,"ts=%llu diff_ts=%u rssi=%u dur=%u\n", dfs->radar_log[i].ts, dfs->radar_log[i].diff_ts, dfs->radar_log[i].rssi, dfs->radar_log[i].dur);
+
+ }
+ dfs->dfs_event_log_count = 0;
+ dfs->dfs_phyerr_count = 0;
+ dfs->dfs_phyerr_reject_count = 0;
+ dfs->dfs_phyerr_queued_count = 0;
+ dfs->dfs_phyerr_freq_min = 0x7fffffff;
+ dfs->dfs_phyerr_freq_max = 0;
+ break;
+ case DFS_SET_USENOL:
+ if (insize < sizeof(u_int32_t) || !indata) {
+ error = -EINVAL;
+ break;
+ }
+ dfs->dfs_rinfo.rn_use_nol = *(u_int32_t *)indata;
+ /* iwpriv markdfs in linux can do the same thing... */
+ break;
+ case DFS_GET_NOL:
+ if (!outdata || !outsize || *outsize < sizeof(struct dfsreq_nolinfo)) {
+ error = -EINVAL;
+ break;
+ }
+ *outsize = sizeof(struct dfsreq_nolinfo);
+ nol = (struct dfsreq_nolinfo *)outdata;
+ dfs_get_nol(dfs, (struct dfsreq_nolelem *)nol->dfs_nol, &nol->ic_nchans);
+ dfs_print_nol(dfs);
+ break;
+ case DFS_SET_NOL:
+ if (insize < sizeof(struct dfsreq_nolinfo) || !indata) {
+ error = -EINVAL;
+ break;
+ }
+ nol = (struct dfsreq_nolinfo *) indata;
+ dfs_set_nol(dfs, (struct dfsreq_nolelem *)nol->dfs_nol, nol->ic_nchans);
+ break;
+
+ case DFS_SHOW_NOL:
+ dfs_print_nol(dfs);
+ break;
+ case DFS_BANGRADAR:
+ #if 0 //MERGE_TBD
+ if(sc->sc_nostabeacons)
+ {
+ printk("No radar detection Enabled \n");
+ break;
+ }
+#endif
+ dfs->dfs_bangradar = 1;
+ dfs->ath_radar_tasksched = 1;
+ OS_SET_TIMER(&dfs->ath_dfs_task_timer, 0);
+ break;
+#endif /* ATH_DFS_RADAR_DETECTION_ONLY */
+ default:
+ error = -EINVAL;
+ }
+bad:
+ return error;
+}
+int
+dfs_set_thresholds(struct ieee80211com *ic, const u_int32_t threshtype,
+ const u_int32_t value)
+{
+ struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs;
+ int16_t chanindex;
+ struct dfs_state *rs;
+ struct ath_dfs_phyerr_param pe;
+ int is_fastclk = 0; /* XXX throw-away */
+
+ if (dfs == NULL) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s: ic_dfs is NULL\n",
+ __func__);
+ return 0;
+ }
+
+ chanindex = dfs->dfs_curchan_radindex;
+ if ((chanindex <0) || (chanindex >= DFS_NUM_RADAR_STATES)) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
+ "%s: chanindex = %d, DFS_NUM_RADAR_STATES=%d\n",
+ __func__,
+ chanindex,
+ DFS_NUM_RADAR_STATES);
+ return 0;
+ }
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
+ "%s: threshtype=%d, value=%d\n", __func__, threshtype, value);
+
+ ath_dfs_phyerr_init_noval(&pe);
+
+ rs = &(dfs->dfs_radar[chanindex]);
+ switch (threshtype) {
+ case DFS_PARAM_FIRPWR:
+ rs->rs_param.pe_firpwr = (int32_t) value;
+ pe.pe_firpwr = value;
+ break;
+ case DFS_PARAM_RRSSI:
+ rs->rs_param.pe_rrssi = value;
+ pe.pe_rrssi = value;
+ break;
+ case DFS_PARAM_HEIGHT:
+ rs->rs_param.pe_height = value;
+ pe.pe_height = value;
+ break;
+ case DFS_PARAM_PRSSI:
+ rs->rs_param.pe_prssi = value;
+ pe.pe_prssi = value;
+ break;
+ case DFS_PARAM_INBAND:
+ rs->rs_param.pe_inband = value;
+ pe.pe_inband = value;
+ break;
+ /* 5413 specific */
+ case DFS_PARAM_RELPWR:
+ rs->rs_param.pe_relpwr = value;
+ pe.pe_relpwr = value;
+ break;
+ case DFS_PARAM_RELSTEP:
+ rs->rs_param.pe_relstep = value;
+ pe.pe_relstep = value;
+ break;
+ case DFS_PARAM_MAXLEN:
+ rs->rs_param.pe_maxlen = value;
+ pe.pe_maxlen = value;
+ break;
+ default:
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
+ "%s: unknown threshtype (%d)\n",
+ __func__,
+ threshtype);
+ break;
+ }
+
+ /*
+ * The driver layer dfs_enable routine is tasked with translating
+ * values from the global format to the per-device (HAL, offload)
+ * format.
+ */
+ ic->ic_dfs_enable(ic, &is_fastclk, &pe);
+ return 1;
+}
+
+int
+dfs_get_thresholds(struct ieee80211com *ic, struct ath_dfs_phyerr_param *param)
+{
+ //UMACDFS : TODO:ath_hal_getdfsthresh(sc->sc_ah, param);
+
+ OS_MEMZERO(param, sizeof(*param));
+
+ (void) ic->ic_dfs_get_thresholds(ic, param);
+
+ return 1;
+}
+
+u_int16_t dfs_usenol(struct ieee80211com *ic)
+{
+ struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs;
+ return dfs ? (u_int16_t) dfs->dfs_rinfo.rn_use_nol : 0;
+}
+
+u_int16_t dfs_isdfsregdomain(struct ieee80211com *ic)
+{
+ struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs;
+ return dfs ? dfs->dfsdomain : 0;
+}
+
+#endif /* ATH_UPPORT_DFS */
+
diff --git a/CORE/SERVICES/DFS/src/dfs.h b/CORE/SERVICES/DFS/src/dfs.h
new file mode 100644
index 000000000000..a65db7c9813c
--- /dev/null
+++ b/CORE/SERVICES/DFS/src/dfs.h
@@ -0,0 +1,780 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ dfs.h
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+
+#ifndef _DFS_H_
+#define _DFS_H_
+
+/*
+*TO DO DFS- Need to include this file later on
+*#include "ath_internal.h"
+*/
+/*DFS New Include Start*/
+
+#include <adf_net_types.h> /* ADF_NBUF_EXEMPT_NO_EXEMPTION, etc. */
+#include <adf_nbuf.h> /* adf_nbuf_t, etc. */
+#include <adf_os_util.h> /* adf_os_assert */
+#include <adf_os_lock.h> /* adf_os_spinlock */
+#include <queue.h> /* TAILQ */
+#include <adf_os_time.h>
+#include <adf_os_timer.h>
+#include <adf_os_mem.h>
+#include <osdep.h>
+/*DFS Utility Include END*/
+
+/* From wlan_modules/include/ */
+#include "ath_dfs_structs.h"
+/*DFS - Newly added File to interface cld UMAC and dfs data structures*/
+#include <wma_dfs_interface.h>
+/*
+*TO DO DFS- Need to include this file later on
+#include "ah.h"
+*/
+//#include "ah_desc.h"
+#include "dfs_ioctl.h"
+#include "dfs_ioctl_private.h"
+#include "dfs_interface.h"
+#include "_ieee80211_common.h"
+
+#define ATH_SUPPORT_DFS 1
+#define CHANNEL_TURBO 0x00010
+#define DFS_PRINTK(_fmt, ...) printk((_fmt), __VA_ARGS__)
+#define DFS_DPRINTK(dfs, _m, _fmt, ...) do { \
+ if (((dfs) == NULL) || \
+ ((dfs) != NULL && \
+ ((_m) & (dfs)->dfs_debug_mask))) { \
+ printk(_fmt, __VA_ARGS__); \
+ } \
+} while (0)
+
+#define DFS_MIN(a,b) ((a)<(b)?(a):(b))
+#define DFS_MAX(a,b) ((a)>(b)?(a):(b))
+#define DFS_DIFF(a,b) (DFS_MAX(a,b) - DFS_MIN(a,b))
+/*
+ * Maximum number of radar events to be processed in a single iteration.
+ * Allows soft watchdog to run.
+ */
+#define MAX_EVENTS 100
+
+/*
+ * Constants to use for chirping detection.
+ *
+ * All are unconverted as HW reports them.
+ *
+ * XXX Are these constants with or without fast clock 5GHz operation?
+ * XXX Peregrine reports pulses in microseconds, not hardware clocks!
+ */
+#define MIN_BIN5_DUR 63 /* 50 * 1.25*/
+#define MIN_BIN5_DUR_MICROSEC 50
+#define MAYBE_BIN5_DUR 35 /* 28 * 1.25*/
+#define MAYBE_BIN5_DUR_MICROSEC 28
+//#define MAX_BIN5_DUR 131 /* 105 * 1.25*/
+#define MAX_BIN5_DUR 145 /* use 145 for osprey */ //conversion is already done using dfs->dur_multiplier//
+#define MAX_BIN5_DUR_MICROSEC 105
+
+#define DFS_MARGIN_EQUAL(a, b, margin) ((DFS_DIFF(a,b)) <= margin)
+#define DFS_MAX_STAGGERED_BURSTS 3
+
+/* All filter thresholds in the radar filter tables are effective at a 50% channel loading */
+#define DFS_CHAN_LOADING_THRESH 50
+#define DFS_EXT_CHAN_LOADING_THRESH 30
+#define DFS_DEFAULT_PRI_MARGIN 6
+#define DFS_DEFAULT_FIXEDPATTERN_PRI_MARGIN 4
+#define ATH_DFSQ_LOCK(_dfs) spin_lock_dpc((&(_dfs)->dfs_radarqlock))
+#define ATH_DFSQ_UNLOCK(_dfs) spin_unlock_dpc((&(_dfs)->dfs_radarqlock))
+#define ATH_DFSQ_LOCK_INIT(_dfs) adf_os_spinlock_init(&(_dfs)->dfs_radarqlock)
+
+#define ATH_ARQ_LOCK(_dfs) spin_lock_dpc((&(_dfs)->dfs_arqlock))
+#define ATH_ARQ_UNLOCK(_dfs) spin_unlock_dpc((&(_dfs)->dfs_arqlock))
+#define ATH_ARQ_LOCK_INIT(_dfs) adf_os_spinlock_init(&(_dfs)->dfs_arqlock)
+
+#define ATH_DFSEVENTQ_LOCK(_dfs) spin_lock_dpc((&(_dfs)->dfs_eventqlock))
+#define ATH_DFSEVENTQ_UNLOCK(_dfs) spin_unlock_dpc((&(_dfs)->dfs_eventqlock))
+#define ATH_DFSEVENTQ_LOCK_INIT(_dfs) adf_os_spinlock_init((&(_dfs)->dfs_eventqlock));
+
+
+
+
+
+#define DFS_TSMASK 0xFFFFFFFF /* Mask for time stamp from descriptor */
+#define DFS_TSSHIFT 32 /* Shift for time stamp from descriptor */
+#define DFS_TSF_WRAP 0xFFFFFFFFFFFFFFFFULL /* 64 bit TSF wrap value */
+#define DFS_64BIT_TSFMASK 0x0000000000007FFFULL /* TS mask for 64 bit value */
+
+
+#define DFS_AR_RADAR_RSSI_THR 5 /* in dB */
+#define DFS_AR_RADAR_RESET_INT 1 /* in secs */
+#define DFS_AR_RADAR_MAX_HISTORY 500
+#define DFS_AR_REGION_WIDTH 128
+#define DFS_AR_RSSI_THRESH_STRONG_PKTS 17 /* in dB */
+#define DFS_AR_RSSI_DOUBLE_THRESHOLD 15 /* in dB */
+#define DFS_AR_MAX_NUM_ACK_REGIONS 9
+#define DFS_AR_ACK_DETECT_PAR_THRESH 20
+#define DFS_AR_PKT_COUNT_THRESH 20
+
+#define DFS_MAX_DL_SIZE 64
+#define DFS_MAX_DL_MASK 0x3F
+
+#define DFS_NOL_TIME DFS_NOL_TIMEOUT_US
+ /* 30 minutes in usecs */
+
+#define DFS_WAIT_TIME 60*1000000 /* 1 minute in usecs */
+
+#define DFS_DISABLE_TIME 3*60*1000000 /* 3 minutes in usecs */
+
+#define DFS_MAX_B5_SIZE 128
+#define DFS_MAX_B5_MASK 0x0000007F /* 128 */
+
+#define DFS_MAX_RADAR_OVERLAP 16 /* Max number of overlapping filters */
+
+#define DFS_MAX_EVENTS 1024 /* Max number of dfs events which can be q'd */
+
+#define DFS_RADAR_EN 0x80000000 /* Radar detect is capable */
+#define DFS_AR_EN 0x40000000 /* AR detect is capable */
+#define DFS_MAX_RSSI_VALUE 0x7fffffff /* Max rssi value */
+
+#define DFS_BIN_MAX_PULSES 60 /* max num of pulses in a burst */
+#define DFS_BIN5_PRI_LOWER_LIMIT 990 /* us */
+
+/* to cover the single pusle burst case, change from 2010 us to 2010000 us */
+
+/*
+ * this is reverted back to 2010 as larger value causes false
+ * bin5 detect (EV76432, EV76320)
+ */
+#define DFS_BIN5_PRI_HIGHER_LIMIT 2010 /* us */
+
+#define DFS_BIN5_WIDTH_MARGIN 4 /* us */
+#define DFS_BIN5_RSSI_MARGIN 5 /* dBm */
+/*Following threshold is not specified but should be okay statistically*/
+#define DFS_BIN5_BRI_LOWER_LIMIT 300000 /* us */
+#define DFS_BIN5_BRI_UPPER_LIMIT 12000000 /* us */
+
+#define DFS_MAX_PULSE_BUFFER_SIZE 1024 /* Max number of pulses kept in buffer */
+#define DFS_MAX_PULSE_BUFFER_MASK 0x3ff
+
+#define DFS_FAST_CLOCK_MULTIPLIER (800/11)
+#define DFS_NO_FAST_CLOCK_MULTIPLIER (80)
+
+typedef adf_os_spinlock_t dfsq_lock_t;
+
+#ifdef WIN32
+#pragma pack(push, dfs_pulseparams, 1)
+#endif
+struct dfs_pulseparams {
+ u_int64_t p_time; /* time for start of pulse in usecs*/
+ u_int8_t p_dur; /* Duration of pulse in usecs*/
+ u_int8_t p_rssi; /* Duration of pulse in usecs*/
+} adf_os_packed;
+#ifdef WIN32
+#pragma pack(pop, dfs_pulseparams)
+#endif
+
+#ifdef WIN32
+#pragma pack(push, dfs_pulseline, 1)
+#endif
+struct dfs_pulseline {
+ /* pl_elems - array of pulses in delay line */
+ struct dfs_pulseparams pl_elems[DFS_MAX_PULSE_BUFFER_SIZE];
+ u_int32_t pl_firstelem; /* Index of the first element */
+ u_int32_t pl_lastelem; /* Index of the last element */
+ u_int32_t pl_numelems; /* Number of elements in the delay line */
+} adf_os_packed;
+#ifdef WIN32
+#pragma pack(pop, dfs_pulseline)
+#endif
+
+#ifdef WIN32
+#pragma pack(push, dfs_event, 1)
+#endif
+
+#define DFS_EVENT_CHECKCHIRP 0x01 /* Whether to check the chirp flag */
+#define DFS_EVENT_HW_CHIRP 0x02 /* hardware chirp */
+#define DFS_EVENT_SW_CHIRP 0x04 /* software chirp */
+
+/*
+ * Use this only if the event has CHECKCHIRP set.
+ */
+#define DFS_EVENT_ISCHIRP(e) \
+ ((e)->re_flags & (DFS_EVENT_HW_CHIRP | DFS_EVENT_SW_CHIRP))
+
+/*
+ * Check if the given event is to be rejected as not possibly
+ * a chirp. This means:
+ * (a) it's a hardware or software checked chirp, and
+ * (b) the HW/SW chirp bits are both 0.
+ */
+#define DFS_EVENT_NOTCHIRP(e) \
+ (((e)->re_flags & (DFS_EVENT_CHECKCHIRP)) && \
+ (! DFS_EVENT_ISCHIRP((e))))
+
+struct dfs_event {
+ u_int64_t re_full_ts; /* 64-bit full timestamp from interrupt time */
+ u_int32_t re_ts; /* Original 15 bit recv timestamp */
+ u_int8_t re_rssi; /* rssi of radar event */
+ u_int8_t re_dur; /* duration of radar pulse */
+ u_int8_t re_chanindex; /* Channel of event */
+ u_int8_t re_flags; /* Event flags */
+ u_int32_t re_freq; /* Centre frequency of event, KHz */
+ u_int32_t re_freq_lo; /* Lower bounds of frequency, KHz */
+ u_int32_t re_freq_hi; /* Upper bounds of frequency, KHz */
+ STAILQ_ENTRY(dfs_event) re_list; /* List of radar events */
+} adf_os_packed;
+#ifdef WIN32
+#pragma pack(pop, dfs_event)
+#endif
+
+#define DFS_AR_MAX_ACK_RADAR_DUR 511
+#define DFS_AR_MAX_NUM_PEAKS 3
+#define DFS_AR_ARQ_SIZE 2048 /* 8K AR events for buffer size */
+#define DFS_AR_ARQ_SEQSIZE 2049 /* Sequence counter wrap for AR */
+
+#define DFS_RADARQ_SIZE 512 /* 1K radar events for buffer size */
+#define DFS_RADARQ_SEQSIZE 513 /* Sequence counter wrap for radar */
+#define DFS_NUM_RADAR_STATES 64 /* Number of radar channels we keep state for */
+#define DFS_MAX_NUM_RADAR_FILTERS 10 /* Max number radar filters for each type */
+#define DFS_MAX_RADAR_TYPES 32 /* Number of different radar types */
+
+struct dfs_ar_state {
+ u_int32_t ar_prevwidth;
+ u_int32_t ar_phyerrcount[DFS_AR_MAX_ACK_RADAR_DUR];
+ u_int32_t ar_acksum;
+ u_int32_t ar_packetthreshold; /* Thresh to determine traffic load */
+ u_int32_t ar_parthreshold; /* Thresh to determine peak */
+ u_int32_t ar_radarrssi; /* Rssi threshold for AR event */
+ u_int16_t ar_prevtimestamp;
+ u_int16_t ar_peaklist[DFS_AR_MAX_NUM_PEAKS];
+};
+
+#ifdef WIN32
+#pragma pack(push, dfs_delayelem, 1)
+#endif
+struct dfs_delayelem {
+ u_int32_t de_time; /* Current "filter" time for start of pulse in usecs*/
+ u_int8_t de_dur; /* Duration of pulse in usecs*/
+ u_int8_t de_rssi; /* rssi of pulse in dB*/
+ u_int64_t de_ts; /* time stamp for this delay element */
+} adf_os_packed;
+#ifdef WIN32
+#pragma pack(pop, dfs_delayelem)
+#endif
+
+/* NB: The first element in the circular buffer is the oldest element */
+
+#ifdef WIN32
+#pragma pack(push, dfs_delayline, 1)
+#endif
+struct dfs_delayline {
+ struct dfs_delayelem dl_elems[DFS_MAX_DL_SIZE]; /* Array of pulses in delay line */
+ u_int64_t dl_last_ts; /* Last timestamp the delay line was used (in usecs) */
+ u_int32_t dl_firstelem; /* Index of the first element */
+ u_int32_t dl_lastelem; /* Index of the last element */
+ u_int32_t dl_numelems; /* Number of elements in the delay line */
+} adf_os_packed;
+#ifdef WIN32
+#pragma pack(pop, dfs_delayline)
+#endif
+
+#ifdef WIN32
+#pragma pack(push, dfs_filter, 1)
+#endif
+struct dfs_filter {
+ struct dfs_delayline rf_dl; /* Delay line of pulses for this filter */
+ u_int32_t rf_numpulses; /* Number of pulses in the filter */
+ u_int32_t rf_minpri; /* min pri to be considered for this filter*/
+ u_int32_t rf_maxpri; /* max pri to be considered for this filter*/
+ u_int32_t rf_threshold; /* match filter output threshold for radar detect */
+ u_int32_t rf_filterlen; /* Length (in usecs) of the filter */
+ u_int32_t rf_patterntype; /* fixed or variable pattern type */
+ u_int32_t rf_fixed_pri_radar_pulse; /* indicates if it is a fixed pri pulse */
+ u_int32_t rf_mindur; /* Min duration for this radar filter */
+ u_int32_t rf_maxdur; /* Max duration for this radar filter */
+ u_int32_t rf_ignore_pri_window;
+ u_int32_t rf_pulseid; /* Unique ID corresponding to the original filter ID */
+} adf_os_packed;
+#ifdef WIN32
+#pragma pack(pop, dfs_filter)
+#endif
+
+struct dfs_filtertype {
+ struct dfs_filter ft_filters[DFS_MAX_NUM_RADAR_FILTERS];
+ u_int32_t ft_filterdur; /* Duration of pulse which specifies filter type*/
+ u_int32_t ft_numfilters; /* Num filters of this type */
+ u_int64_t ft_last_ts; /* Last timestamp this filtertype was used
+ * (in usecs) */
+ u_int32_t ft_mindur; /* min pulse duration to be considered
+ * for this filter type */
+ u_int32_t ft_maxdur; /* max pulse duration to be considered
+ * for this filter type */
+ u_int32_t ft_rssithresh; /* min rssi to be considered
+ * for this filter type */
+ u_int32_t ft_numpulses; /* Num pulses in each filter of this type */
+ u_int32_t ft_patterntype; /* fixed or variable pattern type */
+ u_int32_t ft_minpri; /* min pri to be considered for this type */
+ u_int32_t ft_rssimargin; /* rssi threshold margin. In Turbo Mode HW
+ * reports rssi 3dB lower than in non TURBO
+ * mode. This will offset that diff. */
+};
+
+struct dfs_state {
+ struct ieee80211_channel rs_chan; /* Channel info */
+ u_int8_t rs_chanindex; /* Channel index in radar structure */
+ u_int32_t rs_numradarevents; /* Number of radar events */
+
+ struct ath_dfs_phyerr_param rs_param;
+};
+
+#define DFS_NOL_TIMEOUT_S (30*60) /* 30 minutes in seconds */
+//#define DFS_NOL_TIMEOUT_S (5*60) /* 5 minutes in seconds - debugging */
+#define DFS_NOL_TIMEOUT_MS (DFS_NOL_TIMEOUT_S * 1000)
+#define DFS_NOL_TIMEOUT_US (DFS_NOL_TIMEOUT_MS * 1000)
+
+#ifdef WIN32
+#pragma pack(push, dfs_nolelem, 1)
+#endif
+struct dfs_nolelem {
+ u_int32_t nol_freq; /* centre frequency */
+ u_int32_t nol_chwidth; /* event width (MHz) */
+ unsigned long nol_start_ticks; /* NOL start time in OS ticks */
+ u_int32_t nol_timeout_ms; /* NOL timeout value in msec */
+ os_timer_t nol_timer; /* per element NOL timer */
+ struct dfs_nolelem *nol_next; /* next element pointer */
+} adf_os_packed;
+#ifdef WIN32
+#pragma pack(pop, dfs_nolelem)
+#endif
+
+/* Pass structure to DFS NOL timer */
+struct dfs_nol_timer_arg {
+ struct ath_dfs *dfs;
+ u_int16_t delfreq;
+ u_int16_t delchwidth;
+};
+
+#ifdef WIN32
+#pragma pack(push, dfs_info, 1)
+#endif
+struct dfs_info {
+ int rn_use_nol; /* Use the NOL when radar found (default: TRUE) */
+ u_int32_t rn_numradars; /* Number of different types of radars */
+ u_int64_t rn_lastfull_ts; /* Last 64 bit timstamp from recv interrupt */
+ u_int16_t rn_last_ts; /* last 15 bit ts from recv descriptor */
+ u_int32_t rn_last_unique_ts; /* last unique 32 bit ts from recv descriptor */
+
+ u_int64_t rn_ts_prefix; /* Prefix to prepend to 15 bit recv ts */
+ u_int32_t rn_numbin5radars; /* Number of bin5 radar pulses to search for */
+ u_int32_t rn_fastdivGCval; /* Value of fast diversity gc limit from init file */
+ int32_t rn_minrssithresh; /* Min rssi for all radar types */
+ u_int32_t rn_maxpulsedur; /* Max pulse width in TSF ticks */
+
+ u_int8_t dfs_ext_chan_busy;
+ u_int64_t ext_chan_busy_ts;
+
+ u_int64_t dfs_bin5_chirp_ts;
+ u_int8_t dfs_last_bin5_dur;
+} adf_os_packed;
+#ifdef WIN32
+#pragma pack(pop, dfs_info)
+#endif
+
+struct dfs_bin5elem {
+ u_int64_t be_ts; /* Timestamp for the bin5 element */
+ u_int32_t be_rssi; /* Rssi for the bin5 element */
+ u_int32_t be_dur; /* Duration of bin5 element */
+};
+
+struct dfs_bin5radars {
+ struct dfs_bin5elem br_elems[DFS_MAX_B5_SIZE]; /* List of bin5 elems that fall
+ * within the time window */
+ u_int32_t br_firstelem; /* Index of the first element */
+ u_int32_t br_lastelem; /* Index of the last element */
+ u_int32_t br_numelems; /* Number of elements in the delay line */
+ struct dfs_bin5pulse br_pulse; /* Original info about bin5 pulse */
+};
+
+struct dfs_stats {
+ u_int32_t num_radar_detects; /* total num. of radar detects */
+ u_int32_t total_phy_errors;
+ u_int32_t owl_phy_errors;
+ u_int32_t pri_phy_errors;
+ u_int32_t ext_phy_errors;
+ u_int32_t dc_phy_errors;
+ u_int32_t early_ext_phy_errors;
+ u_int32_t bwinfo_errors;
+ u_int32_t datalen_discards;
+ u_int32_t rssi_discards;
+ u_int64_t last_reset_tstamp;
+};
+
+/*
+ * This is for debuggin DFS as console log interferes with (helps)
+ * radar detection
+*/
+
+#define DFS_EVENT_LOG_SIZE 256
+struct dfs_event_log {
+ u_int64_t ts; /* 64-bit full timestamp from interrupt time */
+ u_int32_t diff_ts; /* diff timestamp */
+ u_int8_t rssi; /* rssi of radar event */
+ u_int8_t dur; /* duration of radar pulse */
+};
+
+
+#define ATH_DFS_RESET_TIME_S 7
+#define ATH_DFS_WAIT (60 + ATH_DFS_RESET_TIME_S) /* 60 seconds */
+#define ATH_DFS_WAIT_MS ((ATH_DFS_WAIT) * 1000) /*in MS*/
+
+#define ATH_DFS_WEATHER_CHANNEL_WAIT_MIN 10 /*10 minutes*/
+#define ATH_DFS_WEATHER_CHANNEL_WAIT_S (ATH_DFS_WEATHER_CHANNEL_WAIT_MIN * 60)
+#define ATH_DFS_WEATHER_CHANNEL_WAIT_MS ((ATH_DFS_WEATHER_CHANNEL_WAIT_S) * 1000) /*in MS*/
+
+#define ATH_DFS_WAIT_POLL_PERIOD 2 /* 2 seconds */
+#define ATH_DFS_WAIT_POLL_PERIOD_MS ((ATH_DFS_WAIT_POLL_PERIOD) * 1000) /*in MS*/
+#define ATH_DFS_TEST_RETURN_PERIOD 2 /* 2 seconds */
+#define ATH_DFS_TEST_RETURN_PERIOD_MS ((ATH_DFS_TEST_RETURN_PERIOD) * 1000)/* n MS*/
+#define IS_CHANNEL_WEATHER_RADAR(chan) ((chan->ic_freq >= 5600) && (chan->ic_freq <= 5650))
+
+#define DFS_DEBUG_TIMEOUT_S 30 // debug timeout is 30 seconds
+#define DFS_DEBUG_TIMEOUT_MS (DFS_DEBUG_TIMEOUT_S * 1000)
+
+
+#define RSSI_POSSIBLY_FALSE 50
+#define SEARCH_FFT_REPORT_PEAK_MAG_THRSH 40
+
+
+
+#if 0
+struct ath_dfs_caps {
+ u_int32_t
+ ath_dfs_ext_chan_ok:1, /* Can radar be detected on the extension chan? */
+ ath_dfs_combined_rssi_ok:1, /* Can use combined radar RSSI? */
+ /* the following flag is used to indicate if radar detection scheme */
+ /* should use enhanced chirping detection algorithm. This flag also */
+ /* determines if certain radar data should be discarded to minimize */
+ /* false detection of radar. */
+ ath_dfs_use_enhancement:1,
+ ath_strong_signal_diversiry:1;
+
+ /*
+ * goes with ath_strong_signal_diversiry:
+ * If we have fast diversity capability, read off
+ * Strong Signal fast diversity count set in the ini
+ * file, and store so we can restore the value when
+ * radar is disabled
+ */
+ u_int32_t ath_fastdiv_val;
+};
+
+struct ath_dfs_radar_tab_info {
+ u_int32_t dfsdomain;
+ int numradars;
+ struct dfs_pulse *dfs_radars;
+ int numb5radars;
+ struct dfs_bin5pulse *b5pulses;
+ HAL_PHYERR_PARAM dfs_defaultparams;
+};
+#endif
+struct ath_dfs {
+ uint32_t dfs_debug_mask; /* current debug bitmask */
+ int16_t dfs_curchan_radindex; /* cur. channel radar index */
+ int16_t dfs_extchan_radindex; /* extension channel radar index */
+ u_int32_t dfsdomain; /* cur. DFS domain */
+ u_int32_t dfs_proc_phyerr; /* Flags for Phy Errs to process */
+ struct ieee80211com *ic;
+ STAILQ_HEAD(,dfs_event) dfs_eventq; /* Q of free dfs event objects */
+ dfsq_lock_t dfs_eventqlock; /* Lock for free dfs event list */
+ STAILQ_HEAD(,dfs_event) dfs_radarq; /* Q of radar events */
+ dfsq_lock_t dfs_radarqlock; /* Lock for dfs q */
+ STAILQ_HEAD(,dfs_event) dfs_arq; /* Q of AR events */
+ dfsq_lock_t dfs_arqlock; /* Lock for AR q */
+
+ struct dfs_ar_state dfs_ar_state; /* AR state */
+
+ /* dfs_radar - Per-Channel Radar detector state */
+ struct dfs_state dfs_radar[DFS_NUM_RADAR_STATES];
+
+ /* dfs_radarf - One filter for each radar pulse type */
+ struct dfs_filtertype *dfs_radarf[DFS_MAX_RADAR_TYPES];
+
+ struct dfs_info dfs_rinfo; /* State vars for radar processing */
+ struct dfs_bin5radars *dfs_b5radars;/* array of bin5 radar events */
+ int8_t **dfs_radartable; /* map of radar durs to filter types */
+#ifndef ATH_DFS_RADAR_DETECTION_ONLY
+ struct dfs_nolelem *dfs_nol; /* Non occupancy list for radar */
+ int dfs_nol_count; /* How many items? */
+#endif
+
+ struct ath_dfs_phyerr_param dfs_defaultparams; /* Default phy params per radar state */
+ struct dfs_stats ath_dfs_stats; /* DFS related stats */
+ struct dfs_pulseline *pulses; /* pulse history */
+ struct dfs_event *events; /* Events structure */
+
+ u_int32_t
+ ath_radar_tasksched:1, /* radar task is scheduled */
+ ath_dfswait:1, /* waiting on channel for radar detect */
+ ath_dfstest:1; /* Test timer in progress */
+ struct ath_dfs_caps dfs_caps;
+ u_int8_t ath_dfstest_ieeechan; /* IEEE chan num to return to after
+ * a dfs mute test */
+#ifndef ATH_DFS_RADAR_DETECTION_ONLY
+ u_int32_t ath_dfs_cac_time; /* CAC period */
+ u_int32_t ath_dfstesttime; /* Time to stay off chan during dfs test */
+ os_timer_t ath_dfswaittimer; /* dfs wait timer */
+ os_timer_t ath_dfstesttimer; /* dfs mute test timer */
+ os_timer_t ath_dfs_debug_timer; /* dfs debug timer */
+ u_int8_t dfs_bangradar;
+#endif
+ os_timer_t ath_dfs_task_timer; /* dfs wait timer */
+ int dur_multiplier;
+
+ u_int16_t ath_dfs_isdfsregdomain; /* true when we are DFS domain */
+ int ath_dfs_false_rssi_thres;
+ int ath_dfs_peak_mag;
+
+ struct dfs_event_log radar_log[DFS_EVENT_LOG_SIZE];
+ int dfs_event_log_count;
+ int dfs_event_log_on;
+ int dfs_phyerr_count; /* same as number of PHY radar interrupts */
+ int dfs_phyerr_reject_count; /* when TLV is supported, # of radar events ignored after TLV is parsed */
+ int dfs_phyerr_queued_count; /* number of radar events queued for matching the filters */
+ int dfs_phyerr_freq_min;
+ int dfs_phyerr_freq_max;
+ int dfs_phyerr_w53_counter;
+ int dfs_pri_multiplier; /* allow pulse if they are within multiple of PRI for the radar type */
+ int ath_dfs_nol_timeout;
+};
+
+/* This should match the table from if_ath.c */
+enum {
+ ATH_DEBUG_DFS = 0x00000100, /* Minimal DFS debug */
+ ATH_DEBUG_DFS1 = 0x00000200, /* Normal DFS debug */
+ ATH_DEBUG_DFS2 = 0x00000400, /* Maximal DFS debug */
+ ATH_DEBUG_DFS3 = 0x00000800, /* matched filterID display */
+
+ ATH_DEBUG_DFS_PHYERR = 0x00001000, /* phy error parsing */
+ ATH_DEBUG_DFS_NOL = 0x00002000, /* NOL related entries */
+ ATH_DEBUG_DFS_PHYERR_SUM = 0x00004000, /* PHY error summary */
+ ATH_DEBUG_DFS_PHYERR_PKT = 0x00008000, /* PHY error payload */
+
+ ATH_DEBUG_DFS_BIN5 = 0x00010000, /* bin5 checks */
+ ATH_DEBUG_DFS_BIN5_FFT = 0x00020000, /* bin5 FFT check */
+ ATH_DEBUG_DFS_BIN5_PULSE = 0x00040000, /* bin5 pulse check */
+};
+
+#define IS_CHAN_HT40(_c) IEEE80211_IS_CHAN_11N_HT40(_c)
+#define IS_CHAN_HT40_PLUS(_c) IEEE80211_IS_CHAN_11N_HT40PLUS(_c)
+#define IS_CHAN_HT40_MINUS(_c) IEEE80211_IS_CHAN_11N_HT40MINUS(_c)
+
+/*
+ * chirp notes!
+ *
+ * Pre-Sowl chips don't do FFT reports, so chirp pulses simply show up
+ * as long duration pulses.
+ *
+ * The bin5 checking code would simply look for a chirp pulse of the correct
+ * duration (within MIN_BIN5_DUR and MAX_BIN5_DUR) and add it to the "chirp"
+ * pattern.
+ *
+ * For Sowl and later, an FFT was done on longer duration frames. If those
+ * frames looked like a chirp, their duration was adjusted to fall within
+ * the chirp duration limits. If the pulse failed the chirp test (it had
+ * no FFT data or the FFT didn't meet the chirping requirements) then the
+ * pulse duration was adjusted to be greater than MAX_BIN5_DUR, so it
+ * would always fail chirp detection.
+ *
+ * This is pretty horrible.
+ *
+ * The eventual goal for chirp handling is thus:
+ *
+ * + In case someone ever wants to do chirp detection with this code on
+ * chips that don't support chirp detection, you can still do it based
+ * on pulse duration. That's your problem to solve.
+ *
+ * + For chips that do hardware chirp detection or FFT, the "do_check_chirp"
+ * bit should be set.
+ *
+ * + Then, either is_hw_chirp or is_sw_chirp is set, indicating that
+ * the hardware or software post-processing of the chirp event found
+ * that indeed it was a chirp.
+ *
+ * + Finally, the bin5 code should just check whether the chirp bits are
+ * set and behave appropriately, falling back onto the duration checks
+ * if someone wishes to use this on older hardware (or with disabled
+ * FFTs, for whatever reason.)
+ */
+/*
+ * XXX TODO:
+ *
+ * + add duration in uS and raw duration, so the PHY error parsing
+ * code is responsible for doing the duration calculation;
+ * + add ts in raw and corrected, so the PHY error parsing
+ * code is responsible for doing the offsetting, not the radar
+ * event code.
+ */
+struct dfs_phy_err {
+ u_int64_t fulltsf; /* 64-bit TSF as read from MAC */
+
+ uint32_t is_pri:1, /* detected on primary channel */
+ is_ext:1, /* detected on extension channel */
+ is_dc:1, /* detected at DC */
+ is_early:1, /* early detect */
+ do_check_chirp:1, /* whether to check hw_chirp/sw_chirp */
+ is_hw_chirp:1, /* hardware-detected chirp */
+ is_sw_chirp:1; /* software detected chirp */
+
+ u_int32_t rs_tstamp; /* 32 bit TSF from RX descriptor (event) */
+ u_int32_t freq; /* Centre frequency of event - KHz */
+ u_int32_t freq_lo; /* Lower bounds of frequency - KHz */
+ u_int32_t freq_hi; /* Upper bounds of frequency - KHz */
+
+ u_int8_t rssi; /* pulse RSSI */
+ u_int8_t dur; /* pulse duration, raw (not uS) */
+};
+
+/* Attach, detach, handle ioctl prototypes */
+
+int dfs_get_thresholds(struct ieee80211com *ic,
+ struct ath_dfs_phyerr_param *param);
+int dfs_set_thresholds(struct ieee80211com *ic,
+ const u_int32_t threshtype, const u_int32_t value);
+
+/* PHY error and radar event handling */
+int dfs_process_radarevent(struct ath_dfs *dfs, struct ieee80211_channel *chan);
+
+/* Non occupancy (NOL) handling prototypes */
+void dfs_nol_addchan(struct ath_dfs *dfs, struct ieee80211_channel *chan, u_int32_t dfs_nol_timeout);
+void dfs_get_nol(struct ath_dfs *dfs, struct dfsreq_nolelem *dfs_nol, int *nchan);
+void dfs_set_nol(struct ath_dfs *dfs, struct dfsreq_nolelem *dfs_nol, int nchan);
+void dfs_nol_update(struct ath_dfs *dfs);
+void dfs_nol_timer_cleanup(struct ath_dfs *dfs);
+
+/* FCC Bin5 detection prototypes */
+int dfs_bin5_check_pulse(struct ath_dfs *dfs, struct dfs_event *re,
+ struct dfs_bin5radars *br);
+int dfs_bin5_addpulse(struct ath_dfs *dfs, struct dfs_bin5radars *br,
+ struct dfs_event *re, u_int64_t thists);
+int dfs_bin5_check(struct ath_dfs *dfs);
+int dfs_check_chirping(struct ath_dfs *dfs, void *buf,
+ u_int16_t datalen, int is_ctl,
+ int is_ext, int *slope, int *is_dc);
+u_int8_t dfs_retain_bin5_burst_pattern(struct ath_dfs *dfs, u_int32_t diff_ts, u_int8_t old_dur);
+u_int8_t dfs_retain_bin5_burst_pattern(struct ath_dfs *dfs, u_int32_t diff_ts, u_int8_t old_dur);
+int dfs_get_random_bin5_dur(struct ath_dfs *dfs, u_int64_t tstamp);
+
+/* Debug prototypes */
+void dfs_print_delayline(struct ath_dfs *dfs, struct dfs_delayline *dl);
+void dfs_print_nol(struct ath_dfs *dfs);
+void dfs_print_filters(struct ath_dfs *dfs);
+void dfs_print_activity(struct ath_dfs *dfs);
+OS_TIMER_FUNC(dfs_debug_timeout);
+void dfs_print_filter(struct ath_dfs *dfs, struct dfs_filter *rf);
+
+/* Misc prototypes */
+u_int32_t dfs_round(int32_t val);
+struct dfs_state* dfs_getchanstate(struct ath_dfs *dfs, u_int8_t *index, int ext_ch_flag);
+
+/* Reset and init data structures */
+
+int dfs_init_radar_filters( struct ieee80211com *ic, struct ath_dfs_radar_tab_info *radar_info);
+void dfs_reset_alldelaylines(struct ath_dfs *dfs);
+void dfs_reset_delayline(struct dfs_delayline *dl);
+void dfs_reset_filter_delaylines(struct dfs_filtertype *dft);
+void dfs_reset_radarq(struct ath_dfs *dfs);
+
+/* Detection algorithm prototypes */
+void dfs_add_pulse(struct ath_dfs *dfs, struct dfs_filter *rf,
+ struct dfs_event *re, u_int32_t deltaT, u_int64_t this_ts);
+
+int dfs_bin_fixedpattern_check(struct ath_dfs *dfs, struct dfs_filter *rf,
+ u_int32_t dur, int ext_chan_flag);
+int dfs_bin_check(struct ath_dfs *dfs, struct dfs_filter *rf,
+ u_int32_t deltaT, u_int32_t dur, int ext_chan_flag);
+
+int dfs_bin_pri_check(struct ath_dfs *dfs, struct dfs_filter *rf,
+ struct dfs_delayline *dl, u_int32_t score,
+ u_int32_t refpri, u_int32_t refdur, int ext_chan_flag, int fundamentalpri);
+int dfs_staggered_check(struct ath_dfs *dfs, struct dfs_filter *rf,
+ u_int32_t deltaT, u_int32_t width);
+/* False detection reduction */
+int dfs_get_pri_margin(struct ath_dfs *dfs, int is_extchan_detect,
+ int is_fixed_pattern);
+int dfs_get_filter_threshold(struct ath_dfs *dfs, struct dfs_filter *rf,
+ int is_extchan_detect);
+
+/* AR related prototypes */
+
+/* Commenting out since all the ar functions are obsolete and
+ * the function definition has been removed as part of dfs_ar.c
+ * void dfs_process_ar_event(struct ath_dfs *dfs, struct ieee80211_channel *chan);
+ */
+/* Commenting out since all the ar functions are obsolete and
+ * the function definition has been removed as part of dfs_ar.c
+ * void ath_ar_disable(struct ath_dfs *dfs);
+ */
+/* Commenting out since all the ar functions are obsolete and
+ * the function definition has been removed as part of dfs_ar.c
+ * void ath_ar_enable(struct ath_dfs *dfs);
+ */
+void dfs_reset_ar(struct ath_dfs *dfs);
+/* Commenting out since all the ar functions are obsolete and
+ * the function definition has been removed as part of dfs_ar.c
+ * void dfs_reset_arq(struct ath_dfs *dfs);
+ */
+
+
+struct ieee80211_channel *ieee80211_get_extchan(struct ieee80211com *ic);
+
+#endif /* _DFS_H_ */
diff --git a/CORE/SERVICES/DFS/src/dfs_bindetects.c b/CORE/SERVICES/DFS/src/dfs_bindetects.c
new file mode 100644
index 000000000000..a01285e6207b
--- /dev/null
+++ b/CORE/SERVICES/DFS/src/dfs_bindetects.c
@@ -0,0 +1,461 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ dfs_bindetects.c
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+
+#include "dfs.h"
+/*TO DO DFS removing
+#include <ieee80211_var.h>
+*/
+#ifdef ATH_SUPPORT_DFS
+
+int
+dfs_bin_fixedpattern_check(struct ath_dfs *dfs, struct dfs_filter *rf, u_int32_t dur, int ext_chan_flag)
+{
+ struct dfs_pulseline *pl = dfs->pulses;
+ int i, n, refpri, primargin, numpulses=0;
+ u_int64_t start_ts, end_ts, event_ts, prev_event_ts, next_event_ts, window_start, window_end;
+ u_int32_t index, next_index, deltadur;
+
+ /* For fixed pattern types, rf->rf_patterntype=1*/
+ primargin = dfs_get_pri_margin(dfs, ext_chan_flag, (rf->rf_patterntype==1));
+
+ refpri = (rf->rf_minpri + rf->rf_maxpri)/2;
+ index = pl->pl_lastelem;
+ end_ts = pl->pl_elems[index].p_time;
+ start_ts = end_ts - (refpri*rf->rf_numpulses);
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS3,
+ "lastelem ts=%llu start_ts=%llu, end_ts=%llu\n",
+ (unsigned long long) pl->pl_elems[index].p_time,
+ (unsigned long long) start_ts,
+ (unsigned long long) end_ts);
+
+ /* find the index of first element in our window of interest */
+ for(i=0;i<pl->pl_numelems;i++) {
+ index = (index-1) & DFS_MAX_PULSE_BUFFER_MASK;
+ if(pl->pl_elems[index].p_time >= start_ts )
+ continue;
+ else {
+ index = (index) & DFS_MAX_PULSE_BUFFER_MASK;
+ break;
+ }
+ }
+ for (n=0;n<=rf->rf_numpulses; n++) {
+ window_start = (start_ts + (refpri*n))-(primargin+n);
+ window_end = window_start + 2*(primargin+n);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "window_start %u window_end %u \n",
+ (u_int32_t)window_start, (u_int32_t)window_end);
+ for(i=0;i<pl->pl_numelems;i++) {
+ prev_event_ts = pl->pl_elems[index].p_time;
+ index = (index+1) & DFS_MAX_PULSE_BUFFER_MASK;
+ event_ts = pl->pl_elems[index].p_time;
+ next_index = (index+1) & DFS_MAX_PULSE_BUFFER_MASK;
+ next_event_ts = pl->pl_elems[next_index].p_time;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "ts %u \n", (u_int32_t)event_ts);
+ if( (event_ts <= window_end) && (event_ts >= window_start)){
+ deltadur = DFS_DIFF(pl->pl_elems[index].p_dur, dur);
+ if( (pl->pl_elems[index].p_dur == 1) ||
+ ((dur != 1) && (deltadur <= 2))) {
+ numpulses++;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "numpulses %u \n", numpulses);
+ break;
+ }
+ }
+ else if( event_ts > window_end) {
+ index = (index-1) & DFS_MAX_PULSE_BUFFER_MASK;
+ break;
+ }
+ else if( event_ts == prev_event_ts) {
+ if( ((next_event_ts - event_ts) > refpri) ||
+ ((next_event_ts - event_ts) == 0)) {
+ deltadur = DFS_DIFF(pl->pl_elems[index].p_dur, dur);
+ if( (pl->pl_elems[index].p_dur == 1) ||
+ ((pl->pl_elems[index].p_dur != 1) && (deltadur <= 2))) {
+ numpulses++;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "zero PRI: numpulses %u \n", numpulses);
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (numpulses >= dfs_get_filter_threshold(dfs, rf, ext_chan_flag)) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s FOUND filterID=%u numpulses=%d unadj thresh=%d\n", __func__, rf->rf_pulseid, numpulses, rf->rf_threshold);
+ return 1;
+ }
+ else
+ return 0;
+}
+
+void
+dfs_add_pulse(struct ath_dfs *dfs, struct dfs_filter *rf, struct dfs_event *re,
+ u_int32_t deltaT, u_int64_t this_ts)
+{
+ u_int32_t index,n, window;
+ struct dfs_delayline *dl;
+
+ dl = &rf->rf_dl;
+ /* Circular buffer of size 2^n */
+ index = (dl->dl_lastelem + 1) & DFS_MAX_DL_MASK;
+ //if ((dl->dl_numelems+1) == DFS_MAX_DL_SIZE)
+ if ((dl->dl_numelems) == DFS_MAX_DL_SIZE)
+ dl->dl_firstelem = (dl->dl_firstelem + 1) & DFS_MAX_DL_MASK;
+ else
+ dl->dl_numelems++;
+ dl->dl_lastelem = index;
+ dl->dl_elems[index].de_time = deltaT;
+ dl->dl_elems[index].de_ts = this_ts;
+ window = deltaT;
+ dl->dl_elems[index].de_dur = re->re_dur;
+ dl->dl_elems[index].de_rssi = re->re_rssi;
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "%s: adding: filter id %d, dur=%d, rssi=%d, ts=%llu\n",
+ __func__,
+ rf->rf_pulseid,
+ re->re_dur,
+ re->re_rssi,
+ (unsigned long long int) this_ts);
+
+ for (n=0;n<dl->dl_numelems-1; n++) {
+ index = (index-1) & DFS_MAX_DL_MASK;
+ /*
+ * calculate window based on full time stamp instead of deltaT
+ * deltaT (de_time) may result in incorrect window value
+ */
+ window = (u_int32_t) (this_ts - dl->dl_elems[index].de_ts);
+
+ if (window > rf->rf_filterlen) {
+ dl->dl_firstelem = (index+1) & DFS_MAX_DL_MASK;
+ dl->dl_numelems = n+1;
+ }
+ }
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "dl firstElem = %d lastElem = %d\n",dl->dl_firstelem,
+ dl->dl_lastelem);
+}
+
+
+int
+dfs_bin_check(struct ath_dfs *dfs, struct dfs_filter *rf, u_int32_t deltaT,
+ u_int32_t width, int ext_chan_flag)
+{
+ u_int32_t refpri, refdur, searchpri, deltapri,deltapri_2,deltapri_3, averagerefpri;
+ u_int32_t n, i, primargin, durmargin, highscore, highscoreindex;
+ int score[DFS_MAX_DL_SIZE], delayindex, dindex, found=0;
+ struct dfs_delayline *dl;
+ u_int32_t scoreindex, lowpriindex= 0, lowpri = 0xffff;
+ int numpulses=0;
+ int lowprichk=3, pri_match=0;
+
+ dl = &rf->rf_dl;
+ if( dl->dl_numelems < (rf->rf_threshold-1)) {
+ return 0;
+ }
+ if( deltaT > rf->rf_filterlen)
+ return 0;
+
+ primargin = dfs_get_pri_margin(dfs, ext_chan_flag, (rf->rf_patterntype==1));
+
+
+ if(rf->rf_maxdur < 10) {
+ durmargin = 4;
+ }
+ else {
+ durmargin = 6;
+ }
+
+ if( rf->rf_patterntype == 1 ){
+ found = dfs_bin_fixedpattern_check(dfs, rf, width, ext_chan_flag);
+ if(found) {
+ dl->dl_numelems = 0;
+ }
+ return found;
+ }
+
+ OS_MEMZERO(score, sizeof(int)*DFS_MAX_DL_SIZE);
+ /* find out the lowest pri */
+ for (n=0;n<dl->dl_numelems; n++) {
+ delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
+ refpri = dl->dl_elems[delayindex].de_time;
+ if( refpri == 0)
+ continue;
+ else if(refpri < lowpri) {
+ lowpri = dl->dl_elems[delayindex].de_time;
+ lowpriindex = n;
+ }
+ }
+ /* find out the each delay element's pri score */
+ for (n=0;n<dl->dl_numelems; n++) {
+ delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
+ refpri = dl->dl_elems[delayindex].de_time;
+ if( refpri == 0)
+ continue;
+ if (refpri < rf->rf_maxpri) { // use only valid PRI range for high score
+ for (i=0;i<dl->dl_numelems; i++) {
+ dindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK;
+ searchpri = dl->dl_elems[dindex].de_time;
+ deltapri = DFS_DIFF(searchpri, refpri);
+ deltapri_2 = DFS_DIFF(searchpri, 2*refpri);
+ deltapri_3 = DFS_DIFF(searchpri, 3*refpri);
+ if (rf->rf_ignore_pri_window==2) {
+ pri_match = ((deltapri < primargin) || (deltapri_2 < primargin) || (deltapri_3 < primargin));
+ } else {
+ pri_match = (deltapri < primargin);
+ }
+
+ if (pri_match)
+ score[n]++;
+ }
+ } else {
+ score[n] = 0;
+ }
+ if( score[n] > rf->rf_threshold) {
+ /* we got the most possible candidate,
+ * no need to continue further */
+ break;
+ }
+ }
+ /* find out the high scorer */
+ highscore = 0;
+ highscoreindex = 0;
+ for (n=0;n<dl->dl_numelems; n++) {
+ if( score[n] > highscore) {
+ highscore = score[n];
+ highscoreindex = n;
+ }
+ else if( score[n] == highscore ) {
+ /*more than one pri has highscore take the least pri */
+ delayindex = (dl->dl_firstelem + highscoreindex) & DFS_MAX_DL_MASK;
+ dindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
+ if( dl->dl_elems[dindex].de_time <=
+ dl->dl_elems[delayindex].de_time ) {
+ highscoreindex = n;
+ }
+ }
+ }
+ /* find the average pri of pulses around the pri of highscore or
+ * the pulses around the lowest pri */
+ if (rf->rf_ignore_pri_window > 0) {
+ lowprichk = (rf->rf_threshold >> 1)+1;
+ } else {
+ lowprichk = 3;
+ }
+
+ if( highscore < lowprichk) {
+ scoreindex = lowpriindex;
+ }
+ else {
+ scoreindex = highscoreindex;
+ }
+ /* We got the possible pri, save its parameters as reference */
+ delayindex = (dl->dl_firstelem + scoreindex) & DFS_MAX_DL_MASK;
+ refdur = dl->dl_elems[delayindex].de_dur;
+ refpri = dl->dl_elems[delayindex].de_time;
+ averagerefpri = 0;
+
+ if (rf->rf_fixed_pri_radar_pulse) {
+ refpri = (rf->rf_minpri + rf->rf_maxpri)/2;
+ }
+
+ numpulses = dfs_bin_pri_check(dfs, rf, dl, score[scoreindex], refpri,
+ refdur, ext_chan_flag, refpri);
+ if (numpulses >= dfs_get_filter_threshold(dfs, rf, ext_chan_flag)) {
+ found = 1;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "ext_flag=%d MATCH filter=%u numpulses=%u thresh=%u refdur=%d refpri=%d primargin=%d\n", ext_chan_flag, rf->rf_pulseid, numpulses,rf->rf_threshold, refdur, refpri, primargin);
+ dfs_print_delayline(dfs, &rf->rf_dl);
+ dfs_print_filter(dfs, rf);
+ }
+ return found;
+}
+
+int
+dfs_bin_pri_check(struct ath_dfs *dfs, struct dfs_filter *rf,
+ struct dfs_delayline *dl, u_int32_t score, u_int32_t refpri,
+ u_int32_t refdur, int ext_chan_flag, int fundamentalpri)
+{
+ u_int32_t searchpri, searchdur, searchrssi, deltapri = 0,deltapri1 = 0, deltapri2 = 0, deltadur, averagerefpri=0,MatchCount = 0;
+ u_int32_t delta_ts_variance, delta_time_stamps, prev_good_timestamp=0;
+ int delayindex, dindex;
+ u_int32_t i, j=0, primargin, durmargin, highscore=score, highscoreindex=0;
+ int numpulses=1; //first pulse in the burst is most likely being filtered out based on maxfilterlen
+ int priscorechk=1,numpulsetochk=2,primatch=0;
+
+ //Use the adjusted PRI margin to reduce false alarms
+ /* For non fixed pattern types, rf->rf_patterntype=0*/
+ primargin = dfs_get_pri_margin(dfs, ext_chan_flag, (rf->rf_patterntype==1));
+
+ if ( (refpri > rf->rf_maxpri) || (refpri < rf->rf_minpri) ) {
+ numpulses = 0;
+ return numpulses;
+ }
+
+
+ if(rf->rf_maxdur < 10) {
+ durmargin = 4;
+ } else {
+ durmargin = 6;
+ }
+
+ if ((!rf->rf_fixed_pri_radar_pulse)) {
+ if (rf->rf_ignore_pri_window==1) {
+ priscorechk = (rf->rf_threshold >> 1);
+ } else {
+ priscorechk = 1;
+ }
+
+ MatchCount = 0;
+ if( score > priscorechk) {
+ for (i=0;i<dl->dl_numelems; i++) {
+ dindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK;
+ searchpri = dl->dl_elems[dindex].de_time;
+ deltapri = DFS_DIFF(searchpri, refpri);
+ if( deltapri < primargin) {
+ averagerefpri += searchpri;
+ MatchCount++;
+ }
+ }
+ if (rf->rf_patterntype != 2) {
+ if (MatchCount > 0)
+ refpri = (averagerefpri/MatchCount); //average
+ } else {
+ refpri = (averagerefpri/score);
+ }
+ }
+ }
+ /* Note: Following primultiple calculation should be done once per filter
+ * during initialization stage (dfs_attach) and stored in its array
+ * atleast for fixed frequency types like FCC Bin1 to save some CPU cycles.
+ * multiplication, devide operators in the following code are left as it is
+ * for readability hoping the complier will use left/right shifts wherever possible
+ */
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "refpri = %d high score = %d index = %d numpulses = %d\n",
+ refpri, highscore, highscoreindex, numpulses);
+ /* Count the other delay elements that have pri and dur with in the
+ * acceptable range from the reference one */
+ for (i=0; i<dl->dl_numelems; i++) {
+ delayindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK;
+ searchpri = dl->dl_elems[delayindex].de_time;
+ if( searchpri == 0) {
+ /* This events PRI is zero, take it as a
+ * valid pulse but decrement next event's PRI by refpri
+ */
+ dindex = (delayindex+1)& DFS_MAX_DL_MASK;
+ dl->dl_elems[dindex].de_time -= refpri;
+ searchpri = refpri;
+ }
+ searchdur = dl->dl_elems[delayindex].de_dur;
+ searchrssi = dl->dl_elems[delayindex].de_rssi;
+ deltadur = DFS_DIFF(searchdur, refdur);
+ deltapri = DFS_DIFF(searchpri, refpri);
+
+ //deltapri3 = DFS_DIFF(searchpri, 3 * refpri);
+ primatch=0;
+
+ if ((rf->rf_ignore_pri_window>0) && (rf->rf_patterntype!=2)) {
+ for (j=0;j<rf->rf_numpulses;j++){
+ deltapri1 = DFS_DIFF(searchpri, (j+1)*refpri);
+ if (deltapri1 < (2*primargin)) {
+ primatch = 1;
+ break;
+ }
+ }
+ } else {
+ if (( deltapri1 < primargin) || ( deltapri2 < primargin)) {
+ primatch = 1;
+ }
+ }
+
+ if ( primatch && ( deltadur < durmargin) ) {
+ if ( (numpulses == 1) ) {
+ numpulses++;
+ } else {
+ delta_time_stamps = dl->dl_elems[delayindex].de_ts - prev_good_timestamp;
+ if ((rf->rf_ignore_pri_window>0)) {
+ numpulsetochk = rf->rf_numpulses;
+
+ if ((rf->rf_patterntype==2) && (fundamentalpri<refpri+100)) {
+ numpulsetochk = 4;
+ }
+ } else {
+ numpulsetochk = 4;
+ }
+ for (j = 0; j < numpulsetochk; j++){
+ delta_ts_variance = DFS_DIFF(delta_time_stamps, ((j+1)*fundamentalpri));
+ if ( delta_ts_variance < (2*(j+1)*primargin) ) {
+ numpulses++;
+ if (rf->rf_ignore_pri_window>0) {
+ break;
+ }
+ }
+ }
+ }
+ prev_good_timestamp = dl->dl_elems[delayindex].de_ts;
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "rf->minpri=%d rf->maxpri=%d searchpri = %d index = %d numpulses = %d deltapri=%d j=%d\n",
+ rf->rf_minpri, rf->rf_maxpri, searchpri, i, numpulses, deltapri, j);
+ }
+
+ }
+ return numpulses;
+}
+#endif /* ATH_SUPPORT_DFS */
diff --git a/CORE/SERVICES/DFS/src/dfs_debug.c b/CORE/SERVICES/DFS/src/dfs_debug.c
new file mode 100644
index 000000000000..5164f737d22b
--- /dev/null
+++ b/CORE/SERVICES/DFS/src/dfs_debug.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ dfs_debug.c
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+#include "dfs.h"
+/* TO DO DFS
+#include <ieee80211_var.h>
+*/
+#ifdef ATH_SUPPORT_DFS
+
+void
+dfs_print_delayline(struct ath_dfs *dfs, struct dfs_delayline *dl)
+{
+ int i=0,index;
+ struct dfs_delayelem *de;
+
+ index = dl->dl_lastelem;
+ for (i=0; i<dl->dl_numelems; i++) {
+ de = &dl->dl_elems[index];
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "Elem %d: ts = %u (0x%x) dur=%u\n",i,
+ de->de_time, de->de_time, de->de_dur);
+ index = (index - 1)& DFS_MAX_DL_MASK;
+ }
+}
+void
+dfs_print_filter(struct ath_dfs *dfs, struct dfs_filter *rf)
+{
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
+ "filterID[%d] rf_numpulses=%u; rf->rf_minpri=%u; "
+ "rf->rf_maxpri=%u; rf->rf_threshold=%u; rf->rf_filterlen=%u; "
+ "rf->rf_mindur=%u; rf->rf_maxdur=%u\n",
+ rf->rf_pulseid,
+ rf->rf_numpulses,
+ rf->rf_minpri,
+ rf->rf_maxpri,
+ rf->rf_threshold,
+ rf->rf_filterlen,
+ rf->rf_mindur,
+ rf->rf_maxdur);
+}
+
+void
+dfs_print_filters(struct ath_dfs *dfs)
+{
+ struct dfs_filtertype *ft = NULL;
+ struct dfs_filter *rf;
+ int i,j;
+
+ if (dfs == NULL) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: sc_dfs is NULL\n", __func__);
+ return;
+ }
+ for (i=0; i<DFS_MAX_RADAR_TYPES; i++) {
+ if (dfs->dfs_radarf[i] != NULL) {
+ ft = dfs->dfs_radarf[i];
+ if((ft->ft_numfilters > DFS_MAX_NUM_RADAR_FILTERS) || (!ft->ft_numfilters))
+ continue;
+ DFS_PRINTK("===========ft->ft_numfilters=%u===========\n", ft->ft_numfilters);
+ for (j=0; j<ft->ft_numfilters; j++) {
+ rf = &(ft->ft_filters[j]);
+ DFS_PRINTK("filter[%d] filterID = %d rf_numpulses=%u; rf->rf_minpri=%u; rf->rf_maxpri=%u; rf->rf_threshold=%u; rf->rf_filterlen=%u; rf->rf_mindur=%u; rf->rf_maxdur=%u\n",j, rf->rf_pulseid,
+ rf->rf_numpulses, rf->rf_minpri, rf->rf_maxpri, rf->rf_threshold, rf->rf_filterlen, rf->rf_mindur, rf->rf_maxdur);
+ }
+ }
+ }
+}
+
+void dfs_print_activity(struct ath_dfs *dfs)
+{
+ int chan_busy=0, ext_chan_busy=0;
+ u_int32_t rxclear=0, rxframe=0, txframe=0, cycles=0;
+
+ cycles = dfs->ic->ic_get_mib_cycle_counts_pct(dfs->ic, &rxclear, &rxframe, &txframe);
+ chan_busy = cycles;
+
+ ext_chan_busy = dfs->ic->ic_get_ext_busy(dfs->ic);
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS,"cycles=%d rxclear=%d rxframe=%d"
+ " txframe=%d extchanbusy=%d\n", cycles, rxclear,
+ rxframe, txframe, ext_chan_busy);
+ return;
+}
+
+/*
+ * XXX migrate this to use ath_dfs as the arg, not ieee80211com!
+ */
+#ifndef ATH_DFS_RADAR_DETECTION_ONLY
+OS_TIMER_FUNC(dfs_debug_timeout)
+{
+ struct ieee80211com *ic;
+ struct ath_dfs* dfs;
+
+ OS_GET_TIMER_ARG(ic, struct ieee80211com *);
+
+ dfs = (struct ath_dfs *)ic->ic_dfs;
+
+ dfs_print_activity(dfs);
+
+ OS_SET_TIMER(&dfs->ath_dfs_debug_timer, DFS_DEBUG_TIMEOUT_MS);
+}
+#endif
+
+#endif /* ATH_SUPPORT_DFS */
diff --git a/CORE/SERVICES/DFS/src/dfs_fcc_bin5.c b/CORE/SERVICES/DFS/src/dfs_fcc_bin5.c
new file mode 100644
index 000000000000..983905b73740
--- /dev/null
+++ b/CORE/SERVICES/DFS/src/dfs_fcc_bin5.c
@@ -0,0 +1,829 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ dfs_fcc_bin5.c
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+#include "dfs.h"
+/* TO DO DFS
+#include <ieee80211_var.h>
+*/
+#ifdef ATH_SUPPORT_DFS
+
+/*
+ * Reject the pulse if:
+ * + It's outside the RSSI threshold;
+ * + It's outside the pulse duration;
+ * + It's been verified by HW/SW chirp checking
+ * and neither of those found a chirp.
+ */
+int
+dfs_bin5_check_pulse(struct ath_dfs *dfs, struct dfs_event *re,
+ struct dfs_bin5radars *br)
+{
+ int b5_rssithresh = br->br_pulse.b5_rssithresh;
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_PULSE,
+ "%s: re_dur=%d, rssi=%d, check_chirp=%d, "
+ "hw_chirp=%d, sw_chirp=%d\n",
+ __func__,
+ (int) re->re_dur,
+ (int) re->re_rssi,
+ !! (re->re_flags & DFS_EVENT_CHECKCHIRP),
+ !! (re->re_flags & DFS_EVENT_HW_CHIRP),
+ !! (re->re_flags & DFS_EVENT_SW_CHIRP));
+
+ /*
+ * If the sw/hw chirp detection says to fail the pulse,
+ * do so.
+ */
+ if (DFS_EVENT_NOTCHIRP(re)) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5,
+ "%s: rejecting chirp: ts=%llu, dur=%d, rssi=%d "
+ "checkchirp=%d, hwchirp=%d, swchirp=%d\n",
+ __func__,
+ (unsigned long long) re->re_full_ts,
+ (int) re->re_dur,
+ (int) re->re_rssi,
+ !! (re->re_flags & DFS_EVENT_CHECKCHIRP),
+ !! (re->re_flags & DFS_EVENT_HW_CHIRP),
+ !! (re->re_flags & DFS_EVENT_SW_CHIRP));
+ return (0);
+ }
+
+ /* Adjust the filter threshold for rssi in non TURBO mode */
+ if( ! (dfs->ic->ic_curchan->ic_flags & CHANNEL_TURBO))
+ b5_rssithresh += br->br_pulse.b5_rssimargin;
+
+ /*
+ * Check if the pulse is within duration and rssi
+ * thresholds.
+ */
+ if ((re->re_dur >= br->br_pulse.b5_mindur) &&
+ (re->re_dur <= br->br_pulse.b5_maxdur) &&
+ (re->re_rssi >= b5_rssithresh)) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5,
+ "%s: dur=%d, rssi=%d - adding!\n",
+ __func__, (int) re->re_dur, (int) re->re_rssi);
+ return (1);
+ }
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5,
+ "%s: too low to be Bin5 pulse tsf=%llu, dur=%d, rssi=%d\n",
+ __func__,
+ (unsigned long long) re->re_full_ts,
+ (int) re->re_dur,
+ (int) re->re_rssi);
+
+ return (0);
+}
+
+
+int dfs_bin5_addpulse(struct ath_dfs *dfs, struct dfs_bin5radars *br,
+ struct dfs_event *re, u_int64_t thists)
+{
+ u_int32_t index,stop;
+ u_int64_t tsDelta;
+
+ /* Check if this pulse is a valid pulse in terms of repetition,
+ * if not, return without adding it to the queue.
+ * PRI : Pulse Repitetion Interval
+ * BRI : Burst Repitetion Interval */
+ if( br->br_numelems != 0){
+ index = br->br_lastelem;
+ tsDelta = thists - br->br_elems[index].be_ts;
+ if( (tsDelta < DFS_BIN5_PRI_LOWER_LIMIT) ||
+ ( (tsDelta > DFS_BIN5_PRI_HIGHER_LIMIT) &&
+ (tsDelta < DFS_BIN5_BRI_LOWER_LIMIT))) {
+ return 0;
+ }
+ }
+ /* Circular buffer of size 2^n */
+ index = (br->br_lastelem +1) & DFS_MAX_B5_MASK;
+ br->br_lastelem = index;
+ if (br->br_numelems == DFS_MAX_B5_SIZE)
+ br->br_firstelem = (br->br_firstelem+1)&DFS_MAX_B5_MASK;
+ else
+ br->br_numelems++;
+ br->br_elems[index].be_ts = thists;
+ br->br_elems[index].be_rssi = re->re_rssi;
+ br->br_elems[index].be_dur = re->re_dur; /* please note that this is in u-sec */
+ stop = 0;
+ index = br->br_firstelem;
+ while ((!stop) && (br->br_numelems-1) > 0) {
+ if ((thists - br->br_elems[index].be_ts) >
+ ((u_int64_t) br->br_pulse.b5_timewindow)) {
+ br->br_numelems--;
+ br->br_firstelem = (br->br_firstelem +1) & DFS_MAX_B5_MASK;
+ index = br->br_firstelem;
+ } else
+ stop = 1;
+ }
+ return 1;
+}
+
+/*
+ * If the dfs structure is NULL (which should be illegal if everyting is working
+ * properly, then signify that a bin5 radar was found
+ */
+
+int
+dfs_bin5_check(struct ath_dfs *dfs)
+{
+ struct dfs_bin5radars *br;
+ int index[DFS_MAX_B5_SIZE];
+ u_int32_t n = 0, i = 0, i1 = 0, this = 0, prev = 0, rssi_diff = 0, width_diff = 0, bursts= 0;
+ u_int32_t total_diff=0, average_diff=0, total_width=0, average_width=0, numevents=0;
+ u_int64_t pri;
+
+
+ if (dfs == NULL) {
+ DFS_PRINTK("%s: ic_dfs is NULL\n", __func__);
+ return 1;
+ }
+ for (n=0;n<dfs->dfs_rinfo.rn_numbin5radars; n++) {
+ br = &(dfs->dfs_b5radars[n]);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5,
+ "Num elems = %d\n", br->br_numelems);
+
+ /* find a valid bin 5 pulse and use it as reference */
+ for(i1=0;i1 < br->br_numelems; i1++) {
+ this = ((br->br_firstelem +i1) & DFS_MAX_B5_MASK);
+ if ((br->br_elems[this].be_dur >= MIN_BIN5_DUR_MICROSEC) &&
+ (br->br_elems[this].be_dur <= MAX_BIN5_DUR_MICROSEC)) {
+ break;
+ }
+ }
+
+ prev = this;
+ for(i = i1 + 1; i < br->br_numelems; i++){
+ this = ((br->br_firstelem +i) & DFS_MAX_B5_MASK);
+
+ /* first make sure it is a bin 5 pulse by checking the duration */
+ if ((br->br_elems[this].be_dur < MIN_BIN5_DUR_MICROSEC) || (br->br_elems[this].be_dur > MAX_BIN5_DUR_MICROSEC)) {
+ continue;
+ }
+
+ /* Rule 1: 1000 <= PRI <= 2000 + some margin */
+ if( br->br_elems[this].be_ts >= br->br_elems[prev].be_ts ) {
+ pri = br->br_elems[this].be_ts - br->br_elems[prev].be_ts;
+ }
+ else {//roll over case
+ //pri = (0xffffffffffffffff - br->br_elems[prev].be_ts) + br->br_elems[this].be_ts;
+ pri = br->br_elems[this].be_ts;
+ }
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5,
+ " pri=%llu this.ts=%llu this.dur=%d this.rssi=%d prev.ts=%llu\n",
+ (unsigned long long)pri,
+ (unsigned long long)br->br_elems[this].be_ts,
+ (int) br->br_elems[this].be_dur,
+ (int) br->br_elems[this].be_rssi,
+ (unsigned long long)br->br_elems[prev].be_ts);
+ if(( (pri >= DFS_BIN5_PRI_LOWER_LIMIT) && (pri <= DFS_BIN5_PRI_HIGHER_LIMIT))) { //pri: pulse repitition interval in us
+ /* Rule 2: pulse width of the pulses in the burst should be same (+/- margin) */
+ if( br->br_elems[this].be_dur >= br->br_elems[prev].be_dur) {
+ width_diff = br->br_elems[this].be_dur - br->br_elems[prev].be_dur;
+ }
+ else {
+ width_diff = br->br_elems[prev].be_dur - br->br_elems[this].be_dur;
+ }
+ if( width_diff <= DFS_BIN5_WIDTH_MARGIN ) {
+ /* Rule 3: RSSI of the pulses in the burst should be same (+/- margin) */
+ if( br->br_elems[this].be_rssi >= br->br_elems[prev].be_rssi) {
+ rssi_diff = br->br_elems[this].be_rssi - br->br_elems[prev].be_rssi;
+ }
+ else {
+ rssi_diff = br->br_elems[prev].be_rssi - br->br_elems[this].be_rssi;
+ }
+ if( rssi_diff <= DFS_BIN5_RSSI_MARGIN ) {
+ bursts++;
+ /* Save the indexes of this pair for later width variance check */
+ if( numevents >= 2 ) {
+ /* make sure the event is not duplicated,
+ * possible in a 3 pulse burst */
+ if( index[numevents-1] != prev) {
+ index[numevents++] = prev;
+ }
+ }
+ else {
+ index[numevents++] = prev; }
+ index[numevents++] = this;
+ } else {
+ DFS_DPRINTK(dfs,
+ ATH_DEBUG_DFS_BIN5,
+ "%s %d Bin5 rssi_diff=%d\n",
+ __func__, __LINE__, rssi_diff);
+ }
+ } else {
+ DFS_DPRINTK(dfs,
+ ATH_DEBUG_DFS_BIN5,
+ "%s %d Bin5 width_diff=%d\n",
+ __func__, __LINE__,
+ width_diff);
+ }
+ } else if ((pri >= DFS_BIN5_BRI_LOWER_LIMIT) &&
+ (pri <= DFS_BIN5_BRI_UPPER_LIMIT)) {
+ // check pulse width to make sure it is in range of bin 5
+ //if ((br->br_elems[this].be_dur >= MIN_BIN5_DUR_MICROSEC) && (br->br_elems[this].be_dur <= MAX_BIN5_DUR_MICROSEC)) {
+ bursts++;
+ //}
+ } else{
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5,
+ "%s %d Bin5 PRI check fail pri=%llu\n",
+ __func__, __LINE__, (unsigned long long)pri);
+ }
+ prev = this;
+ }
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, "bursts=%u numevents=%u\n", bursts, numevents);
+ if ( bursts >= br->br_pulse.b5_threshold) {
+ if( (br->br_elems[br->br_lastelem].be_ts - br->br_elems[br->br_firstelem].be_ts) < 3000000 ) {
+ return 0;
+ }
+ else {
+ /*
+ * don't do this check since not all the cases have this kind of burst width variation.
+ *
+ for (i=0; i<bursts; i++){
+ total_width += br->br_elems[index[i]].be_dur;
+ }
+ average_width = total_width/bursts;
+ for (i=0; i<bursts; i++){
+ total_diff += DFS_DIFF(br->br_elems[index[i]].be_dur, average_width);
+ }
+ average_diff = total_diff/bursts;
+ if( average_diff > DFS_BIN5_WIDTH_MARGIN ) {
+ return 1;
+ } else {
+
+ DFS_DPRINTK(ic, ATH_DEBUG_DFS_BIN5, "bursts=%u numevents=%u total_width=%d average_width=%d total_diff=%d average_diff=%d\n", bursts, numevents, total_width, average_width, total_diff, average_diff);
+
+ }
+ */
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5, "bursts=%u numevents=%u total_width=%d average_width=%d total_diff=%d average_diff=%d\n", bursts, numevents, total_width, average_width, total_diff, average_diff);
+ DFS_PRINTK("bin 5 radar detected, bursts=%d\n", bursts);
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+/* Return TRUE if chirping pulse, FALSE if not.
+ Decision is made based on processing the FFT data included with the PHY error.
+ Calculate the slope using the maximum bin index reported in the FFT data.
+ Calculate slope between FFT packet 0 and packet n-1. Also calculate slope between
+ packet 1 and packet n.
+ If a pulse is chirping, a slope of 5 and greater is seen.
+ Non-chirping pulses have slopes of 0, 1, 2 or 3.
+*/
+
+/*
+ * Chirp detection for Sowl/Howl.
+ */
+static int
+dfs_check_chirping_sowl(struct ath_dfs *dfs, void *buf,
+ u_int16_t datalen, int is_ctl, int is_ext, int *slope, int *is_dc)
+{
+#define FFT_LEN 70
+#define FFT_LOWER_BIN_MAX_INDEX_BYTE 66
+#define FFT_UPPER_BIN_MAX_INDEX_BYTE 69
+#define MIN_CHIRPING_SLOPE 4
+ int is_chirp=0;
+ int p, num_fft_packets=0;
+ int ctl_slope=0, ext_slope=0;
+ int ctl_high0, ctl_low0, ctl_slope0=0, ext_high0, ext_low0, ext_slope0=0;
+ int ctl_high1, ctl_low1, ctl_slope1=0, ext_high1, ext_low1, ext_slope1=0;
+ u_int8_t *fft_data_ptr;
+
+ *slope = 0;
+ *is_dc = 0;
+
+ num_fft_packets = datalen / FFT_LEN;
+ fft_data_ptr = ((u_int8_t*)buf);
+
+ /* DEBUG - Print relevant portions of the FFT data*/
+ for (p=0; p < num_fft_packets; p++) {
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, "fft_data_ptr=0x%p\t", fft_data_ptr);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT,
+ "[66]=%d [69]=%d\n",
+ *(fft_data_ptr+FFT_LOWER_BIN_MAX_INDEX_BYTE) >> 2,
+ *(fft_data_ptr+FFT_UPPER_BIN_MAX_INDEX_BYTE) >> 2);
+
+ fft_data_ptr += FFT_LEN;
+ }
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, "datalen=%d num_fft_packets=%d\n", datalen, num_fft_packets);
+
+ /* There is not enough FFT data to figure out whether the pulse is chirping or not*/
+ if (num_fft_packets < 4) {
+ return 0;
+ }
+
+ fft_data_ptr = ((u_int8_t*)buf);
+
+ if (is_ctl) {
+
+ fft_data_ptr = ((u_int8_t*)buf);
+ ctl_low0 = *(fft_data_ptr+FFT_LOWER_BIN_MAX_INDEX_BYTE) >> 2;
+ fft_data_ptr += FFT_LEN;
+ ctl_low1 = *(fft_data_ptr+FFT_LOWER_BIN_MAX_INDEX_BYTE) >> 2;
+
+ // last packet with first packet
+ fft_data_ptr = ((u_int8_t*)buf) + (FFT_LEN*(num_fft_packets - 1));
+ ctl_high1 = *(fft_data_ptr+FFT_LOWER_BIN_MAX_INDEX_BYTE) >> 2;
+
+ // second last packet with 0th packet
+ fft_data_ptr = ((u_int8_t*)buf) + (FFT_LEN*(num_fft_packets - 2));
+ ctl_high0 = *(fft_data_ptr+FFT_LOWER_BIN_MAX_INDEX_BYTE) >> 2;
+
+ ctl_slope0 = ctl_high0 - ctl_low0;
+ if (ctl_slope0 < 0) ctl_slope0 *= (-1);
+
+ ctl_slope1 = ctl_high1 - ctl_low1;
+ if (ctl_slope1 < 0) ctl_slope1 *= (-1);
+
+ ctl_slope = ((ctl_slope0 > ctl_slope1) ? ctl_slope0: ctl_slope1);
+ *slope = ctl_slope;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, "ctl_slope0=%d ctl_slope1=%d ctl_slope=%d\n",
+ ctl_slope0, ctl_slope1, ctl_slope);
+
+ } else if (is_ext) {
+
+ fft_data_ptr = ((u_int8_t*)buf);
+ ext_low0 = *(fft_data_ptr+FFT_UPPER_BIN_MAX_INDEX_BYTE) >> 2;
+
+ fft_data_ptr += FFT_LEN;
+ ext_low1 = *(fft_data_ptr+FFT_UPPER_BIN_MAX_INDEX_BYTE) >> 2;
+
+ fft_data_ptr = ((u_int8_t*)buf) + (FFT_LEN*(num_fft_packets - 1));
+ ext_high1 = *(fft_data_ptr+FFT_UPPER_BIN_MAX_INDEX_BYTE) >> 2;
+ fft_data_ptr = ((u_int8_t*)buf) + (FFT_LEN*(num_fft_packets - 2));
+ ext_high0 = *(fft_data_ptr+FFT_UPPER_BIN_MAX_INDEX_BYTE) >> 2;
+
+ ext_slope0 = ext_high0 - ext_low0;
+ if (ext_slope0 < 0) ext_slope0 *= (-1);
+
+ ext_slope1 = ext_high1 - ext_low1;
+ if (ext_slope1 < 0) ext_slope1 *= (-1);
+
+ ext_slope = ((ext_slope0 > ext_slope1) ? ext_slope0: ext_slope1);
+ *slope = ext_slope;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT | ATH_DEBUG_DFS_BIN5,
+ "ext_slope0=%d ext_slope1=%d ext_slope=%d\n",
+ ext_slope0, ext_slope1, ext_slope);
+ } else
+ return 0;
+
+ if ((ctl_slope >= MIN_CHIRPING_SLOPE) || (ext_slope >= MIN_CHIRPING_SLOPE)) {
+ is_chirp = 1;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5 | ATH_DEBUG_DFS_BIN5_FFT |
+ ATH_DEBUG_DFS_PHYERR_SUM,
+ "is_chirp=%d is_dc=%d\n", is_chirp, *is_dc);
+ }
+ return is_chirp;
+
+#undef FFT_LEN
+#undef FFT_LOWER_BIN_MAX_INDEX_BYTE
+#undef FFT_UPPER_BIN_MAX_INDEX_BYTE
+#undef MIN_CHIRPING_SLOPE
+}
+
+/*
+ * Merlin (and Osprey, etc) chirp radar chirp detection.
+ */
+static int
+dfs_check_chirping_merlin(struct ath_dfs *dfs, void *buf, u_int16_t datalen,
+ int is_ctl, int is_ext, int *slope, int *is_dc)
+{
+#define ABS_DIFF(_x, _y) ((int)_x > (int)_y ? (int)_x - (int)_y : (int)_y - (int)_x)
+#define ABS(_x) ((int)_x > 0 ? (int)_x : - (int)_x)
+
+#define DELTA_STEP 1 /* This should be between 1 and 3. Default is 1. */
+#define NUM_DIFFS 3 /* Number of Diffs to compute. valid range is 2-4 */
+#define MAX_DIFF 2 /* Threshold for difference of delta peaks */
+#define BIN_COUNT_MAX 6 /* Max. number of strong bins for narrow band */
+
+
+/*
+ * Dynamic 20/40 mode FFT packet format related definition
+ */
+
+#define NUM_FFT_BYTES_HT40 70
+#define NUM_BIN_BYTES_HT40 64
+#define NUM_SUBCHAN_BINS_HT40 64
+#define LOWER_INDEX_BYTE_HT40 66
+#define UPPER_INDEX_BYTE_HT40 69
+#define LOWER_WEIGHT_BYTE_HT40 64
+#define UPPER_WEIGHT_BYTE_HT40 67
+#define LOWER_MAG_BYTE_HT40 65
+#define UPPER_MAG_BYTE_HT40 68
+
+/*
+ * Static 20 mode FFT packet format related definition
+ */
+
+#define NUM_FFT_BYTES_HT20 31
+#define NUM_BIN_BYTES_HT20 28
+#define NUM_SUBCHAN_BINS_HT20 56
+#define LOWER_INDEX_BYTE_HT20 30
+#define UPPER_INDEX_BYTE_HT20 30
+#define LOWER_WEIGHT_BYTE_HT20 28
+#define UPPER_WEIGHT_BYTE_HT20 28
+#define LOWER_MAG_BYTE_HT20 29
+#define UPPER_MAG_BYTE_HT20 29
+
+ int num_fft_packets; /* number of FFT packets reported to software */
+ int num_fft_bytes;
+ int num_bin_bytes;
+ int num_subchan_bins;
+ int lower_index_byte;
+ int upper_index_byte;
+ int lower_weight_byte;
+ int upper_weight_byte;
+ int lower_mag_byte;
+ int upper_mag_byte;
+
+ int max_index_lower [DELTA_STEP + NUM_DIFFS];
+ int max_index_upper [DELTA_STEP + NUM_DIFFS];
+ int max_mag_lower [DELTA_STEP + NUM_DIFFS];
+ int max_mag_upper [DELTA_STEP + NUM_DIFFS];
+ int bin_wt_lower [DELTA_STEP + NUM_DIFFS];
+ int bin_wt_upper [DELTA_STEP + NUM_DIFFS];
+ int max_mag_sel [DELTA_STEP + NUM_DIFFS];
+ int max_mag [DELTA_STEP + NUM_DIFFS];
+ int max_index [DELTA_STEP + NUM_DIFFS];
+
+
+
+ int max_d[] = {10, 19, 28};
+ int min_d[] = {1, 2, 3};
+
+ u_int8_t *ptr; /* pointer to FFT data */
+ int i;
+ int fft_start;
+ int chirp_found;
+ int delta_peak[NUM_DIFFS];
+ int j;
+ int bin_count;
+ int bw_mask;
+ int delta_diff;
+ int same_sign;
+ int temp;
+
+ if (IS_CHAN_HT40(dfs->ic->ic_curchan)) {
+ num_fft_bytes = NUM_FFT_BYTES_HT40;
+ num_bin_bytes = NUM_BIN_BYTES_HT40;
+ num_subchan_bins = NUM_SUBCHAN_BINS_HT40;
+ lower_index_byte = LOWER_INDEX_BYTE_HT40;
+ upper_index_byte = UPPER_INDEX_BYTE_HT40;
+ lower_weight_byte = LOWER_WEIGHT_BYTE_HT40;
+ upper_weight_byte = UPPER_WEIGHT_BYTE_HT40;
+ lower_mag_byte = LOWER_MAG_BYTE_HT40;
+ upper_mag_byte = UPPER_MAG_BYTE_HT40;
+
+ /* if we are in HT40MINUS then swap primary and extension */
+ if (IS_CHAN_HT40_MINUS(dfs->ic->ic_curchan)) {
+ temp = is_ctl;
+ is_ctl = is_ext;
+ is_ext = temp;
+ }
+
+ } else {
+ num_fft_bytes = NUM_FFT_BYTES_HT20;
+ num_bin_bytes = NUM_BIN_BYTES_HT20;
+ num_subchan_bins = NUM_SUBCHAN_BINS_HT20;
+ lower_index_byte = LOWER_INDEX_BYTE_HT20;
+ upper_index_byte = UPPER_INDEX_BYTE_HT20;
+ lower_weight_byte = LOWER_WEIGHT_BYTE_HT20;
+ upper_weight_byte = UPPER_WEIGHT_BYTE_HT20;
+ lower_mag_byte = LOWER_MAG_BYTE_HT20;
+ upper_mag_byte = UPPER_MAG_BYTE_HT20;
+ }
+
+ ptr = (u_int8_t*)buf;
+ /*
+ * sanity check for FFT buffer
+ */
+
+ if ((ptr == NULL) || (datalen == 0)) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, "%s: FFT buffer pointer is null or size is 0\n", __func__);
+ return 0;
+ }
+
+ num_fft_packets = (datalen - 3) / num_fft_bytes;
+ if (num_fft_packets < (NUM_DIFFS + DELTA_STEP)) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT, "datalen = %d, num_fft_packets = %d, too few packets... (exiting)\n", datalen, num_fft_packets);
+ return 0;
+ }
+
+ if ((((datalen - 3) % num_fft_bytes) == 2) && (datalen > num_fft_bytes)) {
+ // FIXME !!!
+ ptr += 2;
+ datalen -= 2;
+ }
+
+ for (i = 0; i < (NUM_DIFFS + DELTA_STEP); i++) {
+ fft_start = i * num_fft_bytes;
+ bin_wt_lower[i] = ptr[fft_start + lower_weight_byte] & 0x3f;
+ bin_wt_upper[i] = ptr[fft_start + upper_weight_byte] & 0x3f;
+
+ max_index_lower[i] = ptr[fft_start + lower_index_byte] >> 2;
+ max_index_upper[i] = (ptr[fft_start + upper_index_byte] >> 2) + num_subchan_bins;
+
+ if (!IS_CHAN_HT40(dfs->ic->ic_curchan)) {
+ /*
+ * for HT20 mode indices are 6 bit signed number
+ */
+ max_index_lower[i] ^= 0x20;
+ max_index_upper[i] = 0;
+ }
+ /*
+ * Reconstruct the maximum magnitude for each sub-channel. Also select
+ * and flag the max overall magnitude between the two sub-channels.
+ */
+
+ max_mag_lower[i] = ((ptr[fft_start + lower_index_byte] & 0x03) << 8) +
+ ptr[fft_start + lower_mag_byte];
+ max_mag_upper[i] = ((ptr[fft_start + upper_index_byte] & 0x03) << 8) +
+ ptr[fft_start + upper_mag_byte];
+ bw_mask = ((bin_wt_lower[i] == 0) ? 0 : is_ctl) +
+ (((bin_wt_upper[i] == 0) ? 0 : is_ext) << 1);
+
+ /*
+ * Limit the max bin based on channel bandwidth
+ * If the upper sub-channel max index is stuck at '1', the signal is dominated
+ * by residual DC (or carrier leak) and should be ignored.
+ */
+
+ if (bw_mask == 1) {
+ max_mag_sel[i] = 0;
+ max_mag[i] = max_mag_lower[i];
+ max_index[i] = max_index_lower[i];
+ } else if(bw_mask == 2) {
+ max_mag_sel[i] = 1;
+ max_mag[i] = max_mag_upper[i];
+ max_index[i] = max_index_upper[i];
+ } else if(max_index_upper[i] == num_subchan_bins) {
+ max_mag_sel[i] = 0; /* Ignore DC bin. */
+ max_mag[i] = max_mag_lower[i];
+ max_index[i] = max_index_lower[i];
+ } else {
+ if (max_mag_upper[i] > max_mag_lower[i]) {
+ max_mag_sel[i] = 1;
+ max_mag[i] = max_mag_upper[i];
+ max_index[i] = max_index_upper[i];
+ } else {
+ max_mag_sel[i] = 0;
+ max_mag[i] = max_mag_lower[i];
+ max_index[i] = max_index_lower[i];
+ }
+ }
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT,
+ "i=%d, max_index[i]=%d, max_index_lower[i]=%d, "
+ "max_index_upper[i]=%d\n",
+ i, max_index[i], max_index_lower[i], max_index_upper[i]);
+ }
+
+
+
+ chirp_found = 1;
+ delta_diff = 0;
+ same_sign = 1;
+
+ /*
+ delta_diff computation -- look for movement in peak.
+ make sure that the chirp direction (i.e. sign) is always the same,
+ i.e. sign of the two peaks should be same.
+ */
+ for (i = 0; i < NUM_DIFFS; i++) {
+ delta_peak[i] = max_index[i + DELTA_STEP] - max_index[i];
+ if (i > 0) {
+ delta_diff = delta_peak[i] - delta_peak[i-1];
+ same_sign = !((delta_peak[i] & 0x80) ^ (delta_peak[i-1] & 0x80));
+ }
+ chirp_found &= (ABS(delta_peak[i]) >= min_d[DELTA_STEP - 1]) &&
+ (ABS(delta_peak[i]) <= max_d[DELTA_STEP - 1]) &&
+ same_sign &&
+ (ABS(delta_diff) <= MAX_DIFF);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT,
+ "i=%d, delta_peak[i]=%d, delta_diff=%d\n",
+ i, delta_peak[i], delta_diff);
+ }
+
+
+ if (chirp_found)
+ {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT,
+ "%s: CHIRPING_BEFORE_STRONGBIN_YES\n", __func__);
+ } else {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT,
+ "%s: CHIRPING_BEFORE_STRONGBIN_NO\n", __func__);
+ }
+
+ /*
+ Work around for potential hardware data corruption bug. Check for
+ wide band signal by counting strong bins indicated by bitmap flags.
+ This check is done if chirp_found is true. We do this as a final check
+ to weed out corrupt FFTs bytes. This looks expensive but in most cases it
+ will exit early.
+ */
+
+ for (i = 0; (i < (NUM_DIFFS + DELTA_STEP)) && (chirp_found == 1); i++) {
+ bin_count = 0;
+ /* point to the start of the 1st byte of the selected sub-channel. */
+ fft_start = (i * num_fft_bytes) + (max_mag_sel[i] ? (num_subchan_bins >> 1) : 0);
+ for (j = 0; j < (num_subchan_bins >> 1); j++)
+ {
+ /*
+ * If either bin is flagged "strong", accumulate the bin_count.
+ * It's not accurate, but good enough...
+ */
+ bin_count += (ptr[fft_start + j] & 0x88) ? 1 : 0;
+ }
+ chirp_found &= (bin_count > BIN_COUNT_MAX) ? 0 : 1;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT,
+ "i=%d, computed bin_count=%d\n", i, bin_count);
+ }
+
+ if (chirp_found)
+ {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT | ATH_DEBUG_DFS_PHYERR_SUM,
+ "%s: CHIRPING_YES\n", __func__);
+ } else {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_FFT | ATH_DEBUG_DFS_PHYERR_SUM,
+ "%s: CHIRPING_NO\n", __func__);
+ }
+ return chirp_found;
+
+#undef ABS_DIFF
+#undef ABS
+#undef DELTA_STEP
+#undef NUM_DIFFS
+#undef MAX_DIFF
+#undef BIN_COUNT_MAX
+
+#undef NUM_FFT_BYTES_HT40
+#undef NUM_BIN_BYTES_HT40
+#undef NUM_SUBCHAN_BINS_HT40
+#undef LOWER_INDEX_BYTE_HT40
+#undef UPPER_INDEX_BYTE_HT40
+#undef LOWER_WEIGHT_BYTE_HT40
+#undef UPPER_WEIGHT_BYTE_HT40
+#undef LOWER_MAG_BYTE_HT40
+#undef UPPER_MAG_BYTE_HT40
+
+#undef NUM_FFT_BYTES_HT40
+#undef NUM_BIN_BYTES_HT40
+#undef NUM_SUBCHAN_BINS_HT40
+#undef LOWER_INDEX_BYTE_HT40
+#undef UPPER_INDEX_BYTE_HT40
+#undef LOWER_WEIGHT_BYTE_HT40
+#undef UPPER_WEIGHT_BYTE_HT40
+#undef LOWER_MAG_BYTE_HT40
+#undef UPPER_MAG_BYTE_HT40
+}
+
+int
+dfs_check_chirping(struct ath_dfs *dfs, void *buf,
+ u_int16_t datalen, int is_ctl, int is_ext, int *slope, int *is_dc)
+{
+
+ if (dfs->dfs_caps.ath_dfs_use_enhancement)
+ return dfs_check_chirping_merlin(dfs, buf, datalen, is_ctl,
+ is_ext, slope, is_dc);
+ else
+ return dfs_check_chirping_sowl(dfs, buf, datalen, is_ctl,
+ is_ext, slope, is_dc);
+}
+
+u_int8_t
+dfs_retain_bin5_burst_pattern(struct ath_dfs *dfs, u_int32_t diff_ts,
+ u_int8_t old_dur)
+{
+
+ /*
+ * Pulses may get split into 2 during chirping, this print is only
+ * to show that it happened, we do not handle this condition if we
+ * cannot detect the chirping.
+ */
+ /*
+ * SPLIT pulses will have a time stamp difference of < 50
+ */
+ if (diff_ts < 50) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5,
+ "%s SPLIT pulse diffTs=%u dur=%d (old_dur=%d)\n",
+ __func__, diff_ts,
+ dfs->dfs_rinfo.dfs_last_bin5_dur, old_dur);
+ }
+ /*
+ * Check if this is the 2nd or 3rd pulse in the same burst,
+ * PRI will be between 1000 and 2000 us
+ */
+ if (((diff_ts >= DFS_BIN5_PRI_LOWER_LIMIT) &&
+ (diff_ts <= DFS_BIN5_PRI_HIGHER_LIMIT))) {
+ /*
+ * This pulse belongs to the same burst as the pulse before,
+ * so return the same random duration for it
+ */
+ DFS_DPRINTK(dfs,ATH_DEBUG_DFS_BIN5,
+ "%s this pulse belongs to the same burst as before, give "
+ "it same dur=%d (old_dur=%d)\n",
+ __func__, dfs->dfs_rinfo.dfs_last_bin5_dur, old_dur);
+
+ return (dfs->dfs_rinfo.dfs_last_bin5_dur);
+ }
+ /*
+ * This pulse does not belong to this burst, return unchanged
+ * duration.
+ */
+ return old_dur;
+}
+
+/*
+ * Chirping pulses may get cut off at DC and report lower durations.
+ *
+ * This function will compute a suitable random duration for each pulse.
+ * Duration must be between 50 and 100 us, but remember that in
+ * ath_process_phyerr() which calls this function, we are dealing with the
+ * HW reported duration (unconverted). dfs_process_radarevent() will
+ * actually convert the duration into the correct value.
+ *
+ * XXX This function doesn't take into account whether the hardware
+ * is operating in 5GHz fast clock mode or not.
+ *
+ * XXX And this function doesn't take into account whether the hardware
+ * is peregrine or not. Grr.
+ */
+int
+dfs_get_random_bin5_dur(struct ath_dfs *dfs, u_int64_t tstamp)
+{
+ u_int8_t new_dur=MIN_BIN5_DUR;
+ int range;
+
+ get_random_bytes(&new_dur, sizeof(u_int8_t));
+
+ range = (MAX_BIN5_DUR - MIN_BIN5_DUR + 1);
+
+ new_dur %= range;
+
+ new_dur += MIN_BIN5_DUR;
+
+ return new_dur;
+}
+
+#endif /* ATH_SUPPORT_DFS */
+
diff --git a/CORE/SERVICES/DFS/src/dfs_init.c b/CORE/SERVICES/DFS/src/dfs_init.c
new file mode 100644
index 000000000000..3fc9a0946549
--- /dev/null
+++ b/CORE/SERVICES/DFS/src/dfs_init.c
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ dfs_init.c
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+#include "dfs.h"
+/* TO DO DFS
+#include <ieee80211_var.h>
+*/
+#ifdef ATH_SUPPORT_DFS
+
+extern int domainoverride;
+
+/*
+ * Clear all delay lines for all filter types
+ *
+ * This may be called before any radar pulses are configured
+ * (eg on a non-DFS channel, with radar PHY errors still showing up.)
+ * In that case, just drop out early.
+ */
+void dfs_reset_alldelaylines(struct ath_dfs *dfs)
+{
+ struct dfs_filtertype *ft = NULL;
+ struct dfs_filter *rf;
+ struct dfs_delayline *dl;
+ struct dfs_pulseline *pl;
+ int i,j;
+
+ if (dfs == NULL) {
+ printk("%s[%d]: sc_dfs is NULL\n",__func__,__LINE__);
+ //DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: sc_dfs is NULL\n", __func__);
+ return;
+ }
+ pl = dfs->pulses;
+
+ if (pl == NULL) {
+ printk("%s[%d]: pl==NULL, dfs=%p\n",__func__,__LINE__,dfs);
+ //DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: pl==NULL, dfs=%p\n",__func__,dfs);
+ return;
+ }
+
+ if (dfs->dfs_b5radars == NULL) {
+ printk("%s[%d]: pl==NULL, b5radars=%p\n",__func__,__LINE__,dfs->dfs_b5radars);
+ //DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: pl==NULL, b5radars=%p\n",__func__,dfs->dfs_b5radars);
+ return;
+ }
+
+ /* reset the pulse log */
+ pl->pl_firstelem = pl->pl_numelems = 0;
+ pl->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK;
+
+ for (i=0; i<DFS_MAX_RADAR_TYPES; i++) {
+ if (dfs->dfs_radarf[i] != NULL) {
+ ft = dfs->dfs_radarf[i];
+ for (j=0; j<ft->ft_numfilters; j++) {
+ rf = &(ft->ft_filters[j]);
+ dl = &(rf->rf_dl);
+ if(dl != NULL) {
+ OS_MEMZERO(dl, sizeof(struct dfs_delayline));
+ dl->dl_lastelem = (0xFFFFFFFF) & DFS_MAX_DL_MASK;
+ }
+ }
+ }
+ }
+ for (i=0; i<dfs->dfs_rinfo.rn_numbin5radars; i++) {
+ OS_MEMZERO(&(dfs->dfs_b5radars[i].br_elems[0]), sizeof(struct dfs_bin5elem)*DFS_MAX_B5_SIZE);
+ dfs->dfs_b5radars[i].br_firstelem = 0;
+ dfs->dfs_b5radars[i].br_numelems = 0;
+ dfs->dfs_b5radars[i].br_lastelem = (0xFFFFFFFF)&DFS_MAX_B5_MASK;
+ }
+}
+/*
+ * Clear only a single delay line
+ */
+
+void dfs_reset_delayline(struct dfs_delayline *dl)
+{
+ OS_MEMZERO(&(dl->dl_elems[0]), sizeof(dl->dl_elems));
+ dl->dl_lastelem = (0xFFFFFFFF)&DFS_MAX_DL_MASK;
+}
+
+void dfs_reset_filter_delaylines(struct dfs_filtertype *dft)
+{
+ int i;
+ struct dfs_filter *df;
+ for (i=0; i< DFS_MAX_NUM_RADAR_FILTERS; i++) {
+ df = &dft->ft_filters[i];
+ dfs_reset_delayline(&(df->rf_dl));
+ }
+}
+
+void
+dfs_reset_radarq(struct ath_dfs *dfs)
+{
+ struct dfs_event *event;
+ if (dfs == NULL) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: sc_dfs is NULL\n", __func__);
+ return;
+ }
+ ATH_DFSQ_LOCK(dfs);
+ ATH_DFSEVENTQ_LOCK(dfs);
+ while (!STAILQ_EMPTY(&(dfs->dfs_radarq))) {
+ event = STAILQ_FIRST(&(dfs->dfs_radarq));
+ STAILQ_REMOVE_HEAD(&(dfs->dfs_radarq), re_list);
+ OS_MEMZERO(event, sizeof(struct dfs_event));
+ STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), event, re_list);
+ }
+ ATH_DFSEVENTQ_UNLOCK(dfs);
+ ATH_DFSQ_UNLOCK(dfs);
+}
+
+
+/* This function Initialize the radar filter tables
+ * if the ath dfs domain is uninitalized or
+ * ath dfs domain is different from hal dfs domain
+ */
+int dfs_init_radar_filters(struct ieee80211com *ic,
+ struct ath_dfs_radar_tab_info *radar_info)
+{
+ u_int32_t T, Tmax;
+ int numpulses,p,n, i;
+ int numradars = 0, numb5radars = 0;
+ struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs;
+ struct dfs_filtertype *ft = NULL;
+ struct dfs_filter *rf=NULL;
+ struct dfs_pulse *dfs_radars;
+ struct dfs_bin5pulse *b5pulses=NULL;
+ int32_t min_rssithresh=DFS_MAX_RSSI_VALUE;
+ u_int32_t max_pulsedur=0;
+
+ if (dfs == NULL) {
+ printk("%s[%d]: dfs is NULL\n",__func__,__LINE__);
+ //DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "dfs is NULL %s",__func__);
+ return 1;
+ }
+ printk("%s[%d]:dfsdomain=%d, numradars=%d, numb5radars=%d\n",__func__,
+ __LINE__, radar_info->dfsdomain,radar_info->numradars,radar_info->numb5radars);
+/*
+ * DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
+ * "%s: dfsdomain=%d, numradars=%d, numb5radars=%d\n",
+ * __func__,
+ * radar_info->dfsdomain,
+ * radar_info->numradars,
+ * radar_info->numb5radars);
+ */
+ /* clear up the dfs domain flag first */
+#ifndef ATH_DFS_RADAR_DETECTION_ONLY
+ dfs->ath_dfs_isdfsregdomain = 0;
+#endif
+
+ /*
+ * If radar_info is NULL or dfsdomain is NULL, treat
+ * the rest of the radar configuration as suspect.
+ */
+ if (radar_info == NULL || radar_info->dfsdomain == 0) {
+ printk("%s[%d]: Unknown dfs domain %d \n",__func__,__LINE__,dfs->dfsdomain);
+ /*DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: Unknown dfs domain %d\n",
+ __func__, dfs->dfsdomain);*/
+ /* Disable radar detection since we don't have a radar domain */
+ dfs->dfs_proc_phyerr &= ~DFS_RADAR_EN;
+ return 0;
+ }
+
+ dfs->dfsdomain = radar_info->dfsdomain;
+ dfs_radars = radar_info->dfs_radars;
+ numradars = radar_info->numradars;
+ b5pulses = radar_info->b5pulses;
+ numb5radars = radar_info->numb5radars;
+
+ /* XXX this should be an explicit copy of some sort! */
+ dfs->dfs_defaultparams = radar_info->dfs_defaultparams;
+
+#ifndef ATH_DFS_RADAR_DETECTION_ONLY
+ dfs->ath_dfs_isdfsregdomain = 1;
+#endif
+
+ dfs->dfs_rinfo.rn_numradars = 0;
+ /* Clear filter type table */
+ for (n=0; n<256; n++) {
+ for (i=0;i<DFS_MAX_RADAR_OVERLAP; i++)
+ (dfs->dfs_radartable[n])[i] = -1;
+ }
+ /* Now, initialize the radar filters */
+ for (p=0; p<numradars; p++) {
+ ft = NULL;
+ for (n=0; n<dfs->dfs_rinfo.rn_numradars; n++) {
+ if ((dfs_radars[p].rp_pulsedur == dfs->dfs_radarf[n]->ft_filterdur) &&
+ (dfs_radars[p].rp_numpulses == dfs->dfs_radarf[n]->ft_numpulses) &&
+ (dfs_radars[p].rp_mindur == dfs->dfs_radarf[n]->ft_mindur) &&
+ (dfs_radars[p].rp_maxdur == dfs->dfs_radarf[n]->ft_maxdur)) {
+ ft = dfs->dfs_radarf[n];
+ break;
+ }
+ }
+ if (ft == NULL) {
+ /* No filter of the appropriate dur was found */
+ if ((dfs->dfs_rinfo.rn_numradars+1) >DFS_MAX_RADAR_TYPES) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: Too many filter types\n",
+ __func__);
+ goto bad4;
+ }
+ ft = dfs->dfs_radarf[dfs->dfs_rinfo.rn_numradars];
+ ft->ft_numfilters = 0;
+ ft->ft_numpulses = dfs_radars[p].rp_numpulses;
+ ft->ft_patterntype = dfs_radars[p].rp_patterntype;
+ ft->ft_mindur = dfs_radars[p].rp_mindur;
+ ft->ft_maxdur = dfs_radars[p].rp_maxdur;
+ ft->ft_filterdur = dfs_radars[p].rp_pulsedur;
+ ft->ft_rssithresh = dfs_radars[p].rp_rssithresh;
+ ft->ft_rssimargin = dfs_radars[p].rp_rssimargin;
+ ft->ft_minpri = 1000000;
+
+ if (ft->ft_rssithresh < min_rssithresh)
+ min_rssithresh = ft->ft_rssithresh;
+ if (ft->ft_maxdur > max_pulsedur)
+ max_pulsedur = ft->ft_maxdur;
+ for (i=ft->ft_mindur; i<=ft->ft_maxdur; i++) {
+ u_int32_t stop=0,tableindex=0;
+ while ((tableindex < DFS_MAX_RADAR_OVERLAP) && (!stop)) {
+ if ((dfs->dfs_radartable[i])[tableindex] == -1)
+ stop = 1;
+ else
+ tableindex++;
+ }
+ if (stop) {
+ (dfs->dfs_radartable[i])[tableindex] =
+ (int8_t) (dfs->dfs_rinfo.rn_numradars);
+ } else {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
+ "%s: Too many overlapping radar filters\n",
+ __func__);
+ goto bad4;
+ }
+ }
+ dfs->dfs_rinfo.rn_numradars++;
+ }
+ rf = &(ft->ft_filters[ft->ft_numfilters++]);
+ dfs_reset_delayline(&rf->rf_dl);
+ numpulses = dfs_radars[p].rp_numpulses;
+
+ rf->rf_numpulses = numpulses;
+ rf->rf_patterntype = dfs_radars[p].rp_patterntype;
+ rf->rf_pulseid = dfs_radars[p].rp_pulseid;
+ rf->rf_mindur = dfs_radars[p].rp_mindur;
+ rf->rf_maxdur = dfs_radars[p].rp_maxdur;
+ rf->rf_numpulses = dfs_radars[p].rp_numpulses;
+ rf->rf_ignore_pri_window = dfs_radars[p].rp_ignore_pri_window;
+ T = (100000000/dfs_radars[p].rp_max_pulsefreq) -
+ 100*(dfs_radars[p].rp_meanoffset);
+ rf->rf_minpri =
+ dfs_round((int32_t)T - (100*(dfs_radars[p].rp_pulsevar)));
+ Tmax = (100000000/dfs_radars[p].rp_pulsefreq) -
+ 100*(dfs_radars[p].rp_meanoffset);
+ rf->rf_maxpri =
+ dfs_round((int32_t)Tmax + (100*(dfs_radars[p].rp_pulsevar)));
+
+ if( rf->rf_minpri < ft->ft_minpri )
+ ft->ft_minpri = rf->rf_minpri;
+
+ rf->rf_fixed_pri_radar_pulse = ( dfs_radars[p].rp_max_pulsefreq == dfs_radars[p].rp_pulsefreq ) ? 1 : 0;
+ rf->rf_threshold = dfs_radars[p].rp_threshold;
+ rf->rf_filterlen = rf->rf_maxpri * rf->rf_numpulses;
+
+ printk("%s[%d]: minprf = %d maxprf = %d pulsevar = %d thresh=%d\n",
+ __func__,__LINE__,dfs_radars[p].rp_pulsefreq, dfs_radars[p].rp_max_pulsefreq,
+ dfs_radars[p].rp_pulsevar, rf->rf_threshold);
+ printk("%s[%d]:minpri = %d maxpri = %d filterlen = %d filterID = %d\n",__func__,__LINE__,
+ rf->rf_minpri, rf->rf_maxpri, rf->rf_filterlen, rf->rf_pulseid);
+
+ /*DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "minprf = %d maxprf = %d pulsevar = %d thresh=%d\n",
+ dfs_radars[p].rp_pulsefreq, dfs_radars[p].rp_max_pulsefreq, dfs_radars[p].rp_pulsevar, rf->rf_threshold);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "minpri = %d maxpri = %d filterlen = %d filterID = %d\n",
+ rf->rf_minpri, rf->rf_maxpri, rf->rf_filterlen, rf->rf_pulseid);*/
+ }
+
+#ifdef DFS_DEBUG
+ dfs_print_filters(ic);
+#endif
+ dfs->dfs_rinfo.rn_numbin5radars = numb5radars;
+ if (dfs->dfs_b5radars != NULL)
+ OS_FREE(dfs->dfs_b5radars);
+
+ dfs->dfs_b5radars = (struct dfs_bin5radars *)OS_MALLOC(NULL,
+ numb5radars * sizeof(struct dfs_bin5radars), GFP_KERNEL);
+ if (dfs->dfs_b5radars == NULL) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
+ "%s: cannot allocate memory for bin5 radars\n",
+ __func__);
+ goto bad4;
+ }
+ for (n=0; n<numb5radars; n++) {
+ dfs->dfs_b5radars[n].br_pulse = b5pulses[n];
+ dfs->dfs_b5radars[n].br_pulse.b5_timewindow *= 1000000;
+ if (dfs->dfs_b5radars[n].br_pulse.b5_rssithresh < min_rssithresh)
+ min_rssithresh = dfs->dfs_b5radars[n].br_pulse.b5_rssithresh;
+ if (dfs->dfs_b5radars[n].br_pulse.b5_maxdur > max_pulsedur)
+ max_pulsedur = dfs->dfs_b5radars[n].br_pulse.b5_maxdur;
+ }
+ dfs_reset_alldelaylines(dfs);
+ dfs_reset_radarq(dfs);
+ dfs->dfs_curchan_radindex = -1;
+ dfs->dfs_extchan_radindex = -1;
+ dfs->dfs_rinfo.rn_minrssithresh = min_rssithresh;
+ /* Convert durations to TSF ticks */
+ dfs->dfs_rinfo.rn_maxpulsedur = dfs_round((int32_t)((max_pulsedur*100/80)*100));
+ /* relax the max pulse duration a little bit due to inaccuracy caused by chirping. */
+ dfs->dfs_rinfo.rn_maxpulsedur = dfs->dfs_rinfo.rn_maxpulsedur +20;
+ printk("%s[%d]: DFS min filter rssiThresh = %d \n",__func__,__LINE__,min_rssithresh);
+ printk("%s[%d]:DFS max pulse dur = %d ticks\n ",__func__,__LINE__,dfs->dfs_rinfo.rn_maxpulsedur);
+ //DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "DFS min filter rssiThresh = %d\n",min_rssithresh);
+ //DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "DFS max pulse dur = %d ticks\n", dfs->dfs_rinfo.rn_maxpulsedur);
+ return 0;
+
+ bad4:
+ return 1;
+}
+
+void
+dfs_clear_stats(struct ieee80211com *ic)
+{
+ struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs;
+ if (dfs == NULL)
+ return;
+ OS_MEMZERO(&dfs->ath_dfs_stats, sizeof (struct dfs_stats));
+ dfs->ath_dfs_stats.last_reset_tstamp = ic->ic_get_TSF64(ic);
+}
+
+#endif /* ATH_SUPPORT_DFS */
diff --git a/CORE/SERVICES/DFS/src/dfs_ioctl.h b/CORE/SERVICES/DFS/src/dfs_ioctl.h
new file mode 100644
index 000000000000..7503715b280c
--- /dev/null
+++ b/CORE/SERVICES/DFS/src/dfs_ioctl.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ dfs_ioctl.h
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+
+/*
+ * ioctl defines
+ */
+
+#ifndef _DFS_IOCTL_H_
+#define _DFS_IOCTL_H_
+
+#define DFS_MUTE_TIME 1
+#define DFS_SET_THRESH 2
+#define DFS_GET_THRESH 3
+#define DFS_GET_USENOL 4
+#define DFS_SET_USENOL 5
+#define DFS_RADARDETECTS 6
+#define DFS_BANGRADAR 7
+#define DFS_SHOW_NOL 8
+#define DFS_DISABLE_DETECT 9
+#define DFS_ENABLE_DETECT 10
+#define DFS_DISABLE_FFT 11
+#define DFS_ENABLE_FFT 12
+#define DFS_SET_DEBUG_LEVEL 13
+#define DFS_GET_NOL 14
+#define DFS_SET_NOL 15
+
+#define DFS_SET_FALSE_RSSI_THRES 16
+#define DFS_SET_PEAK_MAG 17
+#define DFS_IGNORE_CAC 18
+#define DFS_SET_NOL_TIMEOUT 19
+#define DFS_LAST_IOCTL 20
+#ifndef IEEE80211_CHAN_MAX
+#define IEEE80211_CHAN_MAX 255
+#endif
+
+struct dfsreq_nolelem {
+ u_int16_t nol_freq; /* NOL channel frequency */
+ u_int16_t nol_chwidth;
+ unsigned long nol_start_ticks; /* OS ticks when the NOL timer started */
+ u_int32_t nol_timeout_ms; /* Nol timeout value in msec */
+};
+
+struct dfsreq_nolinfo {
+ u_int32_t ic_nchans;
+ struct dfsreq_nolelem dfs_nol[IEEE80211_CHAN_MAX];
+};
+
+/*
+ * ioctl parameter types
+ */
+
+#define DFS_PARAM_FIRPWR 1
+#define DFS_PARAM_RRSSI 2
+#define DFS_PARAM_HEIGHT 3
+#define DFS_PARAM_PRSSI 4
+#define DFS_PARAM_INBAND 5
+//5413 specific parameters
+#define DFS_PARAM_RELPWR 7
+#define DFS_PARAM_RELSTEP 8
+#define DFS_PARAM_MAXLEN 9
+
+struct dfs_ioctl_params {
+ int32_t dfs_firpwr; /* FIR pwr out threshold */
+ int32_t dfs_rrssi; /* Radar rssi thresh */
+ int32_t dfs_height; /* Pulse height thresh */
+ int32_t dfs_prssi; /* Pulse rssi thresh */
+ int32_t dfs_inband; /* Inband thresh */
+ int32_t dfs_relpwr; /* pulse relative pwr thresh */
+ int32_t dfs_relstep; /* pulse relative step thresh */
+ int32_t dfs_maxlen; /* pulse max duration */
+};
+
+/*
+ * XXX keep these in sync with ath_dfs_phyerr_param!
+ */
+#define DFS_IOCTL_PARAM_NOVAL 65535
+#define DFS_IOCTL_PARAM_ENABLE 0x8000
+
+#endif /* _DFS_IOCTL_H_ */
diff --git a/CORE/SERVICES/DFS/src/dfs_ioctl_private.h b/CORE/SERVICES/DFS/src/dfs_ioctl_private.h
new file mode 100644
index 000000000000..2e506e7782bb
--- /dev/null
+++ b/CORE/SERVICES/DFS/src/dfs_ioctl_private.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ dfs_ioctl_private.h
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+/*
+ * ioctl defines
+ */
+
+#ifndef _DFS_IOCTL_PRIVATE_H_
+#define _DFS_IOCTL_PRIVATE_H_
+
+/*
+ * Assert that the NOVAL values match.
+ */
+#if (ATH_DFS_PHYERR_PARAM_NOVAL != DFS_IOCTL_PARAM_NOVAL)
+#error "ATH_DFS_PHYERR_PARAM_NOVAL != DFS_IOCTL_PARAM_NOVAL"
+#endif
+
+/*
+ * Assert that the ENABLE values match.
+ */
+#if (ATH_DFS_PHYERR_PARAM_ENABLE != DFS_IOCTL_PARAM_ENABLE)
+#error "ATH_DFS_PHYERR_PARAM_ENABLE != DFS_IOCTL_PARAM_ENABLE"
+#endif
+
+/*
+ * These two methods are used by the lmac glue to copy between
+ * the DFS and HAL PHY configuration.
+ *
+ * I'm "cheating" here and assuming that the ENABLE and NOVAL
+ * values match - see the above macros.
+ */
+static inline void
+ath_dfs_ioctlparam_to_dfsparam(const struct dfs_ioctl_params *src,
+ struct ath_dfs_phyerr_param *dst)
+{
+
+ dst->pe_firpwr = src->dfs_firpwr;
+ dst->pe_rrssi = src->dfs_rrssi;
+ dst->pe_height = src->dfs_height;
+ dst->pe_prssi = src->dfs_prssi;
+ dst->pe_inband = src->dfs_inband;
+ dst->pe_relpwr = src->dfs_relpwr;
+ dst->pe_relstep = src->dfs_relstep;
+ dst->pe_maxlen = src->dfs_maxlen;
+}
+
+static inline void
+ath_dfs_dfsparam_to_ioctlparam(struct ath_dfs_phyerr_param *src,
+ struct dfs_ioctl_params *dst)
+{
+
+ dst->dfs_firpwr = src->pe_firpwr;
+ dst->dfs_rrssi = src->pe_rrssi;
+ dst->dfs_height = src->pe_height;
+ dst->dfs_prssi = src->pe_prssi;
+ dst->dfs_inband = src->pe_inband;
+ dst->dfs_relpwr = src->pe_relpwr;
+ dst->dfs_relstep = src->pe_relstep;
+ dst->dfs_maxlen = src->pe_maxlen;
+}
+
+#endif /* _DFS_IOCTL_PRIVATE_H_ */
diff --git a/CORE/SERVICES/DFS/src/dfs_misc.c b/CORE/SERVICES/DFS/src/dfs_misc.c
new file mode 100644
index 000000000000..04e2630647e0
--- /dev/null
+++ b/CORE/SERVICES/DFS/src/dfs_misc.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ dfs_misc.c
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+#include "dfs.h"
+/* TO DO DFS
+#include <ieee80211_var.h>
+*/
+#ifndef UNINET
+/* TO DO DFS
+#include <ieee80211_channel.h>
+*/
+#endif
+#ifdef ATH_SUPPORT_DFS
+
+static int adjust_pri_per_chan_busy(int ext_chan_busy, int pri_margin)
+{
+ int adjust_pri=0;
+
+ if(ext_chan_busy > DFS_EXT_CHAN_LOADING_THRESH) {
+
+ adjust_pri = (ext_chan_busy - DFS_EXT_CHAN_LOADING_THRESH) * (pri_margin);
+ adjust_pri /= 100;
+
+ }
+ return adjust_pri;
+}
+
+static int adjust_thresh_per_chan_busy(int ext_chan_busy, int thresh)
+{
+ int adjust_thresh=0;
+
+ if(ext_chan_busy > DFS_EXT_CHAN_LOADING_THRESH) {
+
+ adjust_thresh = (ext_chan_busy - DFS_EXT_CHAN_LOADING_THRESH) * thresh;
+ adjust_thresh /= 100;
+
+ }
+ return adjust_thresh;
+}
+/* For the extension channel, if legacy traffic is present, we see a lot of false alarms,
+so make the PRI margin narrower depending on the busy % for the extension channel.*/
+
+int
+dfs_get_pri_margin(struct ath_dfs *dfs, int is_extchan_detect,
+ int is_fixed_pattern)
+{
+
+ int adjust_pri=0, ext_chan_busy=0;
+ int pri_margin;
+
+ if (is_fixed_pattern)
+ pri_margin = DFS_DEFAULT_FIXEDPATTERN_PRI_MARGIN;
+ else
+ pri_margin = DFS_DEFAULT_PRI_MARGIN;
+
+ if (IS_CHAN_HT40(dfs->ic->ic_curchan)) {
+ ext_chan_busy = dfs->ic->ic_get_ext_busy(dfs->ic);
+ if(ext_chan_busy >= 0) {
+ dfs->dfs_rinfo.ext_chan_busy_ts = dfs->ic->ic_get_TSF64(dfs->ic);
+ dfs->dfs_rinfo.dfs_ext_chan_busy = ext_chan_busy;
+ } else {
+ // Check to see if the cached value of ext_chan_busy can be used
+ ext_chan_busy = 0;
+ if (dfs->dfs_rinfo.dfs_ext_chan_busy) {
+ if (dfs->dfs_rinfo.rn_lastfull_ts < dfs->dfs_rinfo.ext_chan_busy_ts) {
+ ext_chan_busy = dfs->dfs_rinfo.dfs_ext_chan_busy;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ " PRI Use cached copy of ext_chan_busy extchanbusy=%d \n", ext_chan_busy);
+ }
+ }
+ }
+ adjust_pri = adjust_pri_per_chan_busy(ext_chan_busy, pri_margin);
+
+ pri_margin -= adjust_pri;
+ }
+ return pri_margin;
+}
+
+/* For the extension channel, if legacy traffic is present, we see a lot of false alarms,
+so make the thresholds higher depending on the busy % for the extension channel.*/
+
+int dfs_get_filter_threshold(struct ath_dfs *dfs, struct dfs_filter *rf,
+ int is_extchan_detect)
+{
+ int ext_chan_busy=0;
+ int thresh, adjust_thresh=0;
+
+ thresh = rf->rf_threshold;
+
+ if (IS_CHAN_HT40(dfs->ic->ic_curchan)) {
+ ext_chan_busy = dfs->ic->ic_get_ext_busy(dfs->ic);
+ if(ext_chan_busy >= 0) {
+ dfs->dfs_rinfo.ext_chan_busy_ts = dfs->ic->ic_get_TSF64(dfs->ic);
+ dfs->dfs_rinfo.dfs_ext_chan_busy = ext_chan_busy;
+ } else {
+ // Check to see if the cached value of ext_chan_busy can be used
+ ext_chan_busy = 0;
+ if (dfs->dfs_rinfo.dfs_ext_chan_busy) {
+ if (dfs->dfs_rinfo.rn_lastfull_ts < dfs->dfs_rinfo.ext_chan_busy_ts) {
+ ext_chan_busy = dfs->dfs_rinfo.dfs_ext_chan_busy;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ " THRESH Use cached copy of ext_chan_busy extchanbusy=%d rn_lastfull_ts=%llu ext_chan_busy_ts=%llu\n",
+ ext_chan_busy,
+ (unsigned long long)dfs->dfs_rinfo.rn_lastfull_ts,
+ (unsigned long long)dfs->dfs_rinfo.ext_chan_busy_ts);
+ }
+ }
+ }
+
+ adjust_thresh = adjust_thresh_per_chan_busy(ext_chan_busy, thresh);
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ " filterID=%d extchanbusy=%d adjust_thresh=%d\n",
+ rf->rf_pulseid, ext_chan_busy, adjust_thresh);
+
+ thresh += adjust_thresh;
+ }
+ return thresh;
+}
+
+
+u_int32_t dfs_round(int32_t val)
+{
+ u_int32_t ival,rem;
+
+ if (val < 0)
+ return 0;
+ ival = val/100;
+ rem = val-(ival*100);
+ if (rem <50)
+ return ival;
+ else
+ return(ival+1);
+}
+
+struct ieee80211_channel *
+ieee80211_get_extchan(struct ieee80211com *ic)
+{
+ int chan_offset = 0;
+ if (IEEE80211_IS_CHAN_HT40PLUS_CAPABLE(ic->ic_curchan)) {
+ chan_offset = 20;
+ } else if (IEEE80211_IS_CHAN_HT40MINUS_CAPABLE(ic->ic_curchan)) {
+ chan_offset = -20;
+ } else {
+ return NULL;
+ }
+ return(ic->ic_find_channel(ic, ic->ic_curchan->ic_freq + chan_offset, IEEE80211_CHAN_11NA_HT20));
+}
+
+/*
+ * Finds the radar state entry that matches the current channel
+ */
+struct dfs_state *
+dfs_getchanstate(struct ath_dfs *dfs, u_int8_t *index, int ext_chan_flag)
+{
+ struct dfs_state *rs=NULL;
+ int i;
+ struct ieee80211_channel *cmp_ch;
+
+ if (dfs == NULL) {
+ printk("%s[%d]: sc_dfs is NULL\n",__func__,__LINE__);
+ // DFS_DPRINTK(dfs, ATH_DEBUG_DFS,"%s: sc_dfs is NULL\n",__func__);
+ return NULL;
+ }
+
+ if (ext_chan_flag) {
+ cmp_ch = ieee80211_get_extchan(dfs->ic);
+ if (cmp_ch) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "Extension channel freq = %u flags=0x%x\n", cmp_ch->ic_freq, cmp_ch->ic_flagext);
+ } else {
+ return NULL;
+ }
+
+ } else {
+ cmp_ch = dfs->ic->ic_curchan;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "Primary channel freq = %u flags=0x%x\n", cmp_ch->ic_freq, cmp_ch->ic_flagext);
+ }
+ for (i=0;i<DFS_NUM_RADAR_STATES; i++) {
+ if ((dfs->dfs_radar[i].rs_chan.ic_freq== cmp_ch->ic_freq) &&
+ (dfs->dfs_radar[i].rs_chan.ic_flags == cmp_ch->ic_flags)) {
+ if (index != NULL)
+ *index = (u_int8_t) i;
+ return &(dfs->dfs_radar[i]);
+ }
+ }
+ /* No existing channel found, look for first free channel state entry */
+ for (i=0; i<DFS_NUM_RADAR_STATES; i++) {
+ if (dfs->dfs_radar[i].rs_chan.ic_freq == 0) {
+ rs = &(dfs->dfs_radar[i]);
+ /* Found one, set channel info and default thresholds */
+ rs->rs_chan = *cmp_ch;
+
+ /* Copy the parameters from the default set */
+ ath_dfs_phyerr_param_copy(&rs->rs_param,
+ &dfs->dfs_defaultparams);
+
+ if (index != NULL)
+ *index = (u_int8_t) i;
+ return (rs);
+ }
+ }
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "%s: No more radar states left.\n", __func__);
+ return(NULL);
+}
+
+
+
+#endif /* ATH_SUPPORT_DFS */
diff --git a/CORE/SERVICES/DFS/src/dfs_nol.c b/CORE/SERVICES/DFS/src/dfs_nol.c
new file mode 100644
index 000000000000..db570b609c33
--- /dev/null
+++ b/CORE/SERVICES/DFS/src/dfs_nol.c
@@ -0,0 +1,407 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ dfs_nol.c
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+
+#include "dfs.h"
+/* TO DO DFS
+#include <ieee80211_var.h>
+*/
+#ifndef UNINET
+/*TO DO DFS
+#include <ieee80211_channel.h>
+*/
+#endif
+#if defined(ATH_SUPPORT_DFS) && !defined(ATH_DFS_RADAR_DETECTION_ONLY)
+#include "dfs_ioctl.h"
+#include "dfs_ioctl_private.h"
+#include "adf_os_time.h" /* adf_os_time_t, adf_os_time_after */
+
+static void
+dfs_nol_delete(struct ath_dfs *dfs, u_int16_t delfreq, u_int16_t delchwidth);
+
+static
+OS_TIMER_FUNC(dfs_remove_from_nol)
+{
+ struct dfs_nol_timer_arg *nol_arg;
+ struct ath_dfs *dfs;
+ struct ieee80211com *ic;
+ u_int16_t delfreq;
+ u_int16_t delchwidth;
+
+ OS_GET_TIMER_ARG(nol_arg, struct dfs_nol_timer_arg *);
+
+ dfs = nol_arg->dfs;
+ ic = dfs->ic;
+ delfreq = nol_arg->delfreq;
+ delchwidth = nol_arg->delchwidth;
+
+ /* Only operate in HOSTAP/IBSS */
+ if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
+ ic->ic_opmode != IEEE80211_M_IBSS)
+ goto done;
+
+ /* Delete the given NOL entry */
+ dfs_nol_delete(dfs, delfreq, delchwidth);
+
+ /* Update the wireless stack with the new NOL */
+ dfs_nol_update(dfs);
+
+done:
+ OS_FREE(nol_arg);
+ return;
+}
+
+void
+dfs_print_nol(struct ath_dfs *dfs)
+{
+ struct dfs_nolelem *nol;
+ int i = 0;
+ uint32_t diff_ms, remaining_sec;
+
+ if (dfs == NULL) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, "%s: sc_dfs is NULL\n", __func__);
+ return;
+ }
+ nol = dfs->dfs_nol;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, "%s: NOL\n", __func__);
+ while (nol != NULL) {
+ diff_ms = adf_os_ticks_to_msecs(adf_os_ticks() - nol->nol_start_ticks);
+ diff_ms = (nol->nol_timeout_ms - diff_ms);
+ remaining_sec = diff_ms / 1000; /* convert to seconds */
+ printk("nol:%d channel=%d MHz width=%d MHz time left=%u seconds nol starttick=%llu \n",
+ i++, nol->nol_freq, nol->nol_chwidth, remaining_sec,
+ (unsigned long long)nol->nol_start_ticks);
+ nol = nol->nol_next;
+ }
+}
+
+
+void
+dfs_get_nol(struct ath_dfs *dfs, struct dfsreq_nolelem *dfs_nol,
+ int *nchan)
+{
+ struct dfs_nolelem *nol;
+
+ *nchan = 0;
+
+ if (dfs == NULL) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, "%s: sc_dfs is NULL\n", __func__);
+ return;
+ }
+
+ nol = dfs->dfs_nol;
+ while (nol != NULL) {
+ dfs_nol[*nchan].nol_freq = nol->nol_freq;
+ dfs_nol[*nchan].nol_chwidth = nol->nol_chwidth;
+ dfs_nol[*nchan].nol_start_ticks = nol->nol_start_ticks;
+ dfs_nol[*nchan].nol_timeout_ms = nol->nol_timeout_ms;
+ ++(*nchan);
+ nol = nol->nol_next;
+ }
+}
+
+
+void
+dfs_set_nol(struct ath_dfs *dfs, struct dfsreq_nolelem *dfs_nol, int nchan)
+{
+#define TIME_IN_MS 1000
+ u_int32_t nol_time_left_ms;
+ struct ieee80211_channel chan;
+ int i;
+
+ if (dfs == NULL) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, "%s: sc_dfs is NULL\n", __func__);
+ return;
+ }
+
+ for (i = 0; i < nchan; i++)
+ {
+ nol_time_left_ms = adf_os_ticks_to_msecs(adf_os_ticks() - dfs_nol[i].nol_start_ticks);
+ if (nol_time_left_ms < dfs_nol[i].nol_timeout_ms) {
+ chan.ic_freq = dfs_nol[i].nol_freq;
+ chan.ic_flags= 0;
+ chan.ic_flagext = 0;
+ nol_time_left_ms = (dfs_nol[i].nol_timeout_ms - nol_time_left_ms);
+ dfs_nol_addchan(dfs, &chan, (nol_time_left_ms / TIME_IN_MS));
+ }
+ }
+#undef TIME_IN_MS
+ dfs_nol_update(dfs);
+}
+
+
+void
+dfs_nol_addchan(struct ath_dfs *dfs, struct ieee80211_channel *chan,
+ u_int32_t dfs_nol_timeout)
+{
+#define TIME_IN_MS 1000
+#define TIME_IN_US (TIME_IN_MS * 1000)
+ struct dfs_nolelem *nol, *elem, *prev;
+ struct dfs_nol_timer_arg *dfs_nol_arg;
+ /* XXX for now, assume all events are 20MHz wide */
+ int ch_width = 20;
+
+ if (dfs == NULL) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, "%s: sc_dfs is NULL\n", __func__);
+ return;
+ }
+ nol = dfs->dfs_nol;
+ prev = dfs->dfs_nol;
+ elem = NULL;
+ while (nol != NULL) {
+ if ((nol->nol_freq == chan->ic_freq) &&
+ (nol->nol_chwidth == ch_width)) {
+ nol->nol_start_ticks = adf_os_ticks();
+ nol->nol_timeout_ms = dfs_nol_timeout*TIME_IN_MS;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL,
+ "%s: Update OS Ticks for NOL %d MHz / %d MHz\n",
+ __func__, nol->nol_freq, nol->nol_chwidth);
+ OS_CANCEL_TIMER(&nol->nol_timer);
+ OS_SET_TIMER(&nol->nol_timer, dfs_nol_timeout*TIME_IN_MS);
+ return;
+ }
+ prev = nol;
+ nol = nol->nol_next;
+ }
+ /* Add a new element to the NOL*/
+ elem = (struct dfs_nolelem *)OS_MALLOC(NULL, sizeof(struct dfs_nolelem),GFP_ATOMIC);
+ if (elem == NULL) {
+ goto bad;
+ }
+ dfs_nol_arg = (struct dfs_nol_timer_arg *)OS_MALLOC(NULL,
+ sizeof(struct dfs_nol_timer_arg), GFP_ATOMIC);
+ if (dfs_nol_arg == NULL) {
+ OS_FREE(elem);
+ goto bad;
+ }
+ elem->nol_freq = chan->ic_freq;
+ elem->nol_chwidth = ch_width;
+ elem->nol_start_ticks = adf_os_ticks();
+ elem->nol_timeout_ms = dfs_nol_timeout*TIME_IN_MS;
+ elem->nol_next = NULL;
+ if (prev) {
+ prev->nol_next = elem;
+ } else {
+ /* This is the first element in the NOL */
+ dfs->dfs_nol = elem;
+ }
+ dfs_nol_arg->dfs = dfs;
+ dfs_nol_arg->delfreq = elem->nol_freq;
+ dfs_nol_arg->delchwidth = elem->nol_chwidth;
+
+ OS_INIT_TIMER(NULL, &elem->nol_timer, dfs_remove_from_nol,
+ dfs_nol_arg);
+ OS_SET_TIMER(&elem->nol_timer, dfs_nol_timeout*TIME_IN_MS);
+
+ /* Update the NOL counter */
+ dfs->dfs_nol_count++;
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL,
+ "%s: new NOL channel %d MHz / %d MHz\n",
+ __func__,
+ elem->nol_freq,
+ elem->nol_chwidth);
+ return;
+
+bad:
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL | ATH_DEBUG_DFS,
+ "%s: failed to allocate memory for nol entry\n", __func__);
+
+#undef TIME_IN_MS
+#undef TIME_IN_US
+}
+
+/*
+ * Delete the given frequency/chwidth from the NOL.
+ */
+static void
+dfs_nol_delete(struct ath_dfs *dfs, u_int16_t delfreq, u_int16_t delchwidth)
+{
+ struct dfs_nolelem *nol,**prev_next;
+
+ if (dfs == NULL) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: sc_dfs is NULL\n", __func__);
+ return;
+ }
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL,
+ "%s: remove channel=%d/%d MHz from NOL\n",
+ __func__,
+ delfreq, delchwidth);
+ prev_next = &(dfs->dfs_nol);
+ nol = dfs->dfs_nol;
+ while (nol != NULL) {
+ if (nol->nol_freq == delfreq && nol->nol_chwidth == delchwidth) {
+ *prev_next = nol->nol_next;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL,
+ "%s removing channel %d/%dMHz from NOL tstamp=%d\n",
+ __func__, nol->nol_freq, nol->nol_chwidth,
+ (adf_os_ticks_to_msecs(adf_os_ticks()) / 1000));
+ OS_CANCEL_TIMER(&nol->nol_timer);
+ OS_FREE(nol);
+ nol = NULL;
+ nol = *prev_next;
+
+ /* Update the NOL counter */
+ dfs->dfs_nol_count--;
+
+ /* Be paranoid! */
+ if (dfs->dfs_nol_count < 0) {
+ DFS_PRINTK("%s: dfs_nol_count < 0; eek!\n", __func__);
+ dfs->dfs_nol_count = 0;
+ }
+
+ } else {
+ prev_next = &(nol->nol_next);
+ nol = nol->nol_next;
+ }
+ }
+}
+
+/*
+ * Notify the driver/umac that it should update the channel radar/NOL
+ * flags based on the current NOL list.
+ */
+void
+dfs_nol_update(struct ath_dfs *dfs)
+{
+ struct ieee80211com *ic = dfs->ic;
+ struct dfs_nol_chan_entry *dfs_nol;
+ struct dfs_nolelem *nol;
+ int nlen;
+
+ /*
+ * Allocate enough entries to store the NOL.
+ *
+ * At least on Linux (don't ask why), if you allocate a 0 entry
+ * array, the returned pointer is 0x10. Make sure you're
+ * aware of this when you start debugging.
+ */
+ dfs_nol = (struct dfs_nol_chan_entry *)OS_MALLOC(NULL,
+ sizeof(struct dfs_nol_chan_entry) * dfs->dfs_nol_count,
+ GFP_ATOMIC);
+
+ if (dfs_nol == NULL) {
+ /*
+ * XXX TODO: if this fails, just schedule a task to retry
+ * updating the NOL at a later stage. That way the NOL
+ * update _DOES_ happen - hopefully the failure was just
+ * temporary.
+ */
+ DFS_PRINTK("%s: failed to allocate NOL update memory!\n",
+ __func__);
+ return;
+ }
+
+
+ /* populate the nol array */
+ nlen = 0;
+
+ nol = dfs->dfs_nol;
+ while (nol != NULL && nlen < dfs->dfs_nol_count) {
+ dfs_nol[nlen].nol_chfreq = nol->nol_freq;
+ dfs_nol[nlen].nol_chwidth = nol->nol_chwidth;
+ dfs_nol[nlen].nol_start_ticks = nol->nol_start_ticks;
+ dfs_nol[nlen].nol_timeout_ms = nol->nol_timeout_ms;
+ nlen++;
+ nol = nol->nol_next;
+ }
+
+ /* Be suitably paranoid for now */
+ if (nlen != dfs->dfs_nol_count)
+ DFS_PRINTK("%s: nlen (%d) != dfs->dfs_nol_count (%d)!\n",
+ __func__, nlen, dfs->dfs_nol_count);
+
+ /*
+ * Call the driver layer to have it recalculate the NOL flags for
+ * each driver/umac channel.
+ *
+ * If the list is empty, pass NULL instead of dfs_nol.
+ *
+ * The operating system may have some special representation for
+ * "malloc a 0 byte memory region" - for example,
+ * Linux 2.6.38-13 (ubuntu) returns 0x10 rather than a valid
+ * allocation (and is likely not NULL so the pointer doesn't
+ * match NULL checks in any later code.
+ */
+ ic->ic_dfs_clist_update(ic, DFS_NOL_CLIST_CMD_UPDATE,
+ (nlen > 0) ? dfs_nol : NULL, nlen);
+
+ /*
+ * .. and we're done.
+ */
+ OS_FREE(dfs_nol);
+}
+
+void dfs_nol_timer_cleanup(struct ath_dfs *dfs)
+{
+ struct dfs_nolelem *nol = dfs->dfs_nol, *prev;
+
+ /* First Cancel timer */
+ while (nol) {
+ OS_CANCEL_TIMER(&nol->nol_timer);
+ nol = nol->nol_next;
+ }
+ /* Free NOL elem, don't mix this while loop with above loop */
+ nol = dfs->dfs_nol;
+ while (nol) {
+ prev = nol;
+ nol = nol->nol_next;
+ OS_FREE(prev);
+ }
+ return;
+}
+#endif /* defined(ATH_SUPPORT_DFS) && !defined(ATH_DFS_RADAR_DETECTION_ONLY) */
diff --git a/CORE/VOSS/src/packet.c b/CORE/SERVICES/DFS/src/dfs_phyerr.h
index 980b96f56bc5..5b471d8f0d9e 100644
--- a/CORE/VOSS/src/packet.c
+++ b/CORE/SERVICES/DFS/src/dfs_phyerr.h
@@ -25,44 +25,40 @@
* to the Linux Foundation.
*/
-/**========================================================================
+/*===========================================================================
- \file packet.c
- \brief Implementation of packet module
+ dfs_phyerr.h
- ========================================================================*/
-/**=========================================================================
- EDIT HISTORY FOR FILE
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
This section contains comments describing changes made to the module.
Notice that changes are listed in reverse chronological order.
- $Header:$ $DateTime: $ $Author: $
- when who what, where, why
- -------- --- -----------------------------------------
- 26/03/2013 Ganesh Created module for Packet Handling
- Babu
- ==========================================================================*/
-#include "packet.h"
-#include "adf_nbuf.h"
-#include "vos_memory.h"
-
-/**
- * voss_rx_packet_free Free the Rx Packet
- * @ Rx Packet
- */
-void voss_rx_packet_free(void* rxpacket)
-{
- tp_rxpacket rx_packet = (tp_rxpacket)rxpacket;
+ when who what, where, why
+---------- --- --------------------------------------------------------
- /* Free up the Adf nbuf */
- adf_nbuf_free(rx_packet->rx_nbuf);
+===========================================================================*/
- /* Free up the Rx packet */
- vos_mem_free(rx_packet);
-}
+#ifndef __DFS_PHYERR_H__
+#define __DFS_PHYERR_H__
+extern int dfs_process_phyerr_bb_tlv(struct ath_dfs *dfs, void *buf,
+ u_int16_t datalen, u_int8_t rssi, u_int8_t ext_rssi,
+ u_int32_t rs_tstamp, u_int64_t fulltsf, struct dfs_phy_err *e);
+#endif /* __DFS_PHYERR_H__ */
diff --git a/CORE/SERVICES/DFS/src/dfs_phyerr_tlv.c b/CORE/SERVICES/DFS/src/dfs_phyerr_tlv.c
new file mode 100644
index 000000000000..bb584a5883c8
--- /dev/null
+++ b/CORE/SERVICES/DFS/src/dfs_phyerr_tlv.c
@@ -0,0 +1,667 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ dfs_phyerr_tlv.c
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+
+#include "dfs.h"
+/* TO DO DFS
+#include <ieee80211_var.h>
+*/
+/* TO DO DFS
+#include <ieee80211_channel.h>
+*/
+#include "dfs_phyerr.h"
+#include "dfs_phyerr_tlv.h"
+
+/*
+ * Parsed radar status
+ */
+struct rx_radar_status {
+ uint32_t raw_tsf;
+ uint32_t tsf_offset;
+ int rssi;
+ int pulse_duration;
+ int is_chirp:1;
+ int delta_peak;
+ int delta_diff;
+ int sidx;
+ int freq_offset; /* in KHz */
+};
+
+
+struct rx_search_fft_report {
+ uint32_t total_gain_db;
+ uint32_t base_pwr_db;
+ int fft_chn_idx;
+ int peak_sidx;
+ int relpwr_db;
+ int avgpwr_db;
+ int peak_mag;
+ int num_str_bins_ib;
+};
+
+
+/*
+ * XXX until "fastclk" is stored in the DFS configuration..
+ */
+#define PERE_IS_OVERSAMPLING(_dfs) (1)
+
+/*
+ * XXX there _has_ to be a better way of doing this!
+ * -adrian
+ */
+static int32_t
+sign_extend_32(uint32_t v, int nb)
+{
+ uint32_t m = 1U << (nb - 1);
+
+ /* Chop off high bits, just in case */
+ v &= v & ((1U << nb) - 1);
+
+ /* Extend */
+ return (v ^ m) - m;
+}
+
+/*
+ * Calculate the frequency offset from the given signed bin index
+ * from the radar summary report.
+ *
+ * This takes the oversampling mode into account.
+ *
+ * For oversampling, each bin has resolution 44MHz/128.
+ * For non-oversampling, each bin has resolution 40MHz/128.
+ *
+ * It returns kHz - ie, 1000th's of MHz.
+ */
+static int
+calc_freq_offset(int sindex, int is_oversampling)
+{
+
+ if (is_oversampling)
+ return (sindex * (44000 / 128));
+ else
+ return (sindex * (40000 / 128));
+}
+
+static void
+radar_summary_print(struct ath_dfs *dfs, struct rx_radar_status *rsu)
+{
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ " pulsedur=%d\n", rsu->pulse_duration);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ " rssi=%d\n", rsu->rssi);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ " ischirp=%d\n", rsu->is_chirp);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ " sidx=%d\n", rsu->sidx);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ " raw tsf=%d\n", rsu->raw_tsf);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ " tsf_offset=%d\n", rsu->tsf_offset);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ " cooked tsf=%d\n", rsu->raw_tsf - rsu->tsf_offset);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ " frequency offset=%d.%d MHz (oversampling=%d)\n",
+ (int) (rsu->freq_offset / 1000),
+ (int) abs(rsu->freq_offset % 1000),
+ PERE_IS_OVERSAMPLING(dfs));
+}
+
+/*
+ * 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 a Peregrine BB TLV frame.
+ *
+ * This routine parses each TLV, prints out what's going on and
+ * calls an appropriate sub-function.
+ *
+ * Since the TLV format doesn't _specify_ all TLV components are
+ * DWORD aligned, we must treat them as not and access the fields
+ * appropriately.
+ */
+static int
+tlv_parse_frame(struct ath_dfs *dfs, struct rx_radar_status *rs,
+ struct rx_search_fft_report *rsfr, const char *buf, size_t len, u_int8_t rssi)
+{
+ int i = 0;
+ uint32_t tlv_hdr[1];
+ bool first_tlv = true;
+ bool false_detect = false;
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ "%s: total length = %d bytes\n", __func__, len);
+ while ((i < len ) && (false_detect == false)) {
+ /* Ensure we at least have four bytes */
+ if ((len - i) < sizeof(tlv_hdr)) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR |
+ ATH_DEBUG_DFS_PHYERR_SUM,
+ "%s: ran out of bytes, len=%d, i=%d\n",
+ __func__, len, i);
+ return (0);
+ }
+
+ /*
+ * Copy the offset into the header,
+ * so the DWORD style access macros
+ * can be used.
+ */
+ OS_MEMCPY(&tlv_hdr, buf + i, sizeof(tlv_hdr));
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ "%s: HDR: TLV SIG=0x%x, TAG=0x%x, LEN=%d bytes\n",
+ __func__,
+ MS(tlv_hdr[TLV_REG], TLV_SIG),
+ MS(tlv_hdr[TLV_REG], TLV_TAG),
+ MS(tlv_hdr[TLV_REG], TLV_LEN));
+
+ /*
+ * Sanity check the length field is available in
+ * the remaining frame. Drop out if this isn't
+ * the case - we can't trust the rest of the TLV
+ * entries.
+ */
+ if (MS(tlv_hdr[TLV_REG], TLV_LEN) + i >= len) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ "%s: TLV oversize: TLV LEN=%d, available=%d, "
+ "i=%d\n",
+ __func__,
+ MS(tlv_hdr[TLV_REG], TLV_LEN),
+ len,
+ i);
+ break;
+ }
+
+ /* Skip the TLV header - one DWORD */
+ i += sizeof(tlv_hdr);
+
+ /* Handle the payload */
+ /* XXX TODO! */
+ switch (MS(tlv_hdr[TLV_REG], TLV_SIG)) {
+ case TAG_ID_RADAR_PULSE_SUMMARY: /* Radar pulse summary */
+ /* XXX TODO verify return value */
+ /* XXX TODO validate only seeing one of these */
+ radar_summary_parse(dfs, buf + i,
+ MS(tlv_hdr[TLV_REG], TLV_LEN), rs);
+ break;
+ case TAG_ID_SEARCH_FFT_REPORT:
+ radar_fft_search_report_parse(dfs, buf + i,
+ MS(tlv_hdr[TLV_REG], TLV_LEN), rsfr);
+ /*
+ we examine search FFT report and make the following assumption
+ as per algorithms group's input:
+ (1) There may be multiple TLV
+ (2) We make false detection decison solely based on the first TLV
+ (3) If the first TLV is a serch FFT report then we check the peak_mag value.
+ When RSSI is equal to dfs->ath_dfs_false_rssI_thres (default 50)
+ and peak_mag is less than 2 * dfs->ath_dfs_peak_mag (default 40)
+ we treat it as false detect.
+ Please note that 50 is not a true RSSI estimate, but value indicated
+ by HW for RF saturation event.
+ */
+
+ if ((first_tlv == true) &&
+ (rssi == dfs->ath_dfs_false_rssi_thres) &&
+ (rsfr->peak_mag < (2 * dfs->ath_dfs_peak_mag))) {
+ false_detect = true;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: setting false_detect to TRUE\n", __func__);
+ }
+
+ break;
+ default:
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ "%s: unknown entry, SIG=0x%02x\n",
+ __func__,
+ MS(tlv_hdr[TLV_REG], TLV_SIG));
+ }
+
+ /* Skip the payload */
+ i += MS(tlv_hdr[TLV_REG], TLV_LEN);
+ first_tlv = false;
+ }
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR, "%s: done\n\n", __func__);
+
+ return (false_detect? 0 : 1);
+}
+
+/*
+ * 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);
+}
+
+/*
+ * Calculate the centre frequency and low/high range for a radar pulse event.
+ *
+ * XXX TODO: Handle half/quarter rates correctly!
+ * XXX TODO: handle VHT160 correctly!
+ * XXX TODO: handle VHT80+80 correctly!
+ */
+static int
+tlv_calc_event_freq_pulse(struct ath_dfs *dfs, struct rx_radar_status *rs,
+ uint32_t *freq_centre, uint32_t *freq_lo, uint32_t *freq_hi)
+{
+ int chan_width;
+ int chan_centre;
+
+ /* Fetch the channel centre frequency in MHz */
+ chan_centre = tlv_calc_freq_info(dfs, rs);
+
+ /* Convert to KHz */
+ chan_centre *= 1000;
+
+ /*
+ * XXX hard-code event width to be 2 * bin size for now;
+ * XXX this needs to take into account the core clock speed
+ * XXX for half/quarter rate mode.
+ */
+ if (PERE_IS_OVERSAMPLING(dfs))
+ chan_width = (44000 * 2 / 128);
+ else
+ chan_width = (40000 * 2 / 128);
+
+ /* XXX adjust chan_width for half/quarter rate! */
+
+ /*
+ * Now we can do the math to figure out the correct channel range.
+ */
+ (*freq_centre) = (uint32_t) (chan_centre + rs->freq_offset);
+ (*freq_lo) = (uint32_t) ((chan_centre + rs->freq_offset)
+ - chan_width);
+ (*freq_hi) = (uint32_t) ((chan_centre + rs->freq_offset)
+ + chan_width);
+
+ return (1);
+}
+
+/*
+ * The chirp bandwidth in KHz is defined as:
+ *
+ * totalBW(KHz) = delta_peak(mean)
+ * * [ (bin resolution in KHz) / (radar_fft_long_period in uS) ]
+ * * pulse_duration (us)
+ *
+ * The bin resolution depends upon oversampling.
+ *
+ * For now, we treat the radar_fft_long_period as a hard-coded 8uS.
+ */
+static int
+tlv_calc_event_freq_chirp(struct ath_dfs *dfs, struct rx_radar_status *rs,
+ uint32_t *freq_centre, uint32_t *freq_lo, uint32_t *freq_hi)
+{
+ int32_t bin_resolution; /* KHz * 100 */
+ int32_t radar_fft_long_period = 8; /* microseconds */
+ int32_t delta_peak;
+ int32_t pulse_duration;
+ int32_t total_bw;
+ int32_t chan_centre;
+ int32_t freq_1, freq_2;
+
+ /*
+ * KHz isn't enough resolution here!
+ * So treat it as deci-hertz (10Hz) and convert back to KHz
+ * later.
+ */
+ if (PERE_IS_OVERSAMPLING(dfs))
+ bin_resolution = (44000 * 100) / 128;
+ else
+ bin_resolution = (40000 * 100) / 128;
+
+ delta_peak = rs->delta_peak;
+ pulse_duration = rs->pulse_duration;
+
+ total_bw = delta_peak * (bin_resolution / radar_fft_long_period) *
+ pulse_duration;
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR | ATH_DEBUG_DFS_PHYERR_SUM,
+ "%s: delta_peak=%d, pulse_duration=%d, bin_resolution=%d.%dKHz, "
+ "radar_fft_long_period=%d, total_bw=%d.%ldKHz\n",
+ __func__,
+ delta_peak,
+ pulse_duration,
+ bin_resolution / 1000,
+ bin_resolution % 1000,
+ radar_fft_long_period,
+ total_bw / 100,
+ abs(total_bw % 100));
+
+ total_bw /= 100; /* back to KHz */
+
+ /* Grab the channel centre frequency in MHz */
+ chan_centre = tlv_calc_freq_info(dfs, rs);
+
+ /* Early abort! */
+ if (chan_centre == 0) {
+ (*freq_centre) = 0;
+ return (0);
+ }
+
+ /* Convert to KHz */
+ chan_centre *= 1000;
+
+ /*
+ * sidx is the starting frequency; total_bw is a signed value and
+ * for negative chirps (ie, moving down in frequency rather than up)
+ * the end frequency may be less than the start frequency.
+ */
+ if (total_bw > 0) {
+ freq_1 = chan_centre + rs->freq_offset;
+ freq_2 = chan_centre + rs->freq_offset + total_bw;
+ } else {
+ freq_1 = chan_centre + rs->freq_offset + total_bw;
+ freq_2 = chan_centre + rs->freq_offset;
+ }
+
+ (*freq_lo) = (uint32_t)(freq_1);
+ (*freq_hi) = (uint32_t)(freq_2);
+ (*freq_centre) = (uint32_t) (freq_1 + (abs(total_bw) / 2));
+
+ return (1);
+}
+
+/*
+ * Calculate the centre and band edge frequencies of the given radar
+ * event.
+ */
+static int
+tlv_calc_event_freq(struct ath_dfs *dfs, struct rx_radar_status *rs,
+ uint32_t *freq_centre, uint32_t *freq_lo, uint32_t *freq_hi)
+{
+ if (rs->is_chirp)
+ return tlv_calc_event_freq_chirp(dfs, rs, freq_centre,
+ freq_lo, freq_hi);
+ else
+ return tlv_calc_event_freq_pulse(dfs, rs, freq_centre,
+ freq_lo, freq_hi);
+}
+
+/*
+ * This is the public facing function which parses the PHY error
+ * and populates the dfs_phy_err struct.
+ */
+int
+dfs_process_phyerr_bb_tlv(struct ath_dfs *dfs, void *buf, u_int16_t datalen,
+ u_int8_t rssi, u_int8_t ext_rssi, u_int32_t rs_tstamp, u_int64_t fulltsf,
+ struct dfs_phy_err *e)
+{
+ struct rx_radar_status rs;
+ struct rx_search_fft_report rsfr;
+
+ OS_MEMZERO(&rs, sizeof(rs));
+
+ /*
+ * Add the ppdu_start/ppdu_end fields given to us by the upper
+ * layers. The firmware gives us a summary set of parameters rather
+ * than the whole PPDU_START/PPDU_END descriptor contenst.
+ */
+ rs.rssi = rssi;
+ rs.raw_tsf = rs_tstamp;
+
+ /*
+ * Try parsing the TLV set.
+ */
+ if (! tlv_parse_frame(dfs, &rs, &rsfr, buf, datalen, rssi)){
+ printk("%s[%d]: !tlv_parse_frame FAILED \n",__func__,__LINE__);
+ return (0);
+ }
+ /* For debugging, print what we have parsed */
+ radar_summary_print(dfs, &rs);
+
+ /* Populate dfs_phy_err from rs */
+ OS_MEMSET(e, 0, sizeof(*e));
+ e->rssi = rs.rssi;
+ e->dur = rs.pulse_duration;
+ e->is_pri = 1; /* XXX always PRI for now */
+ e->is_ext = 0;
+ e->is_dc = 0;
+ e->is_early = 0;
+ /*
+ * XXX TODO: add a "chirp detection enabled" capability or config
+ * bit somewhere, in case for some reason the hardware chirp
+ * detection AND FFTs are disabled.
+ */
+ /* For now, assume this hardware always does chirp detection */
+ e->do_check_chirp = 1;
+ e->is_hw_chirp = !! (rs.is_chirp);
+ e->is_sw_chirp = 0; /* We don't yet do software chirp checking */
+
+ e->fulltsf = fulltsf;
+ e->rs_tstamp = rs.raw_tsf - rs.tsf_offset;
+
+ /* XXX error check */
+ (void) tlv_calc_event_freq(dfs, &rs, &e->freq, &e->freq_lo,
+ &e->freq_hi);
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR_SUM,
+ "%s: fbin=%d, freq=%d.%d MHz, raw tsf=%u, offset=%d, "
+ "cooked tsf=%u, rssi=%d, dur=%d, is_chirp=%d, fulltsf=%llu, "
+ "freq=%d.%d MHz, freq_lo=%d.%dMHz, freq_hi=%d.%d MHz\n",
+ __func__,
+ rs.sidx,
+ (int) (rs.freq_offset / 1000),
+ (int) abs(rs.freq_offset % 1000),
+ rs.raw_tsf,
+ rs.tsf_offset,
+ e->rs_tstamp,
+ rs.rssi,
+ rs.pulse_duration,
+ (int) rs.is_chirp,
+ (unsigned long long) fulltsf,
+ (int) e->freq / 1000,
+ (int) abs(e->freq) % 1000,
+ (int) e->freq_lo / 1000,
+ (int) abs(e->freq_lo) % 1000,
+ (int) e->freq_hi / 1000,
+ (int) abs(e->freq_hi) % 1000);
+
+ return (1);
+}
diff --git a/CORE/SERVICES/DFS/src/dfs_phyerr_tlv.h b/CORE/SERVICES/DFS/src/dfs_phyerr_tlv.h
new file mode 100644
index 000000000000..c15e7f5517c1
--- /dev/null
+++ b/CORE/SERVICES/DFS/src/dfs_phyerr_tlv.h
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ dfs_phyerr_tlv.h
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+#ifndef __DFS_PHYERR_PEREGRINE_H__
+#define __DFS_PHYERR_PEREGRINE_H__
+
+/*
+ * Register manipulation macros that expect bit field defines
+ * to follow the convention that an _S suffix is appended for
+ * a shift count, while the field mask has no suffix.
+ */
+#define SM(_v, _f) (((_v) << _f##_S) & _f)
+#define MS(_v, _f) (((_v) & _f) >> _f##_S)
+
+/*
+ * The TLV dword is at the beginning of each TLV section.
+ */
+#define TLV_REG 0x00
+
+#define TLV_LEN 0x0000FFFF
+#define TLV_LEN_S 0
+
+#define TLV_SIG 0x00FF0000
+#define TLV_SIG_S 16
+
+#define TLV_TAG 0xFF000000
+#define TLV_TAG_S 24
+
+#define TAG_ID_SEARCH_FFT_REPORT 0xFB
+#define TAG_ID_RADAR_PULSE_SUMMARY 0xF8
+/*
+ * Radar pulse summary
+ *
+ * + TYPE=0xF8 (Radar pulse summary reprot)
+ * + SIG=0xBB (baseband PHY generated TLV components)
+ */
+
+#define RADAR_REPORT_PULSE_REG_1 0x00
+
+#define RADAR_REPORT_PULSE_IS_CHIRP 0x80000000
+#define RADAR_REPORT_PULSE_IS_CHIRP_S 31
+
+#define RADAR_REPORT_PULSE_IS_MAX_WIDTH 0x40000000
+#define RADAR_REPORT_PULSE_IS_MAX_WIDTH_S 30
+
+#define RADAR_REPORT_AGC_TOTAL_GAIN 0x3FF00000
+#define RADAR_REPORT_AGC_TOTAL_GAIN_S 20
+
+#define RADAR_REPORT_PULSE_DELTA_DIFF 0x000F0000
+#define RADAR_REPORT_PULSE_DELTA_DIFF_S 16
+
+#define RADAR_REPORT_PULSE_DELTA_PEAK 0x0000FC00
+#define RADAR_REPORT_PULSE_DELTA_PEAK_S 10
+
+#define RADAR_REPORT_PULSE_SIDX 0x000003FF
+#define RADAR_REPORT_PULSE_SIDX_S 0x0
+
+#define RADAR_REPORT_PULSE_REG_2 0x01
+
+#define RADAR_REPORT_PULSE_SRCH_FFT_A_VALID 0x80000000
+#define RADAR_REPORT_PULSE_SRCH_FFT_A_VALID_S 31
+
+#define RADAR_REPORT_PULSE_AGC_MB_GAIN 0x7F000000
+#define RADAR_REPORT_PULSE_AGC_MB_GAIN_S 24
+
+#define RADAR_REPORT_PULSE_SUBCHAN_MASK 0x00FF0000
+#define RADAR_REPORT_PULSE_SUBCHAN_MASK_S 16
+
+#define RADAR_REPORT_PULSE_TSF_OFFSET 0x0000FF00
+#define RADAR_REPORT_PULSE_TSF_OFFSET_S 8
+
+#define RADAR_REPORT_PULSE_DUR 0x000000FF
+#define RADAR_REPORT_PULSE_DUR_S 0
+
+#define SEARCH_FFT_REPORT_REG_1 0x00
+
+
+#define SEARCH_FFT_REPORT_TOTAL_GAIN_DB 0xFF800000
+#define SEARCH_FFT_REPORT_TOTAL_GAIN_DB_S 23
+
+#define SEARCH_FFT_REPORT_BASE_PWR_DB 0x007FC000
+#define SEARCH_FFT_REPORT_BASE_PWR_DB_S 14
+
+#define SEARCH_FFT_REPORT_FFT_CHN_IDX 0x00003000
+#define SEARCH_FFT_REPORT_FFT_CHN_IDX_S 12
+
+#define SEARCH_FFT_REPORT_PEAK_SIDX 0x00000FFF
+#define SEARCH_FFT_REPORT_PEAK_SIDX_S 0
+
+#define SEARCH_FFT_REPORT_REG_2 0x01
+
+#define SEARCH_FFT_REPORT_RELPWR_DB 0xFC000000
+#define SEARCH_FFT_REPORT_RELPWR_DB_S 26
+
+#define SEARCH_FFT_REPORT_AVGPWR_DB 0x03FC0000
+#define SEARCH_FFT_REPORT_AVGPWR_DB_S 18
+
+#define SEARCH_FFT_REPORT_PEAK_MAG 0x0003FF00
+#define SEARCH_FFT_REPORT_PEAK_MAG_S 8
+
+#define SEARCH_FFT_REPORT_NUM_STR_BINS_IB 0x000000FF
+#define SEARCH_FFT_REPORT_NUM_STR_BINS_IB_S 0
+
+
+
+/*
+ * Although this code is now not parsing the whole frame (descriptor
+ * and all), the relevant fields are still useful information
+ * for anyone who is working on the PHY error part of DFS pattern
+ * matching.
+ *
+ * However, to understand _where_ these descriptors start, you
+ * should do some digging into the peregrine descriptor format.
+ * The 30 second version: each RX ring has a bitmap listing which
+ * descriptors are to be included, and then a set of offsets
+ * into the RX buffer for where each descriptor will be written.
+ * It's not like the 802.11n generation hardware which has
+ * a fixed descriptor format.
+ */
+
+/*
+ * RX_PPDU_START
+ */
+#define RX_PPDU_START_LEN (10*4)
+
+#define RX_PPDU_START_REG_4 0x0004
+#define RX_PPDU_START_RSSI_COMB 0x000000FF
+#define RX_PPDU_START_RSSI_COMB_S 0
+
+/*
+ * RX_PPDU_END
+ */
+#define RX_PPDU_END_LEN (21*4)
+
+#define RX_PPDU_END_REG_16 16
+#define RX_PPDU_END_TSF_TIMESTAMP 0xFFFFFFFF
+#define RX_PPDU_END_TSF_TIMESTAMP_S 0
+
+#define RX_PPDU_END_REG_18 18
+#define RX_PPDU_END_PHY_ERR_CODE 0x0000FF00
+#define RX_PPDU_END_PHY_ERR_CODE_S 8
+#define RX_PPDU_END_PHY_ERR 0x00010000
+#define RX_PPDU_END_PHY_ERR_S 16
+
+/*
+ * The RSSI values can have "special meanings".
+ *
+ * If rssi=50, it means that the peak detector triggered.
+ */
+#define RSSI_PEAK_DETECTOR_SAT 50
+
+/*
+ *
+ * If rssi=25, it means that the ADC was saturated, but that only is
+ * valid when there is one ADC gain change. For short pulses this
+ * is true - you won't have time to do a gain change before the pulse
+ * goes away. But for longer pulses, ADC gain changes can occur, so
+ * you'll get a more accurate RSSI figure.
+ *
+ * For short pulses (and the definition of "short" still isn't clear
+ * at the time of writing) there isn't any real time to do a gain change
+ * (or two, or three..) in order to get an accurate estimation of signal
+ * sizing. Thus, RSSI will not be very accurate for short duration pulses.
+ * All you can really say for certain is that yes, there's a pulse that
+ * met the requirements of the pulse detector.
+ *
+ * For more information, see the 802.11ac Microarchitecture guide.
+ * (TODO: add a twiki reference.)
+ */
+
+#endif /* __DFS_PHYERR_PEREGRINE_H__ */
diff --git a/CORE/SERVICES/DFS/src/dfs_process_phyerr.c b/CORE/SERVICES/DFS/src/dfs_process_phyerr.c
new file mode 100644
index 000000000000..f98cb99964ff
--- /dev/null
+++ b/CORE/SERVICES/DFS/src/dfs_process_phyerr.c
@@ -0,0 +1,883 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ dfs_process_phyerr.c
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+
+#include "dfs.h"
+#include "dfs_phyerr.h" /* For chip-specific phyerr function declarations */
+/* TO DO DFS
+#include <ieee80211_var.h>
+*/
+#ifndef UNINET
+/* TO DO DFS
+#include <ieee80211_channel.h>
+*/
+#endif
+#ifdef ATH_SUPPORT_DFS
+
+/*
+ * Return the frequency width for the current operating channel.
+ *
+ * This isn't the channel width - it's how wide the reported event
+ * may be. For HT20 this is 20MHz. For HT40 on Howl and later it'll
+ * still be 20MHz - the hardware returns either pri or ext channel.
+ */
+static inline int
+dfs_get_event_freqwidth(struct ath_dfs *dfs)
+{
+
+ /* 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);
+
+ /*
+ * XXX For now, assume 20MHz wide - but this is incorrect when
+ * operating in half/quarter mode!
+ */
+ return (20);
+}
+
+/*
+ * 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));
+}
+
+/*
+ * Process an Owl-style phy error.
+ *
+ * Return 1 on success or 0 on failure.
+ */
+int
+dfs_process_phyerr_owl(struct ath_dfs *dfs, void *buf, u_int16_t datalen,
+ u_int8_t rssi, u_int8_t ext_rssi, u_int32_t rs_tstamp, u_int64_t fulltsf,
+ struct dfs_phy_err *e)
+{
+ const char *cbuf = (const char *) buf;
+ u_int8_t dur;
+ int event_width;
+
+ /* XXX this shouldn't be kept count here */
+ dfs->ath_dfs_stats.owl_phy_errors++;
+
+ /*
+ * HW cannot detect extension channel radar so it only passes us
+ * primary channel radar data
+ */
+ if (datalen == 0)
+ dur = 0;
+ else
+ dur = ((u_int8_t *) cbuf)[0];
+
+ /*
+ * This is a spurious event; toss.
+ */
+ if (rssi == 0 && dur == 0)
+ dfs->ath_dfs_stats.datalen_discards++;
+ return (0);
+
+ /*
+ * Fill out dfs_phy_err with the information we have
+ * at hand.
+ */
+ OS_MEMSET(e, 0, sizeof(*e));
+ e->rssi = rssi;
+ e->dur = dur;
+ e->is_pri = 1;
+ e->is_ext = 0;
+ e->is_dc = 0;
+ e->is_early = 1;
+ e->fulltsf = fulltsf;
+ e->rs_tstamp = rs_tstamp;
+
+ /*
+ * Owl only ever reports events on the primary channel;
+ * it doesn't even see events on the secondary channel.
+ */
+ event_width = dfs_get_event_freqwidth(dfs);
+ e->freq = dfs_get_event_freqcentre(dfs, 1, 0, 0) * 1000;
+ e->freq_lo = e->freq - (event_width / 2) * 1000;
+ e->freq_hi = e->freq + (event_width / 2) * 1000;
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR_SUM,
+ "%s: rssi=%u dur=%u, freq=%d MHz, freq_lo=%d MHz, "
+ "freq_hi=%d MHz\n",
+ __func__,
+ rssi,
+ dur,
+ e->freq / 1000,
+ e->freq_lo / 1000,
+ e->freq_hi / 1000);
+
+ return (1);
+}
+
+/*
+ * Process a Sowl/Howl style phy error.
+ */
+int
+dfs_process_phyerr_sowl(struct ath_dfs *dfs, void *buf, u_int16_t datalen,
+ u_int8_t rssi, u_int8_t ext_rssi, u_int32_t rs_tstamp, u_int64_t fulltsf,
+ struct dfs_phy_err *e)
+{
+#define EXT_CH_RADAR_FOUND 0x02
+#define PRI_CH_RADAR_FOUND 0x01
+#define EXT_CH_RADAR_EARLY_FOUND 0x04
+ const char *cbuf = (const char *) buf;
+ u_int8_t dur = 0;
+ u_int8_t pulse_bw_info, pulse_length_ext, pulse_length_pri;
+ int pri_found, ext_found;
+ int early_ext = 0;
+ int event_width;
+
+ /*
+ * If radar can be detected on the extension channel, datalen zero
+ * pulses are bogus, discard them.
+ */
+ if (!datalen) {
+ dfs->ath_dfs_stats.datalen_discards++;
+ return (0);
+ }
+
+ /* Ensure that we have at least three bytes of payload */
+ if (datalen < 3) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
+ "%s: short error frame (%d bytes)\n",
+ __func__, datalen);
+ dfs->ath_dfs_stats.datalen_discards++;
+ return (0);
+ }
+
+ /*
+ * Fetch the payload directly - the compiler will happily generate
+ * byte-read instructions with a const char * cbuf pointer.
+ */
+ pulse_length_pri = cbuf[datalen - 3];
+ pulse_length_ext = cbuf[datalen - 2];
+ pulse_bw_info = cbuf[datalen - 1];
+
+ /*
+ * Only the last 3 bits of the BW info are relevant, they indicate
+ * which channel the radar was detected in.
+ */
+ pulse_bw_info &= 0x07;
+
+ /*
+ * If pulse on DC, both primary and extension flags will be set
+ */
+ if (((pulse_bw_info & EXT_CH_RADAR_FOUND) &&
+ (pulse_bw_info & PRI_CH_RADAR_FOUND))) {
+ /*
+ * Conducted testing, when pulse is on DC, both
+ * pri and ext durations are reported to be same.
+ *
+ * Radiated testing, when pulse is on DC, different
+ * pri and ext durations are reported, so take the
+ * larger of the two
+ */
+ if (pulse_length_ext >= pulse_length_pri) {
+ dur = pulse_length_ext;
+ ext_found = 1;
+ } else {
+ dur = pulse_length_pri;
+ pri_found = 1;
+ }
+ dfs->ath_dfs_stats.dc_phy_errors++;
+ } else {
+ if (pulse_bw_info & EXT_CH_RADAR_FOUND) {
+ dur = pulse_length_ext;
+ pri_found = 0;
+ ext_found = 1;
+ dfs->ath_dfs_stats.ext_phy_errors++;
+ }
+ if (pulse_bw_info & PRI_CH_RADAR_FOUND) {
+ dur = pulse_length_pri;
+ pri_found = 1;
+ ext_found = 0;
+ dfs->ath_dfs_stats.pri_phy_errors++;
+ }
+ if (pulse_bw_info & EXT_CH_RADAR_EARLY_FOUND) {
+ dur = pulse_length_ext;
+ pri_found = 0;
+ ext_found = 1;
+ early_ext = 1;
+ dfs->ath_dfs_stats.early_ext_phy_errors++;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ "EARLY ext channel dur=%u rssi=%u datalen=%d\n",
+ dur, rssi, datalen);
+ }
+ if (! pulse_bw_info) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ "ERROR channel dur=%u rssi=%u pulse_bw_info=0x%x "
+ "datalen MOD 4 = %d\n",
+ dur, rssi, pulse_bw_info,
+ (datalen & 0x3));
+ /*
+ * Bogus bandwidth info received in descriptor,
+ * so ignore this PHY error
+ */
+ dfs->ath_dfs_stats.bwinfo_errors++;
+ return (0);
+ }
+ }
+
+ /*
+ * Always use combined RSSI reported, unless RSSI reported on
+ * extension is stronger
+ */
+ if ((ext_rssi > rssi) && (ext_rssi < 128)) {
+ rssi = ext_rssi;
+ }
+
+ /*
+ * Fill out the rssi/duration fields from above.
+ */
+ OS_MEMSET(e, 0, sizeof(*e));
+ e->rssi = rssi;
+ e->dur = dur;
+ e->is_pri = pri_found;
+ e->is_ext = ext_found;
+ e->is_dc = !! (((pulse_bw_info & EXT_CH_RADAR_FOUND) &&
+ (pulse_bw_info & PRI_CH_RADAR_FOUND)));
+ e->is_early = early_ext;
+ e->fulltsf = fulltsf;
+ e->rs_tstamp = rs_tstamp;
+
+ /*
+ * Sowl and later can report pri/ext events.
+ */
+ event_width = dfs_get_event_freqwidth(dfs);
+ e->freq =
+ dfs_get_event_freqcentre(dfs, e->is_pri, e->is_ext, e->is_dc)
+ * 1000;
+ e->freq_lo = e->freq - (event_width / 2) * 1000;
+ e->freq_hi = e->freq + (event_width / 2) * 1000;
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR_SUM,
+ "%s: pulse_bw_info=0x%x pulse_length_ext=%u pulse_length_pri=%u "
+ "rssi=%u ext_rssi=%u, freq=%d MHz, freq_lo=%d MHz, "
+ "freq_hi=%d MHz\n",
+ __func__,
+ pulse_bw_info,
+ pulse_length_ext,
+ pulse_length_pri,
+ rssi,
+ ext_rssi,
+ e->freq / 1000,
+ e->freq_lo / 1000,
+ e->freq_hi / 1000);
+
+ return (1);
+}
+
+/*
+ * Process a Merlin/Osprey style phy error.
+ */
+int
+dfs_process_phyerr_merlin(struct ath_dfs *dfs, void *buf,
+ u_int16_t datalen, u_int8_t rssi, u_int8_t ext_rssi, u_int32_t rs_tstamp,
+ u_int64_t fulltsf, struct dfs_phy_err *e)
+{
+ const char *cbuf = (const char *) buf;
+ u_int8_t pulse_bw_info = 0;
+
+ /*
+ * Process using the sowl code
+ */
+ if (! dfs_process_phyerr_sowl(dfs, buf, datalen, rssi, ext_rssi,
+ rs_tstamp, fulltsf, e)) {
+ return (0);
+ }
+
+ /*
+ * For osprey (and Merlin) bw_info has implication for selecting
+ * RSSI value. So re-fetch the bw_info field so the RSSI values
+ * can be appropriately overridden.
+ */
+ pulse_bw_info = cbuf[datalen - 1];
+
+ switch (pulse_bw_info & 0x03) {
+ case 0x00:
+ /* No radar in ctrl or ext channel */
+ rssi = 0;
+ break;
+ case 0x01:
+ /* radar in ctrl channel */
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ "RAW RSSI: rssi=%u ext_rssi=%u\n",
+ rssi, ext_rssi);
+ if (ext_rssi >= (rssi + 3)) {
+ /*
+ * cannot use ctrl channel RSSI if
+ * extension channel is stronger
+ */
+ rssi = 0;
+ }
+ break;
+ case 0x02:
+ /* radar in extension channel */
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ "RAW RSSI: rssi=%u ext_rssi=%u\n",
+ rssi, ext_rssi);
+ if (rssi >= (ext_rssi + 12)) {
+ /*
+ * cannot use extension channel RSSI if control channel
+ * is stronger
+ */
+ rssi = 0;
+ } else {
+ rssi = ext_rssi;
+ }
+ break;
+ case 0x03:
+ /* when both are present use stronger one */
+ if (rssi < ext_rssi) {
+ rssi = ext_rssi;
+ }
+ break;
+ }
+
+ /*
+ * Override the rssi decision made by the sowl code.
+ * The rest of the fields (duration, timestamp, etc)
+ * are left untouched.
+ */
+ e->rssi = rssi;
+
+ return(1);
+}
+
+static void
+dump_phyerr_contents(const char *d, int len)
+{
+ int i, n, bufsize = 64;
+
+ /*
+ * This is statically sized for a 4-digit address + 16 * 2 digit
+ * data string.
+ *
+ * It's done so the printk() passed to the kernel is an entire
+ * line, so the kernel logging code will atomically print it.
+ * Otherwise we'll end up with interleaved lines with output
+ * from other kernel threads.
+ */
+ char buf[64];
+
+ /* Initial conditions */
+ buf[0] = '\n';
+ n = 0;
+
+ for (i = 0; i < len; i++) {
+ if (i % 16 == 0) {
+ n += snprintf(buf + n, bufsize - n,
+ "%04x: ", i);
+ }
+ n += snprintf(buf + n, bufsize - n, "%02x ", d[i] & 0xff);
+ if (i % 16 == 15) {
+ n = 0;
+ buf[0] = '\0';
+ }
+ }
+
+ /*
+ * Print the final line if we didn't print it above.
+ */
+ if (n != 0)
+ printk("%s: %s\n", __func__, buf);
+}
+
+void
+dfs_process_phyerr(struct ieee80211com *ic, void *buf, u_int16_t datalen,
+ u_int8_t r_rssi, u_int8_t r_ext_rssi, u_int32_t r_rs_tstamp,
+ u_int64_t r_fulltsf)
+{
+ struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs;
+ struct ieee80211_channel *chan=ic->ic_curchan;
+ struct dfs_event *event;
+ struct dfs_phy_err e;
+ int empty;
+
+
+ dfs->dfs_phyerr_count++;
+ //dump_phyerr_contents(buf, datalen);
+ /*
+ * XXX The combined_rssi_ok support has been removed.
+ * This was only clear for Owl.
+ *
+ * XXX TODO: re-add this; it requires passing in the ctl/ext
+ * RSSI set from the RX status descriptor.
+ *
+ * XXX TODO TODO: this may be done for us from the legacy
+ * phy error path in ath_dev; please review that code.
+ */
+
+ /*
+ * At this time we have a radar pulse that we need to examine and
+ * queue. But if dfs_process_radarevent already detected radar and set
+ * CHANNEL_INTERFERENCE flag then do not queue any more radar data.
+ * When we are in a new channel this flag will be clear and we will
+ * start queueing data for new channel. (EV74162)
+ */
+ if (dfs->dfs_debug_mask & ATH_DEBUG_DFS_PHYERR_PKT)
+ //dump_phyerr_contents(buf, datalen);
+
+ if (IEEE80211_IS_CHAN_RADAR(chan)) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
+ "%s: Radar already found in the channel, "
+ " do not queue radar data\n",
+ __func__);
+ return;
+ }
+
+ if (dfs == NULL) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: sc_dfs is NULL\n",__func__);
+ return;
+ }
+ dfs->ath_dfs_stats.total_phy_errors++;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "%s[%d] phyerr %d len %d\n",
+ __func__, __LINE__,
+ dfs->ath_dfs_stats.total_phy_errors, datalen);
+
+ /*
+ * hardware stores this as 8 bit signed value.
+ * we will cap it at 0 if it is a negative number
+ */
+ if (r_rssi & 0x80)
+ r_rssi = 0;
+
+ if (r_ext_rssi & 0x80)
+ r_ext_rssi = 0;
+
+ OS_MEMSET(&e, 0, sizeof(e));
+
+ /*
+ * This is a bit evil - instead of just passing in
+ * the chip version, the existing code uses a set
+ * of HAL capability bits to determine what is
+ * possible.
+ *
+ * The way I'm decoding it is thus:
+ *
+ * + DFS enhancement? Merlin or later
+ * + DFS extension channel? Sowl or later. (Howl?)
+ * + otherwise, Owl (and legacy.)
+ */
+ if (dfs->dfs_caps.ath_chip_is_bb_tlv) {
+ if (dfs_process_phyerr_bb_tlv(dfs, buf, datalen, r_rssi,
+ r_ext_rssi, r_rs_tstamp, r_fulltsf, &e) == 0) {
+ dfs->dfs_phyerr_reject_count++;
+ return;
+ } else {
+ if (dfs->dfs_phyerr_freq_min > e.freq)
+ dfs->dfs_phyerr_freq_min = e. freq;
+
+ if (dfs->dfs_phyerr_freq_max < e.freq)
+ dfs->dfs_phyerr_freq_max = e. freq;
+ }
+ } else if (dfs->dfs_caps.ath_dfs_use_enhancement) {
+ if (dfs_process_phyerr_merlin(dfs, buf, datalen, r_rssi,
+ r_ext_rssi, r_rs_tstamp, r_fulltsf, &e) == 0){
+ return;
+ }
+ } else if (dfs->dfs_caps.ath_dfs_ext_chan_ok) {
+ if (dfs_process_phyerr_sowl(dfs, buf, datalen, r_rssi,
+ r_ext_rssi, r_rs_tstamp, r_fulltsf, &e) == 0){
+ return;
+ }
+ } else {
+ if (dfs_process_phyerr_owl(dfs, buf, datalen, r_rssi,
+ r_ext_rssi, r_rs_tstamp, r_fulltsf, &e) == 0){
+ return;
+ }
+ }
+
+ /*
+ * If the hardware supports radar reporting on the extension channel
+ * it will supply FFT data for longer radar pulses.
+ *
+ * TLV chips don't go through this software check - the hardware
+ * check should be enough. If we want to do software checking
+ * later on then someone will have to craft an FFT parser
+ * suitable for the TLV FFT data format.
+ */
+ if ((! dfs->dfs_caps.ath_chip_is_bb_tlv) &&
+ dfs->dfs_caps.ath_dfs_ext_chan_ok) {
+ /*
+ * HW has a known issue with chirping pulses injected at or
+ * around DC in 40MHz mode. Such pulses are reported with
+ * much lower durations and SW then discards them because
+ * they do not fit the minimum bin5 pulse duration.
+ *
+ * To work around this issue, if a pulse is within a 10us
+ * range of the bin5 min duration, check if the pulse is
+ * chirping. If the pulse is chirping, bump up the duration
+ * to the minimum bin5 duration.
+ *
+ * This makes sure that a valid chirping pulse will not be
+ * discarded because of incorrect low duration.
+ *
+ * TBD - Is it possible to calculate the 'real' duration of
+ * the pulse using the slope of the FFT data?
+ *
+ * TBD - Use FFT data to differentiate between radar pulses
+ * and false PHY errors.
+ * This will let us reduce the number of false alarms seen.
+ *
+ * BIN 5 chirping pulses are only for FCC or Japan MMK4 domain
+ */
+ if (((dfs->dfsdomain == DFS_FCC_DOMAIN) ||
+ (dfs->dfsdomain == DFS_MKK4_DOMAIN)) &&
+ (e.dur >= MAYBE_BIN5_DUR) && (e.dur < MAX_BIN5_DUR)) {
+ int add_dur;
+ int slope = 0, dc_found = 0;
+
+ /*
+ * Set the event chirping flags; as we're doing
+ * an actual chirp check.
+ */
+ e.do_check_chirp = 1;
+ e.is_hw_chirp = 0;
+ e.is_sw_chirp = 0;
+
+ /*
+ * dfs_check_chirping() expects is_pri and is_ext
+ * to be '1' for true and '0' for false for now,
+ * as the function itself uses these values in
+ * constructing things rather than testing them
+ * for 'true' or 'false'.
+ */
+ add_dur = dfs_check_chirping(dfs, buf, datalen,
+ (e.is_pri ? 1 : 0),
+ (e.is_ext ? 1 : 0),
+ &slope, &dc_found);
+ if (add_dur) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ "old dur %d slope =%d\n", e.dur, slope);
+ e.is_sw_chirp = 1;
+ // bump up to a random bin5 pulse duration
+ if (e.dur < MIN_BIN5_DUR) {
+ e.dur = dfs_get_random_bin5_dur(dfs,
+ e.fulltsf);
+ }
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ "new dur %d\n", e.dur);
+ } else {
+ /* set the duration so that it is rejected */
+ e.is_sw_chirp = 0;
+ e.dur = MAX_BIN5_DUR + 100;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ "is_chirping = %d dur=%d \n",
+ add_dur, e.dur);
+ }
+ } else {
+ /*
+ * We have a pulse that is either bigger than
+ * MAX_BIN5_DUR or * less than MAYBE_BIN5_DUR
+ */
+ if ((dfs->dfsdomain == DFS_FCC_DOMAIN) ||
+ (dfs->dfsdomain == DFS_MKK4_DOMAIN)) {
+ /*
+ * XXX Would this result in very large pulses
+ * wrapping around to become short pulses?
+ */
+ if (e.dur >= MAX_BIN5_DUR) {
+ /*
+ * set the duration so that it is
+ * rejected
+ */
+ e.dur = MAX_BIN5_DUR + 50;
+ }
+ }
+ }
+ }
+
+ /*
+ * Add the parsed, checked and filtered entry to the radar pulse
+ * event list. This is then checked by dfs_radar_processevent().
+ *
+ * XXX TODO: some filtering is still done below this point - fix
+ * XXX this!
+ */
+ ATH_DFSEVENTQ_LOCK(dfs);
+ empty = STAILQ_EMPTY(&(dfs->dfs_eventq));
+ ATH_DFSEVENTQ_UNLOCK(dfs);
+ if (empty) {
+ return;
+ }
+
+ /*
+ * If the channel is a turbo G channel, then the event is
+ * for the adaptive radio (AR) pattern matching rather than
+ * radar detection.
+ */
+ if ((chan->ic_flags & CHANNEL_108G) == CHANNEL_108G) {
+ if (!(dfs->dfs_proc_phyerr & DFS_AR_EN)) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "%s: DFS_AR_EN not enabled\n",
+ __func__);
+ return;
+ }
+ ATH_DFSEVENTQ_LOCK(dfs);
+ event = STAILQ_FIRST(&(dfs->dfs_eventq));
+ if (event == NULL) {
+ ATH_DFSEVENTQ_UNLOCK(dfs);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
+ "%s: no more events space left\n",
+ __func__);
+ return;
+ }
+ STAILQ_REMOVE_HEAD(&(dfs->dfs_eventq), re_list);
+ ATH_DFSEVENTQ_UNLOCK(dfs);
+ event->re_rssi = e.rssi;
+ event->re_dur = e.dur;
+ event->re_full_ts = e.fulltsf;
+ event->re_ts = (e.rs_tstamp) & DFS_TSMASK;
+ event->re_chanindex = dfs->dfs_curchan_radindex;
+ event->re_flags = 0;
+
+ /*
+ * Handle chirp flags.
+ */
+ if (e.do_check_chirp) {
+ event->re_flags |= DFS_EVENT_CHECKCHIRP;
+ if (e.is_hw_chirp)
+ event->re_flags |= DFS_EVENT_HW_CHIRP;
+ if (e.is_sw_chirp)
+ event->re_flags |= DFS_EVENT_SW_CHIRP;
+ }
+
+ ATH_ARQ_LOCK(dfs);
+ STAILQ_INSERT_TAIL(&(dfs->dfs_arq), event, re_list);
+ ATH_ARQ_UNLOCK(dfs);
+ } else {
+ if (IEEE80211_IS_CHAN_DFS(chan)) {
+ if (!(dfs->dfs_proc_phyerr & DFS_RADAR_EN)) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS3,
+ "%s: DFS_RADAR_EN not enabled\n",
+ __func__);
+ return;
+ }
+ /*
+ * rssi is not accurate for short pulses, so do
+ * not filter based on that for short duration pulses
+ *
+ * XXX do this filtering above?
+ */
+ if (dfs->dfs_caps.ath_dfs_ext_chan_ok) {
+ if ((e.rssi < dfs->dfs_rinfo.rn_minrssithresh &&
+ (e.dur > 4)) ||
+ e.dur > (dfs->dfs_rinfo.rn_maxpulsedur) ) {
+ dfs->ath_dfs_stats.rssi_discards++;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
+ "Extension channel pulse is "
+ "discarded: dur=%d, "
+ "maxpulsedur=%d, rssi=%d, "
+ "minrssi=%d\n",
+ e.dur,
+ dfs->dfs_rinfo.rn_maxpulsedur,
+ e.rssi,
+ dfs->dfs_rinfo.rn_minrssithresh);
+ return;
+ }
+ } else {
+ if (e.rssi < dfs->dfs_rinfo.rn_minrssithresh ||
+ e.dur > dfs->dfs_rinfo.rn_maxpulsedur) {
+ /* XXX TODO add a debug statement? */
+ dfs->ath_dfs_stats.rssi_discards++;
+ return;
+ }
+ }
+
+ /*
+ * 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);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
+ "%s: no more events space left\n",
+ __func__);
+ return;
+ }
+ 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 = e.dur;
+ event->re_full_ts = e.fulltsf;
+ event->re_ts = (e.rs_tstamp) & DFS_TSMASK;
+ event->re_rssi = e.rssi;
+
+ /*
+ * Handle chirp flags.
+ */
+ if (e.do_check_chirp) {
+ event->re_flags |= DFS_EVENT_CHECKCHIRP;
+ if (e.is_hw_chirp)
+ event->re_flags |= DFS_EVENT_HW_CHIRP;
+ if (e.is_sw_chirp)
+ event->re_flags |= DFS_EVENT_SW_CHIRP;
+ }
+
+ /*
+ * Correctly set which channel is being reported on
+ */
+ if (e.is_pri) {
+ event->re_chanindex = dfs->dfs_curchan_radindex;
+ } else {
+ if (dfs->dfs_extchan_radindex == -1) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ "%s - phyerr on ext channel\n", __func__);
+ }
+ event->re_chanindex = dfs->dfs_extchan_radindex;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_PHYERR,
+ "%s New extension channel event is added "
+ "to queue\n",__func__);
+ }
+ ATH_DFSQ_LOCK(dfs);
+ STAILQ_INSERT_TAIL(&(dfs->dfs_radarq), event, re_list);
+ ATH_DFSQ_UNLOCK(dfs);
+ }
+ }
+
+ /*
+ * Schedule the radar/AR task as appropriate.
+ *
+ * XXX isn't a lock needed for ath_radar_tasksched?
+ */
+
+/*
+* Commenting out the dfs_process_ar_event() since the function is never
+* called at run time as dfs_arq will be empty and the function
+* dfs_process_ar_event is obsolete and function definition is removed
+* as part of dfs_ar.c file
+*
+* if (!STAILQ_EMPTY(&dfs->dfs_arq))
+* // XXX shouldn't this be a task/timer too?
+* dfs_process_ar_event(dfs, ic->ic_curchan);
+*/
+
+ if (!STAILQ_EMPTY(&dfs->dfs_radarq) && !dfs->ath_radar_tasksched) {
+ dfs->ath_radar_tasksched = 1;
+ OS_SET_TIMER(&dfs->ath_dfs_task_timer, 0);
+ }
+#undef EXT_CH_RADAR_FOUND
+#undef PRI_CH_RADAR_FOUND
+#undef EXT_CH_RADAR_EARLY_FOUND
+}
+#endif /* ATH_SUPPORT_DFS */
diff --git a/CORE/SERVICES/DFS/src/dfs_process_radarevent.c b/CORE/SERVICES/DFS/src/dfs_process_radarevent.c
new file mode 100644
index 000000000000..adb9ad37bcdf
--- /dev/null
+++ b/CORE/SERVICES/DFS/src/dfs_process_radarevent.c
@@ -0,0 +1,583 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ dfs_radarevent.c
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+
+#include "dfs.h"
+/* TO DO DFS
+#include <ieee80211_var.h>
+*/
+#ifdef ATH_SUPPORT_DFS
+
+#define FREQ_5500_MHZ 5500
+#define FREQ_5500_MHZ 5500
+
+#define DFS_MAX_FREQ_SPREAD 1375 * 1
+#define DFS_LARGE_PRI_MULTIPLIER 4
+#define DFS_W53_DEFAULT_PRI_MULTIPLIER 2
+
+static char debug_dup[33];
+static int debug_dup_cnt;
+
+/*
+ * Convert the hardware provided duration to TSF ticks (usecs)
+ * taking the clock (fast or normal) into account.
+ *
+ * Legacy (pre-11n, Owl, Sowl, Howl) operate 5GHz using a 40MHz
+ * clock. Later 11n chips (Merlin, Osprey, etc) operate 5GHz using
+ * a 44MHz clock, so the reported pulse durations are different.
+ *
+ * Peregrine reports the pulse duration in microseconds regardless
+ * of the operating mode. (XXX TODO: verify this, obviously.)
+ */
+static inline u_int8_t
+dfs_process_pulse_dur(struct ath_dfs *dfs, u_int8_t re_dur)
+{
+ /*
+ * Short pulses are sometimes returned as having a duration of 0,
+ * so round those up to 1.
+ *
+ * XXX This holds true for BB TLV chips too, right?
+ */
+ if (re_dur == 0)
+ return 1;
+
+ /*
+ * For BB TLV chips, the hardware always returns microsecond
+ * pulse durations.
+ */
+ if (dfs->dfs_caps.ath_chip_is_bb_tlv)
+ return re_dur;
+
+ /*
+ * This is for 11n and legacy chips, which may or may not
+ * use the 5GHz fast clock mode.
+ */
+ /* Convert 0.8us durations to TSF ticks (usecs) */
+ return (u_int8_t)dfs_round((int32_t)((dfs->dur_multiplier)*re_dur));
+}
+
+/*
+ * Process a radar event.
+ *
+ * If a radar event is found, return 1. Otherwise, return 0.
+ *
+ * There is currently no way to specify that a radar event has occured on
+ * a specific channel, so the current methodology is to mark both the pri
+ * and ext channels as being unavailable. This should be fixed for 802.11ac
+ * or we'll quickly run out of valid channels to use.
+ */
+int
+dfs_process_radarevent(struct ath_dfs *dfs, struct ieee80211_channel *chan)
+{
+//commenting for now to validate radar indication msg to SAP
+//#if 0
+ struct dfs_event re,*event;
+ struct dfs_state *rs=NULL;
+ struct dfs_filtertype *ft;
+ struct dfs_filter *rf;
+ int found, retval = 0, p, empty;
+ int events_processed = 0;
+ u_int32_t tabledepth, index;
+ u_int64_t deltafull_ts = 0, this_ts, deltaT;
+ struct ieee80211_channel *thischan;
+ struct dfs_pulseline *pl;
+ static u_int32_t test_ts = 0;
+ static u_int32_t diff_ts = 0;
+ int ext_chan_event_flag = 0;
+#if 0
+ int pri_multiplier = 2;
+#endif
+ int i;
+
+ if (dfs == NULL) {
+ printk("%s[%d]: --------- dfs is NULL ------- \n",__func__,__LINE__);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: sc_sfs is NULL\n",
+ __func__);
+ return 0;
+ }
+ pl = dfs->pulses;
+ if ( !(IEEE80211_IS_CHAN_DFS(dfs->ic->ic_curchan))) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "%s: radar event on non-DFS chan\n",
+ __func__);
+ dfs_reset_radarq(dfs);
+ dfs_reset_alldelaylines(dfs);
+ return 0;
+ }
+#ifndef ATH_DFS_RADAR_DETECTION_ONLY
+ /* TEST : Simulate radar bang, make sure we add the channel to NOL (bug 29968) */
+ if (dfs->dfs_bangradar) {
+ /* bangradar will always simulate radar found on the primary channel */
+ rs = &dfs->dfs_radar[dfs->dfs_curchan_radindex];
+ dfs->dfs_bangradar = 0; /* reset */
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: bangradar\n", __func__);
+ retval = 1;
+ goto dfsfound;
+ }
+#endif
+
+ /*
+ The HW may miss some pulses especially with high channel loading.
+ This is true for Japan W53 where channel loaoding is 50%. Also
+ for ETSI where channel loading is 30% this can be an issue too.
+ To take care of missing pulses, we introduce pri_margin multiplie.
+ This is normally 2 but can be higher for W53.
+ */
+
+ if ((dfs->dfsdomain == DFS_MKK4_DOMAIN) &&
+ (dfs->dfs_caps.ath_chip_is_bb_tlv) &&
+ (chan->ic_freq < FREQ_5500_MHZ)) {
+
+ dfs->dfs_pri_multiplier = DFS_W53_DEFAULT_PRI_MULTIPLIER;
+ /* do not process W53 pulses unless we have a minimum number of them */
+ if (dfs->dfs_phyerr_w53_counter >= 5) {
+ /*
+ for chips that support frequency information, we can
+ relax PRI restriction if the frequency
+ spread is narrow.
+ */
+ if ((dfs->dfs_phyerr_freq_max - dfs->dfs_phyerr_freq_min) < DFS_MAX_FREQ_SPREAD) {
+ dfs->dfs_pri_multiplier = DFS_LARGE_PRI_MULTIPLIER;
+ }
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s: w53_counter=%d, freq_max=%d, freq_min=%d, pri_multiplier=%d\n",
+ __func__,
+ dfs->dfs_phyerr_w53_counter,
+ dfs->dfs_phyerr_freq_max,
+ dfs->dfs_phyerr_freq_min,
+ dfs->dfs_pri_multiplier);
+ dfs->dfs_phyerr_freq_min = 0x7fffffff;
+ dfs->dfs_phyerr_freq_max = 0;
+ } else {
+ return 0;
+ }
+ }
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s: pri_multiplier=%d\n", __func__, dfs->dfs_pri_multiplier);
+
+ ATH_DFSQ_LOCK(dfs);
+ empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
+ ATH_DFSQ_UNLOCK(dfs);
+
+ while ((!empty) && (!retval) && (events_processed < MAX_EVENTS)) {
+ ATH_DFSQ_LOCK(dfs);
+ event = STAILQ_FIRST(&(dfs->dfs_radarq));
+ if (event != NULL)
+ STAILQ_REMOVE_HEAD(&(dfs->dfs_radarq), re_list);
+ ATH_DFSQ_UNLOCK(dfs);
+
+ if (event == NULL) {
+ empty = 1;
+ printk("%s[%d]: event is NULL \n",__func__,__LINE__);
+ break;
+ }
+ events_processed++;
+ re = *event;
+
+ OS_MEMZERO(event, sizeof(struct dfs_event));
+ ATH_DFSEVENTQ_LOCK(dfs);
+ STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), event, re_list);
+ ATH_DFSEVENTQ_UNLOCK(dfs);
+
+ found = 0;
+ if (re.re_chanindex < DFS_NUM_RADAR_STATES)
+ rs = &dfs->dfs_radar[re.re_chanindex];
+ else {
+ ATH_DFSQ_LOCK(dfs);
+ empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
+ ATH_DFSQ_UNLOCK(dfs);
+ continue;
+ }
+ if (rs->rs_chan.ic_flagext & CHANNEL_INTERFERENCE) {
+ ATH_DFSQ_LOCK(dfs);
+ empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
+ ATH_DFSQ_UNLOCK(dfs);
+ continue;
+ }
+
+ if (dfs->dfs_rinfo.rn_lastfull_ts == 0) {
+ /*
+ * Either not started, or 64-bit rollover exactly to zero
+ * Just prepend zeros to the 15-bit ts
+ */
+ dfs->dfs_rinfo.rn_ts_prefix = 0;
+ } else {
+ /* WAR 23031- patch duplicate ts on very short pulses */
+ /* This pacth has two problems in linux environment.
+ * 1)The time stamp created and hence PRI depends entirely on the latency.
+ * If the latency is high, it possibly can split two consecutive
+ * pulses in the same burst so far away (the same amount of latency)
+ * that make them look like they are from differenct bursts. It is
+ * observed to happen too often. It sure makes the detection fail.
+ * 2)Even if the latency is not that bad, it simply shifts the duplicate
+ * timestamps to a new duplicate timestamp based on how they are processed.
+ * This is not worse but not good either.
+ *
+ * Take this pulse as a good one and create a probable PRI later
+ */
+ if (re.re_dur == 0 && re.re_ts == dfs->dfs_rinfo.rn_last_unique_ts) {
+ debug_dup[debug_dup_cnt++] = '1';
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "\n %s deltaT is 0 \n", __func__);
+ } else {
+ dfs->dfs_rinfo.rn_last_unique_ts = re.re_ts;
+ debug_dup[debug_dup_cnt++] = '0';
+ }
+ if (debug_dup_cnt >= 32){
+ debug_dup_cnt = 0;
+ }
+
+
+ if (re.re_ts <= dfs->dfs_rinfo.rn_last_ts) {
+ dfs->dfs_rinfo.rn_ts_prefix +=
+ (((u_int64_t) 1) << DFS_TSSHIFT);
+ /* Now, see if it's been more than 1 wrap */
+ deltafull_ts = re.re_full_ts - dfs->dfs_rinfo.rn_lastfull_ts;
+ if (deltafull_ts >
+ ((u_int64_t)((DFS_TSMASK - dfs->dfs_rinfo.rn_last_ts) + 1 + re.re_ts)))
+ deltafull_ts -= (DFS_TSMASK - dfs->dfs_rinfo.rn_last_ts) + 1 + re.re_ts;
+ deltafull_ts = deltafull_ts >> DFS_TSSHIFT;
+ if (deltafull_ts > 1) {
+ dfs->dfs_rinfo.rn_ts_prefix +=
+ ((deltafull_ts - 1) << DFS_TSSHIFT);
+ }
+ } else {
+ deltafull_ts = re.re_full_ts - dfs->dfs_rinfo.rn_lastfull_ts;
+ if (deltafull_ts > (u_int64_t) DFS_TSMASK) {
+ deltafull_ts = deltafull_ts >> DFS_TSSHIFT;
+ dfs->dfs_rinfo.rn_ts_prefix +=
+ ((deltafull_ts - 1) << DFS_TSSHIFT);
+ }
+ }
+ }
+ /*
+ * At this stage rn_ts_prefix has either been blanked or
+ * calculated, so it's safe to use.
+ */
+ this_ts = dfs->dfs_rinfo.rn_ts_prefix | ((u_int64_t) re.re_ts);
+ dfs->dfs_rinfo.rn_lastfull_ts = re.re_full_ts;
+ dfs->dfs_rinfo.rn_last_ts = re.re_ts;
+
+ /*
+ * The hardware returns the duration in a variety of formats,
+ * so it's converted from the hardware format to TSF (usec)
+ * values here.
+ *
+ * XXX TODO: this should really be done when the PHY error
+ * is processed, rather than way out here..
+ */
+ re.re_dur = dfs_process_pulse_dur(dfs, re.re_dur);
+
+ /*
+ * Calculate the start of the radar pulse.
+ *
+ * The TSF is stamped by the MAC upon reception of the
+ * event, which is (typically?) at the end of the event.
+ * But the pattern matching code expects the event timestamps
+ * to be at the start of the event. So to fake it, we
+ * subtract the pulse duration from the given TSF.
+ *
+ * This is done after the 64-bit timestamp has been calculated
+ * so long pulses correctly under-wrap the counter. Ie, if
+ * this was done on the 32 (or 15!) bit TSF when the TSF
+ * value is closed to 0, it will underflow to 0xfffffXX, which
+ * would mess up the logical "OR" operation done above.
+ *
+ * This isn't valid for Peregrine as the hardware gives us
+ * the actual TSF offset of the radar event, not just the MAC
+ * TSF of the completed receive.
+ *
+ * XXX TODO: ensure that the TLV PHY error processing
+ * code will correctly calculate the TSF to be the start
+ * of the radar pulse.
+ *
+ * XXX TODO TODO: modify the TLV parsing code to subtract
+ * the duration from the TSF, based on the current fast clock
+ * value.
+ */
+ if ((! dfs->dfs_caps.ath_chip_is_bb_tlv) && re.re_dur != 1) {
+ this_ts -= re.re_dur;
+ }
+
+ /* Save the pulse parameters in the pulse buffer(pulse line) */
+ index = (pl->pl_lastelem + 1) & DFS_MAX_PULSE_BUFFER_MASK;
+ if (pl->pl_numelems == DFS_MAX_PULSE_BUFFER_SIZE)
+ pl->pl_firstelem = (pl->pl_firstelem+1) & DFS_MAX_PULSE_BUFFER_MASK;
+ else
+ pl->pl_numelems++;
+ pl->pl_lastelem = index;
+ pl->pl_elems[index].p_time = this_ts;
+ pl->pl_elems[index].p_dur = re.re_dur;
+ pl->pl_elems[index].p_rssi = re.re_rssi;
+ diff_ts = (u_int32_t)this_ts - test_ts;
+ test_ts = (u_int32_t)this_ts;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,"ts%u %u %u diff %u pl->pl_lastelem.p_time=%llu\n",(u_int32_t)this_ts, re.re_dur, re.re_rssi, diff_ts, (unsigned long long)pl->pl_elems[index].p_time);
+ if (dfs->dfs_event_log_on) {
+ i = dfs->dfs_event_log_count % DFS_EVENT_LOG_SIZE;
+ dfs->radar_log[i].ts = this_ts;
+ dfs->radar_log[i].diff_ts = diff_ts;
+ dfs->radar_log[i].rssi = re.re_rssi;
+ dfs->radar_log[i].dur = re.re_dur;
+ dfs->dfs_event_log_count++;
+ }
+ printk("%s[%d]:xxxxx ts =%u re.re_dur=%u re.re_rssi =%u diff =%u pl->pl_lastelem.p_time=%llu xxxxx\n",__func__,__LINE__,(u_int32_t)this_ts, re.re_dur, re.re_rssi, diff_ts, (unsigned long long)pl->pl_elems[index].p_time);
+
+
+
+ /* If diff_ts is very small, we might be getting false pulse detects
+ * due to heavy interference. We might be getting spectral splatter
+ * from adjacent channel. In order to prevent false alarms we
+ * clear the delay-lines. This might impact positive detections under
+ * harsh environments, but helps with false detects. */
+
+ if (diff_ts < 100) {
+ dfs_reset_alldelaylines(dfs);
+ dfs_reset_radarq(dfs);
+ }
+ found = 0;
+
+ /* BIN5 pulses are FCC and Japan specific */
+
+ if ((dfs->dfsdomain == DFS_FCC_DOMAIN) || (dfs->dfsdomain == DFS_MKK4_DOMAIN)) {
+ for (p=0; (p < dfs->dfs_rinfo.rn_numbin5radars) && (!found); p++) {
+ struct dfs_bin5radars *br;
+
+ br = &(dfs->dfs_b5radars[p]);
+ if (dfs_bin5_check_pulse(dfs, &re, br)) {
+ // This is a valid Bin5 pulse, check if it belongs to a burst
+ re.re_dur = dfs_retain_bin5_burst_pattern(dfs, diff_ts, re.re_dur);
+ // Remember our computed duration for the next pulse in the burst (if needed)
+ dfs->dfs_rinfo.dfs_bin5_chirp_ts = this_ts;
+ dfs->dfs_rinfo.dfs_last_bin5_dur = re.re_dur;
+
+ if( dfs_bin5_addpulse(dfs, br, &re, this_ts) ) {
+ found |= dfs_bin5_check(dfs);
+ }
+ } else{
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS_BIN5_PULSE,
+ "%s not a BIN5 pulse (dur=%d)\n",
+ __func__, re.re_dur);
+ }
+ }
+ }
+
+ if (found) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: Found bin5 radar\n", __func__);
+ retval |= found;
+ goto dfsfound;
+ }
+
+ tabledepth = 0;
+ rf = NULL;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1," *** chan freq (%d): ts %llu dur %u rssi %u\n",
+ rs->rs_chan.ic_freq, (unsigned long long)this_ts, re.re_dur, re.re_rssi);
+
+ while ((tabledepth < DFS_MAX_RADAR_OVERLAP) &&
+ ((dfs->dfs_radartable[re.re_dur])[tabledepth] != -1) &&
+ (!retval)) {
+ ft = dfs->dfs_radarf[((dfs->dfs_radartable[re.re_dur])[tabledepth])];
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2," ** RD (%d): ts %x dur %u rssi %u\n",
+ rs->rs_chan.ic_freq,
+ re.re_ts, re.re_dur, re.re_rssi);
+
+ if (re.re_rssi < ft->ft_rssithresh && re.re_dur > 4) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,"%s : Rejecting on rssi rssi=%u thresh=%u\n", __func__, re.re_rssi, ft->ft_rssithresh);
+ printk("%s[%d]: Rejecting on rssi rssi=%u thresh=%u\n",__func__,__LINE__,re.re_rssi, ft->ft_rssithresh);
+ tabledepth++;
+ ATH_DFSQ_LOCK(dfs);
+ empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
+ ATH_DFSQ_UNLOCK(dfs);
+ continue;
+ }
+ deltaT = this_ts - ft->ft_last_ts;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,"deltaT = %lld (ts: 0x%llx) (last ts: 0x%llx)\n",(unsigned long long)deltaT, (unsigned long long)this_ts, (unsigned long long)ft->ft_last_ts);
+ if ((deltaT < ft->ft_minpri) && (deltaT !=0)){
+ /* This check is for the whole filter type. Individual filters
+ will check this again. This is first line of filtering.*/
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "%s: Rejecting on pri pri=%lld minpri=%u\n", __func__, (unsigned long long)deltaT, ft->ft_minpri);
+ printk("%s[%d]:Rejecting on pri pri=%lld minpri=%u\n",__func__,__LINE__,(unsigned long long)deltaT,ft->ft_minpri);
+ tabledepth++;
+ continue;
+ }
+ for (p=0, found = 0; (p<ft->ft_numfilters) && (!found); p++) {
+ rf = &(ft->ft_filters[p]);
+ if ((re.re_dur >= rf->rf_mindur) && (re.re_dur <= rf->rf_maxdur)) {
+ /* The above check is probably not necessary */
+ deltaT = (this_ts < rf->rf_dl.dl_last_ts) ?
+ (int64_t) ((DFS_TSF_WRAP - rf->rf_dl.dl_last_ts) + this_ts + 1) :
+ this_ts - rf->rf_dl.dl_last_ts;
+
+ if ((deltaT < rf->rf_minpri) && (deltaT != 0)) {
+ /* Second line of PRI filtering. */
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "filterID %d : Rejecting on individual filter min PRI deltaT=%lld rf->rf_minpri=%u\n",
+ rf->rf_pulseid, (unsigned long long)deltaT, rf->rf_minpri);
+ printk("%s[%d]:filterID= %d::Rejecting on individual filter min PRI deltaT=%lld rf->rf_minpri=%u\n",__func__,__LINE__,rf->rf_pulseid, (unsigned long long)deltaT, rf->rf_minpri);
+ continue;
+ }
+
+ if (rf->rf_ignore_pri_window > 0) {
+ if (deltaT < rf->rf_minpri) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "filterID %d : Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u\n",
+ rf->rf_pulseid, (unsigned long long)deltaT, rf->rf_minpri);
+ printk("%s[%d]:filterID= %d :: Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u\n",__func__,__LINE__,rf->rf_pulseid, (unsigned long long)deltaT, rf->rf_minpri);
+ /* But update the last time stamp */
+ rf->rf_dl.dl_last_ts = this_ts;
+ continue;
+ }
+ } else {
+
+ /*
+ The HW may miss some pulses especially with high channel loading.
+ This is true for Japan W53 where channel loaoding is 50%. Also
+ for ETSI where channel loading is 30% this can be an issue too.
+ To take care of missing pulses, we introduce pri_margin multiplie.
+ This is normally 2 but can be higher for W53.
+ */
+
+ if ( (deltaT > (dfs->dfs_pri_multiplier * rf->rf_maxpri) ) || (deltaT < rf->rf_minpri) ) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "filterID %d : Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u\n",
+ rf->rf_pulseid, (unsigned long long)deltaT, rf->rf_minpri);
+printk("%s[%d]:filterID= %d :: Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u\n",__func__,__LINE__,rf->rf_pulseid, (unsigned long long)deltaT, rf->rf_minpri);
+ /* But update the last time stamp */
+ rf->rf_dl.dl_last_ts = this_ts;
+ continue;
+ }
+ }
+ dfs_add_pulse(dfs, rf, &re, deltaT, this_ts);
+
+
+ /* If this is an extension channel event, flag it for false alarm reduction */
+ if (re.re_chanindex == dfs->dfs_extchan_radindex) {
+ ext_chan_event_flag = 1;
+ }
+ if (rf->rf_patterntype == 2) {
+ found = dfs_staggered_check(dfs, rf, (u_int32_t) deltaT, re.re_dur);
+ } else {
+ found = dfs_bin_check(dfs, rf, (u_int32_t) deltaT, re.re_dur, ext_chan_event_flag);
+ }
+ if (dfs->dfs_debug_mask & ATH_DEBUG_DFS2) {
+ dfs_print_delayline(dfs, &rf->rf_dl);
+ }
+ rf->rf_dl.dl_last_ts = this_ts;
+ }
+ }
+ ft->ft_last_ts = this_ts;
+ retval |= found;
+ if (found) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS3,
+ "Found on channel minDur = %d, filterId = %d\n",ft->ft_mindur,
+ rf != NULL ? rf->rf_pulseid : -1);
+ }
+ tabledepth++;
+ }
+ ATH_DFSQ_LOCK(dfs);
+ empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
+ ATH_DFSQ_UNLOCK(dfs);
+ }
+dfsfound:
+ if (retval) {
+ /* Collect stats */
+ dfs->ath_dfs_stats.num_radar_detects++;
+ thischan = &rs->rs_chan;
+ printk("%s[%d]: ########################## Radar found on channel %d (%d MHz) ########################## \n",__func__,__LINE__,thischan->ic_ieee,
+thischan->ic_freq);
+ DFS_PRINTK("Radar found on channel %d (%d MHz)\n",
+ thischan->ic_ieee,
+ thischan->ic_freq);
+
+#if 0 //UMACDFS : TODO
+ /* Disable radar for now */
+ rfilt = ath_hal_getrxfilter(ah);
+ rfilt &= ~HAL_RX_FILTER_PHYRADAR;
+ ath_hal_setrxfilter(ah, rfilt);
+#endif
+ dfs_reset_radarq(dfs);
+ dfs_reset_alldelaylines(dfs);
+ /* XXX Should we really enable again? Maybe not... */
+/* No reason to re-enable so far - Ajay*/
+#if 0
+ pe.pe_firpwr = rs->rs_firpwr;
+ pe.pe_rrssi = rs->rs_radarrssi;
+ pe.pe_height = rs->rs_height;
+ pe.pe_prssi = rs->rs_pulserssi;
+ pe.pe_inband = rs->rs_inband;
+ /* 5413 specific */
+ pe.pe_relpwr = rs->rs_relpwr;
+ pe.pe_relstep = rs->rs_relstep;
+ pe.pe_maxlen = rs->rs_maxlen;
+
+ ath_hal_enabledfs(ah, &pe);
+ rfilt |= HAL_RX_FILTER_PHYRADAR;
+ ath_hal_setrxfilter(ah, rfilt);
+#endif
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
+ "Primary channel freq = %u flags=0x%x\n",
+ chan->ic_freq, chan->ic_flagext);
+ if ((dfs->ic->ic_curchan->ic_freq!= thischan->ic_freq)) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
+ "Ext channel freq = %u flags=0x%x\n",
+ thischan->ic_freq, thischan->ic_flagext);
+ }
+ dfs->dfs_phyerr_freq_min = 0x7fffffff;
+ dfs->dfs_phyerr_freq_max = 0;
+ dfs->dfs_phyerr_w53_counter = 0;
+ }
+ //printk("IN FUNC %s[%d]: retval = %d \n",__func__,__LINE__,retval);
+ return retval;
+//#endif
+// return 1;
+}
+
+#endif /* ATH_SUPPORT_DFS */
diff --git a/CORE/SERVICES/DFS/src/dfs_staggered.c b/CORE/SERVICES/DFS/src/dfs_staggered.c
new file mode 100644
index 000000000000..f5f9f49a45ae
--- /dev/null
+++ b/CORE/SERVICES/DFS/src/dfs_staggered.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ dfs_staggered.c
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+
+#include "dfs.h"
+/* TO DO DFS
+#include <ieee80211_var.h>
+*/
+#ifdef ATH_SUPPORT_DFS
+
+static int is_pri_multiple(u_int32_t sample_pri, u_int32_t refpri)
+{
+#define MAX_ALLOWED_MISSED 3
+ int i;
+
+ if (sample_pri < refpri || (!refpri))
+ return 0;
+
+ for (i=1; i<= MAX_ALLOWED_MISSED; i++) {
+ if((sample_pri%(i*refpri) <= 5)) {
+ //printk("sample_pri=%d is a multiple of refpri=%d\n", sample_pri, refpri);
+ return 1;
+ }
+ }
+ return 0;
+#undef MAX_ALLOWED_MISSED
+}
+
+static int is_unique_pri(u_int32_t highestpri , u_int32_t midpri,
+ u_int32_t lowestpri , u_int32_t refpri )
+{
+#define DFS_STAGGERED_PRI_MARGIN_MIN 20
+#define DFS_STAGGERED_PRI_MARGIN_MAX 400
+ if ((DFS_DIFF(lowestpri, refpri) >= DFS_STAGGERED_PRI_MARGIN_MIN) &&
+ (DFS_DIFF(midpri, refpri) >= DFS_STAGGERED_PRI_MARGIN_MIN) &&
+ (DFS_DIFF(highestpri, refpri) >= DFS_STAGGERED_PRI_MARGIN_MIN)) {
+ return 1;
+ } else {
+ if ((is_pri_multiple(refpri, highestpri)) || (is_pri_multiple(refpri, lowestpri)) ||
+ (is_pri_multiple(refpri, midpri)))
+ return 0;
+ }
+ return 0;
+#undef DFS_STAGGERED_PRI_MARGIN_MIN
+#undef DFS_STAGGERED_PRI_MARGIN_MAX
+}
+
+
+int dfs_staggered_check(struct ath_dfs *dfs, struct dfs_filter *rf,
+ u_int32_t deltaT, u_int32_t width)
+{
+ u_int32_t refpri, refdur, searchpri=0, deltapri;//, averagerefpri;
+ u_int32_t n, i, primargin, durmargin;
+ int score[DFS_MAX_DL_SIZE], delayindex, dindex, found=0;
+ struct dfs_delayline *dl;
+ u_int32_t scoreindex, lowpriindex= 0, lowpri = 0xffff;
+#if 0
+ int numpulses=0;
+#endif
+ int higherthan, lowerthan, numscores;
+ int numpulseshigh=0, numpulsesmid=0, numpulsestemp=0;
+ u_int32_t lowestscore=0, lowestscoreindex=0, lowestpri=0;
+ u_int32_t midscore=0, midscoreindex=0, midpri=0;
+ u_int32_t highestscore=0, highestscoreindex=0, highestpri=0;
+
+ dl = &rf->rf_dl;
+ if( dl->dl_numelems < (rf->rf_threshold-1)) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "numelems %d < threshold for filter %d\n",
+ dl->dl_numelems, rf->rf_pulseid);
+ return 0;
+ }
+ if( deltaT > rf->rf_filterlen) {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "numelems %d < threshold for filter %d\n",
+ dl->dl_numelems, rf->rf_pulseid);
+ return 0;
+ }
+ primargin = 6;
+ if(rf->rf_maxdur < 10) {
+ durmargin = 4;
+ }
+ else {
+ durmargin = 6;
+ }
+
+ OS_MEMZERO(score, sizeof(int)*DFS_MAX_DL_SIZE);
+ /* find out the lowest pri */
+ for (n=0;n<dl->dl_numelems; n++) {
+ delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
+ refpri = dl->dl_elems[delayindex].de_time;
+ if( refpri == 0)
+ continue;
+ else if(refpri < lowpri) {
+ lowpri = dl->dl_elems[delayindex].de_time;
+ lowpriindex = n;
+ }
+ }
+ /* find out the each delay element's pri score */
+ for (n=0;n<dl->dl_numelems; n++) {
+ delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
+ refpri = dl->dl_elems[delayindex].de_time;
+ if( refpri == 0) {
+ continue;
+ }
+
+ if ( (refpri > rf->rf_maxpri) || (refpri < rf->rf_minpri) ) {
+ score[n] = 0;
+ continue;
+ }
+
+ for (i=0;i<dl->dl_numelems; i++) {
+ dindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK;
+ searchpri = dl->dl_elems[dindex].de_time;
+ deltapri = DFS_DIFF(searchpri, refpri);
+ if( deltapri < primargin)
+ score[n]++;
+ }
+ }
+ for (n=0;n<dl->dl_numelems; n++) {
+ delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
+ refdur = dl->dl_elems[delayindex].de_time;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "score[%d]=%d pri=%d\n", n, score[n], refdur);
+ }
+
+ /* find out the 2 or 3 highest scorers */
+ scoreindex = 0;
+ highestscore=0;
+ highestscoreindex=0;
+ highestpri=0; numscores=0; lowestscore=0;
+
+ for (n=0;n<dl->dl_numelems; n++) {
+ higherthan=0;
+ lowerthan=0;
+ delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
+ refpri = dl->dl_elems[delayindex].de_time;
+
+ if ((score[n] >= highestscore) &&
+ (is_unique_pri(highestpri, midpri, lowestpri, refpri))) {
+ lowestscore = midscore;
+ lowestpri = midpri;
+ lowestscoreindex = midscoreindex;
+ midscore = highestscore;
+ midpri = highestpri;
+ midscoreindex = highestscoreindex;
+ highestscore = score[n];
+ highestpri = refpri;
+ highestscoreindex = n;
+ } else {
+ if ((score[n] >= midscore) &&
+ (is_unique_pri(highestpri, midpri, lowestpri, refpri))) {
+ lowestscore = midscore;
+ lowestpri = midpri;
+ lowestscoreindex = midscoreindex;
+ midscore = score[n];
+ midpri = refpri;
+ midscoreindex = n;
+ } else if ((score[n] >= lowestscore) &&
+ (is_unique_pri(highestpri, midpri, lowestpri, refpri))) {
+ lowestscore = score[n];
+ lowestpri = refpri;
+ lowestscoreindex = n;
+ }
+ }
+
+ }
+
+ if (midscore == 0) {
+ // This means we have only 1 pulse type. It can not be staggered!
+ return 0;
+ }
+
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
+ "FINAL highestscore=%d highestscoreindex=%d highestpri=%d\n",
+ highestscore, highestscoreindex, highestpri);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
+ "FINAL lowestscore=%d lowestscoreindex=%d lowpri=%d\n",
+ lowestscore, lowestscoreindex, lowestpri);
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
+ "FINAL midscore=%d midscoreindex=%d midpri=%d\n",
+ midscore, midscoreindex, midpri);
+
+
+ delayindex = (dl->dl_firstelem + highestscoreindex) & DFS_MAX_DL_MASK;
+ refdur = dl->dl_elems[delayindex].de_dur;
+ refpri = dl->dl_elems[delayindex].de_time;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
+ "highscoreindex=%d refdur=%d refpri=%d\n",
+ highestscoreindex, refdur, refpri);
+
+ numpulsestemp = dfs_bin_pri_check(dfs, rf, dl, highestscore, refpri, refdur,0, highestpri);
+ numpulseshigh = numpulsestemp;
+ numpulsestemp = dfs_bin_pri_check(dfs, rf, dl, highestscore, refpri, refdur,0, highestpri + midpri);
+ if (numpulsestemp > numpulseshigh) {
+ numpulseshigh = numpulsestemp;
+ }
+ numpulsestemp = dfs_bin_pri_check(dfs, rf, dl, highestscore, refpri, refdur,0, highestpri + midpri + lowestpri);
+ if (numpulsestemp > numpulseshigh) {
+ numpulseshigh = numpulsestemp;
+ }
+
+
+ delayindex = (dl->dl_firstelem + midscoreindex) & DFS_MAX_DL_MASK;
+ refdur = dl->dl_elems[delayindex].de_dur;
+ refpri = dl->dl_elems[delayindex].de_time;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
+ "midscoreindex=%d refdur=%d refpri=%d\n",
+ midscoreindex, refdur, refpri);
+
+ //numpulsesmid = dfs_bin_pri_check(dfs, rf, dl, midscore, refpri, refdur,0, 1);
+ numpulsestemp = dfs_bin_pri_check(dfs, rf, dl, midscore, refpri, refdur,0, midpri);
+ numpulsesmid = numpulsestemp;
+ numpulsestemp = dfs_bin_pri_check(dfs, rf, dl, midscore, refpri, refdur,0, highestpri + midpri);
+ if (numpulsestemp > numpulsesmid) {
+ numpulsesmid = numpulsestemp;
+ }
+ numpulsestemp = dfs_bin_pri_check(dfs, rf, dl, midscore, refpri, refdur,0, highestpri + midpri + lowestpri);
+ if (numpulsestemp > numpulsesmid) {
+ numpulsesmid = numpulsestemp;
+ }
+
+
+ /*delayindex = (dl->dl_firstelem + lowestscoreindex) & DFS_MAX_DL_MASK;
+ refdur = dl->dl_elems[delayindex].de_dur;
+ refpri = dl->dl_elems[delayindex].de_time;
+ DFS_DPRINTK(ic, ATH_DEBUG_DFS1, "lowestscoreindex=%d refdur=%d refpri=%d\n", lowestscoreindex, refdur, refpri);
+
+ numpulseslow = dfs_bin_pri_check(dfs, rf, dl, lowestscore, refpri, refdur,0, 1);
+ */
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
+ "numpulseshigh=%d, numpulsesmid=%d\n",
+ numpulseshigh, numpulsesmid);
+// printf("numpulseshigh=%d, numpulsesmid=%d, numpulseslow %d\n",numpulseshigh, numpulsesmid, numpulseslow);
+
+ if ( (numpulseshigh >= rf->rf_threshold) && (numpulsesmid >= rf->rf_threshold) ) {
+ /*if (numpulses >= rf->rf_threshold) {*/
+ found = 1;
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "MATCH filter=%u numpulseshigh=%u numpulsesmid= %u thresh=%u\n", rf->rf_pulseid, numpulseshigh, numpulsesmid, rf->rf_threshold);
+ }
+ return found;
+ }
+
+#endif /* ATH_SUPPORT_DFS */
diff --git a/CORE/SERVICES/HIF/PCIe/ar6320def.h b/CORE/SERVICES/HIF/PCIe/ar6320def.h
index a4b1f4dcf46f..d9de7b513298 100644
--- a/CORE/SERVICES/HIF/PCIe/ar6320def.h
+++ b/CORE/SERVICES/HIF/PCIe/ar6320def.h
@@ -26,7 +26,7 @@
*/
#ifndef _AR6320DEF_H_
-#define AR6320__AR6320DEF_H_
+#define _AR6320DEF_H_
/* Base Addresses */
#define AR6320_RTC_SOC_BASE_ADDRESS 0x00000000
diff --git a/CORE/SERVICES/HIF/PCIe/ar6320v2def.h b/CORE/SERVICES/HIF/PCIe/ar6320v2def.h
new file mode 100644
index 000000000000..b889eeb6f3dd
--- /dev/null
+++ b/CORE/SERVICES/HIF/PCIe/ar6320v2def.h
@@ -0,0 +1,519 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#ifndef _AR6320V2DEF_H_
+#define _AR6320V2DEF_H_
+
+/* Base Addresses */
+#define AR6320V2_RTC_SOC_BASE_ADDRESS 0x00000800
+#define AR6320V2_RTC_WMAC_BASE_ADDRESS 0x00001000
+#define AR6320V2_MAC_COEX_BASE_ADDRESS 0x0000f000
+#define AR6320V2_BT_COEX_BASE_ADDRESS 0x00002000
+#define AR6320V2_SOC_PCIE_BASE_ADDRESS 0x00038000
+#define AR6320V2_SOC_CORE_BASE_ADDRESS 0x0003a000
+#define AR6320V2_WLAN_UART_BASE_ADDRESS 0x0000c000
+#define AR6320V2_WLAN_SI_BASE_ADDRESS 0x00010000
+#define AR6320V2_WLAN_GPIO_BASE_ADDRESS 0x00005000
+#define AR6320V2_WLAN_ANALOG_INTF_BASE_ADDRESS 0x00006000
+#define AR6320V2_WLAN_MAC_BASE_ADDRESS 0x00010000
+#define AR6320V2_EFUSE_BASE_ADDRESS 0x00024000
+#define AR6320V2_FPGA_REG_BASE_ADDRESS 0x00039000
+#define AR6320V2_WLAN_UART2_BASE_ADDRESS 0x00054c00
+#define AR6320V2_CE_WRAPPER_BASE_ADDRESS 0x00034000
+#define AR6320V2_CE0_BASE_ADDRESS 0x00034400
+#define AR6320V2_CE1_BASE_ADDRESS 0x00034800
+#define AR6320V2_CE2_BASE_ADDRESS 0x00034c00
+#define AR6320V2_CE3_BASE_ADDRESS 0x00035000
+#define AR6320V2_CE4_BASE_ADDRESS 0x00035400
+#define AR6320V2_CE5_BASE_ADDRESS 0x00035800
+#define AR6320V2_CE6_BASE_ADDRESS 0x00035c00
+#define AR6320V2_CE7_BASE_ADDRESS 0x00036000
+#define AR6320V2_DBI_BASE_ADDRESS 0x0003c000
+#define AR6320V2_WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x00007800
+
+#define AR6320V2_SCRATCH_3_ADDRESS 0x0028
+#define AR6320V2_TARG_DRAM_START 0x00400000
+#define AR6320V2_SOC_SYSTEM_SLEEP_OFFSET 0x000000c0
+#define AR6320V2_SOC_RESET_CONTROL_OFFSET 0x00000000
+#define AR6320V2_SOC_CLOCK_CONTROL_OFFSET 0x00000028
+#define AR6320V2_SOC_CLOCK_CONTROL_SI0_CLK_MASK 0x00000001
+#define AR6320V2_SOC_RESET_CONTROL_SI0_RST_MASK 0x00000000
+#define AR6320V2_WLAN_GPIO_PIN0_ADDRESS 0x00000068
+#define AR6320V2_WLAN_GPIO_PIN1_ADDRESS 0x0000006c
+#define AR6320V2_WLAN_GPIO_PIN0_CONFIG_MASK 0x00007800
+#define AR6320V2_WLAN_GPIO_PIN1_CONFIG_MASK 0x00007800
+#define AR6320V2_SOC_CPU_CLOCK_OFFSET 0x00000020
+#define AR6320V2_SOC_LPO_CAL_OFFSET 0x000000e0
+#define AR6320V2_WLAN_GPIO_PIN10_ADDRESS 0x00000090
+#define AR6320V2_WLAN_GPIO_PIN11_ADDRESS 0x00000094
+#define AR6320V2_WLAN_GPIO_PIN12_ADDRESS 0x00000098
+#define AR6320V2_WLAN_GPIO_PIN13_ADDRESS 0x0000009c
+#define AR6320V2_SOC_CPU_CLOCK_STANDARD_LSB 0
+#define AR6320V2_SOC_CPU_CLOCK_STANDARD_MASK 0x00000003
+#define AR6320V2_SOC_LPO_CAL_ENABLE_LSB 20
+#define AR6320V2_SOC_LPO_CAL_ENABLE_MASK 0x00100000
+
+#define AR6320V2_WLAN_SYSTEM_SLEEP_DISABLE_LSB 0
+#define AR6320V2_WLAN_SYSTEM_SLEEP_DISABLE_MASK 0x00000001
+#define AR6320V2_WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000008
+#define AR6320V2_WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000004
+#define AR6320V2_SI_CONFIG_BIDIR_OD_DATA_LSB 18
+#define AR6320V2_SI_CONFIG_BIDIR_OD_DATA_MASK 0x00040000
+#define AR6320V2_SI_CONFIG_I2C_LSB 16
+#define AR6320V2_SI_CONFIG_I2C_MASK 0x00010000
+#define AR6320V2_SI_CONFIG_POS_SAMPLE_LSB 7
+#define AR6320V2_SI_CONFIG_POS_SAMPLE_MASK 0x00000080
+#define AR6320V2_SI_CONFIG_INACTIVE_CLK_LSB 4
+#define AR6320V2_SI_CONFIG_INACTIVE_CLK_MASK 0x00000010
+#define AR6320V2_SI_CONFIG_INACTIVE_DATA_LSB 5
+#define AR6320V2_SI_CONFIG_INACTIVE_DATA_MASK 0x00000020
+#define AR6320V2_SI_CONFIG_DIVIDER_LSB 0
+#define AR6320V2_SI_CONFIG_DIVIDER_MASK 0x0000000f
+#define AR6320V2_SI_CONFIG_OFFSET 0x00000000
+#define AR6320V2_SI_TX_DATA0_OFFSET 0x00000008
+#define AR6320V2_SI_TX_DATA1_OFFSET 0x0000000c
+#define AR6320V2_SI_RX_DATA0_OFFSET 0x00000010
+#define AR6320V2_SI_RX_DATA1_OFFSET 0x00000014
+#define AR6320V2_SI_CS_OFFSET 0x00000004
+#define AR6320V2_SI_CS_DONE_ERR_MASK 0x00000400
+#define AR6320V2_SI_CS_DONE_INT_MASK 0x00000200
+#define AR6320V2_SI_CS_START_LSB 8
+#define AR6320V2_SI_CS_START_MASK 0x00000100
+#define AR6320V2_SI_CS_RX_CNT_LSB 4
+#define AR6320V2_SI_CS_RX_CNT_MASK 0x000000f0
+#define AR6320V2_SI_CS_TX_CNT_LSB 0
+#define AR6320V2_SI_CS_TX_CNT_MASK 0x0000000f
+#define AR6320V2_CE_COUNT 8
+#define AR6320V2_SR_WR_INDEX_ADDRESS 0x003c
+#define AR6320V2_DST_WATERMARK_ADDRESS 0x0050
+#define AR6320V2_RX_MSDU_END_4_FIRST_MSDU_LSB 14
+#define AR6320V2_RX_MSDU_END_4_FIRST_MSDU_MASK 0x00004000
+#define AR6320V2_RX_MPDU_START_0_SEQ_NUM_LSB 16
+#define AR6320V2_RX_MPDU_START_0_SEQ_NUM_MASK 0x0fff0000
+#define AR6320V2_RX_MPDU_START_2_PN_47_32_LSB 0
+#define AR6320V2_RX_MPDU_START_2_PN_47_32_MASK 0x0000ffff
+#define AR6320V2_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB 16
+#define AR6320V2_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK 0xffff0000
+#define AR6320V2_RX_MSDU_END_4_LAST_MSDU_LSB 15
+#define AR6320V2_RX_MSDU_END_4_LAST_MSDU_MASK 0x00008000
+#define AR6320V2_RX_ATTENTION_0_MCAST_BCAST_LSB 2
+#define AR6320V2_RX_ATTENTION_0_MCAST_BCAST_MASK 0x00000004
+#define AR6320V2_RX_ATTENTION_0_FRAGMENT_LSB 13
+#define AR6320V2_RX_ATTENTION_0_FRAGMENT_MASK 0x00002000
+#define AR6320V2_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK 0x08000000
+#define AR6320V2_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB 16
+#define AR6320V2_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK 0x00ff0000
+#define AR6320V2_RX_MSDU_START_0_MSDU_LENGTH_LSB 0
+#define AR6320V2_RX_MSDU_START_0_MSDU_LENGTH_MASK 0x00003fff
+
+#define AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_OFFSET 0x00000008
+#define AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_LSB 8
+#define AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_MASK 0x00000300
+#define AR6320V2_RX_MPDU_START_0_ENCRYPTED_LSB 13
+#define AR6320V2_RX_MPDU_START_0_ENCRYPTED_MASK 0x00002000
+#define AR6320V2_RX_ATTENTION_0_MORE_DATA_MASK 0x00000400
+#define AR6320V2_RX_ATTENTION_0_MSDU_DONE_MASK 0x80000000
+#define AR6320V2_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK 0x00040000
+#define AR6320V2_DST_WR_INDEX_ADDRESS 0x0040
+#define AR6320V2_SRC_WATERMARK_ADDRESS 0x004c
+#define AR6320V2_SRC_WATERMARK_LOW_MASK 0xffff0000
+#define AR6320V2_SRC_WATERMARK_HIGH_MASK 0x0000ffff
+#define AR6320V2_DST_WATERMARK_LOW_MASK 0xffff0000
+#define AR6320V2_DST_WATERMARK_HIGH_MASK 0x0000ffff
+#define AR6320V2_CURRENT_SRRI_ADDRESS 0x0044
+#define AR6320V2_CURRENT_DRRI_ADDRESS 0x0048
+#define AR6320V2_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK 0x00000002
+#define AR6320V2_HOST_IS_SRC_RING_LOW_WATERMARK_MASK 0x00000004
+#define AR6320V2_HOST_IS_DST_RING_HIGH_WATERMARK_MASK 0x00000008
+#define AR6320V2_HOST_IS_DST_RING_LOW_WATERMARK_MASK 0x00000010
+#define AR6320V2_HOST_IS_ADDRESS 0x0030
+#define AR6320V2_HOST_IS_COPY_COMPLETE_MASK 0x00000001
+#define AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS 0x0000
+#define AR6320V2_HOST_IE_ADDRESS 0x002c
+#define AR6320V2_HOST_IE_COPY_COMPLETE_MASK 0x00000001
+#define AR6320V2_SR_BA_ADDRESS 0x0000
+#define AR6320V2_SR_SIZE_ADDRESS 0x0004
+#define AR6320V2_CE_CTRL1_ADDRESS 0x0010
+#define AR6320V2_CE_CTRL1_DMAX_LENGTH_MASK 0x0000ffff
+#define AR6320V2_DR_BA_ADDRESS 0x0008
+#define AR6320V2_DR_SIZE_ADDRESS 0x000c
+#define AR6320V2_MISC_IE_ADDRESS 0x0034
+#define AR6320V2_MISC_IS_AXI_ERR_MASK 0x00000400
+#define AR6320V2_MISC_IS_DST_ADDR_ERR_MASK 0x00000200
+#define AR6320V2_MISC_IS_SRC_LEN_ERR_MASK 0x00000100
+#define AR6320V2_MISC_IS_DST_MAX_LEN_VIO_MASK 0x00000080
+#define AR6320V2_MISC_IS_DST_RING_OVERFLOW_MASK 0x00000040
+#define AR6320V2_MISC_IS_SRC_RING_OVERFLOW_MASK 0x00000020
+#define AR6320V2_SRC_WATERMARK_LOW_LSB 16
+#define AR6320V2_SRC_WATERMARK_HIGH_LSB 0
+#define AR6320V2_DST_WATERMARK_LOW_LSB 16
+#define AR6320V2_DST_WATERMARK_HIGH_LSB 0
+#define AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK 0x0000ff00
+#define AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB 8
+#define AR6320V2_CE_CTRL1_DMAX_LENGTH_LSB 0
+#define AR6320V2_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK 0x00010000
+#define AR6320V2_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK 0x00020000
+#define AR6320V2_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB 16
+#define AR6320V2_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB 17
+#define AR6320V2_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK 0x00000020
+#define AR6320V2_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB 5
+#define AR6320V2_SOC_GLOBAL_RESET_ADDRESS 0x0008
+#define AR6320V2_RTC_STATE_ADDRESS 0x0000
+#define AR6320V2_RTC_STATE_COLD_RESET_MASK 0x00002000
+#define AR6320V2_PCIE_SOC_WAKE_RESET 0x00000000
+#define AR6320V2_PCIE_SOC_WAKE_ADDRESS 0x0004
+#define AR6320V2_PCIE_SOC_WAKE_V_MASK 0x00000001
+#define AR6320V2_RTC_STATE_V_MASK 0x00000007
+#define AR6320V2_RTC_STATE_V_LSB 0
+#define AR6320V2_RTC_STATE_V_ON 3
+#define AR6320V2_PCIE_LOCAL_BASE_ADDRESS 0x80000
+#define AR6320V2_FW_IND_EVENT_PENDING 1
+#define AR6320V2_FW_IND_INITIALIZED 2
+#define AR6320V2_PCIE_INTR_ENABLE_ADDRESS 0x0008
+#define AR6320V2_PCIE_INTR_CLR_ADDRESS 0x0014
+#define AR6320V2_PCIE_INTR_FIRMWARE_MASK 0x00000400
+#define AR6320V2_PCIE_INTR_CE0_MASK 0x00000800
+#define AR6320V2_PCIE_INTR_CE_MASK_ALL 0x0007f800 /* All CEs */
+#define AR6320V2_PCIE_INTR_CAUSE_ADDRESS 0x000c
+#define AR6320V2_CPU_INTR_ADDRESS 0x0010
+#define AR6320V2_SOC_LF_TIMER_CONTROL0_ADDRESS 0x00000050
+#define AR6320V2_SOC_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004
+#define AR6320V2_SOC_RESET_CONTROL_ADDRESS 0x00000000
+#define AR6320V2_SOC_RESET_CONTROL_CE_RST_MASK 0x00000001
+#define AR6320V2_SOC_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040
+#define AR6320V2_CORE_CTRL_ADDRESS 0x0000
+#define AR6320V2_CORE_CTRL_CPU_INTR_MASK 0x00002000
+#define AR6320V2_LOCAL_SCRATCH_OFFSET 0x000000c0
+#define AR6320V2_CLOCK_GPIO_OFFSET 0xffffffff
+#define AR6320V2_CLOCK_GPIO_BT_CLK_OUT_EN_LSB 0
+#define AR6320V2_CLOCK_GPIO_BT_CLK_OUT_EN_MASK 0
+#define AR6320V2_SOC_CHIP_ID_ADDRESS 0x000000f0
+#define AR6320V2_SOC_CHIP_ID_VERSION_MASK 0xfffc0000
+#define AR6320V2_SOC_CHIP_ID_VERSION_LSB 18
+#define AR6320V2_SOC_CHIP_ID_REVISION_MASK 0x00000f00
+#define AR6320V2_SOC_CHIP_ID_REVISION_LSB 8
+
+#define AR6320V2_PCIE_INTR_CE_MASK(n) (AR6320V2_PCIE_INTR_CE0_MASK << (n))
+#define AR6320V2_DRAM_BASE_ADDRESS AR6320V2_TARG_DRAM_START
+#define AR6320V2_FW_INDICATOR_ADDRESS (AR6320V2_SOC_CORE_BASE_ADDRESS + AR6320V2_SCRATCH_3_ADDRESS)
+#define AR6320V2_SYSTEM_SLEEP_OFFSET AR6320V2_SOC_SYSTEM_SLEEP_OFFSET
+#define AR6320V2_WLAN_SYSTEM_SLEEP_OFFSET 0x002c
+#define AR6320V2_WLAN_RESET_CONTROL_OFFSET AR6320V2_SOC_RESET_CONTROL_OFFSET
+#define AR6320V2_CLOCK_CONTROL_OFFSET AR6320V2_SOC_CLOCK_CONTROL_OFFSET
+#define AR6320V2_CLOCK_CONTROL_SI0_CLK_MASK AR6320V2_SOC_CLOCK_CONTROL_SI0_CLK_MASK
+#define AR6320V2_RESET_CONTROL_MBOX_RST_MASK 0x00000004
+#define AR6320V2_RESET_CONTROL_SI0_RST_MASK AR6320V2_SOC_RESET_CONTROL_SI0_RST_MASK
+#define AR6320V2_GPIO_BASE_ADDRESS AR6320V2_WLAN_GPIO_BASE_ADDRESS
+#define AR6320V2_GPIO_PIN0_OFFSET AR6320V2_WLAN_GPIO_PIN0_ADDRESS
+#define AR6320V2_GPIO_PIN1_OFFSET AR6320V2_WLAN_GPIO_PIN1_ADDRESS
+#define AR6320V2_GPIO_PIN0_CONFIG_MASK AR6320V2_WLAN_GPIO_PIN0_CONFIG_MASK
+#define AR6320V2_GPIO_PIN1_CONFIG_MASK AR6320V2_WLAN_GPIO_PIN1_CONFIG_MASK
+#define AR6320V2_SI_BASE_ADDRESS 0x00050000
+#define AR6320V2_CPU_CLOCK_OFFSET AR6320V2_SOC_CPU_CLOCK_OFFSET
+#define AR6320V2_LPO_CAL_OFFSET AR6320V2_SOC_LPO_CAL_OFFSET
+#define AR6320V2_GPIO_PIN10_OFFSET AR6320V2_WLAN_GPIO_PIN10_ADDRESS
+#define AR6320V2_GPIO_PIN11_OFFSET AR6320V2_WLAN_GPIO_PIN11_ADDRESS
+#define AR6320V2_GPIO_PIN12_OFFSET AR6320V2_WLAN_GPIO_PIN12_ADDRESS
+#define AR6320V2_GPIO_PIN13_OFFSET AR6320V2_WLAN_GPIO_PIN13_ADDRESS
+#define AR6320V2_CPU_CLOCK_STANDARD_LSB AR6320V2_SOC_CPU_CLOCK_STANDARD_LSB
+#define AR6320V2_CPU_CLOCK_STANDARD_MASK AR6320V2_SOC_CPU_CLOCK_STANDARD_MASK
+#define AR6320V2_LPO_CAL_ENABLE_LSB AR6320V2_SOC_LPO_CAL_ENABLE_LSB
+#define AR6320V2_LPO_CAL_ENABLE_MASK AR6320V2_SOC_LPO_CAL_ENABLE_MASK
+#define AR6320V2_ANALOG_INTF_BASE_ADDRESS AR6320V2_WLAN_ANALOG_INTF_BASE_ADDRESS
+#define AR6320V2_MBOX_BASE_ADDRESS 0x00008000
+#define AR6320V2_INT_STATUS_ENABLE_ERROR_LSB 7
+#define AR6320V2_INT_STATUS_ENABLE_ERROR_MASK 0x00000080
+#define AR6320V2_INT_STATUS_ENABLE_CPU_LSB 6
+#define AR6320V2_INT_STATUS_ENABLE_CPU_MASK 0x00000040
+#define AR6320V2_INT_STATUS_ENABLE_COUNTER_LSB 4
+#define AR6320V2_INT_STATUS_ENABLE_COUNTER_MASK 0x00000010
+#define AR6320V2_INT_STATUS_ENABLE_MBOX_DATA_LSB 0
+#define AR6320V2_INT_STATUS_ENABLE_MBOX_DATA_MASK 0x0000000f
+#define AR6320V2_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB 17
+#define AR6320V2_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK 0x00020000
+#define AR6320V2_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB 16
+#define AR6320V2_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK 0x00010000
+#define AR6320V2_COUNTER_INT_STATUS_ENABLE_BIT_LSB 24
+#define AR6320V2_COUNTER_INT_STATUS_ENABLE_BIT_MASK 0xff000000
+#define AR6320V2_INT_STATUS_ENABLE_ADDRESS 0x0828
+#define AR6320V2_CPU_INT_STATUS_ENABLE_BIT_LSB 8
+#define AR6320V2_CPU_INT_STATUS_ENABLE_BIT_MASK 0x0000ff00
+#define AR6320V2_HOST_INT_STATUS_ADDRESS 0x0800
+#define AR6320V2_CPU_INT_STATUS_ADDRESS 0x0801
+#define AR6320V2_ERROR_INT_STATUS_ADDRESS 0x0802
+#define AR6320V2_ERROR_INT_STATUS_WAKEUP_MASK 0x00040000
+#define AR6320V2_ERROR_INT_STATUS_WAKEUP_LSB 18
+#define AR6320V2_ERROR_INT_STATUS_RX_UNDERFLOW_MASK 0x00020000
+#define AR6320V2_ERROR_INT_STATUS_RX_UNDERFLOW_LSB 17
+#define AR6320V2_ERROR_INT_STATUS_TX_OVERFLOW_MASK 0x00010000
+#define AR6320V2_ERROR_INT_STATUS_TX_OVERFLOW_LSB 16
+#define AR6320V2_COUNT_DEC_ADDRESS 0x0840
+#define AR6320V2_HOST_INT_STATUS_CPU_MASK 0x00000040
+#define AR6320V2_HOST_INT_STATUS_CPU_LSB 6
+#define AR6320V2_HOST_INT_STATUS_ERROR_MASK 0x00000080
+#define AR6320V2_HOST_INT_STATUS_ERROR_LSB 7
+#define AR6320V2_HOST_INT_STATUS_COUNTER_MASK 0x00000010
+#define AR6320V2_HOST_INT_STATUS_COUNTER_LSB 4
+#define AR6320V2_RX_LOOKAHEAD_VALID_ADDRESS 0x0805
+#define AR6320V2_WINDOW_DATA_ADDRESS 0x0874
+#define AR6320V2_WINDOW_READ_ADDR_ADDRESS 0x087c
+#define AR6320V2_WINDOW_WRITE_ADDR_ADDRESS 0x0878
+
+struct targetdef_s ar6320v2_targetdef = {
+ .d_RTC_SOC_BASE_ADDRESS = AR6320V2_RTC_SOC_BASE_ADDRESS,
+ .d_RTC_WMAC_BASE_ADDRESS = AR6320V2_RTC_WMAC_BASE_ADDRESS,
+ .d_SYSTEM_SLEEP_OFFSET = AR6320V2_WLAN_SYSTEM_SLEEP_OFFSET,
+ .d_WLAN_SYSTEM_SLEEP_OFFSET = AR6320V2_WLAN_SYSTEM_SLEEP_OFFSET,
+ .d_WLAN_SYSTEM_SLEEP_DISABLE_LSB = AR6320V2_WLAN_SYSTEM_SLEEP_DISABLE_LSB,
+ .d_WLAN_SYSTEM_SLEEP_DISABLE_MASK = AR6320V2_WLAN_SYSTEM_SLEEP_DISABLE_MASK,
+ .d_CLOCK_CONTROL_OFFSET = AR6320V2_CLOCK_CONTROL_OFFSET,
+ .d_CLOCK_CONTROL_SI0_CLK_MASK = AR6320V2_CLOCK_CONTROL_SI0_CLK_MASK,
+ .d_RESET_CONTROL_OFFSET = AR6320V2_SOC_RESET_CONTROL_OFFSET,
+ .d_RESET_CONTROL_MBOX_RST_MASK = AR6320V2_RESET_CONTROL_MBOX_RST_MASK,
+ .d_RESET_CONTROL_SI0_RST_MASK = AR6320V2_RESET_CONTROL_SI0_RST_MASK,
+ .d_WLAN_RESET_CONTROL_OFFSET = AR6320V2_WLAN_RESET_CONTROL_OFFSET,
+ .d_WLAN_RESET_CONTROL_COLD_RST_MASK = AR6320V2_WLAN_RESET_CONTROL_COLD_RST_MASK,
+ .d_WLAN_RESET_CONTROL_WARM_RST_MASK = AR6320V2_WLAN_RESET_CONTROL_WARM_RST_MASK,
+ .d_GPIO_BASE_ADDRESS = AR6320V2_GPIO_BASE_ADDRESS,
+ .d_GPIO_PIN0_OFFSET = AR6320V2_GPIO_PIN0_OFFSET,
+ .d_GPIO_PIN1_OFFSET = AR6320V2_GPIO_PIN1_OFFSET,
+ .d_GPIO_PIN0_CONFIG_MASK = AR6320V2_GPIO_PIN0_CONFIG_MASK,
+ .d_GPIO_PIN1_CONFIG_MASK = AR6320V2_GPIO_PIN1_CONFIG_MASK,
+ .d_SI_CONFIG_BIDIR_OD_DATA_LSB = AR6320V2_SI_CONFIG_BIDIR_OD_DATA_LSB,
+ .d_SI_CONFIG_BIDIR_OD_DATA_MASK = AR6320V2_SI_CONFIG_BIDIR_OD_DATA_MASK,
+ .d_SI_CONFIG_I2C_LSB = AR6320V2_SI_CONFIG_I2C_LSB,
+ .d_SI_CONFIG_I2C_MASK = AR6320V2_SI_CONFIG_I2C_MASK,
+ .d_SI_CONFIG_POS_SAMPLE_LSB = AR6320V2_SI_CONFIG_POS_SAMPLE_LSB,
+ .d_SI_CONFIG_POS_SAMPLE_MASK = AR6320V2_SI_CONFIG_POS_SAMPLE_MASK,
+ .d_SI_CONFIG_INACTIVE_CLK_LSB = AR6320V2_SI_CONFIG_INACTIVE_CLK_LSB,
+ .d_SI_CONFIG_INACTIVE_CLK_MASK = AR6320V2_SI_CONFIG_INACTIVE_CLK_MASK,
+ .d_SI_CONFIG_INACTIVE_DATA_LSB = AR6320V2_SI_CONFIG_INACTIVE_DATA_LSB,
+ .d_SI_CONFIG_INACTIVE_DATA_MASK = AR6320V2_SI_CONFIG_INACTIVE_DATA_MASK,
+ .d_SI_CONFIG_DIVIDER_LSB = AR6320V2_SI_CONFIG_DIVIDER_LSB,
+ .d_SI_CONFIG_DIVIDER_MASK = AR6320V2_SI_CONFIG_DIVIDER_MASK,
+ .d_SI_BASE_ADDRESS = AR6320V2_SI_BASE_ADDRESS,
+ .d_SI_CONFIG_OFFSET = AR6320V2_SI_CONFIG_OFFSET,
+ .d_SI_TX_DATA0_OFFSET = AR6320V2_SI_TX_DATA0_OFFSET,
+ .d_SI_TX_DATA1_OFFSET = AR6320V2_SI_TX_DATA1_OFFSET,
+ .d_SI_RX_DATA0_OFFSET = AR6320V2_SI_RX_DATA0_OFFSET,
+ .d_SI_RX_DATA1_OFFSET = AR6320V2_SI_RX_DATA1_OFFSET,
+ .d_SI_CS_OFFSET = AR6320V2_SI_CS_OFFSET,
+ .d_SI_CS_DONE_ERR_MASK = AR6320V2_SI_CS_DONE_ERR_MASK,
+ .d_SI_CS_DONE_INT_MASK = AR6320V2_SI_CS_DONE_INT_MASK,
+ .d_SI_CS_START_LSB = AR6320V2_SI_CS_START_LSB,
+ .d_SI_CS_START_MASK = AR6320V2_SI_CS_START_MASK,
+ .d_SI_CS_RX_CNT_LSB = AR6320V2_SI_CS_RX_CNT_LSB,
+ .d_SI_CS_RX_CNT_MASK = AR6320V2_SI_CS_RX_CNT_MASK,
+ .d_SI_CS_TX_CNT_LSB = AR6320V2_SI_CS_TX_CNT_LSB,
+ .d_SI_CS_TX_CNT_MASK = AR6320V2_SI_CS_TX_CNT_MASK,
+ .d_BOARD_DATA_SZ = AR6320_BOARD_DATA_SZ,
+ .d_BOARD_EXT_DATA_SZ = AR6320_BOARD_EXT_DATA_SZ,
+ .d_MBOX_BASE_ADDRESS = AR6320V2_MBOX_BASE_ADDRESS,
+ .d_LOCAL_SCRATCH_OFFSET = AR6320V2_LOCAL_SCRATCH_OFFSET,
+ .d_CPU_CLOCK_OFFSET = AR6320V2_CPU_CLOCK_OFFSET,
+ .d_LPO_CAL_OFFSET = AR6320V2_LPO_CAL_OFFSET,
+ .d_GPIO_PIN10_OFFSET = AR6320V2_GPIO_PIN10_OFFSET,
+ .d_GPIO_PIN11_OFFSET = AR6320V2_GPIO_PIN11_OFFSET,
+ .d_GPIO_PIN12_OFFSET = AR6320V2_GPIO_PIN12_OFFSET,
+ .d_GPIO_PIN13_OFFSET = AR6320V2_GPIO_PIN13_OFFSET,
+ .d_CLOCK_GPIO_OFFSET = AR6320V2_CLOCK_GPIO_OFFSET,
+ .d_CPU_CLOCK_STANDARD_LSB = AR6320V2_CPU_CLOCK_STANDARD_LSB,
+ .d_CPU_CLOCK_STANDARD_MASK = AR6320V2_CPU_CLOCK_STANDARD_MASK,
+ .d_LPO_CAL_ENABLE_LSB = AR6320V2_LPO_CAL_ENABLE_LSB,
+ .d_LPO_CAL_ENABLE_MASK = AR6320V2_LPO_CAL_ENABLE_MASK,
+ .d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB = AR6320V2_CLOCK_GPIO_BT_CLK_OUT_EN_LSB,
+ .d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK = AR6320V2_CLOCK_GPIO_BT_CLK_OUT_EN_MASK,
+ .d_ANALOG_INTF_BASE_ADDRESS = AR6320V2_ANALOG_INTF_BASE_ADDRESS,
+ .d_WLAN_MAC_BASE_ADDRESS = AR6320V2_WLAN_MAC_BASE_ADDRESS,
+ .d_CE0_BASE_ADDRESS = AR6320V2_CE0_BASE_ADDRESS,
+ .d_CE1_BASE_ADDRESS = AR6320V2_CE1_BASE_ADDRESS,
+ .d_FW_INDICATOR_ADDRESS = AR6320V2_FW_INDICATOR_ADDRESS,
+ .d_DRAM_BASE_ADDRESS = AR6320V2_DRAM_BASE_ADDRESS,
+ .d_SOC_CORE_BASE_ADDRESS = AR6320V2_SOC_CORE_BASE_ADDRESS,
+ .d_CORE_CTRL_ADDRESS = AR6320V2_CORE_CTRL_ADDRESS,
+ .d_CE_COUNT = AR6320V2_CE_COUNT,
+ .d_MSI_NUM_REQUEST = MSI_NUM_REQUEST,
+ .d_MSI_ASSIGN_FW = MSI_ASSIGN_FW,
+ .d_MSI_ASSIGN_CE_INITIAL = MSI_ASSIGN_CE_INITIAL,
+ .d_PCIE_INTR_ENABLE_ADDRESS = AR6320V2_PCIE_INTR_ENABLE_ADDRESS,
+ .d_PCIE_INTR_CLR_ADDRESS = AR6320V2_PCIE_INTR_CLR_ADDRESS,
+ .d_PCIE_INTR_FIRMWARE_MASK = AR6320V2_PCIE_INTR_FIRMWARE_MASK,
+ .d_PCIE_INTR_CE_MASK_ALL = AR6320V2_PCIE_INTR_CE_MASK_ALL,
+ .d_CORE_CTRL_CPU_INTR_MASK = AR6320V2_CORE_CTRL_CPU_INTR_MASK,
+ .d_SR_WR_INDEX_ADDRESS = AR6320V2_SR_WR_INDEX_ADDRESS,
+ .d_DST_WATERMARK_ADDRESS = AR6320V2_DST_WATERMARK_ADDRESS,
+ /* htt_rx.c */
+ .d_RX_MSDU_END_4_FIRST_MSDU_MASK = AR6320V2_RX_MSDU_END_4_FIRST_MSDU_MASK,
+ .d_RX_MSDU_END_4_FIRST_MSDU_LSB = AR6320V2_RX_MSDU_END_4_FIRST_MSDU_LSB,
+ .d_RX_MPDU_START_0_SEQ_NUM_MASK = AR6320V2_RX_MPDU_START_0_SEQ_NUM_MASK,
+ .d_RX_MPDU_START_0_SEQ_NUM_LSB = AR6320V2_RX_MPDU_START_0_SEQ_NUM_LSB,
+ .d_RX_MPDU_START_2_PN_47_32_LSB = AR6320V2_RX_MPDU_START_2_PN_47_32_LSB,
+ .d_RX_MPDU_START_2_PN_47_32_MASK = AR6320V2_RX_MPDU_START_2_PN_47_32_MASK,
+ .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK = AR6320V2_RX_MSDU_END_1_EXT_WAPI_PN_63_48_MASK,
+ .d_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB = AR6320V2_RX_MSDU_END_1_EXT_WAPI_PN_63_48_LSB,
+ .d_RX_MSDU_END_4_LAST_MSDU_MASK = AR6320V2_RX_MSDU_END_4_LAST_MSDU_MASK,
+ .d_RX_MSDU_END_4_LAST_MSDU_LSB = AR6320V2_RX_MSDU_END_4_LAST_MSDU_LSB,
+ .d_RX_ATTENTION_0_MCAST_BCAST_MASK = AR6320V2_RX_ATTENTION_0_MCAST_BCAST_MASK,
+ .d_RX_ATTENTION_0_MCAST_BCAST_LSB = AR6320V2_RX_ATTENTION_0_MCAST_BCAST_LSB,
+ .d_RX_ATTENTION_0_FRAGMENT_MASK = AR6320V2_RX_ATTENTION_0_FRAGMENT_MASK,
+ .d_RX_ATTENTION_0_FRAGMENT_LSB = AR6320V2_RX_ATTENTION_0_FRAGMENT_LSB,
+ .d_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK = AR6320V2_RX_ATTENTION_0_MPDU_LENGTH_ERR_MASK,
+ .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK = AR6320V2_RX_FRAG_INFO_0_RING2_MORE_COUNT_MASK,
+ .d_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB = AR6320V2_RX_FRAG_INFO_0_RING2_MORE_COUNT_LSB,
+ .d_RX_MSDU_START_0_MSDU_LENGTH_MASK = AR6320V2_RX_MSDU_START_0_MSDU_LENGTH_MASK,
+ .d_RX_MSDU_START_0_MSDU_LENGTH_LSB = AR6320V2_RX_MSDU_START_0_MSDU_LENGTH_LSB,
+ .d_RX_MSDU_START_2_DECAP_FORMAT_OFFSET = AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_OFFSET,
+ .d_RX_MSDU_START_2_DECAP_FORMAT_MASK = AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_MASK,
+ .d_RX_MSDU_START_2_DECAP_FORMAT_LSB = AR6320V2_RX_MSDU_START_2_DECAP_FORMAT_LSB,
+ .d_RX_MPDU_START_0_ENCRYPTED_MASK = AR6320V2_RX_MPDU_START_0_ENCRYPTED_MASK,
+ .d_RX_MPDU_START_0_ENCRYPTED_LSB = AR6320V2_RX_MPDU_START_0_ENCRYPTED_LSB,
+ .d_RX_ATTENTION_0_MORE_DATA_MASK = AR6320V2_RX_ATTENTION_0_MORE_DATA_MASK,
+ .d_RX_ATTENTION_0_MSDU_DONE_MASK = AR6320V2_RX_ATTENTION_0_MSDU_DONE_MASK,
+ .d_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK = AR6320V2_RX_ATTENTION_0_TCP_UDP_CHKSUM_FAIL_MASK,
+ /* copy_engine.c */
+ .d_DST_WR_INDEX_ADDRESS = AR6320V2_DST_WR_INDEX_ADDRESS,
+ .d_SRC_WATERMARK_ADDRESS = AR6320V2_SRC_WATERMARK_ADDRESS,
+ .d_SRC_WATERMARK_LOW_MASK = AR6320V2_SRC_WATERMARK_LOW_MASK,
+ .d_SRC_WATERMARK_HIGH_MASK = AR6320V2_SRC_WATERMARK_HIGH_MASK,
+ .d_DST_WATERMARK_LOW_MASK = AR6320V2_DST_WATERMARK_LOW_MASK,
+ .d_DST_WATERMARK_HIGH_MASK = AR6320V2_DST_WATERMARK_HIGH_MASK,
+ .d_CURRENT_SRRI_ADDRESS = AR6320V2_CURRENT_SRRI_ADDRESS,
+ .d_CURRENT_DRRI_ADDRESS = AR6320V2_CURRENT_DRRI_ADDRESS,
+ .d_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK = AR6320V2_HOST_IS_SRC_RING_HIGH_WATERMARK_MASK,
+ .d_HOST_IS_SRC_RING_LOW_WATERMARK_MASK = AR6320V2_HOST_IS_SRC_RING_LOW_WATERMARK_MASK,
+ .d_HOST_IS_DST_RING_HIGH_WATERMARK_MASK = AR6320V2_HOST_IS_DST_RING_HIGH_WATERMARK_MASK,
+ .d_HOST_IS_DST_RING_LOW_WATERMARK_MASK = AR6320V2_HOST_IS_DST_RING_LOW_WATERMARK_MASK,
+ .d_HOST_IS_ADDRESS = AR6320V2_HOST_IS_ADDRESS,
+ .d_HOST_IS_COPY_COMPLETE_MASK = AR6320V2_HOST_IS_COPY_COMPLETE_MASK,
+ .d_CE_WRAPPER_BASE_ADDRESS = AR6320V2_CE_WRAPPER_BASE_ADDRESS,
+ .d_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS = AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS,
+ .d_HOST_IE_ADDRESS = AR6320V2_HOST_IE_ADDRESS,
+ .d_HOST_IE_COPY_COMPLETE_MASK = AR6320V2_HOST_IE_COPY_COMPLETE_MASK,
+ .d_SR_BA_ADDRESS = AR6320V2_SR_BA_ADDRESS,
+ .d_SR_SIZE_ADDRESS = AR6320V2_SR_SIZE_ADDRESS,
+ .d_CE_CTRL1_ADDRESS = AR6320V2_CE_CTRL1_ADDRESS,
+ .d_CE_CTRL1_DMAX_LENGTH_MASK = AR6320V2_CE_CTRL1_DMAX_LENGTH_MASK,
+ .d_DR_BA_ADDRESS = AR6320V2_DR_BA_ADDRESS,
+ .d_DR_SIZE_ADDRESS = AR6320V2_DR_SIZE_ADDRESS,
+ .d_MISC_IE_ADDRESS = AR6320V2_MISC_IE_ADDRESS,
+ .d_MISC_IS_AXI_ERR_MASK = AR6320V2_MISC_IS_AXI_ERR_MASK,
+ .d_MISC_IS_DST_ADDR_ERR_MASK = AR6320V2_MISC_IS_DST_ADDR_ERR_MASK,
+ .d_MISC_IS_SRC_LEN_ERR_MASK = AR6320V2_MISC_IS_SRC_LEN_ERR_MASK,
+ .d_MISC_IS_DST_MAX_LEN_VIO_MASK = AR6320V2_MISC_IS_DST_MAX_LEN_VIO_MASK,
+ .d_MISC_IS_DST_RING_OVERFLOW_MASK = AR6320V2_MISC_IS_DST_RING_OVERFLOW_MASK,
+ .d_MISC_IS_SRC_RING_OVERFLOW_MASK = AR6320V2_MISC_IS_SRC_RING_OVERFLOW_MASK,
+ .d_SRC_WATERMARK_LOW_LSB = AR6320V2_SRC_WATERMARK_LOW_LSB,
+ .d_SRC_WATERMARK_HIGH_LSB = AR6320V2_SRC_WATERMARK_HIGH_LSB,
+ .d_DST_WATERMARK_LOW_LSB = AR6320V2_DST_WATERMARK_LOW_LSB,
+ .d_DST_WATERMARK_HIGH_LSB = AR6320V2_DST_WATERMARK_HIGH_LSB,
+ .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK = AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK,
+ .d_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB = AR6320V2_CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB,
+ .d_CE_CTRL1_DMAX_LENGTH_LSB = AR6320V2_CE_CTRL1_DMAX_LENGTH_LSB,
+ .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK = AR6320V2_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK,
+ .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK = AR6320V2_CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK,
+ .d_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB = AR6320V2_CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB,
+ .d_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB = AR6320V2_CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB,
+
+ .d_PCIE_INTR_CAUSE_ADDRESS = AR6320V2_PCIE_INTR_CAUSE_ADDRESS,
+ .d_SOC_RESET_CONTROL_ADDRESS = AR6320V2_SOC_RESET_CONTROL_ADDRESS,
+ .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK = AR6320V2_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_MASK,
+ .d_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB = AR6320V2_SOC_RESET_CONTROL_PCIE_RST_SHORT_OVRD_LSB,
+ .d_SOC_RESET_CONTROL_CE_RST_MASK = AR6320V2_SOC_RESET_CONTROL_CE_RST_MASK,
+ .d_SOC_RESET_CONTROL_CPU_WARM_RST_MASK = AR6320V2_SOC_RESET_CONTROL_CPU_WARM_RST_MASK,
+ .d_CPU_INTR_ADDRESS = AR6320V2_CPU_INTR_ADDRESS,
+ .d_SOC_LF_TIMER_CONTROL0_ADDRESS = AR6320V2_SOC_LF_TIMER_CONTROL0_ADDRESS,
+ .d_SOC_LF_TIMER_CONTROL0_ENABLE_MASK = AR6320V2_SOC_LF_TIMER_CONTROL0_ENABLE_MASK,
+ /* chip id start */
+ .d_SOC_CHIP_ID_ADDRESS = AR6320V2_SOC_CHIP_ID_ADDRESS,
+ .d_SOC_CHIP_ID_VERSION_MASK = AR6320V2_SOC_CHIP_ID_VERSION_MASK,
+ .d_SOC_CHIP_ID_VERSION_LSB = AR6320V2_SOC_CHIP_ID_VERSION_LSB,
+ .d_SOC_CHIP_ID_REVISION_MASK = AR6320V2_SOC_CHIP_ID_REVISION_MASK,
+ .d_SOC_CHIP_ID_REVISION_LSB = AR6320V2_SOC_CHIP_ID_REVISION_LSB,
+ /* chip id end */
+};
+
+struct hostdef_s ar6320v2_hostdef = {
+ .d_INT_STATUS_ENABLE_ERROR_LSB = AR6320V2_INT_STATUS_ENABLE_ERROR_LSB,
+ .d_INT_STATUS_ENABLE_ERROR_MASK = AR6320V2_INT_STATUS_ENABLE_ERROR_MASK,
+ .d_INT_STATUS_ENABLE_CPU_LSB = AR6320V2_INT_STATUS_ENABLE_CPU_LSB,
+ .d_INT_STATUS_ENABLE_CPU_MASK = AR6320V2_INT_STATUS_ENABLE_CPU_MASK,
+ .d_INT_STATUS_ENABLE_COUNTER_LSB = AR6320V2_INT_STATUS_ENABLE_COUNTER_LSB,
+ .d_INT_STATUS_ENABLE_COUNTER_MASK = AR6320V2_INT_STATUS_ENABLE_COUNTER_MASK,
+ .d_INT_STATUS_ENABLE_MBOX_DATA_LSB = AR6320V2_INT_STATUS_ENABLE_MBOX_DATA_LSB,
+ .d_INT_STATUS_ENABLE_MBOX_DATA_MASK = AR6320V2_INT_STATUS_ENABLE_MBOX_DATA_MASK,
+ .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB = AR6320V2_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB,
+ .d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK = AR6320V2_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK,
+ .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB = AR6320V2_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB,
+ .d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK = AR6320V2_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK,
+ .d_COUNTER_INT_STATUS_ENABLE_BIT_LSB = AR6320V2_COUNTER_INT_STATUS_ENABLE_BIT_LSB,
+ .d_COUNTER_INT_STATUS_ENABLE_BIT_MASK = AR6320V2_COUNTER_INT_STATUS_ENABLE_BIT_MASK,
+ .d_INT_STATUS_ENABLE_ADDRESS = AR6320V2_INT_STATUS_ENABLE_ADDRESS,
+ .d_CPU_INT_STATUS_ENABLE_BIT_LSB = AR6320V2_CPU_INT_STATUS_ENABLE_BIT_LSB,
+ .d_CPU_INT_STATUS_ENABLE_BIT_MASK = AR6320V2_CPU_INT_STATUS_ENABLE_BIT_MASK,
+ .d_HOST_INT_STATUS_ADDRESS = AR6320V2_HOST_INT_STATUS_ADDRESS,
+ .d_CPU_INT_STATUS_ADDRESS = AR6320V2_CPU_INT_STATUS_ADDRESS,
+ .d_ERROR_INT_STATUS_ADDRESS = AR6320V2_ERROR_INT_STATUS_ADDRESS,
+ .d_ERROR_INT_STATUS_WAKEUP_MASK = AR6320V2_ERROR_INT_STATUS_WAKEUP_MASK,
+ .d_ERROR_INT_STATUS_WAKEUP_LSB = AR6320V2_ERROR_INT_STATUS_WAKEUP_LSB,
+ .d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK = AR6320V2_ERROR_INT_STATUS_RX_UNDERFLOW_MASK,
+ .d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB = AR6320V2_ERROR_INT_STATUS_RX_UNDERFLOW_LSB,
+ .d_ERROR_INT_STATUS_TX_OVERFLOW_MASK = AR6320V2_ERROR_INT_STATUS_TX_OVERFLOW_MASK,
+ .d_ERROR_INT_STATUS_TX_OVERFLOW_LSB = AR6320V2_ERROR_INT_STATUS_TX_OVERFLOW_LSB,
+ .d_COUNT_DEC_ADDRESS = AR6320V2_COUNT_DEC_ADDRESS,
+ .d_HOST_INT_STATUS_CPU_MASK = AR6320V2_HOST_INT_STATUS_CPU_MASK,
+ .d_HOST_INT_STATUS_CPU_LSB = AR6320V2_HOST_INT_STATUS_CPU_LSB,
+ .d_HOST_INT_STATUS_ERROR_MASK = AR6320V2_HOST_INT_STATUS_ERROR_MASK,
+ .d_HOST_INT_STATUS_ERROR_LSB = AR6320V2_HOST_INT_STATUS_ERROR_LSB,
+ .d_HOST_INT_STATUS_COUNTER_MASK = AR6320V2_HOST_INT_STATUS_COUNTER_MASK,
+ .d_HOST_INT_STATUS_COUNTER_LSB = AR6320V2_HOST_INT_STATUS_COUNTER_LSB,
+ .d_RX_LOOKAHEAD_VALID_ADDRESS = AR6320V2_RX_LOOKAHEAD_VALID_ADDRESS,
+ .d_WINDOW_DATA_ADDRESS = AR6320V2_WINDOW_DATA_ADDRESS,
+ .d_WINDOW_READ_ADDR_ADDRESS = AR6320V2_WINDOW_READ_ADDR_ADDRESS,
+ .d_WINDOW_WRITE_ADDR_ADDRESS = AR6320V2_WINDOW_WRITE_ADDR_ADDRESS,
+ .d_SOC_GLOBAL_RESET_ADDRESS = AR6320V2_SOC_GLOBAL_RESET_ADDRESS,
+ .d_RTC_STATE_ADDRESS = AR6320V2_RTC_STATE_ADDRESS,
+ .d_RTC_STATE_COLD_RESET_MASK = AR6320V2_RTC_STATE_COLD_RESET_MASK,
+ .d_PCIE_LOCAL_BASE_ADDRESS = AR6320V2_PCIE_LOCAL_BASE_ADDRESS,
+ .d_PCIE_SOC_WAKE_RESET = AR6320V2_PCIE_SOC_WAKE_RESET,
+ .d_PCIE_SOC_WAKE_ADDRESS = AR6320V2_PCIE_SOC_WAKE_ADDRESS,
+ .d_PCIE_SOC_WAKE_V_MASK = AR6320V2_PCIE_SOC_WAKE_V_MASK,
+ .d_RTC_STATE_V_MASK = AR6320V2_RTC_STATE_V_MASK,
+ .d_RTC_STATE_V_LSB = AR6320V2_RTC_STATE_V_LSB,
+ .d_FW_IND_EVENT_PENDING = AR6320V2_FW_IND_EVENT_PENDING,
+ .d_FW_IND_INITIALIZED = AR6320V2_FW_IND_INITIALIZED,
+ .d_RTC_STATE_V_ON = AR6320V2_RTC_STATE_V_ON,
+#if defined(SDIO_3_0)
+ .d_HOST_INT_STATUS_MBOX_DATA_MASK = AR6320V2_HOST_INT_STATUS_MBOX_DATA_MASK,
+ .d_HOST_INT_STATUS_MBOX_DATA_LSB = AR6320V2_HOST_INT_STATUS_MBOX_DATA_LSB,
+#endif
+ .d_PCIE_SOC_RDY_STATUS_ADDRESS = PCIE_SOC_RDY_STATUS_ADDRESS,
+ .d_PCIE_SOC_RDY_STATUS_BAR_MASK = PCIE_SOC_RDY_STATUS_BAR_MASK,
+ .d_SOC_PCIE_BASE_ADDRESS = SOC_PCIE_BASE_ADDRESS,
+ .d_MSI_MAGIC_ADR_ADDRESS = MSI_MAGIC_ADR_ADDRESS,
+ .d_MSI_MAGIC_ADDRESS = MSI_MAGIC_ADDRESS,
+};
+#endif
diff --git a/CORE/SERVICES/HIF/PCIe/cepci.h b/CORE/SERVICES/HIF/PCIe/cepci.h
index 4a04b7020a4d..144cf558d2fc 100644
--- a/CORE/SERVICES/HIF/PCIe/cepci.h
+++ b/CORE/SERVICES/HIF/PCIe/cepci.h
@@ -24,14 +24,6 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-//------------------------------------------------------------------------------
-// <copyright file="cepci.h" company="Qualcomm">
-// Copyright (c) 2012 Qualcomm Atheros Inc. All rights reserved.
-// $ATH_LICENSE_HOSTSDK0_C$
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Qualcomm Atheros Inc."
-//==============================================================================
#ifndef __CEPCI_H__
#define __CEPCI_H__
diff --git a/CORE/SERVICES/HIF/PCIe/hif_pci.c b/CORE/SERVICES/HIF/PCIe/hif_pci.c
index 72c24a8fab9f..4b1e4e2336e4 100644
--- a/CORE/SERVICES/HIF/PCIe/hif_pci.c
+++ b/CORE/SERVICES/HIF/PCIe/hif_pci.c
@@ -52,7 +52,6 @@
#define ATH_MODULE_NAME hif
#include <a_debug.h>
#include "hif_pci.h"
-#include "vos_lock.h"
/* use credit flow control over HTC */
unsigned int htc_credit_flow = 1;
@@ -1493,6 +1492,8 @@ HIFStop(HIF_DEVICE *hif_device)
if (!hif_state->started) {
return; /* already stopped or stopping */
}
+
+ sc->hif_init_done = FALSE;
/* sync shutdown */
hif_completion_thread_shutdown(hif_state);
hif_completion_thread(hif_state);
@@ -1523,7 +1524,6 @@ HIFStop(HIF_DEVICE *hif_device)
adf_os_timer_cancel(&hif_state->sleep_timer);
adf_os_timer_free(&hif_state->sleep_timer);
- vos_wake_lock_destroy(&hif_state->hif_wake_lock);
hif_state->started = FALSE;
AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-%s\n",__FUNCTION__));
@@ -1960,7 +1960,6 @@ HIF_sleep_entry(void *arg)
A_PCI_WRITE32(pci_addr + PCIE_LOCAL_BASE_ADDRESS +
PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET);
hif_state->fake_sleep = FALSE;
- vos_wake_lock_release(&hif_state->hif_wake_lock);
} else {
adf_os_timer_start(&hif_state->sleep_timer,
HIF_SLEEP_INACTIVITY_TIMER_PERIOD_MS);
@@ -1972,6 +1971,29 @@ HIF_sleep_entry(void *arg)
adf_os_spin_unlock(&hif_state->keep_awake_lock);
}
+void
+HIFCancelDeferredTargetSleep(HIF_DEVICE *hif_device)
+{
+ struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device;
+ A_target_id_t pci_addr = TARGID_TO_PCI_ADDR(hif_state->targid);
+ struct hif_pci_softc *sc = hif_state->sc;
+
+ adf_os_spin_lock(&hif_state->keep_awake_lock);
+ /*
+ * If the deferred sleep timer is running cancel it
+ * and put the soc into sleep.
+ */
+ if (hif_state->fake_sleep == TRUE) {
+ adf_os_timer_cancel(&hif_state->sleep_timer);
+ if (hif_state->verified_awake == FALSE) {
+ A_PCI_WRITE32(pci_addr + PCIE_LOCAL_BASE_ADDRESS +
+ PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET);
+ }
+ hif_state->fake_sleep = FALSE;
+ }
+ adf_os_spin_unlock(&hif_state->keep_awake_lock);
+}
+
/*
* Called from PCI layer whenever a new PCI device is probed.
* Initializes per-device HIF state and notifies the main
@@ -2010,7 +2032,6 @@ HIF_PCIDeviceProbed(hif_handle_t hif_hdl)
hif_state->sleep_ticks = 0;
adf_os_timer_init(NULL, &hif_state->sleep_timer,
HIF_sleep_entry, (void *)hif_state);
- vos_wake_lock_init(&hif_state->hif_wake_lock, "hif_wake_lock");
hif_state->fw_indicator_address = FW_INDICATOR_ADDRESS;
hif_state->targid = A_TARGET_ID(sc->hif_device);
@@ -2165,18 +2186,24 @@ HIF_PCIDeviceProbed(hif_handle_t hif_hdl)
{
A_UINT8 banks_switched = 1;
A_UINT32 chip_id;
- rv = HIFDiagReadAccess(sc->hif_device, CHIP_ID_ADDRESS, &chip_id);
+ rv = HIFDiagReadAccess(sc->hif_device, CHIP_ID_ADDRESS | RTC_SOC_BASE_ADDRESS, &chip_id);
if (rv != A_OK) {
AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed get chip id val (%d)\n", rv));
goto done;
}
- if (CHIP_ID_VERSION_GET(chip_id) == 0xD && (CHIP_ID_REVISION_GET(chip_id) == 0x0 || CHIP_ID_REVISION_GET(chip_id) == 0x1)) {
- /* for ROME 1.0, 3 banks are switched to IRAM */
- AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("chip ver=0x%x, chip rev=0x%x\n", CHIP_ID_VERSION_GET(chip_id), CHIP_ID_REVISION_GET(chip_id)));
- banks_switched = 3;
- }
- ealloc_value |= ((banks_switched << HI_EARLY_ALLOC_IRAM_BANKS_SHIFT) & HI_EARLY_ALLOC_IRAM_BANKS_MASK);
- }
+ if (CHIP_ID_VERSION_GET(chip_id) == 0xD) {
+ if ((CHIP_ID_REVISION_GET(chip_id) == 0x0) || (CHIP_ID_REVISION_GET(chip_id) == 0x1)
+ || (CHIP_ID_REVISION_GET(chip_id) == 0x4)) {
+ /* for ROME 1.0/1.1 and 2.1, 3 banks are switched to IRAM */
+ banks_switched = 3;
+ }
+ else if (CHIP_ID_REVISION_GET(chip_id) == 0x2) {
+ /* for ROME 1.3, 2 banks are switched to IRAM */
+ banks_switched = 2;
+ }
+ }
+ ealloc_value |= ((banks_switched << HI_EARLY_ALLOC_IRAM_BANKS_SHIFT) & HI_EARLY_ALLOC_IRAM_BANKS_MASK);
+ }
rv = HIFDiagWriteAccess(sc->hif_device, ealloc_targ_addr, ealloc_value);
if (rv != A_OK) {
AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("ath: HIF_PCIDeviceProbed set early alloc val (%d)\n", rv));
@@ -2295,7 +2322,6 @@ HIFTargetSleepStateAdjust(A_target_id_t targid,
adf_os_timer_cancel(&hif_state->sleep_timer);
adf_os_timer_start(&hif_state->sleep_timer,
HIF_SLEEP_INACTIVITY_TIMER_PERIOD_MS);
- vos_wake_lock_acquire(&hif_state->hif_wake_lock);
}
adf_os_spin_unlock(&hif_state->keep_awake_lock);
} else {
diff --git a/CORE/SERVICES/HIF/PCIe/hif_pci.h b/CORE/SERVICES/HIF/PCIe/hif_pci.h
index e17bc33b24c4..ebea6fca261f 100644
--- a/CORE/SERVICES/HIF/PCIe/hif_pci.h
+++ b/CORE/SERVICES/HIF/PCIe/hif_pci.h
@@ -95,7 +95,6 @@ struct HIF_CE_state {
A_BOOL verified_awake;
A_BOOL fake_sleep;
adf_os_timer_t sleep_timer;
- vos_wake_lock_t hif_wake_lock;
unsigned long sleep_ticks;
//struct task_struct *pci_dev_inserted_thread;
diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c
index 14a000b68de2..f2cc9621d642 100644
--- a/CORE/SERVICES/HIF/PCIe/if_pci.c
+++ b/CORE/SERVICES/HIF/PCIe/if_pci.c
@@ -3,7 +3,6 @@
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
- *
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
@@ -60,6 +59,9 @@
#define AR9888_DEVICE_ID (0x003c)
#define AR6320_DEVICE_ID (0x003e)
+#define AR6320_FW_1_1 (0x11)
+#define AR6320_FW_1_3 (0x13)
+#define AR6320_FW_2_0 (0x20)
#define MAX_NUM_OF_RECEIVES 1000 /* Maximum number of Rx buf to process before break out */
@@ -342,6 +344,10 @@ wlan_tasklet(unsigned long data)
struct hif_pci_softc *sc = (struct hif_pci_softc *) data;
volatile int tmp;
+ if (sc->hif_init_done == FALSE) {
+ goto irq_handled;
+ }
+
(irqreturn_t)HIF_fw_interrupt_handler(sc->irq_event, sc);
CE_per_engine_service_any(sc->irq_event, sc);
adf_os_atomic_set(&sc->tasklet_from_intr, 0);
@@ -354,6 +360,7 @@ wlan_tasklet(unsigned long data)
tasklet_schedule(&sc->intr_tq);
return;
}
+irq_handled:
if (LEGACY_INTERRUPTS(sc)) {
/* Enable Legacy PCI line interrupts */
A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS),
@@ -375,6 +382,7 @@ hif_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
struct ol_softc *ol_sc;
int probe_again = 0;
u_int16_t device_id;
+ u_int16_t revision_id;
u_int32_t lcr_val;
@@ -459,6 +467,10 @@ again:
ret = -EIO;
goto err_iomap;
}
+
+ /* Disable asynchronous suspend */
+ device_disable_async_suspend(&pdev->dev);
+
sc = A_MALLOC(sizeof(*sc));
if (!sc) {
ret = -ENOMEM;
@@ -480,19 +492,37 @@ again:
sc->cacheline_sz = dma_get_cache_alignment();
+ pci_read_config_word(pdev, 0x08, &revision_id);
+
switch (id->device) {
case AR9888_DEVICE_ID:
- hif_type = HIF_TYPE_AR9888;
- target_type = TARGET_TYPE_AR9888;
- break;
+ hif_type = HIF_TYPE_AR9888;
+ target_type = TARGET_TYPE_AR9888;
+ break;
+
case AR6320_DEVICE_ID:
- hif_type = HIF_TYPE_AR6320;
- target_type = TARGET_TYPE_AR6320;
- break;
+ switch(revision_id) {
+ case AR6320_FW_1_1:
+ case AR6320_FW_1_3:
+ hif_type = HIF_TYPE_AR6320;
+ target_type = TARGET_TYPE_AR6320;
+ break;
+
+ case AR6320_FW_2_0:
+ hif_type = HIF_TYPE_AR6320V2;
+ target_type = TARGET_TYPE_AR6320V2;
+ break;
+
+ default:
+ printk(KERN_ERR "unsupported revision id\n");
+
+ }
+ break;
+
default:
- printk(KERN_ERR "unsupported device id\n");
- ret = -ENODEV;
- goto err_tgtstate;
+ printk(KERN_ERR "unsupported device id\n");
+ ret = -ENODEV;
+ goto err_tgtstate;
}
/*
* Attach Target register table. This is needed early on --
@@ -653,6 +683,7 @@ int hif_pci_reinit(struct pci_dev *pdev, const struct pci_device_id *id)
u_int32_t hif_type;
u_int32_t target_type;
u_int32_t lcr_val;
+ u_int16_t revision_id;
again:
ret = 0;
@@ -753,16 +784,33 @@ again:
adf_os_spinlock_init(&sc->target_lock);
sc->cacheline_sz = dma_get_cache_alignment();
+ pci_read_config_word(pdev, 0x08, &revision_id);
switch (id->device) {
case AR9888_DEVICE_ID:
hif_type = HIF_TYPE_AR9888;
target_type = TARGET_TYPE_AR9888;
break;
+
case AR6320_DEVICE_ID:
- hif_type = HIF_TYPE_AR6320;
- target_type = TARGET_TYPE_AR6320;
+ switch(revision_id) {
+ case AR6320_FW_1_1:
+ case AR6320_FW_1_3:
+ hif_type = HIF_TYPE_AR6320;
+ target_type = TARGET_TYPE_AR6320;
+ break;
+
+ case AR6320_FW_2_0:
+ hif_type = HIF_TYPE_AR6320V2;
+ target_type = TARGET_TYPE_AR6320V2;
+ break;
+
+ default:
+ printk(KERN_ERR "unsupported revision id\n");
+
+ }
break;
+
default:
printk(KERN_ERR "%s: Unsupported device ID!\n", __func__);
ret = -ENODEV;
@@ -1065,6 +1113,30 @@ hif_pci_configure(struct hif_pci_softc *sc, hif_handle_t *hif_hdl)
}
#endif
+ if(num_msi_desired == 0) {
+ printk("\n Using PCI Legacy Interrupt\n");
+
+ /* Make sure to wake the Target before enabling Legacy Interrupt */
+ A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS,
+ PCIE_SOC_WAKE_V_MASK);
+ while (!hif_pci_targ_is_awake(sc, sc->mem)) {
+ ;
+ }
+ /* Use Legacy PCI Interrupts */
+ /*
+ * A potential race occurs here: The CORE_BASE write depends on
+ * target correctly decoding AXI address but host won't know
+ * when target writes BAR to CORE_CTRL. This write might get lost
+ * if target has NOT written BAR. For now, fix the race by repeating
+ * the write in below synchronization checking.
+ */
+ A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS |
+ PCIE_INTR_ENABLE_ADDRESS),
+ PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL);
+ A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS,
+ PCIE_SOC_WAKE_RESET);
+ }
+
sc->num_msi_intrs = num_msi_desired;
sc->ce_count = CE_COUNT;
@@ -1102,30 +1174,14 @@ hif_pci_configure(struct hif_pci_softc *sc, hif_handle_t *hif_hdl)
*hif_hdl = sc->hif_device;
- if(num_msi_desired == 0) {
- printk("\n Using PCI Legacy Interrupt\n");
-
- /* Make sure to wake the Target before enabling Legacy Interrupt */
- A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS,
- PCIE_SOC_WAKE_V_MASK);
- while (!hif_pci_targ_is_awake(sc, sc->mem)) {
- ;
- }
- /* Use Legacy PCI Interrupts */
- /*
- * A potential race occurs here: The CORE_BASE write depends on
- * target correctly decoding AXI address but host won't know
- * when target writes BAR to CORE_CTRL. This write might get lost
- * if target has NOT written BAR. For now, fix the race by repeating
- * the write in below synchronization checking.
- */
- A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS |
- PCIE_INTR_ENABLE_ADDRESS),
- PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL);
- A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS,
- PCIE_SOC_WAKE_RESET);
- }
-
+ /*
+ * Flag to avoid potential unallocated memory access from MSI
+ * interrupt handler which could get scheduled as soon as MSI
+ * is enabled, i.e to take care of the race due to the order
+ * in where MSI is enabled before the memory, that will be
+ * in interrupt handlers, is allocated.
+ */
+ sc->hif_init_done = TRUE;
return 0;
err_stalled:
diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.h b/CORE/SERVICES/HIF/PCIe/if_pci.h
index 6219544cbc44..74f7130e04c7 100644
--- a/CORE/SERVICES/HIF/PCIe/if_pci.h
+++ b/CORE/SERVICES/HIF/PCIe/if_pci.h
@@ -87,6 +87,7 @@ struct hif_pci_softc {
struct targetdef_s *targetdef;
struct hostdef_s *hostdef;
atomic_t tasklet_from_intr;
+ bool hif_init_done;
};
#define TARGID(sc) ((A_target_id_t)(&(sc)->mem))
#define TARGID_TO_HIF(targid) (((struct hif_pci_softc *)((char *)(targid) - (char *)&(((struct hif_pci_softc *)0)->mem)))->hif_device)
diff --git a/CORE/SERVICES/HIF/PCIe/regtable.c b/CORE/SERVICES/HIF/PCIe/regtable.c
index ad080d3d9f81..822b977b4bb6 100644
--- a/CORE/SERVICES/HIF/PCIe/regtable.c
+++ b/CORE/SERVICES/HIF/PCIe/regtable.c
@@ -24,35 +24,14 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-/*
- * Copyright (c) 2013 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-/*
- * Copyright (c) 2010 Atheros Communications, Inc.
- * All rights reserved.
- *
- *
- * $ATH_LICENSE_HOSTSDK0_C$
- *
- */
+
#include "bmi_msg.h"
#include "targaddrs.h"
#include "cepci.h"
#include "regtable.h"
#include "ar9888def.h"
#include "ar6320def.h"
+#include "ar6320v2def.h"
void target_register_tbl_attach(struct hif_pci_softc *sc, u32 target_type)
{
@@ -63,6 +42,9 @@ void target_register_tbl_attach(struct hif_pci_softc *sc, u32 target_type)
case TARGET_TYPE_AR6320:
sc->targetdef = &ar6320_targetdef;
break;
+ case TARGET_TYPE_AR6320V2:
+ sc->targetdef = &ar6320v2_targetdef;
+ break;
default:
break;
}
@@ -77,6 +59,9 @@ void hif_register_tbl_attach(struct hif_pci_softc *sc, u32 hif_type)
case HIF_TYPE_AR6320:
sc->hostdef = &ar6320_hostdef;
break;
+ case HIF_TYPE_AR6320V2:
+ sc->hostdef = &ar6320v2_hostdef;
+ break;
default:
break;
}
diff --git a/CORE/SERVICES/HTC/htc.c b/CORE/SERVICES/HTC/htc.c
index 9880891b1ee8..2a6172a26989 100644
--- a/CORE/SERVICES/HTC/htc.c
+++ b/CORE/SERVICES/HTC/htc.c
@@ -781,3 +781,11 @@ void HTCSetTargetToSleep(void *context)
#endif
#endif
}
+
+void HTCCancelDeferredTargetSleep(void *context)
+{
+#if CONFIG_ATH_PCIE_MAX_PERF == 0
+ struct ol_softc *sc = (struct ol_softc *)context;
+ HIFCancelDeferredTargetSleep(sc->hif_hdl);
+#endif
+}
diff --git a/CORE/SERVICES/WMA/regdomain.c b/CORE/SERVICES/WMA/regdomain.c
index 1daa4aa9ec81..5a0b8d498174 100644
--- a/CORE/SERVICES/WMA/regdomain.c
+++ b/CORE/SERVICES/WMA/regdomain.c
@@ -372,7 +372,7 @@ u_int32_t regdmn_getwmodesnreg(u_int32_t modesAvail,
return modesAvail;
}
-static void regdmn_get_ctl_info(struct regulatory *reg, u_int32_t modesAvail,
+void regdmn_get_ctl_info(struct regulatory *reg, u_int32_t modesAvail,
u_int32_t modeSelect)
{
const REG_DOMAIN *regdomain2G = NULL;
@@ -478,3 +478,25 @@ void regdmn_set_regval(struct regulatory *reg)
regdmn_get_ctl_info(reg, wma->reg_cap.wireless_modes, modeSelect);
return;
}
+
+/* get the ctl from regdomain */
+u_int8_t regdmn_get_ctl_for_regdmn(u_int32_t reg_dmn)
+{
+ u_int8_t i;
+ u_int8_t default_regdmn_ctl = FCC;
+
+ if (reg_dmn == CTRY_DEFAULT)
+ {
+ return default_regdmn_ctl;
+ }
+ else
+ {
+ for (i = 0; i < ol_regdmn_Rdt.regDomainsCt; i++)
+ {
+ if (ol_regdmn_Rdt.regDomains[i].regDmnEnum == reg_dmn)
+ return ol_regdmn_Rdt.regDomains[i].conformance_test_limit;
+ }
+ }
+ return -1;
+}
+
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index e674a23f2523..207cd2910088 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -67,6 +67,10 @@
#include "wlan_tgt_def_config.h"
#endif
+#if defined(QCA_IBSS_SUPPORT)
+#include "wlan_hdd_assoc.h"
+#endif
+
#include "adf_nbuf.h"
#include "adf_os_types.h"
#include "ol_txrx_api.h"
@@ -87,7 +91,6 @@
#include "testmode.h"
#endif
-
#if !defined(REMOVE_PKT_LOG) && !defined(QCA_WIFI_ISOC)
#include "pktlog_ac.h"
#endif
@@ -98,6 +101,9 @@
#include "csrApi.h"
#include "ol_fw.h"
+#include "wma_dfs_interface.h"
+#include "dfs_interface.h"
+#include "radar_filters.h"
/* ################### defines ################### */
#define WMA_2_4_GHZ_MAX_FREQ 3000
#define WOW_CSA_EVENT_OFFSET 12
@@ -107,6 +113,15 @@
/* default value */
#define DEFAULT_INFRA_STA_KEEP_ALIVE_PERIOD 20
#define DEFAULT_MAX_IDLETIME 20
+/* pdev vdev and peer stats*/
+#define FW_PDEV_STATS_SET 0x1
+#define FW_VDEV_STATS_SET 0x2
+#define FW_PEER_STATS_SET 0x4
+#define FW_STATS_SET 0x7
+/*AR9888/AR6320 noise floor approx value
+ * similar to the mentioned the TLSHIM
+ */
+#define WMA_TGT_NOISE_FLOOR_DBM (-96)
/*There is no standard way of caluclating minimum inactive
*timer and max unresposive timer from max inactive timer
*the below expression are taken from qca_main code
@@ -127,6 +142,11 @@
#define CHAN_DUMP 2
#define WD_DUMP 3
+/* conformance test limits */
+#define FCC 0x10
+#define MKK 0x40
+#define ETSI 0x30
+
#define WMI_DEFAULT_NOISE_FLOOR_DBM (-96)
static void wma_send_msg(tp_wma_handle wma_handle, u_int16_t msg_type,
@@ -138,10 +158,14 @@ static void wma_send_beacon_tmpl(WMA_HANDLE handle,
static void wma_data_tx_ack_comp_hdlr(void *wma_context,
adf_nbuf_t netbuf,
int32_t status);
+#endif
static VOS_STATUS wma_vdev_detach(tp_wma_handle wma_handle,
tpDelStaSelfParams pdel_sta_self_req_param,
u_int8_t generateRsp);
-#endif
+static struct wma_target_req *
+wma_fill_vdev_req(tp_wma_handle wma, u_int8_t vdev_id,
+ u_int32_t msg_type, u_int8_t type, void *params,
+ u_int32_t timeout);
static tANI_U32 gFwWlanFeatCaps;
@@ -155,6 +179,9 @@ static int wma_update_tdls_peer_state(WMA_HANDLE handle,
tTdlsPeerStateParams *peerStateParams);
#endif
+static eHalStatus wma_set_smps_params(tp_wma_handle wma_handle,
+ tANI_U8 vdev_id, int value);
+
#if defined(QCA_WIFI_FTM) && !defined(QCA_WIFI_ISOC)
void wma_utf_attach(tp_wma_handle wma_handle);
void wma_utf_detach(tp_wma_handle wma_handle);
@@ -162,6 +189,31 @@ static VOS_STATUS
wma_process_ftm_command(tp_wma_handle wma_handle,
struct ar6k_testmode_cmd_data *msg_buffer);
#endif
+
+/*DFS Attach*/
+struct ieee80211com* wma_dfs_attach(struct ieee80211com *ic);
+static void wma_set_regdomain(a_uint32_t regdmn);
+
+/*Configure DFS with radar tables and regulatory domain*/
+void wma_dfs_configure(struct ieee80211com *ic);
+
+/*Configure the current channel with the DFS*/
+struct ieee80211_channel *
+wma_dfs_configure_channel(struct ieee80211com *dfs_ic,
+ wmi_channel *chan,
+ WLAN_PHY_MODE chanmode,
+ struct wma_vdev_start_req *req);
+
+/* VDEV UP */
+static int
+wmi_unified_vdev_up_send(wmi_unified_t wmi,
+ u_int8_t vdev_id, u_int16_t aid,
+ u_int8_t bssid[IEEE80211_ADDR_LEN]);
+
+
+/* Configure the regulatory domain for DFS radar filter initialization*/
+void wma_set_dfs_regdomain(tp_wma_handle wma);
+
static void *wma_find_vdev_by_addr(tp_wma_handle wma, u_int8_t *addr,
u_int8_t *vdev_id)
{
@@ -364,7 +416,7 @@ static struct wma_target_req *wma_find_vdev_req(tp_wma_handle wma,
}
adf_os_spin_unlock_bh(&wma->vdev_respq_lock);
if (!found) {
- WMA_LOGD("%s: target request not found for vdev_id %d type %d\n",
+ WMA_LOGP("%s: target request not found for vdev_id %d type %d\n",
__func__, vdev_id, type);
return NULL;
}
@@ -457,6 +509,7 @@ static int wma_vdev_start_resp_handler(void *handle, u_int8_t *cmd_param_info,
struct wma_target_req *req_msg;
WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf;
wmi_vdev_start_response_event_fixed_param *resp_event;
+ struct wma_txrx_node *iface;
param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) cmd_param_info;
if (!param_buf) {
@@ -473,6 +526,7 @@ static int wma_vdev_start_resp_handler(void *handle, u_int8_t *cmd_param_info,
return -EINVAL;
}
vos_timer_stop(&req_msg->event_timeout);
+ iface = &wma->interfaces[resp_event->vdev_id];
if (req_msg->msg_type == WDA_CHNL_SWITCH_REQ) {
tpSwitchChannelParams params =
(tpSwitchChannelParams) req_msg->user_data;
@@ -481,6 +535,13 @@ static int wma_vdev_start_resp_handler(void *handle, u_int8_t *cmd_param_info,
params->chainMask = resp_event->chain_mask;
params->smpsMode = host_map_smps_mode(resp_event->smps_mode);
params->status = resp_event->status;
+ if (resp_event->resp_type == WMI_VDEV_RESTART_RESP_EVENT &&
+ (iface->type == WMI_VDEV_TYPE_AP)) {
+ wmi_unified_vdev_up_send(wma->wmi_handle,
+ resp_event->vdev_id,
+ iface->aid,
+ iface->bssid);
+ }
wma_send_msg(wma, WDA_SWITCH_CHANNEL_RSP, (void *)params, 0);
} else if (req_msg->msg_type == WDA_ADD_BSS_REQ) {
tpAddBssParams bssParams = (tpAddBssParams) req_msg->user_data;
@@ -731,8 +792,8 @@ static int wma_peer_sta_kickout_event_handler(void *handle, u8 *event, u32 len)
return -EINVAL;
}
- WMA_LOGD("%s:\nPEER:[%pM]\n BSSID:[%pM]\nINTERFACE:%d\npeer_ID:%d\n",
- __func__, macaddr, wma->interfaces[vdev_id].addr, vdev_id,
+ WMA_LOGA("PEER:[%pM]\n BSSID:[%pM]\nINTERFACE:%d\npeer_ID:%d\n",
+ macaddr, wma->interfaces[vdev_id].addr, vdev_id,
peer_id);
if (kickout_event->reason == WMI_PEER_STA_KICKOUT_REASON_IBSS_DISCONNECT) {
@@ -767,6 +828,31 @@ static int wma_peer_sta_kickout_event_handler(void *handle, u8 *event, u32 len)
return 0;
}
+static int wmi_unified_vdev_down_send(wmi_unified_t wmi, u_int8_t vdev_id)
+{
+ wmi_vdev_down_cmd_fixed_param *cmd;
+ wmi_buf_t buf;
+ int32_t len = sizeof(*cmd);
+
+ buf = wmi_buf_alloc(wmi, len);
+ if (!buf) {
+ WMA_LOGP("%s : wmi_buf_alloc failed\n", __func__);
+ return -ENOMEM;
+ }
+ cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf);
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param));
+ cmd->vdev_id = vdev_id;
+ if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) {
+ WMA_LOGP("Failed to send vdev down\n");
+ adf_nbuf_free(buf);
+ return -EIO;
+ }
+ WMA_LOGD("%s: vdev_id %d\n", __func__, vdev_id);
+ return 0;
+}
+
static int wma_vdev_stop_resp_handler(void *handle, u_int8_t *cmd_param_info,
u32 len)
{
@@ -780,6 +866,7 @@ static int wma_vdev_stop_resp_handler(void *handle, u_int8_t *cmd_param_info,
#ifdef QCA_IBSS_SUPPORT
tDelStaSelfParams del_sta_param;
#endif
+ struct wma_txrx_node *iface;
param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) cmd_param_info;
if (!param_buf) {
@@ -809,6 +896,12 @@ static int wma_vdev_stop_resp_handler(void *handle, u_int8_t *cmd_param_info,
WMA_LOGD("%s Failed to find peer %pM\n",
__func__, params->bssid);
wma_remove_peer(wma, params->bssid, resp_event->vdev_id, peer);
+ wmi_unified_vdev_down_send(wma->wmi_handle, resp_event->vdev_id);
+ iface = &wma->interfaces[resp_event->vdev_id];
+ if (iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) {
+ WMA_LOGD("%s: P2P BSS is stopped", __func__);
+ iface->bss_status = WMA_BSS_STATUS_STOPPED;
+ }
#ifndef QCA_WIFI_ISOC
bcn = wma->interfaces[resp_event->vdev_id].beacon;
@@ -836,12 +929,218 @@ static int wma_vdev_stop_resp_handler(void *handle, u_int8_t *cmd_param_info,
params->status = VOS_STATUS_SUCCESS;
wma_send_msg(wma, WDA_DELETE_BSS_RSP, (void *)params, 0);
+ if (iface->del_staself_req) {
+ WMA_LOGD("%s: scheduling defered deletion", __func__);
+ wma_vdev_detach(wma, iface->del_staself_req, 1);
+ }
}
vos_timer_destroy(&req_msg->event_timeout);
vos_mem_free(req_msg);
return 0;
}
+static void wma_update_pdev_stats(tp_wma_handle wma,
+ wmi_pdev_stats *pdev_stats)
+{
+ tAniGetPEStatsRsp *stats_rsp_params;
+ tANI_U32 temp_mask;
+ tANI_U8 *stats_buf;
+ tCsrGlobalClassAStatsInfo *classa_stats = NULL;
+ struct wma_txrx_node *node;
+ u_int8_t i;
+
+ for (i = 0; i < wma->max_bssid; i++) {
+ node = &wma->interfaces[i];
+ stats_rsp_params = node->stats_rsp;
+ if (stats_rsp_params) {
+ node->fw_stats_set |= FW_PDEV_STATS_SET;
+ WMA_LOGD("<---FW PDEV STATS received for vdevId:%d",
+ i);
+ stats_buf = (tANI_U8 *) (stats_rsp_params + 1);
+ temp_mask = stats_rsp_params->statsMask;
+ if (temp_mask & (1 << eCsrSummaryStats))
+ stats_buf += sizeof(tCsrSummaryStatsInfo);
+
+ if (temp_mask & (1 << eCsrGlobalClassAStats)) {
+ classa_stats =
+ (tCsrGlobalClassAStatsInfo *) stats_buf;
+ classa_stats->max_pwr = pdev_stats->chan_tx_pwr;
+ }
+ }
+ }
+}
+
+static void wma_update_vdev_stats(tp_wma_handle wma,
+ wmi_vdev_stats *vdev_stats)
+{
+ tAniGetPEStatsRsp *stats_rsp_params;
+ tCsrSummaryStatsInfo *summary_stats = NULL;
+ tANI_U8 *stats_buf;
+ struct wma_txrx_node *node;
+ tANI_U8 i;
+ v_S7_t rssi = 0;
+ tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq*)wma->pGetRssiReq;
+
+ node = &wma->interfaces[vdev_stats->vdev_id];
+ stats_rsp_params = node->stats_rsp;
+ if (stats_rsp_params) {
+ stats_buf = (tANI_U8 *) (stats_rsp_params + 1);
+ node->fw_stats_set |= FW_VDEV_STATS_SET;
+ WMA_LOGD("<---FW VDEV STATS received for vdevId:%d",
+ vdev_stats->vdev_id);
+ if (stats_rsp_params->statsMask &
+ (1 << eCsrSummaryStats)) {
+ summary_stats = (tCsrSummaryStatsInfo *) stats_buf;
+ for (i=0 ; i < 4 ; i++) {
+ summary_stats->tx_frm_cnt[i] =
+ vdev_stats->tx_frm_cnt[i];
+ summary_stats->fail_cnt[i] =
+ vdev_stats->fail_cnt[i];
+ summary_stats->multiple_retry_cnt[i] =
+ vdev_stats->multiple_retry_cnt[i];
+ }
+
+ summary_stats->rx_frm_cnt = vdev_stats->rx_frm_cnt;
+ summary_stats->rx_error_cnt = vdev_stats->rx_err_cnt;
+ summary_stats->rx_discard_cnt =
+ vdev_stats->rx_discard_cnt;
+ summary_stats->ack_fail_cnt = vdev_stats->ack_fail_cnt;
+ summary_stats->rts_succ_cnt = vdev_stats->rts_succ_cnt;
+ summary_stats->rts_fail_cnt = vdev_stats->rts_fail_cnt;
+ }
+ }
+
+ if (pGetRssiReq &&
+ pGetRssiReq->sessionId == vdev_stats->vdev_id) {
+ if((vdev_stats->vdev_snr.dat_snr > 0) &&
+ (vdev_stats->vdev_snr.bcn_snr > 0))
+ rssi = (vdev_stats->vdev_snr.dat_snr + vdev_stats->vdev_snr.bcn_snr)/2;
+ else
+ rssi = vdev_stats->vdev_snr.bcn_snr;
+
+ /* Get the absolute rssi value from the current rssi value
+ * the sinr value is hardcoded into 0 in the core stack
+ */
+ WMA_LOGD("vdev id %d beancon snr %d data snr %d",
+ vdev_stats->vdev_id,
+ vdev_stats->vdev_snr.bcn_snr,
+ vdev_stats->vdev_snr.dat_snr);
+
+ rssi = rssi + WMA_TGT_NOISE_FLOOR_DBM;
+ WMA_LOGD("Average Rssi = %d, vdev id= %d", rssi,
+ pGetRssiReq->sessionId);
+
+ /* update the average rssi value to UMAC layer */
+ if (NULL != pGetRssiReq->rssiCallback) {
+ ((tCsrRssiCallback)(pGetRssiReq->rssiCallback))(rssi,pGetRssiReq->staId,
+ pGetRssiReq->pDevContext);
+ }
+
+ vos_mem_free(pGetRssiReq);
+ wma->pGetRssiReq = NULL;
+ }
+}
+
+static void wma_post_stats(tp_wma_handle wma, struct wma_txrx_node *node)
+{
+ tAniGetPEStatsRsp *stats_rsp_params;
+
+ stats_rsp_params = node->stats_rsp;
+ /* send response to UMAC*/
+ wma_send_msg(wma, WDA_GET_STATISTICS_RSP, (void *)stats_rsp_params, 0) ;
+ node->stats_rsp = NULL;
+ node->fw_stats_set = 0;
+}
+
+static void wma_update_peer_stats(tp_wma_handle wma, wmi_peer_stats *peer_stats)
+{
+ tAniGetPEStatsRsp *stats_rsp_params;
+ tCsrGlobalClassAStatsInfo *classa_stats = NULL;
+ struct wma_txrx_node *node;
+ tANI_U8 *stats_buf, vdev_id, macaddr[IEEE80211_ADDR_LEN];
+ tANI_U32 temp_mask;
+
+ WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_stats->peer_macaddr, &macaddr[0]);
+ if (!wma_find_vdev_by_bssid(wma, macaddr, &vdev_id))
+ return;
+
+ node = &wma->interfaces[vdev_id];
+ if (node->stats_rsp) {
+ node->fw_stats_set |= FW_PEER_STATS_SET;
+ WMA_LOGD("<-- FW PEER STATS received for vdevId:%d", vdev_id);
+ stats_rsp_params = (tAniGetPEStatsRsp *) node->stats_rsp;
+ stats_buf = (tANI_U8 *) (stats_rsp_params + 1);
+ temp_mask = stats_rsp_params->statsMask;
+ if (temp_mask & (1 << eCsrSummaryStats))
+ stats_buf += sizeof(tCsrSummaryStatsInfo);
+
+ if (temp_mask & (1 << eCsrGlobalClassAStats)) {
+ classa_stats = (tCsrGlobalClassAStatsInfo *) stats_buf;
+ WMA_LOGD("peer tx rate:%d", peer_stats->peer_tx_rate);
+ /*The linkspeed returned by fw is in kbps so convert
+ *it in to units of 500kbps which is expected by UMAC*/
+ if (peer_stats->peer_tx_rate) {
+ classa_stats->tx_rate =
+ peer_stats->peer_tx_rate/500;
+ }
+ /* currently tx rate flags are not provided by
+ * the fw*/
+ classa_stats->tx_rate_flags = eHAL_TX_RATE_LEGACY;
+ }
+
+ if (node->fw_stats_set & FW_STATS_SET) {
+ WMA_LOGD("<--STATS RSP VDEV_ID:%d", vdev_id);
+ wma_post_stats(wma, node);
+ }
+ }
+}
+
+static int wma_stats_event_handler(void *handle, u_int8_t *cmd_param_info,
+ u_int32_t len)
+{
+ tp_wma_handle wma = (tp_wma_handle)handle;
+ wmi_stats_event_fixed_param *event;
+ wmi_pdev_stats *pdev_stats;
+ wmi_vdev_stats *vdev_stats;
+ wmi_peer_stats *peer_stats;
+ WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
+ u_int8_t i, *temp;
+
+ WMA_LOGD("%s: Enter", __func__);
+ param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)cmd_param_info;
+ if (!param_buf)
+ return -1;
+
+ event = param_buf->fixed_param;
+ temp = (A_UINT8 *)param_buf->data;
+ if (event->num_pdev_stats > 0) {
+ for (i = 0; i < event->num_pdev_stats; i++) {
+ pdev_stats = (wmi_pdev_stats*)temp;
+ wma_update_pdev_stats(wma, pdev_stats);
+ temp += sizeof(wmi_pdev_stats);
+ }
+ }
+
+ if (event->num_vdev_stats > 0) {
+ for (i = 0; i < event->num_vdev_stats; i++) {
+ vdev_stats = (wmi_vdev_stats *)temp;
+ wma_update_vdev_stats(wma, vdev_stats);
+ temp += sizeof(wmi_vdev_stats);
+ }
+ }
+
+ if (event->num_peer_stats > 0) {
+ for (i = 0; i < event->num_peer_stats; i++) {
+ peer_stats = (wmi_peer_stats *)temp;
+ wma_update_peer_stats(wma, peer_stats);
+ temp += sizeof(wmi_peer_stats);
+ }
+ }
+
+ WMA_LOGD("%s: Exit", __func__);
+ return 0;
+}
+
#ifndef QCA_WIFI_ISOC
u_int8_t *wma_add_p2p_ie(u_int8_t *frm)
{
@@ -1601,10 +1900,182 @@ static int wma_tdls_event_handler(void *handle, u_int8_t *event, u_int32_t len)
#endif /* FEATURE_WLAN_TDLS */
/*
+ * WMI Handler for WMI_PHYERR_EVENTID event from firmware.
+ * This handler is currently handling only DFS phy errors.
+ * Return- 1:Success, 0:Failure
+ */
+static int wma_unified_phyerr_rx_event_handler(void * handle,
+ u_int8_t *data, u_int32_t datalen)
+{
+ tp_wma_handle wma = (tp_wma_handle) handle;
+ WMI_PHYERR_EVENTID_param_tlvs *param_tlvs;
+ wmi_comb_phyerr_rx_hdr *pe_hdr;
+ u_int8_t *bufp;
+ wmi_single_phyerr_rx_event *ev;
+ struct ieee80211com *ic = wma->dfs_ic;
+ adf_os_size_t n;
+ A_UINT64 tsf64 = 0;
+ int phy_err_code = 0;
+ int error = 0;
+ 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 %d, received %d",
+ __func__, sizeof(*pe_hdr), datalen);
+ 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);
+
+ /*
+ * 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=%d, hdr=%d 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=%d,"
+ "buf_len=%d, datalen=%d",
+ __func__,n,ev->hdr.buf_len,pe_hdr->buf_len);
+ error = 1;
+ break;
+ }
+ phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr);
+
+ /*
+ * If the phyerror category matches,
+ * pass radar events to the dfs pattern matching code.
+ * Don't pass radar events with no buffer payload.
+ */
+ if (phy_err_code == 0x5 || phy_err_code == 0x24)
+ {
+ 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);
+ }
+ }
+
+ /*
+ * 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);
+ }
+}
+
+/*
+ * WMI Handler for WMI_OFFLOAD_BCN_TX_STATUS_EVENTID event from firmware.
+ * This event is generated by FW when the beacon transmission is offloaded
+ * and the host performs beacon template modification using WMI_BCN_TMPL_CMDID
+ * The FW generates this event when the first successful beacon transmission
+ * after template update
+ * Return- 1:Success, 0:Failure
+ */
+static int wma_unified_bcntx_status_event_handler(void *handle, u_int8_t *cmd_param_info,
+ u_int32_t len)
+{
+ tp_wma_handle wma = (tp_wma_handle) handle;
+ WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf;
+ wmi_offload_bcn_tx_status_event_fixed_param *resp_event;
+ tSirFirstBeaconTxCompleteInd *beacon_tx_complete_ind;
+
+ param_buf = (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *) cmd_param_info;
+ if (!param_buf) {
+ WMA_LOGE("Invalid bcn tx response event buffer");
+ return -EINVAL;
+ }
+
+ beacon_tx_complete_ind = (tSirFirstBeaconTxCompleteInd *)
+ vos_mem_malloc(sizeof(tSirFirstBeaconTxCompleteInd));
+
+ resp_event = param_buf->fixed_param;
+
+ beacon_tx_complete_ind->messageType = WDA_DFS_BEACON_TX_SUCCESS_IND;
+ beacon_tx_complete_ind->length = sizeof(tSirFirstBeaconTxCompleteInd);
+ beacon_tx_complete_ind->bssIdx = resp_event->vdev_id;
+
+ wma_send_msg(wma, WDA_DFS_BEACON_TX_SUCCESS_IND, (void *)beacon_tx_complete_ind, 0);
+ return 0;
+}
+
+/*
* Allocate and init wmi adaptation layer.
*/
VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx,
wda_tgt_cfg_cb tgt_cfg_cb,
+ wda_dfs_radar_indication_cb radar_ind_cb,
tMacOpenParameters *mac_params)
{
tp_wma_handle wma_handle;
@@ -1612,6 +2083,7 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx,
adf_os_device_t adf_dev;
v_VOID_t *wmi_handle;
VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
+ struct ol_softc *scn;
WMA_LOGD("%s: Enter", __func__);
@@ -1662,13 +2134,27 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx,
goto err_wmi_attach;
}
+ /* Allocate dfs_ic and initialize DFS */
+ wma_handle->dfs_ic = wma_dfs_attach(wma_handle->dfs_ic);
+ if(wma_handle->dfs_ic == NULL) {
+ WMA_LOGP("Memory allocation failed for dfs_ic");
+ }
+
+ vos_wake_lock_init(&wma_handle->wow_wake_lock, "wow_wakelock");
+
#if defined(QCA_WIFI_FTM) && !defined(QCA_WIFI_ISOC)
if (vos_get_conparam() == VOS_FTM_MODE)
wma_utf_attach(wma_handle);
#endif
/*TODO: Recheck below parameters */
- mac_params->maxStation = WMA_MAX_SUPPORTED_STAS;
+ /*
+ * Increase maxStation by 1 here so that correct hashtable and
+ * gpLimPeerIdxpool memory is allocated in peCreateSession
+ */
+ scn = vos_get_context(VOS_MODULE_ID_HIF, vos_context);
+ mac_params->maxStation = ol_get_number_of_peers_supported(scn) + 1;
+
mac_params->maxBssId = WMA_MAX_SUPPORTED_BSS;
mac_params->frameTransRequired = 0;
@@ -1692,6 +2178,7 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx,
wma_unified_debug_print_event_handler);
wma_handle->tgt_cfg_update_cb = tgt_cfg_cb;
+ wma_handle->dfs_radar_indication_cb = radar_ind_cb;
#ifdef QCA_WIFI_ISOC
vos_status = vos_event_init(&wma_handle->cfg_nv_tx_complete);
@@ -1741,6 +2228,11 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx,
WMI_PEER_STA_KICKOUT_EVENTID,
wma_peer_sta_kickout_event_handler);
+ /* register for stats response event */
+ wmi_unified_register_event_handler(wma_handle->wmi_handle,
+ WMI_UPDATE_STATS_EVENTID,
+ wma_stats_event_handler);
+
#ifdef FEATURE_OEM_DATA_SUPPORT
wmi_unified_register_event_handler(wma_handle->wmi_handle,
WMI_OEM_CAPABILITY_EVENTID,
@@ -1754,6 +2246,17 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx,
WMI_OEM_ERROR_REPORT_EVENTID,
wma_oem_error_report_event_callback);
#endif
+ /*register phyerr event handler for handling DFS errors */
+ wmi_unified_register_event_handler(wma_handle->wmi_handle,
+ WMI_PHYERR_EVENTID,
+ wma_unified_phyerr_rx_event_handler);
+
+ /* Register beacon tx complete event id. The event is required
+ * for sending channel switch announcement frames
+ */
+ wmi_unified_register_event_handler(wma_handle->wmi_handle,
+ WMI_OFFLOAD_BCN_TX_STATUS_EVENTID,
+ wma_unified_bcntx_status_event_handler);
/* Firmware debug log */
vos_status = dbglog_init(wma_handle->wmi_handle);
@@ -1991,6 +2494,42 @@ static int wma_unified_vdev_delete_send(wmi_unified_t wmi_handle, u_int8_t if_id
return ret;
}
+void wma_vdev_detach_callback(void *ctx)
+{
+ tp_wma_handle wma;
+ struct wma_txrx_node *iface = (struct wma_txrx_node *)ctx;
+ tpDelStaSelfParams param;
+ struct wma_target_req *req_msg;
+
+ wma = vos_get_context(VOS_MODULE_ID_WDA,
+ vos_get_global_context(VOS_MODULE_ID_WDA, NULL));
+
+ if (!wma || !iface->del_staself_req) {
+ WMA_LOGP("%s: wma %p iface %p", __func__, wma,
+ iface->del_staself_req);
+ return;
+ }
+ param = (tpDelStaSelfParams) iface->del_staself_req;
+ WMA_LOGD("%s: sending WDA_DEL_STA_SELF_RSP for vdev %d",
+ __func__, param->sessionId);
+
+ req_msg = wma_find_vdev_req(wma, param->sessionId,
+ WMA_TARGET_REQ_TYPE_VDEV_DEL);
+ if (req_msg) {
+ WMA_LOGD("%s: Found vdev request for vdev id %d\n",
+ __func__, param->sessionId);
+ vos_timer_stop(&req_msg->event_timeout);
+ vos_timer_destroy(&req_msg->event_timeout);
+ adf_os_mem_free(req_msg);
+ }
+ if(iface->addBssStaContext)
+ adf_os_mem_free(iface->addBssStaContext);
+ vos_mem_zero(iface, sizeof(*iface));
+ param->status = VOS_STATUS_SUCCESS;
+
+ wma_send_msg(wma, WDA_DEL_STA_SELF_RSP, (void *)param, 0);
+}
+
/* function : wma_vdev_detach
* Descriptin :
* Args :
@@ -2001,15 +2540,15 @@ static VOS_STATUS wma_vdev_detach(tp_wma_handle wma_handle,
u_int8_t generateRsp)
{
VOS_STATUS status = VOS_STATUS_SUCCESS;
- void *txrx_hdl;
ol_txrx_peer_handle peer;
ol_txrx_pdev_handle pdev;
u_int8_t peer_id;
u_int8_t vdev_id = pdel_sta_self_req_param->sessionId;
+ struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
+ struct wma_target_req *msg;
- if ((wma_handle->interfaces[vdev_id].type == WMI_VDEV_TYPE_AP) &&
- ((wma_handle->interfaces[vdev_id].sub_type ==
- WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE))) {
+ if ((iface->type == WMI_VDEV_TYPE_AP) &&
+ (iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE)) {
WMA_LOGA("P2P Device: removing self peer %pM",
pdel_sta_self_req_param->selfMacAddr);
@@ -2026,34 +2565,53 @@ static VOS_STATUS wma_vdev_detach(tp_wma_handle wma_handle,
}
wma_remove_peer(wma_handle,
pdel_sta_self_req_param->selfMacAddr,
- pdel_sta_self_req_param->sessionId,
- peer);
+ vdev_id, peer);
+ }
+ if ((iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) &&
+ (iface->bss_status == WMA_BSS_STATUS_STARTED)) {
+ WMA_LOGD("P2P BSS is not yet stopped. Defering vdev deletion");
+ iface->del_staself_req = pdel_sta_self_req_param;
+ return status;
}
/* remove the interface from ath_dev */
- if (wma_unified_vdev_delete_send(wma_handle->wmi_handle,
- pdel_sta_self_req_param->sessionId)) {
+ if (wma_unified_vdev_delete_send(wma_handle->wmi_handle, vdev_id)) {
WMA_LOGP("Unable to remove an interface for ath_dev.\n");
status = VOS_STATUS_E_FAILURE;
+ goto out;
}
- txrx_hdl = wma_handle->interfaces[pdel_sta_self_req_param->sessionId].handle;
- if(!txrx_hdl)
+ if(!iface->handle) {
status = VOS_STATUS_E_FAILURE;
- else
- ol_txrx_vdev_detach(txrx_hdl, NULL, NULL);
- if(wma_handle->interfaces[pdel_sta_self_req_param->sessionId].addBssStaContext) {
- adf_os_mem_free(wma_handle->interfaces[pdel_sta_self_req_param->sessionId].addBssStaContext);
- }
- vos_mem_zero(&wma_handle->interfaces[pdel_sta_self_req_param->sessionId],
- sizeof(wma_handle->interfaces[pdel_sta_self_req_param->sessionId]));
+ WMA_LOGP("handle of vdev_id %d is NULL", vdev_id);
+ goto out;
+ }
- WMA_LOGA("vdev_id:%hu vdev_hdl:%p\n", pdel_sta_self_req_param->sessionId,
- txrx_hdl);
+ WMA_LOGA("vdev_id:%hu vdev_hdl:%p\n", vdev_id, iface->handle);
+ if (!generateRsp) {
+ WMA_LOGD("Call txrx detach w/o callback for vdev %d", vdev_id);
+ ol_txrx_vdev_detach(iface->handle, NULL, NULL);
+ goto out;
+ }
-#ifdef QCA_IBSS_SUPPORT
+ iface->del_staself_req = pdel_sta_self_req_param;
+ msg = wma_fill_vdev_req(wma_handle, vdev_id, WDA_DEL_STA_SELF_REQ,
+ WMA_TARGET_REQ_TYPE_VDEV_DEL, iface, 2000);
+ if (!msg) {
+ WMA_LOGP("%s: Failed to fill vdev request for vdev_id %d\n",
+ __func__, vdev_id);
+ status = VOS_STATUS_E_NOMEM;
+ goto out;
+ }
+ WMA_LOGD("Call txrx detach with callback for vdev %d", vdev_id);
+ ol_txrx_vdev_detach(iface->handle, wma_vdev_detach_callback, iface);
+ return status;
+out:
+ if(iface->addBssStaContext)
+ adf_os_mem_free(iface->addBssStaContext);
+ vos_mem_zero(iface, sizeof(*iface));
+ pdel_sta_self_req_param->status = status;
if (generateRsp)
-#endif
wma_send_msg(wma_handle, WDA_DEL_STA_SELF_RSP, (void *)pdel_sta_self_req_param, 0);
return status;
@@ -2422,21 +2980,13 @@ static ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle,
} else {
WMA_LOGE("Failed to get value for WNI_CFG_FRAGMENTATION_THRESHOLD, leaving unchanged");
}
- if (self_sta_req->type == WMI_VDEV_TYPE_STA &&
- mac->roam.configParam.isFastRoamIniFeatureEnabled) {
- /* Enable roaming offload
- * return value is not significant because some firmware versions may have
- * roam offload always enabled. It will stay enabled even if this command fails.
- */
- ret = wmi_unified_vdev_set_param_send(wma_handle->wmi_handle, self_sta_req->sessionId,
- WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, 1);
- if (ret) {
- /* could not enable roam offload in firmware. Disable it for host. */
- WMA_LOGE("Failed to set WMI_VDEV_PARAM_ROAM_FW_OFFLOAD");
- } else {
+ /* Initialize roaming offload state */
+ if (self_sta_req->type == WMI_VDEV_TYPE_STA) {
wma_handle->roam_offload_vdev_id = (A_UINT32) self_sta_req->sessionId;
+ wma_handle->roam_offload_enabled = TRUE;
+ wmi_unified_vdev_set_param_send(wma_handle->wmi_handle, wma_handle->roam_offload_vdev_id,
+ WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, 1);
}
- }
if (wlan_cfgGetInt(mac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED,
&cfg_val) == eSIR_SUCCESS) {
@@ -2638,21 +3188,21 @@ VOS_STATUS wma_get_buf_start_scan_cmd(tp_wma_handle wma_handle,
cmd->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION;
cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES;
- for (i = 0; i < wma_handle->max_bssid; i++) {
- if (wma_is_vdev_in_ap_mode(wma_handle, i))
- break;
- }
- if (i != wma_handle->max_bssid)
- cmd->burst_duration = scan_req->maxChannelTime *
- WMA_SCAN_AP_PRESENT_MAX_OFFCHANNEL_NUM;
+ if (scan_req->scanType == eSIR_PASSIVE_SCAN)
+ cmd->burst_duration = 0;
else {
- if (scan_req->scanType == eSIR_PASSIVE_SCAN)
- cmd->burst_duration = scan_req->maxChannelTime *
- WMA_SCAN_MAX_OFFCHANNEL_NUM_PASSIVE;
- else
- cmd->burst_duration = scan_req->maxChannelTime *
- WMA_SCAN_MAX_OFFCHANNEL_NUM_ACTIVE;
+ if (scan_req->channelList.numChannels <
+ WMA_BURST_SCAN_MAX_NUM_OFFCHANNELS) {
+ cmd->burst_duration =
+ scan_req->channelList.numChannels *
+ scan_req->maxChannelTime;
+ } else {
+ cmd->burst_duration =
+ WMA_BURST_SCAN_MAX_NUM_OFFCHANNELS *
+ scan_req->maxChannelTime;
+ }
}
+
if (!scan_req->p2pScanType) {
WMA_LOGD("Normal Scan request");
cmd->scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES;
@@ -2780,91 +3330,6 @@ error:
}
-/*AR9888/AR6320 noise floor approx value
- * similar to the mentioned the TLSHIM
- */
-#define WMA_TGT_NOISE_FLOOR_DBM (-96)
-/*
- * WMI event handler for periodic target stats event
- */
-
-static int wmi_unified_update_stats_event_handler(void* handle,
- u_int8_t *data, u_int32_t datalen)
-{
- wmi_stats_event_fixed_param *ev;
- A_UINT8 *temp;
- A_UINT8 i;
- WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
- tp_wma_handle wma = (tp_wma_handle) handle;
- A_UINT8 rssi = 0;
- tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq*)wma->pGetRssiReq;
- u_int8_t vdev_id = 0;
- wmi_vdev_stats *vdev_stats = NULL;
-
- if(NULL != pGetRssiReq)
- vdev_id = pGetRssiReq->sessionId;
- WMA_LOGD("%s: vdev_id %d\n", __func__, vdev_id);
- param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)data;
- if (!param_buf) {
- WMA_LOGE("%s: Received NULL buf ptr from FW", __func__);
- return VOS_STATUS_E_NOMEM;
- }
- ev = param_buf->fixed_param;
- if (NULL != param_buf->data)
- temp = (A_UINT8 *)param_buf->data;
- if (NULL != ev) {
- for (i = 0; i < ev->num_vdev_stats; i++) {
- if(NULL == temp )
- continue ;
- vdev_stats = (wmi_vdev_stats *)temp;
- if(NULL == vdev_stats)
- continue;
- WMA_LOGE("vdev id %d beancon snr %d data snr %d\n",
- vdev_stats->vdev_id, vdev_stats->vdev_snr.bcn_snr,
- vdev_stats->vdev_snr.dat_snr);
- /* if the data average rssi present return that,
- * else return beacon average rssi
- */
- if (vdev_stats->vdev_id == vdev_id) {
- if((vdev_stats->vdev_snr.dat_snr > 0) && (vdev_stats->vdev_snr.bcn_snr > 0))
- rssi = (vdev_stats->vdev_snr.dat_snr + vdev_stats->vdev_snr.bcn_snr)/2;
- else
- rssi = vdev_stats->vdev_snr.bcn_snr;
- /* Get the absolute rssi value from the current rssi value
- * the sinr value is hardcoded into 0 in the core stack
- */
- rssi = rssi + WMA_TGT_NOISE_FLOOR_DBM;
- WMA_LOGE("Average Rssi = %d, vdev id= %d",(int)rssi, vdev_id);
-
- /* update the average rssi value to UMAC layer */
- if ((NULL != pGetRssiReq) && (NULL != pGetRssiReq->rssiCallback)) {
- ((tCsrRssiCallback)(pGetRssiReq->rssiCallback))(rssi,pGetRssiReq->staId,
- pGetRssiReq->pDevContext);
- pGetRssiReq->rssiCallback = NULL;
- vos_mem_free(pGetRssiReq);
- wma->pGetRssiReq = NULL;
- }
- else {
- WMA_LOGE("WMA pGetRssiReq->rssiCallback is NULL");
- if (NULL != pGetRssiReq) {
- vos_mem_free(pGetRssiReq);
- wma->pGetRssiReq = NULL;
- }
- }
- break;
- }
-
- temp += sizeof(wmi_vdev_stats);
- }
- }
-
- return VOS_STATUS_SUCCESS;
-}
-
-
-/*
- * Return the data rssi for the given peer.
- */
VOS_STATUS wma_send_snr_request(tp_wma_handle wma_handle, void *pGetRssiReq)
{
wmi_buf_t buf;
@@ -3487,7 +3952,7 @@ v_VOID_t wma_roam_scan_fill_ap_profile(tp_wma_handle wma_handle, tpAniSirGlobal
ap_profile_p->rsn_ucastcipherset = WMI_CIPHER_NONE;
ap_profile_p->rsn_mcastcipherset = WMI_CIPHER_NONE;
ap_profile_p->rsn_mcastmgmtcipherset = WMI_CIPHER_NONE;
- ap_profile_p->rssi_threshold = 5;
+ ap_profile_p->rssi_threshold = WMA_ROAM_RSSI_DIFF_DEFAULT;
} else {
ap_profile_p->ssid.ssid_len = roam_req->ConnectedNetwork.ssId.length;
vos_mem_copy(ap_profile_p->ssid.ssid, roam_req->ConnectedNetwork.ssId.ssId,
@@ -3500,7 +3965,7 @@ v_VOID_t wma_roam_scan_fill_ap_profile(tp_wma_handle wma_handle, tpAniSirGlobal
ap_profile_p->rsn_mcastcipherset =
eCsrEncryptionType_to_rsn_cipherset(roam_req->ConnectedNetwork.mcencryption);
ap_profile_p->rsn_mcastmgmtcipherset = ap_profile_p->rsn_mcastcipherset;
- ap_profile_p->rssi_threshold = 5;
+ ap_profile_p->rssi_threshold = roam_req->RoamRssiDiff;
}
}
@@ -3513,32 +3978,62 @@ v_VOID_t wma_roam_scan_fill_ap_profile(tp_wma_handle wma_handle, tpAniSirGlobal
v_VOID_t wma_roam_scan_fill_scan_params(tp_wma_handle wma_handle, tpAniSirGlobal pMac,
tSirRoamOffloadScanReq *roam_req, wmi_start_scan_cmd_fixed_param *scan_params)
{
- vos_mem_zero(scan_params, sizeof(wmi_start_scan_cmd_fixed_param));
- if (roam_req != NULL) {
- /* Parameters updated after association is complete */
- scan_params->dwell_time_active = roam_req->NeighborScanChannelMinTime;
- scan_params->dwell_time_passive = roam_req->NeighborScanChannelMaxTime;
- scan_params->min_rest_time = 50;
- scan_params->max_rest_time = roam_req->NeighborScanTimerPeriod - scan_params->dwell_time_passive;
- scan_params->repeat_probe_time = roam_req->NeighborScanChannelMaxTime/3;
- scan_params->probe_spacing_time = 0;
- scan_params->probe_delay = 0;
- scan_params->max_scan_time = 50000; /* 50 seconds for full scan cycle */
- scan_params->idle_time = 200;
- scan_params->burst_duration = roam_req->NeighborScanChannelMaxTime;
- } else {
- /* roam_req = NULL during initial or pre-assoc invocation */
- scan_params->dwell_time_active = 100;
- scan_params->dwell_time_passive = 110;
- scan_params->min_rest_time = 50;
- scan_params->max_rest_time = 500;
- scan_params->repeat_probe_time = 50;
- scan_params->probe_spacing_time = 0;
- scan_params->probe_delay = 0;
- scan_params->max_scan_time = 50000;
- scan_params->idle_time = 200;
- scan_params->burst_duration = 110;
- }
+ tANI_U16 max_scan_time, min_scan_time, burst_duration;
+ tANI_U16 nprobes = 1;
+ vos_mem_zero(scan_params, sizeof(wmi_start_scan_cmd_fixed_param));
+ if (roam_req != NULL) {
+ /* Parameters updated after association is complete */
+ WMA_LOGI("%s: Input parameters: NeighborScanChannelMinTime = %d, NeighborScanChannelMaxTime = %d\n",
+ __func__, roam_req->NeighborScanChannelMinTime, roam_req->NeighborScanChannelMaxTime);
+ WMA_LOGI("%s: Input parameters: NeighborScanTimerPeriod = %d, HomeAwayTime = %d, nProbes = %d\n",
+ __func__, roam_req->NeighborScanTimerPeriod, roam_req->HomeAwayTime, roam_req->nProbes);
+ /* NeighborScanChannelMinTime = SETROAMSCANCHANNELMINTIME and gNeighborScanChannelMinTime */
+ if (roam_req->HomeAwayTime > (2 * WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME)) {
+ burst_duration = roam_req->HomeAwayTime - 2 * WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME;
+ max_scan_time = min(roam_req->NeighborScanChannelMaxTime, burst_duration);
+ } else {
+ burst_duration = max_scan_time = roam_req->NeighborScanChannelMaxTime;
+ }
+ /* ROME cld firmware have single value and not min, max
+ * therefore setting both values to same thing.
+ */
+ min_scan_time = max_scan_time;
+ nprobes = roam_req->nProbes;
+ scan_params->dwell_time_active = min_scan_time;
+
+ /* NeighborScanChannelMaxTime = SETSCANCHANNELTIME and gNeighborScanChannelMaxTime */
+ /* HomeAwayTime = SETSCANHOMEAWAYTIME and gRoamScanHomeAwayTime */
+ /* max_scan_time is for 1 channel, burst_duration is for total for all in a burst */
+ scan_params->dwell_time_passive = max_scan_time;
+
+ /* NeighborScanTimerPeriod = SETSCANHOMETIME and gNeighborScanTimerPeriod */
+ scan_params->min_rest_time = roam_req->NeighborScanTimerPeriod;
+ scan_params->max_rest_time = roam_req->NeighborScanTimerPeriod;
+ scan_params->repeat_probe_time = (nprobes > 0) ? scan_params->dwell_time_active / nprobes : 0;
+ scan_params->probe_spacing_time = 0;
+ scan_params->probe_delay = 0;
+ scan_params->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION; /* 30 seconds for full scan cycle */
+ scan_params->idle_time = scan_params->min_rest_time;
+ scan_params->burst_duration = burst_duration;
+ } else {
+ /* roam_req = NULL during initial or pre-assoc invocation */
+ scan_params->dwell_time_active = WMA_ROAM_DWELL_TIME_ACTIVE_DEFAULT;
+ scan_params->dwell_time_passive = WMA_ROAM_DWELL_TIME_PASSIVE_DEFAULT;
+ scan_params->min_rest_time = WMA_ROAM_MIN_REST_TIME_DEFAULT;
+ scan_params->max_rest_time = WMA_ROAM_MAX_REST_TIME_DEFAULT;
+ scan_params->repeat_probe_time = 0;
+ scan_params->probe_spacing_time = 0;
+ scan_params->probe_delay = 0;
+ scan_params->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION;
+ scan_params->idle_time = scan_params->min_rest_time;
+ scan_params->burst_duration = WMA_ROAM_DWELL_TIME_PASSIVE_DEFAULT;
+ }
+ WMA_LOGI("%s: Rome roam scan parameters: dwell_time_active = %d, dwell_time_passive = %d\n",
+ __func__, scan_params->dwell_time_active, scan_params->dwell_time_passive);
+ WMA_LOGI("%s: min_rest_time = %d, max_rest_time = %d, repeat_probe_time = %d\n",
+ __func__, scan_params->min_rest_time, scan_params->max_rest_time, scan_params->repeat_probe_time);
+ WMA_LOGI("%s: max_scan_time = %d, idle_time = %d, burst_duration = %d\n",
+ __func__, scan_params->max_scan_time, scan_params->idle_time, scan_params->burst_duration);
}
/* function : wma_roam_scan_offload_ap_profile
* Descriptin : Send WMI_ROAM_AP_PROFILE TLV to firmware
@@ -3614,22 +4109,16 @@ VOS_STATUS wma_roam_scan_offload_init_connect(tp_wma_handle wma_handle)
wmi_start_scan_cmd_fixed_param scan_params;
wmi_ap_profile ap_profile;
- if (!pMac) {
- return VOS_STATUS_SUCCESS;
- }
- if (!pMac->roam.configParam.isFastRoamIniFeatureEnabled) {
- /* Fast roaming is disabled */
- return VOS_STATUS_SUCCESS;
- }
/* first program the parameters to conservative values so that roaming scan won't be
* triggered before association completes
*/
/* rssi_thresh = 10 is low enough */
- vos_status = wma_roam_scan_offload_rssi_thresh(wma_handle, 10, 30);
+ vos_status = wma_roam_scan_offload_rssi_thresh(wma_handle, WMA_ROAM_LOW_RSSI_TRIGGER_VERYLOW,
+ WMA_ROAM_RSSI_THRESH_DIFF_DEFAULT);
vos_status = wma_roam_scan_offload_scan_period(wma_handle,
- 100000, 500000);
+ WMA_ROAM_OPP_SCAN_PERIOD_DEFAULT, WMA_ROAM_OPP_SCAN_AGING_PERIOD_DEFAULT);
vos_status = wma_roam_scan_offload_rssi_change(wma_handle,
- 15, 14);
+ WMA_ROAM_RSSI_CHANGE_RESCAN_DEFAULT, WMA_ROAM_BEACON_WEIGHT_DEFAULT);
wma_roam_scan_fill_ap_profile(wma_handle, pMac, NULL, &ap_profile);
vos_status = wma_roam_scan_offload_ap_profile(wma_handle, &ap_profile);
@@ -3652,15 +4141,14 @@ VOS_STATUS wma_roam_scan_offload_end_connect(tp_wma_handle wma_handle)
wma_handle->vos_context);
wmi_start_scan_cmd_fixed_param scan_params;
- if (!pMac->roam.configParam.isFastRoamIniFeatureEnabled) {
- /* Fast roaming is disabled */
- return VOS_STATUS_SUCCESS;
- }
+ /* If roam scan is running, stop it */
+ if (wma_handle->roam_offload_enabled) {
- wma_roam_scan_fill_scan_params(wma_handle, pMac, NULL, &scan_params);
- vos_status = wma_roam_scan_offload_mode(wma_handle, &scan_params,
- WMI_ROAM_SCAN_MODE_NONE);
- return vos_status;
+ wma_roam_scan_fill_scan_params(wma_handle, pMac, NULL, &scan_params);
+ vos_status = wma_roam_scan_offload_mode(wma_handle, &scan_params,
+ WMI_ROAM_SCAN_MODE_NONE);
+ }
+ return VOS_STATUS_SUCCESS;
}
/* function : wma_process_roam_scan_req
@@ -3676,53 +4164,55 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle,
wmi_ap_profile ap_profile;
tpAniSirGlobal pMac = (tpAniSirGlobal)vos_get_context(VOS_MODULE_ID_PE,
wma_handle->vos_context);
- A_INT32 noise_floor = WMI_DEFAULT_NOISE_FLOOR_DBM;
WMA_LOGI("%s: command 0x%x\n", __func__, roam_req->Command);
- if (!pMac->roam.configParam.isFastRoamIniFeatureEnabled) {
- /* Fast roaming is disabled */
- return VOS_STATUS_SUCCESS;
- }
+ if (!wma_handle->roam_offload_enabled) {
+ /* roam scan offload is not enabled in firmware.
+ * Cannot initialize it in the middle of connection.
+ */
+ return VOS_STATUS_E_PERM;
+ }
switch (roam_req->Command) {
case ROAM_SCAN_OFFLOAD_START:
/*
* Scan/Roam threshold parameters are translated from fields of tSirRoamOffloadScanReq
* to WMITLV values sent to Rome firmware.
- * some of these parameters are configurable in qcom_cfg.ini file.
+ * some of these parameters are configurable in qcom_cfg.ini file.
*/
- /* First parameter is positive rssi value to trigger rssi based scan.
- * Opportunistic scan is started at 30 dB higher that trigger rssi.
+ /* First parameter is positive rssi value to trigger rssi based scan.
+ * Opportunistic scan is started at 30 dB higher that trigger rssi.
*/
- vos_status = wma_roam_scan_offload_rssi_thresh(wma_handle,
- (roam_req->LookupThreshold - noise_floor),
- 30);
- if (vos_status != VOS_STATUS_SUCCESS) {
+ vos_status = wma_roam_scan_offload_rssi_thresh(wma_handle,
+ (roam_req->LookupThreshold - WMA_NOISE_FLOOR_DBM_DEFAULT),
+ WMA_ROAM_RSSI_THRESH_DIFF_DEFAULT);
+ if (vos_status != VOS_STATUS_SUCCESS) {
break;
}
- /* Opportunistic scan runs on a timer, value set by NeighborRoamScanRefreshPeriod.
- * Age out the entries after 3 such cycles.
- */
- vos_status = wma_roam_scan_offload_scan_period(wma_handle,
- roam_req->NeighborRoamScanRefreshPeriod,
- roam_req->NeighborRoamScanRefreshPeriod * 3);
- if (vos_status != VOS_STATUS_SUCCESS) {
+ /* Opportunistic scan runs on a timer, value set by NeighborRoamScanRefreshPeriod.
+ * Age out the entries after 3 such cycles.
+ */
+ vos_status = wma_roam_scan_offload_scan_period(wma_handle,
+ roam_req->NeighborRoamScanRefreshPeriod,
+ roam_req->NeighborRoamScanRefreshPeriod * 3);
+ if (vos_status != VOS_STATUS_SUCCESS) {
break;
}
- /* Start new rssi triggered scan only if it changes by RoamRssiDiff value.
- * Beacon weight of 14 means average rssi is taken over 14 previous samples +
- * 2 times the current beacon's rssi.
- */
- vos_status = wma_roam_scan_offload_rssi_change(wma_handle,
- roam_req->RoamRssiDiff, 14);
- if (vos_status != VOS_STATUS_SUCCESS) {
+ /* Start new rssi triggered scan only if it changes by RoamRssiDiff value.
+ * Beacon weight of 14 means average rssi is taken over 14 previous samples +
+ * 2 times the current beacon's rssi.
+ */
+ vos_status = wma_roam_scan_offload_rssi_change(wma_handle,
+ WMA_ROAM_RSSI_CHANGE_RESCAN_DEFAULT,
+ WMA_ROAM_BEACON_WEIGHT_DEFAULT);
+ if (vos_status != VOS_STATUS_SUCCESS) {
break;
}
wma_roam_scan_fill_ap_profile(wma_handle, pMac, roam_req, &ap_profile);
- vos_status = wma_roam_scan_offload_ap_profile(wma_handle,
- &ap_profile);
- if (vos_status != VOS_STATUS_SUCCESS) {
+ vos_status = wma_roam_scan_offload_ap_profile(wma_handle,
+ &ap_profile);
+ if (vos_status != VOS_STATUS_SUCCESS) {
break;
}
vos_status = wma_roam_scan_offload_chan_list(wma_handle,
@@ -3740,6 +4230,22 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle,
case ROAM_SCAN_OFFLOAD_STOP:
wma_roam_scan_offload_end_connect(wma_handle);
+ if (roam_req->StartScanReason == REASON_OS_REQUESTED_ROAMING_NOW) {
+ vos_msg_t vosMsg;
+ vosMsg.type = eWNI_SME_ROAM_SCAN_OFFLOAD_RSP;
+ vosMsg.bodyptr = NULL;
+ vosMsg.bodyval = roam_req->StartScanReason;
+ /*
+ * Since REASSOC request is processed in Roam_Scan_Offload_Rsp
+ * post a dummy rsp msg back to SME with proper reason code.
+ */
+ if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME,
+ (vos_msg_t*)&vosMsg))
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "Failed to post the rsp to UMAC" , __func__);
+ }
+ }
break;
case ROAM_SCAN_OFFLOAD_RESTART:
@@ -3747,6 +4253,17 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle,
break;
case ROAM_SCAN_OFFLOAD_UPDATE_CFG:
+ wma_roam_scan_fill_scan_params(wma_handle, pMac, roam_req, &scan_params);
+ vos_status = wma_roam_scan_offload_mode(wma_handle, &scan_params,
+ WMI_ROAM_SCAN_MODE_NONE);
+ if (vos_status != VOS_STATUS_SUCCESS) {
+ break;
+ }
+
+ if (roam_req->RoamScanOffloadEnabled == FALSE) {
+ break;
+ }
+
/*
* Runtime (after association) changes to rssi thresholds and other parameters.
*/
@@ -3756,20 +4273,40 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle,
if (vos_status != VOS_STATUS_SUCCESS) {
break;
}
- vos_status = wma_roam_scan_offload_rssi_thresh(wma_handle,
- (roam_req->LookupThreshold - noise_floor),
- 30);
- if (vos_status != VOS_STATUS_SUCCESS) {
+
+ vos_status = wma_roam_scan_offload_rssi_thresh(wma_handle,
+ (roam_req->LookupThreshold - WMA_NOISE_FLOOR_DBM_DEFAULT),
+ WMA_ROAM_RSSI_THRESH_DIFF_DEFAULT);
+ if (vos_status != VOS_STATUS_SUCCESS) {
+ break;
+ }
+
+ vos_status = wma_roam_scan_offload_scan_period(wma_handle,
+ roam_req->NeighborRoamScanRefreshPeriod,
+ roam_req->NeighborRoamScanRefreshPeriod * 3);
+ if (vos_status != VOS_STATUS_SUCCESS) {
break;
}
- vos_status = wma_roam_scan_offload_scan_period(wma_handle,
- roam_req->NeighborRoamScanRefreshPeriod,
- roam_req->NeighborRoamScanRefreshPeriod * 3);
- if (vos_status != VOS_STATUS_SUCCESS) {
+
+ vos_status = wma_roam_scan_offload_rssi_change(wma_handle,
+ WMA_ROAM_RSSI_CHANGE_RESCAN_DEFAULT,
+ WMA_ROAM_BEACON_WEIGHT_DEFAULT);
+ if (vos_status != VOS_STATUS_SUCCESS) {
break;
}
- vos_status = wma_roam_scan_offload_rssi_change(wma_handle,
- roam_req->RoamRssiDiff, 14);
+
+ wma_roam_scan_fill_ap_profile(wma_handle, pMac, roam_req, &ap_profile);
+ vos_status = wma_roam_scan_offload_ap_profile(wma_handle,
+ &ap_profile);
+ if (vos_status != VOS_STATUS_SUCCESS) {
+ break;
+ }
+
+ wma_roam_scan_fill_scan_params(wma_handle, pMac, roam_req, &scan_params);
+ vos_status = wma_roam_scan_offload_mode(wma_handle, &scan_params,
+ (WMI_ROAM_SCAN_MODE_PERIODIC
+ | WMI_ROAM_SCAN_MODE_RSSI_CHANGE));
+
break;
default:
@@ -4198,7 +4735,8 @@ static WLAN_PHY_MODE wma_chan_to_mode(u8 chan, ePhyChanBondState chan_offset,
if ((chan >= WMA_11G_CHANNEL_BEGIN) && (chan <= WMA_11G_CHANNEL_END)) {
switch (chan_offset) {
case PHY_SINGLE_CHANNEL_CENTERED:
- phymode = vht_capable ? MODE_11AC_VHT20 :MODE_11NG_HT20;
+ /* Configure MODE_11NG_HT20 for self vdev(for vht too) */
+ phymode = MODE_11NG_HT20;
break;
case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
@@ -4268,12 +4806,12 @@ tANI_U8 wma_getCenterChannel(tANI_U8 chan, tANI_U8 chan_offset)
}
static VOS_STATUS wma_vdev_start(tp_wma_handle wma,
- struct wma_vdev_start_req *req)
+ struct wma_vdev_start_req *req, v_BOOL_t isRestart)
{
wmi_vdev_start_request_cmd_fixed_param *cmd;
wmi_buf_t buf;
wmi_channel *chan;
- int32_t len;
+ int32_t len, ret;
WLAN_PHY_MODE chanmode;
u_int8_t *buf_ptr;
struct wma_txrx_node *intr = wma->interfaces;
@@ -4330,33 +4868,45 @@ static VOS_STATUS wma_vdev_start(tp_wma_handle wma,
* If that is ever the case we would insert the decision whether to
* enable the firmware flag here.
*/
- if (req->is_dfs) {
+
+ /*
+ * If the Channel is DFS,
+ * set the WMI_CHAN_FLAG_DFS flag
+ */
+ if (req->is_dfs) {
+ /* provide the current channel to DFS*/
+ wma->dfs_ic->ic_curchan =
+ wma_dfs_configure_channel(wma->dfs_ic,chan,chanmode,req);
WMI_SET_CHANNEL_FLAG(chan, WMI_CHAN_FLAG_DFS);
- cmd->disable_hw_ack = (req->oper_mode) ? 0 : 1;
+ cmd->disable_hw_ack = VOS_TRUE;
}
- cmd->beacon_interval = req->beacon_intval;
+ cmd->beacon_interval = req->beacon_intval;
cmd->dtim_period = req->dtim_period;
/* FIXME: Find out min, max and regulatory power levels */
WMI_SET_CHANNEL_REG_POWER(chan, req->max_txpow);
/* TODO: Handle regulatory class, max antenna */
+ if (!isRestart) {
+ cmd->beacon_interval = req->beacon_intval;
+ cmd->dtim_period = req->dtim_period;
+
+ /* Copy the SSID */
+ if (req->ssid.length) {
+ if (req->ssid.length < sizeof(cmd->ssid.ssid))
+ cmd->ssid.ssid_len = req->ssid.length;
+ else
+ cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid);
+ vos_mem_copy(cmd->ssid.ssid, req->ssid.ssId,
+ cmd->ssid.ssid_len);
+ }
- /* Copy the SSID */
- if (req->ssid.length) {
- if (req->ssid.length < sizeof(cmd->ssid.ssid))
- cmd->ssid.ssid_len = req->ssid.length;
- else
- cmd->ssid.ssid_len = sizeof(cmd->ssid.ssid);
- vos_mem_copy(cmd->ssid.ssid, req->ssid.ssId,
- cmd->ssid.ssid_len);
- }
-
- if (req->hidden_ssid)
- cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID;
+ if (req->hidden_ssid)
+ cmd->flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID;
- if (req->pmf_enabled)
- cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED;
+ if (req->pmf_enabled)
+ cmd->flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED;
+ }
cmd->num_noa_descriptors = 0;
buf_ptr = (u_int8_t *)(((u_int32_t) cmd) + sizeof(*cmd) +
@@ -4369,12 +4919,17 @@ static VOS_STATUS wma_vdev_start(tp_wma_handle wma,
chan->mhz, req->chan, chanmode, req->is_dfs,
req->beacon_intval, cmd->dtim_period, chan->band_center_freq1);
- if (wmi_unified_cmd_send(wma->wmi_handle, buf, len,
- WMI_VDEV_START_REQUEST_CMDID) < 0) {
- WMA_LOGP("Failed to send vdev start command\n");
- adf_nbuf_free(buf);
- return VOS_STATUS_E_FAILURE;
- }
+ if (isRestart)
+ ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+ WMI_VDEV_RESTART_REQUEST_CMDID);
+ else
+ ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+ WMI_VDEV_START_REQUEST_CMDID);
+ if (ret < 0) {
+ WMA_LOGP("Failed to send vdev start command\n");
+ adf_nbuf_free(buf);
+ return VOS_STATUS_E_FAILURE;
+ }
return VOS_STATUS_SUCCESS;
}
@@ -4394,18 +4949,25 @@ void wma_vdev_resp_timer(void *data)
wma = (tp_wma_handle) vos_get_context(VOS_MODULE_ID_WDA, vos_context);
pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context);
- WMA_LOGD("%s: request %d is timed out\n", __func__, tgt_req->msg_type);
+ WMA_LOGA("%s: request %d is timed out", __func__, tgt_req->msg_type);
wma_find_vdev_req(wma, tgt_req->vdev_id, tgt_req->type);
if (tgt_req->msg_type == WDA_CHNL_SWITCH_REQ) {
tpSwitchChannelParams params =
(tpSwitchChannelParams)tgt_req->user_data;
params->status = VOS_STATUS_E_TIMEOUT;
+ WMA_LOGA("%s: WDA_SWITCH_CHANNEL_REQ timedout", __func__);
wma_send_msg(wma, WDA_SWITCH_CHANNEL_RSP, (void *)params, 0);
} else if (tgt_req->msg_type == WDA_DELETE_BSS_REQ) {
tpDeleteBssParams params =
(tpDeleteBssParams)tgt_req->user_data;
+ struct wma_txrx_node *iface = &wma->interfaces[tgt_req->vdev_id];
peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, &peer_id);
wma_remove_peer(wma, params->bssid, tgt_req->vdev_id, peer);
+ wmi_unified_vdev_down_send(wma->wmi_handle, tgt_req->vdev_id);
+ if (iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) {
+ WMA_LOGD("%s: P2P BSS is stopped", __func__);
+ iface->bss_status = WMA_BSS_STATUS_STOPPED;
+ }
#ifdef QCA_IBSS_SUPPORT
if (wma_is_vdev_in_ibss_mode(wma, params->sessionId)) {
del_sta_param.sessionId = params->sessionId;
@@ -4415,7 +4977,25 @@ void wma_vdev_resp_timer(void *data)
}
#endif
params->status = VOS_STATUS_E_TIMEOUT;
+ WMA_LOGA("%s: WDA_DELETE_BSS_REQ timedout", __func__);
wma_send_msg(wma, WDA_DELETE_BSS_RSP, (void *)params, 0);
+ if (iface->del_staself_req) {
+ WMA_LOGD("%s: scheduling defered deletion", __func__);
+ wma_vdev_detach(wma, iface->del_staself_req, 1);
+ }
+ } else if (tgt_req->msg_type == WDA_DEL_STA_SELF_REQ) {
+ struct wma_txrx_node *iface =
+ (struct wma_txrx_node *)tgt_req->user_data;
+ tpDelStaSelfParams params =
+ (tpDelStaSelfParams)iface->del_staself_req;
+
+ params->status = VOS_STATUS_E_TIMEOUT;
+ WMA_LOGA("%s: WDA_DEL_STA_SELF_REQ timedout", __func__);
+ wma_send_msg(wma, WDA_DEL_STA_SELF_RSP,
+ (void *)iface->del_staself_req, 0);
+ if(iface->addBssStaContext)
+ adf_os_mem_free(iface->addBssStaContext);
+ vos_mem_zero(iface, sizeof(*iface));
}
vos_timer_destroy(&tgt_req->event_timeout);
vos_mem_free(tgt_req);
@@ -4423,7 +5003,7 @@ void wma_vdev_resp_timer(void *data)
static struct wma_target_req *wma_fill_vdev_req(tp_wma_handle wma, u_int8_t vdev_id,
u_int32_t msg_type, u_int8_t type,
- void *params)
+ void *params, u_int32_t timeout)
{
struct wma_target_req *req;
@@ -4441,7 +5021,7 @@ static struct wma_target_req *wma_fill_vdev_req(tp_wma_handle wma, u_int8_t vdev
req->user_data = params;
vos_timer_init(&req->event_timeout, VOS_TIMER_TYPE_SW,
wma_vdev_resp_timer, req);
- vos_timer_start(&req->event_timeout, 1000);
+ vos_timer_start(&req->event_timeout, timeout);
adf_os_spin_lock_bh(&wma->vdev_respq_lock);
list_add_tail(&req->node, &wma->vdev_resp_queue);
adf_os_spin_unlock_bh(&wma->vdev_respq_lock);
@@ -4476,7 +5056,7 @@ static void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params)
goto send_resp;
}
msg = wma_fill_vdev_req(wma, req.vdev_id, WDA_CHNL_SWITCH_REQ,
- WMA_TARGET_REQ_TYPE_VDEV_START, params);
+ WMA_TARGET_REQ_TYPE_VDEV_START, params, 1000);
if (!msg) {
WMA_LOGP("Failed to fill channel switch request for vdev %d\n",
req.vdev_id);
@@ -4492,8 +5072,9 @@ static void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params)
#endif
req.beacon_intval = 100;
req.dtim_period = 1;
- status = wma_vdev_start(wma, &req);
- if (status != VOS_STATUS_SUCCESS) {
+ req.is_dfs = params->isDfsChannel;
+ status = wma_vdev_start(wma, &req, VOS_TRUE);
+ if (status != VOS_STATUS_SUCCESS) {
wma_remove_vdev_req(wma, req.vdev_id, WMA_TARGET_REQ_TYPE_VDEV_START);
WMA_LOGP("vdev start failed status = %d\n", status);
goto send_resp;
@@ -4739,6 +5320,10 @@ static int32_t wmi_unified_send_peer_assoc(tp_wma_handle wma,
cmd->peer_vht_caps = params->vht_caps;
#endif
+
+ if (params->rmfEnabled)
+ cmd->peer_flags |= WMI_PEER_PMF;
+
rx_stbc = (params->ht_caps & IEEE80211_HTCAP_C_RXSTBC) >>
IEEE80211_HTCAP_C_RXSTBC_S;
if (rx_stbc) {
@@ -4965,6 +5550,14 @@ static int32_t wma_set_priv_cfg(tp_wma_handle wma_handle,
privcmd->param_vdev_id,
privcmd->param_value);
break;
+ case WMI_STA_SMPS_FORCE_MODE_CMDID:
+ wma_set_mimops(wma_handle, privcmd->param_vdev_id,
+ privcmd->param_value);
+ break;
+ case WMI_STA_SMPS_PARAM_CMDID:
+ wma_set_smps_params(wma_handle, privcmd->param_vdev_id,
+ privcmd->param_value);
+ break;
default:
WMA_LOGE("Invalid wma config command id:%d",
privcmd->param_id);
@@ -5003,13 +5596,49 @@ static int wmi_crash_inject(wmi_unified_t wmi_handle)
return ret;
}
+static int32_t wmi_unified_set_sta_ps_param(wmi_unified_t wmi_handle,
+ u_int32_t vdev_id, u_int32_t param, u_int32_t value)
+{
+ wmi_sta_powersave_param_cmd_fixed_param *cmd;
+ wmi_buf_t buf;
+ int32_t len = sizeof(*cmd);
+
+ WMA_LOGD("Set Sta Ps param vdevId %d Param %d val %d",
+ vdev_id, param, value);
+
+ buf = wmi_buf_alloc(wmi_handle, len);
+ if (!buf) {
+ WMA_LOGP("Set Sta Ps param Mem Alloc Failed");
+ return -ENOMEM;
+ }
+
+ cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf);
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ wmi_sta_powersave_param_cmd_fixed_param));
+ cmd->vdev_id = vdev_id;
+ cmd->param = param;
+ cmd->value = value;
+
+ if (wmi_unified_cmd_send(wmi_handle, buf, len,
+ WMI_STA_POWERSAVE_PARAM_CMDID)) {
+ WMA_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d",
+ vdev_id, param, value);
+ adf_nbuf_free(buf);
+ return -EIO;
+ }
+ return 0;
+}
+
static void wma_process_cli_set_cmd(tp_wma_handle wma,
wda_cli_set_cmd_t *privcmd)
{
- int ret = 0, vid = privcmd->param_vdev_id;
+ int ret = 0, vid = privcmd->param_vdev_id, pps_val = 0;
struct wma_txrx_node *intr = wma->interfaces;
tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context(VOS_MODULE_ID_PE,
wma->vos_context);
+ struct qpower_params *qparams = &intr[vid].config.qpower_params;
WMA_LOGD("wmihandle %p", wma->wmi_handle);
@@ -5151,6 +5780,137 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma,
break;
}
break;
+ case PPS_CMD:
+ WMA_LOGD("dbg pid %d pval %d", privcmd->param_id,
+ privcmd->param_value);
+ switch (privcmd->param_id) {
+
+ case WMI_VDEV_PPS_PAID_MATCH:
+ pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+ (PKT_PWR_SAVE_PAID_MATCH & 0xffff);
+ intr[vid].config.pps_params.paid_match_enable = privcmd->param_value;
+ break;
+ case WMI_VDEV_PPS_GID_MATCH:
+ pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+ (PKT_PWR_SAVE_GID_MATCH & 0xffff);
+ intr[vid].config.pps_params.gid_match_enable = privcmd->param_value;
+ break;
+ case WMI_VDEV_PPS_EARLY_TIM_CLEAR:
+ pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+ (PKT_PWR_SAVE_EARLY_TIM_CLEAR & 0xffff);
+ intr[vid].config.pps_params.tim_clear = privcmd->param_value;
+ break;
+ case WMI_VDEV_PPS_EARLY_DTIM_CLEAR:
+ pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+ (PKT_PWR_SAVE_EARLY_DTIM_CLEAR & 0xffff);
+ intr[vid].config.pps_params.dtim_clear = privcmd->param_value;
+ break;
+ case WMI_VDEV_PPS_EOF_PAD_DELIM:
+ pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+ (PKT_PWR_SAVE_EOF_PAD_DELIM & 0xffff);
+ intr[vid].config.pps_params.eof_delim = privcmd->param_value;
+ break;
+ case WMI_VDEV_PPS_MACADDR_MISMATCH:
+ pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+ (PKT_PWR_SAVE_MACADDR_MISMATCH & 0xffff);
+ intr[vid].config.pps_params.mac_match = privcmd->param_value;
+ break;
+ case WMI_VDEV_PPS_DELIM_CRC_FAIL:
+ pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+ (PKT_PWR_SAVE_DELIM_CRC_FAIL & 0xffff);
+ intr[vid].config.pps_params.delim_fail = privcmd->param_value;
+ break;
+ case WMI_VDEV_PPS_GID_NSTS_ZERO:
+ pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+ (PKT_PWR_SAVE_GID_NSTS_ZERO & 0xffff);
+ intr[vid].config.pps_params.nsts_zero = privcmd->param_value;
+ break;
+ case WMI_VDEV_PPS_RSSI_CHECK:
+ pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
+ (PKT_PWR_SAVE_RSSI_CHECK & 0xffff);
+ intr[vid].config.pps_params.rssi_chk = privcmd->param_value;
+ break;
+ default:
+ WMA_LOGE("Invalid param id 0x%x", privcmd->param_id);
+ break;
+ }
+ break;
+
+ case QPOWER_CMD:
+ WMA_LOGD("QPOWER CLI CMD pid %d pval %d", privcmd->param_id,
+ privcmd->param_value);
+ switch (privcmd->param_id) {
+ case WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT:
+ WMA_LOGD("QPOWER CLI CMD:Ps Poll Cnt val %d",
+ privcmd->param_value);
+ /* Set the QPower Ps Poll Count */
+ ret = wmi_unified_set_sta_ps_param(wma->wmi_handle,
+ vid,
+ WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
+ privcmd->param_value);
+ if (ret) {
+ WMA_LOGE("Set Q-PsPollCnt Failed vdevId %d val %d",
+ vid, privcmd->param_value);
+ } else {
+ qparams->max_ps_poll_cnt =
+ privcmd->param_value;
+ }
+ break;
+ case WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE:
+ WMA_LOGD("QPOWER CLI CMD:Max Tx Before wake val %d",
+ privcmd->param_value);
+ /* Set the QPower Max Tx Before Wake */
+ ret = wmi_unified_set_sta_ps_param(wma->wmi_handle,
+ vid,
+ WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
+ privcmd->param_value);
+ if (ret) {
+ WMA_LOGE("Set Q-MaxTxBefWake Failed vId %d val %d",
+ vid, privcmd->param_value);
+ } else {
+ qparams->max_tx_before_wake =
+ privcmd->param_value;
+ }
+ break;
+ case WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
+ WMA_LOGD("QPOWER CLI CMD:Ps Poll Wake Inv val %d",
+ privcmd->param_value);
+ /* Set the QPower Spec Ps Poll Wake Inv */
+ ret = wmi_unified_set_sta_ps_param(wma->wmi_handle,
+ vid,
+ WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
+ privcmd->param_value);
+ if (ret) {
+ WMA_LOGE("Set Q-PsPoll WakeIntv Failed vId %d val %d",
+ vid, privcmd->param_value);
+ } else {
+ qparams->spec_ps_poll_wake_interval =
+ privcmd->param_value;
+ }
+ break;
+ case WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
+ WMA_LOGD("QPOWER CLI CMD:Spec NoData Ps Poll val %d",
+ privcmd->param_value);
+ /* Set the QPower Spec NoData PsPoll */
+ ret = wmi_unified_set_sta_ps_param(wma->wmi_handle,
+ vid,
+ WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
+ privcmd->param_value);
+ if (ret) {
+ WMA_LOGE("Set Q-SpecNoDataPsPoll Failed vId %d val %d",
+ vid, privcmd->param_value);
+ } else {
+ qparams->max_spec_nodata_ps_poll =
+ privcmd->param_value;
+ }
+ break;
+
+ default:
+ WMA_LOGE("Invalid param id 0x%x", privcmd->param_id);
+ break;
+ }
+ break;
+
default:
WMA_LOGE("Invalid vpdev command id");
}
@@ -5180,33 +5940,6 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma,
case WMI_VDEV_PARAM_FIXED_RATE:
intr[vid].config.tx_rate = privcmd->param_value;
break;
- case WMI_VDEV_PPS_PAID_MATCH:
- intr[vid].config.pps_params.paid_match_enable = privcmd->param_value;
- break;
- case WMI_VDEV_PPS_GID_MATCH:
- intr[vid].config.pps_params.gid_match_enable = privcmd->param_value;
- break;
- case WMI_VDEV_PPS_EARLY_TIM_CLEAR:
- intr[vid].config.pps_params.tim_clear = privcmd->param_value;
- break;
- case WMI_VDEV_PPS_EARLY_DTIM_CLEAR:
- intr[vid].config.pps_params.dtim_clear = privcmd->param_value;
- break;
- case WMI_VDEV_PPS_EOF_PAD_DELIM:
- intr[vid].config.pps_params.eof_delim = privcmd->param_value;
- break;
- case WMI_VDEV_PPS_MACADDR_MISMATCH:
- intr[vid].config.pps_params.mac_match = privcmd->param_value;
- break;
- case WMI_VDEV_PPS_DELIM_CRC_FAIL:
- intr[vid].config.pps_params.delim_fail = privcmd->param_value;
- break;
- case WMI_VDEV_PPS_GID_NSTS_ZERO:
- intr[vid].config.pps_params.nsts_zero = privcmd->param_value;
- break;
- case WMI_VDEV_PPS_RSSI_CHECK:
- intr[vid].config.pps_params.rssi_chk = privcmd->param_value;
- break;
default:
WMA_LOGE("Invalid wda_cli_set vdev command/Not"
" yet implemented 0x%x", privcmd->param_id);
@@ -5238,6 +5971,17 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma,
case WMI_PDEV_PARAM_RX_CHAIN_MASK:
wma->pdevconfig.rxchainmask = privcmd->param_value;
break;
+ case WMI_PDEV_PARAM_BURST_ENABLE:
+ wma->pdevconfig.burst_enable = privcmd->param_value;
+ if ((wma->pdevconfig.burst_enable == 1) &&
+ (wma->pdevconfig.burst_dur == 0))
+ wma->pdevconfig.burst_dur = WMA_DEFAULT_SIFS_BURST_DURATION;
+ else if (wma->pdevconfig.burst_enable == 0)
+ wma->pdevconfig.burst_dur = 0;
+ break;
+ case WMI_PDEV_PARAM_BURST_DUR:
+ wma->pdevconfig.burst_dur = privcmd->param_value;
+ break;
case WMI_PDEV_PARAM_POWER_GATING_SLEEP:
wma->pdevconfig.pwrgating = privcmd->param_value;
break;
@@ -5278,6 +6022,15 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma,
" yet implemented 0x%x", privcmd->param_id);
break;
}
+ } else if (5 == privcmd->param_vp_dev) {
+ ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, privcmd->param_vdev_id,
+ WMI_VDEV_PARAM_PACKET_POWERSAVE,
+ pps_val);
+ if (ret)
+ WMA_LOGE("Failed to send wmi packet power save cmd");
+ else
+ WMA_LOGD("Sent packet power save cmd %d value %x to target",
+ privcmd->param_id, pps_val);
}
}
@@ -5318,33 +6071,7 @@ int wma_cli_get_command(void *wmapvosContext, int vdev_id,
case WMI_VDEV_PARAM_FIXED_RATE:
ret = intr[vdev_id].config.tx_rate;
break;
- case WMI_VDEV_PPS_PAID_MATCH:
- ret = intr[vdev_id].config.pps_params.paid_match_enable;
- break;
- case WMI_VDEV_PPS_GID_MATCH:
- ret = intr[vdev_id].config.pps_params.gid_match_enable;
- break;
- case WMI_VDEV_PPS_EARLY_TIM_CLEAR:
- ret = intr[vdev_id].config.pps_params.tim_clear;
- break;
- case WMI_VDEV_PPS_EARLY_DTIM_CLEAR:
- ret = intr[vdev_id].config.pps_params.dtim_clear;
- break;
- case WMI_VDEV_PPS_EOF_PAD_DELIM:
- ret = intr[vdev_id].config.pps_params.eof_delim;
- break;
- case WMI_VDEV_PPS_MACADDR_MISMATCH:
- ret = intr[vdev_id].config.pps_params.mac_match;
- break;
- case WMI_VDEV_PPS_DELIM_CRC_FAIL:
- ret = intr[vdev_id].config.pps_params.delim_fail;
- break;
- case WMI_VDEV_PPS_GID_NSTS_ZERO:
- ret = intr[vdev_id].config.pps_params.nsts_zero;
- break;
- case WMI_VDEV_PPS_RSSI_CHECK:
- ret = intr[vdev_id].config.pps_params.rssi_chk;
- break;
+
default:
WMA_LOGE("Invalid cli_get vdev command/Not"
" yet implemented 0x%x", param_id);
@@ -5385,6 +6112,12 @@ int wma_cli_get_command(void *wmapvosContext, int vdev_id,
case WMI_PDEV_PARAM_POWER_GATING_SLEEP:
ret = wma->pdevconfig.pwrgating;
break;
+ case WMI_PDEV_PARAM_BURST_ENABLE:
+ ret = wma->pdevconfig.burst_enable;
+ break;
+ case WMI_PDEV_PARAM_BURST_DUR:
+ ret = wma->pdevconfig.burst_dur;
+ break;
default:
WMA_LOGE("Invalid cli_get pdev command/Not"
" yet implemented 0x%x", param_id);
@@ -5403,43 +6136,66 @@ int wma_cli_get_command(void *wmapvosContext, int vdev_id,
" yet implemented 0x%x", param_id);
return -EINVAL;
}
- }
- return ret;
-}
-
-static int32_t wmi_unified_set_sta_ps_param(wmi_unified_t wmi_handle,
- u_int32_t vdev_id, u_int32_t param, u_int32_t value)
-{
- wmi_sta_powersave_param_cmd_fixed_param *cmd;
- wmi_buf_t buf;
- int32_t len = sizeof(*cmd);
+ } else if (PPS_CMD == vpdev) {
+ switch (param_id) {
+ case WMI_VDEV_PPS_PAID_MATCH:
+ ret = intr[vdev_id].config.pps_params.paid_match_enable;
+ break;
+ case WMI_VDEV_PPS_GID_MATCH:
+ ret = intr[vdev_id].config.pps_params.gid_match_enable;
+ break;
+ case WMI_VDEV_PPS_EARLY_TIM_CLEAR:
+ ret = intr[vdev_id].config.pps_params.tim_clear;
+ break;
+ case WMI_VDEV_PPS_EARLY_DTIM_CLEAR:
+ ret = intr[vdev_id].config.pps_params.dtim_clear;
+ break;
+ case WMI_VDEV_PPS_EOF_PAD_DELIM:
+ ret = intr[vdev_id].config.pps_params.eof_delim;
+ break;
+ case WMI_VDEV_PPS_MACADDR_MISMATCH:
+ ret = intr[vdev_id].config.pps_params.mac_match;
+ break;
+ case WMI_VDEV_PPS_DELIM_CRC_FAIL:
+ ret = intr[vdev_id].config.pps_params.delim_fail;
+ break;
+ case WMI_VDEV_PPS_GID_NSTS_ZERO:
+ ret = intr[vdev_id].config.pps_params.nsts_zero;
+ break;
+ case WMI_VDEV_PPS_RSSI_CHECK:
+ ret = intr[vdev_id].config.pps_params.rssi_chk;
+ break;
+ default:
+ WMA_LOGE("Invalid pps vdev command/Not"
+ " yet implemented 0x%x", param_id);
+ return -EINVAL;
+ }
+ } else if (QPOWER_CMD == vpdev) {
+ switch (param_id) {
+ case WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT:
+ ret = intr[vdev_id].config.qpower_params.max_ps_poll_cnt;
+ break;
- WMA_LOGD("Set Sta Ps param vdevId %d Param %d val %d",
- vdev_id, param, value);
+ case WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE:
+ ret = intr[vdev_id].config.qpower_params.max_tx_before_wake;
+ break;
- buf = wmi_buf_alloc(wmi_handle, len);
- if (!buf) {
- WMA_LOGP("Set Sta Ps param Mem Alloc Failed");
- return -ENOMEM;
- }
+ case WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
+ ret =
+ intr[vdev_id].config.qpower_params.spec_ps_poll_wake_interval;
+ break;
- cmd = (wmi_sta_powersave_param_cmd_fixed_param *) wmi_buf_data(buf);
- WMITLV_SET_HDR(&cmd->tlv_header,
- WMITLV_TAG_STRUC_wmi_sta_powersave_param_cmd_fixed_param,
- WMITLV_GET_STRUCT_TLVLEN(
- wmi_sta_powersave_param_cmd_fixed_param));
- cmd->vdev_id = vdev_id;
- cmd->param = param;
- cmd->value = value;
+ case WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
+ ret = intr[vdev_id].config.qpower_params.max_spec_nodata_ps_poll;
+ break;
- if (wmi_unified_cmd_send(wmi_handle, buf, len,
- WMI_STA_POWERSAVE_PARAM_CMDID)) {
- WMA_LOGE("Set Sta Ps param Failed vdevId %d Param %d val %d",
- vdev_id, param, value);
- adf_nbuf_free(buf);
- return -EIO;
+ default:
+ WMA_LOGE("Invalid generic vdev command/Not"
+ " yet implemented 0x%x", param_id);
+ return -EINVAL;
+ }
}
- return 0;
+ return ret;
}
static void
@@ -5618,7 +6374,7 @@ static void wma_add_bss_ap_mode(tp_wma_handle wma, tpAddBssParams add_bss)
goto send_fail_resp;
}
msg = wma_fill_vdev_req(wma, vdev_id, WDA_ADD_BSS_REQ,
- WMA_TARGET_REQ_TYPE_VDEV_START, add_bss);
+ WMA_TARGET_REQ_TYPE_VDEV_START, add_bss, 1000);
if (!msg) {
WMA_LOGP("%s Failed to allocate vdev request vdev_id %d\n",
__func__, vdev_id);
@@ -5649,14 +6405,13 @@ static void wma_add_bss_ap_mode(tp_wma_handle wma, tpAddBssParams add_bss)
vos_mem_copy(req.ssid.ssId, add_bss->ssId.ssId,
add_bss->ssId.length);
- status = wma_vdev_start(wma, &req);
+ status = wma_vdev_start(wma, &req, VOS_FALSE);
if (status != VOS_STATUS_SUCCESS) {
wma_remove_vdev_req(wma, vdev_id,
WMA_TARGET_REQ_TYPE_VDEV_START);
goto peer_cleanup;
}
- /* Configure rest of bss info once the vdev started */
wma_vdev_set_bss_params(wma, vdev_id,
add_bss->beaconInterval, add_bss->dtimPeriod,
add_bss->shortSlotTimeSupported, add_bss->llbCoexist,
@@ -5714,7 +6469,7 @@ static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss)
/* create new vdev for ibss */
vos_copy_macaddr((v_MACADDR_t *)&(add_sta_self_param.selfMacAddr),
- (v_MACADDR_t *)&(add_bss->bssId));
+ (v_MACADDR_t *)&(add_bss->selfMacAddr));
add_sta_self_param.sessionId = vdev_id;
add_sta_self_param.type = WMI_VDEV_TYPE_IBSS;
add_sta_self_param.subType = 0;
@@ -5731,17 +6486,17 @@ static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss)
WMA_LOGE("%s: new vdev created for IBSS\n", __func__);
/* create self peer */
- status = wma_create_peer(wma, pdev, vdev, add_bss->bssId,
+ status = wma_create_peer(wma, pdev, vdev, add_bss->selfMacAddr,
WMI_PEER_TYPE_DEFAULT, vdev_id);
if (status != VOS_STATUS_SUCCESS) {
WMA_LOGE("%s: Failed to create peer\n", __func__);
goto send_fail_resp;
}
- peer = ol_txrx_find_peer_by_addr(pdev, add_bss->bssId, &peer_id);
+ peer = ol_txrx_find_peer_by_addr(pdev, add_bss->selfMacAddr, &peer_id);
if (!peer) {
WMA_LOGE("%s Failed to find peer %pM\n", __func__,
- add_bss->bssId);
+ add_bss->selfMacAddr);
goto send_fail_resp;
}
@@ -5749,7 +6504,7 @@ static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss)
add_bss->operMode = BSS_OPERATIONAL_MODE_IBSS;
msg = wma_fill_vdev_req(wma, vdev_id, WDA_ADD_BSS_REQ,
- WMA_TARGET_REQ_TYPE_VDEV_START, add_bss);
+ WMA_TARGET_REQ_TYPE_VDEV_START, add_bss, 1000);
if (!msg) {
WMA_LOGP("%s Failed to allocate vdev request vdev_id %d\n",
__func__, vdev_id);
@@ -5782,7 +6537,7 @@ static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss)
WMA_LOGD("%s: chan %d chan_offset %d\n", __func__, req.chan, req.chan_offset);
WMA_LOGD("%s: ssid = %s\n", __func__, req.ssid.ssId);
- status = wma_vdev_start(wma, &req);
+ status = wma_vdev_start(wma, &req, VOS_FALSE);
if (status != VOS_STATUS_SUCCESS) {
wma_remove_vdev_req(wma, vdev_id,
WMA_TARGET_REQ_TYPE_VDEV_START);
@@ -5833,6 +6588,8 @@ static void wma_add_bss_sta_mode(tp_wma_handle wma, tpAddBssParams add_bss)
}
adf_os_mem_copy(iface->addBssStaContext, &add_bss->staContext,
sizeof(tAddStaParams));
+ // Save parameters later needed by WDA_ADD_STA_REQ
+ iface->rmfEnabled = add_bss->rmfEnabled;
iface->beaconInterval = add_bss->beaconInterval;
iface->dtimPeriod = add_bss->dtimPeriod;
iface->llbCoexist = add_bss->llbCoexist;
@@ -5846,7 +6603,8 @@ static void wma_add_bss_sta_mode(tp_wma_handle wma, tpAddBssParams add_bss)
goto send_fail_resp;
}
msg = wma_fill_vdev_req(wma, vdev_id, WDA_ADD_BSS_REQ,
- WMA_TARGET_REQ_TYPE_VDEV_START, add_bss);
+ WMA_TARGET_REQ_TYPE_VDEV_START,
+ add_bss, 1000);
if (!msg) {
WMA_LOGP("%s Failed to allocate vdev request vdev_id %d\n",
__func__, vdev_id);
@@ -5876,7 +6634,7 @@ static void wma_add_bss_sta_mode(tp_wma_handle wma, tpAddBssParams add_bss)
vos_mem_copy(req.ssid.ssId, add_bss->ssId.ssId,
add_bss->ssId.length);
- status = wma_vdev_start(wma, &req);
+ status = wma_vdev_start(wma, &req, VOS_FALSE);
if (status != VOS_STATUS_SUCCESS) {
wma_remove_vdev_req(wma, vdev_id,
WMA_TARGET_REQ_TYPE_VDEV_START);
@@ -5979,7 +6737,7 @@ static int wmi_unified_vdev_up_send(wmi_unified_t wmi,
wmi_buf_t buf;
int32_t len = sizeof(*cmd);
- printk("%s: VDEV_UP\n", __func__);
+ WMA_LOGD("%s: VDEV_UP\n", __func__);
WMA_LOGD("%s: vdev_id %d aid %d bssid %pM\n", __func__,
vdev_id, aid, bssid);
buf = wmi_buf_alloc(wmi, len);
@@ -6259,6 +7017,95 @@ static int wmi_unified_csa_offload_enable(tp_wma_handle wma,
return 0;
}
+#ifndef CONFIG_QCA_WIFI_ISOC
+#ifdef QCA_IBSS_SUPPORT
+
+static u_int16_t wma_calc_ibss_heart_beat_timer(int16_t peer_num)
+{
+ /* heart beat timer value look-up table */
+ /* entry index : (the number of currently connected peers) - 1
+ entry value : the heart time threshold value in seconds for
+ detecting ibss peer departure */
+ static const u_int16_t heart_beat_timer[HDD_MAX_NUM_IBSS_STA] = {
+ 4, 8, 12, 16, 20, 24, 28, 32,
+ 36, 40, 44, 48, 52, 56, 60, 64,
+ 68, 72, 76, 80, 84, 88, 92, 96,
+ 100, 104, 108, 112, 116, 120, 124, 128};
+
+ if (peer_num < 1 || peer_num > HDD_MAX_NUM_IBSS_STA)
+ return 0;
+
+ return heart_beat_timer[peer_num - 1];
+
+}
+
+static void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma,
+ u_int8_t vdev_id,
+ int8_t peer_num_delta)
+{
+ ol_txrx_vdev_handle vdev;
+ int16_t new_peer_num;
+ u_int16_t new_timer_value_sec;
+ u_int32_t new_timer_value_ms;
+
+ if (peer_num_delta != 1 && peer_num_delta != -1) {
+ WMA_LOGE("Invalid peer_num_delta value %d", peer_num_delta);
+ return;
+ }
+
+ vdev = wma_find_vdev_by_id(wma, vdev_id);
+ if (!vdev) {
+ WMA_LOGE("vdev not found : vdev_id %d", vdev_id);
+ return;
+ }
+
+ new_peer_num = vdev->ibss_peer_num + peer_num_delta;
+ if (new_peer_num > HDD_MAX_NUM_IBSS_STA || new_peer_num < 0) {
+ WMA_LOGE("new peer num %d out of valid boundary", new_peer_num);
+ return;
+ }
+
+ /* adjust peer numbers */
+ vdev->ibss_peer_num = new_peer_num;
+
+ /* reset timer value if all peers departed */
+ if (new_peer_num == 0) {
+ vdev->ibss_peer_heart_beat_timer = 0;
+ return;
+ }
+
+ /* calculate new timer value */
+ new_timer_value_sec = wma_calc_ibss_heart_beat_timer(new_peer_num);
+ if (new_timer_value_sec == 0) {
+ WMA_LOGE("timer value %d is invalid for peer number %d",
+ new_timer_value_sec, new_peer_num);
+ return;
+ }
+ if (new_timer_value_sec == vdev->ibss_peer_heart_beat_timer) {
+ WMA_LOGD("timer value %d stays same, no need to notify target",
+ new_timer_value_sec);
+ return;
+ }
+
+ /* send new timer value to target */
+ vdev->ibss_peer_heart_beat_timer = new_timer_value_sec;
+
+ new_timer_value_ms = ((u_int32_t)new_timer_value_sec) * 1000;
+
+ if (wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id,
+ WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS,
+ new_timer_value_ms)) {
+ WMA_LOGE("Failed to set IBSS link monitoring timer value");
+ return;
+ }
+
+ WMA_LOGD("Set IBSS link monitor timer: peer_num = %d timer_value = %d",
+ new_peer_num, new_timer_value_ms);
+}
+
+#endif /* QCA_IBSS_SUPPORT */
+#endif /* CONFIG_QCA_WIFI_ISOC */
+
#ifdef FEATURE_WLAN_TDLS
static void wma_add_tdls_sta(tp_wma_handle wma, tpAddStaParams add_sta)
{
@@ -6447,6 +7294,10 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params)
status = VOS_STATUS_E_FAILURE;
}
+ if (iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) {
+ WMA_LOGD("%s: P2P BSS is started", __func__);
+ iface->bss_status = WMA_BSS_STATUS_STARTED;
+ }
/* Sta is now associated, configure various params */
/* SM power save, configure the h/w as configured
@@ -6470,7 +7321,7 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params)
(params->htCapable || params->vhtCapable))
wma_set_ppsconfig(params->smesessionId,
WMA_VHT_PPS_DELIM_CRC_FAIL, 1);
-
+ iface->aid = params->assocId;
out:
params->status = status;
WMA_LOGD("%s: statype %d vdev_id %d aid %d bssid %pM staIdx %d status %d\n",
@@ -6507,6 +7358,15 @@ static void wma_add_sta(tp_wma_handle wma, tpAddStaParams add_sta)
wma_add_sta_req_ap_mode(wma, add_sta);
break;
}
+
+#ifndef CONFIG_QCA_WIFI_ISOC
+#ifdef QCA_IBSS_SUPPORT
+ /* adjust heart beat thresold timer value for detecting ibss peer departure */
+ if (oper_mode == BSS_OPERATIONAL_MODE_IBSS)
+ wma_adjust_ibss_heart_beat_timer(wma, add_sta->smesessionId, 1);
+#endif
+#endif
+
}
/*
@@ -6555,7 +7415,9 @@ static wmi_buf_t wma_setup_install_key_cmd(tp_wma_handle wma_handle,
wmi_buf_t buf;
u_int8_t *buf_ptr;
u_int8_t *key_data;
-
+#ifdef WLAN_FEATURE_11W
+ struct wma_txrx_node *iface = NULL;
+#endif /* WLAN_FEATURE_11W */
if ((key_params->key_type == eSIR_ED_NONE &&
key_params->key_len) || (key_params->key_type != eSIR_ED_NONE &&
!key_params->key_len)) {
@@ -6625,6 +7487,11 @@ static wmi_buf_t wma_setup_install_key_cmd(tp_wma_handle wma_handle,
case eSIR_ED_CCMP:
cmd->key_cipher = WMI_CIPHER_AES_CCM;
break;
+#ifdef WLAN_FEATURE_11W
+ case eSIR_ED_AES_128_CMAC:
+ cmd->key_cipher = WMI_CIPHER_AES_CMAC;
+ break;
+#endif /* WLAN_FEATURE_11W */
default:
/* TODO: MFP ? */
WMA_LOGE("%s:Invalid encryption type:%d", __func__, key_params->key_type);
@@ -6664,6 +7531,19 @@ static wmi_buf_t wma_setup_install_key_cmd(tp_wma_handle wma_handle,
#endif
cmd->key_len = key_params->key_len;
+#ifdef WLAN_FEATURE_11W
+ if (key_params->key_type == eSIR_ED_AES_128_CMAC)
+ {
+ iface = &wma_handle->interfaces[key_params->vdev_id];
+ if (iface) {
+ iface->key.key_length = key_params->key_len;
+ vos_mem_copy (iface->key.key,
+ (const void *) key_params->key_data,
+ iface->key.key_length);
+ }
+ }
+#endif /* WLAN_FEATURE_11W */
+
WMA_LOGD("Key setup : vdev_id %d key_idx %d key_type %d key_len %d"
" unicast %d peer_mac %pM def_key_idx %d", key_params->vdev_id,
key_params->key_idx, key_params->key_type, key_params->key_len,
@@ -6711,11 +7591,18 @@ static void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info)
vos_mem_copy(key_params.peer_mac,
wma_handle->interfaces[key_info->smesessionId].bssid,
ETH_ALEN);
+ }
+ else if (wlan_op_mode_ibss == txrx_vdev->opmode) {
+ /* vdev mac address will be passed for IBSS mode
+ ** Self Mac address is supposed to be in wma_handle->hwaddr
+ */
+ vos_mem_copy(key_params.peer_mac, wma_handle->hwaddr,
+ ETH_ALEN);
} else {
- /* vdev mac address will be passed for AP/IBSS mode */
+ /* vdev mac address will be passed for all other modes */
vos_mem_copy(key_params.peer_mac, txrx_vdev->mac_addr.raw,
ETH_ALEN);
- }
+ }
if (key_info->numKeys == 0 &&
(key_info->encType == eSIR_ED_WEP40 ||
@@ -6945,31 +7832,6 @@ out:
wma_send_msg(wma_handle, WDA_SET_STAKEY_RSP, (void *) key_info, 0);
}
-static int wmi_unified_vdev_down_send(wmi_unified_t wmi, u_int8_t vdev_id)
-{
- wmi_vdev_down_cmd_fixed_param *cmd;
- wmi_buf_t buf;
- int32_t len = sizeof(*cmd);
-
- buf = wmi_buf_alloc(wmi, len);
- if (!buf) {
- WMA_LOGP("%s : wmi_buf_alloc failed\n", __func__);
- return -ENOMEM;
- }
- cmd = (wmi_vdev_down_cmd_fixed_param *) wmi_buf_data(buf);
- WMITLV_SET_HDR(&cmd->tlv_header,
- WMITLV_TAG_STRUC_wmi_vdev_down_cmd_fixed_param,
- WMITLV_GET_STRUCT_TLVLEN(wmi_vdev_down_cmd_fixed_param));
- cmd->vdev_id = vdev_id;
- if (wmi_unified_cmd_send(wmi, buf, len, WMI_VDEV_DOWN_CMDID)) {
- WMA_LOGP("Failed to send vdev down\n");
- adf_nbuf_free(buf);
- return -EIO;
- }
- WMA_LOGD("%s: vdev_id %d\n", __func__, vdev_id);
- return 0;
-}
-
static void wma_delete_sta_req_ap_mode(tp_wma_handle wma,
tpDeleteStaParams del_sta)
{
@@ -7059,6 +7921,9 @@ static void wma_delete_sta_req_sta_mode(tp_wma_handle wma,
tpDeleteStaParams params)
{
VOS_STATUS status = VOS_STATUS_SUCCESS;
+ struct wma_txrx_node *iface;
+ iface = &wma->interfaces[params->smesessionId];
+ iface->uapsd_cached_val = 0;
#ifdef FEATURE_WLAN_TDLS
if (STA_ENTRY_TDLS_PEER == params->staType)
@@ -7068,11 +7933,6 @@ static void wma_delete_sta_req_sta_mode(tp_wma_handle wma,
}
#endif
wma_roam_scan_offload_end_connect(wma);
- if (wmi_unified_vdev_down_send(wma->wmi_handle, params->smesessionId) < 0) {
- WMA_LOGP("%s: failed to bring down vdev %d\n",
- __func__, params->smesessionId);
- status = VOS_STATUS_E_FAILURE;
- }
params->status = status;
WMA_LOGD("%s: vdev_id %d status %d\n", __func__, params->smesessionId, status);
wma_send_msg(wma, WDA_DELETE_STA_RSP, (void *)params, 0);
@@ -7103,6 +7963,15 @@ static void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta)
wma_delete_sta_req_ap_mode(wma, del_sta);
break;
}
+
+#ifndef CONFIG_QCA_WIFI_ISOC
+#ifdef QCA_IBSS_SUPPORT
+ /* adjust heart beat thresold timer value for detecting ibss peer departure */
+ if (oper_mode == BSS_OPERATIONAL_MODE_IBSS)
+ wma_adjust_ibss_heart_beat_timer(wma, del_sta->smesessionId, -1);
+#endif
+#endif
+
}
static int32_t wmi_unified_vdev_stop_send(wmi_unified_t wmi, u_int8_t vdev_id)
@@ -7158,12 +8027,18 @@ static void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params)
goto out;
}
+ /*Free the allocated stats response buffer for the the session*/
+ if (wma->interfaces[params->smesessionId].stats_rsp) {
+ vos_mem_free(wma->interfaces[params->smesessionId].stats_rsp);
+ wma->interfaces[params->smesessionId].stats_rsp = NULL;
+ }
+
if (wlan_op_mode_ibss == txrx_vdev->opmode) {
wma->ibss_started = 0;
}
msg = wma_fill_vdev_req(wma, params->smesessionId, WDA_DELETE_BSS_REQ,
- WMA_TARGET_REQ_TYPE_VDEV_STOP, params);
+ WMA_TARGET_REQ_TYPE_VDEV_STOP, params, 1000);
if (!msg) {
WMA_LOGP("%s: Failed to fill vdev request for vdev_id %d\n",
__func__, params->smesessionId);
@@ -7633,7 +8508,10 @@ static void wma_send_beacon(tp_wma_handle wma, tpSendbeaconParams bcn_info)
VOS_STATUS status;
#endif
u_int8_t *p2p_ie;
- vdev = wma_find_vdev_by_addr(wma, bcn_info->bssId, &vdev_id);
+ tpAniBeaconStruct beacon;
+
+ beacon = (tpAniBeaconStruct)(bcn_info->beacon);
+ vdev = wma_find_vdev_by_addr(wma, beacon->macHdr.sa, &vdev_id);
if (!vdev) {
WMA_LOGE("%s : failed to get vdev handle\n", __func__);
return;
@@ -7643,7 +8521,6 @@ static void wma_send_beacon(tp_wma_handle wma, tpSendbeaconParams bcn_info)
if (WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
WMI_SERVICE_BEACON_OFFLOAD)) {
WMA_LOGE("%s : Beacon Offload Enabled Sending Unified command", __func__);
-
if (wmi_unified_bcn_tmpl_send(wma, vdev_id, bcn_info, 4) < 0){
WMA_LOGE("%s : wmi_unified_bcn_tmpl_send Failed ", __func__);
return;
@@ -8107,15 +8984,26 @@ static void wma_enable_sta_ps_mode(tp_wma_handle wma, tpEnablePsParams ps_req)
}
} else if (eSIR_ADDON_ENABLE_UAPSD == ps_req->psSetting) {
u_int32_t uapsd_val = 0;
+ struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
uapsd_val = wma_get_uapsd_mask(&ps_req->uapsdParams);
- WMA_LOGD("Enable Uapsd vdevId %d Mask %d", vdev_id, uapsd_val);
- ret = wmi_unified_set_sta_ps_param(wma->wmi_handle, vdev_id,
- WMI_STA_PS_PARAM_UAPSD, uapsd_val);
- if (ret) {
- WMA_LOGE("Enable Uapsd Failed vdevId %d", vdev_id);
- ps_req->status = VOS_STATUS_E_FAILURE;
- goto resp;
+ if(uapsd_val != iface->uapsd_cached_val) {
+ WMA_LOGD("Enable Uapsd vdevId %d Mask %d",
+ vdev_id, uapsd_val);
+ ret = wmi_unified_set_sta_ps_param(wma->wmi_handle,
+ vdev_id, WMI_STA_PS_PARAM_UAPSD,
+ uapsd_val);
+ if (ret) {
+ WMA_LOGE("Enable Uapsd Failed vdevId %d",
+ vdev_id);
+ ps_req->status = VOS_STATUS_E_FAILURE;
+ goto resp;
+ }
+ /* Cache the Uapsd Mask */
+ iface->uapsd_cached_val = uapsd_val;
+ } else {
+ WMA_LOGD("Already Uapsd Enabled vdevId %d Mask %d",
+ vdev_id, uapsd_val);
}
WMA_LOGD("Enable Forced Sleep vdevId %d", vdev_id);
@@ -8285,7 +9173,7 @@ wmi_unified_set_sta_uapsd_auto_trig_cmd(
{
wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd;
int32_t ret;
- u_int32_t param_len = (num_ac - 1) *
+ u_int32_t param_len = num_ac *
sizeof(wmi_sta_uapsd_auto_trig_param);
u_int32_t cmd_len = sizeof(*cmd) + param_len + WMI_TLV_HDR_SIZE;
u_int32_t i;
@@ -8713,6 +9601,15 @@ static const u8 *wma_wow_wake_reason_str(A_INT32 wake_reason)
case WOW_REASON_WLAN_HB:
return "WLAN_HB";
#endif /* FEATURE_WLAN_LPHB */
+
+ case WOW_REASON_CSA_EVENT:
+ return "CSA_EVENT";
+ case WOW_REASON_PROBE_REQ_WPS_IE_RECV:
+ return "PROBE_REQ_RECV";
+ case WOW_REASON_AUTH_REQ_RECV:
+ return "AUTH_REQ_RECV";
+ case WOW_REASON_ASSOC_REQ_RECV:
+ return "ASSOC_REQ_RECV";
}
return "unknown";
}
@@ -8799,16 +9696,36 @@ static int wma_wow_wakeup_host_event(void *handle, u_int8_t *event,
wma_wow_wake_reason_str(wake_info->wake_reason),
wake_info->vdev_id);
- if(wake_info->wake_reason == WOW_REASON_AP_ASSOC_LOST)
+ if (wake_info->wake_reason == WOW_REASON_AUTH_REQ_RECV) {
+ WMA_LOGD("Holding 50 sec wake_lock");
+ vos_wake_lock_timeout_acquire(&wma->wow_wake_lock, 50000);
+ } else if (wake_info->wake_reason == WOW_REASON_ASSOC_REQ_RECV) {
+ WMA_LOGD("Holding 30 sec wake_lock");
+ vos_wake_lock_timeout_acquire(&wma->wow_wake_lock, 30000);
+ } else if (wake_info->wake_reason == WOW_REASON_DEAUTH_RECVD) {
+ WMA_LOGD("Holding 30 sec wake_lock");
+ vos_wake_lock_timeout_acquire(&wma->wow_wake_lock, 30000);
+ } else if (wake_info->wake_reason == WOW_REASON_DISASSOC_RECVD) {
+ WMA_LOGD("Holding 30 sec wake_lock");
+ vos_wake_lock_timeout_acquire(&wma->wow_wake_lock, 30000);
+ }
+
+ if(wake_info->wake_reason == WOW_REASON_AP_ASSOC_LOST) {
+ WMA_LOGA("Beacon miss indication on vdev %x",
+ wake_info->vdev_id);
wma_beacon_miss_handler(wma, wake_info->vdev_id);
-
+ }
+#ifdef FEATURE_WLAN_SCAN_PNO
if (wake_info->wake_reason == WOW_REASON_NLOD) {
node = &wma->interfaces[wake_info->vdev_id];
if (node) {
WMA_LOGD("NLO match happened");
node->nlo_match_evt_received = TRUE;
}
+ vos_wake_lock_timeout_acquire(&wma->pno_wake_lock,
+ WMA_PNO_WAKE_LOCK_TIMEOUT);
}
+#endif
if (wake_info->wake_reason == WOW_REASON_CSA_EVENT) {
WMI_CSA_HANDLING_EVENTID_param_tlvs param;
@@ -9065,6 +9982,9 @@ int wma_enable_wow_in_fw(WMA_HANDLE handle)
WMA_LOGD("WOW enabled successfully in fw");
+ HTCCancelDeferredTargetSleep(vos_get_context(VOS_MODULE_ID_HIF,
+ wma->vos_context));
+
wma->wow.wow_enable_cmd_sent = TRUE;
return VOS_STATUS_SUCCESS;
}
@@ -9131,99 +10051,22 @@ static VOS_STATUS wma_wow_usr(tp_wma_handle wma, u_int8_t vdev_id,
static VOS_STATUS wma_wow_ap(tp_wma_handle wma, u_int8_t vdev_id,
u_int8_t *enable_ptrn_match)
{
- u_int8_t unicast_ptrn[] = { 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x08 };
- u_int8_t unicst_mask[] = { 0x01, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x7f };
- u_int8_t unicst_offset = 0;
u_int8_t arp_ptrn[] = { 0x08, 0x06 };
u_int8_t arp_mask[] = { 0xff, 0xff };
u_int8_t arp_offset = 20;
- u_int8_t discvr_ptrn[] = { 0xe0, 0x00, 0x00, 0xf8 };
- u_int8_t discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
- u_int8_t discvr_offset = 38;
- u_int8_t dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ };
- u_int8_t dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ };
- u_int8_t dhcp_offset = 0, free_slot;
- VOS_STATUS ret = VOS_STATUS_SUCCESS;
-
- if (!wma->interfaces[vdev_id].vdev_up ||
- !WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
- WMI_SERVICE_BEACON_OFFLOAD)) {
- return ret;
- }
-
- free_slot = wma->wow.total_free_ptrn_id -
- wma->wow.used_free_ptrn_id + 1;
-
- if (free_slot < WMA_AP_WOW_DEFAULT_PTRN_MAX) {
- WMA_LOGD("Free slots are not enough, avail:%d, need: %d",
- free_slot, WMA_AP_WOW_DEFAULT_PTRN_MAX);
- WMA_LOGD("Ignoring default AP mode wow pattern for vdev : %d",
- vdev_id);
- return ret;
- }
-
- WMA_LOGD("Configuring default AP mode wow pattern for vdev %d",
- vdev_id);
-
- /* Setup unicast IP, EAPOL-like and ARP pkt pattern */
- ret = wma_send_wow_patterns_to_fw(wma, vdev_id,
- wma->wow.free_ptrn_id[wma->wow.used_free_ptrn_id++],
- unicast_ptrn, sizeof(unicast_ptrn),
- unicst_offset, unicst_mask, sizeof(unicst_mask));
- if (ret != VOS_STATUS_SUCCESS) {
- WMA_LOGE("Failed to add WOW unicast IP pattern");
- return ret;
- }
+ VOS_STATUS ret;
- /* Setup all ARP pkt pattern */
+ /* Setup all ARP pkt pattern. This is dummy pattern hence the lenght
+ is zero */
ret = wma_send_wow_patterns_to_fw(wma, vdev_id,
wma->wow.free_ptrn_id[wma->wow.used_free_ptrn_id++],
- arp_ptrn, sizeof(arp_ptrn), arp_offset,
- arp_mask, sizeof(arp_mask));
+ arp_ptrn, 0, arp_offset,
+ arp_mask, 0);
if (ret != VOS_STATUS_SUCCESS) {
WMA_LOGE("Failed to add WOW ARP pattern");
return ret;
}
- /*
- * Setup multicast pattern for mDNS 224.0.0.251,
- * SSDP 239.255.255.250 and LLMNR 224.0.0.252
- */
- ret = wma_send_wow_patterns_to_fw(wma, vdev_id,
- wma->wow.free_ptrn_id[wma->wow.used_free_ptrn_id++],
- discvr_ptrn, sizeof(discvr_ptrn), discvr_offset,
- discvr_mask, sizeof(discvr_mask));
- if (ret != VOS_STATUS_SUCCESS) {
- WMA_LOGE("Failed to add WOW mDNS/SSDP/LLMNR pattern");
- return ret;
- }
-
- /* Setup all DHCP broadcast pkt pattern */
- ret = wma_send_wow_patterns_to_fw(wma, vdev_id,
- wma->wow.free_ptrn_id[wma->wow.used_free_ptrn_id++],
- dhcp_pattern, sizeof(dhcp_pattern), dhcp_offset,
- dhcp_mask, sizeof(dhcp_mask));
- if (ret != VOS_STATUS_SUCCESS) {
- WMA_LOGE("Failed to add WOW DHCP broadcast pattern");
- return ret;
- }
-
*enable_ptrn_match = 1 << vdev_id;
return ret;
}
@@ -9360,12 +10203,14 @@ static bool wma_is_wow_prtn_cached(tp_wma_handle wma, u_int8_t vdev_id)
* Pushes wow patterns from local cache to FW and configures
* wakeup trigger events.
*/
-static VOS_STATUS wma_feed_wow_config_to_fw(tp_wma_handle wma)
+static VOS_STATUS wma_feed_wow_config_to_fw(tp_wma_handle wma,
+ v_BOOL_t pno_in_progress)
{
struct wma_txrx_node *iface;
VOS_STATUS ret = VOS_STATUS_SUCCESS;
u_int8_t ptrn_id, vdev_id;
u_int8_t enable_ptrn_match = 0;
+ v_BOOL_t ap_vdev_available = FALSE;
WMA_LOGD("Clearing already configured wow patterns in fw");
@@ -9386,14 +10231,17 @@ static VOS_STATUS wma_feed_wow_config_to_fw(tp_wma_handle wma)
if (!iface->handle ||
!iface->ptrn_match_enable ||
- (!wma_is_vdev_in_ap_mode(wma, vdev_id) &&
+ (!(wma_is_vdev_in_ap_mode(wma, vdev_id)|| wma_is_vdev_in_ibss_mode(wma, vdev_id)) &&
!iface->conn_state))
continue;
+ if (wma_is_vdev_in_ap_mode(wma, vdev_id) || wma_is_vdev_in_ibss_mode(wma, vdev_id))
+ ap_vdev_available = TRUE;
+
if (wma_is_wow_prtn_cached(wma, vdev_id)) {
/* Configure wow patterns provided by the user */
ret = wma_wow_usr(wma, vdev_id, &enable_ptrn_match);
- } else if (wma_is_vdev_in_ap_mode(wma, vdev_id)) {
+ } else if (wma_is_vdev_in_ap_mode(wma, vdev_id) ||wma_is_vdev_in_ibss_mode(wma, vdev_id)) {
/* Configure AP mode default wow patterns */
ret = wma_wow_ap(wma, vdev_id, &enable_ptrn_match);
} else {
@@ -9406,6 +10254,16 @@ static VOS_STATUS wma_feed_wow_config_to_fw(tp_wma_handle wma)
}
/*
+ * Configure csa ie wakeup event.
+ */
+ ret = wma_add_wow_wakeup_event(wma, WOW_CSA_IE_EVENT, TRUE);
+
+ if (ret != VOS_STATUS_SUCCESS)
+ return ret;
+
+ WMA_LOGD("CSA IE match is enabled in fw");
+
+ /*
* Configure pattern match wakeup event. FW does pattern match
* only if pattern match event is enabled.
*/
@@ -9467,6 +10325,46 @@ static VOS_STATUS wma_feed_wow_config_to_fw(tp_wma_handle wma)
wma->wow.gtk_err_enable ? "enabled" : "disabled");
}
#endif
+ /* Configure probe req based wakeup */
+ ret = wma_add_wow_wakeup_event(wma, WOW_PROBE_REQ_WPS_IE_EVENT,
+ ap_vdev_available);
+ if (ret != VOS_STATUS_SUCCESS) {
+ WMA_LOGE("Failed to configure probe req based wakeup");
+ } else {
+ WMA_LOGD("Probe req based wakeup is %s in fw",
+ ap_vdev_available ? "enabled" : "disabled");
+ }
+
+ /* Configure auth req based wakeup */
+ ret = wma_add_wow_wakeup_event(wma, WOW_AUTH_REQ_EVENT,
+ ap_vdev_available);
+ if (ret != VOS_STATUS_SUCCESS) {
+ WMA_LOGE("Failed to configure auth req based wakeup");
+ } else {
+ WMA_LOGD("Auth req based wakeup is %s in fw",
+ ap_vdev_available ? "enabled" : "disabled");
+ }
+
+ /* Configure assoc req based wakeup */
+ ret = wma_add_wow_wakeup_event(wma, WOW_ASSOC_REQ_EVENT,
+ ap_vdev_available);
+ if (ret != VOS_STATUS_SUCCESS) {
+ WMA_LOGE("Failed to configure assoc req based wakeup");
+ } else {
+ WMA_LOGD("Assoc req based wakeup is %s in fw",
+ ap_vdev_available ? "enabled" : "disabled");
+ }
+
+ /* Configure pno based wakeup */
+ ret = wma_add_wow_wakeup_event(wma, WOW_NLO_DETECTED_EVENT,
+ pno_in_progress);
+ if (ret != VOS_STATUS_SUCCESS) {
+ WMA_LOGE("Failed to configure pno based wakeup");
+ } else {
+ WMA_LOGD("PNO based wakeup is %s in fw",
+ pno_in_progress ? "enabled" : "disabled");
+ }
+
/* WOW is enabled in pcie suspend callback */
wma->wow.wow_enable = TRUE;
wma->wow.wow_enable_cmd_sent = FALSE;
@@ -9654,7 +10552,7 @@ static VOS_STATUS wma_suspend_req(tp_wma_handle wma, tpSirWlanSuspendParam info)
* 3) Is PNO in progress in any one of vdev ?
*/
for (i = 0; i < wma->max_bssid; i++) {
- if (wma_is_vdev_in_ap_mode(wma, i) &&
+ if ( (wma_is_vdev_in_ap_mode(wma, i) || wma_is_vdev_in_ibss_mode(wma, i)) &&
wma->interfaces[i].vdev_up &&
WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
WMI_SERVICE_BEACON_OFFLOAD)) {
@@ -9687,7 +10585,7 @@ enable_wow:
* At this point, suspend indication is received on
* last vdev. It's the time to enable wow in fw.
*/
- ret = wma_feed_wow_config_to_fw(wma);
+ ret = wma_feed_wow_config_to_fw(wma, pno_in_progress);
if (ret != VOS_STATUS_SUCCESS) {
vos_mem_free(info);
return ret;
@@ -9771,6 +10669,7 @@ static VOS_STATUS wma_resume_req(tp_wma_handle wma, tpSirWlanResumeParam info)
ret = wma_send_host_wakeup_ind_to_fw(wma);
vos_mem_free(info);
+ vos_wake_lock_timeout_acquire(&wma->wow_wake_lock, 2000);
return ret;
}
@@ -9787,6 +10686,58 @@ int wma_is_wow_mode_selected(WMA_HANDLE handle)
return wma->wow.wow_enable;
}
+tAniGetPEStatsRsp * wma_get_stats_rsp_buf(tAniGetPEStatsReq *get_stats_param)
+{
+ tAniGetPEStatsRsp *stats_rsp_params;
+ tANI_U32 len, temp_mask, counter = 0;
+
+ len= sizeof(tAniGetPEStatsRsp);
+ temp_mask = get_stats_param->statsMask;
+
+ while (temp_mask) {
+ if (temp_mask & 1) {
+ switch (counter) {
+ case eCsrSummaryStats:
+ len += sizeof(tCsrSummaryStatsInfo);
+ break;
+ case eCsrGlobalClassAStats:
+ len += sizeof(tCsrGlobalClassAStatsInfo);
+ break;
+ case eCsrGlobalClassBStats:
+ len += sizeof(tCsrGlobalClassBStatsInfo);
+ break;
+ case eCsrGlobalClassCStats:
+ len += sizeof(tCsrGlobalClassCStatsInfo);
+ break;
+ case eCsrGlobalClassDStats:
+ len += sizeof(tCsrGlobalClassDStatsInfo);
+ break;
+ case eCsrPerStaStats:
+ len += sizeof(tCsrPerStaStatsInfo);
+ break;
+ }
+ }
+
+ counter++;
+ temp_mask >>= 1;
+ }
+
+ stats_rsp_params = (tAniGetPEStatsRsp *)vos_mem_malloc(len);
+ if (!stats_rsp_params) {
+ WMA_LOGE("memory allocation failed for tAniGetPEStatsRsp");
+ VOS_ASSERT(0);
+ return NULL;
+ }
+
+ vos_mem_zero(stats_rsp_params, len);
+ stats_rsp_params->staId = get_stats_param->staId;
+ stats_rsp_params->statsMask = get_stats_param->statsMask;
+ stats_rsp_params->msgType = WDA_GET_STATISTICS_RSP;
+ stats_rsp_params->msgLen = len - sizeof(tAniGetPEStatsRsp);
+ stats_rsp_params->rc = eHAL_STATUS_SUCCESS;
+ return stats_rsp_params;
+}
+
/* function : wma_get_stats_req
* Description : return the statistics
* Args : wma handle, pointer to tAniGetPEStatsReq
@@ -9796,32 +10747,70 @@ static void wma_get_stats_req(WMA_HANDLE handle,
tAniGetPEStatsReq *get_stats_param)
{
tp_wma_handle wma_handle = (tp_wma_handle) handle;
+ struct wma_txrx_node *node;
+ wmi_buf_t buf;
+ wmi_request_stats_cmd_fixed_param *cmd;
tAniGetPEStatsRsp *pGetPEStatsRspParams;
+ u_int8_t len = sizeof(wmi_request_stats_cmd_fixed_param);
- if(get_stats_param)
- vos_mem_free(get_stats_param);
+ WMA_LOGD("%s: Enter", __func__);
+ node = &wma_handle->interfaces[get_stats_param->sessionId];
+ if (node->stats_rsp) {
+ pGetPEStatsRspParams = node->stats_rsp;
+ if (pGetPEStatsRspParams->staId == get_stats_param->staId &&
+ pGetPEStatsRspParams->statsMask ==
+ get_stats_param->statsMask) {
+ WMA_LOGI("Stats for staId %d with stats mask %d "
+ "is pending.... ignore new request",
+ get_stats_param->staId,
+ get_stats_param->statsMask);
+ goto end;
+ } else {
+ vos_mem_free(node->stats_rsp);
+ node->stats_rsp = NULL;
+ node->fw_stats_set = 0;
+ }
+ }
- pGetPEStatsRspParams =
- (tAniGetPEStatsRsp *)vos_mem_malloc(sizeof(tAniGetPEStatsRsp));
+ pGetPEStatsRspParams = wma_get_stats_rsp_buf(get_stats_param);
+ if (!pGetPEStatsRspParams)
+ goto end;
- if(!pGetPEStatsRspParams) {
- WMA_LOGE("%s: Memory Allocation Failure", __func__);
- return;
+ buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+ if (!buf) {
+ WMA_LOGE("%s: Failed to allocate wmi buffer", __func__);
+ goto failed;
}
- vos_mem_zero(pGetPEStatsRspParams, sizeof(tAniGetPEStatsRsp));
- pGetPEStatsRspParams->msgLen = sizeof(tAniGetPEStatsRsp);
+ node->fw_stats_set = 0;
+ node->stats_rsp = pGetPEStatsRspParams;
+ cmd = (wmi_request_stats_cmd_fixed_param *)wmi_buf_data(buf);
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(wmi_request_stats_cmd_fixed_param));
+ cmd->stats_id = WMI_REQUEST_PEER_STAT|WMI_REQUEST_PDEV_STAT|
+ WMI_REQUEST_VDEV_STAT;
+ cmd->vdev_id = get_stats_param->sessionId;
+ WMI_CHAR_ARRAY_TO_MAC_ADDR(node->bssid, &cmd->peer_macaddr);
+ WMA_LOGD("STATS REQ VDEV_ID:%d-->", cmd->vdev_id);
+ if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+ WMI_REQUEST_STATS_CMDID)) {
- /* TODO: As of now there is no WMI command to get the
- * statistics. If WMI command for getting stats is available,
- * then send the WMI command for getting the stats.
- * Return status as FAILURE for now */
- pGetPEStatsRspParams->rc = eHAL_STATUS_FAILURE;
+ vos_mem_free(buf);
+ goto failed;
+ }
+
+ goto end;
+failed:
+ pGetPEStatsRspParams->rc = eHAL_STATUS_FAILURE;
+ node->stats_rsp = NULL;
/* send response to UMAC*/
wma_send_msg(wma_handle, WDA_GET_STATISTICS_RSP, pGetPEStatsRspParams,
0) ;
-
+end:
+ vos_mem_free(get_stats_param);
+ WMA_LOGD("%s: Exit", __func__);
return;
}
@@ -10570,7 +11559,7 @@ static VOS_STATUS wma_enable_arp_ns_offload(tp_wma_handle wma, tpSirHostOffloadR
/* Fill data only for NS offload in the first ARP tuple for LA */
if (!bArpOnly &&
- (pHostOffloadParams->enableOrDisable == SIR_OFFLOAD_ENABLE && i==0)) {
+ ((pHostOffloadParams->enableOrDisable & SIR_OFFLOAD_ENABLE) && i==0)) {
ns_tuple->flags |= WMI_NSOFF_FLAGS_VALID;
/*Copy the target/solicitation/remote ip addr */
@@ -10608,7 +11597,7 @@ static VOS_STATUS wma_enable_arp_ns_offload(tp_wma_handle wma, tpSirHostOffloadR
WMITLV_GET_STRUCT_TLVLEN(WMI_ARP_OFFLOAD_TUPLE));
/* Fill data for ARP and NS in the first tupple for LA */
- if ((wma->mArpInfo.enableOrDisable == SIR_OFFLOAD_ENABLE) && (i==0)) {
+ if ((wma->mArpInfo.enableOrDisable & SIR_OFFLOAD_ENABLE) && (i==0)) {
/*Copy the target ip addr and flags*/
arp_tuple->flags = WMI_ARPOFF_FLAGS_VALID;
A_MEMCPY(&arp_tuple->target_ipaddr,wma->mArpInfo.params.hostIpv4Addr,
@@ -11956,7 +12945,7 @@ static int wma_roam_event_callback(WMA_HANDLE handle, u_int8_t *event_buf,
switch(wmi_event->reason) {
case WMI_ROAM_REASON_BMISS:
- WMA_LOGD("%s:Beacon Miss for vdevid %x",__func__,
+ WMA_LOGA("Beacon Miss for vdevid %x",
wmi_event->vdev_id);
wma_beacon_miss_handler(wma_handle, wmi_event->vdev_id);
break;
@@ -12241,7 +13230,8 @@ wma_batch_scan_result_event_handler
pHddApMetaInfo->ssid[0] = '\0';
}
pHddApMetaInfo->ch = network_info->ch;
- pHddApMetaInfo->rssi = network_info->rssi;
+ pHddApMetaInfo->rssi = ((network_info->rssi + 100) -
+ WMI_DEFAULT_NOISE_FLOOR_DBM);
pHddApMetaInfo->timestamp = network_info->timestamp;
WMA_LOGD("ch %d rssi %d timestamp %d",pHddApMetaInfo->ch,
@@ -12464,14 +13454,6 @@ VOS_STATUS wma_start(v_VOID_t *vos_ctx)
vos_status = VOS_STATUS_E_FAILURE;
goto end;
}
- /* register target stats event handler */
- status = wmi_unified_register_event_handler(wma_handle->wmi_handle, WMI_UPDATE_STATS_EVENTID,
- wmi_unified_update_stats_event_handler);
- if (status) {
- WMA_LOGP("Failed to register stats event handler");
- vos_status = VOS_STATUS_E_FAILURE;
- goto end;
- }
#ifdef FEATURE_WLAN_SCAN_PNO
if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
@@ -12573,6 +13555,10 @@ VOS_STATUS wma_start(v_VOID_t *vos_ctx)
goto end;
}
+#ifdef FEATURE_WLAN_SCAN_PNO
+ vos_wake_lock_init(&wma_handle->pno_wake_lock, "wlan_pno_wl");
+#endif
+
end:
WMA_LOGD("%s: Exit", __func__);
return vos_status;
@@ -12681,11 +13667,16 @@ VOS_STATUS wma_close(v_VOID_t *vos_ctx)
ptrn_id++)
wma_free_wow_ptrn(wma_handle, ptrn_id);
+#ifdef FEATURE_WLAN_SCAN_PNO
+ vos_wake_lock_destroy(&wma_handle->pno_wake_lock);
+#endif
/* unregister Firmware debug log */
vos_status = dbglog_deinit(wma_handle->wmi_handle);
if(vos_status != VOS_STATUS_SUCCESS)
WMA_LOGP("dbglog_deinit failed");
+
+ vos_wake_lock_destroy(&wma_handle->wow_wake_lock);
/* close the vos events */
vos_event_destroy(&wma_handle->wma_ready_event);
vos_event_destroy(&wma_handle->target_suspend);
@@ -12988,6 +13979,8 @@ static void wma_update_hdd_cfg(tp_wma_handle wma_handle)
hdd_tgt_cfg.band_cap = eCSR_BAND_ALL;
}
+ hdd_tgt_cfg.max_intf_count = wma_handle->wlan_resource_config.num_vdevs;
+
adf_os_mem_copy(hdd_tgt_cfg.hw_macaddr.bytes, wma_handle->hwaddr,
ATH_MAC_LEN);
@@ -13251,6 +14244,39 @@ v_VOID_t wma_rx_service_ready_event(WMA_HANDLE handle, void *cmd_param_info)
}
}
+static void wma_set_regdomain(a_uint32_t regdmn)
+{
+ void *vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL);
+ tp_wma_handle wma = vos_get_context(VOS_MODULE_ID_WDA, vos_context);
+ u_int32_t modeSelect = 0xFFFFFFFF;
+
+ /* Set DFS regulatory domain */
+ wma_set_dfs_regdomain(wma);
+
+ switch (wma->phy_capability) {
+ case WMI_11G_CAPABILITY:
+ case WMI_11NG_CAPABILITY:
+ modeSelect &= ~(REGDMN_MODE_11A | REGDMN_MODE_TURBO |
+ REGDMN_MODE_108A | REGDMN_MODE_11A_HALF_RATE |
+ REGDMN_MODE_11A_QUARTER_RATE | REGDMN_MODE_11NA_HT20 |
+ REGDMN_MODE_11NA_HT40PLUS | REGDMN_MODE_11NA_HT40MINUS |
+ REGDMN_MODE_11AC_VHT20 | REGDMN_MODE_11AC_VHT40PLUS |
+ REGDMN_MODE_11AC_VHT40MINUS | REGDMN_MODE_11AC_VHT80);
+ break;
+ case WMI_11A_CAPABILITY:
+ case WMI_11NA_CAPABILITY:
+ case WMI_11AC_CAPABILITY:
+ modeSelect &= ~(REGDMN_MODE_11B | REGDMN_MODE_11G |
+ REGDMN_MODE_108G | REGDMN_MODE_11NG_HT20 |
+ REGDMN_MODE_11NG_HT40PLUS | REGDMN_MODE_11NG_HT40MINUS |
+ REGDMN_MODE_11AC_VHT20_2G | REGDMN_MODE_11AC_VHT40_2G |
+ REGDMN_MODE_11AC_VHT80_2G);
+ break;
+ }
+
+ return;
+}
+
/* function : wma_rx_ready_event
* Descriptin :
* Args :
@@ -13330,6 +14356,8 @@ v_VOID_t wma_rx_ready_event(WMA_HANDLE handle, void *cmd_param_info)
vos_event_set(&wma_handle->wma_ready_event);
+ wma_set_dfs_regdomain(wma_handle);
+
WMA_LOGD("Exit");
}
@@ -13481,6 +14509,14 @@ VOS_STATUS WDA_TxPacket(void *wma_context, void *tx_frame, u_int16_t frmLen,
tpSirMacFrameCtl pFc = (tpSirMacFrameCtl)(adf_nbuf_data(tx_frame));
u_int8_t use_6mbps = 0;
u_int8_t downld_comp_required = 0;
+#ifdef WLAN_FEATURE_11W
+ tANI_U8 *pFrame = NULL;
+ void *pPacket = NULL;
+ u_int16_t newFrmLen = 0;
+ struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
+ tpAniSirGlobal pMac = (tpAniSirGlobal)vos_get_context(VOS_MODULE_ID_PE,
+ wma_handle->vos_context);
+#endif /* WLAN_FEATURE_11W */
/* Get the vdev handle from vdev id */
txrx_vdev = wma_handle->interfaces[vdev_id].handle;
@@ -13495,6 +14531,12 @@ VOS_STATUS WDA_TxPacket(void *wma_context, void *tx_frame, u_int16_t frmLen,
return VOS_STATUS_E_FAILURE;
}
+#ifdef WLAN_FEATURE_11W
+ if(!pMac) {
+ WMA_LOGE("pMac Handle is NULL");
+ return VOS_STATUS_E_FAILURE;
+ }
+#endif /* WLAN_FEATURE_11W */
/*
* Currently only support to
* send 80211 Mgmt and 80211 Data are added.
@@ -13504,6 +14546,43 @@ VOS_STATUS WDA_TxPacket(void *wma_context, void *tx_frame, u_int16_t frmLen,
WMA_LOGE("No Support to send other frames except 802.11 Mgmt/Data");
return VOS_STATUS_E_FAILURE;
}
+#ifdef WLAN_FEATURE_11W
+ if ((iface && iface->rmfEnabled && pFc->wep) &&
+ (frmType == HAL_TXRX_FRM_802_11_MGMT) &&
+ (pFc->subType == SIR_MAC_MGMT_DISASSOC ||
+ pFc->subType == SIR_MAC_MGMT_DEAUTH ||
+ pFc->subType == SIR_MAC_MGMT_ACTION)) {
+ struct ieee80211_frame *wh =
+ (struct ieee80211_frame *)adf_nbuf_data(tx_frame);
+ /* Allocate extra bytes for privacy header and trailer */
+ newFrmLen = frmLen + IEEE80211_CCMP_HEADERLEN + IEEE80211_CCMP_MICLEN;
+ vos_status = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( tANI_U16 )newFrmLen, ( void** ) &pFrame,
+ ( void** ) &pPacket );
+
+ if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
+ WMA_LOGP("Failed to allocate %d bytes for RMF"
+ " status code (%x)", newFrmLen, vos_status);
+ /* Free the original packet memory */
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pData, ( void* ) tx_frame );
+ goto error;
+ }
+
+ /* Initialize the frame with 0's and only fill
+ MAC header and data, Keep the CCMP header and
+ trailer as 0's, firmware shall fill this */
+ vos_mem_set( pFrame, newFrmLen , 0 );
+ vos_mem_copy( pFrame, wh, sizeof(*wh));
+ vos_mem_copy( pFrame + sizeof(*wh) + IEEE80211_CCMP_HEADERLEN,
+ pData + sizeof(*wh), frmLen - sizeof(*wh));
+
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pData, ( void* ) tx_frame );
+ tx_frame = pPacket;
+ frmLen = newFrmLen;
+ }
+#endif /* WLAN_FEATURE_11W */
if ((frmType == HAL_TXRX_FRM_802_11_MGMT) &&
(pFc->subType == SIR_MAC_MGMT_PROBE_RSP)) {
@@ -13787,15 +14866,21 @@ int wma_suspend_target(WMA_HANDLE handle, int disable_target_intr)
else {
cmd->suspend_opt = WMI_PDEV_SUSPEND;
}
-
+ vos_event_reset(&wma_handle->target_suspend);
if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmibuf, len,
WMI_PDEV_SUSPEND_CMDID)) {
adf_nbuf_free(wmibuf);
return -1;
}
- vos_event_reset(&wma_handle->target_suspend);
- return vos_wait_single_event(&wma_handle->target_suspend,
- WMA_TGT_SUSPEND_COMPLETE_TIMEOUT);
+ if (vos_wait_single_event(&wma_handle->target_suspend,
+ WMA_TGT_SUSPEND_COMPLETE_TIMEOUT)
+ != VOS_STATUS_SUCCESS) {
+ WMA_LOGE("Failed to suspend target");
+ return -1;
+ }
+ HTCCancelDeferredTargetSleep(vos_get_context(VOS_MODULE_ID_HIF,
+ wma_handle->vos_context));
+ return 0;
}
void wma_target_suspend_complete(void *context)
@@ -14580,3 +15665,336 @@ static int wma_update_tdls_peer_state(WMA_HANDLE handle,
}
#endif /* FEATURE_WLAN_TDLS */
+/*
+ * Attach DFS methods to the umac state.
+ */
+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;
+
+ /* Initializes DFS Data Structures and queues*/
+ dfs_attach(dfs_ic);
+
+ return dfs_ic;
+}
+
+/*
+ * Configures Radar Filters during
+ * vdev start/channel change/regulatory domain
+ * change.This Configuration enables to program
+ * the DFS pattern matching module.
+ */
+void
+wma_dfs_configure(struct ieee80211com *ic)
+{
+ struct ath_dfs_radar_tab_info rinfo;
+ int dfsdomain;
+ if(ic == NULL)
+ {
+ WMA_LOGE("%s: DFS ic is Invalid\n",__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_DOMAIN:
+ WMA_LOGI("%s: DFS-FCC domain\n",__func__);
+ rinfo.dfsdomain = DFS_FCC_DOMAIN;
+ rinfo.dfs_radars = dfs_fcc_radars;
+ rinfo.numradars = ARRAY_LENGTH(dfs_fcc_radars);
+ rinfo.b5pulses = dfs_fcc_bin5pulses;
+ rinfo.numb5radars = ARRAY_LENGTH(dfs_fcc_bin5pulses);
+ break;
+ case DFS_ETSI_DOMAIN:
+ WMA_LOGI("%s: DFS-ETSI domain\n",__func__);
+ rinfo.dfsdomain = DFS_ETSI_DOMAIN;
+ rinfo.dfs_radars = dfs_etsi_radars;
+ rinfo.numradars = ARRAY_LENGTH(dfs_etsi_radars);
+ rinfo.b5pulses = NULL;
+ rinfo.numb5radars = 0;
+ break;
+ case DFS_MKK4_DOMAIN:
+ WMA_LOGI("%s: DFS-MKK4 domain\n",__func__);
+ rinfo.dfsdomain = DFS_MKK4_DOMAIN;
+ rinfo.dfs_radars = dfs_mkk4_radars;
+ rinfo.numradars = ARRAY_LENGTH(dfs_mkk4_radars);
+ rinfo.b5pulses = dfs_jpn_bin5pulses;
+ rinfo.numb5radars = ARRAY_LENGTH(dfs_jpn_bin5pulses);
+ break;
+ default:
+ WMA_LOGI("%s: DFS-UNINT domain\n",__func__);
+ rinfo.dfsdomain = DFS_UNINIT_DOMAIN;
+ rinfo.dfs_radars = NULL;
+ rinfo.numradars = 0;
+ rinfo.b5pulses = NULL;
+ rinfo.numb5radars = 0;
+ break;
+ }
+
+ /*
+ * Set the regulatory domain,
+ * radar pulse table and enable
+ * radar events if required.
+ */
+ dfs_radar_enable(ic, &rinfo);
+}
+
+/*
+ * Set the Channel parameters in to DFS module
+ * Also,configure the DFS radar filters for
+ * matching the DFS phyerrors.
+ */
+struct ieee80211_channel *
+wma_dfs_configure_channel(struct ieee80211com *dfs_ic,
+ wmi_channel *chan,
+ WLAN_PHY_MODE chanmode,
+ struct wma_vdev_start_req *req)
+{
+ if(dfs_ic == NULL)
+ {
+ WMA_LOGE("%s: DFS ic is Invalid\n",__func__);
+ return NULL;
+ }
+ dfs_ic->ic_curchan = (struct ieee80211_channel *) OS_MALLOC(NULL,
+ sizeof(struct ieee80211_channel),
+ GFP_ATOMIC);
+ if (dfs_ic->ic_curchan == NULL)
+ {
+ WMA_LOGE("allocation of dfs_ic->ic_curchan failed %zu \n",
+ __func__,
+ sizeof(struct ieee80211_channel));
+ return NULL;
+ }
+ OS_MEMZERO(dfs_ic->ic_curchan, sizeof (struct ieee80211_channel));
+
+ dfs_ic->ic_curchan->ic_ieee = req->chan;
+ dfs_ic->ic_curchan->ic_freq = chan->mhz;
+ dfs_ic->ic_curchan->ic_vhtop_ch_freq_seg1 = chan->band_center_freq1;
+ dfs_ic->ic_curchan->ic_vhtop_ch_freq_seg2 = chan->band_center_freq2;
+
+ 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;
+ }
+ if(chanmode == MODE_11AC_VHT80)
+ {
+ dfs_ic->ic_curchan->ic_flags |= IEEE80211_CHAN_VHT80;
+ }
+ if (req->chan_offset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+ {
+ dfs_ic->ic_curchan->ic_flags |=
+ (req->vht_capable ?
+ IEEE80211_CHAN_VHT40PLUS : IEEE80211_CHAN_HT40PLUS);
+ }
+ else if (req->chan_offset == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+ {
+ dfs_ic->ic_curchan->ic_flags |=
+ (req->vht_capable ?
+ IEEE80211_CHAN_VHT40MINUS : IEEE80211_CHAN_HT40MINUS);
+ }
+ else if (req->chan_offset == PHY_SINGLE_CHANNEL_CENTERED)
+ {
+ dfs_ic->ic_curchan->ic_flags |=
+ (req->vht_capable ? IEEE80211_CHAN_VHT20 : IEEE80211_CHAN_HT20);
+ }
+ 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;
+ }
+
+ /*
+ * Configuring the DFS with current channel and the radar filters
+ */
+ wma_dfs_configure(dfs_ic);
+ WMA_LOGI("%s: DFS- CHANNEL CONFIGURED\n",__func__);
+ return dfs_ic->ic_curchan;
+}
+/*
+ * Configure the regulatory domain for DFS radar filter initialization
+ */
+void
+wma_set_dfs_regdomain(tp_wma_handle wma)
+{
+ u_int8_t ctl;
+ u_int32_t regdmn = wma->reg_cap.eeprom_rd;
+
+ if (regdmn < 0)
+ {
+ WMA_LOGE("%s:DFS-Invalid regdomain\n",__func__);
+ }
+ ctl = regdmn_get_ctl_for_regdmn(regdmn);
+ if (!ctl)
+ {
+ WMA_LOGI("%s:DFS-Invalid CTL\n",__func__);
+ }
+ if (ctl == FCC)
+ {
+ WMA_LOGI("%s:DFS- CTL = FCC\n",__func__);
+ wma->dfs_ic->current_dfs_regdomain = DFS_FCC_DOMAIN;
+ }
+ else if (ctl == ETSI)
+ {
+ WMA_LOGI("%s:DFS- CTL = ETSI\n",__func__);
+ wma->dfs_ic->current_dfs_regdomain = DFS_ETSI_DOMAIN;
+ }
+ else if (ctl == MKK)
+ {
+ WMA_LOGI("%s:DFS- CTL = MKK\n",__func__);
+ wma->dfs_ic->current_dfs_regdomain = DFS_MKK4_DOMAIN;
+ }
+ WMA_LOGI("%s: ****** Current Reg Domain: %d *******\n", __func__,
+ wma->dfs_ic->current_dfs_regdomain);
+}
+
+/*
+ * Indicate Radar to SAP/HDD
+ */
+int
+wma_dfs_indicate_radar(struct ieee80211com *ic,
+ struct ieee80211_channel *ichan)
+{
+ tp_wma_handle wma;
+ void *hdd_ctx;
+ struct wma_dfs_radar_indication *radar_event;
+ struct hdd_dfs_radar_ind hdd_radar_event;
+ void *vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL);
+ wma = (tp_wma_handle) vos_get_context(VOS_MODULE_ID_WDA, vos_context);
+ hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD,wma->vos_context);
+
+ if (wma == NULL)
+ {
+ WMA_LOGE("%s:DFS- Invalid wma\n",__func__);
+ return (0);
+ }
+ if (wma->dfs_ic != ic)
+ {
+ WMA_LOGE("%s:DFS- Invalid WMA handle\n",__func__);
+ return (0);
+ }
+ radar_event = (struct wma_dfs_radar_indication *)
+ OS_MALLOC(NULL,
+ sizeof(struct wma_dfs_radar_indication),
+ GFP_ATOMIC);
+ if (radar_event == NULL)
+ {
+ WMA_LOGE("%s:DFS- Invalid radar_event\n",__func__);
+ return (0);
+ }
+
+ /*
+ * Do not post multiple Radar events on the same channel.
+ */
+ if ( ichan->ic_ieee != (wma->dfs_ic->last_radar_found_chan) )
+ {
+ wma->dfs_ic->last_radar_found_chan = ichan->ic_ieee;
+ /* Indicate the radar event to HDD to stop the netif Tx queues*/
+ hdd_radar_event.ieee_chan_number = ichan->ic_ieee;
+ hdd_radar_event.chan_freq = ichan->ic_freq;
+ hdd_radar_event.dfs_radar_status = WMA_DFS_RADAR_FOUND;
+ wma->dfs_radar_indication_cb(hdd_ctx,&hdd_radar_event);
+ WMA_LOGE("%s:DFS- RADAR INDICATED TO HDD\n",__func__);
+
+ /*
+ * Indicate to the radar event to SAP to
+ * select a new channel and set CSA IE
+ */
+ radar_event->vdev_id = ic->vdev_id;
+ radar_event->ieee_chan_number = ichan->ic_ieee;
+ radar_event->chan_freq = ichan->ic_freq;
+ radar_event->dfs_radar_status = WMA_DFS_RADAR_FOUND;
+ radar_event->use_nol = ic->ic_dfs_usenol(ic);
+ wma_send_msg(wma, WDA_DFS_RADAR_IND, (void *)radar_event, 0);
+ WMA_LOGE("%s:DFS- WDA_DFS_RADAR_IND Message Posted\n",__func__);
+ }
+ return 1;
+}
+
+static eHalStatus wma_set_smps_params(tp_wma_handle wma, tANI_U8 vdev_id, int value)
+{
+ int ret = eHAL_STATUS_SUCCESS;
+ wmi_sta_smps_param_cmd_fixed_param *cmd;
+ wmi_buf_t buf;
+ u_int16_t len = sizeof(*cmd);
+
+ buf = wmi_buf_alloc(wma->wmi_handle, len);
+ if (!buf) {
+ WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
+ return -ENOMEM;
+ }
+ cmd = (wmi_sta_smps_param_cmd_fixed_param *) wmi_buf_data(buf);
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_sta_smps_param_cmd_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ wmi_sta_smps_param_cmd_fixed_param));
+
+ cmd->vdev_id = vdev_id;
+ cmd->value = value & WMA_SMPS_MASK_LOWER_16BITS;
+ cmd->param = (value >> WMA_SMPS_PARAM_VALUE_S) & WMA_SMPS_MASK_UPPER_3BITS;
+
+ WMA_LOGD("Setting vdev %d value = %x param %x \n", vdev_id, cmd->value, cmd->param);
+
+ ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+ WMI_STA_SMPS_PARAM_CMDID);
+ if (ret < 0) {
+ WMA_LOGE("Failed to send set Mimo PS ret = %d", ret);
+ wmi_buf_free(buf);
+ }
+
+ return ret;
+}
+
+VOS_STATUS WMA_GetWcnssSoftwareVersion(v_PVOID_t pvosGCtx,
+ tANI_U8 *pVersion,
+ tANI_U32 versionBufferSize)
+{
+
+ tp_wma_handle wma_handle;
+ wma_handle = vos_get_context(VOS_MODULE_ID_WDA, pvosGCtx);
+
+ snprintf(pVersion, versionBufferSize, "%x", (unsigned int)wma_handle->target_fw_version);
+ return VOS_STATUS_SUCCESS;
+}
diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h
index 3644b87fbbe8..33560c9ebcc3 100644
--- a/CORE/SERVICES/WMA/wma.h
+++ b/CORE/SERVICES/WMA/wma.h
@@ -67,6 +67,7 @@
#include "sirMacProtDef.h"
#include "wlan_qct_wda.h"
#include "ol_txrx_types.h"
+#include "wlan_qct_wda.h"
#include <linux/workqueue.h>
/* Platform specific configuration for max. no. of fragments */
@@ -134,12 +135,30 @@
#define WMA_HW_DEF_SCAN_MAX_DURATION 30000 /* 30 secs */
/* Max offchannel duration */
-#define WMA_SCAN_AP_PRESENT_MAX_OFFCHANNEL_NUM 5
-#define WMA_SCAN_MAX_OFFCHANNEL_NUM_ACTIVE 10
-#define WMA_SCAN_MAX_OFFCHANNEL_NUM_PASSIVE 4
+#define WMA_BURST_SCAN_MAX_NUM_OFFCHANNELS 5
-#define WMA_INVALID_KEY_IDX 0xff
+/* Roaming default values
+ * All time and period values are in milliseconds.
+ * All rssi values are in dB except for WMA_NOISE_FLOOR_DBM_DEFAULT.
+ */
+
+#define WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME (3)
+#define WMA_NOISE_FLOOR_DBM_DEFAULT (-96)
+#define WMA_ROAM_RSSI_DIFF_DEFAULT (5)
+#define WMA_ROAM_DWELL_TIME_ACTIVE_DEFAULT (100)
+#define WMA_ROAM_DWELL_TIME_PASSIVE_DEFAULT (110)
+#define WMA_ROAM_MIN_REST_TIME_DEFAULT (50)
+#define WMA_ROAM_MAX_REST_TIME_DEFAULT (500)
+#define WMA_ROAM_LOW_RSSI_TRIGGER_DEFAULT (20)
+#define WMA_ROAM_LOW_RSSI_TRIGGER_VERYLOW (10)
+#define WMA_ROAM_RSSI_THRESH_DIFF_DEFAULT (30)
+#define WMA_ROAM_RSSI_CHANGE_RESCAN_DEFAULT (5)
+#define WMA_ROAM_BEACON_WEIGHT_DEFAULT (14)
+#define WMA_ROAM_OPP_SCAN_PERIOD_DEFAULT (120000)
+#define WMA_ROAM_OPP_SCAN_AGING_PERIOD_DEFAULT (WMA_ROAM_OPP_SCAN_PERIOD_DEFAULT * 5)
+#define WMA_INVALID_KEY_IDX 0xff
+#define WMA_DFS_RADAR_FOUND 1
typedef struct {
HTC_ENDPOINT_ID endpoint_id;
}t_cfg_nv_param;
@@ -266,6 +285,13 @@ struct pps {
v_BOOL_t rssi_chk;
};
+struct qpower_params {
+ u_int32_t max_ps_poll_cnt;
+ u_int32_t max_tx_before_wake;
+ u_int32_t spec_ps_poll_wake_interval;
+ u_int32_t max_spec_nodata_ps_poll;
+};
+
typedef struct {
u_int32_t ani_enable;
u_int32_t ani_poll_len;
@@ -278,6 +304,8 @@ typedef struct {
u_int32_t txpow2g;
u_int32_t txpow5g;
u_int32_t pwrgating;
+ u_int32_t burst_enable;
+ u_int32_t burst_dur;
} pdev_cli_config_t;
typedef struct {
@@ -292,6 +320,7 @@ typedef struct {
u_int32_t ampdu;
u_int32_t amsdu;
struct pps pps_params;
+ struct qpower_params qpower_params;
} vdev_cli_config_t;
#define WMA_WOW_PTRN_MASK_VALID 0xFF
@@ -325,6 +354,17 @@ struct wma_wow {
v_BOOL_t bmiss_enable;
v_BOOL_t gtk_err_enable;
};
+#ifdef WLAN_FEATURE_11W
+#define CMAC_IPN_LEN 6
+typedef struct {
+ u_int16_t key_length;
+ u_int8_t key[CSR_AES_KEY_LEN];
+ u_int8_t ipn[CMAC_IPN_LEN];
+} wma_igtk_key_t;
+#endif
+
+#define WMA_BSS_STATUS_STARTED 0x1
+#define WMA_BSS_STATUS_STOPPED 0x2
struct wma_txrx_node {
u_int8_t addr[ETH_ALEN];
@@ -354,6 +394,17 @@ struct wma_txrx_node {
v_BOOL_t vdev_up;
u_int64_t tsfadjust;
void *addBssStaContext;
+ tANI_U8 aid;
+ /* Robust Management Frame (RMF) enabled/disabled */
+ tANI_U8 rmfEnabled;
+#ifdef WLAN_FEATURE_11W
+ wma_igtk_key_t key;
+#endif /* WLAN_FEATURE_11W */
+ u_int32_t uapsd_cached_val;
+ tAniGetPEStatsRsp *stats_rsp;
+ tANI_U8 fw_stats_set;
+ void *del_staself_req;
+ tANI_U8 bss_status;
};
#if defined(QCA_WIFI_FTM) && !defined(QCA_WIFI_ISOC)
@@ -430,6 +481,8 @@ typedef struct {
struct wma_mem_chunk mem_chunks[MAX_MEM_CHUNKS];
#endif
wda_tgt_cfg_cb tgt_cfg_update_cb;
+ /*Callback to indicate radar to HDD*/
+ wda_dfs_radar_indication_cb dfs_radar_indication_cb;
HAL_REG_CAPABILITIES reg_cap;
u_int32_t scan_id;
struct wma_txrx_node *interfaces;
@@ -461,6 +514,7 @@ typedef struct {
v_BOOL_t ptrn_match_enable_all_vdev;
void* pGetRssiReq;
u_int32_t roam_offload_vdev_id;
+ v_BOOL_t roam_offload_enabled;
/* Here ol_ini_info is used to store ini
* status of arp offload, ns offload
@@ -471,6 +525,14 @@ typedef struct {
u_int8_t ol_ini_info;
u_int8_t ibss_started;
tSetBssKeyParams ibsskey_info;
+
+ /*DFS umac interface information*/
+ struct ieee80211com *dfs_ic;
+#ifdef FEATURE_WLAN_SCAN_PNO
+ vos_wake_lock_t pno_wake_lock;
+#endif
+ vos_wake_lock_t wow_wake_lock;
+
}t_wma_handle, *tp_wma_handle;
struct wma_target_cap {
@@ -990,6 +1052,15 @@ VOS_STATUS wma_update_vdev_tbl(tp_wma_handle wma_handle, u_int8_t vdev_id,
ol_txrx_vdev_handle tx_rx_vdev_handle, u_int8_t *mac,
u_int32_t vdev_type, bool add_del);
+#ifndef QCA_WIFI_ISOC
+int32_t regdmn_get_regdmn_for_country(u_int8_t *alpha2);
+void regdmn_get_ctl_info(struct regulatory *reg, u_int32_t modesAvail,
+ u_int32_t modeSelect);
+
+/*get the ctl from regdomain*/
+u_int8_t regdmn_get_ctl_for_regdmn(u_int32_t reg_dmn);
+#endif
+
#define WMA_FW_PHY_STATS 0x1
#define WMA_FW_RX_REORDER_STATS 0x2
#define WMA_FW_RX_RC_STATS 0x3
@@ -1012,6 +1083,7 @@ struct wma_tx_ack_work_ctx {
#define WMA_TARGET_REQ_TYPE_VDEV_START 0x1
#define WMA_TARGET_REQ_TYPE_VDEV_STOP 0x2
+#define WMA_TARGET_REQ_TYPE_VDEV_DEL 0x3
struct wma_target_req {
vos_timer_t event_timeout;
@@ -1100,6 +1172,8 @@ VOS_STATUS wma_send_snr_request(tp_wma_handle wma_handle, void *pGetRssiReq);
/* Default rssi threshold defined in CFG80211 */
#define WMA_RSSI_THOLD_DEFAULT -300
+#define WMA_PNO_WAKE_LOCK_TIMEOUT (30 * 1000) /* in msec */
+
#endif
/* U-APSD maximum service period of peer station */
@@ -1229,6 +1303,7 @@ typedef enum {
#define WMA_DEFAULT_QPOWER_MAX_PSPOLL_BEFORE_WAKE 1
#define WMA_DEFAULT_QPOWER_TX_WAKE_THRESHOLD 2
+#define WMA_DEFAULT_SIFS_BURST_DURATION 8160
#define WMA_VHT_PPS_PAID_MATCH 1
#define WMA_VHT_PPS_GID_MATCH 2
@@ -1260,4 +1335,47 @@ typedef struct {
#endif /* FEATURE_WLAN_TDLS */
+/*
+ * Structure to indicate RADAR
+ */
+
+struct wma_dfs_radar_indication {
+ /* unique id identifying the VDEV */
+ A_UINT32 vdev_id;
+ /*Channel number on which the RADAR is present */
+ u_int8_t ieee_chan_number;
+ /* Channel Frequency*/
+ A_UINT32 chan_freq;
+ /* Flag to Indicate RADAR presence on the
+ * current operating channel
+ */
+ u_int32_t dfs_radar_status;
+ /* Flag to indicate use NOL */
+ int use_nol;
+};
+
+/*
+ * WMA-DFS Hooks
+ */
+int ol_if_dfs_attach(struct ieee80211com *ic, void *ptr, void *radar_info);
+u_int64_t ol_if_get_tsf64(struct ieee80211com *ic);
+int ol_if_dfs_disable(struct ieee80211com *ic);
+struct ieee80211_channel * ieee80211_find_channel(struct ieee80211com *ic,
+ int freq, u_int32_t flags);
+int ol_if_dfs_enable(struct ieee80211com *ic, int *is_fastclk, void *pe);
+u_int32_t ieee80211_ieee2mhz(u_int32_t chan, u_int32_t flags);
+int ol_if_dfs_get_ext_busy(struct ieee80211com *ic);
+int ol_if_dfs_get_mib_cycle_counts_pct(struct ieee80211com *ic,
+ u_int32_t *rxc_pcnt, u_int32_t *rxf_pcnt, u_int32_t *txf_pcnt);
+u_int16_t ol_if_dfs_usenol(struct ieee80211com *ic);
+void ieee80211_mark_dfs(struct ieee80211com *ic,
+ struct ieee80211_channel *ichan);
+int wma_dfs_indicate_radar(struct ieee80211com *ic,
+ struct ieee80211_channel *ichan);
+u_int16_t dfs_usenol(struct ieee80211com *ic);
+
+#define WMA_SMPS_MASK_LOWER_16BITS 0xFF
+#define WMA_SMPS_MASK_UPPER_3BITS 0x7
+#define WMA_SMPS_PARAM_VALUE_S 29
+
#endif
diff --git a/CORE/SERVICES/WMA/wma_dfs_interface.c b/CORE/SERVICES/WMA/wma_dfs_interface.c
new file mode 100644
index 000000000000..5fb437a77394
--- /dev/null
+++ b/CORE/SERVICES/WMA/wma_dfs_interface.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+ wma_dfs_interface.c
+
+ OVERVIEW:
+
+ Source code borrowed from QCA_MAIN DFS module
+
+ DEPENDENCIES:
+
+ Are listed for each API below.
+
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+
+===========================================================================*/
+
+
+
+#include "wma.h"
+#include "ath_dfs_structs.h"
+#include "wma_dfs_interface.h"
+
+#ifndef ATH_SUPPORT_DFS
+#define ATH_SUPPORT_DFS 1
+#endif
+
+int
+ol_if_dfs_attach(struct ieee80211com *ic, void *ptr, void *radar_info)
+{
+ struct ath_dfs_caps *pCap = (struct ath_dfs_caps *) ptr;
+
+ adf_os_print("%s: called; ptr=%p, radar_info=%p\n",
+ __func__, ptr, radar_info);
+
+ pCap->ath_chip_is_bb_tlv = 1;
+ pCap->ath_dfs_combined_rssi_ok = 0;
+ pCap->ath_dfs_ext_chan_ok = 0;
+ pCap->ath_dfs_use_enhancement = 0;
+ pCap->ath_strong_signal_diversiry = 0;
+ pCap->ath_fastdiv_val = 0;
+
+ return(0);
+}
+
+/*
+ * Place Holder API
+ * We get the tsf from Firmware.
+ */
+u_int64_t
+ol_if_get_tsf64(struct ieee80211com *ic)
+{
+ return (0);
+}
+
+/*
+ * ic_dfs_disable is just a place holder
+ * function since firmware takes care of
+ * disabling the dfs phyerrors disabling.
+ */
+int
+ol_if_dfs_disable(struct ieee80211com *ic)
+{
+ return (0);
+}
+
+
+/*
+ * Locate a channel given a frequency+flags. We cache
+ * the previous lookup to optimize swithing between two
+ * channels--as happens with dynamic turbo.
+ * This verifies that found channels have not been excluded because of 11d.
+ */
+struct ieee80211_channel *
+ieee80211_find_channel(struct ieee80211com *ic, int freq, u_int32_t flags)
+{
+ struct ieee80211_channel *c;
+ int i;
+
+ flags &= IEEE80211_CHAN_ALLTURBO;
+ /* brute force search */
+ for (i = 0; i < ic->ic_nchans; i++)
+ {
+ c = &ic->ic_channels[i];
+
+ if ((! IEEE80211_IS_CHAN_11D_EXCLUDED(c)) &&
+ (c->ic_freq == freq) &&
+ ((c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags))
+ {
+ return c;
+ }
+ }
+
+ return NULL;
+}
+
+
+/*
+ * ic_dfs_enable - enable DFS
+ * For offload solutions, radar PHY errors will be enabled by the target
+ * firmware when DFS is requested for the current channel.
+ */
+int ol_if_dfs_enable(struct ieee80211com *ic, int *is_fastclk, void *pe)
+{
+ /*
+ * For peregrine, treat fastclk as the "oversampling" mode.
+ * It's on by default. This may change at some point, so
+ * we should really query the firmware to find out what
+ * the current configuration is.
+ */
+ (* is_fastclk) = 1;
+
+ return (0);
+}
+
+/*
+ * Convert IEEE channel number to MHz frequency.
+ */
+u_int32_t
+ieee80211_ieee2mhz(u_int32_t chan, u_int32_t flags)
+{
+ if (flags & IEEE80211_CHAN_2GHZ)
+ {
+ /* 2GHz band */
+ if (chan == 14)
+ return 2484;
+ if (chan < 14)
+ return 2407 + chan*5;
+ else
+ return 2512 + ((chan-15)*20);
+ }
+ else if (flags & IEEE80211_CHAN_5GHZ)
+ {
+ /* 5Ghz band */
+ return 5000 + (chan*5);
+ }
+ else
+ {
+ /* either, guess */
+ if (chan == 14)
+ return 2484;
+ if (chan < 14) /* 0-13 */
+ return 2407 + chan*5;
+ if (chan < 27) /* 15-26 */
+ return 2512 + ((chan-15)*20);
+ return 5000 + (chan*5);
+ }
+}
+
+/*
+ * Place holder function ic_get_ext_busy
+ */
+int
+ol_if_dfs_get_ext_busy(struct ieee80211com *ic)
+{
+ return (0);
+}
+
+/*
+ * ic_get_mib_cycle_counts_pct
+ */
+int
+ol_if_dfs_get_mib_cycle_counts_pct(struct ieee80211com *ic,
+ u_int32_t *rxc_pcnt, u_int32_t *rxf_pcnt, u_int32_t *txf_pcnt)
+{
+ return (0);
+}
+
+u_int16_t
+ol_if_dfs_usenol(struct ieee80211com *ic)
+{
+#if ATH_SUPPORT_DFS
+ return(dfs_usenol(ic));
+#else
+ return (0);
+#endif /* ATH_SUPPORT_DFS */
+ return 0;
+}
+
+/*
+ * Function to indicate Radar on the current
+ * SAP operating channel.This indication will
+ * be posted to SAP to select a new channel
+ * randomly and issue a vdev restart to
+ * operate on the new channel.
+ */
+void
+ieee80211_mark_dfs(struct ieee80211com *ic, struct ieee80211_channel *ichan)
+{
+ int status;
+ status = wma_dfs_indicate_radar(ic, ichan);
+}
diff --git a/CORE/SERVICES/WMA/wma_stub.h b/CORE/SERVICES/WMA/wma_stub.h
index bf911303e6f1..a0a2393ab8a8 100644
--- a/CORE/SERVICES/WMA/wma_stub.h
+++ b/CORE/SERVICES/WMA/wma_stub.h
@@ -62,12 +62,6 @@ static inline void WMA_disableCapablityFeature(tANI_U8 feature_index) {
return;
}
-static inline VOS_STATUS WMA_GetWcnssSoftwareVersion(v_PVOID_t pvosGCtx,
- tANI_U8 *pVersion,
- tANI_U32 versionBufferSize){
- return VOS_STATUS_SUCCESS;
-}
-
static inline VOS_STATUS WMA_HALDumpCmdReq(tpAniSirGlobal pMac, tANI_U32 cmd,
tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3,
tANI_U32 arg4, tANI_U8 *pBuffer) {
diff --git a/CORE/SERVICES/WMI/wmi_tlv_platform.c b/CORE/SERVICES/WMI/wmi_tlv_platform.c
index 0f105096a10c..a859e214215b 100644
--- a/CORE/SERVICES/WMI/wmi_tlv_platform.c
+++ b/CORE/SERVICES/WMI/wmi_tlv_platform.c
@@ -24,21 +24,6 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-/*
- * Copyright (c) 2013 Qualcomm Atheros,Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
/*
* LMAC offload interface functions for WMI TLV Interface
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index 3a4c852d004d..411391e22849 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -466,6 +466,13 @@ typedef enum
eCSR_ROAM_CCX_ADJ_AP_REPORT_IND,
eCSR_ROAM_CCX_BCN_REPORT_IND,
#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
+
+ // Radar indication from lower layers
+ eCSR_ROAM_DFS_RADAR_IND,
+ eCSR_ROAM_SET_CHANNEL_RSP,
+
+ // Channel sw update notification
+ eCSR_ROAM_DFS_CHAN_SW_NOTIFY
}eRoamCmdStatus;
@@ -559,6 +566,12 @@ typedef enum
eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED,
#endif
#endif
+
+ eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND,
+ eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS,
+ eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE,
+ eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS,
+ eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_FAILURE,
}eCsrRoamResult;
@@ -889,6 +902,8 @@ typedef struct tagCsrRoamProfile
#endif
tVOS_CON_MODE csrPersona;
+ tANI_U8 disableDFSChSwitch;
+
}tCsrRoamProfile;
@@ -1203,6 +1218,8 @@ typedef struct tagCsrRoamInfo
tANI_U8* assocReqPtr;
tANI_S8 rxRssi;
+ tSirSmeDfsEventInd dfs_event;
+ tSirChanChangeResponse *channelChangeRespEvent;
}tCsrRoamInfo;
diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h
index 53d3d50cf91d..4c0cf4cbe865 100644
--- a/CORE/SME/inc/csrInternal.h
+++ b/CORE/SME/inc/csrInternal.h
@@ -63,6 +63,7 @@
#define CSR_SCAN_RETURN_AFTER_EITHER_BAND_11d_FOUND ( CSR_SCAN_RETURN_AFTER_5_BAND_11d_FOUND | CSR_SCAN_RETURN_AFTER_24_BAND_11d_FOUND )
#define CSR_NUM_RSSI_CAT 15
#define CSR_MAX_STATISTICS_REQ 10
+#define CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME 3
//Support for multiple session
#define CSR_SESSION_ID_INVALID 0xFF // session ID invalid
@@ -838,6 +839,7 @@ typedef struct tagCsrPeStatsReqInfo
tpAniSirGlobal pMac;
/* To remember if the peStats timer is stopped successfully or not */
tANI_BOOLEAN timerStopFailed;
+ tANI_U8 sessionId;
}tCsrPeStatsReqInfo;
@@ -854,6 +856,7 @@ typedef struct tagCsrStatsClientReqInfo
vos_timer_t timer;
tANI_BOOLEAN timerExpired;
tpAniSirGlobal pMac; // TODO: Confirm this change BTAMP
+ tANI_U8 sessionId;
}tCsrStatsClientReqInfo;
typedef struct tagCsrTlStatsReqInfo
@@ -1212,14 +1215,15 @@ eHalStatus csrRoamRegisterLinkQualityIndCallback(tpAniSirGlobal pMac,
\param cache - If requester is happy with cached stats
\param staId - The station ID for which the stats is requested for
\param pContext - user context to be passed back along with the callback
-
+ \param sessionId - sme session Id.
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus csrGetStatistics(tpAniSirGlobal pMac, eCsrStatsRequesterType requesterId,
tANI_U32 statsMask,
tCsrStatsCallback callback,
tANI_U32 periodicity, tANI_BOOLEAN cache,
- tANI_U8 staId, void *pContext);
+ tANI_U8 staId, void *pContext,
+ tANI_U8 sessionId);
/* ---------------------------------------------------------------------------
\fn csrGetTLSTAState
@@ -1422,4 +1426,16 @@ eHalStatus csrHandoffRequest(tpAniSirGlobal pMac, tCsrHandoffRequest *pHandoffIn
tANI_BOOLEAN csrRoamIsStaMode(tpAniSirGlobal pMac, tANI_U32 sessionId);
#endif
+
+/* Post Channel Change Indication */
+eHalStatus csrRoamChannelChangeReq( tpAniSirGlobal pMac,
+ tANI_U32 sessionId, tANI_U8 targetChannel);
+
+/* Post Beacon Tx Start Indication */
+eHalStatus csrRoamStartBeaconReq( tpAniSirGlobal pMac,
+ tANI_U32 sessionId, tANI_U8 dfsCacWaitStatus);
+
+eHalStatus
+csrRoamSendChanSwIERequest(tpAniSirGlobal pMac, tANI_U8 sessionId,
+ tANI_U8 targetChannel, tANI_U8 csaIeReqd);
#endif
diff --git a/CORE/SME/inc/pmcApi.h b/CORE/SME/inc/pmcApi.h
index 79db57192625..0a7be56c2561 100644
--- a/CORE/SME/inc/pmcApi.h
+++ b/CORE/SME/inc/pmcApi.h
@@ -627,5 +627,8 @@ eHalStatus pmcOffloadSetTdlsProhibitBmpsStatus(tHalHandle hHal,
tANI_U32 sessionId,
v_BOOL_t val);
#endif
+
+tANI_BOOLEAN pmcOffloadIsPowerSaveEnabled (tHalHandle hHal, tANI_U32 sessionId,
+ tPmcPowerSavingMode psMode);
#endif
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 548834fa4287..93d62b0c047b 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -849,13 +849,14 @@ eHalStatus sme_GetConfigParam(tHalHandle hHal, tSmeConfigParams *pParam);
\param cache - If requester is happy with cached stats
\param staId - The station ID for which the stats is requested for
\param pContext - user context to be passed back along with the callback
+ \param sessionId - sme session interface
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_GetStatistics(tHalHandle hHal, eCsrStatsRequesterType requesterId,
tANI_U32 statsMask,
tCsrStatsCallback callback,
tANI_U32 periodicity, tANI_BOOLEAN cache,
- tANI_U8 staId, void *pContext);
+ tANI_U8 staId, void *pContext, tANI_U8 sessionId);
/* ---------------------------------------------------------------------------
\fn smeGetTLSTAState
@@ -1099,11 +1100,13 @@ extern eHalStatus sme_QueryPowerState (
\brief Checks if the device is able to enter a particular power save mode
This does not imply that the device is in a particular PS mode
\param hHal - The handle returned by macOpen.
+ \param sessionId - sme sessionid
\param psMode - the power saving mode
\return eHalStatus
---------------------------------------------------------------------------*/
-extern tANI_BOOLEAN sme_IsPowerSaveEnabled(
+extern tANI_BOOLEAN sme_IsPowerSaveEnabled (
tHalHandle hHal,
+ tANI_U32 sessionId,
tPmcPowerSavingMode psMode);
/* ---------------------------------------------------------------------------
@@ -2854,18 +2857,6 @@ eHalStatus sme_SetCcxRoamScanChannelList(tHalHandle hHal,
#endif
/*--------------------------------------------------------------------------
- \brief csrUpdateBgScanConfigIniChannelList() - Update bgscan roam cache
- This is a synchronuous call
- \param hHal - The handle returned by macOpen.
- \return eHAL_STATUS_SUCCESS - SME update config successful.
- Other status means SME is failed to update
- \sa
- --------------------------------------------------------------------------*/
-eHalStatus sme_UpdateBgScanConfigIniChannelList(tHalHandle hHal,
- eCsrBand eBand);
-
-
-/*--------------------------------------------------------------------------
\brief sme_getRoamScanChannelList() - get roam scan channel list
This is a synchronuous call
\param hHal - The handle returned by macOpen.
@@ -3288,4 +3279,21 @@ eHalStatus sme_AddChAvoidCallback
void (*pCallbackfn)(void *hdd_context, void *indi_param)
);
#endif /* FEATURE_WLAN_CH_AVOID */
+
+eHalStatus sme_RoamChannelChangeReq( tHalHandle hHal,
+ tANI_U8 sessionId, tANI_U8 targetChannel);
+
+eHalStatus sme_RoamStartBeaconReq( tHalHandle hHal,
+ tANI_U8 sessionId, tANI_U8 dfsCacWaitStatus);
+/* -------------------------------------------------------------------------
+ \fn sme_RoamCsaIeRequest
+ \brief API to request CSA IE transmission from PE
+ \param hHal - The handle returned by macOpen
+ \param sessionId - session ID
+ \param pDfsCsaReq - CSA IE request
+ \return eHalStatus
+---------------------------------------------------------------------------*/
+eHalStatus sme_RoamCsaIeRequest(tHalHandle hHal, tANI_U8 sessionId,
+ tANI_U8 targetChannel, tANI_U8 csaIeReqd);
+
#endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/inc/sme_Trace.h b/CORE/SME/inc/sme_Trace.h
index 35cdf8ccef8b..c370b5fc9dfd 100644
--- a/CORE/SME/inc/sme_Trace.h
+++ b/CORE/SME/inc/sme_Trace.h
@@ -31,12 +31,6 @@
\author Kiran Kumar Reddy CH L V
- Copyright (c) 2013 Qualcomm Atheros, Inc.
-
- All Rights Reserved.
-
- Qualcomm Atheros Confidential and Proprietary.
-
========================================================================*/
#ifndef __SME_TRACE_H__
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 776b9bff9ac2..34c33b88a57b 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -218,7 +218,8 @@ VOS_STATUS csrRoamVccTriggerRssiIndCallback(tHalHandle hHal,
void * context);
static void csrRoamLinkDown(tpAniSirGlobal pMac, tANI_U32 sessionId);
void csrRoamVccTrigger(tpAniSirGlobal pMac);
-eHalStatus csrSendMBStatsReqMsg( tpAniSirGlobal pMac, tANI_U32 statsMask, tANI_U8 staId);
+eHalStatus csrSendMBStatsReqMsg( tpAniSirGlobal pMac, tANI_U32 statsMask,
+ tANI_U8 staId, tANI_U8 sessionId);
/*
pStaEntry is no longer invalid upon the return of this function.
*/
@@ -230,7 +231,10 @@ tCsrStatsClientReqInfo * csrRoamInsertEntryIntoList( tpAniSirGlobal pMac,
tCsrStatsClientReqInfo *pStaEntry);
void csrRoamStatsClientTimerHandler(void *pv);
tCsrPeStatsReqInfo * csrRoamCheckPeStatsReqList(tpAniSirGlobal pMac, tANI_U32 statsMask,
- tANI_U32 periodicity, tANI_BOOLEAN *pFound, tANI_U8 staId);
+ tANI_U32 periodicity,
+ tANI_BOOLEAN *pFound,
+ tANI_U8 staId,
+ tANI_U8 sessionId);
void csrRoamReportStatistics(tpAniSirGlobal pMac, tANI_U32 statsMask,
tCsrStatsCallback callback, tANI_U8 staId, void *pContext);
void csrRoamSaveStatsFromTl(tpAniSirGlobal pMac, WLANTL_TRANSFER_STA_TYPE *pTlStats);
@@ -1399,7 +1403,8 @@ eHalStatus csrSetBand(tHalHandle hHal, eCsrBand eBand)
pMac->roam.configParam.bandCapability = eBand;
csrScanGetSupportedChannels( pMac );
#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
- csrUpdateBgScanConfigIniChannelList( pMac, eBand );
+ if (!csrRoamIsRoamOffloadScanEnabled(pMac))
+ csrUpdateBgScanConfigIniChannelList( pMac, eBand );
#endif
status = csrInitGetChannels( pMac );
if (eHAL_STATUS_SUCCESS == status)
@@ -8530,6 +8535,12 @@ eHalStatus csrRoamProcessSetKeyCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand )
#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
WLAN_VOS_DIAG_EVENT_DEF(setKeyEvent, vos_event_wlan_security_payload_type);
+
+ if(NULL == pSession){
+ smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
+ return eHAL_STATUS_FAILURE;
+ }
+
if(eSIR_ED_NONE != edType)
{
vos_mem_set(&setKeyEvent,
@@ -8612,6 +8623,12 @@ eHalStatus csrRoamProcessRemoveKeyCommand( tpAniSirGlobal pMac, tSmeCmd *pComman
#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
WLAN_VOS_DIAG_EVENT_DEF(removeKeyEvent, vos_event_wlan_security_payload_type);
+
+ if(NULL == pSession){
+ smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
+ return eHAL_STATUS_FAILURE;
+ }
+
vos_mem_set(&removeKeyEvent,
sizeof(vos_event_wlan_security_payload_type),0);
removeKeyEvent.eventId = WLAN_SECURITY_EVENT_REMOVE_KEY_REQ;
@@ -9826,11 +9843,16 @@ void csrRoamCheckForLinkStatusChange( tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg )
}
#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR
smsLog(pMac, LOGW, "CSR: Peer departed notification from LIM");
- roamInfo.staId = (tANI_U8)pIbssPeerInd->staId;
- roamInfo.ucastSig = (tANI_U8)pIbssPeerInd->ucastSig;
- roamInfo.bcastSig = (tANI_U8)pIbssPeerInd->bcastSig;
- vos_mem_copy(&roamInfo.peerMac, pIbssPeerInd->peerAddr,
- sizeof(tCsrBssid));
+ if(pIbssPeerInd)
+ {
+ roamInfo.staId = (tANI_U8)pIbssPeerInd->staId;
+ roamInfo.ucastSig = (tANI_U8)pIbssPeerInd->ucastSig;
+ roamInfo.bcastSig = (tANI_U8)pIbssPeerInd->bcastSig;
+ vos_mem_copy(&roamInfo.peerMac, pIbssPeerInd->peerAddr,
+ sizeof(tCsrBssid));
+ }
+ else
+ smsLog(pMac, LOGE, "CSR: departed peer info is NULL");
csrRoamCallCallback(pMac, sessionId, &roamInfo, 0,
eCSR_ROAM_CONNECT_STATUS_UPDATE, eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED);
}
@@ -11277,9 +11299,9 @@ tANI_U8 csrRoamGetIbssStartChannelNumber50( tpAniSirGlobal pMac )
{
for ( idxValidChannels = 0; idxValidChannels < len ; idxValidChannels++ )
{
- if ( CSR_IS_CHANNEL_5GHZ(pMac->roam.validChannelList[ idx ]) ) // the max channel# in 11g is 14
+ if ( CSR_IS_CHANNEL_5GHZ(pMac->roam.validChannelList[ idxValidChannels ]) ) // the max channel# in 11g is 14
{
- channel = csrStartIbssChannels50[ idx ];
+ channel = csrStartIbssChannels50[ idxValidChannels ];
break;
}
}
@@ -14595,7 +14617,8 @@ void csrRoamPeStatsTimerHandler(void *pv)
if(!pPeStatsReqListEntry->rspPending)
{
status = csrSendMBStatsReqMsg(pMac, pPeStatsReqListEntry->statsMask & ~(1 << eCsrGlobalClassDStats),
- pPeStatsReqListEntry->staId);
+ pPeStatsReqListEntry->staId,
+ pPeStatsReqListEntry->sessionId);
if(!HAL_STATUS_SUCCESS(status))
{
smsLog(pMac, LOGE, FL("csrRoamPeStatsTimerHandler:failed to send down stats req to PE"));
@@ -14663,7 +14686,8 @@ void csrRoamStatsClientTimerHandler(void *pv)
-eHalStatus csrSendMBStatsReqMsg( tpAniSirGlobal pMac, tANI_U32 statsMask, tANI_U8 staId)
+eHalStatus csrSendMBStatsReqMsg( tpAniSirGlobal pMac, tANI_U32 statsMask,
+ tANI_U8 staId, tANI_U8 sessionId)
{
tAniGetPEStatsReq *pMsg;
eHalStatus status = eHAL_STATUS_SUCCESS;
@@ -14678,6 +14702,7 @@ eHalStatus csrSendMBStatsReqMsg( tpAniSirGlobal pMac, tANI_U32 statsMask, tANI_U
pMsg->msgLen = (tANI_U16)sizeof(tAniGetPEStatsReq);
pMsg->staId = staId;
pMsg->statsMask = statsMask;
+ pMsg->sessionId = sessionId;
status = palSendMBMessage(pMac->hHdd, pMsg );
if(!HAL_STATUS_SUCCESS(status))
{
@@ -15270,7 +15295,8 @@ eHalStatus csrGetStatistics(tpAniSirGlobal pMac, eCsrStatsRequesterType requeste
tANI_U32 statsMask,
tCsrStatsCallback callback,
tANI_U32 periodicity, tANI_BOOLEAN cache,
- tANI_U8 staId, void *pContext)
+ tANI_U8 staId, void *pContext,
+ tANI_U8 sessionId)
{
tCsrStatsClientReqInfo staEntry;
tCsrStatsClientReqInfo *pStaEntry = NULL;
@@ -15365,6 +15391,7 @@ eHalStatus csrGetStatistics(tpAniSirGlobal pMac, eCsrStatsRequesterType requeste
staEntry.staId = staId;
staEntry.pMac = pMac;
staEntry.timerExpired = FALSE;
+ staEntry.sessionId = sessionId;
//if periodic report requested with non cached result from PE/TL
@@ -15377,7 +15404,8 @@ eHalStatus csrGetStatistics(tpAniSirGlobal pMac, eCsrStatsRequesterType requeste
//check if same request made already & waiting for rsp
pPeStaEntry = csrRoamCheckPeStatsReqList(pMac, statsMask & ~(1 << eCsrGlobalClassDStats),
- periodicity, &found, staId);
+ periodicity, &found, staId,
+ sessionId);
if(!pPeStaEntry)
{
//bail out, maxed out on number of req for PE
@@ -15462,7 +15490,10 @@ eHalStatus csrGetStatistics(tpAniSirGlobal pMac, eCsrStatsRequesterType requeste
if(statsMask & ~(1 << eCsrGlobalClassDStats))
{
//send down a req
- status = csrSendMBStatsReqMsg(pMac, statsMask & ~(1 << eCsrGlobalClassDStats), staId);
+ status = csrSendMBStatsReqMsg(pMac,
+ statsMask & ~(1 << eCsrGlobalClassDStats),
+ staId,
+ sessionId);
if(!HAL_STATUS_SUCCESS(status))
{
smsLog(pMac, LOGE, FL("csrGetStatistics:failed to send down stats req to PE"));
@@ -15675,6 +15706,7 @@ eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 command, tANI_U8 reas
eHalStatus status = eHAL_STATUS_SUCCESS;
tpCsrChannelInfo currChannelListInfo;
tANI_U32 host_channels = 0;
+ eCsrBand eBand;
tANI_U8 ChannelCacheStr[128] = {0};
currChannelListInfo = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo;
@@ -15772,27 +15804,47 @@ eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 command, tANI_U8 reas
currChannelListInfo->numOfChannels == 0)
{
- /*Retreive the Channel Cache either from ini or from the Occupied Channels list.
+ /*Retrieve the Channel Cache either from ini or from the Occupied Channels list.
* Give Preference to INI Channels.*/
if (pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels)
{
ChannelList = pNeighborRoamInfo->cfgParams.channelInfo.ChannelList;
+ /* The INI channels need to be filtered with respect to the current
+ * band that is supported.
+ */
+ eBand = pMac->roam.configParam.bandCapability;
+ if ((eCSR_BAND_24 != eBand) && (eCSR_BAND_5G != eBand) && (eCSR_BAND_ALL != eBand))
+ {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "Invalid band, No operation carried out (Band %d)", eBand);
+ vos_mem_free(pRequestBuf);
+ return eHAL_STATUS_FAILURE;
+ }
for (i=0; i<pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels ;i++)
+ {
+ if (((eCSR_BAND_24 == eBand) && CSR_IS_CHANNEL_24GHZ(*ChannelList)) ||
+ ((eCSR_BAND_5G == eBand) && CSR_IS_CHANNEL_5GHZ(*ChannelList)) ||
+ (eCSR_BAND_ALL == eBand))
{
- if(!CSR_IS_CHANNEL_DFS(*ChannelList) && *ChannelList)
- {
- pRequestBuf->ConnectedNetwork.ChannelCache[num_channels++] = *ChannelList;
- }
- ChannelList++;
+ if(!CSR_IS_CHANNEL_DFS(*ChannelList) &&
+ csrRoamIsChannelValid(pMac, *ChannelList) &&
+ *ChannelList && (num_channels < SIR_ROAM_MAX_CHANNELS))
+ {
+ pRequestBuf->ConnectedNetwork.ChannelCache[num_channels++] = *ChannelList;
+ }
+ ChannelList++;
}
- pRequestBuf->ConnectedNetwork.ChannelCount = num_channels;
- pRequestBuf->ChannelCacheType = CHANNEL_LIST_STATIC;
+ }
+ pRequestBuf->ConnectedNetwork.ChannelCount = num_channels;
+ pRequestBuf->ChannelCacheType = CHANNEL_LIST_STATIC;
}
- else{
+ else
+ {
ChannelList = pMac->scan.occupiedChannels.channelList;
for(i=0; i<pMac->scan.occupiedChannels.numChannels; i++)
{
- if(!CSR_IS_CHANNEL_DFS(*ChannelList) && *ChannelList)
+ if(!CSR_IS_CHANNEL_DFS(*ChannelList) &&
+ *ChannelList && (num_channels < SIR_ROAM_MAX_CHANNELS))
{
pRequestBuf->ConnectedNetwork.ChannelCache[num_channels++] = *ChannelList;
}
@@ -15880,6 +15932,21 @@ eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 command, tANI_U8 reas
pRequestBuf->HomeAwayTime = pMac->roam.configParam.nRoamScanHomeAwayTime;
+ /* Home Away Time should be at least equal to (MaxDwell time + (2*RFS)),
+ * where RFS is the RF Switching time. It is twice RFS to consider the
+ * time to go off channel and return to the home channel. */
+ if (pRequestBuf->HomeAwayTime < (pRequestBuf->NeighborScanChannelMaxTime + (2 * CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME)))
+ {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
+ "%s: Invalid config, Home away time(%d) is less than (twice RF switching time + channel max time)(%d)"
+ " Hence enforcing home away time to disable (0)",
+ __func__, pRequestBuf->HomeAwayTime,
+ (pRequestBuf->NeighborScanChannelMaxTime + (2 * CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME)
+ ));
+ pRequestBuf->HomeAwayTime = 0;
+ }
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,"HomeAwayTime:%d",pRequestBuf->HomeAwayTime);
+
/*Prepare a probe request for 2.4GHz band and one for 5GHz band*/
ucDot11Mode = (tANI_U8) csrTranslateToWNICfgDot11Mode(pMac,
csrFindBestPhyMode( pMac, pMac->roam.configParam.phyMode ));
@@ -15930,8 +15997,12 @@ eHalStatus csrRoamOffloadScanRspHdlr(tpAniSirGlobal pMac, tANI_U8 reason)
}
#endif
-tCsrPeStatsReqInfo * csrRoamCheckPeStatsReqList(tpAniSirGlobal pMac, tANI_U32 statsMask,
- tANI_U32 periodicity, tANI_BOOLEAN *pFound, tANI_U8 staId)
+tCsrPeStatsReqInfo * csrRoamCheckPeStatsReqList(tpAniSirGlobal pMac,
+ tANI_U32 statsMask,
+ tANI_U32 periodicity,
+ tANI_BOOLEAN *pFound,
+ tANI_U8 staId,
+ tANI_U8 sessionId)
{
tANI_BOOLEAN found = FALSE;
eHalStatus status = eHAL_STATUS_SUCCESS;
@@ -15968,6 +16039,7 @@ tCsrPeStatsReqInfo * csrRoamCheckPeStatsReqList(tpAniSirGlobal pMac, tANI_U32 s
staEntry.staId = staId;
staEntry.statsMask = statsMask;
staEntry.timerRunning = FALSE;
+ staEntry.sessionId = sessionId;
pTempStaEntry = csrRoamInsertEntryIntoPeStatsReqList(pMac, &pMac->roam.peStatsReqList, &staEntry);
if(!pTempStaEntry)
{
@@ -15997,7 +16069,10 @@ tCsrPeStatsReqInfo * csrRoamCheckPeStatsReqList(tpAniSirGlobal pMac, tANI_U32 s
if(!pTempStaEntry->rspPending &&
!pTempStaEntry->periodicity)
{
- status = csrSendMBStatsReqMsg(pMac, statsMask & ~(1 << eCsrGlobalClassDStats), staId);
+ status = csrSendMBStatsReqMsg(pMac,
+ statsMask & ~(1 << eCsrGlobalClassDStats),
+ staId,
+ sessionId);
if(!HAL_STATUS_SUCCESS(status))
{
smsLog(pMac, LOGE, FL("csrRoamCheckPeStatsReqList:failed to send down stats req to PE"));
@@ -17166,6 +17241,7 @@ VOS_STATUS csrSetCCKMIe(tpAniSirGlobal pMac, const tANI_U8 sessionId,
pSession->suppCckmIeInfo.cckmIeLen = ccKmIeLen;
return status;
}
+
/* ---------------------------------------------------------------------------
\fn csrRoamReadTSF
\brief This function reads the TSF; and also add the time elapsed since
@@ -17196,3 +17272,122 @@ VOS_STATUS csrRoamReadTSF(tpAniSirGlobal pMac, tANI_U8 *pTimestamp)
return status;
}
#endif /*FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
+
+/*
+ * Post Channel Change Request to LIM
+ * This API is primarily used to post
+ * Channel Change Req for SAP
+ */
+eHalStatus
+csrRoamChannelChangeReq( tpAniSirGlobal pMac, tANI_U32 sessionId,
+ tANI_U8 targetChannel)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tSirChanChangeRequest *pMsg;
+ tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
+
+ if (NULL == pSession)
+ {
+ smsLog( pMac, LOGE, FL
+ ( " Session does not exist for session id %d" ), sessionId);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ pMsg = vos_mem_malloc( sizeof(tSirChanChangeRequest) );
+ if (!pMsg)
+ {
+ return ( eHAL_STATUS_FAILURE );
+ }
+
+ vos_mem_set((void *)pMsg, sizeof( tSirChanChangeRequest ), 0);
+
+ pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_CHANNEL_CHANGE_REQ);
+ pMsg->messageLen = sizeof(tSirChanChangeRequest);
+ pMsg->sessionId = pSession->sessionId;
+ pMsg->targetChannel = targetChannel;
+
+ status = palSendMBMessage(pMac->hHdd, pMsg);
+
+ return ( status );
+}
+
+/*
+ * Post Beacon Tx Start request to LIM
+ * immediately after SAP CAC WAIT is
+ * completed without any RADAR indications.
+ */
+eHalStatus csrRoamStartBeaconReq( tpAniSirGlobal pMac, tANI_U32 sessionId,
+ tANI_U8 dfsCacWaitStatus)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tSirStartBeaconIndication *pMsg;
+ tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
+
+ if (NULL == pSession)
+ {
+ smsLog( pMac, LOGE, FL
+ ( " Session does not exist for session id %d" ), sessionId);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ pMsg = vos_mem_malloc(sizeof(tSirStartBeaconIndication));
+
+ if (!pMsg)
+ {
+ return eHAL_STATUS_FAILURE;
+ }
+
+ vos_mem_set((void *)pMsg, sizeof( tSirStartBeaconIndication ), 0);
+ pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_START_BEACON_REQ);
+ pMsg->messageLen = sizeof(tSirStartBeaconIndication);
+ pMsg->sessionId = pSession->sessionId;
+ pMsg->beaconStartStatus = dfsCacWaitStatus;
+
+ status = palSendMBMessage(pMac->hHdd, pMsg);
+
+ return ( status );
+}
+
+/*----------------------------------------------------------------------------
+ \fn csrRoamSendChanSwIERequest
+ \brief This function sends request to transmit channel switch announcement
+ IE to lower layers
+ \param pMac - pMac global structure
+ \param sessionId - SME session id
+ \param pDfsCacInd - CAC indication data to PE/LIM
+ \- return Success or failure
+-----------------------------------------------------------------------------*/
+eHalStatus
+csrRoamSendChanSwIERequest(tpAniSirGlobal pMac, tANI_U8 sessionId,
+ tANI_U8 targetChannel, tANI_U8 csaIeReqd)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tSirDfsCsaIeRequest *pMsg;
+ tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
+
+ if (NULL == pSession)
+ {
+ smsLog( pMac, LOGE, FL
+ ( " Session does not exist for session id %d" ), sessionId);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ pMsg = vos_mem_malloc(sizeof(tSirDfsCsaIeRequest));
+ if (!pMsg)
+ {
+ return eHAL_STATUS_FAILURE;
+ }
+
+ vos_mem_set((void *)pMsg, sizeof(tSirDfsCsaIeRequest), 0);
+ pMsg->msgType =
+ pal_cpu_to_be16((tANI_U16)eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ);
+ pMsg->msgLen = sizeof(tSirDfsCsaIeRequest);
+
+ pMsg->sessionId = pSession->sessionId;
+ pMsg->targetChannel = targetChannel;
+ pMsg->csaIeRequired = csaIeReqd;
+
+ status = palSendMBMessage(pMac->hHdd, pMsg);
+
+ return status;
+}
diff --git a/CORE/SME/src/csr/csrApiScan.c b/CORE/SME/src/csr/csrApiScan.c
index bff7305a1322..015e89870bbf 100644
--- a/CORE/SME/src/csr/csrApiScan.c
+++ b/CORE/SME/src/csr/csrApiScan.c
@@ -2203,7 +2203,7 @@ eHalStatus csrScanGetResult(tpAniSirGlobal pMac, tCsrScanResultFilter *pFilter,
/* re-assign preference value based on modified rssi bucket */
pBssDesc->preferValue = csrGetBssPreferValue(pMac, (int)pBssDesc->Result.BssDescriptor.rssi);
- smsLog(pMac, LOG2, FL("BSSID(%02X:%02X:%02X:%02X:%02X:%02X) Rssi(%d) Chnl(%d) PrefVal(%lu) SSID=%.*s"),
+ smsLog(pMac, LOG2, FL("BSSID(%02X:%02X:%02X:%02X:%02X:%02X) Rssi(%d) Chnl(%d) PrefVal(%u) SSID=%.*s"),
pBssDesc->Result.BssDescriptor.bssId[0],
pBssDesc->Result.BssDescriptor.bssId[1],
pBssDesc->Result.BssDescriptor.bssId[2],
diff --git a/CORE/SME/src/pmc/pmc.c b/CORE/SME/src/pmc/pmc.c
index de1524dbecea..6fadfc62ba27 100644
--- a/CORE/SME/src/pmc/pmc.c
+++ b/CORE/SME/src/pmc/pmc.c
@@ -3317,7 +3317,6 @@ eHalStatus pmcOffloadEnterPowersaveState(tpAniSirGlobal pMac, tANI_U32 sessionId
{
pmc->pmcState = UAPSD;
pmc->uapsdStatus = PMC_UAPSD_ENABLED;
- pmc->uapsdSessionRequired = FALSE;
/* Call registered uapsd cbs */
pmcOffloadDoStartUapsdCallbacks(pMac, sessionId, eHAL_STATUS_SUCCESS);
}
@@ -3346,7 +3345,7 @@ eHalStatus pmcOffloadEnterPowersaveState(tpAniSirGlobal pMac, tANI_U32 sessionId
eHAL_STATUS_FAILURE);
}
}
- else if(pmc->uapsdSessionRequired)
+ else if((UAPSD != pmc->pmcState) && pmc->uapsdSessionRequired)
{
if(eHAL_STATUS_FAILURE ==
pmcOffloadQueueStartUapsdRequest(pMac, sessionId))
@@ -3387,7 +3386,6 @@ eHalStatus pmcOffloadExitPowersaveState(tpAniSirGlobal pMac, tANI_U32 sessionId)
if(PMC_UAPSD_DISABLE_PENDING == pmc->uapsdStatus)
{
- pmc->uapsdSessionRequired = FALSE;
pmc->uapsdStatus = PMC_UAPSD_DISABLED;
}
@@ -3458,7 +3456,7 @@ void pmcOffloadExitBmpsIndHandler(tpAniSirGlobal pMac, tSirSmeRsp *pMsg)
else
{
smsLog(pMac, LOG1,
- FL("Exit BMPS indication on session %lu, reason %d"),
+ FL("Exit BMPS indication on session %u, reason %d"),
pExitBmpsInd->smeSessionId, pExitBmpsInd->exitBmpsReason);
pmcOffloadQueueRequestFullPower(pMac, pExitBmpsInd->smeSessionId,
pExitBmpsInd->exitBmpsReason);
diff --git a/CORE/SME/src/pmc/pmcApi.c b/CORE/SME/src/pmc/pmcApi.c
index 5d9691e849e8..eb7bc507ac00 100644
--- a/CORE/SME/src/pmc/pmcApi.c
+++ b/CORE/SME/src/pmc/pmcApi.c
@@ -4260,3 +4260,48 @@ eHalStatus pmcOffloadSetTdlsProhibitBmpsStatus(tHalHandle hHal,
return eHAL_STATUS_SUCCESS;
}
#endif
+
+/******************************************************************************
+*
+* Name: pmcOffloadIsPowerSaveEnabled
+*
+* Description:
+* Checks if the device is able to enter one of the power save modes.
+* "Able to enter" means the power save mode is enabled for the device
+* and the host is using the correct power source for entry into the
+* power save mode. This routine does not indicate whether the device
+* is actually in the power save mode at a particular point in time.
+*
+* Parameters:
+* hHal - HAL handle for device
+* psMode - the power saving mode
+*
+* Returns:
+* TRUE if device is able to enter the power save mode, FALSE otherwise
+*
+******************************************************************************/
+tANI_BOOLEAN pmcOffloadIsPowerSaveEnabled (tHalHandle hHal, tANI_U32 sessionId,
+ tPmcPowerSavingMode psMode)
+{
+ tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+ tpPsOffloadPerSessionInfo pmc = &pMac->pmcOffloadInfo.pmc[sessionId];
+
+ pmcLog(pMac, LOG2, FL("Entering pmcIsPowerSaveEnabled, power save mode %d"),
+ psMode);
+
+ /* Check ability to enter based on the specified power saving mode. */
+ switch (psMode)
+ {
+ case ePMC_BEACON_MODE_POWER_SAVE:
+ return pMac->pmcOffloadInfo.staPsEnabled;
+
+ case ePMC_UAPSD_MODE_POWER_SAVE:
+ return pmc->UapsdEnabled;
+
+ default:
+ pmcLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode);
+ PMC_ABORT;
+ return FALSE;
+ }
+}
+
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index f701be8cde88..af6b33cdff84 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -114,6 +114,14 @@ eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal,
tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm );
#endif
+/* Message processor for events from DFS */
+eHalStatus dfsMsgProcessor(tpAniSirGlobal pMac,
+ v_U16_t msg_type,void *pMsgBuf);
+
+/* Channel Change Response Indication Handler */
+eHalStatus sme_ProcessChannelChangeResp(tpAniSirGlobal pMac,
+ v_U16_t msg_type,void *pMsgBuf);
+
//Internal SME APIs
eHalStatus sme_AcquireGlobalLock( tSmeStruct *psSme)
{
@@ -1898,6 +1906,65 @@ eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal,
}
#endif
+/*------------------------------------------------------------------
+ *
+ * Handle the DFS Radar Event and indicate it to the SAP
+ *
+ *------------------------------------------------------------------*/
+eHalStatus dfsMsgProcessor(tpAniSirGlobal pMac, v_U16_t msgType, void *pMsgBuf)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tCsrRoamInfo roamInfo = {0};
+ tSirSmeDfsEventInd *dfs_event;
+ tANI_U32 sessionId = 0;
+ eRoamCmdStatus roamStatus;
+ eCsrRoamResult roamResult;
+
+ switch (msgType)
+ {
+ case eWNI_SME_DFS_RADAR_FOUND:
+ {
+ /* Radar found !! */
+ dfs_event = (tSirSmeDfsEventInd *)pMsgBuf;
+ if (NULL == dfs_event)
+ {
+ smsLog(pMac, LOGE,
+ "%s: pMsg is NULL for eWNI_SME_DFS_RADAR_FOUND message",
+ __func__);
+ return eHAL_STATUS_FAILURE;
+ }
+ sessionId = dfs_event->sessionId;
+ roamInfo.dfs_event.sessionId = sessionId;
+ roamInfo.dfs_event.ieee_chan_number = dfs_event->ieee_chan_number;
+ roamInfo.dfs_event.chan_freq = dfs_event->chan_freq;
+ roamInfo.dfs_event.dfs_radar_status = dfs_event->dfs_radar_status;
+ roamInfo.dfs_event.use_nol = dfs_event->use_nol;
+
+ roamStatus = eCSR_ROAM_DFS_RADAR_IND;
+ roamResult = eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND;
+ break;
+ }
+ case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND:
+ {
+ roamStatus = eCSR_ROAM_DFS_CHAN_SW_NOTIFY;
+ roamResult = eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS;
+ break;
+ }
+ default:
+ {
+ smsLog(pMac, LOG1, "%s: Invalid DFS message = 0x%x", __func__,
+ msgType);
+ status = eHAL_STATUS_FAILURE;
+ return status;
+ }
+ }
+
+ /* Indicate Radar Event to SAP */
+ csrRoamCallCallback(pMac, sessionId, &roamInfo, 0,
+ roamStatus, roamResult);
+ return status;
+}
+
#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
/*------------------------------------------------------------------
*
@@ -2417,6 +2484,28 @@ eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg)
break;
#endif /* FEATURE_WLAN_CH_AVOID */
+ case eWNI_SME_DFS_RADAR_FOUND:
+ case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND:
+ {
+ status = dfsMsgProcessor(pMac, pMsg->type, pMsg->bodyptr);
+ vos_mem_free( pMsg->bodyptr );
+ }
+ break;
+
+ case eWNI_SME_CHANNEL_CHANGE_RSP:
+ if (pMsg->bodyptr)
+ {
+ status = sme_ProcessChannelChangeResp(pMac,
+ pMsg->type, pMsg->bodyptr);
+ vos_mem_free( pMsg->bodyptr );
+ }
+ else
+ {
+ smsLog( pMac, LOGE,
+ "Empty rsp message for (eWNI_SME_CHANNEL_CHANGE_RSP),"
+ "nothing to process");
+ }
+ break ;
default:
if ( ( pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN )
@@ -4091,10 +4180,13 @@ eHalStatus sme_QueryPowerState (
\brief Checks if the device is able to enter a particular power save mode
This does not imply that the device is in a particular PS mode
\param hHal - The handle returned by macOpen.
+ \param sessionId - sme session id
\param psMode - the power saving mode
\return eHalStatus
---------------------------------------------------------------------------*/
-tANI_BOOLEAN sme_IsPowerSaveEnabled (tHalHandle hHal, tPmcPowerSavingMode psMode)
+tANI_BOOLEAN sme_IsPowerSaveEnabled (tHalHandle hHal,
+ tANI_U32 sessionId,
+ tPmcPowerSavingMode psMode)
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
@@ -4105,7 +4197,10 @@ tANI_BOOLEAN sme_IsPowerSaveEnabled (tHalHandle hHal, tPmcPowerSavingMode psMode
status = sme_AcquireGlobalLock( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
- result = pmcIsPowerSaveEnabled(hHal, psMode);
+ if(!pMac->psOffloadEnabled)
+ result = pmcIsPowerSaveEnabled(hHal, psMode);
+ else
+ result = pmcOffloadIsPowerSaveEnabled(hHal, sessionId, psMode);
sme_ReleaseGlobalLock( &pMac->sme );
return result;
}
@@ -4786,13 +4881,15 @@ eHalStatus sme_GetTsmStats(tHalHandle hHal,
\param cache - If requester is happy with cached stats
\param staId - The station ID for which the stats is requested for
\param pContext - user context to be passed back along with the callback
+ \param sessionId - sme session interface
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_GetStatistics(tHalHandle hHal, eCsrStatsRequesterType requesterId,
tANI_U32 statsMask,
tCsrStatsCallback callback,
tANI_U32 periodicity, tANI_BOOLEAN cache,
- tANI_U8 staId, void *pContext)
+ tANI_U8 staId, void *pContext,
+ tANI_U8 sessionId)
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
@@ -4801,7 +4898,8 @@ eHalStatus sme_GetStatistics(tHalHandle hHal, eCsrStatsRequesterType requesterId
if ( HAL_STATUS_SUCCESS( status ) )
{
status = csrGetStatistics( pMac, requesterId , statsMask, callback,
- periodicity, cache, staId, pContext);
+ periodicity, cache, staId, pContext,
+ sessionId );
sme_ReleaseGlobalLock( &pMac->sme );
}
@@ -9404,26 +9502,20 @@ eHalStatus sme_ChangeRoamScanChannelList(tHalHandle hHal, tANI_U8 *pChannelList,
}
csrFlushCfgBgScanRoamChannelList(pMac);
csrCreateBgScanRoamChannelList(pMac, pChannelList, numChannels);
- status = csrUpdateBgScanConfigIniChannelList(pMac, csrGetCurrentBand(hHal));
-
- if ( HAL_STATUS_SUCCESS( status ))
+ sme_SetRoamScanControl(hHal, 1);
+ if (NULL != pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
{
- sme_SetRoamScanControl(hHal, 1);
- if (NULL != pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
+ j = 0;
+ for (i = 0; i < pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; i++)
{
- j = 0;
- for (i = 0; i < pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; i++)
- {
- j += snprintf(newChannelList + j, sizeof(newChannelList) - j," %d",
- pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]);
- }
+ j += snprintf(newChannelList + j, sizeof(newChannelList) - j," %d",
+ pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]);
}
-
- VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
- "LFR runtime successfully set roam scan channels to %s - old value is %s - roam state is %d",
- newChannelList, oldChannelList,
- pMac->roam.neighborRoamInfo.neighborRoamState);
}
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
+ "LFR runtime successfully set roam scan channels to %s - old value is %s - roam state is %d",
+ newChannelList, oldChannelList,
+ pMac->roam.neighborRoamInfo.neighborRoamState);
sme_ReleaseGlobalLock( &pMac->sme );
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
@@ -9506,21 +9598,6 @@ eHalStatus sme_SetCcxRoamScanChannelList(tHalHandle hHal,
#endif
/*--------------------------------------------------------------------------
- \brief csrUpdateBgScanConfigIniChannelList() - Update bgscan roam cache
- This is a synchronous call
- \param hHal - The handle returned by macOpen.
- \return eHAL_STATUS_SUCCESS - SME update config successful.
- Other status means SME is failed to update
- \sa
- --------------------------------------------------------------------------*/
-eHalStatus sme_UpdateBgScanConfigIniChannelList(tHalHandle hHal,
- eCsrBand eBand)
-{
- tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
- return csrUpdateBgScanConfigIniChannelList(pMac, eBand);
-}
-
-/*--------------------------------------------------------------------------
\brief sme_getRoamScanChannelList() - get roam scan channel list
This is a synchronous call
\param hHal - The handle returned by macOpen.
@@ -10830,3 +10907,129 @@ eHalStatus sme_AddChAvoidCallback
}
#endif /* FEATURE_WLAN_CH_AVOID */
+/* -------------------------------------------------------------------------
+ \fn sme_RoamChannelChangeReq
+ \brief API to Indicate Channel change to new target channel
+ \param hHal - The handle returned by macOpen
+ \param sessionId - session ID
+ \param targetChannel - New Channel to move the SAP to.
+ \return eHalStatus
+---------------------------------------------------------------------------*/
+eHalStatus sme_RoamChannelChangeReq( tHalHandle hHal,
+ tANI_U8 sessionId, tANI_U8 targetChannel )
+{
+ eHalStatus status = eHAL_STATUS_FAILURE;
+ tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+ status = sme_AcquireGlobalLock( &pMac->sme );
+ if ( HAL_STATUS_SUCCESS( status ) )
+ {
+ status = csrRoamChannelChangeReq( pMac, sessionId, targetChannel);
+
+ sme_ReleaseGlobalLock( &pMac->sme );
+ }
+ return (status);
+}
+
+/* -------------------------------------------------------------------------
+ \fn sme_ProcessChannelChangeResp
+ \brief API to Indicate Channel change response message to SAP.
+ \return eHalStatus
+---------------------------------------------------------------------------*/
+eHalStatus sme_ProcessChannelChangeResp(tpAniSirGlobal pMac,
+ v_U16_t msg_type, void *pMsgBuf)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tCsrRoamInfo pRoamInfo = {0};
+ eCsrRoamResult roamResult;
+ tpSwitchChannelParams pChnlParams = (tpSwitchChannelParams) pMsgBuf;
+ tANI_U32 SessionId = pChnlParams->peSessionId;
+
+ pRoamInfo.channelChangeRespEvent =
+ (tSirChanChangeResponse *)vos_mem_malloc(
+ sizeof(tSirChanChangeResponse));
+ if (NULL == pRoamInfo.channelChangeRespEvent)
+ {
+ status = eHAL_STATUS_FAILURE;
+ smsLog(pMac, LOGE, "Channel Change Event Allocation Failed: %d\n",
+ status);
+ return status;
+ }
+ if (msg_type == eWNI_SME_CHANNEL_CHANGE_RSP)
+ {
+ pRoamInfo.channelChangeRespEvent->sessionId = SessionId;
+ pRoamInfo.channelChangeRespEvent->newChannelNumber =
+ pChnlParams->channelNumber;
+ pRoamInfo.channelChangeRespEvent->secondaryChannelOffset =
+ pChnlParams->secondaryChannelOffset;
+
+ if (pChnlParams->status == eHAL_STATUS_SUCCESS)
+ {
+ pRoamInfo.channelChangeRespEvent->channelChangeStatus = 1;
+ roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS;
+ }
+ else
+ {
+ pRoamInfo.channelChangeRespEvent->channelChangeStatus = 0;
+ roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE;
+ }
+
+ csrRoamCallCallback(pMac, SessionId, &pRoamInfo, 0,
+ eCSR_ROAM_SET_CHANNEL_RSP, roamResult);
+
+ }
+ else
+ {
+ status = eHAL_STATUS_FAILURE;
+ smsLog(pMac, LOGE, "Invalid Channel Change Resp Message: %d\n",
+ status);
+ }
+ return status;
+}
+
+/* -------------------------------------------------------------------------
+ \fn sme_RoamStartBeaconReq
+ \brief API to Indicate LIM to start Beacon Tx
+ \after SAP CAC Wait is completed.
+ \param hHal - The handle returned by macOpen
+ \param sessionId - session ID
+ \param dfsCacWaitStatus - CAC WAIT status flag
+ \return eHalStatus
+---------------------------------------------------------------------------*/
+eHalStatus sme_RoamStartBeaconReq( tHalHandle hHal, tANI_U8 sessionId,
+ tANI_U8 dfsCacWaitStatus)
+{
+ eHalStatus status = eHAL_STATUS_FAILURE;
+ tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+ status = sme_AcquireGlobalLock( &pMac->sme );
+
+ if ( HAL_STATUS_SUCCESS( status ) )
+ {
+ status = csrRoamStartBeaconReq( pMac, sessionId, dfsCacWaitStatus);
+ sme_ReleaseGlobalLock( &pMac->sme );
+ }
+ return (status);
+}
+
+/* -------------------------------------------------------------------------
+ \fn sme_RoamCsaIeRequest
+ \brief API to request CSA IE transmission from PE
+ \param hHal - The handle returned by macOpen
+ \param sessionId - session ID
+ \param pDfsCsaReq - CSA IE request
+ \return eHalStatus
+---------------------------------------------------------------------------*/
+eHalStatus sme_RoamCsaIeRequest(tHalHandle hHal, tANI_U8 sessionId,
+ tANI_U8 targetChannel, tANI_U8 csaIeReqd)
+{
+ eHalStatus status = eHAL_STATUS_FAILURE;
+ tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+ status = sme_AcquireGlobalLock( &pMac->sme );
+ if ( HAL_STATUS_SUCCESS( status ) )
+ {
+ status = csrRoamSendChanSwIERequest(pMac, sessionId,
+ targetChannel, csaIeReqd);
+ sme_ReleaseGlobalLock( &pMac->sme );
+ }
+ return (status);
+}
+
diff --git a/CORE/SME/src/sme_common/sme_Trace.c b/CORE/SME/src/sme_common/sme_Trace.c
index 72196d934aba..aa6a872d9fbc 100644
--- a/CORE/SME/src/sme_common/sme_Trace.c
+++ b/CORE/SME/src/sme_common/sme_Trace.c
@@ -31,12 +31,6 @@
\author Kiran Kumar Reddy CH L V
- Copyright (c) 2013 Qualcomm Atheros, Inc.
-
- All Rights Reserved.
-
- Qualcomm Atheros Confidential and Proprietary.
-
========================================================================*/
#include "aniGlobal.h" //for tpAniSirGlobal
#include "smsDebug.h"
diff --git a/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c b/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c
index c6fb96df19f5..13b600c2998f 100644
--- a/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c
+++ b/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c
@@ -196,24 +196,24 @@ static void ptt_proc_quarky_msg(tAniNlHdr *wnl, tAniHdr *wmsg, int radio)
{
case PTT_MSG_READ_REGISTER:
reg_addr = *(v_U32_t*) ((char*)wmsg + 8);
- PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_READ_REGISTER [0x%08lX]\n",
+ PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_READ_REGISTER [0x%08X]\n",
__func__, reg_addr);
vosStatus = sme_DbgReadRegister(pAdapterHandle->hHal, reg_addr, &reg_val);
*(v_U32_t*) ((char*)wmsg + 12) = reg_val;
if(vosStatus != VOS_STATUS_SUCCESS)
- PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Read Register [0x%08lX] failed!!\n",
+ PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Read Register [0x%08X] failed!!\n",
__func__, reg_addr);
ptt_sock_send_msg_to_app(wmsg, 0, ANI_NL_MSG_PUMAC, wnl->nlh.nlmsg_pid);
break;
case PTT_MSG_WRITE_REGISTER:
reg_addr = *(v_U32_t*) ((const unsigned char*)wmsg + 8);
reg_val = *(v_U32_t*)((const unsigned char*)wmsg + 12);
- PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_WRITE_REGISTER Addr [0x%08lX] value [0x%08lX]\n",
+ PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_WRITE_REGISTER Addr [0x%08X] value [0x%08X]\n",
__func__, reg_addr, reg_val);
vosStatus = sme_DbgWriteRegister(pAdapterHandle->hHal, reg_addr, reg_val);
if(vosStatus != VOS_STATUS_SUCCESS)
{
- PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Write Register [0x%08lX] value [0x%08lX] failed!!\n",
+ PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Write Register [0x%08X] value [0x%08X] failed!!\n",
__func__, reg_addr, reg_val);
}
//send message to the app
@@ -222,12 +222,12 @@ static void ptt_proc_quarky_msg(tAniNlHdr *wnl, tAniHdr *wmsg, int radio)
case PTT_MSG_READ_MEMORY:
reg_addr = *(v_U32_t*) ((char*)wmsg + 8);
len_payload = *(v_U32_t*) ((char*)wmsg + 12);
- PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_READ_MEMORY addr [0x%08lX] bytes [0x%08lX]\n",
+ PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_READ_MEMORY addr [0x%08X] bytes [0x%08X]\n",
__func__, reg_addr, len_payload);
buf = (v_U8_t*)wmsg + 16;
vosStatus = sme_DbgReadMemory(pAdapterHandle->hHal, reg_addr, buf, len_payload);
if(vosStatus != VOS_STATUS_SUCCESS) {
- PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Memory read failed for [0x%08lX]!!\n",
+ PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Memory read failed for [0x%08X]!!\n",
__func__, reg_addr);
}
ptt_sock_swap_32(buf, len_payload);
@@ -237,14 +237,14 @@ static void ptt_proc_quarky_msg(tAniNlHdr *wnl, tAniHdr *wmsg, int radio)
case PTT_MSG_WRITE_MEMORY:
reg_addr = *(v_U32_t*) ((char*)wmsg + 8);
len_payload = *(v_U32_t*) ((char*)wmsg + 12);
- PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_DBG_WRITE_MEMORY addr [0x%08lX] bytes [0x%08lX]\n",
+ PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_DBG_WRITE_MEMORY addr [0x%08X] bytes [0x%08X]\n",
__func__, reg_addr, len_payload);
buf = (v_U8_t*)wmsg + 16;
ptt_sock_swap_32(buf, len_payload);
vosStatus = sme_DbgWriteMemory(pAdapterHandle->hHal, reg_addr, buf, len_payload);
if(vosStatus != VOS_STATUS_SUCCESS)
{
- PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Memory write failed for addr [0x%08lX]!!\n",
+ PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Memory write failed for addr [0x%08X]!!\n",
__func__, reg_addr);
}
//send message to the app
diff --git a/CORE/SYS/common/src/wlan_qct_sys.c b/CORE/SYS/common/src/wlan_qct_sys.c
index 328ec951319e..ff5a8bec0e37 100644
--- a/CORE/SYS/common/src/wlan_qct_sys.c
+++ b/CORE/SYS/common/src/wlan_qct_sys.c
@@ -380,16 +380,12 @@ VOS_STATUS sysMcProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg )
case SYS_MSG_ID_MC_TIMER:
{
- vos_timer_callback_t timerCB;
- // hummmm... note says...
- // invoke the timer callback and the user data stick
- // into the bodyval; no body to free. I think this is
- // what that means.
- timerCB = (vos_timer_callback_t)pMsg->bodyptr;
-
- // make the callback to the timer routine...
- timerCB( (v_VOID_t *)pMsg->bodyval );
+ vos_timer_callback_t timerCB = pMsg->callback;
+ if (NULL != timerCB)
+ {
+ timerCB(pMsg->bodyptr);
+ }
break;
}
case SYS_MSG_ID_FTM_RSP:
@@ -469,17 +465,12 @@ VOS_STATUS sysTxProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg )
case SYS_MSG_ID_TX_TIMER:
{
- vos_timer_callback_t timerCB;
-
- // hummmm... note says...
- // invoke the timer callback and the user data stick
- // into the bodyval; no body to free. I think this is
- // what that means.
- timerCB = (vos_timer_callback_t)pMsg->bodyptr;
-
- // make the callback to the timer routine...
- timerCB( (v_VOID_t *)pMsg->bodyval );
+ vos_timer_callback_t timerCB = pMsg->callback;
+ if (NULL != timerCB)
+ {
+ timerCB(pMsg->bodyptr);
+ }
break;
}
@@ -526,17 +517,12 @@ VOS_STATUS sysRxProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg )
{
case SYS_MSG_ID_RX_TIMER:
{
- vos_timer_callback_t timerCB;
-
- // hummmm... note says...
- // invoke the timer callback and the user data stick
- // into the bodyval; no body to free. I think this is
- // what that means.
- timerCB = (vos_timer_callback_t)pMsg->bodyptr;
-
- // make the callback to the timer routine...
- timerCB( (v_VOID_t *)pMsg->bodyval );
+ vos_timer_callback_t timerCB = pMsg->callback;
+ if (NULL != timerCB)
+ {
+ timerCB(pMsg->bodyptr);
+ }
break;
}
diff --git a/CORE/TL/inc/wlan_qct_tl.h b/CORE/TL/inc/wlan_qct_tl.h
index dc54fd115627..898c6ce1df20 100644
--- a/CORE/TL/inc/wlan_qct_tl.h
+++ b/CORE/TL/inc/wlan_qct_tl.h
@@ -1298,39 +1298,6 @@ adf_nbuf_t WLANTL_SendSTA_DataFrame(v_PVOID_t pvosGCtx, v_U8_t ucSTAId,
adf_nbuf_t buf);
#endif
-#ifdef IPA_OFFLOAD
-/*===========================================================================
-
- FUNCTION WLANTL_SendIPA_DataFrame
-
- DESCRIPTION
-
- HDD will call this API when there is a packet to be transmitted from IPA
-
- DEPENDENCIES
-
- A station must have been registered before sending packet to txrx layer
-
-
- PARAMETERS
-
- vos_ctx: pointer to the global vos context; a handle to TL's
- control block can be extracted from its context
- vdev: virtual device
- buf: packet given by uppler layer for tx
-
- RETURN VALUE
-
- On success it will return NULL. On failure it will be the
- passed buf pointer so that the caller will be able to free
- up the buffer.
-
-============================================================================*/
-adf_nbuf_t WLANTL_SendIPA_DataFrame(void *vos_ctx, void *vdev,
- adf_nbuf_t buf);
-#endif
-
-
/*==========================================================================
FUNCTION WLANTL_SetSTAPriority
diff --git a/CORE/TL/src/wlan_qct_tl.c b/CORE/TL/src/wlan_qct_tl.c
index e68f1926e0c4..5e90b7593a6b 100644
--- a/CORE/TL/src/wlan_qct_tl.c
+++ b/CORE/TL/src/wlan_qct_tl.c
@@ -5846,7 +5846,7 @@ WLANTL_RxFrames
broadcast = VOS_FALSE;
#else
vosStatus = WLANTL_ReadRSSI(pvosGCtx, pvBDHeader, ucSTAId);
-#endif /*FEATURE_WLAN_GEN6_ROAMING*/
+#endif
if (!VOS_IS_STATUS_SUCCESS(vosStatus))
{
TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,
@@ -6148,7 +6148,7 @@ WLANTL_RxCachedFrames
broadcast = VOS_FALSE;
#else
vosStatus = WLANTL_ReadRSSI(vos_get_global_context(VOS_MODULE_ID_TL,pTLCb), pvBDHeader, ucSTAId);
-#endif /*FEATURE_WLAN_GEN6_ROAMING*/
+#endif
if(!VOS_IS_STATUS_SUCCESS(vosStatus))
{
TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
diff --git a/CORE/TL/src/wlan_qct_tl_hosupport.c b/CORE/TL/src/wlan_qct_tl_hosupport.c
index 911acde7f863..6d7007bb48f6 100644
--- a/CORE/TL/src/wlan_qct_tl_hosupport.c
+++ b/CORE/TL/src/wlan_qct_tl_hosupport.c
@@ -2031,4 +2031,4 @@ VOS_STATUS WLANTL_HSSerializeTlIndication
return status;
}
-#endif //FEATURE_WLAN_GEN6_ROAMING || WLAN_FEATURE_NEIGHBOR_ROAMING
+#endif //WLAN_FEATURE_NEIGHBOR_ROAMING
diff --git a/CORE/TL/src/wlan_qct_tl_hosupport.h b/CORE/TL/src/wlan_qct_tl_hosupport.h
index e75aefd697ed..72ac18473985 100644
--- a/CORE/TL/src/wlan_qct_tl_hosupport.h
+++ b/CORE/TL/src/wlan_qct_tl_hosupport.h
@@ -301,6 +301,6 @@ VOS_STATUS WLANTL_StatHandleTXFrame
WLANTL_MetaInfoType *txMetaInfo
);
-#endif //FEATURE_WLAN_GEN6_ROAMING
+#endif
#endif /* WLAN_QCT_TL_HOSUPPORT_H */
diff --git a/CORE/UTILS/FWLOG/dbglog_host.c b/CORE/UTILS/FWLOG/dbglog_host.c
index d04931d536fb..d8163120798c 100644
--- a/CORE/UTILS/FWLOG/dbglog_host.c
+++ b/CORE/UTILS/FWLOG/dbglog_host.c
@@ -24,21 +24,6 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-/*
- * Copyright (c) 2013, Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
/* Host Debug log implementation */
@@ -513,8 +498,24 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"COEX_MWS_REMOTE_EVENT",
"COEX_MWS_OTHER",
"COEX_MWS_ERROR",
- "COEX_MWS_ANT_DIVERSITY",
- "COEX_DEBUG_ID_END"
+ "COEX_MWS_ANT_DIVERSITY", //237
+ "COEX_P2P_GO",
+ "COEX_P2P_CLIENT",
+ "COEX_SCC_1",
+ "COEX_SCC_2",
+ "COEX_MCC_1",
+ "COEX_MCC_2",
+ "COEX_TRF_SHAPE_NOA",
+ "COEX_NOA_ONESHOT",
+ "COEX_NOA_PERIODIC",
+ "COEX_LE_1",
+ "COEX_LE_2",
+ "COEX_ANT_1",
+ "COEX_ANT_2",
+ "COEX_ENTER_NOA",
+ "COEX_EXIT_NOA",
+ "COEX_BT_SCAN_PROTECT", // 253
+ "COEX_DEBUG_ID_END" // 254
},
{
"ROAM_DBGID_DEFINITION_START",
@@ -645,6 +646,7 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"VDEV_MGR_VDEV_PAUSE_DELAY_UPDATE",
"VDEV_MGR_VDEV_PAUSE_FAIL",
"VDEV_MGR_GEN_PERIODIC_NOA",
+ "VDEV_MGR_OFF_CHAN_GO_CH_REQ_SETUP",
"VDEV_MGR_DEFINITION_END",
},
{
@@ -896,6 +898,7 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"P2P_GO_GET_NOA_INFO",
"P2P_GO_ADD_ONE_SHOT_NOA",
"P2P_GO_GET_NOA_IE",
+ "P2P_GO_BCN_TX_COMP",
"P2P_DBGID_DEFINITION_END",
},
{
diff --git a/CORE/VOSS/inc/i_vos_packet.h b/CORE/VOSS/inc/i_vos_packet.h
index 9e390736c0c8..0bdb3d572de9 100644
--- a/CORE/VOSS/inc/i_vos_packet.h
+++ b/CORE/VOSS/inc/i_vos_packet.h
@@ -62,6 +62,7 @@ typedef struct
u_int8_t offloadScanLearn:1;
u_int8_t roamCandidateInd:1;
u_int8_t scan:1;
+ u_int8_t dpuFeedback;
}t_packetmeta, *tp_packetmeta;
/* implementation specific vos packet type */
diff --git a/CORE/VOSS/inc/packet.h b/CORE/VOSS/inc/packet.h
deleted file mode 100644
index 18af00f8c804..000000000000
--- a/CORE/VOSS/inc/packet.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
- *
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file was originally distributed by Qualcomm Atheros, Inc.
- * under proprietary terms before Copyright ownership was assigned
- * to the Linux Foundation.
- */
-
-/**========================================================================
-
- \file packet.h
- \brief
-
- ========================================================================*/
-/**=========================================================================
- EDIT HISTORY FOR FILE
-
-
- This section contains comments describing changes made to the module.
- Notice that changes are listed in reverse chronological order.
-
- $Header:$ $DateTime: $ $Author: $
-
-
- when who what, where, why
- -------- --- -----------------------------------------
- 26/03/2013 Ganesh Created module for Packet Handling
- Babu
- ==========================================================================*/
-#ifndef _PACKET_H_
-#define _PACKET_H_
-#include "adf_os_types.h"
-
-/*
- * Rx Packet Struct
- */
-typedef struct
-{
- u_int8_t channel;
- u_int8_t snr;
- u_int32_t rssi;
- u_int32_t timestamp;
- u_int8_t *mpdu_hdr_ptr;
- u_int8_t *mpdu_data_ptr;
- u_int32_t mpdu_len;
- u_int32_t mpdu_hdr_len;
- u_int32_t mpdu_data_len;
-}t_rxpacketmeta, *tp_rxpacketmeta;
-
-typedef struct
-{
- /* Rx Packet Meta Information */
- t_rxpacketmeta rxpktmeta;
-
- /* Pointer to Rx Packet */
- void *rx_nbuf;
-
-}t_rxpacket, *tp_rxpacket;
-
-/**
- * voss_rx_packet_free Free the Rx Packet
- * @ Rx Packet
- */
-void voss_rx_packet_free(void* rxpacket);
-
-#endif //_PACKET_H_
-
diff --git a/CORE/VOSS/inc/vos_mq.h b/CORE/VOSS/inc/vos_mq.h
index ac7b150e7212..7654aa80f89d 100644
--- a/CORE/VOSS/inc/vos_mq.h
+++ b/CORE/VOSS/inc/vos_mq.h
@@ -77,9 +77,15 @@ typedef struct vos_msg_s
* Messages should use either bodyptr or bodyval; not both !!!.
*/
void *bodyptr;
-
- v_U32_t bodyval;
-
+
+ v_U32_t bodyval;
+
+ /*
+ * Some messages provide a callback function. The function signature
+ * must be agreed upon between the two entities exchanging the message
+ */
+ void *callback;
+
} vos_msg_t;
diff --git a/CORE/VOSS/inc/vos_utils.h b/CORE/VOSS/inc/vos_utils.h
index c3f0aba1cc33..1ddf2dcb8000 100644
--- a/CORE/VOSS/inc/vos_utils.h
+++ b/CORE/VOSS/inc/vos_utils.h
@@ -168,4 +168,9 @@ VOS_STATUS vos_decrypt_AES(v_U32_t cryptHandle, /* Handle */
v_U32_t vos_chan_to_freq(v_U8_t chan);
v_U8_t vos_freq_to_chan(v_U32_t freq);
+#ifdef WLAN_FEATURE_11W
+v_BOOL_t vos_is_mmie_valid(v_U8_t *key, v_U8_t *ipn,
+ v_U8_t* frm, v_U8_t* efrm);
+v_U8_t vos_get_mmie_size(void);
+#endif /* WLAN_FEATURE_11W */
#endif // #if !defined __VOSS_UTILS_H
diff --git a/CORE/VOSS/inc/wcnss_api.h b/CORE/VOSS/inc/wcnss_api.h
index b5bc45e02506..197841ea2f5b 100644
--- a/CORE/VOSS/inc/wcnss_api.h
+++ b/CORE/VOSS/inc/wcnss_api.h
@@ -86,44 +86,6 @@ static inline unsigned int wcnss_get_serial_number(void)
{
return 0;
}
-
-static inline void *wcnss_wlan_crypto_alloc_ahash(const char *alg_name,
- unsigned int type,
- unsigned int mask)
-{
- return NULL;
-}
-
-static inline int wcnss_wlan_crypto_ahash_digest(void *req)
-{
- return 0;
-}
-
-static inline void wcnss_wlan_crypto_free_ahash(void *tfm)
-{
-}
-
-static inline int wcnss_wlan_crypto_ahash_setkey(void *tfm,
- const u8 *key,
- unsigned int keylen)
-{
- return 0;
-}
-
-static inline void *wcnss_wlan_crypto_alloc_ablkcipher(const char *alg_name,
- u32 type, u32 mask)
-{
- return NULL;
-}
-
-static inline void wcnss_wlan_ablkcipher_request_free(void *req)
-{
-}
-
-static inline void wcnss_wlan_crypto_free_ablkcipher(void *tfm)
-{
-}
-
static inline int req_riva_power_on_lock(char *driver_name)
{
return 0;
diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c
index ca735ecaa54f..9d0e324e4f08 100644
--- a/CORE/VOSS/src/vos_api.c
+++ b/CORE/VOSS/src/vos_api.c
@@ -405,6 +405,7 @@ VOS_STATUS vos_open( v_CONTEXT_t *pVosContext, v_SIZE_t hddContextSize )
#if defined (QCA_WIFI_2_0) && \
!defined (QCA_WIFI_ISOC)
hdd_update_tgt_cfg,
+ hdd_dfs_indicate_radar,
#else
NULL,
#endif
@@ -425,6 +426,11 @@ VOS_STATUS vos_open( v_CONTEXT_t *pVosContext, v_SIZE_t hddContextSize )
#if defined (QCA_WIFI_2_0) && \
!defined (QCA_WIFI_ISOC)
+ /* This macOpenParams.maxStation has value incremented by 1 for PeerIdx logic.
+ * So here we are decrementing by 1 to assign in the ini.With this change
+ * there is no ned to define gSoftApMaxPeers ini for Rome >= 1.3
+ */
+ pHddCtx->cfg_ini->maxNumberOfPeers = macOpenParms.maxStation - 1;
if (HTCWaitTarget(vos_get_context(VOS_MODULE_ID_HTC, gpVosContext))) {
VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
"%s: Failed to complete BMI phase", __func__);
diff --git a/CORE/VOSS/src/vos_getBin.c b/CORE/VOSS/src/vos_getBin.c
index 036ea5699f8c..0c147c97c643 100644
--- a/CORE/VOSS/src/vos_getBin.c
+++ b/CORE/VOSS/src/vos_getBin.c
@@ -28,9 +28,6 @@
vos_getBin.c
\brief
Description...
- Copyright (c) 2012-2013 Qualcomm Atheros, Inc.
- All Rights Reserved.
- Qualcomm Atheros Confidential and Proprietary.
==============================================================================*/
/* $HEADER$ */
/**-----------------------------------------------------------------------------
diff --git a/CORE/VOSS/src/vos_nvitem.c b/CORE/VOSS/src/vos_nvitem.c
index 184e8f7240a1..ea2599edea0f 100644
--- a/CORE/VOSS/src/vos_nvitem.c
+++ b/CORE/VOSS/src/vos_nvitem.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -3081,160 +3081,6 @@ VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
}
-/* create_crda_regulatory_entry_from_regd should be called during init time */
-static int create_linux_regulatory_entry_from_regd(struct wiphy *wiphy,
- struct regulatory_request *request,
- v_U8_t nBandCapability)
-{
- int i, j, n, domain_id;
- int bw20_start_channel_index, bw20_end_channel_index;
- int bw40_start_channel_index, bw40_end_channel_index;
- v_CONTEXT_t pVosContext = NULL;
- hdd_context_t *pHddCtx = NULL;
-
- if (wiphy->regd == NULL)
- {
- wiphy_dbg(wiphy, "error: wiphy->regd is NULL\n");
- return -1;
- }
- pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
-
- if (NULL != pVosContext)
- {
- pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
- if (NULL == pHddCtx)
- {
- VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("Invalid pHddCtx pointer") );
- }
- else
- {
- pHddCtx->isVHT80Allowed = 0;
- }
- }
- else
- {
- VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("Invalid pVosContext pointer") );
- }
-
- domain_id = temp_reg_domain;
-
- for (n = 0; n < NUM_RF_CHANNELS; n++)
- pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled = NV_CHANNEL_DISABLE;
-
- for (i = 0; i < wiphy->regd->n_reg_rules; i++)
- {
-
- wiphy_dbg(wiphy, "info: crda rule %d --------------------------------------------\n", i);
- bw20_start_channel_index =
- bw20_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
- bw20_end_channel_index =
- bw20_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
-
- if (bw20_start_channel_index == -1 || bw20_end_channel_index == -1)
- {
- wiphy_dbg(wiphy, "error: crda freq not supported, start freq (KHz) %d end freq %d\n",
- wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
- wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
- continue; // skip this rull, but continue to next rule
- }
-
- wiphy_dbg(wiphy, "20MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
- wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
- wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
- bw20_start_channel_index, bw20_end_channel_index);
-
- for (j=bw20_start_channel_index;j<=bw20_end_channel_index;j++)
- {
- if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
- {
- wiphy_dbg(wiphy, "info: CH %d is not in capable band\n",
- rfChannels[j].channelNum);
- continue; // skip this channel, continue to next
- }
-
- if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
- {
- pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
- wiphy_dbg(wiphy, "info: CH %d is DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
- wiphy->regd->reg_rules[i].power_rule.max_eirp);
- }
- else
- {
- pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
- wiphy_dbg(wiphy, "info: CH %d is enabled, no DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
- wiphy->regd->reg_rules[i].power_rule.max_eirp);
- }
-
- /* max_eirp is in mBm (= 100 * dBm) unit */
- pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
- (tANI_S8) ((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100);
- }
-
- /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
- real gain which should be provided by the real design */
- if (wiphy->regd->reg_rules[i].freq_range.max_bandwidth_khz >= 40000)
- {
- if (wiphy->regd->reg_rules[i].freq_range.max_bandwidth_khz >= 80000)
- {
- wiphy_dbg(wiphy, "info: 80MHz (channel bonding) is allowed\n");
- if (NULL == pHddCtx)
- {
- VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("Invalid pHddCtx pointer") );
- }
- else
- {
- pHddCtx->isVHT80Allowed = 1;
- }
-
-
- }
- else
- {
- wiphy_dbg(wiphy, "info: ONLY 40MHz (channel bonding) is allowed\n");
- }
- bw40_start_channel_index =
- bw40_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
- bw40_end_channel_index =
- bw40_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
- if (bw40_start_channel_index == -1 || bw40_end_channel_index == -1)
- {
- wiphy_dbg(wiphy, "error: crda freq not supported, start_freq_khz %d end_freq_khz %d\n",
- wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
- wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
- continue; // skip this rull, but continue to next rule
- }
-
- wiphy_dbg(wiphy, "40MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
- wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
- wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
- bw40_start_channel_index, bw40_end_channel_index);
- for (j=bw40_start_channel_index;j<=bw40_end_channel_index;j++)
- {
- if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
- continue; // skip this channel, continue to next
- if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
- {
- pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
- wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is DFS\n", rfChannels[j].channelNum);
- }
- else
- {
- pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
- wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is enabled, no DFS\n", rfChannels[j].channelNum);
- }
- /* set 40MHz channel power as half (- 3 dB) of 20MHz */
- pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
- (tANI_S8) (((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100)-3);
- }
- }
- }
-
- return 0;
-}
-
/* create_linux_regulatory_entry to populate internal structures from wiphy */
static int create_linux_regulatory_entry(struct wiphy *wiphy,
v_U8_t nBandCapability)
@@ -3351,6 +3197,7 @@ static int create_linux_regulatory_entry(struct wiphy *wiphy,
pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
NV_CHANNEL_DISABLE;
}
+
/* nv cannot distinguish between DFS and passive channels */
else if (wiphy->bands[i]->channels[j].flags &
(IEEE80211_CHAN_RADAR | IEEE80211_CHAN_PASSIVE_SCAN))
@@ -3358,9 +3205,21 @@ static int create_linux_regulatory_entry(struct wiphy *wiphy,
pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].enabled =
NV_CHANNEL_DFS;
+ /* This is a temporary change for getting the SAP functional on DFS channels
+ * If the driver is using linux regulatory domain, the hostapd + cfg8211
+ * reserve the right to allow whether the BSS can be started or not depending
+ * on the current country, whether the radar is present on the channel and/or
+ * also the DFS state of the current channel. This is done if the driver supplies
+ * PASSIVE and DFS flags for DFS channels
+ * Currently we will not advertise these capabilities until the fix is cleanly
+ * done the hostapd and cfg80211
+ */
+ wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_RADAR);
+ wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_PASSIVE_SCAN);
+
/* max_power is in mBm = 100 * dBm */
pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit =
- (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
+ (tANI_S8) ((wiphy->bands[i]->channels[j].max_power));
if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
{
pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
@@ -3368,7 +3227,7 @@ static int create_linux_regulatory_entry(struct wiphy *wiphy,
/* 40MHz channel power is half of 20MHz (-3dB) ?? */
pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit =
- (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
+ (tANI_S8) (((wiphy->bands[i]->channels[j].max_power))-3);
}
if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_80MHZ) == 0)
{
@@ -3390,14 +3249,14 @@ static int create_linux_regulatory_entry(struct wiphy *wiphy,
/* max_power is in dBm */
pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit =
- (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
+ (tANI_S8) ((wiphy->bands[i]->channels[j].max_power));
if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
{
pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled =
NV_CHANNEL_ENABLE;
/* 40MHz channel power is half of 20MHz (-3dB) */
pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit =
- (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
+ (tANI_S8) (((wiphy->bands[i]->channels[j].max_power))-3);
}
if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_80MHZ) == 0)
{
diff --git a/CORE/VOSS/src/vos_timer.c b/CORE/VOSS/src/vos_timer.c
index 8f6c1bdcc602..77081365b0cb 100644
--- a/CORE/VOSS/src/vos_timer.c
+++ b/CORE/VOSS/src/vos_timer.c
@@ -187,8 +187,9 @@ static void vos_linux_timer_callback (unsigned long data)
//Serialize to the Tx thread
sysBuildMessageHeader( SYS_MSG_ID_TX_TIMER, &msg );
- msg.bodyptr = callback;
- msg.bodyval = (v_U32_t)userData;
+ msg.callback = callback;
+ msg.bodyptr = userData;
+ msg.bodyval = 0;
if(vos_tx_mq_serialize( VOS_MQ_ID_SYS, &msg ) == VOS_STATUS_SUCCESS)
return;
@@ -200,8 +201,9 @@ static void vos_linux_timer_callback (unsigned long data)
//Serialize to the Rx thread
sysBuildMessageHeader( SYS_MSG_ID_RX_TIMER, &msg );
- msg.bodyptr = callback;
- msg.bodyval = (v_U32_t)userData;
+ msg.callback = callback;
+ msg.bodyptr = userData;
+ msg.bodyval = 0;
if(vos_rx_mq_serialize( VOS_MQ_ID_SYS, &msg ) == VOS_STATUS_SUCCESS)
return;
@@ -213,8 +215,9 @@ static void vos_linux_timer_callback (unsigned long data)
// Serialize to the MC thread
sysBuildMessageHeader( SYS_MSG_ID_MC_TIMER, &msg );
- msg.bodyptr = callback;
- msg.bodyval = (v_U32_t)userData;
+ msg.callback = callback;
+ msg.bodyptr = userData;
+ msg.bodyval = 0;
if(vos_mq_post_message( VOS_MQ_ID_SYS, &msg ) == VOS_STATUS_SUCCESS)
return;
diff --git a/CORE/VOSS/src/vos_utils.c b/CORE/VOSS/src/vos_utils.c
index 20b04d26cda0..598cd06fbfe4 100644
--- a/CORE/VOSS/src/vos_utils.c
+++ b/CORE/VOSS/src/vos_utils.c
@@ -66,12 +66,20 @@
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <linux/completion.h>
+#include <linux/ieee80211.h>
#include <crypto/hash.h>
+#include <crypto/aes.h>
#include <wcnss_api.h>
+#include <linux/qcomwlan_secif.h>
+#include "ieee80211_common.h"
/*----------------------------------------------------------------------------
* Preprocessor Definitions and Constants
* -------------------------------------------------------------------------*/
+#define AAD_LEN 20
+#define IV_SIZE_AES_128 16
+#define CMAC_IPN_LEN 6
+
/*----------------------------------------------------------------------------
* Type Declarations
@@ -113,7 +121,7 @@ VOS_STATUS vos_crypto_init( v_U32_t *phCryptProv )
VOS_STATUS uResult = VOS_STATUS_E_FAILURE;
// This implementation doesn't require a crypto context
- *phCryptProv = (v_U32_t)NULL;
+ *phCryptProv = 0;
uResult = VOS_STATUS_SUCCESS;
return ( uResult );
}
@@ -178,6 +186,129 @@ VOS_STATUS vos_rand_get_bytes( v_U32_t cryptHandle, v_U8_t *pbBuf, v_U32_t numBy
}
+#ifdef WLAN_FEATURE_11W
+v_U8_t vos_get_mmie_size()
+{
+ return sizeof(struct ieee80211_mmie);
+}
+
+v_BOOL_t vos_is_mmie_valid(v_U8_t *igtk, v_U8_t *ipn,
+ v_U8_t* frm, v_U8_t* efrm)
+{
+ struct ieee80211_mmie *mmie;
+ struct ieee80211_frame *wh;
+ v_U8_t *rx_ipn, aad[AAD_LEN], mic[CMAC_TLEN], *input;
+ v_U16_t nBytes = 0;
+ int ret = 0;
+ struct crypto_cipher *tfm;
+
+ /* Check if frame is invalid length */
+ if ((efrm < frm) || ((efrm - frm) < sizeof(*wh))) {
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ "Invalid frame length");
+ return VOS_FALSE;
+ }
+
+ mmie = (struct ieee80211_mmie *)(efrm - sizeof(*mmie));
+
+ /* Check Element ID */
+ if ((mmie->element_id != IEEE80211_ELEMID_MMIE) ||
+ (mmie->length != (sizeof(*mmie)-2))) {
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ "IE is not Mgmt MIC IE or Invalid length");
+ /* IE is not Mgmt MIC IE or invalid length */
+ return VOS_FALSE;
+ }
+
+ /* Validate IPN */
+ rx_ipn = mmie->sequence_number;
+ if (OS_MEMCMP(rx_ipn, ipn, CMAC_IPN_LEN) <= 0)
+ {
+ /* Replay error */
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ " mmie ipn %02X %02X %02X %02X %02X %02X"
+ " drvr ipn %02X %02X %02X %02X %02X %02X",
+ rx_ipn[0], rx_ipn[1], rx_ipn[2], rx_ipn[3], rx_ipn[4], rx_ipn[5],
+ ipn[0], ipn[1], ipn[2], ipn[3], ipn[4], ipn[5]);
+ return VOS_FALSE;
+ }
+
+ tfm = wcnss_wlan_crypto_alloc_cipher( "aes", 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(tfm)) {
+ ret = PTR_ERR(tfm);
+ VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,
+ "crypto_alloc_cipher failed (%d)", ret);
+ goto err_tfm;
+ }
+
+ ret = crypto_cipher_setkey(tfm, igtk, AES_KEYSIZE_128);
+ if (ret) {
+ VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,
+ "crypto_cipher_setkey failed (%d)", ret);
+ goto err_tfm;
+ }
+
+ /* Construct AAD */
+ wh = (struct ieee80211_frame *)frm;
+
+ /* Generate BIP AAD: FC(masked) || A1 || A2 || A3 */
+
+ /* FC type/subtype */
+ aad[0] = wh->i_fc[0];
+ /* Mask FC Retry, PwrMgt, MoreData flags to zero */
+ aad[1] = wh->i_fc[1] & ~(IEEE80211_FC1_RETRY | IEEE80211_FC1_PWR_MGT |
+ IEEE80211_FC1_MORE_DATA);
+ /* A1 || A2 || A3 */
+ vos_mem_copy(aad + 2, wh->i_addr_all, 3 * IEEE80211_ADDR_LEN);
+
+ /* MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) */
+ nBytes = AAD_LEN + (efrm - (v_U8_t*)(wh+1));
+ input = (v_U8_t *)vos_mem_malloc(nBytes);
+ if (NULL == input)
+ {
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ "Memory allocation failed");
+ ret = VOS_STATUS_E_NOMEM;
+ goto err_tfm;
+ }
+
+ /* Copy the AAD, MMIE with 8 bit MIC zeroed out */
+ vos_mem_zero(input, nBytes);
+ vos_mem_copy(input, aad, AAD_LEN);
+ vos_mem_copy(input+AAD_LEN, (v_U8_t*)(wh+1), nBytes - AAD_LEN - CMAC_TLEN);
+
+ wcnss_wlan_cmac_calc_mic(tfm, input, nBytes, mic);
+ vos_mem_free(input);
+
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ "CMAC(T)= %02X %02X %02X %02X %02X %02X %02X %02X",
+ mic[0], mic[1], mic[2], mic[3],
+ mic[4], mic[5], mic[6], mic[7]);
+
+ if (OS_MEMCMP(mic, mmie->mic, CMAC_TLEN) != 0) {
+ /* MMIE MIC mismatch */
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ "BC/MC MGMT frame MMIE MIC check Failed"
+ " rmic %02X %02X %02X %02X %02X %02X %02X %02X"
+ " cmic %02X %02X %02X %02X %02X %02X %02X %02X",
+ mmie->mic[0], mmie->mic[1], mmie->mic[2], mmie->mic[3],
+ mmie->mic[4], mmie->mic[5], mmie->mic[6], mmie->mic[7],
+ mic[0], mic[1], mic[2], mic[3],
+ mic[4], mic[5], mic[6], mic[7]);
+ return VOS_FALSE;
+ }
+
+ /* Update IPN */
+ vos_mem_copy(ipn, rx_ipn, CMAC_IPN_LEN);
+
+err_tfm:
+ if (tfm)
+ wcnss_wlan_crypto_free_cipher(tfm);
+
+ return !ret?VOS_TRUE:VOS_FALSE;
+}
+
+#endif /* WLAN_FEATURE_11W */
/**
* vos_sha1_hmac_str
*
@@ -532,16 +663,11 @@ static void ecb_aes_complete(struct crypto_async_request *req, int err)
( *** return value not considered yet )
--------------------------------------------------------------------------*/
-#define IV_SIZE_AES_128 16
-#define KEY_SIZE_AES_128 16
-#define AES_BLOCK_SIZE 16
-
VOS_STATUS vos_encrypt_AES(v_U32_t cryptHandle, /* Handle */
v_U8_t *pPlainText, /* pointer to data stream */
v_U8_t *pCiphertext,
v_U8_t *pKey) /* pointer to authentication key */
{
-// VOS_STATUS uResult = VOS_STATUS_E_FAILURE;
struct ecb_aes_result result;
struct ablkcipher_request *req;
struct crypto_ablkcipher *tfm;
@@ -572,7 +698,7 @@ VOS_STATUS vos_encrypt_AES(v_U32_t cryptHandle, /* Handle */
crypto_ablkcipher_clear_flags(tfm, ~0);
- ret = crypto_ablkcipher_setkey(tfm, pKey, KEY_SIZE_AES_128);
+ ret = crypto_ablkcipher_setkey(tfm, pKey, AES_KEYSIZE_128);
if (ret) {
VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_cipher_setkey failed");
goto err_setkey;
@@ -668,7 +794,7 @@ VOS_STATUS vos_decrypt_AES(v_U32_t cryptHandle, /* Handle */
crypto_ablkcipher_clear_flags(tfm, ~0);
- ret = crypto_ablkcipher_setkey(tfm, pKey, KEY_SIZE_AES_128);
+ ret = crypto_ablkcipher_setkey(tfm, pKey, AES_KEYSIZE_128);
if (ret) {
VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_cipher_setkey failed");
goto err_setkey;
diff --git a/CORE/WDA/inc/legacy/halMsgApi.h b/CORE/WDA/inc/legacy/halMsgApi.h
index 35b5675fdd33..2fb9a6aa051a 100644
--- a/CORE/WDA/inc/legacy/halMsgApi.h
+++ b/CORE/WDA/inc/legacy/halMsgApi.h
@@ -1000,7 +1000,7 @@ typedef struct
tANI_U16 smpsMode;
-
+ tANI_U8 isDfsChannel;
}tSwitchChannelParams, *tpSwitchChannelParams;
typedef struct CSAOffloadParams {
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index 7eaac1377c3f..223af8f972e7 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -353,6 +353,13 @@ typedef eHalStatus (*pWDAAckFnTxComp)(tpAniSirGlobal, tANI_U32);
/* generic callback for updating parameters from target to UMAC */
typedef void (*wda_tgt_cfg_cb) (void *context, void *param);
+/*
+ * callback for Indicating Radar to HDD and disable Tx Queues
+ * to stop accepting data Tx packets from netif as radar is
+ * found on the current operating channel
+ */
+typedef void (*wda_dfs_radar_indication_cb) (void *context, void *param);
+
typedef struct
{
tANI_U16 ucValidStaIndex ;
@@ -491,8 +498,15 @@ VOS_STATUS WDA_TxPacket(void *pWDA,
* open WDA context
*/
+#ifndef QCA_WIFI_ISOC
+VOS_STATUS WDA_open(v_PVOID_t pVosContext, v_PVOID_t pOSContext,
+ wda_tgt_cfg_cb pTgtUpdCB,
+ wda_dfs_radar_indication_cb radar_ind_cb,
+ tMacOpenParameters *pMacParams ) ;
+#else
VOS_STATUS WDA_open(v_PVOID_t pVosContext, v_PVOID_t pOSContext,
wda_tgt_cfg_cb pTgtUpdCB, tMacOpenParameters *pMacParams ) ;
+#endif
#ifdef QCA_WIFI_2_0
#define WDA_start wma_start
@@ -644,7 +658,8 @@ tANI_U8 WDA_MapChannel(tANI_U8);
#define WDA_GET_RX_FT_DONE(pRxMeta) 0
-#define WDA_GET_RX_DPU_FEEDBACK(pRxMeta) 0
+#define WDA_GET_RX_DPU_FEEDBACK(pRxMeta) \
+ (((t_packetmeta *)pRxMeta)->dpuFeedback)
#define WDA_GET_RX_BEACON_SENT(pRxMeta) 0
@@ -1296,6 +1311,14 @@ tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb);
#endif
#endif
+/* Message to Indicate Radar Presence on SAP Channel */
+#define WDA_DFS_RADAR_IND SIR_HAL_DFS_RADAR_IND
+
+/* Message to indicate beacon tx completion after beacon template update
+ * beacon offload case
+ */
+#define WDA_DFS_BEACON_TX_SUCCESS_IND SIR_HAL_BEACON_TX_SUCCESS_IND
+
tSirRetStatus wdaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg);
#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 // Bit 6 will be used to control BD rate for Management frames
diff --git a/CORE/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index 7e91b0382708..e5dcda792e24 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -13832,7 +13832,7 @@ void WDA_RoamOffloadScanReqCallback(WDI_Status status, void* pUserData)
{
/* free the mem and return */
VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
- "Failed to post the rsp to UMAC" ,__func__);
+ "%s: Failed to post the rsp to UMAC", __func__);
}
return ;
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi.h b/CORE/WDI/CP/inc/wlan_qct_wdi.h
index 6cbeea8f10ba..7eceb18262a2 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi.h
@@ -10176,7 +10176,7 @@ wpt_uint8 WDI_getHostWlanFeatCaps(wpt_uint8 feat_enum_value);
#ifdef QCA_WIFI_2_0
static inline wpt_uint8 WDI_getFwWlanFeatCaps(wpt_uint8 feat_enum_value)
{
- return 0;
+ return 1;
}
#else
wpt_uint8 WDI_getFwWlanFeatCaps(wpt_uint8 feat_enum_value);
diff --git a/Kbuild b/Kbuild
index c6b51e9ecc14..3b533125b8ab 100644
--- a/Kbuild
+++ b/Kbuild
@@ -50,7 +50,8 @@ endif
# To enable CCX upload, dependent config
# CONFIG_QCOM_CCX must be enabled.
-CONFIG_QCOM_CCX_UPLOAD := n
+CONFIG_QCOM_CCX := y
+CONFIG_QCOM_CCX_UPLOAD := y
# Feature flags which are not (currently) configurable via Kconfig
@@ -357,6 +358,26 @@ SAP_OBJS := $(SAP_SRC_DIR)/sapApiLinkCntl.o \
$(SAP_SRC_DIR)/sapFsm.o \
$(SAP_SRC_DIR)/sapModule.o
+############ DFS ############ 350
+DFS_DIR := CORE/SERVICES/DFS
+DFS_INC_DIR := $(DFS_DIR)/inc
+DFS_SRC_DIR := $(DFS_DIR)/src
+
+DFS_INC := -I$(WLAN_ROOT)/$(DFS_INC_DIR) \
+ -I$(WLAN_ROOT)/$(DFS_SRC_DIR)
+
+DFS_OBJS := $(DFS_SRC_DIR)/dfs_bindetects.o \
+ $(DFS_SRC_DIR)/dfs.o \
+ $(DFS_SRC_DIR)/dfs_debug.o\
+ $(DFS_SRC_DIR)/dfs_fcc_bin5.o\
+ $(DFS_SRC_DIR)/dfs_init.o\
+ $(DFS_SRC_DIR)/dfs_misc.o\
+ $(DFS_SRC_DIR)/dfs_nol.o\
+ $(DFS_SRC_DIR)/dfs_phyerr_tlv.o\
+ $(DFS_SRC_DIR)/dfs_process_phyerr.o\
+ $(DFS_SRC_DIR)/dfs_process_radarevent.o\
+ $(DFS_SRC_DIR)/dfs_staggered.o
+
############ SME ############
SME_DIR := CORE/SME
SME_INC_DIR := $(SME_DIR)/inc
@@ -614,7 +635,8 @@ WMA_DIR := CORE/SERVICES/WMA
WMA_INC := -I$(WLAN_ROOT)/$(WMA_DIR)
-WMA_OBJS := $(WMA_DIR)/wma.o
+WMA_OBJS := $(WMA_DIR)/wma.o \
+ $(WMA_DIR)/wma_dfs_interface.o
ifeq ($(CONFIG_QCA_WIFI_ISOC), 1)
WMA_OBJS += $(WMA_DIR)/wma_isoc.o
@@ -714,7 +736,8 @@ INCS := $(BAP_INC) \
$(TL_INC) \
$(VOSS_INC) \
$(WDA_INC) \
- $(WDI_INC)
+ $(WDI_INC) \
+ $(DFS_INC)
ifeq ($(CONFIG_QCA_WIFI_2_0), 0)
INCS += $(DXE_INC)
@@ -728,7 +751,8 @@ INCS += $(WMA_INC) \
$(TXRX_INC) \
$(PKTLOG_INC) \
$(HTT_INC) \
- $(HTC_INC)
+ $(HTC_INC) \
+ $(DFS_INC)
ifeq ($(CONFIG_QCA_WIFI_ISOC), 0)
INCS += $(HIF_INC) \
@@ -753,7 +777,8 @@ OBJS := $(BAP_OBJS) \
$(SYS_OBJS) \
$(VOSS_OBJS) \
$(WDA_OBJS) \
- $(WDI_OBJS)
+ $(WDI_OBJS) \
+ $(DFS_OBJS)
ifeq ($(CONFIG_QCA_WIFI_2_0), 0)
OBJS += $(DXE_OBJS) \
@@ -765,7 +790,8 @@ OBJS += $(WMA_OBJS) \
$(WMI_OBJS) \
$(FWLOG_OBJS) \
$(HTC_OBJS) \
- $(ADF_OBJS)
+ $(ADF_OBJS) \
+ $(DFS_OBJS)
ifeq ($(CONFIG_QCA_WIFI_ISOC), 0)
OBJS += $(HIF_OBJS) \
diff --git a/Makefile b/Makefile
index 2ad4e68531d8..3930a0e24d8d 100644
--- a/Makefile
+++ b/Makefile
@@ -367,6 +367,25 @@ SAP_OBJS := $(SAP_SRC_DIR)/sapApiLinkCntl.o \
$(SAP_SRC_DIR)/sapFsm.o \
$(SAP_SRC_DIR)/sapModule.o
+############ DFS ############
+DFS_DIR := CORE/SERVICES/DFS
+DFS_INC_DIR := $(DFS_DIR)/inc
+DFS_SRC_DIR := $(DFS_DIR)/src
+DFS_INC := -I$(WLAN_ROOT)/$(DFS_INC_DIR) \
+ -I$(WLAN_ROOT)/$(DFS_SRC_DIR)
+
+DFS_OBJS := $(DFS_SRC_DIR)/dfs_bindetects.o \
+ $(DFS_SRC_DIR)/dfs.o \
+ $(DFS_SRC_DIR)/dfs_debug.o\
+ $(DFS_SRC_DIR)/dfs_fcc_bin5.o\
+ $(DFS_SRC_DIR)/dfs_init.o\
+ $(DFS_SRC_DIR)/dfs_misc.o\
+ $(DFS_SRC_DIR)/dfs_nol.o\
+ $(DFS_SRC_DIR)/dfs_phyerr_tlv.o\
+ $(DFS_SRC_DIR)/dfs_process_phyerr.o\
+ $(DFS_SRC_DIR)/dfs_process_radarevent.o\
+ $(DFS_SRC_DIR)/dfs_staggered.o
+
############ SME ############
SME_DIR := CORE/SME
SME_INC_DIR := $(SME_DIR)/inc
@@ -626,8 +645,8 @@ WMA_DIR := CORE/SERVICES/WMA
WMA_INC := -I$(WLAN_ROOT)/$(WMA_DIR)
-WMA_OBJS := $(WMA_DIR)/wma.o
-
+WMA_OBJS := $(WMA_DIR)/wma.o \
+ $(WMA_DIR)/wma_dfs_interface.o
ifeq ($(CONFIG_QCA_WIFI_ISOC), 1)
WMA_OBJS += $(WMA_DIR)/wma_isoc.o
else
@@ -726,7 +745,8 @@ INCS := $(BAP_INC) \
$(TL_INC) \
$(VOSS_INC) \
$(WDA_INC) \
- $(WDI_INC)
+ $(WDI_INC) \
+ $(DFS_INC)
ifeq ($(CONFIG_QCA_WIFI_2_0), 0)
INCS += $(DXE_INC)
@@ -765,7 +785,8 @@ OBJS := $(BAP_OBJS) \
$(SYS_OBJS) \
$(VOSS_OBJS) \
$(WDA_OBJS) \
- $(WDI_OBJS)
+ $(WDI_OBJS)\
+ $(DFS_OBJS)
ifeq ($(CONFIG_QCA_WIFI_2_0), 0)
OBJS += $(DXE_OBJS) \
diff --git a/firmware_bin/WCNSS_qcom_cfg.ini b/firmware_bin/WCNSS_qcom_cfg.ini
index 21c3c00794d3..2c16e9926623 100644
--- a/firmware_bin/WCNSS_qcom_cfg.ini
+++ b/firmware_bin/WCNSS_qcom_cfg.ini
@@ -97,7 +97,7 @@ gEnableTCPChkSumOffld=0
#Flag to enable HostNSOffload feature or not
-hostNSOffload=0
+hostNSOffload=1
#Flag to enable IPChkSumOffld feature or not
diff --git a/tools/fwdebuglog/cld-fwlog-netlink.c b/tools/fwdebuglog/cld-fwlog-netlink.c
index 6fea2298ab5a..0781441d0f52 100644
--- a/tools/fwdebuglog/cld-fwlog-netlink.c
+++ b/tools/fwdebuglog/cld-fwlog-netlink.c
@@ -53,12 +53,14 @@
#define LOGFILE_FLAG 0x01
#define CONSOLE_FLAG 0x02
#define QXDM_FLAG 0x04
+#define SILENT_FLAG 0x08
const char options[] =
"Options:\n\
-f, --logfile=<Output log file> [Mandotory]\n\
-r, --reclimit=<Maximum number of records before the log rolls over> [Optional]\n\
-c, --console (prints the logs in the console)\n\
+-s, --silent (No print will come when logging)\n\
-q, --qxdm (prints the logs in the qxdm)\n\
The options can also be given in the abbreviated form --option=x or -o x. The options can be given in any order";
@@ -77,7 +79,7 @@ const char *progname;
char dbglogoutfile[PATH_MAX];
int optionflag;
-int rec_limit = 1000000; /* Million records is a good default */
+int rec_limit = 100000000; /* Million records is a good default */
static void
usage(void)
@@ -91,7 +93,7 @@ extern int parser_init();
extern int
-dbglog_parse_debug_logs(u_int8_t *datap, u_int16_t len);
+dbglog_parse_debug_logs(u_int8_t *datap, u_int16_t len, u_int16_t dropped);
static unsigned int get_le32(const unsigned char *pos)
{
@@ -178,11 +180,12 @@ int main(int argc, char *argv[])
{"reclimit", 1, NULL, 'r'},
{"console", 0, NULL, 'c'},
{"qxdm", 0, NULL, 'q'},
+ {"silent", 0, NULL, 's'},
{ 0, 0, 0, 0}
};
while (1) {
- c = getopt_long (argc, argv, "f:cq:r:", long_options, &option_index);
+ c = getopt_long (argc, argv, "f:scq:r:", long_options, &option_index);
if (c == -1) break;
switch (c) {
@@ -205,12 +208,15 @@ int main(int argc, char *argv[])
rec_limit = strtoul(optarg, NULL, 0);
break;
+ case 's':
+ optionflag |= SILENT_FLAG;
+ break;
default:
usage();
}
}
- if (!(optionflag & (LOGFILE_FLAG | CONSOLE_FLAG | QXDM_FLAG))) {
+ if (!(optionflag & (LOGFILE_FLAG | CONSOLE_FLAG | QXDM_FLAG | SILENT_FLAG))) {
usage();
return -1;
}
@@ -274,8 +280,10 @@ int main(int argc, char *argv[])
/* Read message from kernel */
while ((res = recvmsg(sock_fd, &msg, 0)) > 0) {
buf = (unsigned char *)NLMSG_DATA(nlh);
- printf("Read record timestamp=%u length=%u \n",
- get_le32(&buf[0]), get_le32(&buf[4]));
+ if (!((optionflag & SILENT_FLAG) == SILENT_FLAG)) {
+ printf("Read record timestamp=%u length=%u fw dropped=%u\n",
+ get_le32(&buf[0]), get_le32(&buf[4]), get_le32(&buf[8]));
+ }
fseek(log_out, record * RECLEN, SEEK_SET);
if ((res = fwrite(buf, RECLEN, 1, log_out)) != 1){
perror("fwrite");
@@ -296,7 +304,7 @@ int main(int argc, char *argv[])
while ((res = recvmsg(sock_fd, &msg, 0)) > 0) {
buf = (unsigned char *)NLMSG_DATA(nlh);
- dbglog_parse_debug_logs(&buf[8], get_le32(&buf[4]));
+ dbglog_parse_debug_logs(&buf[12], get_le32(&buf[4]), get_le32(&buf[8]));
}
close(sock_fd);
}
diff --git a/tools/fwdebuglog/cld-fwlog-parser.c b/tools/fwdebuglog/cld-fwlog-parser.c
index 4a916d769634..28c24a2449e9 100644
--- a/tools/fwdebuglog/cld-fwlog-parser.c
+++ b/tools/fwdebuglog/cld-fwlog-parser.c
@@ -185,11 +185,20 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"WMI_CMD_PARAMS",
"WMI_EVENT_ALLOC_FAILURE",
"WMI_DBGID_DCS_PARAM_CMD",
+ "WMI_SEND_EVENT_WRONG_TLV",
+ "WMI_SEND_EVENT_NO_TLV_DEF",
"WMI_DBGID_DEFNITION_END",
},
{
"PS_STA_DEFINITION_START",
"PS_STA_PM_ARB_REQUEST",
+ "PS_STA_DELIVER_EVENT",
+ "PS_STA_PSPOLL_SEQ_DONE",
+ "PS_STA_COEX_MODE",
+ "PS_STA_PSPOLL_ALLOW",
+ "PS_STA_SET_PARAM",
+ "PS_STA_SPECPOLL_TIMER_STARTED",
+ "PS_STA_SPECPOLL_TIMER_STOPPED",
},
{
"WHAL_DBGID_DEFINITION_START",
@@ -230,56 +239,7 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"WHAL_ERROR_INTERRUPT_BB_PANIC",
"WHAL_ERROR_PAPRD_MAXGAIN_ABOVE_WINDOW",
"WHAL_ERROR_QCU_HW_PAUSE_MISMATCH",
- "WHAL_COEX_RESET",
- "WHAL_COEX_SELF_GEN_MASK",
- "WHAL_ERROR_COEX_MCI_ISR",
- "WHAL_COEX_MCI_ISR_IntRaw",
- "WHAL_COEX_MCI_ISR_Int1Raw",
- "WHAL_COEX_MCI_ISR_RxMsgRaw",
- "WHAL_COEX_SENDMSG_QUEUE",
- "WHAL_COEX_TX_MCI_REMOTE_RESET",
- "WHAL_COEX_TX_MCI_TYPE_UNKNOWN",
- "WHAL_COEX_TX_MCI_SYS_SLEEPING",
- "WHAL_COEX_TX_MCI_REQ_WAKE",
- "WHAL_COEX_TX_MCI_SYS_WAKING",
- "WHAL_COEX_TX_MCI_LNA_TAKE",
- "WHAL_COEX_TX_MCI_LNA_TRANS",
- "WHAL_COEX_TX_MCI_GPM_UNKNOWN",
- "WHAL_COEX_TX_MCI_GPM_WLAN_SET_ACL_INACTIVITY",
- "WHAL_COEX_TX_MCI_GPM_BT_PAUSE_PROFILE",
- "WHAL_COEX_TX_MCI_GPM_WLAN_PRIO",
- "WHAL_COEX_TX_MCI_GPM_BT_STATUS_UPDATE",
- "WHAL_COEX_TX_MCI_GPM_BT_UPDATE_FLAGS",
- "WHAL_COEX_TX_MCI_GPM_VERSION_QUERY",
- "WHAL_COEX_TX_MCI_GPM_VERSION_RESPONSE",
- "WHAL_COEX_TX_MCI_GPM_STATUS_QUERY",
- "WHAL_COEX_TX_MCI_GPM_HALT_BT_GPM",
- "WHAL_COEX_TX_MCI_GPM_WLAN_CHANNELS",
- "WHAL_COEX_TX_MCI_GPM_BT_PROFILE_INFO",
- "WHAL_COEX_TX_MCI_GPM_BT_CAL_REQ ",
- "WHAL_COEX_TX_MCI_GPM_BT_CAL_GRANT",
- "WHAL_COEX_TX_MCI_GPM_BT_CAL_DONE",
- "WHAL_COEX_TX_MCI_GPM_WLAN_CAL_REQ",
- "WHAL_COEX_TX_MCI_GPM_WLAN_CAL_GRANT",
- "WHAL_COEX_TX_MCI_GPM_WLAN_CAL_DONE",
- "WHAL_COEX_TX_MCI_GPM_BT_DEBUG",
- "WHAL_COEX_WHAL_MCI_RESET",
- "WHAL_COEX_POLL_BT_CAL_DONE_TIMEOUT",
- "WHAL_COEX_WHAL_PAUSE",
- "WHAL_COEX_RX_MCI_GPM_BT_CAL_REQ",
- "WHAL_COEX_RX_MCI_GPM_BT_CAL_DONE",
- "WHAL_COEX_RX_MCI_GPM_BT_CAL_GRANT",
- "WHAL_COEX_WLAN_CAL_START",
- "WHAL_COEX_WLAN_CAL_RESULT ",
- "WHAL_COEX_BtMciState",
- "WHAL_COEX_BtCalState",
- "WHAL_COEX_WlanCalState",
- "WHAL_COEX_RxReqWakeCount",
- "WHAL_COEX_RxRemoteResetCount",
- "WHAL_COEX_RESTART_CAL",
- "WHAL_COEX_WHAL_COEX_RESET",
- "WHAL_COEX_SELF_GEN_MASK",
- "WHAL_DBGID_DEFINITION_END"
+ "WHAL_DBGID_DEFINITION_END",
},
{
"COEX_DEBUGID_START",
@@ -482,20 +442,61 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"COEX_PSP_STAT_2", // 197
"COEX_PSP_RX_STATUS_STATE_2", // 198
"COEX_PSP_ERROR", // 199
- "COEX_T2BT", // 200
- "COEX_BT_DURATION", // 201
- "COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG", // 202
- "COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG_RSP", // 203
- "COEX_TX_MCI_GPM_SCAN_OP", // 204
- "COEX_TX_MCI_GPM_BT_PAUSE_GPM_TX", // 205
- "COEX_CTS2S_SEND", // 206
- "COEX_CTS2S_RESULT", // 207
- "COEX_ENTER_OCS", // 208
- "COEX_EXIT_OCS", // 209
- "COEX_UPDATE_OCS", // 210
- "COEX_STATUS_OCS", // 211
- "COEX_STATS_BT", // 212
- "COEX_DEBUG_MESSAGE_END"
+ "COEX_T2BT", // 200
+ "COEX_BT_DURATION", // 201
+ "COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG", // 202
+ "COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG_RSP", // 203
+ "COEX_TX_MCI_GPM_SCAN_OP", // 204
+ "COEX_TX_MCI_GPM_BT_PAUSE_GPM_TX", // 205
+ "COEX_CTS2S_SEND", // 206
+ "COEX_CTS2S_RESULT", // 207
+ "COEX_ENTER_OCS", // 208
+ "COEX_EXIT_OCS", // 209
+ "COEX_UPDATE_OCS", // 210
+ "COEX_STATUS_OCS", // 211
+ "COEX_STATS_BT", // 212
+ "COEX_MWS_WLAN_INIT",
+ "COEX_MWS_WBTMR_SYNC",
+ "COEX_MWS_TYPE2_RX",
+ "COEX_MWS_TYPE2_TX",
+ "COEX_MWS_WLAN_CHAVD",
+ "COEX_MWS_WLAN_CHAVD_INSERT",
+ "COEX_MWS_WLAN_CHAVD_MERGE",
+ "COEX_MWS_WLAN_CHAVD_RPT",
+ "COEX_MWS_CP_MSG_SEND",
+ "COEX_MWS_CP_ESCAPE",
+ "COEX_MWS_CP_UNFRAME",
+ "COEX_MWS_CP_SYNC_UPDATE",
+ "COEX_MWS_CP_SYNC",
+ "COEX_MWS_CP_WLAN_STATE_IND",
+ "COEX_MWS_CP_SYNCRESP_TIMEOUT",
+ "COEX_MWS_SCHEME_UPDATE",
+ "COEX_MWS_WLAN_EVENT",
+ "COEX_MWS_UART_UNESCAPE",
+ "COEX_MWS_UART_ENCODE_SEND",
+ "COEX_MWS_UART_RECV_DECODE",
+ "COEX_MWS_UL_HDL",
+ "COEX_MWS_REMOTE_EVENT",
+ "COEX_MWS_OTHER",
+ "COEX_MWS_ERROR",
+ "COEX_MWS_ANT_DIVERSITY", //237
+ "COEX_P2P_GO",
+ "COEX_P2P_CLIENT",
+ "COEX_SCC_1",
+ "COEX_SCC_2",
+ "COEX_MCC_1",
+ "COEX_MCC_2",
+ "COEX_TRF_SHAPE_NOA",
+ "COEX_NOA_ONESHOT",
+ "COEX_NOA_PERIODIC",
+ "COEX_LE_1",
+ "COEX_LE_2",
+ "COEX_ANT_1",
+ "COEX_ANT_2",
+ "COEX_ENTER_NOA",
+ "COEX_EXIT_NOA",
+ "COEX_BT_SCAN_PROTECT", // 253
+ "COEX_DEBUG_ID_END" // 254
},
{
"ROAM_DBGID_DEFINITION_START",
@@ -626,6 +627,7 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"VDEV_MGR_VDEV_PAUSE_DELAY_UPDATE",
"VDEV_MGR_VDEV_PAUSE_FAIL",
"VDEV_MGR_GEN_PERIODIC_NOA",
+ "VDEV_MGR_OFF_CHAN_GO_CH_REQ_SETUP",
"VDEV_MGR_DEFINITION_END",
},
{
@@ -642,7 +644,16 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"SCAN_FWLOG_EVENT_RESTARTED",
"SCAN_FWLOG_EVENT_COMPLETED",
},
- { "" /* Rate ctrl*/
+ {
+ "RATECTRL_DBGID_DEFINITION_START", /* Rate ctrl*/
+ "RATECTRL_DBGID_ASSOC",
+ "RATECTRL_DBGID_NSS_CHANGE",
+ "RATECTRL_DBGID_CHAINMASK_ERR",
+ "RATECTRL_DBGID_UNEXPECTED_FRAME",
+ "RATECTRL_DBGID_WAL_RCQUERY",
+ "RATECTRL_DBGID_WAL_RCUPDATE",
+ "RATECTRL_DBGID_GTX_UPDATE",
+ "RATECTRL_DBGID_DEFINITION_END"
},
{
"AP_PS_DBGID_DEFINITION_START",
@@ -662,6 +673,8 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"AP_PS_DBGID_UAPSD_RESPONSE",
"AP_PS_DBGID_SEND_COMPLETE",
"AP_PS_DBGID_SEND_N_COMPLETE",
+ "AP_PS_DBGID_DETECT_OUT_OF_SYNC_STA",
+ "AP_PS_DBGID_DELIVER_CAB",
},
{
"" /* Block Ack */
@@ -766,7 +779,28 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"" /* pcie lp */
},
{
- "" /* RTT */
+ /* RTT */
+ "RTT_CALL_FLOW",
+ "RTT_REQ_SUB_TYPE",
+ "RTT_MEAS_REQ_HEAD",
+ "RTT_MEAS_REQ_BODY",
+ "",
+ "",
+ "RTT_INIT_GLOBAL_STATE",
+ "",
+ "RTT_REPORT",
+ "",
+ "RTT_ERROR_REPORT",
+ "RTT_TIMER_STOP",
+ "RTT_SEND_TM_FRAME",
+ "RTT_V3_RESP_CNT",
+ "RTT_V3_RESP_FINISH",
+ "RTT_CHANNEL_SWITCH_REQ",
+ "RTT_CHANNEL_SWITCH_GRANT",
+ "RTT_CHANNEL_SWITCH_COMPLETE",
+ "RTT_CHANNEL_SWITCH_PREEMPT",
+ "RTT_CHANNEL_SWITCH_STOP",
+ "RTT_TIMER_START",
},
{ /* RESOURCE */
"RESOURCE_DBGID_DEFINITION_START",
@@ -787,7 +821,24 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
""
},
{ /* ANI */
- ""
+ "ANI_DBGID_POLL",
+ "ANI_DBGID_CONTROL",
+ "ANI_DBGID_OFDM_PARAMS",
+ "ANI_DBGID_CCK_PARAMS",
+ "ANI_DBGID_RESET",
+ "ANI_DBGID_RESTART",
+ "ANI_DBGID_OFDM_LEVEL",
+ "ANI_DBGID_CCK_LEVEL",
+ "ANI_DBGID_FIRSTEP",
+ "ANI_DBGID_CYCPWR",
+ "ANI_DBGID_MRC_CCK",
+ "ANI_DBGID_SELF_CORR_LOW",
+ "ANI_DBGID_ENABLE",
+ "ANI_DBGID_CURRENT_LEVEL",
+ "ANI_DBGID_POLL_PERIOD",
+ "ANI_DBGID_LISTEN_PERIOD",
+ "ANI_DBGID_OFDM_LEVEL_CFG",
+ "ANI_DBGID_CCK_LEVEL_CFG"
},
{
"P2P_DBGID_DEFINITION_START",
@@ -828,6 +879,7 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"P2P_GO_GET_NOA_INFO",
"P2P_GO_ADD_ONE_SHOT_NOA",
"P2P_GO_GET_NOA_IE",
+ "P2P_GO_BCN_TX_COMP",
"P2P_DBGID_DEFINITION_END",
},
{
@@ -844,6 +896,7 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"CSA_OFFLOAD_WMI_EVENT_ERROR",
"CSA_OFFLOAD_WMI_EVENT_SENT",
"CSA_OFFLOAD_WMI_CHANSWITCH_RECV",
+ "CSA_DBGID_DEFINITION_END",
},
{ /* NLO offload */
""
@@ -872,6 +925,7 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"WOW_INIT",
"WOW_RECV_MAGIC_PKT",
"WOW_RECV_BITMAP_PATTERN",
+ "WOW_DBGID_DEFINITION_END",
},
{ /* WAL_VDEV */
""
@@ -884,7 +938,16 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"TP_LOCAL_SEND",
},
{ /* STA SMPS */
- ""
+ "STA_SMPS_DBGID_DEFINITION_START",
+ "STA_SMPS_DBGID_CREATE_PDEV_INSTANCE",
+ "STA_SMPS_DBGID_CREATE_VIRTUAL_CHAN_INSTANCE",
+ "STA_SMPS_DBGID_DELETE_VIRTUAL_CHAN_INSTANCE",
+ "STA_SMPS_DBGID_CREATE_STA_INSTANCE",
+ "STA_SMPS_DBGID_DELETE_STA_INSTANCE",
+ "STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_START",
+ "STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_STOP",
+ "STA_SMPS_DBGID_SEND_SMPS_ACTION_FRAME",
+ "SMPS_DBGID_DEFINITION_END",
},
{ /* SWBMISS */
"SWBMISS_DBGID_DEFINITION_START",
@@ -917,6 +980,45 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"TDLS_DBGID_PEER_EVT_DISCOVER",
"TDLS_DBGID_PEER_EVT_DELETE",
},
+ { /* HB */
+ "WLAN_HB_DBGID_DEFINITION_START",
+ "WLAN_HB_DBGID_INIT",
+ "WLAN_HB_DBGID_TCP_GET_TXBUF_FAIL",
+ "WLAN_HB_DBGID_TCP_SEND_FAIL",
+ "WLAN_HB_DBGID_BSS_PEER_NULL",
+ "WLAN_HB_DBGID_UDP_GET_TXBUF_FAIL",
+ "WLAN_HB_DBGID_UDP_SEND_FAIL",
+ "WLAN_HB_DBGID_WMI_CMD_INVALID_PARAM",
+ "WLAN_HB_DBGID_WMI_CMD_INVALID_OP",
+ "WLAN_HB_DBGID_WOW_NOT_ENTERED",
+ "WLAN_HB_DBGID_ALLOC_SESS_FAIL",
+ "WLAN_HB_DBGID_CTX_NULL",
+ "WLAN_HB_DBGID_CHKSUM_ERR",
+ "WLAN_HB_DBGID_UDP_TX",
+ "WLAN_HB_DBGID_TCP_TX",
+ "WLAN_HB_DBGID_DEFINITION_END",
+ },
+ { /* TXBF */
+ "TXBFEE_DBGID_START",
+ "TXBFEE_DBGID_NDPA_RECEIVED",
+ "TXBFEE_DBGID_HOST_CONFIG_TXBFEE_TYPE",
+ "TXBFER_DBGID_SEND_NDPA",
+ "TXBFER_DBGID_GET_NDPA_BUF_FAIL",
+ "TXBFER_DBGID_SEND_NDPA_FAIL",
+ "TXBFER_DBGID_GET_NDP_BUF_FAIL",
+ "TXBFER_DBGID_SEND_NDP_FAIL",
+ "TXBFER_DBGID_GET_BRPOLL_BUF_FAIL",
+ "TXBFER_DBGID_SEND_BRPOLL_FAIL",
+ "TXBFER_DBGID_HOST_CONFIG_CMDID",
+ "TXBFEE_DBGID_HOST_CONFIG_CMDID",
+ "TXBFEE_DBGID_ENABLED_ENABLED_UPLOAD_H",
+ "TXBFEE_DBGID_UPLOADH_CV_TAG",
+ "TXBFEE_DBGID_UPLOADH_H_TAG",
+ "TXBFEE_DBGID_CAPTUREH_RECEIVED",
+ "TXBFEE_DBGID_PACKET_IS_STEERED",
+ "TXBFEE_UPLOADH_EVENT_ALLOC_MEM_FAIL",
+ "TXBFEE_DBGID_END",
+ },
};
static char *
@@ -1077,8 +1179,8 @@ dbglog_print_raw_data(A_UINT32 *buffer, A_UINT32 length)
}
-int
-dbglog_parse_debug_logs(u_int8_t *datap, u_int16_t len)
+static int
+dbglog_parse_debug_logs(u_int8_t *datap, u_int16_t len, u_int16_t dropped)
{
A_UINT32 count=0;
A_UINT32 timestamp=0;
@@ -1092,6 +1194,9 @@ dbglog_parse_debug_logs(u_int8_t *datap, u_int16_t len)
buffer = (A_UINT32 *)datap;
length = (len >> 2);
+ if(dropped > 0)
+ printf("%d log buffer got dropped in firmware \n", dropped);
+
while ((count + 2) < length) {
timestamp = DBGLOG_GET_TIME_STAMP(buffer[count]);
@@ -1385,6 +1490,24 @@ A_BOOL dbglog_ratectrl_print_handler(
case RATECTRL_DBGID_WAL_RCUPDATE:
dbglog_printf(timestamp, vap_id, "ratectrl_dbgid_wal_rcupdate [numelems %d ppduflag 0x%x] ",
args[0], args[1]);
+ break;
+ case RATECTRL_DBGID_GTX_UPDATE:
+ {
+ switch (args[0]) {
+ case 255:
+ dbglog_printf(timestamp, vap_id, "GtxInitPwrCfg [bw[last %d|cur %d] rtcode 0x%x tpc %d tpc_init_pwr_cfg %d] ",
+ args[1] >> 8, args[1] & 0xff, args[2], args[3], args[4]);
+ break;
+ case 254:
+ dbglog_printf(timestamp, vap_id, "gtx_cfg_addr [RTMask0@0x%x PERThreshold@0x%x gtxTPCMin@0x%x userGtxMask@0x%x] ",
+ args[1], args[2], args[3], args[4]);
+ break;
+ default:
+ dbglog_printf(timestamp, vap_id, "gtx_update [act %d bw %d rix 0x%x tpc %d per %d lastrssi %d] ",
+ args[0], args[1], args[2], args[3], args[4], args[5]);
+ }
+ }
+ break;
}
return TRUE;
}
@@ -2430,7 +2553,7 @@ int main(int argc, char *argv[])
while ((res = fread(buf, RECLEN, 1, log_in)) == 1) {
- dbglog_parse_debug_logs(&buf[8], get_le32(&buf[4]));
+ dbglog_parse_debug_logs(&buf[12], get_le32(&buf[4]), get_le32(&buf[8]));
}
fclose(log_in);
diff --git a/tools/fwdebuglog/cld-fwlog-record.c b/tools/fwdebuglog/cld-fwlog-record.c
index 28477a680d4c..138df43b3cea 100644
--- a/tools/fwdebuglog/cld-fwlog-record.c
+++ b/tools/fwdebuglog/cld-fwlog-record.c
@@ -56,8 +56,8 @@ static size_t capture(FILE *out_log, FILE *in_log)
size_t res;
while ((res = fread(buf, RECLEN, 1, in_log)) == 1) {
- printf("Read record timestamp=%u length=%u\n",
- get_le32(buf), get_le32(&buf[4]));
+ printf("Read record timestamp=%u length=%u no. fw dropped=%u\n",
+ get_le32(buf), get_le32(&buf[4]), get_le32(&buf[8]));
fseek(out_log, record * RECLEN, SEEK_SET);
if (fwrite(buf, RECLEN, res, out_log) != res)
perror("fwrite");
diff --git a/tools/fwdebuglog/parser.c b/tools/fwdebuglog/parser.c
index 6a68980af48f..f167c8c2a334 100644
--- a/tools/fwdebuglog/parser.c
+++ b/tools/fwdebuglog/parser.c
@@ -121,6 +121,8 @@ const char *dbglog_get_module_str(A_UINT32 module_id)
return "STA_SMPS";
case WLAN_MODULE_TDLS:
return "TDLS";
+ case WLAN_MODULE_P2P:
+ return "P2P";
default:
return "UNKNOWN";
}
@@ -185,11 +187,20 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"WMI_CMD_PARAMS",
"WMI_EVENT_ALLOC_FAILURE",
"WMI_DBGID_DCS_PARAM_CMD",
+ "WMI_SEND_EVENT_WRONG_TLV",
+ "WMI_SEND_EVENT_NO_TLV_DEF",
"WMI_DBGID_DEFNITION_END",
},
{
"PS_STA_DEFINITION_START",
"PS_STA_PM_ARB_REQUEST",
+ "PS_STA_DELIVER_EVENT",
+ "PS_STA_PSPOLL_SEQ_DONE",
+ "PS_STA_COEX_MODE",
+ "PS_STA_PSPOLL_ALLOW",
+ "PS_STA_SET_PARAM",
+ "PS_STA_SPECPOLL_TIMER_STARTED",
+ "PS_STA_SPECPOLL_TIMER_STOPPED",
},
{
"WHAL_DBGID_DEFINITION_START",
@@ -230,56 +241,7 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"WHAL_ERROR_INTERRUPT_BB_PANIC",
"WHAL_ERROR_PAPRD_MAXGAIN_ABOVE_WINDOW",
"WHAL_ERROR_QCU_HW_PAUSE_MISMATCH",
- "WHAL_COEX_RESET",
- "WHAL_COEX_SELF_GEN_MASK",
- "WHAL_ERROR_COEX_MCI_ISR",
- "WHAL_COEX_MCI_ISR_IntRaw",
- "WHAL_COEX_MCI_ISR_Int1Raw",
- "WHAL_COEX_MCI_ISR_RxMsgRaw",
- "WHAL_COEX_SENDMSG_QUEUE",
- "WHAL_COEX_TX_MCI_REMOTE_RESET",
- "WHAL_COEX_TX_MCI_TYPE_UNKNOWN",
- "WHAL_COEX_TX_MCI_SYS_SLEEPING",
- "WHAL_COEX_TX_MCI_REQ_WAKE",
- "WHAL_COEX_TX_MCI_SYS_WAKING",
- "WHAL_COEX_TX_MCI_LNA_TAKE",
- "WHAL_COEX_TX_MCI_LNA_TRANS",
- "WHAL_COEX_TX_MCI_GPM_UNKNOWN",
- "WHAL_COEX_TX_MCI_GPM_WLAN_SET_ACL_INACTIVITY",
- "WHAL_COEX_TX_MCI_GPM_BT_PAUSE_PROFILE",
- "WHAL_COEX_TX_MCI_GPM_WLAN_PRIO",
- "WHAL_COEX_TX_MCI_GPM_BT_STATUS_UPDATE",
- "WHAL_COEX_TX_MCI_GPM_BT_UPDATE_FLAGS",
- "WHAL_COEX_TX_MCI_GPM_VERSION_QUERY",
- "WHAL_COEX_TX_MCI_GPM_VERSION_RESPONSE",
- "WHAL_COEX_TX_MCI_GPM_STATUS_QUERY",
- "WHAL_COEX_TX_MCI_GPM_HALT_BT_GPM",
- "WHAL_COEX_TX_MCI_GPM_WLAN_CHANNELS",
- "WHAL_COEX_TX_MCI_GPM_BT_PROFILE_INFO",
- "WHAL_COEX_TX_MCI_GPM_BT_CAL_REQ ",
- "WHAL_COEX_TX_MCI_GPM_BT_CAL_GRANT",
- "WHAL_COEX_TX_MCI_GPM_BT_CAL_DONE",
- "WHAL_COEX_TX_MCI_GPM_WLAN_CAL_REQ",
- "WHAL_COEX_TX_MCI_GPM_WLAN_CAL_GRANT",
- "WHAL_COEX_TX_MCI_GPM_WLAN_CAL_DONE",
- "WHAL_COEX_TX_MCI_GPM_BT_DEBUG",
- "WHAL_COEX_WHAL_MCI_RESET",
- "WHAL_COEX_POLL_BT_CAL_DONE_TIMEOUT",
- "WHAL_COEX_WHAL_PAUSE",
- "WHAL_COEX_RX_MCI_GPM_BT_CAL_REQ",
- "WHAL_COEX_RX_MCI_GPM_BT_CAL_DONE",
- "WHAL_COEX_RX_MCI_GPM_BT_CAL_GRANT",
- "WHAL_COEX_WLAN_CAL_START",
- "WHAL_COEX_WLAN_CAL_RESULT ",
- "WHAL_COEX_BtMciState",
- "WHAL_COEX_BtCalState",
- "WHAL_COEX_WlanCalState",
- "WHAL_COEX_RxReqWakeCount",
- "WHAL_COEX_RxRemoteResetCount",
- "WHAL_COEX_RESTART_CAL",
- "WHAL_COEX_WHAL_COEX_RESET",
- "WHAL_COEX_SELF_GEN_MASK",
- "WHAL_DBGID_DEFINITION_END"
+ "WHAL_DBGID_DEFINITION_END",
},
{
"COEX_DEBUGID_START",
@@ -482,53 +444,96 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"COEX_PSP_STAT_2", // 197
"COEX_PSP_RX_STATUS_STATE_2", // 198
"COEX_PSP_ERROR", // 199
- "COEX_T2BT", // 200
- "COEX_BT_DURATION", // 201
- "COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG", // 202
- "COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG_RSP", // 203
- "COEX_TX_MCI_GPM_SCAN_OP", // 204
- "COEX_TX_MCI_GPM_BT_PAUSE_GPM_TX", // 205
- "COEX_CTS2S_SEND", // 206
- "COEX_CTS2S_RESULT", // 207
- "COEX_ENTER_OCS", // 208
- "COEX_EXIT_OCS", // 209
- "COEX_UPDATE_OCS", // 210
- "COEX_STATUS_OCS", // 211
- "COEX_STATS_BT", // 212
- "COEX_DEBUG_MESSAGE_END"
+ "COEX_T2BT", // 200
+ "COEX_BT_DURATION", // 201
+ "COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG", // 202
+ "COEX_TX_MCI_GPM_WLAN_SCHED_INFO_TRIG_RSP", // 203
+ "COEX_TX_MCI_GPM_SCAN_OP", // 204
+ "COEX_TX_MCI_GPM_BT_PAUSE_GPM_TX", // 205
+ "COEX_CTS2S_SEND", // 206
+ "COEX_CTS2S_RESULT", // 207
+ "COEX_ENTER_OCS", // 208
+ "COEX_EXIT_OCS", // 209
+ "COEX_UPDATE_OCS", // 210
+ "COEX_STATUS_OCS", // 211
+ "COEX_STATS_BT", // 212
+ "COEX_MWS_WLAN_INIT",
+ "COEX_MWS_WBTMR_SYNC",
+ "COEX_MWS_TYPE2_RX",
+ "COEX_MWS_TYPE2_TX",
+ "COEX_MWS_WLAN_CHAVD",
+ "COEX_MWS_WLAN_CHAVD_INSERT",
+ "COEX_MWS_WLAN_CHAVD_MERGE",
+ "COEX_MWS_WLAN_CHAVD_RPT",
+ "COEX_MWS_CP_MSG_SEND",
+ "COEX_MWS_CP_ESCAPE",
+ "COEX_MWS_CP_UNFRAME",
+ "COEX_MWS_CP_SYNC_UPDATE",
+ "COEX_MWS_CP_SYNC",
+ "COEX_MWS_CP_WLAN_STATE_IND",
+ "COEX_MWS_CP_SYNCRESP_TIMEOUT",
+ "COEX_MWS_SCHEME_UPDATE",
+ "COEX_MWS_WLAN_EVENT",
+ "COEX_MWS_UART_UNESCAPE",
+ "COEX_MWS_UART_ENCODE_SEND",
+ "COEX_MWS_UART_RECV_DECODE",
+ "COEX_MWS_UL_HDL",
+ "COEX_MWS_REMOTE_EVENT",
+ "COEX_MWS_OTHER",
+ "COEX_MWS_ERROR",
+ "COEX_MWS_ANT_DIVERSITY", //237
+ "COEX_P2P_GO",
+ "COEX_P2P_CLIENT",
+ "COEX_SCC_1",
+ "COEX_SCC_2",
+ "COEX_MCC_1",
+ "COEX_MCC_2",
+ "COEX_TRF_SHAPE_NOA",
+ "COEX_NOA_ONESHOT",
+ "COEX_NOA_PERIODIC",
+ "COEX_LE_1",
+ "COEX_LE_2",
+ "COEX_ANT_1",
+ "COEX_ANT_2",
+ "COEX_ENTER_NOA",
+ "COEX_EXIT_NOA",
+ "COEX_BT_SCAN_PROTECT", // 253
+ "COEX_DEBUG_ID_END" // 254
},
{
- "RO_DBGID_DEFINITION_START",
- "RO_REFRESH_ROAM_TABLE",
- "RO_UPDATE_ROAM_CANDIDATE",
- "RO_UPDATE_ROAM_CANDIDATE_CB",
- "RO_UPDATE_ROAM_CANDIDATE_FINISH",
- "RO_REFRESH_ROAM_TABLE_DONE",
- "RO_PERIODIC_SEARCH_CB",
- "RO_PERIODIC_SEARCH_TIMEOUT",
- "RO_INIT",
- "RO_BMISS_STATE1",
- "RO_BMISS_STATE2",
- "RO_SET_PERIODIC_SEARCH_ENABLE",
- "RO_SET_PERIODIC_SEARCH_DISABLE",
- "RO_ENABLE_SQ_THRESHOLD",
- "RO_DISABLE_SQ_THRESHOLD",
- "RO_ADD_BSS_TO_ROAM_TABLE",
- "RO_SET_PERIODIC_SEARCH_MODE",
- "RO_CONFIGURE_SQ_THRESHOLD1",
- "RO_CONFIGURE_SQ_THRESHOLD2",
- "RO_CONFIGURE_SQ_PARAMS",
- "RO_LOW_SIGNAL_QUALITY_EVENT",
- "RO_HIGH_SIGNAL_QUALITY_EVENT",
- "RO_REMOVE_BSS_FROM_ROAM_TABLE",
- "RO_UPDATE_CONNECTION_STATE_METRIC",
- "RO_LOWRSSI_SCAN_PARAMS",
- "RO_LOWRSSI_SCAN_START",
- "RO_LOWRSSI_SCAN_END",
- "RO_LOWRSSI_SCAN_CANCEL",
- "RO_LOWRSSI_ROAM_CANCEL",
- "RO_REFRESH_ROAM_CANDIDATE",
- "RO_DBGID_DEFINITION_END"
+ "ROAM_DBGID_DEFINITION_START",
+ "ROAM_MODULE_INIT",
+ "ROAM_DEV_START",
+ "ROAM_CONFIG_RSSI_THRESH",
+ "ROAM_CONFIG_SCAN_PERIOD",
+ "ROAM_CONFIG_AP_PROFILE",
+ "ROAM_CONFIG_CHAN_LIST",
+ "ROAM_CONFIG_SCAN_PARAMS",
+ "ROAM_CONFIG_RSSI_CHANGE",
+ "ROAM_SCAN_TIMER_START",
+ "ROAM_SCAN_TIMER_EXPIRE",
+ "ROAM_SCAN_TIMER_STOP",
+ "ROAM_SCAN_STARTED",
+ "ROAM_SCAN_COMPLETE",
+ "ROAM_SCAN_CANCELLED",
+ "ROAM_CANDIDATE_FOUND",
+ "ROAM_RSSI_ACTIVE_SCAN",
+ "ROAM_RSSI_ACTIVE_ROAM",
+ "ROAM_RSSI_GOOD",
+ "ROAM_BMISS_FIRST_RECV",
+ "ROAM_DEV_STOP",
+ "ROAM_FW_OFFLOAD_ENABLE",
+ "ROAM_CANDIDATE_SSID_MATCH",
+ "ROAM_CANDIDATE_SECURITY_MATCH",
+ "ROAM_LOW_RSSI_INTERRUPT",
+ "ROAM_HIGH_RSSI_INTERRUPT",
+ "ROAM_SCAN_REQUESTED",
+ "ROAM_BETTER_CANDIDATE_FOUND",
+ "ROAM_BETTER_AP_EVENT",
+ "ROAM_CANCEL_LOW_PRIO_SCAN",
+ "ROAM_FINAL_BMISS_RECVD",
+ "ROAM_CONFIG_SCAN_MODE",
+ "ROAM_DBGID_DEFINITION_END"
},
{
"RESMGR_CHMGR_DEFINITION_START",
@@ -537,6 +542,8 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"RESMGR_CHMGR_RESUME_COMPLETE",
"RESMGR_CHMGR_VDEV_PAUSE",
"RESMGR_CHMGR_VDEV_UNPAUSE",
+ "RESMGR_CHMGR_CTS2S_TX_COMP",
+ "RESMGR_CHMGR_CFEND_TX_COMP",
"RESMGR_CHMGR_DEFINITION_END"
},
{
@@ -591,6 +598,15 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"RESMGR_VC_REG_UNREG_LINK",
"RESMGR_VC_PRINT_LINK",
"RESMGR_OCS_MISS_TOLERANCE",
+ "RESMGR_DYN_SCH_ALLOCRAM_SIZE",
+ "RESMGR_DYN_SCH_ENABLE",
+ "RESMGR_DYN_SCH_ACTIVE",
+ "RESMGR_DYN_SCH_CH_STATS_START",
+ "RESMGR_DYN_SCH_CH_SX_STATS",
+ "RESMGR_DYN_SCH_TOT_UTIL_PER",
+ "RESMGR_DYN_SCH_HOME_CH_QUOTA",
+ "RESMGR_OCS_REG_RECAL_QUOTA_NOTIF",
+ "RESMGR_OCS_DEREG_RECAL_QUOTA_NOTIF",
"RESMGR_DEFINITION_END"
},
{
@@ -610,6 +626,10 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"VDEV_MGR_VDEV_START_OCS_HP_REQ_COMPLETE",
"VDEV_MGR_VDEV_START_OCS_HP_REQ_STOP",
"VDEV_MGR_HP_START_TIME",
+ "VDEV_MGR_VDEV_PAUSE_DELAY_UPDATE",
+ "VDEV_MGR_VDEV_PAUSE_FAIL",
+ "VDEV_MGR_GEN_PERIODIC_NOA",
+ "VDEV_MGR_OFF_CHAN_GO_CH_REQ_SETUP",
"VDEV_MGR_DEFINITION_END",
},
{
@@ -626,7 +646,16 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"SCAN_FWLOG_EVENT_RESTARTED",
"SCAN_FWLOG_EVENT_COMPLETED",
},
- { "" /* Rate ctrl*/
+ {
+ "RATECTRL_DBGID_DEFINITION_START", /* Rate ctrl*/
+ "RATECTRL_DBGID_ASSOC",
+ "RATECTRL_DBGID_NSS_CHANGE",
+ "RATECTRL_DBGID_CHAINMASK_ERR",
+ "RATECTRL_DBGID_UNEXPECTED_FRAME",
+ "RATECTRL_DBGID_WAL_RCQUERY",
+ "RATECTRL_DBGID_WAL_RCUPDATE",
+ "RATECTRL_DBGID_GTX_UPDATE",
+ "RATECTRL_DBGID_DEFINITION_END"
},
{
"AP_PS_DBGID_DEFINITION_START",
@@ -646,6 +675,8 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"AP_PS_DBGID_UAPSD_RESPONSE",
"AP_PS_DBGID_SEND_COMPLETE",
"AP_PS_DBGID_SEND_N_COMPLETE",
+ "AP_PS_DBGID_DETECT_OUT_OF_SYNC_STA",
+ "AP_PS_DBGID_DELIVER_CAB",
},
{
"" /* Block Ack */
@@ -737,6 +768,10 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"WAL_DBGID_TX_MGMT_COMP_DESCID_STATUS",
"WAL_DBGID_TX_DATA_COMP_MSDUID_STATUS",
"WAL_DBGID_RESET_PCU_CYCLE_CNT",
+ "WAL_DBGID_SETUP_RSSI_INTERRUPTS",
+ "WAL_DBGID_BRSSI_CONFIG",
+ "WAL_DBGID_CURRENT_BRSSI_AVE",
+ "WAL_DBGID_BCN_TX_COMP",
"WAL_DBGID_DEFINITION_END",
},
{
@@ -746,7 +781,28 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"" /* pcie lp */
},
{
- "" /* RTT */
+ /* RTT */
+ "RTT_CALL_FLOW",
+ "RTT_REQ_SUB_TYPE",
+ "RTT_MEAS_REQ_HEAD",
+ "RTT_MEAS_REQ_BODY",
+ "",
+ "",
+ "RTT_INIT_GLOBAL_STATE",
+ "",
+ "RTT_REPORT",
+ "",
+ "RTT_ERROR_REPORT",
+ "RTT_TIMER_STOP",
+ "RTT_SEND_TM_FRAME",
+ "RTT_V3_RESP_CNT",
+ "RTT_V3_RESP_FINISH",
+ "RTT_CHANNEL_SWITCH_REQ",
+ "RTT_CHANNEL_SWITCH_GRANT",
+ "RTT_CHANNEL_SWITCH_COMPLETE",
+ "RTT_CHANNEL_SWITCH_PREEMPT",
+ "RTT_CHANNEL_SWITCH_STOP",
+ "RTT_TIMER_START",
},
{ /* RESOURCE */
"RESOURCE_DBGID_DEFINITION_START",
@@ -767,7 +823,24 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
""
},
{ /* ANI */
- ""
+ "ANI_DBGID_POLL",
+ "ANI_DBGID_CONTROL",
+ "ANI_DBGID_OFDM_PARAMS",
+ "ANI_DBGID_CCK_PARAMS",
+ "ANI_DBGID_RESET",
+ "ANI_DBGID_RESTART",
+ "ANI_DBGID_OFDM_LEVEL",
+ "ANI_DBGID_CCK_LEVEL",
+ "ANI_DBGID_FIRSTEP",
+ "ANI_DBGID_CYCPWR",
+ "ANI_DBGID_MRC_CCK",
+ "ANI_DBGID_SELF_CORR_LOW",
+ "ANI_DBGID_ENABLE",
+ "ANI_DBGID_CURRENT_LEVEL",
+ "ANI_DBGID_POLL_PERIOD",
+ "ANI_DBGID_LISTEN_PERIOD",
+ "ANI_DBGID_OFDM_LEVEL_CFG",
+ "ANI_DBGID_CCK_LEVEL_CFG"
},
{
"P2P_DBGID_DEFINITION_START",
@@ -806,6 +879,9 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"P2P_GO_NOA_NOTIF",
"P2P_GO_TBTT_OFFSET",
"P2P_GO_GET_NOA_INFO",
+ "P2P_GO_ADD_ONE_SHOT_NOA",
+ "P2P_GO_GET_NOA_IE",
+ "P2P_GO_BCN_TX_COMP",
"P2P_DBGID_DEFINITION_END",
},
{
@@ -822,6 +898,7 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"CSA_OFFLOAD_WMI_EVENT_ERROR",
"CSA_OFFLOAD_WMI_EVENT_SENT",
"CSA_OFFLOAD_WMI_CHANSWITCH_RECV",
+ "CSA_DBGID_DEFINITION_END",
},
{ /* NLO offload */
""
@@ -834,6 +911,8 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"WLAN_CHATTER_FILTER_MISS",
"WLAN_CHATTER_FILTER_FULL",
"WLAN_CHATTER_FILTER_TM_ADJ",
+ "WLAN_CHATTER_BUFFER_FULL",
+ "WLAN_CHATTER_TIMEOUT",
"WLAN_CHATTER_DBGID_DEFINITION_END",
},
{
@@ -848,6 +927,7 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"WOW_INIT",
"WOW_RECV_MAGIC_PKT",
"WOW_RECV_BITMAP_PATTERN",
+ "WOW_DBGID_DEFINITION_END",
},
{ /* WAL_VDEV */
""
@@ -860,7 +940,16 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"TP_LOCAL_SEND",
},
{ /* STA SMPS */
- ""
+ "STA_SMPS_DBGID_DEFINITION_START",
+ "STA_SMPS_DBGID_CREATE_PDEV_INSTANCE",
+ "STA_SMPS_DBGID_CREATE_VIRTUAL_CHAN_INSTANCE",
+ "STA_SMPS_DBGID_DELETE_VIRTUAL_CHAN_INSTANCE",
+ "STA_SMPS_DBGID_CREATE_STA_INSTANCE",
+ "STA_SMPS_DBGID_DELETE_STA_INSTANCE",
+ "STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_START",
+ "STA_SMPS_DBGID_VIRTUAL_CHAN_SMPS_STOP",
+ "STA_SMPS_DBGID_SEND_SMPS_ACTION_FRAME",
+ "SMPS_DBGID_DEFINITION_END",
},
{ /* SWBMISS */
"SWBMISS_DBGID_DEFINITION_START",
@@ -893,6 +982,45 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] =
"TDLS_DBGID_PEER_EVT_DISCOVER",
"TDLS_DBGID_PEER_EVT_DELETE",
},
+ { /* HB */
+ "WLAN_HB_DBGID_DEFINITION_START",
+ "WLAN_HB_DBGID_INIT",
+ "WLAN_HB_DBGID_TCP_GET_TXBUF_FAIL",
+ "WLAN_HB_DBGID_TCP_SEND_FAIL",
+ "WLAN_HB_DBGID_BSS_PEER_NULL",
+ "WLAN_HB_DBGID_UDP_GET_TXBUF_FAIL",
+ "WLAN_HB_DBGID_UDP_SEND_FAIL",
+ "WLAN_HB_DBGID_WMI_CMD_INVALID_PARAM",
+ "WLAN_HB_DBGID_WMI_CMD_INVALID_OP",
+ "WLAN_HB_DBGID_WOW_NOT_ENTERED",
+ "WLAN_HB_DBGID_ALLOC_SESS_FAIL",
+ "WLAN_HB_DBGID_CTX_NULL",
+ "WLAN_HB_DBGID_CHKSUM_ERR",
+ "WLAN_HB_DBGID_UDP_TX",
+ "WLAN_HB_DBGID_TCP_TX",
+ "WLAN_HB_DBGID_DEFINITION_END",
+ },
+ { /* TXBF */
+ "TXBFEE_DBGID_START",
+ "TXBFEE_DBGID_NDPA_RECEIVED",
+ "TXBFEE_DBGID_HOST_CONFIG_TXBFEE_TYPE",
+ "TXBFER_DBGID_SEND_NDPA",
+ "TXBFER_DBGID_GET_NDPA_BUF_FAIL",
+ "TXBFER_DBGID_SEND_NDPA_FAIL",
+ "TXBFER_DBGID_GET_NDP_BUF_FAIL",
+ "TXBFER_DBGID_SEND_NDP_FAIL",
+ "TXBFER_DBGID_GET_BRPOLL_BUF_FAIL",
+ "TXBFER_DBGID_SEND_BRPOLL_FAIL",
+ "TXBFER_DBGID_HOST_CONFIG_CMDID",
+ "TXBFEE_DBGID_HOST_CONFIG_CMDID",
+ "TXBFEE_DBGID_ENABLED_ENABLED_UPLOAD_H",
+ "TXBFEE_DBGID_UPLOADH_CV_TAG",
+ "TXBFEE_DBGID_UPLOADH_H_TAG",
+ "TXBFEE_DBGID_CAPTUREH_RECEIVED",
+ "TXBFEE_DBGID_PACKET_IS_STEERED",
+ "TXBFEE_UPLOADH_EVENT_ALLOC_MEM_FAIL",
+ "TXBFEE_DBGID_END",
+ },
};
static char *
@@ -1041,7 +1169,7 @@ dbglog_print_raw_data(A_UINT32 *buffer, A_UINT32 length)
}
int
-dbglog_parse_debug_logs(u_int8_t *datap, u_int16_t len)
+dbglog_parse_debug_logs(u_int8_t *datap, u_int16_t len, u_int16_t dropped)
{
A_UINT32 count=0;
A_UINT32 timestamp=0;
@@ -1052,6 +1180,9 @@ dbglog_parse_debug_logs(u_int8_t *datap, u_int16_t len)
A_UINT32 *buffer;
A_UINT32 length = len >> 2;
+ if(dropped > 0)
+ printf("%d log buffer got dropped in firmware\n", dropped);
+
buffer = (A_UINT32 *)datap;
length = (len >> 2);
@@ -1281,6 +1412,11 @@ dbglog_sta_powersave_print_handler(
{ "RX_WAKE_POLICY", 0 },
{ "DELAYED_PAUSE_RX_LEAK", 1 },
{ "TXRX_INACTIVITY_BLOCKED_RETRY", 1 },
+ { "SPEC_WAKE_INTERVAL", 1 },
+ { "MAX_SPEC_NODATA_PSPOLL", 0 },
+ { "ESTIMATED_PSPOLL_RESP_TIME", 1 },
+ { "QPOWER_MAX_PSPOLL_BEFORE_WAKE", 0 },
+ { "QPOWER_ENABLE", 0 },
};
A_UINT32 param = args[0];
A_UINT32 value = args[1];
@@ -1343,6 +1479,25 @@ A_BOOL dbglog_ratectrl_print_handler(
case RATECTRL_DBGID_WAL_RCUPDATE:
dbglog_printf(timestamp, vap_id, "ratectrl_dbgid_wal_rcupdate [numelems %d ppduflag 0x%x] ",
args[0], args[1]);
+ break;
+ case RATECTRL_DBGID_GTX_UPDATE:
+ {
+ switch (args[0]) {
+ case 255:
+ dbglog_printf(timestamp, vap_id, "GtxInitPwrCfg [bw[last %d|cur %d] rtcode 0x%x tpc %d tpc_init_pwr_cfg %d] ",
+ args[1] >> 8, args[1] & 0xff, args[2], args[3], args[4]);
+ break;
+ case 254:
+ dbglog_printf(timestamp, vap_id, "gtx_cfg_addr [RTMask0@0x%x PERThreshold@0x%x gtxTPCMin@0x%x userGtxMask@0x%x] ",
+ args[1], args[2], args[3], args[4]);
+ break;
+ default:
+ dbglog_printf(timestamp, vap_id, "gtx_update [act %d bw %d rix 0x%x tpc %d per %d lastrssi %d] ",
+ args[0], args[1], args[2], args[3], args[4], args[5]);
+ }
+ }
+ break;
+
}
return TRUE;
}
@@ -2273,6 +2428,88 @@ A_BOOL dbglog_smps_print_handler(A_UINT32 mod_id,
return TRUE;
}
+A_BOOL
+dbglog_p2p_print_handler(
+ A_UINT32 mod_id,
+ A_UINT16 vap_id,
+ A_UINT32 dbg_id,
+ A_UINT32 timestamp,
+ A_UINT16 numargs,
+ A_UINT32 *args)
+{
+ static const char *states[] = {
+ "ACTIVE",
+ "DOZE",
+ "TX_BCN",
+ "CTWIN",
+ "OPPPS",
+ };
+
+ static const char *events[] = {
+ "ONESHOT_NOA",
+ "CTWINDOW",
+ "PERIODIC_NOA",
+ "IDLE",
+ "NOA_CHANGED",
+ "TBTT",
+ "TX_BCN_CMP",
+ "OPPPS_OK",
+ "OPPPS_CHANGED",
+ };
+
+ switch (dbg_id) {
+ case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG:
+ dbglog_sm_print(timestamp, vap_id, numargs, args, "P2P GO PS",
+ states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events));
+ break;
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+A_BOOL
+dbglog_pcielp_print_handler(
+ A_UINT32 mod_id,
+ A_UINT16 vap_id,
+ A_UINT32 dbg_id,
+ A_UINT32 timestamp,
+ A_UINT16 numargs,
+ A_UINT32 *args)
+{
+ static const char *states[] = {
+ "STOP",
+ "TX",
+ "RX",
+ "SLEEP",
+ "SUSPEND",
+ };
+
+ static const char *events[] = {
+ "VDEV_UP",
+ "ALL_VDEV_DOWN",
+ "AWAKE",
+ "SLEEP",
+ "TX_ACTIVITY",
+ "TX_INACTIVITY",
+ "TX_AC_CHANGE",
+ "SUSPEND",
+ "RESUME",
+ };
+
+ switch (dbg_id) {
+ case DBGLOG_DBGID_SM_FRAMEWORK_PROXY_DBGLOG_MSG:
+ dbglog_sm_print(timestamp, vap_id, numargs, args, "PCIELP",
+ states, ARRAY_LENGTH(states), events, ARRAY_LENGTH(events));
+ break;
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
int parser_init()
{
/* Registering parser */
@@ -2286,6 +2523,8 @@ int parser_init()
dbglog_reg_modprint(WLAN_MODULE_BEACON,dbglog_beacon_print_handler);
dbglog_reg_modprint(WLAN_MODULE_DATA_TXRX,dbglog_data_txrx_print_handler);
dbglog_reg_modprint(WLAN_MODULE_STA_SMPS, dbglog_smps_print_handler);
+ dbglog_reg_modprint(WLAN_MODULE_P2P, dbglog_p2p_print_handler);
+ dbglog_reg_modprint(WLAN_MODULE_PCIELP, dbglog_pcielp_print_handler);
return 0;
}