From 0127a73a2dce037a2c18cef93b9eeca183f6c48b Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Thu, 19 Jul 2018 14:06:34 -0700 Subject: [PATCH] qcacld-3.0: Enable/Disable MC filter when connected Multicast address filtering only makes sense if the interface is connected and capable of receiving traffic. Avoid enabling/disabling the multicast address filter list on an interface that is disconnected. Change-Id: Id8aff136e920bb726b8c7dd539d477ff44f080d4 CRs-Fixed: 2282003 --- components/pmo/core/src/wlan_pmo_arp.c | 12 ++-- .../pmo/core/src/wlan_pmo_mc_addr_filtering.c | 14 +++- core/hdd/inc/wlan_hdd_assoc.h | 8 +++ core/hdd/src/wlan_hdd_assoc.c | 57 +++++++--------- core/hdd/src/wlan_hdd_power.c | 67 +++++++++++-------- 5 files changed, 88 insertions(+), 70 deletions(-) diff --git a/components/pmo/core/src/wlan_pmo_arp.c b/components/pmo/core/src/wlan_pmo_arp.c index 0ae14e3a10a1..8f95c3d65cb9 100644 --- a/components/pmo/core/src/wlan_pmo_arp.c +++ b/components/pmo/core/src/wlan_pmo_arp.c @@ -64,14 +64,12 @@ static QDF_STATUS pmo_core_cache_arp_in_vdev_priv( /* cache arp request */ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock); qdf_mem_copy(&vdev_ctx->vdev_arp_req, request, - sizeof(vdev_ctx->vdev_arp_req)); + sizeof(vdev_ctx->vdev_arp_req)); qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock); - pmo_debug("arp offload ipv4 addr: %d.%d.%d.%d enable: %d", - request->host_ipv4_addr[0], - request->host_ipv4_addr[1], - request->host_ipv4_addr[2], - request->host_ipv4_addr[3], - request->enable); + + pmo_debug("cached arp offload; addr:" QDF_IPV4_ADDR_STR ", enable:%d", + QDF_IPV4_ADDR_ARRAY(request->host_ipv4_addr), + request->enable); free_req: qdf_mem_free(request); diff --git a/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c b/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c index f452824fcd1c..a61527dec7e5 100644 --- a/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c +++ b/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c @@ -339,9 +339,6 @@ static QDF_STATUS pmo_core_mc_addr_flitering_sanity( return QDF_STATUS_E_INVAL; } - if (!pmo_core_is_vdev_connected(vdev)) - return QDF_STATUS_E_INVAL; - return QDF_STATUS_SUCCESS; } QDF_STATUS pmo_core_cache_mc_addr_list( @@ -380,6 +377,7 @@ QDF_STATUS pmo_core_cache_mc_addr_list( mc_list_config->vdev_id, mc_list_config->psoc); status = pmo_core_cache_mc_addr_list_in_vdev_priv(mc_list_config, vdev); + dec_ref: pmo_vdev_put_ref(vdev); out: @@ -516,6 +514,11 @@ QDF_STATUS pmo_core_enable_mc_addr_filtering_in_fwr( if (status != QDF_STATUS_SUCCESS) goto put_vdev; + if (!pmo_core_is_vdev_connected(vdev)) { + status = QDF_STATUS_E_INVAL; + goto put_vdev; + } + pmo_debug("enable mclist trigger: %d", trigger); status = pmo_core_handle_enable_mc_list_trigger(vdev, trigger); @@ -613,6 +616,11 @@ QDF_STATUS pmo_core_disable_mc_addr_filtering_in_fwr( if (status != QDF_STATUS_SUCCESS) goto put_ref; + if (!pmo_core_is_vdev_connected(vdev)) { + status = QDF_STATUS_E_INVAL; + goto put_ref; + } + pmo_debug("disable mclist trigger: %d", trigger); status = pmo_core_handle_disable_mc_list_trigger(vdev, trigger); diff --git a/core/hdd/inc/wlan_hdd_assoc.h b/core/hdd/inc/wlan_hdd_assoc.h index 57bc9bdd8fbd..8a27418d590f 100644 --- a/core/hdd/inc/wlan_hdd_assoc.h +++ b/core/hdd/inc/wlan_hdd_assoc.h @@ -233,6 +233,14 @@ bool hdd_is_fils_connection(struct hdd_adapter *adapter); */ bool hdd_conn_is_connected(struct hdd_station_ctx *sta_ctx); +/** + * hdd_adapter_is_connected_sta() - check if @adapter is a connected station + * @adapter: the adapter to check + * + * Return: true if @adapter is a connected station + */ +bool hdd_adapter_is_connected_sta(struct hdd_adapter *adapter); + /** * hdd_conn_get_connected_band() - get current connection radio band * @sta_ctx: pointer to global HDD Station context diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 7f3d0581c09f..145decd97e94 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -268,56 +268,47 @@ void hdd_conn_set_connection_state(struct hdd_adapter *adapter, */ static inline bool hdd_conn_get_connection_state(struct hdd_station_ctx *sta_ctx, - eConnectionState *pConnState) + eConnectionState *out_state) { - bool connected = false; - eConnectionState connState; + eConnectionState state = sta_ctx->conn_info.connState; - /* get the connection state. */ - connState = sta_ctx->conn_info.connState; + if (out_state) + *out_state = state; - if (eConnectionState_Associated == connState || - eConnectionState_IbssConnected == connState || - eConnectionState_IbssDisconnected == connState) { - connected = true; + switch (state) { + case eConnectionState_Associated: + case eConnectionState_IbssConnected: + case eConnectionState_IbssDisconnected: + case eConnectionState_NdiConnected: + return true; + default: + return false; } - - if (pConnState) - *pConnState = connState; - - return connected; } -/** - * hdd_is_connecting() - Function to check connection progress - * @hdd_sta_ctx: pointer to global HDD Station context - * - * Return: true if connecting, false otherwise - */ bool hdd_is_connecting(struct hdd_station_ctx *hdd_sta_ctx) { return hdd_sta_ctx->conn_info.connState == eConnectionState_Connecting; } -/** - * hdd_conn_is_connected() - Function to check connection status - * @sta_ctx: pointer to global HDD Station context - * - * Return: false if any errors encountered, true otherwise - */ bool hdd_conn_is_connected(struct hdd_station_ctx *sta_ctx) { return hdd_conn_get_connection_state(sta_ctx, NULL); } -/** - * hdd_conn_get_connected_band() - get current connection radio band - * @sta_ctx: pointer to global HDD Station context - * - * Return: BAND_2G or BAND_5G based on current AP connection - * BAND_ALL if not connected - */ +bool hdd_adapter_is_connected_sta(struct hdd_adapter *adapter) +{ + switch (adapter->device_mode) { + case QDF_STA_MODE: + case QDF_P2P_CLIENT_MODE: + case QDF_NDI_MODE: + return hdd_conn_is_connected(&adapter->session.station); + default: + return false; + } +} + enum band_info hdd_conn_get_connected_band(struct hdd_station_ctx *sta_ctx) { uint8_t staChannel = 0; diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index 027ecfa105dd..cc7227856766 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -878,13 +878,13 @@ void hdd_enable_arp_offload(struct hdd_adapter *adapter, status = pmo_ucfg_cache_arp_offload_req(arp_req); if (QDF_IS_STATUS_ERROR(status)) { - hdd_err("failed to cache arp offload request"); + hdd_err("failed to cache arp offload req; status:%d", status); goto free_req; } status = pmo_ucfg_enable_arp_offload_in_fwr(adapter->hdd_vdev, trigger); if (QDF_IS_STATUS_ERROR(status)) { - hdd_err("failed to configure arp offload in firmware"); + hdd_err("failed arp offload config in fw; status:%d", status); goto free_req; } @@ -921,40 +921,48 @@ out: } void hdd_enable_mc_addr_filtering(struct hdd_adapter *adapter, - enum pmo_offload_trigger trigger) + enum pmo_offload_trigger trigger) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); QDF_STATUS status; - struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc; hdd_enter(); + if (wlan_hdd_validate_context(hdd_ctx)) goto out; - status = pmo_ucfg_enable_mc_addr_filtering_in_fwr(psoc, - adapter->session_id, trigger); + if (!hdd_adapter_is_connected_sta(adapter)) + goto out; + + status = pmo_ucfg_enable_mc_addr_filtering_in_fwr(hdd_ctx->hdd_psoc, + adapter->session_id, + trigger); if (QDF_IS_STATUS_ERROR(status)) - hdd_info("failed to enable mc list status %d", status); + hdd_err("failed to enable mc list; status:%d", status); + out: hdd_exit(); - } void hdd_disable_mc_addr_filtering(struct hdd_adapter *adapter, - enum pmo_offload_trigger trigger) + enum pmo_offload_trigger trigger) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - QDF_STATUS status = QDF_STATUS_SUCCESS; - struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc; + QDF_STATUS status; hdd_enter(); + if (wlan_hdd_validate_context(hdd_ctx)) goto out; - status = pmo_ucfg_disable_mc_addr_filtering_in_fwr(psoc, - adapter->session_id, trigger); - if (status != QDF_STATUS_SUCCESS) - hdd_info("failed to disable mc list status %d", status); + if (!hdd_adapter_is_connected_sta(adapter)) + goto out; + + status = pmo_ucfg_disable_mc_addr_filtering_in_fwr(hdd_ctx->hdd_psoc, + adapter->session_id, + trigger); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("failed to disable mc list; status:%d", status); out: hdd_exit(); @@ -972,23 +980,28 @@ int hdd_cache_mc_addr_list(struct pmo_mc_addr_list_params *mc_list_config) } void hdd_disable_and_flush_mc_addr_list(struct hdd_adapter *adapter, - enum pmo_offload_trigger trigger) + enum pmo_offload_trigger trigger) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc; - QDF_STATUS status = QDF_STATUS_SUCCESS; + QDF_STATUS status; hdd_enter(); - /* disable mc list first */ - status = pmo_ucfg_disable_mc_addr_filtering_in_fwr(psoc, - adapter->session_id, trigger); - if (status != QDF_STATUS_SUCCESS) - hdd_info("fail to disable mc list"); - /* flush mc list */ - status = pmo_ucfg_flush_mc_addr_list(psoc, adapter->session_id); - if (status != QDF_STATUS_SUCCESS) - hdd_info("fail to flush mc list status %d", status); + if (!hdd_adapter_is_connected_sta(adapter)) + goto flush_mc_list; + + /* disable mc list first because the mc list is cached in PMO */ + status = pmo_ucfg_disable_mc_addr_filtering_in_fwr(hdd_ctx->hdd_psoc, + adapter->session_id, + trigger); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("failed to disable mc list; status:%d", status); + +flush_mc_list: + status = pmo_ucfg_flush_mc_addr_list(hdd_ctx->hdd_psoc, + adapter->session_id); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("failed to flush mc list; status:%d", status); hdd_exit();