summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixelBot AutoMerger <android-nexus-securitybot@system.gserviceaccount.com>2023-05-07 18:13:34 -0700
committerSecurityBot <android-nexus-securitybot@system.gserviceaccount.com>2023-05-07 18:13:34 -0700
commit9d72a095d4441badfae909ab16ca647bf3a1ff29 (patch)
tree43363ced6542f7f4d762479c00994db0cc503206
parent5327ad6cfd834e7e522cd05d081aa65a72bf8766 (diff)
parente4fa8249b85725a0782eb5b7d7bb410e5f960fed (diff)
downloadqcacld-9d72a095d4441badfae909ab16ca647bf3a1ff29.tar.gz
Merge android-msm-pixel-4.19-tm-qpr3 into android-msm-pixel-4.19android-u-beta-3_r0.1android-msm-redbull-4.19-u-beta3
SBMerger: 526756187 Change-Id: Ifa73b1a366937af26a05e61a3532fed7893af73b Signed-off-by: SecurityBot <android-nexus-securitybot@system.gserviceaccount.com>
-rw-r--r--core/cds/src/cds_api.c23
-rw-r--r--core/hdd/inc/wlan_hdd_main.h73
-rw-r--r--core/hdd/src/wlan_hdd_assoc.c12
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.c22
-rw-r--r--core/hdd/src/wlan_hdd_hostapd.c14
-rw-r--r--core/hdd/src/wlan_hdd_ioctl.c8
-rw-r--r--core/hdd/src/wlan_hdd_ipa.c9
-rw-r--r--core/hdd/src/wlan_hdd_main.c296
-rw-r--r--core/hdd/src/wlan_hdd_nan_datapath.c23
-rw-r--r--core/hdd/src/wlan_hdd_oemdata.c6
-rw-r--r--core/hdd/src/wlan_hdd_periodic_sta_stats.c11
-rw-r--r--core/hdd/src/wlan_hdd_power.c55
-rw-r--r--core/hdd/src/wlan_hdd_regulatory.c8
-rw-r--r--core/hdd/src/wlan_hdd_stats.c5
-rw-r--r--core/mac/src/dph/dph_hash_table.c2
-rw-r--r--core/mac/src/pe/include/lim_api.h15
-rw-r--r--core/mac/src/pe/lim/lim_api.c30
-rw-r--r--core/mac/src/pe/lim/lim_process_auth_frame.c9
-rw-r--r--core/mac/src/pe/lim/lim_process_deauth_frame.c4
-rw-r--r--core/mac/src/pe/lim/lim_process_disassoc_frame.c5
-rw-r--r--core/wma/src/wma_mgmt.c3
21 files changed, 442 insertions, 191 deletions
diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c
index d8ebd1db36..01b1f958ac 100644
--- a/core/cds/src/cds_api.c
+++ b/core/cds/src/cds_api.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@@ -2747,7 +2748,7 @@ uint32_t cds_get_arp_stats_gw_ip(void *context)
void cds_incr_arp_stats_tx_tgt_delivered(void)
{
struct hdd_context *hdd_ctx;
- struct hdd_adapter *adapter = NULL;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
hdd_ctx = gp_cds_context->hdd_context;
if (!hdd_ctx) {
@@ -2755,9 +2756,14 @@ void cds_incr_arp_stats_tx_tgt_delivered(void)
return;
}
- hdd_for_each_adapter(hdd_ctx, adapter) {
- if (QDF_STA_MODE == adapter->device_mode)
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
+ if (QDF_STA_MODE == adapter->device_mode) {
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
break;
+ }
+ dev_put(adapter->dev);
}
if (adapter)
@@ -2772,7 +2778,7 @@ void cds_incr_arp_stats_tx_tgt_delivered(void)
void cds_incr_arp_stats_tx_tgt_acked(void)
{
struct hdd_context *hdd_ctx;
- struct hdd_adapter *adapter = NULL;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
hdd_ctx = gp_cds_context->hdd_context;
if (!hdd_ctx) {
@@ -2780,9 +2786,14 @@ void cds_incr_arp_stats_tx_tgt_acked(void)
return;
}
- hdd_for_each_adapter(hdd_ctx, adapter) {
- if (QDF_STA_MODE == adapter->device_mode)
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
+ if (QDF_STA_MODE == adapter->device_mode) {
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
break;
+ }
+ dev_put(adapter->dev);
}
if (adapter)
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index b1a59e179a..7fcfd7983c 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@@ -2236,25 +2237,31 @@ QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb,
void *context);
/**
- * hdd_for_each_adapter - adapter iterator macro
+ * __hdd_take_ref_and_fetch_front_adapter - Helper macro to lock, fetch front
+ * adapter, take ref and unlock.
* @hdd_ctx: the global HDD context
* @adapter: an hdd_adapter pointer to use as a cursor
*/
-#define hdd_for_each_adapter(hdd_ctx, adapter) \
- for (hdd_get_front_adapter(hdd_ctx, &adapter); \
- adapter; \
- hdd_get_next_adapter(hdd_ctx, adapter, &adapter))
+#define __hdd_take_ref_and_fetch_front_adapter(hdd_ctx, adapter) \
+ qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock), \
+ hdd_get_front_adapter_no_lock(hdd_ctx, &adapter), \
+ (adapter) ? dev_hold(adapter->dev) : (false), \
+ qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock)
/**
- * __hdd_take_ref_and_fetch_front_adapter - Helper macro to lock, fetch front
- * adapter, take ref and unlock.
+ * __hdd_take_ref_and_fetch_front_adapter_safe - Helper macro to lock, fetch
+ * front and next adapters, take ref and unlock.
* @hdd_ctx: the global HDD context
* @adapter: an hdd_adapter pointer to use as a cursor
+ * @next_adapter: hdd_adapter pointer to next adapter
*/
-#define __hdd_take_ref_and_fetch_front_adapter(hdd_ctx, adapter) \
+#define __hdd_take_ref_and_fetch_front_adapter_safe(hdd_ctx, adapter, \
+ next_adapter) \
qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock), \
hdd_get_front_adapter_no_lock(hdd_ctx, &adapter), \
(adapter) ? dev_hold(adapter->dev) : (false), \
+ hdd_get_next_adapter_no_lock(hdd_ctx, adapter, &next_adapter), \
+ (next_adapter) ? dev_hold(next_adapter->dev) : (false), \
qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock)
/**
@@ -2270,36 +2277,60 @@ QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb,
qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock)
/**
+ * __hdd_take_ref_and_fetch_next_adapter_safe - Helper macro to lock, fetch next
+ * adapter, take ref and unlock.
+ * @hdd_ctx: the global HDD context
+ * @adapter: hdd_adapter pointer to use as a cursor
+ * @next_adapter: hdd_adapter pointer to next adapter
+ */
+#define __hdd_take_ref_and_fetch_next_adapter_safe(hdd_ctx, adapter, \
+ next_adapter) \
+ qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock), \
+ adapter = next_adapter, \
+ hdd_get_next_adapter_no_lock(hdd_ctx, adapter, &next_adapter), \
+ (next_adapter) ? dev_hold(next_adapter->dev) : (false), \
+ qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock)
+
+/**
* __hdd_is_adapter_valid - Helper macro to return true/false for valid adapter.
* @adapter: an hdd_adapter pointer to use as a cursor
*/
#define __hdd_is_adapter_valid(_adapter) !!_adapter
/**
- * hdd_for_each_adapter_dev_held - Adapter iterator with dev_hold called
+ * hdd_for_each_adapter_dev_held_safe - Adapter iterator with dev_hold called
+ * in a delete safe manner
* @hdd_ctx: the global HDD context
* @adapter: an hdd_adapter pointer to use as a cursor
+ * @next_adapter: hdd_adapter pointer to the next adapter
*
* This iterator will take the reference of the netdev associated with the
- * given adapter so as to prevent it from being removed in other context.
- * If the control goes inside the loop body then the dev_hold has been invoked.
+ * given adapter so as to prevent it from being removed in other context. It
+ * also takes the reference of the next adapter if exist. This avoids infinite
+ * loop due to deletion of the adapter list entry inside the loop. Deletion of
+ * list entry will make the list entry to point to self. If the control goes
+ * inside the loop body then the dev_hold has been invoked.
*
* ***** NOTE *****
* Before the end of each iteration, dev_put(adapter->dev) must be
* called. Not calling this will keep hold of a reference, thus preventing
- * unregister of the netdevice.
+ * unregister of the netdevice. If the loop is terminated in between with
+ * return/goto/break statements, dev_put(next_adapter->dev) must be done
+ * along with dev_put(adapter->dev) before termination of the loop.
*
* Usage example:
- * hdd_for_each_adapter_dev_held(hdd_ctx, adapter) {
- * <work involving adapter>
- * <some more work>
- * dev_put(adapter->dev)
- * }
- */
-#define hdd_for_each_adapter_dev_held(hdd_ctx, adapter) \
- for (__hdd_take_ref_and_fetch_front_adapter(hdd_ctx, adapter); \
+ * hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
+ * <work involving adapter>
+ * <some more work>
+ * dev_put(adapter->dev)
+ * }
+ */
+#define hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) \
+ for (__hdd_take_ref_and_fetch_front_adapter_safe(hdd_ctx, adapter, \
+ next_adapter); \
__hdd_is_adapter_valid(adapter); \
- __hdd_take_ref_and_fetch_next_adapter(hdd_ctx, adapter))
+ __hdd_take_ref_and_fetch_next_adapter_safe(hdd_ctx, adapter, \
+ next_adapter))
/**
* wlan_hdd_get_adapter_by_vdev_id_from_objmgr() - Fetch adapter from objmgr
diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c
index 2badd954e6..918c381afe 100644
--- a/core/hdd/src/wlan_hdd_assoc.c
+++ b/core/hdd/src/wlan_hdd_assoc.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@@ -380,7 +381,7 @@ hdd_conn_get_connected_cipher_algo(struct hdd_station_ctx *sta_ctx,
struct hdd_adapter *hdd_get_sta_connection_in_progress(
struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter = NULL;
+ struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
struct hdd_station_ctx *hdd_sta_ctx;
if (!hdd_ctx) {
@@ -388,7 +389,7 @@ struct hdd_adapter *hdd_get_sta_connection_in_progress(
return NULL;
}
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
if ((QDF_STA_MODE == adapter->device_mode) ||
(QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
@@ -397,6 +398,9 @@ struct hdd_adapter *hdd_get_sta_connection_in_progress(
hdd_sta_ctx->conn_info.conn_state) {
hdd_debug("vdev_id %d: Connection is in progress",
adapter->vdev_id);
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return adapter;
} else if ((eConnectionState_Associated ==
hdd_sta_ctx->conn_info.conn_state) &&
@@ -405,9 +409,13 @@ struct hdd_adapter *hdd_get_sta_connection_in_progress(
adapter->vdev_id)) {
hdd_debug("vdev_id %d: Key exchange is in progress",
adapter->vdev_id);
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return adapter;
}
}
+ dev_put(adapter->dev);
}
return NULL;
}
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index 64a766dc21..40ed3d0c01 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@@ -5153,11 +5154,11 @@ wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
static bool wlan_hdd_check_dfs_channel_for_adapter(struct hdd_context *hdd_ctx,
enum QDF_OPMODE device_mode)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
struct hdd_ap_ctx *ap_ctx;
struct hdd_station_ctx *sta_ctx;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if ((device_mode == adapter->device_mode) &&
(device_mode == QDF_SAP_MODE)) {
ap_ctx =
@@ -5174,6 +5175,9 @@ static bool wlan_hdd_check_dfs_channel_for_adapter(struct hdd_context *hdd_ctx,
hdd_ctx->pdev,
ap_ctx->operating_channel)) {
hdd_err("SAP running on DFS channel");
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return true;
}
}
@@ -5192,9 +5196,13 @@ static bool wlan_hdd_check_dfs_channel_for_adapter(struct hdd_context *hdd_ctx,
wlan_reg_get_channel_state(hdd_ctx->pdev,
sta_ctx->conn_info.channel))) {
hdd_err("client connected on DFS channel");
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return true;
}
}
+ dev_put(adapter->dev);
}
return false;
@@ -10272,13 +10280,15 @@ static enum sta_roam_policy_dfs_mode wlan_hdd_get_sta_roam_dfs_mode(
*/
uint8_t hdd_get_sap_operating_band(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
uint8_t operating_channel = 0;
uint8_t sap_operating_band = 0;
- hdd_for_each_adapter(hdd_ctx, adapter) {
- if (adapter->device_mode != QDF_SAP_MODE)
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
+ if (adapter->device_mode != QDF_SAP_MODE) {
+ dev_put(adapter->dev);
continue;
+ }
operating_channel = adapter->session.ap.operating_channel;
if (IS_24G_CH(operating_channel))
@@ -10287,6 +10297,8 @@ uint8_t hdd_get_sap_operating_band(struct hdd_context *hdd_ctx)
sap_operating_band = BAND_5G;
else
sap_operating_band = BAND_ALL;
+
+ dev_put(adapter->dev);
}
return sap_operating_band;
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index 8842534120..173833cf8c 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@@ -2861,7 +2862,7 @@ static int hdd_softap_unpack_ie(mac_handle_t mac_handle,
*/
static bool hdd_is_any_sta_connecting(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter = NULL;
+ struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
struct hdd_station_ctx *sta_ctx;
if (!hdd_ctx) {
@@ -2869,7 +2870,7 @@ static bool hdd_is_any_sta_connecting(struct hdd_context *hdd_ctx)
return false;
}
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
if ((adapter->device_mode == QDF_STA_MODE) ||
(adapter->device_mode == QDF_P2P_CLIENT_MODE) ||
@@ -2878,9 +2879,13 @@ static bool hdd_is_any_sta_connecting(struct hdd_context *hdd_ctx)
eConnectionState_Connecting) {
hdd_debug("vdev_id %d: connecting",
adapter->vdev_id);
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return true;
}
}
+ dev_put(adapter->dev);
}
return false;
@@ -3327,7 +3332,7 @@ bool hdd_sap_destroy_ctx(struct hdd_adapter *adapter)
void hdd_sap_destroy_ctx_all(struct hdd_context *hdd_ctx, bool is_ssr)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
/* sap_ctx is not destroyed as it will be leveraged for sap restart */
if (is_ssr)
@@ -3335,9 +3340,10 @@ void hdd_sap_destroy_ctx_all(struct hdd_context *hdd_ctx, bool is_ssr)
hdd_debug("destroying all the sap context");
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (adapter->device_mode == QDF_SAP_MODE)
hdd_sap_destroy_ctx(adapter);
+ dev_put(adapter->dev);
}
}
diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c
index 702c15bf67..62ffd93432 100644
--- a/core/hdd/src/wlan_hdd_ioctl.c
+++ b/core/hdd/src/wlan_hdd_ioctl.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@@ -6002,6 +6003,7 @@ static int drv_cmd_max_tx_power(struct hdd_adapter *adapter,
uint8_t *value = command;
struct qdf_mac_addr bssid = QDF_MAC_ADDR_BCAST_INIT;
struct qdf_mac_addr selfmac = QDF_MAC_ADDR_BCAST_INIT;
+ struct hdd_adapter *next_adapter = NULL;
ret = hdd_parse_setmaxtxpower_command(value, &tx_power);
if (ret) {
@@ -6009,7 +6011,7 @@ static int drv_cmd_max_tx_power(struct hdd_adapter *adapter,
return ret;
}
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
/* Assign correct self MAC address */
qdf_copy_macaddr(&bssid,
&adapter->mac_addr);
@@ -6027,9 +6029,13 @@ static int drv_cmd_max_tx_power(struct hdd_adapter *adapter,
if (QDF_STATUS_SUCCESS != status) {
hdd_err("Set max tx power failed");
ret = -EINVAL;
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
goto exit;
}
hdd_debug("Set max tx power success");
+ dev_put(adapter->dev);
}
exit:
diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c
index c121e5fdfe..e76fa222f4 100644
--- a/core/hdd/src/wlan_hdd_ipa.c
+++ b/core/hdd/src/wlan_hdd_ipa.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@@ -33,7 +34,7 @@
void hdd_ipa_set_tx_flow_info(void)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
struct hdd_station_ctx *sta_ctx;
struct hdd_ap_ctx *hdd_ap_ctx;
struct hdd_hostapd_state *hostapd_state;
@@ -70,7 +71,7 @@ void hdd_ipa_set_tx_flow_info(void)
psoc = hdd_ctx->psoc;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
switch (adapter->device_mode) {
case QDF_STA_MODE:
sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
@@ -202,6 +203,7 @@ void hdd_ipa_set_tx_flow_info(void)
if (!preAdapterContext) {
hdd_err("SCC: Previous adapter context NULL");
+ dev_put(adapter->dev);
continue;
}
@@ -250,6 +252,7 @@ void hdd_ipa_set_tx_flow_info(void)
if (!adapter5) {
hdd_err("MCC: 5GHz adapter context NULL");
+ dev_put(adapter->dev);
continue;
}
adapter5->tx_flow_low_watermark =
@@ -278,6 +281,7 @@ void hdd_ipa_set_tx_flow_info(void)
if (!adapter2_4) {
hdd_err("MCC: 2.4GHz adapter context NULL");
+ dev_put(adapter->dev);
continue;
}
adapter2_4->tx_flow_low_watermark =
@@ -310,6 +314,7 @@ void hdd_ipa_set_tx_flow_info(void)
}
targetChannel = 0;
#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+ dev_put(adapter->dev);
}
}
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index f1c5c0bcd6..bf44251b73 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@@ -370,10 +371,12 @@ void hdd_start_complete(int ret)
*/
static void hdd_set_rps_cpu_mask(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
- hdd_for_each_adapter(hdd_ctx, adapter)
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
hdd_send_rps_ind(adapter);
+ dev_put(adapter->dev);
+ }
}
#ifdef QCA_HL_NETDEV_FLOW_CONTROL
@@ -2281,7 +2284,7 @@ exit:
bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
struct hdd_ap_ctx *ap_ctx;
bool dfs_disable_channel_switch = false;
@@ -2298,7 +2301,7 @@ bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx)
return true;
}
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
if ((QDF_SAP_MODE == adapter->device_mode ||
@@ -2314,6 +2317,7 @@ bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx)
cds_get_context(QDF_MODULE_ID_SOC),
adapter->txrx_vdev);
}
+ dev_put(adapter->dev);
}
return true;
@@ -2968,14 +2972,20 @@ int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate)
*/
static bool hdd_wapi_security_sta_exist(void)
{
- struct hdd_adapter *adapter = NULL;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if ((adapter->device_mode == QDF_STA_MODE) &&
adapter->wapi_info.wapi_mode &&
- (adapter->wapi_info.wapi_auth_mode != WAPI_AUTH_MODE_OPEN))
+ (adapter->wapi_info.wapi_auth_mode !=
+ WAPI_AUTH_MODE_OPEN)) {
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return true;
+ }
+ dev_put(adapter->dev);
}
return false;
}
@@ -3012,17 +3022,21 @@ static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev(
*/
static bool hdd_is_chan_switch_in_progress(void)
{
- struct hdd_adapter *adapter = NULL;
+ struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if ((adapter->device_mode == QDF_SAP_MODE ||
adapter->device_mode == QDF_P2P_GO_MODE) &&
qdf_atomic_read(&adapter->ch_switch_in_progress)) {
hdd_debug("channel switch progress for vdev_id %d",
adapter->vdev_id);
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return true;
}
+ dev_put(adapter->dev);
}
return false;
@@ -5325,13 +5339,17 @@ static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx,
static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx,
tSirMacAddr mac_addr)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (!qdf_mem_cmp(adapter->mac_addr.bytes,
mac_addr, sizeof(tSirMacAddr))) {
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return QDF_STATUS_E_FAILURE;
}
+ dev_put(adapter->dev);
}
return QDF_STATUS_SUCCESS;
@@ -6568,27 +6586,31 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
*/
void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
hdd_enter();
- hdd_for_each_adapter(hdd_ctx, adapter)
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
+ dev_put(adapter->dev);
+ }
hdd_exit();
}
QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
hdd_enter();
if (hdd_ctx->sap_pre_cac_work.fn)
cds_flush_work(&hdd_ctx->sap_pre_cac_work);
- hdd_for_each_adapter(hdd_ctx, adapter)
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
hdd_stop_adapter(hdd_ctx, adapter);
+ dev_put(adapter->dev);
+ }
hdd_exit();
@@ -6652,7 +6674,7 @@ static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter)
QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
struct hdd_station_ctx *sta_ctx;
struct qdf_mac_addr peer_macaddr;
bool value;
@@ -6664,7 +6686,7 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
if (hdd_ctx->sap_pre_cac_work.fn)
cds_flush_work(&hdd_ctx->sap_pre_cac_work);
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
hdd_info("[SSR] reset adapter with device mode %s(%d)",
qdf_opmode_str(adapter->device_mode),
adapter->device_mode);
@@ -6770,6 +6792,7 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
/* Destroy vdev which will be recreated during reinit. */
hdd_vdev_destroy(adapter);
+ dev_put(adapter->dev);
}
hdd_exit();
@@ -6779,17 +6802,22 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
hdd_info("FTM mode, don't close the module");
return true;
}
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) ||
- test_bit(SME_SESSION_OPENED, &adapter->event_flags))
+ test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return true;
+ }
+ dev_put(adapter->dev);
}
return false;
@@ -7483,16 +7511,18 @@ static void hdd_delete_sta(struct hdd_adapter *adapter)
QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
eConnectionState conn_state;
bool value;
hdd_enter();
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (!hdd_is_interface_up(adapter) &&
- adapter->device_mode != QDF_NDI_MODE)
+ adapter->device_mode != QDF_NDI_MODE) {
+ dev_put(adapter->dev);
continue;
+ }
hdd_debug("[SSR] start adapter with device mode %s(%d)",
qdf_opmode_str(adapter->device_mode),
@@ -7603,14 +7633,19 @@ QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx)
* applicable to all interfaces
*/
wlan_hdd_cfg80211_register_frames(adapter);
+ dev_put(adapter->dev);
}
- hdd_for_each_adapter(hdd_ctx, adapter) {
- if (!hdd_is_interface_up(adapter))
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
+ if (!hdd_is_interface_up(adapter)) {
+ dev_put(adapter->dev);
continue;
+ }
if (adapter->device_mode == QDF_P2P_GO_MODE)
hdd_stop_p2p_go(adapter);
+
+ dev_put(adapter->dev);
}
hdd_exit();
@@ -7805,15 +7840,19 @@ QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb, void *context)
struct hdd_adapter *hdd_get_adapter_by_rand_macaddr(
struct hdd_context *hdd_ctx, tSirMacAddr mac_addr)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if ((adapter->device_mode == QDF_STA_MODE ||
adapter->device_mode == QDF_P2P_CLIENT_MODE ||
adapter->device_mode == QDF_P2P_DEVICE_MODE) &&
ucfg_p2p_check_random_mac(hdd_ctx->psoc,
- adapter->vdev_id, mac_addr))
+ adapter->vdev_id, mac_addr)) {
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return adapter;
+ }
}
return NULL;
@@ -7822,12 +7861,17 @@ struct hdd_adapter *hdd_get_adapter_by_rand_macaddr(
struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
tSirMacAddr mac_addr)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (!qdf_mem_cmp(adapter->mac_addr.bytes,
- mac_addr, sizeof(tSirMacAddr)))
+ mac_addr, sizeof(tSirMacAddr))) {
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return adapter;
+ }
+ dev_put(adapter->dev);
}
return NULL;
@@ -7836,11 +7880,16 @@ struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx,
uint32_t vdev_id)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
- hdd_for_each_adapter(hdd_ctx, adapter) {
- if (adapter->vdev_id == vdev_id)
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
+ if (adapter->vdev_id == vdev_id) {
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return adapter;
+ }
+ dev_put(adapter->dev);
}
return NULL;
@@ -7849,13 +7898,17 @@ struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx,
struct hdd_adapter *hdd_adapter_get_by_reference(struct hdd_context *hdd_ctx,
struct hdd_adapter *reference)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (adapter == reference) {
dev_hold(adapter->dev);
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
break;
}
+ dev_put(adapter->dev);
}
return adapter;
@@ -7869,11 +7922,16 @@ void hdd_adapter_put(struct hdd_adapter *adapter)
struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
const char *iface_name)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
- hdd_for_each_adapter(hdd_ctx, adapter) {
- if (!qdf_str_cmp(adapter->dev->name, iface_name))
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
+ if (!qdf_str_cmp(adapter->dev->name, iface_name)) {
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return adapter;
+ }
+ dev_put(adapter->dev);
}
return NULL;
@@ -7892,11 +7950,16 @@ struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx,
enum QDF_OPMODE mode)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
- hdd_for_each_adapter(hdd_ctx, adapter) {
- if (adapter->device_mode == mode)
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
+ if (adapter->device_mode == mode) {
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return adapter;
+ }
+ dev_put(adapter->dev);
}
return NULL;
@@ -7940,10 +8003,10 @@ enum QDF_OPMODE hdd_get_device_mode(uint32_t vdev_id)
uint8_t hdd_get_operating_channel(struct hdd_context *hdd_ctx,
enum QDF_OPMODE mode)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
uint8_t operatingChannel = 0;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (mode == adapter->device_mode) {
switch (adapter->device_mode) {
case QDF_STA_MODE:
@@ -7970,10 +8033,13 @@ uint8_t hdd_get_operating_channel(struct hdd_context *hdd_ctx,
default:
break;
}
-
/* Found the device of interest. break the loop */
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
break;
}
+ dev_put(adapter->dev);
}
return operatingChannel;
@@ -7982,11 +8048,11 @@ uint8_t hdd_get_operating_channel(struct hdd_context *hdd_ctx,
static inline QDF_STATUS hdd_unregister_wext_all_adapters(struct hdd_context *
hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
hdd_enter();
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (adapter->device_mode == QDF_STA_MODE ||
adapter->device_mode == QDF_P2P_CLIENT_MODE ||
adapter->device_mode == QDF_IBSS_MODE ||
@@ -7995,6 +8061,7 @@ static inline QDF_STATUS hdd_unregister_wext_all_adapters(struct hdd_context *
adapter->device_mode == QDF_P2P_GO_MODE) {
hdd_unregister_wext(adapter->dev);
}
+ dev_put(adapter->dev);
}
hdd_exit();
@@ -8004,11 +8071,11 @@ static inline QDF_STATUS hdd_unregister_wext_all_adapters(struct hdd_context *
QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
hdd_enter();
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (adapter->device_mode == QDF_STA_MODE ||
adapter->device_mode == QDF_P2P_CLIENT_MODE ||
adapter->device_mode == QDF_IBSS_MODE ||
@@ -8019,6 +8086,7 @@ QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx)
adapter->vdev_id, INVALID_SCAN_ID,
true);
}
+ dev_put(adapter->dev);
}
hdd_exit();
@@ -8035,11 +8103,10 @@ QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx)
*/
static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
int err;
-
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (adapter->device_mode == QDF_STA_MODE ||
adapter->device_mode == QDF_P2P_CLIENT_MODE ||
adapter->device_mode == QDF_IBSS_MODE ||
@@ -8050,6 +8117,7 @@ static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx)
if (err)
hdd_err("Unable to stop scheduled scan");
}
+ dev_put(adapter->dev);
}
hdd_exit();
@@ -8401,11 +8469,16 @@ QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx)
struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
- hdd_for_each_adapter(hdd_ctx, adapter) {
- if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC)
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
+ if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC) {
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return adapter;
+ }
+ dev_put(adapter->dev);
}
return NULL;
@@ -8600,10 +8673,12 @@ static void hdd_display_periodic_stats(struct hdd_context *hdd_ctx,
*/
static void hdd_clear_rps_cpu_mask(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
- hdd_for_each_adapter(hdd_ctx, adapter)
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
hdd_send_rps_disable_ind(adapter);
+ dev_put(adapter->dev);
+ }
}
#ifdef CLD_PM_QOS
@@ -9006,7 +9081,8 @@ static void hdd_ipa_set_perf_level(struct hdd_context *hdd_ctx,
#define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter = NULL, *con_sap_adapter = NULL;
+ struct hdd_adapter *adapter = NULL, *next_adapter = NULL,
+ *con_sap_adapter = NULL;
uint64_t tx_packets = 0, rx_packets = 0;
uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0;
uint64_t fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0;
@@ -9022,19 +9098,22 @@ static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx)
if (hdd_ctx->is_wiphy_suspended)
return;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
/*
* Validate magic so we don't end up accessing
* an invalid adapter.
*/
- if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)
+ if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
+ dev_put(adapter->dev);
continue;
+ }
if ((adapter->device_mode == QDF_STA_MODE ||
adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.conn_state
!= eConnectionState_Associated) {
+ dev_put(adapter->dev);
continue;
}
@@ -9042,6 +9121,7 @@ static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx)
adapter->device_mode == QDF_P2P_GO_MODE) &&
WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active == false) {
+ dev_put(adapter->dev);
continue;
}
@@ -9087,6 +9167,7 @@ static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx)
adapter->prev_fwd_rx_packets = fwd_rx_packets;
qdf_spin_unlock_bh(&hdd_ctx->bus_bw_lock);
connected = true;
+ dev_put(adapter->dev);
}
if (!connected) {
@@ -9270,7 +9351,7 @@ hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx)
char temp_str[20 * WLAN_REASON_TYPE_MAX];
char *comb_log_str;
uint32_t comb_log_str_size;
- struct hdd_adapter *adapter = NULL;
+ struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * WLAN_MAX_VDEVS) + 1;
comb_log_str = qdf_mem_malloc(comb_log_str_size);
@@ -9279,7 +9360,7 @@ hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx)
bytes_written = 0;
- hdd_for_each_adapter_dev_held(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
curr_time = qdf_system_ticks();
total = curr_time - adapter->start_time;
delta = curr_time - adapter->last_time;
@@ -9438,14 +9519,14 @@ void
wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx,
enum qdf_stats_verbosity_level verb_lvl)
{
- struct hdd_adapter *adapter = NULL;
+ struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) {
hdd_display_netif_queue_history_compact(hdd_ctx);
return;
}
- hdd_for_each_adapter_dev_held(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (adapter->vdev_id == CDP_INVALID_VDEV_ID) {
dev_put(adapter->dev);
continue;
@@ -9464,9 +9545,9 @@ wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx,
*/
void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter = NULL;
+ struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
qdf_mem_zero(adapter->queue_oper_stats,
sizeof(adapter->queue_oper_stats));
qdf_mem_zero(adapter->queue_oper_history,
@@ -9475,6 +9556,7 @@ void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx)
adapter->start_time = adapter->last_time = qdf_system_ticks();
adapter->total_pause_time = 0;
adapter->total_unpause_time = 0;
+ dev_put(adapter->dev);
}
}
@@ -9722,7 +9804,7 @@ hdd_store_sap_restart_channel(uint8_t restart_chan, uint8_t *restart_chan_store)
*/
void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
uint32_t i;
bool found = false;
uint8_t restart_chan_store[SAP_MAX_NUM_SESSION] = {0};
@@ -9734,13 +9816,13 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt)
bool is_vendor_acs_support =
cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION);
- hdd_for_each_adapter(hdd_ctxt, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctxt, adapter, next_adapter) {
if (!(adapter->device_mode == QDF_SAP_MODE &&
adapter->session.ap.sap_config.acs_cfg.acs_mode)) {
- hdd_debug("skip device mode:%d acs:%d",
- adapter->device_mode,
- adapter->session.ap.sap_config.
- acs_cfg.acs_mode);
+ hdd_debug_rl("skip device mode:%d acs:%d",
+ adapter->device_mode,
+ adapter->session.ap.sap_config.acs_cfg.acs_mode);
+ dev_put(adapter->dev);
continue;
}
@@ -9779,6 +9861,7 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt)
restart_chan_store);
hdd_debug("ch:%d is safe. no need to change channel",
adapter->session.ap.operating_channel);
+ dev_put(adapter->dev);
continue;
}
@@ -9797,6 +9880,7 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt)
if (is_vendor_acs_support && is_acs_support_for_dfs_ltecoex) {
hdd_update_acs_timer_reason(adapter,
QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX);
+ dev_put(adapter->dev);
continue;
}
@@ -9838,6 +9922,9 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt)
CSA_REASON_UNSAFE_CHANNEL);
hdd_switch_sap_channel(adapter, restart_chan,
true);
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return;
}
else {
@@ -9845,9 +9932,14 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt)
wlan_hdd_send_svc_nlink_msg(
hdd_ctxt->radio_index,
WLAN_SVC_LTE_COEX_IND, NULL, 0);
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return;
}
}
+ /* dev_put has to be done here */
+ dev_put(adapter->dev);
}
}
@@ -10014,7 +10106,7 @@ wlan_hdd_get_adapter_by_vdev_id_from_objmgr(struct hdd_context *hdd_ctx,
void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
{
struct hdd_context *hdd_ctx = NULL;
- struct hdd_adapter *adapter = NULL;
+ struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
int i, num_adapters;
uint8_t vdev_id[WLAN_MAX_VDEVS];
struct ieee80211_mgmt *mgmt =
@@ -10040,7 +10132,8 @@ void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
}
} else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) {
num_adapters = 0;
- hdd_for_each_adapter_dev_held(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter,
+ next_adapter) {
vdev_id[num_adapters] = adapter->vdev_id;
num_adapters++;
/* dev_put has to be done here */
@@ -12769,7 +12862,7 @@ static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
{
struct hdd_context *hdd_ctx;
struct hdd_station_ctx *hdd_sta_ctx;
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
uint16_t len = 0;
char *buf = *buf_ptr;
@@ -12787,7 +12880,7 @@ static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
"\n is_scheduler_suspended %d",
hdd_ctx->is_scheduler_suspended);
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (adapter->dev)
len += scnprintf(buf + len, *size - len,
"\n device name: %s", adapter->dev->name);
@@ -12805,6 +12898,7 @@ static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
default:
break;
}
+ dev_put(adapter->dev);
}
*size -= len;
@@ -13606,14 +13700,14 @@ void wlan_hdd_disable_roaming(struct hdd_adapter *cur_adapter,
uint32_t mlme_operation_requestor)
{
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_adapter);
- struct hdd_adapter *adapter = NULL;
+ struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
struct csr_roam_profile *roam_profile;
struct hdd_station_ctx *sta_ctx;
if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc))
return;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
roam_profile = hdd_roam_profile(adapter);
sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
@@ -13626,6 +13720,7 @@ void wlan_hdd_disable_roaming(struct hdd_adapter *cur_adapter,
REASON_DRIVER_DISABLED,
mlme_operation_requestor);
}
+ dev_put(adapter->dev);
}
}
@@ -13633,14 +13728,14 @@ void wlan_hdd_enable_roaming(struct hdd_adapter *cur_adapter,
uint32_t mlme_operation_requestor)
{
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_adapter);
- struct hdd_adapter *adapter = NULL;
+ struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
struct csr_roam_profile *roam_profile;
struct hdd_station_ctx *sta_ctx;
if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc))
return;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
roam_profile = hdd_roam_profile(adapter);
sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
@@ -13653,6 +13748,7 @@ void wlan_hdd_enable_roaming(struct hdd_adapter *cur_adapter,
REASON_DRIVER_ENABLED,
mlme_operation_requestor);
}
+ dev_put(adapter->dev);
}
}
@@ -13774,7 +13870,7 @@ void wlan_hdd_auto_shutdown_cb(void)
void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
bool ap_connected = false, sta_connected = false;
mac_handle_t mac_handle;
@@ -13797,12 +13893,16 @@ void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable)
/* To enable shutdown timer check conncurrency */
if (policy_mgr_concurrent_open_sessions_running(hdd_ctx->psoc)) {
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter,
+ next_adapter) {
if (adapter->device_mode == QDF_STA_MODE) {
if (WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
conn_info.conn_state ==
eConnectionState_Associated) {
sta_connected = true;
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
break;
}
}
@@ -13811,9 +13911,13 @@ void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable)
if (WLAN_HDD_GET_AP_CTX_PTR(adapter)->
ap_active == true) {
ap_connected = true;
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
break;
}
}
+ dev_put(adapter->dev);
}
}
@@ -13837,11 +13941,11 @@ hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter,
bool check_start_bss)
{
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
- struct hdd_adapter *adapter, *con_sap_adapter;
+ struct hdd_adapter *adapter, *con_sap_adapter, *next_adapter = NULL;
con_sap_adapter = NULL;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (adapter && ((adapter->device_mode == QDF_SAP_MODE) ||
(adapter->device_mode == QDF_P2P_GO_MODE)) &&
adapter != this_sap_adapter) {
@@ -13849,13 +13953,20 @@ hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter,
if (test_bit(SOFTAP_BSS_STARTED,
&adapter->event_flags)) {
con_sap_adapter = adapter;
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
break;
}
} else {
con_sap_adapter = adapter;
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
break;
}
}
+ dev_put(adapter->dev);
}
return con_sap_adapter;
@@ -13876,24 +13987,35 @@ static inline bool hdd_adapter_is_ap(struct hdd_adapter *adapter)
static bool hdd_any_adapter_is_assoc(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (hdd_adapter_is_sta(adapter) &&
WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
conn_info.conn_state == eConnectionState_Associated) {
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return true;
}
if (hdd_adapter_is_ap(adapter) &&
WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active) {
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return true;
}
if (adapter->device_mode == QDF_NDI_MODE &&
WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
- conn_info.conn_state == eConnectionState_NdiConnected)
+ conn_info.conn_state == eConnectionState_NdiConnected) {
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return true;
+ }
+ dev_put(adapter->dev);
}
return false;
diff --git a/core/hdd/src/wlan_hdd_nan_datapath.c b/core/hdd/src/wlan_hdd_nan_datapath.c
index bb17165435..7b532400a8 100644
--- a/core/hdd/src/wlan_hdd_nan_datapath.c
+++ b/core/hdd/src/wlan_hdd_nan_datapath.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@@ -120,27 +121,36 @@ static int hdd_close_ndi(struct hdd_adapter *adapter)
*/
static bool hdd_is_ndp_allowed(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
struct hdd_station_ctx *sta_ctx;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
switch (adapter->device_mode) {
case QDF_P2P_GO_MODE:
case QDF_SAP_MODE:
if (test_bit(SOFTAP_BSS_STARTED,
- &adapter->event_flags))
+ &adapter->event_flags)) {
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return false;
+ }
break;
case QDF_P2P_CLIENT_MODE:
case QDF_IBSS_MODE:
sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
if (hdd_conn_is_connected(sta_ctx) ||
- hdd_is_connecting(sta_ctx))
+ hdd_is_connecting(sta_ctx)) {
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return false;
+ }
break;
default:
break;
}
+ dev_put(adapter->dev);
}
return true;
@@ -491,7 +501,7 @@ error_init_txrx:
int hdd_ndi_open(char *iface_name)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
struct qdf_mac_addr random_ndi_mac;
struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
uint8_t ndi_adapter_count = 0;
@@ -503,9 +513,10 @@ int hdd_ndi_open(char *iface_name)
return -EINVAL;
}
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (WLAN_HDD_IS_NDI(adapter))
ndi_adapter_count++;
+ dev_put(adapter->dev);
}
if (ndi_adapter_count >= MAX_NDI_ADAPTERS) {
hdd_err("Can't allow more than %d NDI adapters",
diff --git a/core/hdd/src/wlan_hdd_oemdata.c b/core/hdd/src/wlan_hdd_oemdata.c
index d23a256a84..76597c4f05 100644
--- a/core/hdd/src/wlan_hdd_oemdata.c
+++ b/core/hdd/src/wlan_hdd_oemdata.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@@ -186,7 +187,7 @@ static void send_oem_reg_rsp_nlink_msg(void)
uint8_t *num_interfaces;
uint8_t *device_mode;
uint8_t *vdev_id;
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
/* OEM msg is always to a specific process & cannot be a broadcast */
if (p_hdd_ctx->oem_pid == 0) {
@@ -217,7 +218,7 @@ static void send_oem_reg_rsp_nlink_msg(void)
*num_interfaces = 0;
/* Iterate through each adapter and fill device mode and vdev id */
- hdd_for_each_adapter(p_hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(p_hdd_ctx, adapter, next_adapter) {
device_mode = buf++;
vdev_id = buf++;
*device_mode = adapter->device_mode;
@@ -226,6 +227,7 @@ static void send_oem_reg_rsp_nlink_msg(void)
hdd_debug("num_interfaces: %d, device_mode: %d, vdev_id: %d",
*num_interfaces, *device_mode,
*vdev_id);
+ dev_put(adapter->dev);
}
ani_hdr->length =
diff --git a/core/hdd/src/wlan_hdd_periodic_sta_stats.c b/core/hdd/src/wlan_hdd_periodic_sta_stats.c
index 1627f8528a..11a66f05ce 100644
--- a/core/hdd/src/wlan_hdd_periodic_sta_stats.c
+++ b/core/hdd/src/wlan_hdd_periodic_sta_stats.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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 above
@@ -41,7 +42,7 @@ void hdd_periodic_sta_stats_init(struct hdd_adapter *adapter)
void hdd_periodic_sta_stats_display(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
struct hdd_stats sta_stats;
struct hdd_config *hdd_cfg;
char *dev_name;
@@ -50,17 +51,20 @@ void hdd_periodic_sta_stats_display(struct hdd_context *hdd_ctx)
if (!hdd_ctx)
return;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
should_log = false;
- if (adapter->device_mode != QDF_STA_MODE)
+ if (adapter->device_mode != QDF_STA_MODE) {
+ dev_put(adapter->dev);
continue;
+ }
hdd_cfg = hdd_ctx->config;
qdf_mutex_acquire(&adapter->sta_periodic_stats_lock);
if (!adapter->is_sta_periodic_stats_enabled) {
qdf_mutex_release(&adapter->sta_periodic_stats_lock);
+ dev_put(adapter->dev);
continue;
}
@@ -89,6 +93,7 @@ void hdd_periodic_sta_stats_display(struct hdd_context *hdd_ctx)
hdd_nofl_info("%s: Rx DNS responses: %d", dev_name,
sta_stats.hdd_dns_stats.rx_dns_rsp_count);
}
+ dev_put(adapter->dev);
}
}
diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c
index 1cd8fb24ad..c271246fa5 100644
--- a/core/hdd/src/wlan_hdd_power.c
+++ b/core/hdd/src/wlan_hdd_power.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@@ -1163,7 +1164,7 @@ hdd_suspend_wlan(void)
{
struct hdd_context *hdd_ctx;
QDF_STATUS status;
- struct hdd_adapter *adapter = NULL;
+ struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
uint32_t conn_state_mask = 0;
hdd_info("WLAN being suspended by OS");
@@ -1180,9 +1181,11 @@ hdd_suspend_wlan(void)
return -EINVAL;
}
- hdd_for_each_adapter(hdd_ctx, adapter) {
- if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
+ if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) {
+ dev_put(adapter->dev);
continue;
+ }
/* stop all TX queues before suspend */
hdd_debug("Disabling queues for dev mode %s",
@@ -1197,6 +1200,7 @@ hdd_suspend_wlan(void)
/* Configure supported OffLoads */
hdd_enable_host_offloads(adapter, pmo_apps_suspend);
hdd_update_conn_state_mask(adapter, &conn_state_mask);
+ dev_put(adapter->dev);
}
status = ucfg_pmo_psoc_user_space_suspend_req(hdd_ctx->psoc,
@@ -1221,7 +1225,7 @@ hdd_suspend_wlan(void)
static int hdd_resume_wlan(void)
{
struct hdd_context *hdd_ctx;
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
QDF_STATUS status;
hdd_info("WLAN being resumed by OS");
@@ -1242,9 +1246,11 @@ static int hdd_resume_wlan(void)
hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_RESUME);
/*loop through all adapters. Concurrency */
- hdd_for_each_adapter(hdd_ctx, adapter) {
- if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
+ if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) {
+ dev_put(adapter->dev);
continue;
+ }
/* Disable supported OffLoads */
hdd_disable_host_offloads(adapter, pmo_apps_resume);
@@ -1258,6 +1264,8 @@ static int hdd_resume_wlan(void)
if (adapter->device_mode == QDF_STA_MODE)
status = hdd_disable_default_pkt_filters(adapter);
+
+ dev_put(adapter->dev);
}
ucfg_ipa_resume(hdd_ctx->pdev);
@@ -1290,17 +1298,18 @@ void hdd_svc_fw_shutdown_ind(struct device *dev)
*/
static void hdd_ssr_restart_sap(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
hdd_enter();
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (adapter->device_mode == QDF_SAP_MODE) {
if (test_bit(SOFTAP_INIT_DONE, &adapter->event_flags)) {
hdd_debug("Restart prev SAP session");
wlan_hdd_start_sap(adapter, true);
}
}
+ dev_put(adapter->dev);
}
hdd_exit();
@@ -1416,9 +1425,9 @@ static inline void hdd_wlan_ssr_reinit_event(void)
*/
static void hdd_send_default_scan_ies(struct hdd_context *hdd_ctx)
{
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
if (hdd_is_interface_up(adapter) &&
(adapter->device_mode == QDF_STA_MODE ||
adapter->device_mode == QDF_P2P_DEVICE_MODE) &&
@@ -1428,6 +1437,7 @@ static void hdd_send_default_scan_ies(struct hdd_context *hdd_ctx)
adapter->scan_info.default_scan_ies,
adapter->scan_info.default_scan_ies_len);
}
+ dev_put(adapter->dev);
}
}
@@ -1833,7 +1843,7 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
struct cfg80211_wowlan *wow)
{
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
- struct hdd_adapter *adapter;
+ struct hdd_adapter *adapter, *next_adapter = NULL;
mac_handle_t mac_handle;
int rc;
@@ -1866,9 +1876,11 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
* "dfs_cac_block_tx" is set to true when RADAR is found and stay true
* until CAC is done for a SoftAP which is in started state.
*/
- hdd_for_each_adapter(hdd_ctx, adapter) {
- if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
+ if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) {
+ dev_put(adapter->dev);
continue;
+ }
if (QDF_SAP_MODE == adapter->device_mode) {
if (BSS_START ==
@@ -1879,6 +1891,9 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
hdd_err("RADAR detection in progress, do not allow suspend");
wlan_hdd_inc_suspend_stats(hdd_ctx,
SUSPEND_FAIL_RADAR);
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return -EAGAIN;
} else if (!ucfg_pmo_get_enable_sap_suspend(
hdd_ctx->psoc)) {
@@ -1886,6 +1901,9 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
* suspend
*/
hdd_err("SAP does not support suspend!!");
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return -EOPNOTSUPP;
}
} else if (QDF_P2P_GO_MODE == adapter->device_mode) {
@@ -1895,9 +1913,13 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
* suspend
*/
hdd_err("GO does not support suspend!!");
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return -EOPNOTSUPP;
}
}
+ dev_put(adapter->dev);
}
/* p2p cleanup task based on scheduler */
ucfg_p2p_cleanup_tx_by_psoc(hdd_ctx->psoc);
@@ -1909,11 +1931,14 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
}
/* flush any pending powersave timers */
- hdd_for_each_adapter(hdd_ctx, adapter) {
- if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
+ if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) {
+ dev_put(adapter->dev);
continue;
+ }
sme_ps_timer_flush_sync(mac_handle, adapter->vdev_id);
+ dev_put(adapter->dev);
}
/*
diff --git a/core/hdd/src/wlan_hdd_regulatory.c b/core/hdd/src/wlan_hdd_regulatory.c
index c18c49ff98..ef87381db6 100644
--- a/core/hdd/src/wlan_hdd_regulatory.c
+++ b/core/hdd/src/wlan_hdd_regulatory.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2014-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@@ -749,6 +750,7 @@ int hdd_reg_set_country(struct hdd_context *hdd_ctx, char *country_code)
int hdd_reg_set_band(struct net_device *dev, u8 ui_band)
{
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ struct hdd_adapter *next_adapter = NULL;
mac_handle_t mac_handle;
enum band_info band;
QDF_STATUS status;
@@ -813,7 +815,7 @@ int hdd_reg_set_band(struct net_device *dev, u8 ui_band)
current_band, band);
mac_handle = hdd_ctx->mac_handle;
- hdd_for_each_adapter(hdd_ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
adapter->vdev_id, INVALID_SCAN_ID, false);
connected_band = hdd_conn_get_connected_band(
@@ -843,10 +845,14 @@ int hdd_reg_set_band(struct net_device *dev, u8 ui_band)
if (status) {
hdd_err("Hdd disconnect failed, status: %d",
status);
+ dev_put(adapter->dev);
+ if (next_adapter)
+ dev_put(next_adapter->dev);
return -EINVAL;
}
}
ucfg_scan_flush_results(hdd_ctx->pdev, NULL);
+ dev_put(adapter->dev);
}
if (QDF_IS_STATUS_ERROR(ucfg_reg_set_band(hdd_ctx->pdev, band))) {
diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c
index e09beade52..ccbcba36c5 100644
--- a/core/hdd/src/wlan_hdd_stats.c
+++ b/core/hdd/src/wlan_hdd_stats.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@@ -6592,13 +6593,13 @@ int wlan_hdd_get_temperature(struct hdd_adapter *adapter, int *temperature)
void wlan_hdd_display_txrx_stats(struct hdd_context *ctx)
{
- struct hdd_adapter *adapter = NULL;
+ struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
struct hdd_tx_rx_stats *stats;
int i = 0;
uint32_t total_rx_pkt, total_rx_dropped,
total_rx_delv, total_rx_refused;
- hdd_for_each_adapter_dev_held(ctx, adapter) {
+ hdd_for_each_adapter_dev_held_safe(ctx, adapter, next_adapter) {
total_rx_pkt = 0;
total_rx_dropped = 0;
total_rx_delv = 0;
diff --git a/core/mac/src/dph/dph_hash_table.c b/core/mac/src/dph/dph_hash_table.c
index 3e7bdea015..2783a6e39b 100644
--- a/core/mac/src/dph/dph_hash_table.c
+++ b/core/mac/src/dph/dph_hash_table.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -242,6 +243,7 @@ tpDphHashNode dph_init_sta_state(struct mac_context *mac, tSirMacAddr staAddr,
sta->is_disassoc_deauth_in_progress = 0;
sta->sta_deletion_in_progress = false;
sta->valid = 1;
+ sta->is_key_installed = 0;
return sta;
}
diff --git a/core/mac/src/pe/include/lim_api.h b/core/mac/src/pe/include/lim_api.h
index d312a47c9f..88c7d877c5 100644
--- a/core/mac/src/pe/include/lim_api.h
+++ b/core/mac/src/pe/include/lim_api.h
@@ -116,6 +116,15 @@ void pe_stop(struct mac_context *mac);
#ifdef WLAN_FEATURE_11W
/**
+ * is_mgmt_protected - check RMF enabled for the peer
+ * @vdev_id: vdev id
+ * @peer_mac_addr: peer mac address
+ *
+ * Return: True if RMF enabled and key is installed
+ */
+bool is_mgmt_protected(uint32_t vdev_id, const uint8_t *peer_mac_addr);
+
+/**
* lim_stop_pmfcomeback_timer() - stop pmf comeback timer
* @session: Pointer to PE session
*
@@ -126,6 +135,12 @@ void lim_stop_pmfcomeback_timer(struct pe_session *session);
static inline void lim_stop_pmfcomeback_timer(struct pe_session *session)
{
}
+
+static inline bool
+is_mgmt_protected(uint32_t vdev_id, const uint8_t *peer_mac_addr)
+{
+ return false;
+}
#endif
/**
diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c
index 55d26d86d6..fb92d2e4c3 100644
--- a/core/mac/src/pe/lim/lim_api.c
+++ b/core/mac/src/pe/lim/lim_api.c
@@ -621,18 +621,8 @@ static void pe_shutdown_notifier_cb(void *ctx)
}
#ifdef WLAN_FEATURE_11W
-/**
- * is_mgmt_protected - check RMF enabled for the peer
- * @vdev_id: vdev id
- * @peer_mac_addr: peer mac address
- *
- * The function check the mgmt frame protection enabled or not
- * for station mode and AP mode
- *
- * Return: true, if the connection is RMF enabled.
- */
-static bool is_mgmt_protected(uint32_t vdev_id,
- const uint8_t *peer_mac_addr)
+bool is_mgmt_protected(uint32_t vdev_id,
+ const uint8_t *peer_mac_addr)
{
uint16_t aid;
tpDphHashNode sta_ds;
@@ -667,22 +657,6 @@ static bool is_mgmt_protected(uint32_t vdev_id,
return protected;
}
-#else
-/**
- * is_mgmt_protected - check RMF enabled for the peer
- * @vdev_id: vdev id
- * @peer_mac_addr: peer mac address
- *
- * The function check the mgmt frame protection enabled or not
- * for station mode and AP mode
- *
- * Return: true, if the connection is RMF enabled.
- */
-static bool is_mgmt_protected(uint32_t vdev_id,
- const uint8_t *peer_mac_addr)
-{
- return false;
-}
#endif
static void p2p_register_callbacks(struct mac_context *mac_ctx)
diff --git a/core/mac/src/pe/lim/lim_process_auth_frame.c b/core/mac/src/pe/lim/lim_process_auth_frame.c
index 5b25cb5044..5bac24eb0a 100644
--- a/core/mac/src/pe/lim/lim_process_auth_frame.c
+++ b/core/mac/src/pe/lim/lim_process_auth_frame.c
@@ -1265,6 +1265,14 @@ lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
return;
}
+ /* Duplicate Auth frame from peer */
+ auth_node = lim_search_pre_auth_list(mac_ctx, mac_hdr->sa);
+ if (auth_node && (auth_node->seq_num == curr_seq_num)) {
+ pe_err("Received an already processed auth frame with seq_num : %d",
+ curr_seq_num);
+ return;
+ }
+
/* save seq number and mac_addr in pe_session */
pe_session->prev_auth_seq_num = curr_seq_num;
qdf_mem_copy(pe_session->prev_auth_mac_addr, mac_hdr->sa, ETH_ALEN);
@@ -1408,7 +1416,6 @@ lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
* Authentication frame3 and there is a context for requesting
* STA. If not, reject with unspecified failure status code
*/
- auth_node = lim_search_pre_auth_list(mac_ctx, mac_hdr->sa);
if (!auth_node) {
pe_err("rx Auth frame with no preauth ctx with WEP bit set "
QDF_MAC_ADDR_STR,
diff --git a/core/mac/src/pe/lim/lim_process_deauth_frame.c b/core/mac/src/pe/lim/lim_process_deauth_frame.c
index 18d02f7b52..89f8409e5d 100644
--- a/core/mac/src/pe/lim/lim_process_deauth_frame.c
+++ b/core/mac/src/pe/lim/lim_process_deauth_frame.c
@@ -121,8 +121,8 @@ lim_process_deauth_frame(struct mac_context *mac, uint8_t *pRxPacketInfo,
}
#ifdef WLAN_FEATURE_11W
/* PMF: If this session is a PMF session, then ensure that this frame was protected */
- if (pe_session->limRmfEnabled
- && (WMA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) &
+ if (is_mgmt_protected(pe_session->vdev_id, (const uint8_t *)pHdr->sa) &&
+ (WMA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) &
DPU_FEEDBACK_UNPROTECTED_ERROR)) {
pe_debug("received an unprotected deauth from AP");
/*
diff --git a/core/mac/src/pe/lim/lim_process_disassoc_frame.c b/core/mac/src/pe/lim/lim_process_disassoc_frame.c
index 5c9869b9b0..56763d92d7 100644
--- a/core/mac/src/pe/lim/lim_process_disassoc_frame.c
+++ b/core/mac/src/pe/lim/lim_process_disassoc_frame.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@@ -113,8 +114,8 @@ lim_process_disassoc_frame(struct mac_context *mac, uint8_t *pRxPacketInfo,
}
#ifdef WLAN_FEATURE_11W
/* PMF: If this session is a PMF session, then ensure that this frame was protected */
- if (pe_session->limRmfEnabled
- && (WMA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) &
+ if (is_mgmt_protected(pe_session->vdev_id, (const uint8_t *)pHdr->sa) &&
+ (WMA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) &
DPU_FEEDBACK_UNPROTECTED_ERROR)) {
pe_err("received an unprotected disassoc from AP");
/*
diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c
index b11950a376..7456601cd7 100644
--- a/core/wma/src/wma_mgmt.c
+++ b/core/wma/src/wma_mgmt.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -4442,7 +4443,7 @@ int wma_form_rx_packet(qdf_nbuf_t buf,
if (status)
return status;
} else if (wma_find_vdev_by_addr(wma_handle, wh->i_addr1,
- &vdev_id) == QDF_STATUS_SUCCESS) {
+ &vdev_id)) {
status = wma_check_and_process_rmf_frame(wma_handle,
vdev_id,
&wh,