summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-06-24 21:18:08 -0600
committerLinux Build Service Account <lnxbuild@localhost>2016-06-24 21:18:08 -0600
commitb000a22b05cb6da8776c0a379bc5f79c80bd1f77 (patch)
treefb438911a7fed96947227f7debd7d8e658d76f17
parentc04dc51b3267acc1e64f89b79b34e6b0deddb457 (diff)
parent9f09a9e30c496b5bf38ee5c41827f24ccf1f85a7 (diff)
Promotion of wlan-cld2.driver.lnx.1.0-00039.
CRs Change ID Subject -------------------------------------------------------------------------------------------------------------- 1032612 I87f82c5faf7e3c8343c8bffcb421a78c1ab47d61 qcacld-2.0: set ce_suspend to true after tasklet complet 982329 Icff3778d35ef7ea646463fe49c4335e260e9e156 qcacld-2.0: Do not trigger del sta if it is already in p 688141 I255364eb3482c046f256adc68e435233ac4e571f Release 4.0.11.106 1033307 If23398b01124638cfb266f5755fc9e45d3969ac9 qcacld-2.0: unmap buffer for CE dst ring en-queue error 1032185 I54f305319e23b1ffcbd54cc6e7dcc74d39a2e511 qcacld-2.0: Fix P2P GO Negotiation failure issue 1032098 I6c2ab331256b190fd0ce67f8fb95ed4d7cb5e61a qcacld-2.0: Dump stack only once 1018887 I71b77cfa09c5039b487e9a93490837a084314fb3 qcacld-2.0: Make OEM response events wakeable 1031468 I52d8575960e4d5bac5aa509df41c20fb846a96e6 qcacld-2.0: Reset the parameters which overrides the ACS 1030729 I38eea06360226322bb4f7fcbf810635b09da5593 qcacld-2.0: Reset card to recover from target mbox error 1032857 I7e9301323410e0e2ae456aa30da9c628dd7841c2 qcacld-2.0: Reset is_ch_avoid_in_progress correctly 688141 I52d4d2d4f1859197d836001aa961d0bf7581d3a9 Release 4.0.11.105 1027526 I0ac8b4ef01f91539852935242176e6c1f0f3ba25 qcacld-2.0: Remove startup_task from SDIO solution 1032578 I631fb202fba6bc129d03ff21cff2adef328abff2 qcacld-2.0: Do not reset short preamble support and beac 688141 I31d32b2ea9a3c85ea976d4c04c322e38ca07c07b Release 4.0.11.107 1013559 Ie963f80b3c3e5ea5e4dd0f46b3dbdbea9d6c7f49 qcacld-2.0: WAR for dfs false detection 1020119 I169e79f6033096f8d4325657dc3a94677e1ea54d qcacld-2.0: Add compile time assert for SKB CB size Change-Id: I507fd7ac40db7c736ea795ae71069d387f7435f0 CRs-Fixed: 1032098, 688141, 1032857, 1033307, 1030729, 1020119, 1018887, 1032612, 982329, 1013559, 1032185, 1031468, 1027526, 1032578
-rw-r--r--CORE/HDD/inc/wlan_hdd_hostapd.h1
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h5
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c14
-rw-r--r--CORE/HDD/src/wlan_hdd_main.c18
-rw-r--r--CORE/HDD/src/wlan_hdd_p2p.c17
-rw-r--r--CORE/MAC/inc/qwlan_version.h4
-rw-r--r--CORE/MAC/src/dph/dphHashTable.c2
-rw-r--r--CORE/MAC/src/include/dphGlobal.h3
-rw-r--r--CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c11
-rw-r--r--CORE/MAC/src/pe/lim/limSession.c15
-rw-r--r--CORE/SERVICES/COMMON/adf/adf_nbuf.c19
-rw-r--r--CORE/SERVICES/COMMON/hif_msg_based.h10
-rw-r--r--CORE/SERVICES/DFS/inc/dfs.h9
-rw-r--r--CORE/SERVICES/DFS/src/dfs.c71
-rw-r--r--CORE/SERVICES/DFS/src/dfs_debug.c25
-rw-r--r--CORE/SERVICES/DFS/src/dfs_init.c127
-rw-r--r--CORE/SERVICES/DFS/src/dfs_process_radarevent.c199
-rw-r--r--CORE/SERVICES/HIF/PCIe/hif_pci.c4
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.c2
-rw-r--r--CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c108
-rw-r--r--CORE/SERVICES/HTC/htc_recv.c5
-rw-r--r--CORE/SERVICES/WMA/wma.c42
-rw-r--r--CORE/SERVICES/WMA/wma.h1
-rw-r--r--CORE/VOSS/inc/vos_types.h6
-rw-r--r--CORE/VOSS/src/vos_packet.c10
-rw-r--r--CORE/VOSS/src/vos_sched.c19
26 files changed, 645 insertions, 102 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_hostapd.h b/CORE/HDD/inc/wlan_hdd_hostapd.h
index 1e18dbf533bc..574bb75b8b6e 100644
--- a/CORE/HDD/inc/wlan_hdd_hostapd.h
+++ b/CORE/HDD/inc/wlan_hdd_hostapd.h
@@ -218,6 +218,7 @@ hdd_change_ch_avoidance_status(hdd_context_t *hdd_ctx,
spin_lock(&hdd_ctx->sap_update_info_lock);
hdd_ctx->is_ch_avoid_in_progress = value;
spin_unlock(&hdd_ctx->sap_update_info_lock);
+ hddLog(LOG1, FL("is_ch_avoid_in_progress %d"), value);
}
#endif // end #if !defined( WLAN_HDD_HOSTAPD_H )
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 7e3a85a3b86c..e5cdec427b15 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -683,6 +683,11 @@ typedef struct hdd_cfg80211_state_s
hdd_remain_on_chan_ctx_t* remain_on_chan_ctx;
struct mutex remain_on_chan_ctx_lock;
eP2PActionFrameState actionFrmState;
+ /* is_go_neg_ack_received flag is set to 1 when
+ * the pending ack for GO negotiation req is
+ * received.
+ */
+ v_BOOL_t is_go_neg_ack_received;
}hdd_cfg80211_state_t;
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index ebdcf9cc824e..0e7794f94521 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -14647,13 +14647,13 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
#endif
status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
params->ssid_len, params->hidden_ssid);
- if (status == 0) {
- if (0 != wlan_hdd_set_udp_resp_offload(pAdapter, TRUE)) {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- "%s: set udp resp cmd failed %d",
- __func__, status);
- }
- }
+ if (status == 0) {
+ if (0 != wlan_hdd_set_udp_resp_offload(pAdapter, TRUE)) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, "%s: set udp resp cmd failed %d",
+ __func__, status);
+ }
+ }
+ hdd_change_ch_avoidance_status(pHddCtx, false);
}
EXIT();
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index c891412a9b5a..3650b56c2a2a 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -16645,12 +16645,10 @@ void hdd_unsafe_channel_restart_sap(hdd_context_t *hdd_ctx)
if ((adapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode) &&
(!hdd_find_prefd_safe_chnl(hdd_ctx, adapter)))
return;
+
hddLog(LOG1, FL("Current operation channel %d"),
adapter->sessionCtx.ap.operatingChannel);
- hddLog(LOG1, FL("sessionCtx.ap.sapConfig.channel %d"),
- adapter->sessionCtx.ap.sapConfig.channel);
-
for (channel_loop = 0;
channel_loop < hdd_ctx->unsafe_channel_count;
channel_loop++) {
@@ -16671,6 +16669,20 @@ void hdd_unsafe_channel_restart_sap(hdd_context_t *hdd_ctx)
hddLog(LOGE,
FL("Restarting SAP due to unsafe channel"));
+ /* SAP restart due to unsafe channel. While
+ * restarting the SAP, makee sure to clear
+ * acs_channel, channel to reset to 0.
+ * Otherwise these settings will override the
+ * ACS while restart.
+ */
+ hdd_ctx->acs_policy.acs_channel =
+ AUTO_CHANNEL_SELECT;
+ adapter->sessionCtx.ap.sapConfig.channel =
+ AUTO_CHANNEL_SELECT;
+
+ hddLog(LOG1, FL("set sapConfig.channel to %d"),
+ AUTO_CHANNEL_SELECT);
+
wlan_hdd_send_svc_nlink_msg(
hdd_ctx->radio_index,
WLAN_SVC_LTE_COEX_IND,
diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c
index e51d57f302d2..1e81402e67bd 100644
--- a/CORE/HDD/src/wlan_hdd_p2p.c
+++ b/CORE/HDD/src/wlan_hdd_p2p.c
@@ -1865,11 +1865,25 @@ void hdd_sendActionCnf( hdd_adapter_t *pAdapter, tANI_BOOLEAN actionSendSuccess
cfgState->actionFrmState = HDD_IDLE;
- hddLog( LOG1, "Send Action cnf, actionSendSuccess %d", actionSendSuccess);
if( NULL == cfgState->buf )
{
return;
}
+ if (cfgState->is_go_neg_ack_received) {
+
+ cfgState->is_go_neg_ack_received = 0 ;
+ /* Sometimes its possible that host may receive the ack for GO
+ * negotiation req after sending go negotaition confirmation,
+ * in such case drop the ack received for the go negotiation
+ * request, so that supplicant waits for the confirmation ack
+ * from firmware.
+ */
+ hddLog( LOG1, FL("Drop the pending ack received in cfgState->actionFrmState %d"),
+ cfgState->actionFrmState);
+ return;
+ }
+
+ hddLog( LOG1, "Send Action cnf, actionSendSuccess %d", actionSendSuccess);
/*
* buf is the same pointer it passed us to send. Since we are sending
@@ -2635,6 +2649,7 @@ void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter,
{
hddLog(LOG1, "%s: ACK_PENDING and But received RESP for Action frame ",
__func__);
+ cfgState->is_go_neg_ack_received = 1;
hdd_sendActionCnf(pAdapter, TRUE);
}
}
diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h
index 01d21a4d8805..dd54648443e4 100644
--- a/CORE/MAC/inc/qwlan_version.h
+++ b/CORE/MAC/inc/qwlan_version.h
@@ -42,9 +42,9 @@ BRIEF DESCRIPTION:
#define QWLAN_VERSION_MINOR 0
#define QWLAN_VERSION_PATCH 11
#define QWLAN_VERSION_EXTRA ""
-#define QWLAN_VERSION_BUILD 104
+#define QWLAN_VERSION_BUILD 107
-#define QWLAN_VERSIONSTR "4.0.11.104"
+#define QWLAN_VERSIONSTR "4.0.11.107"
#define AR6320_REV1_VERSION 0x5000000
diff --git a/CORE/MAC/src/dph/dphHashTable.c b/CORE/MAC/src/dph/dphHashTable.c
index a39886b02587..383fb49e1272 100644
--- a/CORE/MAC/src/dph/dphHashTable.c
+++ b/CORE/MAC/src/dph/dphHashTable.c
@@ -288,6 +288,7 @@ tpDphHashNode dphInitStaState(tpAniSirGlobal pMac, tSirMacAddr staAddr,
#ifdef WLAN_FEATURE_11W
pStaDs->last_assoc_received_time = 0;
#endif
+ pStaDs->sta_deletion_in_progress = false;
pStaDs->valid = 1;
return pStaDs;
}
@@ -436,6 +437,7 @@ tSirRetStatus dphDeleteHashEntry(tpAniSirGlobal pMac, tSirMacAddr staAddr, tANI_
#ifdef WLAN_FEATURE_11W
ptr->last_assoc_received_time = 0;
#endif
+ ptr->sta_deletion_in_progress = false;
ptr->next = 0;
}
else
diff --git a/CORE/MAC/src/include/dphGlobal.h b/CORE/MAC/src/include/dphGlobal.h
index 2d3517605be8..2ea951b08997 100644
--- a/CORE/MAC/src/include/dphGlobal.h
+++ b/CORE/MAC/src/include/dphGlobal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -512,6 +512,7 @@ typedef struct sDphHashNode
*/
tANI_U8 isDisassocDeauthInProgress;
+ bool sta_deletion_in_progress;
struct sDphHashNode *next;
tANI_S8 del_sta_ctx_rssi;
} tDphHashNode, *tpDphHashNode;
diff --git a/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c b/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c
index 2c1581767ce9..5db1fd513647 100644
--- a/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c
+++ b/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c
@@ -277,13 +277,16 @@ limTriggerSTAdeletion(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession pse
}
if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) ||
- (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)) {
+ (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE) ||
+ pStaDs->sta_deletion_in_progress) {
/* Already in the process of deleting context for the peer */
- PELOGE(limLog(pMac, LOGE,
- FL("Deletion is in progress for peer:%p"), pStaDs->staAddr);)
+ limLog(pMac, LOG1,
+ FL("Deletion is in progress (%d) for peer:%p in mlmState %d"),
+ pStaDs->sta_deletion_in_progress, pStaDs->staAddr,
+ pStaDs->mlmStaContext.mlmState);
return;
}
-
+ pStaDs->sta_deletion_in_progress = true;
pStaDs->mlmStaContext.disassocReason =
eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON;
pStaDs->mlmStaContext.cleanupTrigger = eLIM_LINK_MONITORING_DISASSOC;
diff --git a/CORE/MAC/src/pe/lim/limSession.c b/CORE/MAC/src/pe/lim/limSession.c
index e4d3378f1b81..6fe267edca26 100644
--- a/CORE/MAC/src/pe/lim/limSession.c
+++ b/CORE/MAC/src/pe/lim/limSession.c
@@ -143,9 +143,18 @@ void pe_reset_protection_callback(void *ptr)
vos_mem_zero(&pe_session_entry->gLimOlbcParams,
sizeof(pe_session_entry->gLimOlbcParams));
-
- vos_mem_zero(&pe_session_entry->beaconParams,
- sizeof(pe_session_entry->beaconParams));
+ /*
+ * Do not reset fShortPreamble and beaconInterval, as they
+ * are not updated.
+ */
+ pe_session_entry->beaconParams.llaCoexist = 0;
+ pe_session_entry->beaconParams.llbCoexist = 0;
+ pe_session_entry->beaconParams.llgCoexist = 0;
+ pe_session_entry->beaconParams.ht20Coexist = 0;
+ pe_session_entry->beaconParams.llnNonGFCoexist = 0;
+ pe_session_entry->beaconParams.fRIFSMode = 0;
+ pe_session_entry->beaconParams.fLsigTXOPProtectionFullSupport = 0;
+ pe_session_entry->beaconParams.gHTObssMode = 0;
vos_mem_zero(&mac_ctx->lim.gLimOverlap11gParams,
sizeof(mac_ctx->lim.gLimOverlap11gParams));
diff --git a/CORE/SERVICES/COMMON/adf/adf_nbuf.c b/CORE/SERVICES/COMMON/adf/adf_nbuf.c
index aed95aaa5184..944894f25531 100644
--- a/CORE/SERVICES/COMMON/adf/adf_nbuf.c
+++ b/CORE/SERVICES/COMMON/adf/adf_nbuf.c
@@ -1140,3 +1140,22 @@ int adf_nbuf_update_radiotap(struct mon_rx_status *rx_status, adf_nbuf_t nbuf,
rtap_hdr_len, rtap_len - rtap_hdr_len);
return rtap_len;
}
+
+/**
+ * __adf_nbuf_validate_skb_cb() - validate skb CB
+ *
+ * SKB control block size limit is 48 byte, add compile time
+ * assert if SKB control block is exceeding 48 byte.
+ *
+ * Return: none
+ */
+void
+__adf_nbuf_validate_skb_cb(void)
+{
+ /*
+ * Add compile time assert if SKB control block is exceeding
+ * 48 byte.
+ */
+ BUILD_BUG_ON(sizeof(struct cvg_nbuf_cb) >
+ FIELD_SIZEOF(struct sk_buff, cb));
+}
diff --git a/CORE/SERVICES/COMMON/hif_msg_based.h b/CORE/SERVICES/COMMON/hif_msg_based.h
index f7143aab3d48..af339aef1248 100644
--- a/CORE/SERVICES/COMMON/hif_msg_based.h
+++ b/CORE/SERVICES/COMMON/hif_msg_based.h
@@ -1,5 +1,5 @@
/*
- *Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ *Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -148,6 +148,14 @@ void HIFsuspendwow(HIF_DEVICE *hif_device);
void HIFSetBundleMode(HIF_DEVICE *hif_device, bool enabled, int rx_bundle_cnt);
#endif
+#ifdef HIF_SDIO
+int hif_reset_target(HIF_DEVICE *hif_device);
+#else
+static inline int hif_reset_target(HIF_DEVICE *hif_device)
+{
+ return 0;
+}
+#endif
#ifdef __cplusplus
}
#endif
diff --git a/CORE/SERVICES/DFS/inc/dfs.h b/CORE/SERVICES/DFS/inc/dfs.h
index b424e9167f1e..52ae15f1dea4 100644
--- a/CORE/SERVICES/DFS/inc/dfs.h
+++ b/CORE/SERVICES/DFS/inc/dfs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2005-2014, 2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -89,6 +89,7 @@
#include "dfs_interface.h"
#include "_ieee80211_common.h"
#include "vos_api.h"
+#include "sirDebug.h"
#define ATH_SUPPORT_DFS 1
#define CHANNEL_TURBO 0x00010
@@ -128,6 +129,7 @@
//#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 MAX_DFS_RADAR_TYPE 256
#define DFS_MARGIN_EQUAL(a, b, margin) ((DFS_DIFF(a,b)) <= margin)
#define DFS_MAX_STAGGERED_BURSTS 3
@@ -265,6 +267,7 @@ struct dfs_pulseline {
#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.
*/
@@ -298,6 +301,7 @@ struct dfs_event {
#pragma pack(pop, dfs_event)
#endif
+#define DFS_FILTER_DEFAULT_PRI 1000000
#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 */
@@ -569,10 +573,13 @@ struct ath_dfs {
/* dfs_radarf - One filter for each radar pulse type */
struct dfs_filtertype *dfs_radarf[DFS_MAX_RADAR_TYPES];
+ struct dfs_filtertype *dfs_dc_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 */
+ /* map of dc radar durs to filter types */
+ int8_t **dfs_dc_radartable;
#ifndef ATH_DFS_RADAR_DETECTION_ONLY
struct dfs_nolelem *dfs_nol; /* Non occupancy list for radar */
int dfs_nol_count; /* How many items? */
diff --git a/CORE/SERVICES/DFS/src/dfs.c b/CORE/SERVICES/DFS/src/dfs.c
index 313671fc2d05..8677cc29ee21 100644
--- a/CORE/SERVICES/DFS/src/dfs.c
+++ b/CORE/SERVICES/DFS/src/dfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2002-2014, 2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -344,7 +344,7 @@ dfs_attach(struct ieee80211com *ic)
dfs->pulses->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK;
- /* Allocate memory for radar filters */
+ /* 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) {
@@ -357,7 +357,23 @@ dfs_attach(struct ieee80211com *ic)
goto bad1;
}
}
- /* Allocate memory for radar table */
+
+ /* Allocate memory for dc radar filters */
+ for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
+ dfs->dfs_dc_radarf[n] =
+ (struct dfs_filtertype *)OS_MALLOC(NULL,
+ sizeof(struct dfs_filtertype), GFP_ATOMIC);
+ if (!(dfs->dfs_dc_radarf[n])) {
+ DFS_PRINTK("%s: cannot allocate memory for dc radar filter types\n",
+ __func__);
+ goto bad1;
+ }
+ vos_mem_zero(dfs->dfs_dc_radarf[n], sizeof(struct dfs_filtertype));
+ if (0 != dfs_alloc_mem_filter(dfs->dfs_radarf[n]))
+ goto bad4;
+ }
+
+ /* 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",
@@ -374,6 +390,26 @@ dfs_attach(struct ieee80211com *ic)
}
}
+ /* Allocate memory for dc radar table */
+ dfs->dfs_dc_radartable = (int8_t **)OS_MALLOC(NULL,
+ MAX_DFS_RADAR_TYPE * sizeof(int8_t *),
+ GFP_ATOMIC);
+ if (!dfs->dfs_dc_radartable) {
+ DFS_PRINTK("%s: cannot allocate memory for radar table\n",
+ __func__);
+ goto bad2;
+ }
+ for (n = 0; n < MAX_DFS_RADAR_TYPE; n++) {
+ dfs->dfs_dc_radartable[n] = OS_MALLOC(NULL,
+ DFS_MAX_RADAR_OVERLAP * sizeof(int8_t),
+ GFP_ATOMIC);
+ if (!(dfs->dfs_dc_radartable[n])) {
+ DFS_PRINTK("%s: cannot allocate memory for dc radar table entry\n",
+ __func__);
+ goto bad3;
+ }
+ }
+
if (usenol == 0)
DFS_PRINTK("%s: NOL disabled\n", __func__);
else if (usenol == 2)
@@ -411,9 +447,19 @@ dfs_attach(struct ieee80211com *ic)
dfs->ath_dfs_nol_timeout = DFS_NOL_TIMEOUT_S;
return 0;
+bad3:
+ OS_FREE(dfs->dfs_dc_radartable);
+ dfs->dfs_dc_radartable = NULL;
bad2:
OS_FREE(dfs->dfs_radartable);
dfs->dfs_radartable = NULL;
+bad4:
+ for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
+ if (!(dfs->dfs_dc_radarf[n])) {
+ OS_FREE(dfs->dfs_dc_radarf[n]);
+ dfs->dfs_dc_radarf[n] = NULL;
+ }
+ }
bad1:
for (n=0; n<DFS_MAX_RADAR_TYPES; n++) {
if (dfs->dfs_radarf[n] != NULL) {
@@ -519,6 +565,14 @@ dfs_detach(struct ieee80211com *ic)
dfs->dfs_radarf[n] = NULL;
}
}
+ for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
+ if (!(dfs->dfs_dc_radarf[n])) {
+ dfs_free_filter(dfs->dfs_dc_radarf[n]);
+ OS_FREE(dfs->dfs_dc_radarf[n]);
+ dfs->dfs_dc_radarf[n] = NULL;
+ }
+ }
+
if (dfs->dfs_radartable != NULL) {
@@ -535,6 +589,17 @@ dfs_detach(struct ieee80211com *ic)
#endif
}
+ if (!(dfs->dfs_dc_radartable)) {
+ for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) {
+ if (!(dfs->dfs_dc_radartable[n])) {
+ OS_FREE(dfs->dfs_dc_radartable[n]);
+ dfs->dfs_dc_radartable[n] = NULL;
+ }
+ }
+ OS_FREE(dfs->dfs_dc_radartable);
+ dfs->dfs_dc_radartable = NULL;
+ }
+
if (dfs->dfs_b5radars != NULL) {
OS_FREE(dfs->dfs_b5radars);
dfs->dfs_b5radars=NULL;
diff --git a/CORE/SERVICES/DFS/src/dfs_debug.c b/CORE/SERVICES/DFS/src/dfs_debug.c
index d948f1598bfc..efe88520852a 100644
--- a/CORE/SERVICES/DFS/src/dfs_debug.c
+++ b/CORE/SERVICES/DFS/src/dfs_debug.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2002-2013, 2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -109,7 +109,8 @@ dfs_print_filters(struct ath_dfs *dfs)
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);
+ 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,
@@ -117,6 +118,26 @@ dfs_print_filters(struct ath_dfs *dfs)
}
}
}
+
+ for (i=0; i < DFS_MAX_RADAR_TYPES; i++) {
+ if (dfs->dfs_dc_radarf[i])
+ continue;
+
+ ft = dfs->dfs_dc_radarf[i];
+ if ((ft->ft_numfilters > DFS_MAX_NUM_RADAR_FILTERS) ||
+ (!ft->ft_numfilters))
+ continue;
+ DFS_PRINTK("===========DC ft->ft_numfilters=%u===========\n",
+ ft->ft_numfilters);
+ for (j = 0; j < ft->ft_numfilters; j++) {
+ rf = ft->ft_filters[j];
+ DFS_PRINTK("DC 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)
diff --git a/CORE/SERVICES/DFS/src/dfs_init.c b/CORE/SERVICES/DFS/src/dfs_init.c
index 59e4bbf11400..b85b5a8a29a4 100644
--- a/CORE/SERVICES/DFS/src/dfs_init.c
+++ b/CORE/SERVICES/DFS/src/dfs_init.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2002-2014, 2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -115,6 +115,22 @@ void dfs_reset_alldelaylines(struct ath_dfs *dfs)
}
}
}
+ for (i = 0; i < DFS_MAX_RADAR_TYPES; i++) {
+ if (dfs->dfs_dc_radarf[i] == NULL)
+ continue;
+
+ ft = dfs->dfs_dc_radarf[i];
+ for (j = 0; j < ft->ft_numfilters; j++) {
+ rf = ft->ft_filters[j];
+ dl = &(rf->rf_dl);
+ if (dl == NULL)
+ continue;
+
+ 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;
@@ -230,6 +246,12 @@ int dfs_init_radar_filters(struct ieee80211com *ic,
for (i=0;i<DFS_MAX_RADAR_OVERLAP; i++)
(dfs->dfs_radartable[n])[i] = -1;
}
+ /* Clear dc filter type table */
+ for (n = 0; n < 256; n++) {
+ for (i = 0;i < DFS_MAX_RADAR_OVERLAP; i++)
+ (dfs->dfs_dc_radartable[n])[i] = -1;
+ }
+
/* Now, initialize the radar filters */
for (p=0; p<numradars; p++) {
ft = NULL;
@@ -319,8 +341,109 @@ int dfs_init_radar_filters(struct ieee80211com *ic,
}
+ /* Initialize dc 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_dc_radarf[n]->ft_filterdur) &&
+ (dfs_radars[p].rp_numpulses ==
+ dfs->dfs_dc_radarf[n]->ft_numpulses) &&
+ (dfs_radars[p].rp_mindur == dfs->dfs_dc_radarf[n]->ft_mindur) &&
+ (dfs_radars[p].rp_maxdur == dfs->dfs_dc_radarf[n]->ft_maxdur)) {
+
+ ft = dfs->dfs_dc_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",
+ __func__);
+ goto bad4;
+ }
+ ft = dfs->dfs_dc_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 = DFS_FILTER_DEFAULT_PRI;
+
+ 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_dc_radartable[i])[tableindex] == -1)
+ stop = 1;
+ else
+ tableindex++;
+ }
+ if (stop) {
+ (dfs->dfs_dc_radartable[i])[tableindex] =
+ (int8_t) (dfs->dfs_rinfo.rn_numradars);
+ } else {
+ DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
+ "%s: Too many overlapping dc radar filters",
+ __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;
+ /* for pulseid 5, increase threshould by 1 */
+ if (dfs_radars[p].rp_pulseid == 5)
+ rf->rf_threshold = dfs_radars[p].rp_threshold + 1;
+ else
+ rf->rf_threshold = dfs_radars[p].rp_threshold;
+
+ rf->rf_filterlen = rf->rf_maxpri * rf->rf_numpulses;
+
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]: minprf = %d maxprf = %d pulsevar = %d thresh=%d",
+ __func__, __LINE__, dfs_radars[p].rp_pulsefreq,
+ dfs_radars[p].rp_max_pulsefreq, dfs_radars[p].rp_pulsevar,
+ rf->rf_threshold);
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]:minpri = %d maxpri = %d filterlen = %d filterID = %d",
+ __func__, __LINE__, rf->rf_minpri, rf->rf_maxpri,
+ rf->rf_filterlen, rf->rf_pulseid);
+
+ }
#ifdef DFS_DEBUG
- dfs_print_filters(ic);
+ dfs_print_filters(dfs);
#endif
dfs->dfs_rinfo.rn_numbin5radars = numb5radars;
if (dfs->dfs_b5radars != NULL)
diff --git a/CORE/SERVICES/DFS/src/dfs_process_radarevent.c b/CORE/SERVICES/DFS/src/dfs_process_radarevent.c
index 156a229dd0cd..45176f5706d0 100644
--- a/CORE/SERVICES/DFS/src/dfs_process_radarevent.c
+++ b/CORE/SERVICES/DFS/src/dfs_process_radarevent.c
@@ -108,6 +108,175 @@ dfs_process_pulse_dur(struct ath_dfs *dfs, u_int8_t re_dur)
}
/*
+ * dfs_process_dc_pulse: process dc pulses
+ * @dfs: pointer to dfs structure
+ * @event: dfs event
+ * @retval: current found status
+ * @this_ts: event's ts
+ *
+ * Return: None
+ */
+static void dfs_process_dc_pulse(struct ath_dfs *dfs, struct dfs_event *event,
+ int *retval, int this_ts)
+{
+ struct dfs_event re;
+ struct dfs_state *rs=NULL;
+ struct dfs_filtertype *ft;
+ struct dfs_filter *rf;
+ int found, p, empty;
+ int min_pri, miss_pulse_number = 0, deviation = 0;
+ u_int32_t tabledepth = 0;
+ u_int64_t deltaT;
+ int ext_chan_event_flag = 0;
+ int i;
+
+ OS_MEMCPY(&re, event, sizeof(*event));
+ if (re.re_chanindex < DFS_NUM_RADAR_STATES)
+ rs = &dfs->dfs_radar[re.re_chanindex];
+
+ while ((tabledepth < DFS_MAX_RADAR_OVERLAP) &&
+ ((dfs->dfs_dc_radartable[re.re_dur])[tabledepth] != -1) &&
+ (!*retval)) {
+ ft = dfs->dfs_dc_radarf[((dfs->dfs_dc_radartable
+ [re.re_dur])[tabledepth])];
+
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ FL("** RD (%d): ts %x dur %u rssi %u"),
+ rs->rs_chan.ic_freq,
+ re.re_ts, re.re_dur, re.re_rssi);
+
+ deltaT = this_ts - ft->ft_last_ts;
+ if (re.re_rssi < ft->ft_rssithresh && re.re_dur > 4) {
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ FL("Rejecting on rssi rssi=%u thresh=%u depth=%d"),
+ re.re_rssi, ft->ft_rssithresh,
+ tabledepth);
+ tabledepth++;
+ dfs_reset_filter_delaylines(ft);
+ ATH_DFSQ_LOCK(dfs);
+ empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
+ ATH_DFSQ_UNLOCK(dfs);
+ continue;
+ }
+ 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. */
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ FL("Rejecting on pri pri=%lld minpri=%u depth=%d"),
+ (unsigned long long)deltaT,
+ ft->ft_minpri, tabledepth);
+ dfs_reset_filter_delaylines(ft);
+ 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)) {
+ 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. */
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ FL("filterID=%d :: Rejected and cleared individual filter min PRI deltaT=%lld rf->rf_minpri=%u"),
+ rf->rf_pulseid,
+ (unsigned long long)deltaT, rf->rf_minpri);
+ dfs_reset_delayline(&rf->rf_dl);
+ rf->rf_dl.dl_last_ts = this_ts;
+ continue;
+ }
+
+ if (rf->rf_ignore_pri_window > 0) {
+ if (deltaT < rf->rf_minpri) {
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ FL("filterID=%d :: Rejected and cleared on individual filter max PRI deltaT=%lld rf->rf_minpri=%u"),
+ rf->rf_pulseid,
+ (unsigned long long)deltaT, rf->rf_minpri);
+ dfs_reset_delayline(&rf->rf_dl);
+ rf->rf_dl.dl_last_ts = this_ts;
+ continue;
+ }
+ } else {
+ if (deltaT < rf->rf_minpri) {
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ FL("filterID=%d :: Rejected and cleared on individual filter max PRI deltaT=%lld rf->rf_minpri=%u"),
+ rf->rf_pulseid,
+ (unsigned long long)deltaT, rf->rf_minpri);
+ dfs_reset_delayline(&rf->rf_dl);
+ rf->rf_dl.dl_last_ts = this_ts;
+ continue;
+ }
+ }
+ dfs_add_pulse(dfs, rf, &re, deltaT, this_ts);
+
+ /* extra WAR */
+ if ((dfs->dfsdomain == DFS_FCC_DOMAIN &&
+ dfs->dfsdomain == DFS_MKK4_DOMAIN) &&
+ ((rf->rf_pulseid != 31) && (rf->rf_pulseid != 32))) {
+
+ min_pri = 0xffff;
+ for (i = 0; i < rf->rf_dl.dl_numelems; i++) {
+ if (rf->rf_dl.dl_elems[i].de_time < min_pri)
+ min_pri = rf->rf_dl.dl_elems[i].de_time;
+ }
+
+ for (i=0; i < rf->rf_dl.dl_numelems; i++) {
+ miss_pulse_number = vos_round_div(
+ (rf->rf_dl.dl_elems[i].de_time), min_pri);
+ deviation = __adf_os_abs(min_pri *
+ miss_pulse_number -
+ rf->rf_dl.dl_elems[i].de_time);
+ if (deviation > miss_pulse_number*3) {
+ dfs_reset_delayline(&rf->rf_dl);
+ VOS_TRACE(VOS_MODULE_ID_SAP,
+ VOS_TRACE_LEVEL_INFO,
+ FL("filterID=%d :: cleared individual deleyline min_pri =%d miss_pulse_number =%d deviation =%d"),
+ rf->rf_pulseid,
+ min_pri, miss_pulse_number, deviation);
+ }
+ }
+ }
+
+ /* 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, (uint32_t)deltaT,
+ re.re_dur);
+ else
+ found = dfs_bin_check(dfs, rf, (uint32_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;
+ } else {
+ /* if we are rejecting this, clear the queue */
+ dfs_reset_delayline(&rf->rf_dl);
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ FL("filterID= %d :: cleared individual deleyline"),
+ rf->rf_pulseid);
+ }
+ }
+ ft->ft_last_ts = this_ts;
+ *retval |= found;
+ if (found) {
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ FL(":## Radar Found minDur=%d, filterId=%d ##"),
+ ft->ft_mindur,
+ rf != NULL ? rf->rf_pulseid : -1);
+ }
+ tabledepth++;
+ }
+}
+
+/*
* Process a radar event.
*
* If a radar event is found, return 1. Otherwise, return 0.
@@ -381,9 +550,11 @@ dfs_process_radarevent(struct ath_dfs *dfs, struct ieee80211_channel *chan)
dfs->radar_log[i].dur = re.re_dur;
dfs->dfs_event_log_count++;
}
- VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]:xxxxx ts =%u re.re_dur=%u re.re_rssi =%u diff =%u pl->pl_lastelem.p_time=%llu xxxxx",__func__,__LINE__,(u_int32_t)this_ts, re.re_dur, re.re_rssi, diff_ts, (unsigned long long)pl->pl_elems[index].p_time);
-
-
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
+ "%s[%d]:xxxxx ts =%u re.re_dur=%u re.re_rssi =%u diff =%u sidx = %u flags = %x pl->pl_lastelem.p_time=%llu xxxxx",
+ __func__, __LINE__, (u_int32_t)this_ts,
+ re.re_dur, re.re_rssi, diff_ts, re.sidx, re.re_flags,
+ (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
@@ -527,7 +698,26 @@ dfs_process_radarevent(struct ath_dfs *dfs, struct ieee80211_channel *chan)
DFS_DPRINTK(dfs, ATH_DEBUG_DFS1," *** chan freq (%d): ts %llu dur %u rssi %u",
rs->rs_chan.ic_freq, (unsigned long long)this_ts, re.re_dur, re.re_rssi);
- while ((tabledepth < DFS_MAX_RADAR_OVERLAP) &&
+
+ /*
+ * DC pulses processing will be done in this seperate block since some
+ * device may generate pulse which may cause false detection.
+ * This processing is similar kind as of normal pulse processing with
+ * some exception such as:
+ * 1. Clear the queue if pulse doesn't belong to it
+ * 2. Remove chan load optimization(can cause some valid pulses to drop)
+ * 3. Drop pulses on basis of mean deviation for some filters
+ */
+ if (((re.sidx == 0) && DFS_EVENT_NOTCHIRP(&re)) &&
+ ((dfs->dfsdomain == DFS_FCC_DOMAIN) ||
+ (dfs->dfsdomain == DFS_MKK4_DOMAIN) ||
+ (dfs->dfsdomain == DFS_ETSI_DOMAIN && re.re_dur < 18))) {
+ dfs_process_dc_pulse(dfs, &re, &retval, this_ts);
+ }
+
+ /* Pulse not at DC position */
+ else {
+ 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])];
@@ -631,6 +821,7 @@ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "%s[%d]:filterID= %d :: Rejec
rf != NULL ? rf->rf_pulseid : -1);
}
tabledepth++;
+ }
}
ATH_DFSQ_LOCK(dfs);
empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
diff --git a/CORE/SERVICES/HIF/PCIe/hif_pci.c b/CORE/SERVICES/HIF/PCIe/hif_pci.c
index 26c73b5928f9..498f8d6ef69f 100644
--- a/CORE/SERVICES/HIF/PCIe/hif_pci.c
+++ b/CORE/SERVICES/HIF/PCIe/hif_pci.c
@@ -97,9 +97,6 @@ HIF_ACCESS_LOG pcie_access_log[PCIE_ACCESS_LOG_NUM];
static void HIFTargetDumpAccessLog(void);
#endif
-/* Forward references */
-static int hif_post_recv_buffers_for_pipe(struct HIF_CE_pipe_info *pipe_info);
-
/*
* Host software's Copy Engine configuration.
* This table is derived from the CE_PCI TABLE, above.
@@ -1590,6 +1587,7 @@ hif_post_recv_buffers_for_pipe(struct HIF_CE_pipe_info *pipe_info)
("%s CE_recv_buf_enqueue error [%d] needed %d\n",
__func__, pipe_info->pipe_num,
atomic_read(&pipe_info->recv_bufs_needed)));
+ adf_nbuf_unmap_single(scn->adf_dev, nbuf, ADF_OS_DMA_FROM_DEVICE);
atomic_inc(&pipe_info->recv_bufs_needed);
adf_nbuf_free(nbuf);
adf_os_spin_lock_bh(&pipe_info->recv_bufs_needed_lock);
diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c
index 2b9131afd8eb..c2b093cdbdb9 100644
--- a/CORE/SERVICES/HIF/PCIe/if_pci.c
+++ b/CORE/SERVICES/HIF/PCIe/if_pci.c
@@ -798,12 +798,12 @@ wlan_tasklet(unsigned long data)
* Enable the interrupt only when there is no pending frames in
* any of the Copy Engine pipes.
*/
- adf_os_atomic_set(&sc->ce_suspend, 1);
#ifdef CONFIG_SLUB_DEBUG_ON
schedule_work(&reschedule_tasklet_work);
#else
tasklet_schedule(&sc->intr_tq);
#endif
+ adf_os_atomic_set(&sc->ce_suspend, 1);
return;
}
irq_handled:
diff --git a/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c b/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c
index a177243a8f6d..07f5de1bf91e 100644
--- a/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c
+++ b/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c
@@ -1504,39 +1504,6 @@ HIFSetMboxSleep(HIF_DEVICE *device, bool sleep, bool wait, bool cache)
}
#endif
-/* handle HTC startup via thread*/
-static int startup_task(void *param)
-{
- HIF_DEVICE *device;
-
- device = (HIF_DEVICE *)param;
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call HTC from startup_task\n"));
- /* start up inform DRV layer */
- if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) != A_OK) {
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n"));
- }
- return 0;
-}
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) && defined(CONFIG_PM)
-static int enable_task(void *param)
-{
- HIF_DEVICE *device;
- device = (HIF_DEVICE *)param;
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call from resume_task\n"));
-
- /* start up inform DRV layer */
- if (device &&
- device->claimedContext &&
- osdrvCallbacks.devicePowerChangeHandler &&
- osdrvCallbacks.devicePowerChangeHandler(device->claimedContext, HIF_DEVICE_POWER_UP) != A_OK)
- {
- AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n"));
- }
-
- return 0;
-}
-#endif
static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id)
{
int i;
@@ -1995,9 +1962,6 @@ static A_STATUS hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func)
static A_STATUS hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func)
{
- struct task_struct* pTask;
- const char *taskName = NULL;
- int (*taskFunc)(void *) = NULL;
int ret = A_OK;
ENTER("sdio_func 0x%p", func);
@@ -2117,23 +2081,28 @@ static A_STATUS hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func)
}
if (!device->claimedContext) {
- taskFunc = startup_task;
- taskName = "AR6K startup";
- ret = A_OK;
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
+ ("AR6k: call deviceInsertedHandler\n"));
+ ret = osdrvCallbacks.deviceInsertedHandler(
+ osdrvCallbacks.context,device);
+ /* start up inform DRV layer */
+ if (ret != A_OK)
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
+ ("AR6k: Device rejected error:%d \n", ret));
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) && defined(CONFIG_PM)
} else {
- taskFunc = enable_task;
- taskName = "AR6K enable";
- ret = A_PENDING;
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
+ ("AR6k: call devicePwrChangeApi\n"));
+ /* start up inform DRV layer */
+ if (device &&
+ device->claimedContext &&
+ osdrvCallbacks.devicePowerChangeHandler &&
+ ((ret = osdrvCallbacks.devicePowerChangeHandler(
+ device->claimedContext, HIF_DEVICE_POWER_UP)) != A_OK))
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
+ ("AR6k: Device rejected error:%d \n", ret));
#endif /* CONFIG_PM */
}
- /* create resume thread */
- pTask = kthread_create(taskFunc, (void *)device, taskName);
- if (IS_ERR(pTask)) {
- AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create enabel task\n", __FUNCTION__));
- return A_ERROR;
- }
- wake_up_process(pTask);
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifEnableFunc\n"));
/* task will call the enable func, indicate pending */
@@ -2787,5 +2756,46 @@ static int hif_sdio_device_resume(struct device *dev)
{
return hifDeviceResume(dev);
}
+
+/**
+ * hif_reset_target() - Reset target device
+ * @hif_device: pointer to hif_device structure
+ *
+ * Reset the target by invoking power off and power on
+ * sequence to bring back target into active state.
+ * This API shall be called only when driver load/unload
+ * is in progress.
+ *
+ * Return: 0 on success, error for failure case.
+ */
+int hif_reset_target(HIF_DEVICE *hif_device)
+{
+ int ret;
+
+ if (!hif_device || !hif_device->func|| !hif_device->func->card) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("AR6000: %s invalid HIF DEVICE \n", __func__));
+ return -ENODEV;
+ }
+ /* Disable sdio func->pull down WLAN_EN-->pull down DAT_2 line */
+ ret = mmc_power_save_host(hif_device->func->card->host);
+ if(ret) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("AR6000: %s Failed to save mmc Power host %d\n",
+ __func__, ret));
+ goto done;
+ }
+
+ /* pull up DAT_2 line->pull up WLAN_EN-->Enable sdio func */
+ ret = mmc_power_restore_host(hif_device->func->card->host);
+ if(ret) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("AR6000: %s Failed to restore mmc Power host %d\n",
+ __func__, ret));
+ }
+
+done:
+ return ret;
+}
#endif
#endif
diff --git a/CORE/SERVICES/HTC/htc_recv.c b/CORE/SERVICES/HTC/htc_recv.c
index d15ddca39a4a..e4c1ffcdb6d5 100644
--- a/CORE/SERVICES/HTC/htc_recv.c
+++ b/CORE/SERVICES/HTC/htc_recv.c
@@ -582,6 +582,11 @@ A_STATUS HTCWaitRecvCtrlMessage(HTC_TARGET *target)
/* Wait for BMI request/response transaction to complete */
if(!adf_os_wait_for_completion_timeout(&target->CtrlResponseValid,
adf_os_msecs_to_ticks(HTC_CONTROL_RX_TIMEOUT))) {
+ /* Reset the target by invoking power off and power on sequence to
+ * the card to bring back into active state.
+ */
+ if(hif_reset_target(target->hif_dev))
+ VOS_BUG(0);
return A_ERROR;
}
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index b32eb7d8d83f..3930ec242e8a 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -7255,6 +7255,9 @@ static void wma_state_info_dump(char **buf_ptr, uint16_t *size)
len += vos_scnprintf(buf + len, *size - len,
"\n wow_ipv6_mcast_na_stats %d",
wma_handle->wow_ipv6_mcast_na_stats);
+ len += vos_scnprintf(buf + len, *size - len,
+ "\n wow_oem_response_wake_up_count %d",
+ wma_handle->wow_oem_response_wake_up_count);
*size -= len;
*buf_ptr += len;
@@ -20293,6 +20296,8 @@ static const u8 *wma_wow_wake_reason_str(A_INT32 wake_reason, tp_wma_handle wma)
return "REASSOC_RES_RECV";
case WOW_REASON_ACTION_FRAME_RECV:
return "ACTION_FRAME_RECV";
+ case WOW_REASON_OEM_RESPONSE_EVENT:
+ return "WOW_REASON_OEM_RESPONSE_EVENT";
}
return "unknown";
}
@@ -20803,7 +20808,7 @@ static void wma_extscan_wow_event_callback(void *handle, void *event,
*/
static void wma_wow_wake_up_stats_display(tp_wma_handle wma)
{
- WMA_LOGA("uc %d bc %d v4_mc %d v6_mc %d ra %d ns %d na %d pno_match %d pno_complete %d gscan %d low_rssi %d rssi_breach %d icmp %d icmpv6 %d",
+ WMA_LOGA("uc %d bc %d v4_mc %d v6_mc %d ra %d ns %d na %d pno_match %d pno_complete %d gscan %d low_rssi %d rssi_breach %d icmp %d icmpv6 %d oem %d",
wma->wow_ucast_wake_up_count,
wma->wow_bcast_wake_up_count,
wma->wow_ipv4_mcast_wake_up_count,
@@ -20817,7 +20822,8 @@ static void wma_wow_wake_up_stats_display(tp_wma_handle wma)
wma->wow_low_rssi_wake_up_count,
wma->wow_rssi_breach_wake_up_count,
wma->wow_icmpv4_count,
- wma->wow_icmpv6_uc_bc_count);
+ wma->wow_icmpv6_uc_bc_count,
+ wma->wow_oem_response_wake_up_count);
return;
}
@@ -20934,6 +20940,10 @@ static void wma_wow_wake_up_stats(tp_wma_handle wma, uint8_t *data,
wma->wow_rssi_breach_wake_up_count++;
break;
+ case WOW_REASON_OEM_RESPONSE_EVENT:
+ wma->wow_oem_response_wake_up_count++;
+ break;
+
default:
WMA_LOGE("Unknown wake up reason");
break;
@@ -21689,6 +21699,26 @@ static int wma_wow_wakeup_host_event(void *handle, u_int8_t *event,
}
break;
#endif
+
+ case WOW_REASON_OEM_RESPONSE_EVENT:
+ wma_wow_wake_up_stats(wma, NULL, 0,
+ WOW_REASON_OEM_RESPONSE_EVENT);
+ if (param_buf->wow_packet_buffer) {
+ WMA_LOGD(FL("Host woken up by OEM Response event"));
+ wow_buf_pkt_len =
+ *(uint32_t *)param_buf->wow_packet_buffer;
+ vos_trace_hex_dump(VOS_MODULE_ID_WDA,
+ VOS_TRACE_LEVEL_DEBUG,
+ param_buf->wow_packet_buffer,
+ wow_buf_pkt_len);
+ wma_oem_data_response_handler(handle,
+ (uint8_t*)(param_buf->wow_packet_buffer),
+ wow_buf_pkt_len);
+ } else {
+ WMA_LOGD(FL("No wow_packet_buffer for OEM response"));
+ }
+ break;
+
default:
break;
}
@@ -21778,6 +21808,8 @@ static const u8 *wma_wow_wakeup_event_str(WOW_WAKE_EVENT_TYPE event)
return "WOW_NAN_DATA_EVENT";
case WOW_TDLS_CONN_TRACKER_EVENT:
return "WOW_TDLS_CONN_TRACKER_EVENT";
+ case WOW_OEM_RESPONSE_EVENT:
+ return "WOW_OEM_RESPONSE_EVENT";
default:
return "UNSPECIFIED_EVENT";
}
@@ -22995,6 +23027,8 @@ static VOS_STATUS wma_feed_wow_config_to_fw(tp_wma_handle wma,
wma_add_wow_wakeup_event(wma, WOW_TDLS_CONN_TRACKER_EVENT, TRUE);
#endif
+ wma_add_wow_wakeup_event(wma, WOW_OEM_RESPONSE_EVENT, TRUE);
+
/* Enable wow wakeup events in FW */
ret = wma_send_wakeup_mask(wma, TRUE);
if (ret) {
@@ -29806,7 +29840,7 @@ static VOS_STATUS wma_set_beacon_filter(tp_wma_handle wma,
ie_map = (A_UINT32 *)(buf + WMI_TLV_HDR_SIZE);
for (i = 0; i < BCN_FLT_MAX_ELEMS_IE_LIST; i++) {
ie_map[i] = filter_params->ie_map[i];
- WMA_LOGA("beacon filter ie map = %u", ie_map[i]);
+ WMA_LOGD("beacon filter ie map = %u", ie_map[i]);
}
vos_status = wmi_unified_cmd_send(wma->wmi_handle, wmi_buf, len,
@@ -29817,7 +29851,7 @@ static VOS_STATUS wma_set_beacon_filter(tp_wma_handle wma,
wmi_buf_free(wmi_buf);
return VOS_STATUS_E_FAILURE;
}
- WMA_LOGA("added beacon filter = %d", vos_status);
+ WMA_LOGD("added beacon filter = %d", vos_status);
return vos_status;
}
diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h
index 07029837234a..990ecf5f4259 100644
--- a/CORE/SERVICES/WMA/wma.h
+++ b/CORE/SERVICES/WMA/wma.h
@@ -889,6 +889,7 @@ typedef struct wma_handle {
uint32_t wow_ipv6_mcast_na_stats;
uint32_t wow_icmpv4_count;
uint32_t wow_icmpv6_uc_bc_count;
+ uint32_t wow_oem_response_wake_up_count;
uint32_t wow_wakeup_enable_mask;
uint32_t wow_wakeup_disable_mask;
uint16_t max_mgmt_tx_fail_count;
diff --git a/CORE/VOSS/inc/vos_types.h b/CORE/VOSS/inc/vos_types.h
index 960226fa75ce..a9198201600a 100644
--- a/CORE/VOSS/inc/vos_types.h
+++ b/CORE/VOSS/inc/vos_types.h
@@ -58,6 +58,12 @@
// macro to return the floor of an integer division operation
#define VOS_FLOOR_DIV( _a, _b ) ( ( (_a) - ( (_a) % (_b) ) ) / (_b) )
+static inline unsigned int vos_round_div(unsigned int dividend,
+ unsigned int divisor)
+{
+ return (dividend + (divisor / 2)) / divisor;
+}
+
#define VOS_SWAP_U16(_x) \
( ( ( (_x) << 8 ) & 0xFF00 ) | ( ( (_x) >> 8 ) & 0x00FF ) )
diff --git a/CORE/VOSS/src/vos_packet.c b/CORE/VOSS/src/vos_packet.c
index 3844fbfd0975..9a8179cbdd01 100644
--- a/CORE/VOSS/src/vos_packet.c
+++ b/CORE/VOSS/src/vos_packet.c
@@ -342,10 +342,10 @@ void vos_pkt_trace_buf_dump
unsigned long local_time;
spin_lock_bh(&trace_buffer_lock);
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
"PACKET TRACE DUMP START Current Timestamp %u",
(unsigned int)vos_timer_get_system_time());
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
"ORDER : RTC TIME : EVT");
if (VOS_PKT_TRAC_MAX_TRACE_BUF > trace_buffer_order)
@@ -355,7 +355,7 @@ void vos_pkt_trace_buf_dump
local_time = (u32)(trace_buffer[slot].event_sec_time -
(sys_tz.tz_minuteswest * 60));
rtc_time_to_tm(local_time, &tm);
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
"%5d : [%02d:%02d:%02d.%06lu] : %s",
trace_buffer[slot].order,
tm.tm_hour, tm.tm_min, tm.tm_sec,
@@ -371,7 +371,7 @@ void vos_pkt_trace_buf_dump
local_time = (u32)(trace_buffer[slot].event_msec_time -
(sys_tz.tz_minuteswest * 60));
rtc_time_to_tm(local_time, &tm);
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
"%5d : [%02d:%02d:%02d.%06lu] : %s",
trace_buffer[slot].order,
tm.tm_hour, tm.tm_min, tm.tm_sec,
@@ -380,7 +380,7 @@ void vos_pkt_trace_buf_dump
}
}
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
"PACKET TRACE DUMP END");
spin_unlock_bh(&trace_buffer_lock);
diff --git a/CORE/VOSS/src/vos_sched.c b/CORE/VOSS/src/vos_sched.c
index 03ce10e62e7e..bfe5b3a1f4fe 100644
--- a/CORE/VOSS/src/vos_sched.c
+++ b/CORE/VOSS/src/vos_sched.c
@@ -76,7 +76,8 @@
#define MAX_SSR_PROTECT_LOG (16)
/* Timer value for detecting thread stuck issues */
-#define THREAD_STUCK_TIMER_VAL 5000 /* 5 seconds */
+#define THREAD_STUCK_TIMER_VAL 10000 /* 10 seconds */
+#define THREAD_STUCK_THRESHOLD 1
static atomic_t ssr_protect_entry_count;
static atomic_t load_unload_protect_count;
@@ -988,12 +989,11 @@ static void vos_wd_detect_thread_stuck(void)
spin_lock_irqsave(&gpVosWatchdogContext->thread_stuck_lock, flags);
- if (gpVosWatchdogContext->mc_thread_stuck_count) {
+ if (gpVosWatchdogContext->mc_thread_stuck_count ==
+ THREAD_STUCK_THRESHOLD) {
spin_unlock_irqrestore(&gpVosWatchdogContext->thread_stuck_lock,
flags);
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- "%s: Thread Stuck!!! MC Count %d", __func__,
- gpVosWatchdogContext->mc_thread_stuck_count);
+ hddLog(LOGE, FL("MC Thread Stuck!!!"));
vos_dump_stack(gpVosSchedContext->McThread);
vos_flush_logs(WLAN_LOG_TYPE_FATAL,
@@ -1004,11 +1004,18 @@ static void vos_wd_detect_thread_stuck(void)
flags);
}
+ if (!gpVosWatchdogContext->mc_thread_stuck_count) {
+ spin_unlock_irqrestore(&gpVosWatchdogContext->thread_stuck_lock,
+ flags);
+ vos_probe_threads();
+ spin_lock_irqsave(&gpVosWatchdogContext->thread_stuck_lock,
+ flags);
+ }
+
/* Increment the thread stuck count for all threads */
gpVosWatchdogContext->mc_thread_stuck_count++;
spin_unlock_irqrestore(&gpVosWatchdogContext->thread_stuck_lock, flags);
- vos_probe_threads();
/* Restart the timer */
if (VOS_STATUS_SUCCESS !=