Merge "Release 5.2.0.35M" into wlan-cld3.driver.lnx.2.0-dev
diff --git a/core/bmi/src/ol_fw_common.c b/core/bmi/src/ol_fw_common.c
index f79e450..848d8b4 100644
--- a/core/bmi/src/ol_fw_common.c
+++ b/core/bmi/src/ol_fw_common.c
@@ -96,6 +96,15 @@
return status;
}
+#if defined(WLAN_FEATURE_TSF_PLUS)
+#define SDIO_HI_ACS_FLAGS (HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET | \
+ HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE)
+#else
+#define SDIO_HI_ACS_FLAGS (HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET | \
+ HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET | \
+ HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE)
+#endif
+
/*Setting SDIO block size, mbox ISR yield limit for SDIO based HIF*/
static
QDF_STATUS ol_sdio_extra_initialization(struct ol_context *ol_ctx)
@@ -163,9 +172,7 @@
goto exit;
}
- param |= (HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET|
- HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET|
- HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE);
+ param |= SDIO_HI_ACS_FLAGS;
bmi_write_memory(hif_hia_item_address(target_type,
offsetof(struct host_interest_s,
diff --git a/core/dp/htt/htt_t2h.c b/core/dp/htt/htt_t2h.c
index fdd4baa..5fe1bc2 100644
--- a/core/dp/htt/htt_t2h.c
+++ b/core/dp/htt/htt_t2h.c
@@ -681,7 +681,7 @@
}
ol_tx_completion_handler(pdev->txrx_pdev, num_msdus,
- status, msg_word + 1);
+ status, msg_word);
HTT_TX_SCHED(pdev);
break;
}
@@ -905,7 +905,7 @@
}
}
ol_tx_completion_handler(pdev->txrx_pdev, num_msdus,
- status, msg_word + 1);
+ status, msg_word);
break;
}
diff --git a/core/dp/ol/inc/ol_txrx_api.h b/core/dp/ol/inc/ol_txrx_api.h
index b0d56ee..6182105 100644
--- a/core/dp/ol/inc/ol_txrx_api.h
+++ b/core/dp/ol/inc/ol_txrx_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014,2016-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -66,4 +66,28 @@
tp_ol_packetdump_cb ol_rx_packetdump_cb);
void ol_deregister_packetdump_callback(void);
+#ifdef WLAN_FEATURE_TSF_PLUS
+typedef int (*tp_ol_timestamp_cb)(qdf_nbuf_t netbuf, uint64_t target_time);
+
+/**
+ * ol_register_timestamp_callback() - set callbacks for timestamp tx msdu.
+ * @ol_tx_timestamp_cb: callback function for time stamp tx msdu
+ *
+ * This function register timestamp callback, the callback will
+ * be called when tx a msdu
+ *
+ * Return: nothing
+ */
+void ol_register_timestamp_callback(tp_ol_timestamp_cb ol_tx_timestamp_cb);
+
+/**
+ * ol_deregister_timestamp_callback() - reset callbacks for timestamp
+ * tx msdu to NULL.
+ *
+ * This function reset the timestamp callbacks for tx
+ *
+ * Return: nothing
+ */
+void ol_deregister_timestamp_callback(void);
+#endif
#endif /* _OL_TXRX_API__H_ */
diff --git a/core/dp/ol/inc/ol_txrx_htt_api.h b/core/dp/ol/inc/ol_txrx_htt_api.h
index c5faf59..3d22f1b 100644
--- a/core/dp/ol/inc/ol_txrx_htt_api.h
+++ b/core/dp/ol/inc/ol_txrx_htt_api.h
@@ -150,14 +150,12 @@
* @param num_msdus - how many MSDUs are referenced by the tx completion
* message
* @param status - whether transmission was successful
- * @param tx_msdu_id_iterator - abstract method of finding the IDs for the
- * individual MSDUs referenced by the tx completion message, via the
- * htt_tx_compl_desc_id API function
+ * @param msg_word - the tx completion message
*/
void
ol_tx_completion_handler(ol_txrx_pdev_handle pdev,
int num_msdus,
- enum htt_tx_status status, void *tx_msdu_id_iterator);
+ enum htt_tx_status status, void *msg_word);
void ol_tx_credit_completion_handler(ol_txrx_pdev_handle pdev, int credits);
diff --git a/core/dp/txrx/ol_rx.c b/core/dp/txrx/ol_rx.c
index 41b0b9c..b4d51da 100644
--- a/core/dp/txrx/ol_rx.c
+++ b/core/dp/txrx/ol_rx.c
@@ -1135,6 +1135,25 @@
return FILTER_STATUS_REJECT;
}
+#ifdef WLAN_FEATURE_TSF_PLUS
+static inline void ol_rx_timestamp(void *rx_desc, qdf_nbuf_t msdu)
+{
+ struct htt_rx_ppdu_desc_t *rx_ppdu_desc;
+
+ if (!rx_desc || !msdu)
+ return;
+
+ rx_ppdu_desc = (struct htt_rx_ppdu_desc_t *)((uint8_t *)(rx_desc) -
+ HTT_RX_IND_HL_BYTES + HTT_RX_IND_HDR_PREFIX_BYTES);
+ msdu->tstamp = ns_to_ktime((u_int64_t)rx_ppdu_desc->tsf32 *
+ NSEC_PER_USEC);
+}
+#else
+static inline void ol_rx_timestamp(void *rx_desc, qdf_nbuf_t msdu)
+{
+}
+#endif
+
void
ol_rx_deliver(struct ol_txrx_vdev_t *vdev,
struct ol_txrx_peer_t *peer, unsigned int tid,
@@ -1315,6 +1334,8 @@
OL_RX_ERR_STATISTICS_1(pdev, vdev, peer, rx_desc,
OL_RX_ERR_NONE);
TXRX_STATS_MSDU_INCR(vdev->pdev, rx.delivered, msdu);
+
+ ol_rx_timestamp(rx_desc, msdu);
OL_TXRX_LIST_APPEND(deliver_list_head,
deliver_list_tail, msdu);
}
diff --git a/core/dp/txrx/ol_tx_send.c b/core/dp/txrx/ol_tx_send.c
index 8b3c8c8..7664b8e 100644
--- a/core/dp/txrx/ol_tx_send.c
+++ b/core/dp/txrx/ol_tx_send.c
@@ -555,6 +555,65 @@
ol_tx_flow_ct_unpause_os_q(pdev);
}
+#ifdef WLAN_FEATURE_TSF_PLUS
+static inline struct htt_tx_compl_ind_append_tx_tstamp *ol_tx_get_txtstamps(
+ u_int32_t *msg_word, int num_msdus)
+{
+ u_int32_t has_tx_tsf;
+ u_int32_t has_retry;
+ struct htt_tx_compl_ind_append_tx_tstamp *txtstamp_list = NULL;
+ struct htt_tx_compl_ind_append_retries *retry_list = NULL;
+ int offset_dwords;
+
+ has_tx_tsf = HTT_TX_COMPL_IND_APPEND1_GET(*msg_word);
+ if (num_msdus <= 0 || !has_tx_tsf)
+ return NULL;
+
+ offset_dwords = 1 + ((num_msdus + 1) >> 1);
+
+ has_retry = HTT_TX_COMPL_IND_APPEND_GET(*msg_word);
+ if (has_retry) {
+ int retry_index = 0;
+ int width_for_each_retry =
+ (sizeof(struct htt_tx_compl_ind_append_retries) +
+ 3) >> 2;
+
+ retry_list = (struct htt_tx_compl_ind_append_retries *)
+ (msg_word + offset_dwords);
+ while (retry_list) {
+ if (retry_list[retry_index++].flag == 0)
+ break;
+ }
+ offset_dwords += retry_index * width_for_each_retry;
+ }
+ txtstamp_list = (struct htt_tx_compl_ind_append_tx_tstamp *)
+ (msg_word + offset_dwords);
+
+ return txtstamp_list;
+}
+
+static inline void ol_tx_timestamp(ol_txrx_pdev_handle pdev,
+ qdf_nbuf_t netbuf, u_int64_t ts)
+{
+ if (!netbuf)
+ return;
+
+ if (pdev->ol_tx_timestamp_cb)
+ pdev->ol_tx_timestamp_cb(netbuf, ts);
+}
+#else
+static inline struct htt_tx_compl_ind_append_tx_tstamp *ol_tx_get_txtstamps(
+ u_int32_t *msg_word, int num_msdus)
+{
+ return NULL;
+}
+
+static inline void ol_tx_timestamp(ol_txrx_pdev_handle pdev,
+ qdf_nbuf_t netbuf, u_int64_t ts)
+{
+}
+#endif
+
/**
* WARNING: ol_tx_inspect_handler()'s bahavior is similar to that of
* ol_tx_completion_handler().
@@ -564,16 +623,18 @@
void
ol_tx_completion_handler(ol_txrx_pdev_handle pdev,
int num_msdus,
- enum htt_tx_status status, void *tx_desc_id_iterator)
+ enum htt_tx_status status, void *msg)
{
int i;
- uint16_t *desc_ids = (uint16_t *) tx_desc_id_iterator;
uint16_t tx_desc_id;
struct ol_tx_desc_t *tx_desc;
uint32_t byte_cnt = 0;
qdf_nbuf_t netbuf;
tp_ol_packetdump_cb packetdump_cb;
uint32_t is_tx_desc_freed = 0;
+ struct htt_tx_compl_ind_append_tx_tstamp *txtstamp_list = NULL;
+ u_int32_t *msg_word = (u_int32_t *)msg;
+ u_int16_t *desc_ids = (u_int16_t *)(msg_word + 1);
union ol_tx_desc_list_elem_t *lcl_freelist = NULL;
union ol_tx_desc_list_elem_t *tx_desc_last = NULL;
@@ -581,12 +642,20 @@
TAILQ_INIT(&tx_descs);
ol_tx_delay_compute(pdev, status, desc_ids, num_msdus);
+ if (status == htt_tx_status_ok)
+ txtstamp_list = ol_tx_get_txtstamps(msg_word, num_msdus);
for (i = 0; i < num_msdus; i++) {
tx_desc_id = desc_ids[i];
tx_desc = ol_tx_desc_find(pdev, tx_desc_id);
tx_desc->status = status;
netbuf = tx_desc->netbuf;
+
+ if (txtstamp_list)
+ ol_tx_timestamp(pdev, netbuf,
+ (u_int64_t)txtstamp_list->timestamp[i]
+ );
+
QDF_NBUF_UPDATE_TX_PKT_COUNT(netbuf, QDF_NBUF_TX_PKT_FREE);
if (tx_desc->pkt_type != OL_TX_FRM_TSO) {
@@ -1309,3 +1378,27 @@
pdev->ol_tx_packetdump_cb = NULL;
pdev->ol_rx_packetdump_cb = NULL;
}
+
+#ifdef WLAN_FEATURE_TSF_PLUS
+void ol_register_timestamp_callback(tp_ol_timestamp_cb ol_tx_timestamp_cb)
+{
+ ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+ if (!pdev) {
+ ol_txrx_err("%s: pdev is NULL", __func__);
+ return;
+ }
+ pdev->ol_tx_timestamp_cb = ol_tx_timestamp_cb;
+}
+
+void ol_deregister_timestamp_callback(void)
+{
+ ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+ if (!pdev) {
+ ol_txrx_err("%s: pdev is NULL", __func__);
+ return;
+ }
+ pdev->ol_tx_timestamp_cb = NULL;
+}
+#endif
diff --git a/core/dp/txrx/ol_txrx_types.h b/core/dp/txrx/ol_txrx_types.h
index 91a7c99..b9e48c6 100644
--- a/core/dp/txrx/ol_txrx_types.h
+++ b/core/dp/txrx/ol_txrx_types.h
@@ -676,6 +676,10 @@
tp_ol_packetdump_cb ol_tx_packetdump_cb;
tp_ol_packetdump_cb ol_rx_packetdump_cb;
+#ifdef WLAN_FEATURE_TSF_PLUS
+ tp_ol_timestamp_cb ol_tx_timestamp_cb;
+#endif
+
struct {
uint16_t pool_size;
uint16_t num_free;
diff --git a/core/hdd/inc/wlan_hdd_ftm.h b/core/hdd/inc/wlan_hdd_ftm.h
index 32279b0..132cd30 100644
--- a/core/hdd/inc/wlan_hdd_ftm.h
+++ b/core/hdd/inc/wlan_hdd_ftm.h
@@ -41,20 +41,6 @@
#include "qdf_types.h"
#include <wlan_ptt_sock_svc.h>
-enum wlan_hdd_ftm_state {
- WLAN_FTM_INITIALIZED,
- WLAN_FTM_STOPPED,
- WLAN_FTM_STARTED,
-};
-
-/**
- * struct wlan_hdd_ftm_status - FTM status
- * @ftm_state: The current state of the FTM process
- */
-struct wlan_hdd_ftm_status {
- enum wlan_hdd_ftm_state ftm_state;
-};
-
int hdd_update_cds_config_ftm(hdd_context_t *hdd_ctx);
void hdd_ftm_mc_process_msg(void *message);
#if defined(QCA_WIFI_FTM)
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index 322e1d4..4a1cb2b 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -1378,8 +1378,6 @@
/** Config values read from qcom_cfg.ini file */
struct hdd_config *config;
- struct wlan_hdd_ftm_status ftm;
-
/* Completion variable to indicate Mc Thread Suspended */
struct completion mc_sus_event_var;
diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c
index 8b657b7..06b6ede 100644
--- a/core/hdd/src/wlan_hdd_driver_ops.c
+++ b/core/hdd/src/wlan_hdd_driver_ops.c
@@ -239,8 +239,6 @@
if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("hif_enable failed status: %d, reinit: %d",
status, reinit);
- if (!cds_is_fw_down())
- QDF_BUG(0);
ret = qdf_status_to_os_return(status);
goto err_hif_close;
diff --git a/core/hdd/src/wlan_hdd_tsf.c b/core/hdd/src/wlan_hdd_tsf.c
index 0cd36bd..edb8a75 100644
--- a/core/hdd/src/wlan_hdd_tsf.c
+++ b/core/hdd/src/wlan_hdd_tsf.c
@@ -422,11 +422,21 @@
if (!adapter)
return;
+ /* host time is updated in IRQ context, it's always before target time,
+ * and so no need to try update last_host_time at present;
+ * since the interval of capturing TSF
+ * (WLAN_HDD_CAPTURE_TSF_INTERVAL_SEC) is long enough, host and target
+ * time are updated in pairs, and one by one, we can return here to
+ * avoid requiring spin lock, and to speed up the IRQ processing.
+ */
+ if (host_time > 0) {
+ adapter->cur_host_time = host_time;
+ return;
+ }
+
qdf_spin_lock_bh(&adapter->host_target_sync_lock);
if (target_time > 0)
adapter->cur_target_time = target_time;
- if (host_time > 0)
- adapter->cur_host_time = host_time;
sync_status = hdd_check_timestamp_status(adapter->last_target_time,
adapter->last_host_time,
@@ -494,6 +504,34 @@
return 0;
}
+static inline int hdd_uint64_plus(uint64_t x, uint64_t y, uint64_t *ret)
+{
+ if (!ret)
+ return -EINVAL;
+
+ if (x > (U64_MAX - y)) {
+ *ret = 0;
+ return -EINVAL;
+ }
+
+ *ret = x + y;
+ return 0;
+}
+
+static inline int hdd_uint64_minus(uint64_t x, uint64_t y, uint64_t *ret)
+{
+ if (!ret)
+ return -EINVAL;
+
+ if (x < y) {
+ *ret = 0;
+ return -EINVAL;
+ }
+
+ *ret = x - y;
+ return 0;
+}
+
static inline int32_t hdd_get_hosttime_from_targettime(
hdd_adapter_t *adapter, uint64_t target_time,
uint64_t *host_time)
@@ -532,6 +570,37 @@
return ret;
}
+static inline int32_t hdd_get_targettime_from_hosttime(
+ hdd_adapter_t *adapter, uint64_t host_time,
+ uint64_t *target_time)
+{
+ int32_t ret = -EINVAL;
+ bool in_cap_state;
+
+ if (!adapter || host_time == 0)
+ return ret;
+
+ in_cap_state = hdd_tsf_is_in_cap(adapter);
+ if (in_cap_state)
+ qdf_spin_lock_bh(&adapter->host_target_sync_lock);
+
+ if (host_time < adapter->last_host_time)
+ ret = hdd_uint64_minus(adapter->last_target_time,
+ (adapter->last_host_time - host_time) /
+ HOST_TO_TARGET_TIME_RATIO,
+ target_time);
+ else
+ ret = hdd_uint64_plus(adapter->last_target_time,
+ (host_time - adapter->last_host_time) /
+ HOST_TO_TARGET_TIME_RATIO,
+ target_time);
+
+ if (in_cap_state)
+ qdf_spin_unlock_bh(&adapter->host_target_sync_lock);
+
+ return ret;
+}
+
static inline uint64_t hdd_get_monotonic_host_time(void)
{
struct timespec ts;
@@ -540,6 +609,53 @@
return timespec_to_ns(&ts);
}
+static ssize_t __hdd_wlan_tsf_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ hdd_station_ctx_t *hdd_sta_ctx;
+ hdd_adapter_t *adapter;
+ ssize_t size;
+ uint64_t host_time, target_time;
+
+ struct net_device *net_dev = container_of(dev, struct net_device, dev);
+
+ adapter = (hdd_adapter_t *)(netdev_priv(net_dev));
+ if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)
+ return scnprintf(buf, PAGE_SIZE, "Invalid device\n");
+
+ if (!hdd_get_th_sync_status(adapter))
+ return scnprintf(buf, PAGE_SIZE,
+ "TSF sync is not initialized\n");
+
+ hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+ if (eConnectionState_Associated != hdd_sta_ctx->conn_info.connState)
+ return scnprintf(buf, PAGE_SIZE, "NOT connected\n");
+
+ host_time = hdd_get_monotonic_host_time();
+ if (hdd_get_targettime_from_hosttime(adapter, host_time,
+ &target_time))
+ size = scnprintf(buf, PAGE_SIZE, "Invalid timestamp\n");
+ else
+ size = scnprintf(buf, PAGE_SIZE, "%s%llu %llu %pM\n",
+ buf, target_time, host_time,
+ hdd_sta_ctx->conn_info.bssId.bytes);
+ return size;
+}
+
+static ssize_t hdd_wlan_tsf_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t ret;
+
+ cds_ssr_protect(__func__);
+ ret = __hdd_wlan_tsf_show(dev, attr, buf);
+ cds_ssr_unprotect(__func__);
+
+ return ret;
+}
+
+static DEVICE_ATTR(tsf, 0400, hdd_wlan_tsf_show, NULL);
+
static void hdd_capture_tsf_timer_expired_handler(void *arg)
{
uint32_t tsf_op_resp;
@@ -589,6 +705,7 @@
{
QDF_STATUS ret;
hdd_context_t *hddctx;
+ struct net_device *net_dev;
if (!adapter)
return HDD_TSF_OP_FAIL;
@@ -622,6 +739,9 @@
goto fail;
}
+ net_dev = adapter->dev;
+ if (net_dev)
+ device_create_file(&net_dev->dev, &dev_attr_tsf);
hdd_set_th_sync_status(adapter, true);
return HDD_TSF_OP_SUCC;
@@ -634,6 +754,7 @@
{
QDF_STATUS ret;
hdd_context_t *hddctx;
+ struct net_device *net_dev;
if (!adapter)
return HDD_TSF_OP_FAIL;
@@ -645,6 +766,13 @@
hdd_set_th_sync_status(adapter, false);
+ net_dev = adapter->dev;
+ if (net_dev) {
+ struct device *dev = &net_dev->dev;
+
+ device_remove_file(dev, &dev_attr_tsf);
+ }
+
ret = qdf_mc_timer_destroy(&adapter->host_target_sync_timer);
if (ret != QDF_STATUS_SUCCESS)
hdd_err("Failed to destroy timer, ret: %d", ret);
@@ -831,6 +959,8 @@
hdd_err("Failed to register irq handler: %d", ret);
return HDD_TSF_OP_FAIL;
}
+
+ ol_register_timestamp_callback(hdd_tx_timestamp);
return HDD_TSF_OP_SUCC;
}
@@ -839,6 +969,7 @@
{
int ret;
+ ol_deregister_timestamp_callback();
ret = cnss_common_unregister_tsf_captured_handler(
hdd_ctx->parent_dev,
(void *)hdd_ctx);
diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c
index a7bb5ca..a9a4990 100644
--- a/core/hdd/src/wlan_hdd_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_tx_rx.c
@@ -63,6 +63,7 @@
#include <cdp_txrx_handle.h>
#include "wlan_hdd_rx_monitor.h"
#include "wlan_hdd_power.h"
+#include <wlan_hdd_tsf.h>
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
/*
@@ -1253,6 +1254,7 @@
*/
qdf_net_buf_debug_release_skb(skb);
+ hdd_rx_timestamp(skb, ktime_to_us(skb->tstamp));
if (HDD_LRO_NO_RX ==
hdd_lro_rx(pHddCtx, pAdapter, skb)) {
if (hdd_napi_enabled(HDD_NAPI_ANY) &&
@@ -1267,7 +1269,6 @@
else
++pAdapter->hdd_stats.hddTxRxStats.
rxRefused[cpu_index];
-
} else {
++pAdapter->hdd_stats.hddTxRxStats.
rxDelivered[cpu_index];
diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h
index 5487dc3..60b8417 100644
--- a/core/mac/inc/sir_mac_prot_def.h
+++ b/core/mac/inc/sir_mac_prot_def.h
@@ -548,7 +548,6 @@
#define SIR_MAC_AUTH_ALGO_OFFSET 0
#define SIR_MAC_AUTH_XACT_SEQNUM_OFFSET 2
#define SIR_MAC_AUTH_STATUS_CODE_OFFSET 4
-#define SIR_MAC_AUTH_CHALLENGE_OFFSET 6
/* / Transaction sequence number definitions (used in Authentication frames) */
#define SIR_MAC_AUTH_FRAME_1 1
@@ -565,6 +564,11 @@
#define SIR_MAC_WEP_IV_LENGTH 4
#define SIR_MAC_WEP_ICV_LENGTH 4
+/* 2 bytes each for auth algo number, transaction number and status code */
+#define SIR_MAC_AUTH_FRAME_INFO_LEN 6
+/* 2 bytes for ID and length + SIR_MAC_AUTH_CHALLENGE_LENGTH */
+#define SIR_MAC_AUTH_CHALLENGE_BODY_LEN (2 + SIR_MAC_AUTH_CHALLENGE_LENGTH)
+
/* / MAX key length when ULA is used */
#define SIR_MAC_MAX_KEY_LENGTH 32
diff --git a/core/mac/src/pe/lim/lim_security_utils.h b/core/mac/src/pe/lim/lim_security_utils.h
index c3410ea..3dc6a93 100644
--- a/core/mac/src/pe/lim/lim_security_utils.h
+++ b/core/mac/src/pe/lim/lim_security_utils.h
@@ -39,9 +39,11 @@
#define __LIM_SECURITY_UTILS_H
#include "sir_mac_prot_def.h" /* for tSirMacAuthFrameBody */
-#define LIM_ENCR_AUTH_BODY_LEN (sizeof(tSirMacAuthFrameBody) + \
+#define LIM_ENCR_AUTH_BODY_LEN (SIR_MAC_AUTH_FRAME_INFO_LEN + \
+ SIR_MAC_AUTH_CHALLENGE_BODY_LEN + \
SIR_MAC_WEP_IV_LENGTH + \
SIR_MAC_WEP_ICV_LENGTH)
+
struct tLimPreAuthNode;
uint8_t lim_is_auth_algo_supported(tpAniSirGlobal, tAniAuthType, tpPESession);
diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c
index 15b8355..7944fbc 100644
--- a/core/mac/src/pe/lim/lim_send_management_frames.c
+++ b/core/mac/src/pe/lim/lim_send_management_frames.c
@@ -2096,6 +2096,7 @@
uint8_t tx_flag = 0;
uint8_t sme_sessionid = 0;
uint16_t ft_ies_length = 0;
+ bool challenge_req = false;
if (NULL == session) {
pe_err("Error: psession Entry is NULL");
@@ -2117,8 +2118,8 @@
pe_debug("Sending encrypted auth frame to " MAC_ADDRESS_STR,
MAC_ADDR_ARRAY(peer_addr));
- frame_len = sizeof(tSirMacMgmtHdr) + LIM_ENCR_AUTH_BODY_LEN;
body_len = LIM_ENCR_AUTH_BODY_LEN;
+ frame_len = sizeof(tSirMacMgmtHdr) + body_len;
goto alloc_packet;
}
@@ -2140,9 +2141,8 @@
* and status code.
*/
- frame_len = sizeof(tSirMacMgmtHdr) +
- SIR_MAC_AUTH_CHALLENGE_OFFSET;
- body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
+ body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
+ frame_len = sizeof(tSirMacMgmtHdr) + body_len;
if (auth_frame->authAlgoNumber == eSIR_FT_AUTH) {
if (NULL != session->ftPEContext.pFTPreAuthReq &&
@@ -2172,9 +2172,8 @@
* transaction number and status code.
*/
- frame_len = sizeof(tSirMacMgmtHdr) +
- SIR_MAC_AUTH_CHALLENGE_OFFSET;
- body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
+ body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
+ frame_len = sizeof(tSirMacMgmtHdr) + body_len;
} else {
/*
* Shared Key algorithm with challenge text
@@ -2187,9 +2186,10 @@
* for challenge text.
*/
- frame_len = sizeof(tSirMacMgmtHdr) +
- sizeof(tSirMacAuthFrame);
- body_len = sizeof(tSirMacAuthFrameBody);
+ challenge_req = true;
+ body_len = SIR_MAC_AUTH_FRAME_INFO_LEN +
+ SIR_MAC_AUTH_CHALLENGE_BODY_LEN;
+ frame_len = sizeof(tSirMacMgmtHdr) + body_len;
}
break;
@@ -2203,9 +2203,8 @@
* status code.
*/
- frame_len = sizeof(tSirMacMgmtHdr) +
- SIR_MAC_AUTH_CHALLENGE_OFFSET;
- body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
+ body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
+ frame_len = sizeof(tSirMacMgmtHdr) + body_len;
break;
case SIR_MAC_AUTH_FRAME_4:
@@ -2216,9 +2215,8 @@
* status code.
*/
- frame_len = sizeof(tSirMacMgmtHdr) +
- SIR_MAC_AUTH_CHALLENGE_OFFSET;
- body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
+ body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
+ frame_len = sizeof(tSirMacMgmtHdr) + body_len;
break;
default:
@@ -2274,11 +2272,29 @@
sir_swap_u16if_needed(auth_frame->authStatusCode);
body += sizeof(uint16_t);
body_len -= sizeof(uint16_t);
- if (body_len <= (sizeof(auth_frame->type) +
- sizeof(auth_frame->length) +
- sizeof(auth_frame->challengeText)))
- qdf_mem_copy(body, (uint8_t *) &auth_frame->type,
- body_len);
+
+ if (challenge_req) {
+ if (body_len < SIR_MAC_AUTH_CHALLENGE_BODY_LEN) {
+ qdf_mem_copy(body, (uint8_t *)&auth_frame->type,
+ body_len);
+ pe_err("Incomplete challenge info: length: %d, expected: %d",
+ body_len,
+ SIR_MAC_AUTH_CHALLENGE_BODY_LEN);
+ body += body_len;
+ body_len = 0;
+ } else {
+ /* copy challenge IE id, len, challenge text */
+ *body = auth_frame->type;
+ body++;
+ *body = auth_frame->length;
+ body++;
+ qdf_mem_copy(body, auth_frame->challengeText,
+ SIR_MAC_AUTH_CHALLENGE_LENGTH);
+ body += SIR_MAC_AUTH_CHALLENGE_LENGTH;
+
+ body_len -= SIR_MAC_AUTH_CHALLENGE_BODY_LEN;
+ }
+ }
if ((auth_frame->authAlgoNumber == eSIR_FT_AUTH) &&
(auth_frame->authTransactionSeqNumber ==