diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 3a5ab4c6aefb..5d9578ee82ff 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -2351,16 +2351,6 @@ typedef QDF_STATUS (*hdd_adapter_iterate_cb)(struct hdd_adapter *adapter, QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb, void *context); -/** - * hdd_for_each_adapter - adapter iterator macro - * @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)) - /** * __hdd_take_ref_and_fetch_front_adapter - Helper macro to lock, fetch front * adapter, take ref and unlock. @@ -2422,32 +2412,6 @@ QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb, */ #define __hdd_is_adapter_valid(_adapter) !!_adapter -/** - * hdd_for_each_adapter_dev_held - Adapter iterator with dev_hold called - * @hdd_ctx: the global HDD context - * @adapter: an hdd_adapter pointer to use as a cursor - * - * 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. - * - * ***** 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. - * - * Usage example: - * hdd_for_each_adapter_dev_held(hdd_ctx, adapter) { - * - * - * 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_is_adapter_valid(adapter); \ - __hdd_take_ref_and_fetch_next_adapter(hdd_ctx, adapter)) - /** * hdd_for_each_adapter_dev_held_safe - Adapter iterator with dev_hold called * in a delete safe manner diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 8261ecb4ca75..2163cad4084b 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -405,7 +405,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) { @@ -413,7 +413,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) || @@ -422,6 +422,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) && @@ -430,9 +433,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 1334c4c8599b..4337f590c82a 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -5725,11 +5725,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 = @@ -5746,6 +5746,9 @@ static bool wlan_hdd_check_dfs_channel_for_adapter(struct hdd_context *hdd_ctx, hdd_ctx->pdev, ap_ctx->operating_chan_freq)) { hdd_err("SAP running on DFS channel"); + dev_put(adapter->dev); + if (next_adapter) + dev_put(next_adapter->dev); return true; } } @@ -5764,9 +5767,13 @@ static bool wlan_hdd_check_dfs_channel_for_adapter(struct hdd_context *hdd_ctx, hdd_ctx->pdev, sta_ctx->conn_info.chan_freq))) { 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; @@ -11806,13 +11813,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; uint32_t operating_chan_freq; 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_chan_freq = adapter->session.ap.operating_chan_freq; if (WLAN_REG_IS_24GHZ_CH_FREQ(operating_chan_freq)) @@ -11822,6 +11831,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_hang_event.c b/core/hdd/src/wlan_hdd_hang_event.c index 745dcd9a6d0d..e59911785acc 100644 --- a/core/hdd/src/wlan_hdd_hang_event.c +++ b/core/hdd/src/wlan_hdd_hang_event.c @@ -45,7 +45,7 @@ static int wlan_hdd_recovery_notifier_call(struct notifier_block *block, struct hdd_context *hdd_ctx; struct qdf_notifer_data *hdd_hang_data = data; uint8_t *hdd_buf_ptr; - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; uint32_t total_len; struct wlan_objmgr_vdev *vdev; struct hdd_hang_event_fixed_param *cmd; @@ -77,7 +77,7 @@ static int wlan_hdd_recovery_notifier_call(struct notifier_block *block, hdd_hang_data->offset += total_len; } - hdd_for_each_adapter_dev_held(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) { vdev = hdd_objmgr_get_vdev(adapter); if (!vdev) { dev_put(adapter->dev); diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index daaf6cbce257..a98938fd2188 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -2915,7 +2915,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) { @@ -2923,7 +2923,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) || @@ -2932,9 +2932,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; @@ -3470,7 +3474,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) @@ -3478,9 +3482,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 07c8579757c9..890f7fc50aa5 100644 --- a/core/hdd/src/wlan_hdd_ioctl.c +++ b/core/hdd/src/wlan_hdd_ioctl.c @@ -5154,6 +5154,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) { @@ -5161,7 +5162,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); @@ -5179,9 +5180,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 d5295af745bd..5096b7fdb3dc 100644 --- a/core/hdd/src/wlan_hdd_ipa.c +++ b/core/hdd/src/wlan_hdd_ipa.c @@ -33,7 +33,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 +70,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); @@ -207,6 +207,7 @@ void hdd_ipa_set_tx_flow_info(void) if (!preAdapterContext) { hdd_err("SCC: Previous adapter context NULL"); + dev_put(adapter->dev); continue; } @@ -255,6 +256,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 = @@ -283,6 +285,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 = @@ -315,6 +318,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 2c345f260acf..c7aecf9cbe83 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -625,10 +625,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 @@ -2618,7 +2620,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; @@ -2635,7 +2637,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 || @@ -2651,6 +2653,7 @@ bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx) cds_get_context(QDF_MODULE_ID_SOC), adapter->vdev_id); } + dev_put(adapter->dev); } return true; @@ -3329,17 +3332,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; @@ -5882,9 +5889,9 @@ void hdd_cleanup_conn_info(struct hdd_adapter *adapter) void hdd_sta_destroy_ctx_all(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; - hdd_for_each_adapter_dev_held(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) { if (adapter->device_mode == QDF_STA_MODE) hdd_cleanup_conn_info(adapter); dev_put(adapter->dev); @@ -5945,13 +5952,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; @@ -6449,12 +6460,14 @@ static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work) static u8 hdd_get_mode_specific_interface_count(struct hdd_context *hdd_ctx, enum QDF_OPMODE mode) { - struct hdd_adapter *adapter = NULL; + struct hdd_adapter *adapter = NULL, *next_adapter = NULL; u8 intf_count = 0; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) { if (adapter->device_mode == mode) intf_count++; + + dev_put(adapter->dev); } return intf_count; } @@ -7267,27 +7280,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(); @@ -7429,7 +7446,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; bool value; struct wlan_objmgr_vdev *vdev; @@ -7438,7 +7455,7 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value); - 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); @@ -7491,6 +7508,7 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) hdd_set_disconnect_status(adapter, false); hdd_debug("Flush any mgmt references held by peer"); hdd_stop_adapter(hdd_ctx, adapter); + dev_put(adapter->dev); } hdd_exit(); @@ -7500,17 +7518,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; @@ -8195,17 +8218,19 @@ 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; struct wlan_objmgr_vdev *vdev; 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), @@ -8335,14 +8360,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(); @@ -8537,15 +8567,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; @@ -8554,12 +8588,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; @@ -8568,11 +8607,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; @@ -8581,13 +8625,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; @@ -8601,11 +8649,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; @@ -8624,11 +8677,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; @@ -8657,15 +8715,19 @@ enum QDF_OPMODE hdd_get_device_mode(uint32_t vdev_id) uint32_t hdd_get_operating_chan_freq(struct hdd_context *hdd_ctx, enum QDF_OPMODE mode) { - struct hdd_adapter *adapter; + struct hdd_adapter *adapter, *next_adapter = NULL; uint32_t oper_chan_freq = 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) { oper_chan_freq = hdd_get_adapter_home_channel(adapter); + dev_put(adapter->dev); + if (next_adapter) + dev_put(next_adapter->dev); break; } + dev_put(adapter->dev); } return oper_chan_freq; @@ -8674,11 +8736,11 @@ uint32_t hdd_get_operating_chan_freq(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_P2P_DEVICE_MODE || @@ -8686,6 +8748,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(); @@ -8695,11 +8758,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_P2P_DEVICE_MODE || @@ -8709,6 +8772,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(); @@ -8725,10 +8789,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_P2P_DEVICE_MODE || @@ -8738,6 +8802,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); } return QDF_STATUS_SUCCESS; @@ -9092,11 +9157,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; @@ -9367,10 +9437,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 @@ -10048,7 +10120,8 @@ void hdd_send_mscs_action_frame(struct hdd_context *hdd_ctx, 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, tx_bytes = 0; uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0; uint64_t fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0; @@ -10064,19 +10137,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; } @@ -10084,6 +10160,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; } @@ -10141,6 +10218,7 @@ static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx) adapter->prev_tx_bytes = adapter->stats.tx_bytes; qdf_spin_unlock_bh(&hdd_ctx->bus_bw_lock); connected = true; + dev_put(adapter->dev); } if (!connected) { @@ -10546,7 +10624,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); @@ -10555,7 +10633,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; @@ -10714,14 +10792,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; @@ -10740,9 +10818,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, @@ -10751,6 +10829,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); } } @@ -11009,7 +11088,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}; @@ -11022,7 +11101,7 @@ 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_dev_held(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_rl("skip device mode:%d acs:%d", @@ -11136,6 +11215,8 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt) hdd_switch_sap_channel(adapter, restart_chan, true); dev_put(adapter->dev); + if (next_adapter) + dev_put(next_adapter->dev); return; } else { @@ -11144,6 +11225,8 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt) hdd_ctxt->radio_index, WLAN_SVC_LTE_COEX_IND, NULL, 0); dev_put(adapter->dev); + if (next_adapter) + dev_put(next_adapter->dev); return; } } @@ -11321,7 +11404,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 = @@ -11347,7 +11430,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 */ @@ -14160,7 +14244,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; @@ -14178,7 +14262,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); @@ -14196,6 +14280,7 @@ static void hdd_state_info_dump(char **buf_ptr, uint16_t *size) default: break; } + dev_put(adapter->dev); } *size -= len; @@ -15106,13 +15191,13 @@ wlan_hdd_disable_roaming(struct hdd_adapter *cur_adapter, enum wlan_cm_rso_control_requestor rso_op_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 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) { sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); if (cur_adapter->vdev_id != adapter->vdev_id && @@ -15124,6 +15209,7 @@ wlan_hdd_disable_roaming(struct hdd_adapter *cur_adapter, REASON_DRIVER_DISABLED, rso_op_requestor); } + dev_put(adapter->dev); } } @@ -15132,13 +15218,13 @@ wlan_hdd_enable_roaming(struct hdd_adapter *cur_adapter, enum wlan_cm_rso_control_requestor rso_op_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 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) { sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); if (cur_adapter->vdev_id != adapter->vdev_id && @@ -15150,6 +15236,7 @@ wlan_hdd_enable_roaming(struct hdd_adapter *cur_adapter, REASON_DRIVER_ENABLED, rso_op_requestor); } + dev_put(adapter->dev); } } @@ -15271,7 +15358,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; @@ -15294,12 +15381,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; } } @@ -15308,9 +15399,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); } } @@ -15334,11 +15429,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) { @@ -15346,13 +15441,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; @@ -15372,24 +15474,35 @@ static inline bool hdd_adapter_is_ap(struct hdd_adapter *adapter) bool hdd_is_any_adapter_connected(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; @@ -17563,7 +17676,7 @@ int hdd_enable_disable_ca_event(struct hdd_context *hdd_ctx, uint8_t set_value) bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter = NULL; + struct hdd_adapter *adapter = NULL, *next_adapter = NULL; uint8_t vdev_id; if (!hdd_ctx) { @@ -17574,7 +17687,7 @@ bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx) if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) return false; - hdd_for_each_adapter(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) { vdev_id = adapter->vdev_id; if (adapter->device_mode == QDF_STA_MODE && (MLME_IS_ROAM_SYNCH_IN_PROGRESS(hdd_ctx->psoc, vdev_id) || @@ -17583,8 +17696,12 @@ bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx) vdev_id))) { hdd_debug("Roaming is in progress on: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; diff --git a/core/hdd/src/wlan_hdd_nan_datapath.c b/core/hdd/src/wlan_hdd_nan_datapath.c index d2acbf4c994b..dfe0e6270116 100644 --- a/core/hdd/src/wlan_hdd_nan_datapath.c +++ b/core/hdd/src/wlan_hdd_nan_datapath.c @@ -122,25 +122,34 @@ static int hdd_close_ndi(struct hdd_adapter *adapter) #ifdef NDP_SAP_CONCURRENCY_ENABLE 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: 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: 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; @@ -148,26 +157,35 @@ static bool hdd_is_ndp_allowed(struct hdd_context *hdd_ctx) #else 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: 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; @@ -546,7 +564,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; @@ -558,9 +576,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 ef4f1f4cb358..6d17436b6734 100644 --- a/core/hdd/src/wlan_hdd_oemdata.c +++ b/core/hdd/src/wlan_hdd_oemdata.c @@ -190,7 +190,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) { @@ -221,7 +221,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; @@ -230,6 +230,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 1627f8528a1f..c9dd8eb3415b 100644 --- a/core/hdd/src/wlan_hdd_periodic_sta_stats.c +++ b/core/hdd/src/wlan_hdd_periodic_sta_stats.c @@ -41,7 +41,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 +50,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 +92,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 720c9a4a3ca3..952235cd13df 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -1303,7 +1303,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"); @@ -1320,9 +1320,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", @@ -1337,6 +1339,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, @@ -1361,7 +1364,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"); @@ -1382,9 +1385,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); @@ -1398,6 +1403,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); @@ -1430,17 +1437,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(); @@ -1559,9 +1567,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) && @@ -1571,6 +1579,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); } } @@ -1994,7 +2003,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; struct wlan_objmgr_vdev *vdev; int rc; @@ -2028,9 +2037,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 == @@ -2041,6 +2052,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)) { @@ -2048,6 +2062,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) { @@ -2057,9 +2074,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); @@ -2071,11 +2092,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 1cc424a6c912..89fdb6630df6 100644 --- a/core/hdd/src/wlan_hdd_regulatory.c +++ b/core/hdd/src/wlan_hdd_regulatory.c @@ -1389,7 +1389,7 @@ static void hdd_regulatory_chanlist_dump(struct regulatory_channel *chan_list) */ static void hdd_country_change_update_sta(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter = NULL; + struct hdd_adapter *adapter = NULL, *next_adapter = NULL; struct hdd_station_ctx *sta_ctx = NULL; struct csr_roam_profile *roam_profile = NULL; struct wlan_objmgr_pdev *pdev = NULL; @@ -1400,7 +1400,7 @@ static void hdd_country_change_update_sta(struct hdd_context *hdd_ctx) pdev = hdd_ctx->pdev; - hdd_for_each_adapter_dev_held(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) { oper_freq = hdd_get_adapter_home_channel(adapter); freq_changed = wlan_reg_is_disable_for_freq(pdev, oper_freq); @@ -1518,7 +1518,7 @@ static void hdd_restart_sap_with_new_phymode(struct hdd_context *hdd_ctx, */ static void hdd_country_change_update_sap(struct hdd_context *hdd_ctx) { - struct hdd_adapter *adapter = NULL; + struct hdd_adapter *adapter = NULL, *next_adapter = NULL; struct sap_config *sap_config = NULL; struct wlan_objmgr_pdev *pdev = NULL; uint32_t reg_phy_mode, new_phy_mode; @@ -1528,7 +1528,7 @@ static void hdd_country_change_update_sap(struct hdd_context *hdd_ctx) pdev = hdd_ctx->pdev; - hdd_for_each_adapter_dev_held(hdd_ctx, adapter) { + hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) { oper_freq = hdd_get_adapter_home_channel(adapter); switch (adapter->device_mode) { diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c index cd708851e659..bb6b04e28515 100644 --- a/core/hdd/src/wlan_hdd_stats.c +++ b/core/hdd/src/wlan_hdd_stats.c @@ -1712,11 +1712,11 @@ out: */ static void cache_station_stats_cb(struct stats_event *ev, void *cookie) { - struct hdd_adapter *adapter = cookie; + struct hdd_adapter *adapter = cookie, *next_adapter = NULL; struct hdd_context *hdd_ctx = adapter->hdd_ctx; uint8_t vdev_id = adapter->vdev_id; - 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 != vdev_id) { dev_put(adapter->dev); continue; @@ -1724,6 +1724,8 @@ static void cache_station_stats_cb(struct stats_event *ev, void *cookie) copy_station_stats_to_adapter(adapter, ev); /* dev_put has to be done here */ dev_put(adapter->dev); + if (next_adapter) + dev_put(next_adapter->dev); break; } } @@ -6543,13 +6545,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;