summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dp/inc/cdp_txrx_ops.h4
-rw-r--r--dp/inc/cdp_txrx_peer_ops.h25
-rw-r--r--os_if/linux/qca_vendor.h9
-rw-r--r--os_if/linux/scan/src/wlan_cfg80211_scan.c90
-rw-r--r--umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h16
-rw-r--r--umac/regulatory/core/src/reg_services_common.c2
-rw-r--r--umac/regulatory/core/src/reg_utils.c2
-rw-r--r--umac/scan/core/src/wlan_scan_filter.c14
-rw-r--r--umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h8
-rw-r--r--umac/scan/dispatcher/src/wlan_scan_ucfg_api.c6
-rw-r--r--umac/scan/dispatcher/src/wlan_scan_utils_api.c70
-rw-r--r--wmi/inc/wmi_unified_param.h1
-rw-r--r--wmi/inc/wmi_unified_priv.h1
-rw-r--r--wmi/inc/wmi_unified_roam_param.h5
-rw-r--r--wmi/src/wmi_unified.c5
-rw-r--r--wmi/src/wmi_unified_nan_tlv.c11
-rw-r--r--wmi/src/wmi_unified_roam_tlv.c16
-rw-r--r--wmi/src/wmi_unified_tlv.c46
18 files changed, 262 insertions, 69 deletions
diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h
index 7ed927cec..1b0802004 100644
--- a/dp/inc/cdp_txrx_ops.h
+++ b/dp/inc/cdp_txrx_ops.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
@@ -1355,6 +1355,8 @@ struct cdp_peer_ops {
void (*update_last_real_peer)(struct cdp_pdev *pdev, void *vdev,
uint8_t *peer_id, bool restore_last_peer);
void (*peer_detach_force_delete)(void *peer);
+ void (*peer_flush_frags)(struct cdp_pdev *pdev,
+ uint8_t vdev_id, uint8_t *peer_mac);
};
/**
diff --git a/dp/inc/cdp_txrx_peer_ops.h b/dp/inc/cdp_txrx_peer_ops.h
index 85fd1b6f4..19604ab93 100644
--- a/dp/inc/cdp_txrx_peer_ops.h
+++ b/dp/inc/cdp_txrx_peer_ops.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019, 2021 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -673,4 +673,27 @@ is_cdp_peer_detach_force_delete_supported(ol_txrx_soc_handle soc)
return false;
}
+
+/**
+ * cdp_peer_flush_frags() - Flush frags on peer
+ * @soc - data path soc handle
+ * @pdev - data path device instance
+ * @vdev_id - virtual interface id
+ * @peer_mac - peer mac addr
+ *
+ * Return: None
+ */
+static inline void
+cdp_peer_flush_frags(ol_txrx_soc_handle soc, struct cdp_pdev *pdev,
+ uint8_t vdev_id, uint8_t *peer_mac)
+{
+ if (!soc || !soc->ops || !soc->ops->peer_ops) {
+ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
+ "%s invalid instance", __func__);
+ return;
+ }
+
+ if (soc->ops->peer_ops->peer_flush_frags)
+ soc->ops->peer_ops->peer_flush_frags(pdev, vdev_id, peer_mac);
+}
#endif /* _CDP_TXRX_PEER_H_ */
diff --git a/os_if/linux/qca_vendor.h b/os_if/linux/qca_vendor.h
index 8a81c4b73..874390358 100644
--- a/os_if/linux/qca_vendor.h
+++ b/os_if/linux/qca_vendor.h
@@ -2207,6 +2207,12 @@ enum qca_wlan_vendor_attr_ll_stats_results_type {
* @QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RTS_FAIL_CNT: RTS fail count
* @QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_PPDU_SUCC_CNT: PPDU successful count
* @QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_PPDU_FAIL_CNT: PPDU fail count
+ * @QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_TX_TIME: Unsigned int 32bit
+ * value representing total number of msecs the radio is transmitting on
+ * this channel.
+ * @QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_RX_TIME: Unsigned int 32bit
+ * value representing total number of msecs the radio is receiving all
+ * 802.11 frames intended for this device on this channel.
* @QCA_WLAN_VENDOR_ATTR_LL_STATS_AFTER_LAST: After last
* @QCA_WLAN_VENDOR_ATTR_FEATURE_SET_MAX: Max value
*/
@@ -2312,6 +2318,9 @@ enum qca_wlan_vendor_attr_ll_stats_results {
QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_PPDU_SUCC_CNT = 81,
QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_PPDU_FAIL_CNT = 82,
+ QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_TX_TIME = 84,
+ QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_RX_TIME = 85,
+
/* keep last */
QCA_WLAN_VENDOR_ATTR_LL_STATS_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX =
diff --git a/os_if/linux/scan/src/wlan_cfg80211_scan.c b/os_if/linux/scan/src/wlan_cfg80211_scan.c
index e418e8fd8..ecc743a9c 100644
--- a/os_if/linux/scan/src/wlan_cfg80211_scan.c
+++ b/os_if/linux/scan/src/wlan_cfg80211_scan.c
@@ -645,20 +645,22 @@ wlan_copy_bssid_scan_request(struct scan_start_request *scan_req,
#endif
/**
- * wlan_scan_request_enqueue() - enqueue Scan Request
+ * wlan_schedule_scan_start_request() - Schedule scan start request
* @pdev: pointer to pdev object
* @req: Pointer to the scan request
* @source: source of the scan request
- * @scan_id: scan identifier
+ * @scan_start_req: pointer to scan start request
*
- * Enqueue scan request in the global scan list.This list
- * stores the active scan request information.
+ * Schedule scan start request and enqueue scan request in the global scan
+ * list. This list stores the active scan request information.
*
- * Return: 0 on success, error number otherwise
+ * Return: QDF_STATUS
*/
-static int wlan_scan_request_enqueue(struct wlan_objmgr_pdev *pdev,
- struct cfg80211_scan_request *req,
- uint8_t source, uint32_t scan_id)
+static QDF_STATUS
+wlan_schedule_scan_start_request(struct wlan_objmgr_pdev *pdev,
+ struct cfg80211_scan_request *req,
+ uint8_t source,
+ struct scan_start_request *scan_start_req)
{
struct scan_req *scan_req;
QDF_STATUS status;
@@ -666,32 +668,44 @@ static int wlan_scan_request_enqueue(struct wlan_objmgr_pdev *pdev,
struct osif_scan_pdev *osif_scan;
scan_req = qdf_mem_malloc(sizeof(*scan_req));
- if (!scan_req)
- return -ENOMEM;
+ if (!scan_req) {
+ ucfg_scm_scan_free_scan_request_mem(scan_start_req);
+ return QDF_STATUS_E_NOMEM;
+ }
/* Get NL global context from objmgr*/
osif_ctx = wlan_pdev_get_ospriv(pdev);
osif_scan = osif_ctx->osif_scan;
scan_req->scan_request = req;
scan_req->source = source;
- scan_req->scan_id = scan_id;
+ scan_req->scan_id = scan_start_req->scan_req.scan_id;
scan_req->dev = req->wdev->netdev;
qdf_mutex_acquire(&osif_scan->scan_req_q_lock);
- if (qdf_list_size(&osif_scan->scan_req_q) < WLAN_MAX_SCAN_COUNT)
- status = qdf_list_insert_back(&osif_scan->scan_req_q,
- &scan_req->node);
- else
+ if (qdf_list_size(&osif_scan->scan_req_q) < WLAN_MAX_SCAN_COUNT) {
+ status = ucfg_scan_start(scan_start_req);
+ if (QDF_IS_STATUS_SUCCESS(status)) {
+ qdf_list_insert_back(&osif_scan->scan_req_q,
+ &scan_req->node);
+ } else {
+ cfg80211_debug_rl("scan req failed with error %d",
+ status);
+ if (status == QDF_STATUS_E_RESOURCES)
+ cfg80211_debug_rl("HO is in progress.So defer the scan by informing busy");
+ }
+ } else {
+ ucfg_scm_scan_free_scan_request_mem(scan_start_req);
status = QDF_STATUS_E_RESOURCES;
+ }
+
qdf_mutex_release(&osif_scan->scan_req_q_lock);
if (QDF_IS_STATUS_ERROR(status)) {
cfg80211_debug_rl("Failed to enqueue Scan Req as max scan %d already queued",
qdf_list_size(&osif_scan->scan_req_q));
qdf_mem_free(scan_req);
- return -EINVAL;
}
- return 0;
+ return status;
}
/**
@@ -728,12 +742,13 @@ static QDF_STATUS wlan_scan_request_dequeue(
}
scan_priv = osif_ctx->osif_scan;
+ qdf_mutex_acquire(&scan_priv->scan_req_q_lock);
if (qdf_list_empty(&scan_priv->scan_req_q)) {
+ qdf_mutex_release(&scan_priv->scan_req_q_lock);
cfg80211_info("Scan List is empty");
return QDF_STATUS_E_FAILURE;
}
- qdf_mutex_acquire(&scan_priv->scan_req_q_lock);
if (QDF_STATUS_SUCCESS !=
qdf_list_peek_front(&scan_priv->scan_req_q, &next_node)) {
qdf_mutex_release(&scan_priv->scan_req_q_lock);
@@ -1020,9 +1035,11 @@ static void wlan_cfg80211_scan_done_callback(
wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
allow_suspend:
osif_priv = wlan_pdev_get_ospriv(pdev);
+ qdf_mutex_acquire(&osif_priv->osif_scan->scan_req_q_lock);
if (qdf_list_empty(&osif_priv->osif_scan->scan_req_q)) {
struct wlan_objmgr_psoc *psoc;
+ qdf_mutex_release(&osif_priv->osif_scan->scan_req_q_lock);
qdf_runtime_pm_allow_suspend(
&osif_priv->osif_scan->runtime_pm_lock);
@@ -1039,6 +1056,8 @@ allow_suspend:
wlan_scan_acquire_wake_lock_timeout(psoc,
&osif_priv->osif_scan->scan_wake_lock,
SCAN_WAKE_LOCK_CONNECT_DURATION);
+ } else {
+ qdf_mutex_release(&osif_priv->osif_scan->scan_req_q_lock);
}
}
@@ -1289,7 +1308,6 @@ int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev,
wlan_scan_id scan_id;
bool is_p2p_scan = false;
enum wlan_band band;
- struct net_device *netdev = NULL;
QDF_STATUS qdf_status;
enum QDF_OPMODE opmode;
uint32_t extra_ie_len = 0;
@@ -1316,12 +1334,15 @@ int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev,
* is not empty, and the simultaneous scan is disabled, dont allow 2nd
* scan.
*/
+ qdf_mutex_acquire(&osif_priv->osif_scan->scan_req_q_lock);
if (!wlan_cfg80211_allow_simultaneous_scan(psoc) &&
!qdf_list_empty(&osif_priv->osif_scan->scan_req_q) &&
opmode != QDF_SAP_MODE) {
+ qdf_mutex_release(&osif_priv->osif_scan->scan_req_q_lock);
cfg80211_err("Simultaneous scan disabled, reject scan");
return -EBUSY;
}
+ qdf_mutex_release(&osif_priv->osif_scan->scan_req_q_lock);
req = qdf_mem_malloc(sizeof(*req));
if (!req)
@@ -1344,14 +1365,6 @@ int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev,
req->scan_req.scan_id = scan_id;
req->scan_req.scan_req_id = req_id;
- /* Enqueue the scan request */
- ret = wlan_scan_request_enqueue(pdev, request, params->source,
- req->scan_req.scan_id);
- if (ret) {
- qdf_mem_free(req);
- return ret;
- }
-
/* Update scan policy type flags according to cfg scan request */
wlan_cfg80211_update_scan_policy_type_flags(request,
&req->scan_req);
@@ -1544,18 +1557,21 @@ int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev,
qdf_runtime_pm_prevent_suspend(
&osif_priv->osif_scan->runtime_pm_lock);
- qdf_status = ucfg_scan_start(req);
+ qdf_status = wlan_schedule_scan_start_request(pdev, request,
+ params->source, req);
if (QDF_IS_STATUS_ERROR(qdf_status)) {
- cfg80211_err("scan req failed with error %d", qdf_status);
- if (qdf_status == QDF_STATUS_E_RESOURCES)
- cfg80211_err("HO is in progress.So defer the scan by informing busy");
- wlan_scan_request_dequeue(pdev, scan_id, &request,
- &params->source, &netdev);
+ qdf_mutex_acquire(&osif_priv->osif_scan->scan_req_q_lock);
if (qdf_list_empty(&osif_priv->osif_scan->scan_req_q)) {
+ qdf_mutex_release(
+ &osif_priv->osif_scan->scan_req_q_lock);
qdf_runtime_pm_allow_suspend(
- &osif_priv->osif_scan->runtime_pm_lock);
- wlan_scan_release_wake_lock(psoc,
- &osif_priv->osif_scan->scan_wake_lock);
+ &osif_priv->osif_scan->runtime_pm_lock);
+ wlan_scan_release_wake_lock(
+ psoc,
+ &osif_priv->osif_scan->scan_wake_lock);
+ } else {
+ qdf_mutex_release(
+ &osif_priv->osif_scan->scan_req_q_lock);
}
}
@@ -1563,8 +1579,6 @@ int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev,
err:
qdf_mem_free(req);
- wlan_scan_request_dequeue(pdev, scan_id, &request,
- &params->source, &netdev);
return ret;
}
diff --git a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h
index 6a1470b6e..d8d688e58 100644
--- a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h
+++ b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h
@@ -135,6 +135,17 @@
#define WLAN_REQUEST_IE_MAX_LEN 255
#define WLAN_RM_CAPABILITY_IE_MAX_LEN 5
+/* Wide band channel switch IE length */
+#define WLAN_WIDE_BW_CHAN_SWITCH_IE_LEN 3
+
+/* Number of max TX power elements supported plus size of Transmit Power
+ * Information element.
+ */
+#define WLAN_TPE_IE_MAX_LEN 9
+
+/* Max channel switch time IE length */
+#define WLAN_MAX_CHAN_SWITCH_TIME_IE_LEN 4
+
/* HT capability flags */
#define WLAN_HTCAP_C_ADVCODING 0x0001
#define WLAN_HTCAP_C_CHWIDTH40 0x0002
@@ -1410,6 +1421,8 @@ is_bwnss_oui(uint8_t *frm)
((ATH_OUI_BW_NSS_MAP_TYPE << 24) | ATH_OUI));
}
+#define WLAN_BWNSS_MAP_OFFSET 6
+
/**
* is_he_cap_oui() - If vendor IE is HE CAP OUI
* @frm: vendor IE pointer
@@ -1786,9 +1799,12 @@ static inline void wlan_parse_wapi_ie(uint8_t *wapi_ie,
len -= WLAN_OUI_SIZE;
}
+ if (len < 2)
+ return;
wapi->uc_cipher_count = LE_READ_2(ie);
ie += 2;
len -= 2;
+
if ((wapi->uc_cipher_count > WLAN_MAX_CIPHER) ||
len < (wapi->uc_cipher_count * WLAN_OUI_SIZE + 2))
return;
diff --git a/umac/regulatory/core/src/reg_services_common.c b/umac/regulatory/core/src/reg_services_common.c
index 8f717cddb..9e18112e4 100644
--- a/umac/regulatory/core/src/reg_services_common.c
+++ b/umac/regulatory/core/src/reg_services_common.c
@@ -1739,7 +1739,7 @@ QDF_STATUS reg_get_curr_regdomain(struct wlan_objmgr_pdev *pdev,
}
if (index == num_reg_dmn) {
- reg_err("invalid regdomain");
+ reg_debug_rl("invalid regdomain");
return QDF_STATUS_E_FAILURE;
}
diff --git a/umac/regulatory/core/src/reg_utils.c b/umac/regulatory/core/src/reg_utils.c
index ef956a5a6..5c9293f7c 100644
--- a/umac/regulatory/core/src/reg_utils.c
+++ b/umac/regulatory/core/src/reg_utils.c
@@ -320,7 +320,7 @@ bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev)
status = reg_get_curr_regdomain(pdev, &cur_reg_dmn);
if (status != QDF_STATUS_SUCCESS) {
- reg_err("Failed to get reg domain");
+ reg_debug_rl("Failed to get reg domain");
return false;
}
diff --git a/umac/scan/core/src/wlan_scan_filter.c b/umac/scan/core/src/wlan_scan_filter.c
index 4581289d7..6f7a2565e 100644
--- a/umac/scan/core/src/wlan_scan_filter.c
+++ b/umac/scan/core/src/wlan_scan_filter.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -1034,6 +1034,7 @@ static bool scm_is_fils_config_match(struct scan_filter *filter,
int i;
struct fils_indication_ie *indication_ie;
uint8_t *data;
+ uint8_t *end_ptr;
if (!filter->fils_scan_filter.realm_check)
return true;
@@ -1045,14 +1046,19 @@ static bool scm_is_fils_config_match(struct scan_filter *filter,
indication_ie =
(struct fils_indication_ie *) db_entry->ie_list.fils_indication;
+ end_ptr = (uint8_t *)indication_ie + indication_ie->len + 2;
+
data = indication_ie->variable_data;
- if (indication_ie->is_cache_id_present)
+ if (indication_ie->is_cache_id_present &&
+ (data + CACHE_IDENTIFIER_LEN) <= end_ptr)
data += CACHE_IDENTIFIER_LEN;
- if (indication_ie->is_hessid_present)
+ if (indication_ie->is_hessid_present &&
+ (data + HESSID_LEN) <= end_ptr)
data += HESSID_LEN;
- for (i = 1; i <= indication_ie->realm_identifiers_cnt; i++) {
+ for (i = 1; i <= indication_ie->realm_identifiers_cnt &&
+ (data + REAM_HASH_LEN) <= end_ptr; i++) {
if (!qdf_mem_cmp(filter->fils_scan_filter.fils_realm,
data, REAM_HASH_LEN))
return true;
diff --git a/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h b/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h
index b5eee5ce9..dbc4f90ee 100644
--- a/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h
+++ b/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h
@@ -163,6 +163,14 @@ ucfg_scan_get_pno_match(struct wlan_objmgr_vdev *vdev)
}
#endif /* FEATURE_WLAN_SCAN_PNO */
/**
+ * ucfg_scm_scan_free_scan_request_mem() - Free scan request memory
+ * @req: scan_start_request object
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ucfg_scm_scan_free_scan_request_mem(struct scan_start_request *req);
+
+/**
* ucfg_scan_start() - Public API to start a scan
* @req: start scan req params
*
diff --git a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c
index 3c31fc17d..298b3bb2e 100644
--- a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c
+++ b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c
@@ -430,6 +430,12 @@ ucfg_scan_set_custom_scan_chan_list(struct wlan_objmgr_pdev *pdev,
}
QDF_STATUS
+ucfg_scm_scan_free_scan_request_mem(struct scan_start_request *req)
+{
+ return scm_scan_free_scan_request_mem(req);
+}
+
+QDF_STATUS
ucfg_scan_start(struct scan_start_request *req)
{
struct scheduler_msg msg = {0};
diff --git a/umac/scan/dispatcher/src/wlan_scan_utils_api.c b/umac/scan/dispatcher/src/wlan_scan_utils_api.c
index 97ef1a8cd..b1c9ea5ac 100644
--- a/umac/scan/dispatcher/src/wlan_scan_utils_api.c
+++ b/umac/scan/dispatcher/src/wlan_scan_utils_api.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -371,12 +371,18 @@ util_scan_parse_chan_switch_wrapper_ie(struct scan_cache_entry *scan_params,
}
switch (sub_ie->ie_id) {
case WLAN_ELEMID_COUNTRY:
+ if (sub_ie->ie_len < WLAN_COUNTRY_IE_MIN_LEN)
+ return QDF_STATUS_E_INVAL;
scan_params->ie_list.country = (uint8_t *)sub_ie;
break;
case WLAN_ELEMID_WIDE_BAND_CHAN_SWITCH:
+ if (sub_ie->ie_len < WLAN_WIDE_BW_CHAN_SWITCH_IE_LEN)
+ return QDF_STATUS_E_INVAL;
scan_params->ie_list.widebw = (uint8_t *)sub_ie;
break;
case WLAN_ELEMID_VHT_TX_PWR_ENVLP:
+ if (sub_ie->ie_len > WLAN_TPE_IE_MAX_LEN)
+ return QDF_STATUS_E_INVAL;
scan_params->ie_list.txpwrenvlp = (uint8_t *)sub_ie;
break;
}
@@ -419,6 +425,8 @@ util_scan_parse_extn_ie(struct scan_cache_entry *scan_params,
switch (extn_ie->ie_extn_id) {
case WLAN_EXTN_ELEMID_MAX_CHAN_SWITCH_TIME:
+ if (extn_ie->ie_len != WLAN_MAX_CHAN_SWITCH_TIME_IE_LEN)
+ return QDF_STATUS_E_INVAL;
scan_params->ie_list.mcst = (uint8_t *)ie;
break;
case WLAN_EXTN_ELEMID_SRP:
@@ -525,7 +533,8 @@ util_scan_parse_vendor_ie(struct scan_cache_entry *scan_params,
* Bandwidth-NSS map has sub-type & version.
* hence copy data just after version byte
*/
- scan_params->ie_list.bwnss_map = (((uint8_t *)ie) + 8);
+ if (ie->ie_len > WLAN_BWNSS_MAP_OFFSET)
+ scan_params->ie_list.bwnss_map = (((uint8_t *)ie) + 8);
} else if (is_mbo_oce_oui((uint8_t *)ie)) {
scan_params->ie_list.mbo_oce = (uint8_t *)ie;
} else if (is_extender_oui((uint8_t *)ie)) {
@@ -795,7 +804,8 @@ static void util_scan_update_esp_data(struct wlan_esp_ie *esp_information,
return;
}
- for (i = 0; i < total_elements; i++) {
+ for (i = 0; i < total_elements &&
+ data < ((uint8_t *)esp_ie + esp_ie->esp_len + 3); i++) {
esp_info = (struct wlan_esp_info *)data;
if (esp_info->access_category == ESP_AC_BK) {
qdf_mem_copy(&esp_information->esp_info_AC_BK,
@@ -1308,6 +1318,7 @@ static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen,
uint8_t *pos, *tmp;
const uint8_t *tmp_old, *tmp_new;
uint8_t *sub_copy;
+ size_t tmp_rem_len;
/* copy subelement as we need to change its content to
* mark an ie after it is processed.
@@ -1322,8 +1333,10 @@ static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen,
/* new ssid */
tmp_new = util_scan_find_ie(WLAN_ELEMID_SSID, sub_copy, subie_len);
if (tmp_new) {
- qdf_mem_copy(pos, tmp_new, tmp_new[1] + 2);
- pos += (tmp_new[1] + 2);
+ if ((pos + tmp_new[1] + 2) <= (new_ie + ielen)) {
+ qdf_mem_copy(pos, tmp_new, tmp_new[1] + 2);
+ pos += (tmp_new[1] + 2);
+ }
}
/* go through IEs in ie (skip SSID) and subelement,
@@ -1343,8 +1356,12 @@ static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen,
if (!tmp) {
/* ie in old ie but not in subelement */
if (tmp_old[0] != WLAN_ELEMID_MULTIPLE_BSSID) {
- qdf_mem_copy(pos, tmp_old, tmp_old[1] + 2);
- pos += tmp_old[1] + 2;
+ if ((pos + tmp_old[1] + 2) <=
+ (new_ie + ielen)) {
+ qdf_mem_copy(pos, tmp_old,
+ tmp_old[1] + 2);
+ pos += tmp_old[1] + 2;
+ }
}
} else {
/* ie in transmitting ie also in subelement,
@@ -1353,24 +1370,35 @@ static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen,
* vendor ie, compare OUI + type + subType to
* determine if they are the same ie.
*/
- if (tmp_old[0] == WLAN_ELEMID_VENDOR) {
+ tmp_rem_len = subie_len - (tmp - sub_copy);
+ if (tmp_old[0] == WLAN_ELEMID_VENDOR &&
+ tmp_rem_len >= 7) {
if (!qdf_mem_cmp(tmp_old + 2, tmp + 2, 5)) {
/* same vendor ie, copy from
* subelement
*/
- qdf_mem_copy(pos, tmp, tmp[1] + 2);
- pos += tmp[1] + 2;
- tmp[0] = 0xff;
+ if ((pos + tmp[1] + 2) <=
+ (new_ie + ielen)) {
+ qdf_mem_copy(pos, tmp,
+ tmp[1] + 2);
+ pos += tmp[1] + 2;
+ tmp[0] = 0xff;
+ }
} else {
- qdf_mem_copy(pos, tmp_old,
- tmp_old[1] + 2);
- pos += tmp_old[1] + 2;
+ if ((pos + tmp_old[1] + 2) <=
+ (new_ie + ielen)) {
+ qdf_mem_copy(pos, tmp_old,
+ tmp_old[1] + 2);
+ pos += tmp_old[1] + 2;
+ }
}
} else {
/* copy ie from subelement into new ie */
- qdf_mem_copy(pos, tmp, tmp[1] + 2);
- pos += tmp[1] + 2;
- tmp[0] = 0xff;
+ if ((pos + tmp[1] + 2) <= (new_ie + ielen)) {
+ qdf_mem_copy(pos, tmp, tmp[1] + 2);
+ pos += tmp[1] + 2;
+ tmp[0] = 0xff;
+ }
}
}
@@ -1389,8 +1417,10 @@ static uint32_t util_gen_new_ie(uint8_t *ie, uint32_t ielen,
tmp_new[0] == WLAN_ELEMID_SSID ||
tmp_new[0] == WLAN_ELEMID_MULTI_BSSID_IDX ||
tmp_new[0] == 0xff)) {
- qdf_mem_copy(pos, tmp_new, tmp_new[1] + 2);
- pos += tmp_new[1] + 2;
+ if ((pos + tmp_new[1] + 2) <= (new_ie + ielen)) {
+ qdf_mem_copy(pos, tmp_new, tmp_new[1] + 2);
+ pos += tmp_new[1] + 2;
+ }
}
if (tmp_new + tmp_new[1] + 2 - sub_copy == subie_len)
break;
@@ -1432,7 +1462,7 @@ static QDF_STATUS util_scan_parse_mbssid(struct wlan_objmgr_pdev *pdev,
pos = ie;
- new_ie = qdf_mem_malloc(MAX_IE_LEN);
+ new_ie = qdf_mem_malloc(ielen);
if (!new_ie)
return QDF_STATUS_E_NOMEM;
diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h
index a9473e512..3ea5c231f 100644
--- a/wmi/inc/wmi_unified_param.h
+++ b/wmi/inc/wmi_unified_param.h
@@ -5367,6 +5367,7 @@ typedef enum {
wmi_service_packet_capture_support,
wmi_service_peer_delete_no_peer_flush_tids_cmd,
wmi_service_suiteb_roam_support,
+ wmi_service_ll_stats_per_chan_rx_tx_time,
wmi_services_max,
} wmi_conv_service_ids;
#define WMI_SERVICE_UNAVAILABLE 0xFFFF
diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h
index 0319360e1..65bcdd08e 100644
--- a/wmi/inc/wmi_unified_priv.h
+++ b/wmi/inc/wmi_unified_priv.h
@@ -2156,6 +2156,7 @@ struct wmi_soc {
/* WMI service bitmap received from target */
uint32_t *wmi_service_bitmap;
uint32_t *wmi_ext_service_bitmap;
+ uint32_t *wmi_ext2_service_bitmap;
uint32_t services[wmi_services_max];
uint16_t wmi_max_cmds;
uint32_t soc_idx;
diff --git a/wmi/inc/wmi_unified_roam_param.h b/wmi/inc/wmi_unified_roam_param.h
index c2bed0b0a..e5c43057d 100644
--- a/wmi/inc/wmi_unified_roam_param.h
+++ b/wmi/inc/wmi_unified_roam_param.h
@@ -436,8 +436,11 @@ struct scoring_param {
#define IDLE_ROAM_TRIGGER 0
#define BTM_ROAM_TRIGGER 1
+#define NUM_OF_ROAM_MIN_RSSI 3
+
#define DEAUTH_MIN_RSSI 0
#define BMISS_MIN_RSSI 1
+#define MIN_RSSI_2G_TO_5G_ROAM 2
/**
* enum roam_trigger_reason - Reason for triggering roam
@@ -524,7 +527,7 @@ struct ap_profile_params {
uint8_t vdev_id;
struct ap_profile profile;
struct scoring_param param;
- struct roam_trigger_min_rssi min_rssi_params[NUM_OF_ROAM_TRIGGERS];
+ struct roam_trigger_min_rssi min_rssi_params[NUM_OF_ROAM_MIN_RSSI];
struct roam_trigger_score_delta score_delta_param[NUM_OF_ROAM_TRIGGERS];
};
diff --git a/wmi/src/wmi_unified.c b/wmi/src/wmi_unified.c
index 27bb33d99..4d094b349 100644
--- a/wmi/src/wmi_unified.c
+++ b/wmi/src/wmi_unified.c
@@ -2720,6 +2720,11 @@ void wmi_unified_detach(struct wmi_unified *wmi_handle)
soc->wmi_ext_service_bitmap = NULL;
}
+ if (soc->wmi_ext2_service_bitmap) {
+ qdf_mem_free(soc->wmi_ext2_service_bitmap);
+ soc->wmi_ext2_service_bitmap = NULL;
+ }
+
/* Decrease the ref count once refcount infra is present */
soc->wmi_psoc = NULL;
qdf_mem_free(soc);
diff --git a/wmi/src/wmi_unified_nan_tlv.c b/wmi/src/wmi_unified_nan_tlv.c
index 5f43bc10e..f9b6d76b2 100644
--- a/wmi/src/wmi_unified_nan_tlv.c
+++ b/wmi/src/wmi_unified_nan_tlv.c
@@ -744,6 +744,13 @@ static QDF_STATUS extract_ndp_ind_tlv(wmi_unified_t wmi_handle,
return QDF_STATUS_E_INVAL;
}
+ if (fixed_params->nan_scid_len > event->num_ndp_scid) {
+ WMI_LOGE("FW msg ndp scid info len %d more than TLV hdr %d",
+ fixed_params->nan_scid_len,
+ event->num_ndp_scid);
+ return QDF_STATUS_E_INVAL;
+ }
+
if (fixed_params->ndp_cfg_len >
(WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_params))) {
WMI_LOGE("%s: excess wmi buffer: ndp_cfg_len %d",
@@ -922,6 +929,10 @@ static QDF_STATUS extract_ndp_confirm_tlv(wmi_unified_t wmi_handle,
WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr,
rsp->peer_ndi_mac_addr.bytes);
rsp->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len;
+
+ if (rsp->ndp_info.ndp_app_info_len > NDP_APP_INFO_LEN)
+ rsp->ndp_info.ndp_app_info_len = NDP_APP_INFO_LEN;
+
qdf_mem_copy(rsp->ndp_info.ndp_app_info, event->ndp_app_info,
rsp->ndp_info.ndp_app_info_len);
diff --git a/wmi/src/wmi_unified_roam_tlv.c b/wmi/src/wmi_unified_roam_tlv.c
index 851d61875..eba204845 100644
--- a/wmi/src/wmi_unified_roam_tlv.c
+++ b/wmi/src/wmi_unified_roam_tlv.c
@@ -1550,7 +1550,7 @@ send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
len += WMI_TLV_HDR_SIZE;
len += NUM_OF_ROAM_TRIGGERS * sizeof(*score_delta_param);
len += WMI_TLV_HDR_SIZE;
- len += NUM_OF_ROAM_TRIGGERS * sizeof(*min_rssi_param);
+ len += NUM_OF_ROAM_MIN_RSSI * sizeof(*min_rssi_param);
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf) {
return QDF_STATUS_E_NOMEM;
@@ -1743,7 +1743,7 @@ send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
buf_ptr += sizeof(*score_delta_param);
WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
- (NUM_OF_ROAM_TRIGGERS * sizeof(*min_rssi_param)));
+ (NUM_OF_ROAM_MIN_RSSI * sizeof(*min_rssi_param)));
buf_ptr += WMI_TLV_HDR_SIZE;
min_rssi_param = (wmi_roam_cnd_min_rssi_param *)buf_ptr;
@@ -1769,6 +1769,18 @@ send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
min_rssi_param->candidate_min_rssi =
ap_profile->min_rssi_params[BMISS_MIN_RSSI].min_rssi;
+ buf_ptr += sizeof(*min_rssi_param);
+ min_rssi_param = (wmi_roam_cnd_min_rssi_param *)buf_ptr;
+ WMITLV_SET_HDR(&min_rssi_param->tlv_header,
+ WMITLV_TAG_STRUC_wmi_roam_cnd_min_rssi_param,
+ WMITLV_GET_STRUCT_TLVLEN(wmi_roam_cnd_min_rssi_param));
+ trig_reason =
+ ap_profile->min_rssi_params[MIN_RSSI_2G_TO_5G_ROAM].trigger_reason;
+ min_rssi_param->roam_trigger_reason =
+ convert_roam_trigger_reason(trig_reason);
+ min_rssi_param->candidate_min_rssi =
+ ap_profile->min_rssi_params[MIN_RSSI_2G_TO_5G_ROAM].min_rssi;
+
wmi_mtrace(WMI_ROAM_AP_PROFILE, NO_SESSION, 0);
status = wmi_unified_cmd_send(wmi_handle, buf,
len, WMI_ROAM_AP_PROFILE);
diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c
index a8515e587..bc8bab86e 100644
--- a/wmi/src/wmi_unified_tlv.c
+++ b/wmi/src/wmi_unified_tlv.c
@@ -8177,6 +8177,7 @@ QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf;
wmi_service_available_event_fixed_param *ev;
struct wmi_soc *soc = wmi_handle->soc;
+ uint32_t i = 0;
param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf;
@@ -8205,6 +8206,29 @@ QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
soc->wmi_ext_service_bitmap,
(WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)));
+ if (!param_buf->wmi_service_ext_bitmap) {
+ WMI_LOGD("wmi_service_ext_bitmap not available");
+ return QDF_STATUS_SUCCESS;
+ }
+
+ if (!soc->wmi_ext2_service_bitmap) {
+ soc->wmi_ext2_service_bitmap =
+ qdf_mem_malloc(param_buf->num_wmi_service_ext_bitmap *
+ sizeof(uint32_t));
+ if (!soc->wmi_ext2_service_bitmap)
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ qdf_mem_copy(soc->wmi_ext2_service_bitmap,
+ param_buf->wmi_service_ext_bitmap,
+ (param_buf->num_wmi_service_ext_bitmap *
+ sizeof(uint32_t)));
+
+ for (i = 0; i < param_buf->num_wmi_service_ext_bitmap; i++) {
+ WMI_LOGD("wmi_ext2_service_bitmap %u:0x%x",
+ i, soc->wmi_ext2_service_bitmap[i]);
+ }
+
return QDF_STATUS_SUCCESS;
}
/**
@@ -8224,6 +8248,26 @@ static bool is_service_enabled_tlv(wmi_unified_t wmi_handle,
return false;
}
+ if (!soc->wmi_ext_service_bitmap) {
+ WMI_LOGE("WMI service ext bit map is not saved yet");
+ return false;
+ }
+
+ /* if wmi_service_enabled was received with extended2 bitmap,
+ * use WMI_SERVICE_EXT2_IS_ENABLED to check the services.
+ */
+ if (soc->wmi_ext2_service_bitmap)
+ return WMI_SERVICE_EXT2_IS_ENABLED(soc->wmi_service_bitmap,
+ soc->wmi_ext_service_bitmap,
+ soc->wmi_ext2_service_bitmap,
+ service_id);
+
+ if (service_id >= WMI_MAX_EXT_SERVICE) {
+ WMI_LOGE("Service id %d but WMI ext2 service bitmap is NULL",
+ service_id);
+ return false;
+ }
+
/* if wmi_service_enabled was received with extended bitmap,
* use WMI_SERVICE_EXT_IS_ENABLED to check the services.
*/
@@ -13090,6 +13134,8 @@ static void populate_tlv_service(uint32_t *wmi_service)
WMI_SERVICE_PEER_DELETE_NO_PEER_FLUSH_TIDS_CMD;
wmi_service[wmi_service_suiteb_roam_support] =
WMI_SERVICE_WPA3_SUITEB_ROAM_SUPPORT;
+ wmi_service[wmi_service_ll_stats_per_chan_rx_tx_time] =
+ WMI_SERVICE_LL_STATS_PER_CHAN_RX_TX_TIME_SUPPORT;
}
/**