diff options
author | PixelBot AutoMerger <android-nexus-securitybot@system.gserviceaccount.com> | 2023-05-07 18:13:34 -0700 |
---|---|---|
committer | SecurityBot <android-nexus-securitybot@system.gserviceaccount.com> | 2023-05-07 18:13:34 -0700 |
commit | 9d72a095d4441badfae909ab16ca647bf3a1ff29 (patch) | |
tree | 43363ced6542f7f4d762479c00994db0cc503206 | |
parent | 5327ad6cfd834e7e522cd05d081aa65a72bf8766 (diff) | |
parent | e4fa8249b85725a0782eb5b7d7bb410e5f960fed (diff) | |
download | qcacld-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.c | 23 | ||||
-rw-r--r-- | core/hdd/inc/wlan_hdd_main.h | 73 | ||||
-rw-r--r-- | core/hdd/src/wlan_hdd_assoc.c | 12 | ||||
-rw-r--r-- | core/hdd/src/wlan_hdd_cfg80211.c | 22 | ||||
-rw-r--r-- | core/hdd/src/wlan_hdd_hostapd.c | 14 | ||||
-rw-r--r-- | core/hdd/src/wlan_hdd_ioctl.c | 8 | ||||
-rw-r--r-- | core/hdd/src/wlan_hdd_ipa.c | 9 | ||||
-rw-r--r-- | core/hdd/src/wlan_hdd_main.c | 296 | ||||
-rw-r--r-- | core/hdd/src/wlan_hdd_nan_datapath.c | 23 | ||||
-rw-r--r-- | core/hdd/src/wlan_hdd_oemdata.c | 6 | ||||
-rw-r--r-- | core/hdd/src/wlan_hdd_periodic_sta_stats.c | 11 | ||||
-rw-r--r-- | core/hdd/src/wlan_hdd_power.c | 55 | ||||
-rw-r--r-- | core/hdd/src/wlan_hdd_regulatory.c | 8 | ||||
-rw-r--r-- | core/hdd/src/wlan_hdd_stats.c | 5 | ||||
-rw-r--r-- | core/mac/src/dph/dph_hash_table.c | 2 | ||||
-rw-r--r-- | core/mac/src/pe/include/lim_api.h | 15 | ||||
-rw-r--r-- | core/mac/src/pe/lim/lim_api.c | 30 | ||||
-rw-r--r-- | core/mac/src/pe/lim/lim_process_auth_frame.c | 9 | ||||
-rw-r--r-- | core/mac/src/pe/lim/lim_process_deauth_frame.c | 4 | ||||
-rw-r--r-- | core/mac/src/pe/lim/lim_process_disassoc_frame.c | 5 | ||||
-rw-r--r-- | core/wma/src/wma_mgmt.c | 3 |
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, |