diff --git a/core/hdd/inc/wlan_hdd_power.h b/core/hdd/inc/wlan_hdd_power.h index 5a45179ee966..4d62500fb2e9 100644 --- a/core/hdd/inc/wlan_hdd_power.h +++ b/core/hdd/inc/wlan_hdd_power.h @@ -192,20 +192,42 @@ void hdd_disable_host_offloads(hdd_adapter_t *adapter, enum pmo_offload_trigger trigger); /** - * hdd_conf_mc_addr_filtering_enable() - enable MC address list in FW - * @pAdapter: adapter whose MC list is being set + * hdd_enable_mc_addr_filtering() - enable MC address list in FW + * @adapter: adapter whose MC list is being set * @trigger: trigger reason for request * * Return: nothing */ -#ifdef WLAN_FEATURE_PACKET_FILTERING -void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, uint8_t set); -#else -static inline void -wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, uint8_t set) -{ -} -#endif +void hdd_enable_mc_addr_filtering(hdd_adapter_t *adapter, + enum pmo_offload_trigger trigger); + +/** + * hdd_disable_mc_addr_filtering() - disable MC address list in FW + * @adapter: adapter whose MC list is being set + * @trigger: trigger reason for request + * + * Return: nothing + */ +void hdd_disable_mc_addr_filtering(hdd_adapter_t *adapter, + enum pmo_offload_trigger trigger); + +/** + * hdd_cache_mc_addr_list() - API to cache MC address list + * @mc_list_config: set of mc address list configurations + * + * Return: 0 on success else error code + */ +int hdd_cache_mc_addr_list(struct pmo_mc_addr_list_params *mc_list_config); + +/** + * hdd_disable_and_flush_mc_addr_list() - API to Disable & Flush cached MC list + * @adapter: adapter whose MC list is being set + * @trigger: trigger reason for request + * + * Return: nothing + */ +void hdd_disable_and_flush_mc_addr_list(hdd_adapter_t *adapter, + enum pmo_offload_trigger trigger); int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, struct cfg80211_wowlan *wow); diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 265324138955..d9ad767a752e 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -4771,13 +4771,14 @@ hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId, case eCSR_ROAM_DISASSOCIATED: { hdd_info("****eCSR_ROAM_DISASSOCIATED****"); - qdf_ret_status = - hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId, - roamStatus, roamResult); /* Call to clear any MC Addr List filter applied after * successful connection. */ - wlan_hdd_set_mc_addr_list(pAdapter, false); + hdd_disable_and_flush_mc_addr_list(pAdapter, + pmo_peer_disconnect); + qdf_ret_status = + hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId, + roamStatus, roamResult); } break; case eCSR_ROAM_IBSS_LEAVE: diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index a436cc98257d..5dd4e92d93bd 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -2309,81 +2309,73 @@ void wlan_hdd_release_intf_addr(hdd_context_t *hdd_ctx, uint8_t *releaseAddr) static void __hdd_set_multicast_list(struct net_device *dev) { hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); - int mc_count; int i = 0, status; struct netdev_hw_addr *ha; hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); - static const uint8_t ipv6_router_solicitation[] - = {0x33, 0x33, 0x00, 0x00, 0x00, 0x02}; + struct pmo_mc_addr_list_params *mc_list_request = NULL; + struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc; + int mc_count = 0; ENTER_DEV(dev); - if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) - return; + goto out; status = wlan_hdd_validate_context(hdd_ctx); if (0 != status) - return; + goto out; + + mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request)); + if (!mc_list_request) { + hdd_notice("Cannot allocate mc_list_request"); + goto out; + } if (dev->flags & IFF_ALLMULTI) { hdd_notice("allow all multicast frames"); - adapter->mc_addr_list.mc_cnt = 0; + hdd_disable_and_flush_mc_addr_list(adapter, + pmo_mc_list_change_notify); } else { mc_count = netdev_mc_count(dev); - hdd_notice("mc_count : %u", mc_count); - - if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST) { + if (mc_count > pmo_ucfg_max_mc_addr_supported(psoc)) { hdd_notice("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering", - WLAN_HDD_MAX_MC_ADDR_LIST); - wlan_hdd_set_mc_addr_list(adapter, false); - adapter->mc_addr_list.mc_cnt = 0; - return; + pmo_ucfg_max_mc_addr_supported(psoc)); + hdd_disable_and_flush_mc_addr_list(adapter, + pmo_mc_list_change_notify); + goto out; } - - adapter->mc_addr_list.mc_cnt = mc_count; - netdev_for_each_mc_addr(ha, dev) { hdd_notice("ha_addr[%d] "MAC_ADDRESS_STR, i, MAC_ADDR_ARRAY(ha->addr)); - if (i == mc_count) break; - /* - * Skip following addresses: - * 1)IPv6 router solicitation address - * 2)Any other address pattern if its set during - * RXFILTER REMOVE driver command based on - * addr_filter_pattern - */ - if ((!memcmp(ha->addr, ipv6_router_solicitation, - ETH_ALEN)) || - (adapter->addr_filter_pattern && (!memcmp(ha->addr, - &adapter->addr_filter_pattern, 1)))) { - hdd_info("MC/BC filtering Skip addr ="MAC_ADDRESS_STR, - MAC_ADDR_ARRAY(ha->addr)); - adapter->mc_addr_list.mc_cnt--; - continue; - } - - memset(&(adapter->mc_addr_list.addr[i][0]), 0, - ETH_ALEN); - memcpy(&(adapter->mc_addr_list.addr[i][0]), ha->addr, - ETH_ALEN); - hdd_notice("mlist[%d] = " MAC_ADDRESS_STR, i, - MAC_ADDR_ARRAY(adapter->mc_addr_list.addr[i])); + memset(&(mc_list_request->mc_addr[i].bytes), + 0, ETH_ALEN); + memcpy(&(mc_list_request->mc_addr[i].bytes), + ha->addr, ETH_ALEN); + hdd_info("mlist[%d] = %pM", i, + mc_list_request->mc_addr[i].bytes); i++; } } - if (hdd_ctx->config->active_mode_offload) { - hdd_info("enable mc filtering"); - wlan_hdd_set_mc_addr_list(adapter, true); + + mc_list_request->psoc = psoc; + mc_list_request->vdev_id = adapter->sessionId; + mc_list_request->count = mc_count; + status = hdd_cache_mc_addr_list(mc_list_request); + if (status == 0) { + hdd_enable_mc_addr_filtering(adapter, + pmo_mc_list_change_notify); } else { - hdd_info("skip mc filtering enable it during cfg80211 suspend"); + hdd_err("error while caching mc list"); } +out: + if (mc_list_request) + qdf_mem_free(mc_list_request); EXIT(); - return; + } + /** * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list * @dev: pointer to net_device diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index e8f73ef94d06..c57bdf7e0535 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -546,7 +546,7 @@ void hdd_enable_host_offloads(hdd_adapter_t *adapter, hdd_conf_gtk_offload(adapter, true); hdd_enable_arp_offload(adapter, trigger); hdd_enable_ns_offload(adapter, trigger); - wlan_hdd_set_mc_addr_list(adapter, true); + hdd_enable_mc_addr_filtering(adapter, trigger); out: EXIT(); @@ -572,7 +572,7 @@ void hdd_disable_host_offloads(hdd_adapter_t *adapter, hdd_conf_gtk_offload(adapter, false); hdd_disable_arp_offload(adapter, trigger); hdd_disable_ns_offload(adapter, trigger); - wlan_hdd_set_mc_addr_list(adapter, false); + hdd_disable_mc_addr_filtering(adapter, trigger); out: EXIT(); @@ -927,108 +927,86 @@ out: } -#ifdef WLAN_FEATURE_PACKET_FILTERING -/** - * wlan_hdd_set_mc_addr_list() - set MC address list in FW - * @pAdapter: adapter whose MC list is being set - * @set: flag which indicates if addresses are being set or cleared - */ -void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, uint8_t set) +void hdd_enable_mc_addr_filtering(hdd_adapter_t *adapter, + enum pmo_offload_trigger trigger) { - uint8_t i; - tpSirRcvFltMcAddrList pMulticastAddrs = NULL; - tHalHandle hHal = NULL; - hdd_context_t *pHddCtx = (hdd_context_t *) pAdapter->pHddCtx; - hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *hdd_ctx = (hdd_context_t *)adapter->pHddCtx; + QDF_STATUS status; + struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc; ENTER(); + if (wlan_hdd_validate_context(hdd_ctx)) + goto out; - if (wlan_hdd_validate_context(pHddCtx)) - return; - - hHal = pHddCtx->hHal; - - if (NULL == hHal) { - hdd_err("HAL Handle is NULL"); - return; - } - - if (!sta_ctx) { - hdd_err("sta_ctx is NULL"); - return; - } - - /* Check if INI is enabled or not, other wise just return */ - if (!pHddCtx->config->fEnableMCAddrList) { - hdd_notice("gMCAddrListEnable is not enabled in INI"); - return; - } - pMulticastAddrs = qdf_mem_malloc(sizeof(tSirRcvFltMcAddrList)); - if (NULL == pMulticastAddrs) { - hdd_err("Could not allocate Memory"); - return; - } - pMulticastAddrs->action = set; - - if (set) { - /* - * Following pre-conditions should be satisfied before we - * configure the MC address list. - */ - if (pAdapter->mc_addr_list.mc_cnt && - (((pAdapter->device_mode == QDF_STA_MODE || - pAdapter->device_mode == QDF_P2P_CLIENT_MODE) && - hdd_conn_is_connected(sta_ctx)) || - (WLAN_HDD_IS_NDI(pAdapter) && - WLAN_HDD_IS_NDI_CONNECTED(pAdapter)))) { - - pMulticastAddrs->ulMulticastAddrCnt = - pAdapter->mc_addr_list.mc_cnt; - - for (i = 0; i < pAdapter->mc_addr_list.mc_cnt; i++) { - memcpy(pMulticastAddrs->multicastAddr[i].bytes, - pAdapter->mc_addr_list.addr[i], - sizeof(pAdapter->mc_addr_list.addr[i])); - hdd_info("%s multicast filter: addr =" - MAC_ADDRESS_STR, - set ? "setting" : "clearing", - MAC_ADDR_ARRAY(pMulticastAddrs-> - multicastAddr[i].bytes)); - } - /* Set multicast filter */ - sme_8023_multicast_list(hHal, pAdapter->sessionId, - pMulticastAddrs); - } else { - hdd_info("MC address list not sent to FW, cnt: %d", - pAdapter->mc_addr_list.mc_cnt); - } - } else { - /* Need to clear only if it was previously configured */ - if (pAdapter->mc_addr_list.isFilterApplied) { - pMulticastAddrs->ulMulticastAddrCnt = - pAdapter->mc_addr_list.mc_cnt; - for (i = 0; i < pAdapter->mc_addr_list.mc_cnt; i++) { - memcpy(pMulticastAddrs->multicastAddr[i].bytes, - pAdapter->mc_addr_list.addr[i], - sizeof(pAdapter->mc_addr_list.addr[i])); - } - sme_8023_multicast_list(hHal, pAdapter->sessionId, - pMulticastAddrs); - } - - } - /* MAddrCnt is MulticastAddrCnt */ - hdd_notice("smeSessionId:%d; set:%d; MCAdddrCnt :%d", - pAdapter->sessionId, set, - pMulticastAddrs->ulMulticastAddrCnt); - - pAdapter->mc_addr_list.isFilterApplied = set ? true : false; - qdf_mem_free(pMulticastAddrs); - + status = pmo_ucfg_enable_mc_addr_filtering_in_fwr(psoc, + adapter->sessionId, trigger); + if (status != QDF_STATUS_SUCCESS) + hdd_info("failed to enable mc list status %d", status); +out: EXIT(); - return; + +} + +void hdd_disable_mc_addr_filtering(hdd_adapter_t *adapter, + enum pmo_offload_trigger trigger) +{ + hdd_context_t *hdd_ctx = (hdd_context_t *)adapter->pHddCtx; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc; + + ENTER(); + if (wlan_hdd_validate_context(hdd_ctx)) + goto out; + + status = pmo_ucfg_disable_mc_addr_filtering_in_fwr(psoc, + adapter->sessionId, trigger); + if (status != QDF_STATUS_SUCCESS) + hdd_info("failed to disable mc list status %d", status); +out: + EXIT(); + +} + +int hdd_cache_mc_addr_list(struct pmo_mc_addr_list_params *mc_list_config) +{ + QDF_STATUS status; + int ret = 0; + + ENTER(); + /* cache mc addr list */ + status = pmo_ucfg_cache_mc_addr_list(mc_list_config); + if (status != QDF_STATUS_SUCCESS) { + hdd_info("fail to cache mc list status %d", status); + ret = -EINVAL; + } + EXIT(); + + return ret; +} + +void hdd_disable_and_flush_mc_addr_list(hdd_adapter_t *adapter, + enum pmo_offload_trigger trigger) +{ + hdd_context_t *hdd_ctx = (hdd_context_t *)adapter->pHddCtx; + struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + ENTER(); + /* disable mc list first */ + status = pmo_ucfg_disable_mc_addr_filtering_in_fwr(psoc, + adapter->sessionId, 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->sessionId); + if (status != QDF_STATUS_SUCCESS) + hdd_info("fail to flush mc list status %d", status); + EXIT(); + + return; + } -#endif /** * hdd_conf_suspend_ind() - Send Suspend notification