Browse Source

qcacld-3.0: Add support for mc addr list in PMO component

Add support for mc address list  in PMO component.

Change-Id: I711ff4a1394258400573ff6658605b1650832b0f
CRs-Fixed: 2005103
Mukul Sharma 8 years ago
parent
commit
ff2ac2e1e5
4 changed files with 141 additions and 148 deletions
  1. 32 10
      core/hdd/inc/wlan_hdd_power.h
  2. 5 4
      core/hdd/src/wlan_hdd_assoc.c
  3. 38 46
      core/hdd/src/wlan_hdd_main.c
  4. 66 88
      core/hdd/src/wlan_hdd_power.c

+ 32 - 10
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);

+ 5 - 4
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:

+ 38 - 46
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

+ 66 - 88
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;
+	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();
 
-	hHal = pHddCtx->hHal;
+}
 
-	if (NULL == hHal) {
-		hdd_err("HAL Handle is NULL");
-		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;
 
-	if (!sta_ctx) {
-		hdd_err("sta_ctx is NULL");
-		return;
-	}
+	ENTER();
+	if (wlan_hdd_validate_context(hdd_ctx))
+		goto out;
 
-	/* 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;
+	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();
 
-	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);
-		}
+}
 
+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;
 	}
-	/* MAddrCnt is MulticastAddrCnt */
-	hdd_notice("smeSessionId:%d; set:%d; MCAdddrCnt :%d",
-	       pAdapter->sessionId, set,
-	       pMulticastAddrs->ulMulticastAddrCnt);
+	EXIT();
+
+	return ret;
+}
 
-	pAdapter->mc_addr_list.isFilterApplied = set ? true : false;
-	qdf_mem_free(pMulticastAddrs);
+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