Просмотр исходного кода

qcacld-3.0: Disable NS offload when max addresses is reached

When NS offloading is enabled, and we reach the maximum number of supported
addresses, disable NS offload so Apps can handle it.

Change-Id: I8312d5e8091cfbdc1f6e3e1e1093ae1dca0c096c
CRs-Fixed: 1063737
Dustin Brown 8 лет назад
Родитель
Сommit
2444ee6840
1 измененных файлов с 137 добавлено и 114 удалено
  1. 137 114
      core/hdd/src/wlan_hdd_power.c

+ 137 - 114
core/hdd/src/wlan_hdd_power.c

@@ -374,142 +374,165 @@ static int hdd_fill_ipv6_ac_addr(struct inet6_dev *idev,
 }
 
 /**
- * hdd_conf_ns_offload() - Configure NS offload
- * @pAdapter:   pointer to the adapter
- * @fenable:    flag to enable or disable
- *              0 - disable
- *              1 - enable
+ * hdd_disable_ns_offload() - Disables IPv6 NS offload
+ * @adapter:	ponter to the adapter
  *
- * Return: nothing
+ * Return:	nothing
+ */
+static void hdd_disable_ns_offload(hdd_adapter_t *adapter)
+{
+	tSirHostOffloadReq offloadReq;
+	QDF_STATUS status;
+
+	qdf_mem_zero((void *)&offloadReq, sizeof(tSirHostOffloadReq));
+	hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD, SIR_OFFLOAD_DISABLE);
+	offloadReq.enableOrDisable = SIR_OFFLOAD_DISABLE;
+	offloadReq.offloadType =  SIR_IPV6_NS_OFFLOAD;
+	status = sme_set_host_offload(
+		WLAN_HDD_GET_HAL_CTX(adapter),
+		adapter->sessionId, &offloadReq);
+
+	if (QDF_STATUS_SUCCESS != status)
+		hdd_err("Failed to disable NS Offload");
+}
+
+/**
+ * hdd_enable_ns_offload() - Enables IPv6 NS offload
+ * @adapter:	ponter to the adapter
+ *
+ * Return:	nothing
  */
-static void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, bool fenable)
+static void hdd_enable_ns_offload(hdd_adapter_t *adapter)
 {
 	struct inet6_dev *in6_dev;
 	uint8_t ipv6_addr[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA]
 					[SIR_MAC_IPV6_ADDR_LEN] = { {0,} };
 	uint8_t ipv6_addr_type[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA] = { 0 };
-	tSirHostOffloadReq offLoadRequest;
-	hdd_context_t *pHddCtx;
-
-	int i = 0, ret;
-	QDF_STATUS returnStatus;
+	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	tSirHostOffloadReq offloadReq;
+	QDF_STATUS status;
 	uint32_t count = 0;
+	int err, i;
+
+	in6_dev = __in6_dev_get(adapter->dev);
+	if (NULL == in6_dev) {
+		hdd_err("IPv6 dev does not exist. Failed to request NSOffload");
+		return;
+	}
+
+	/* Unicast Addresses */
+	err = hdd_fill_ipv6_uc_addr(in6_dev, ipv6_addr, ipv6_addr_type, &count);
+	if (err) {
+		hdd_disable_ns_offload(adapter);
+		hdd_notice("Reached max supported addresses and not enabling "
+			"NS offload");
+		return;
+	}
+
+	/* Anycast Addresses */
+	err = hdd_fill_ipv6_ac_addr(in6_dev, ipv6_addr, ipv6_addr_type, &count);
+	if (err) {
+		hdd_disable_ns_offload(adapter);
+		hdd_notice("Reached max supported addresses and not enabling "
+			"NS offload");
+		return;
+	}
+
+	qdf_mem_zero(&offloadReq, sizeof(offloadReq));
+	for (i = 0; i < count; i++) {
+		/* Filling up the request structure
+		 * Filling the selfIPv6Addr with solicited address
+		 * A Solicited-Node multicast address is created by
+		 * taking the last 24 bits of a unicast or anycast
+		 * address and appending them to the prefix
+		 *
+		 * FF02:0000:0000:0000:0000:0001:FFXX:XXXX
+		 *
+		 * here XX is the unicast/anycast bits
+		 */
+		offloadReq.nsOffloadInfo.selfIPv6Addr[i][0] = 0xFF;
+		offloadReq.nsOffloadInfo.selfIPv6Addr[i][1] = 0x02;
+		offloadReq.nsOffloadInfo.selfIPv6Addr[i][11] = 0x01;
+		offloadReq.nsOffloadInfo.selfIPv6Addr[i][12] = 0xFF;
+		offloadReq.nsOffloadInfo.selfIPv6Addr[i][13] =
+					ipv6_addr[i][13];
+		offloadReq.nsOffloadInfo.selfIPv6Addr[i][14] =
+					ipv6_addr[i][14];
+		offloadReq.nsOffloadInfo.selfIPv6Addr[i][15] =
+					ipv6_addr[i][15];
+		offloadReq.nsOffloadInfo.slotIdx = i;
+		qdf_mem_copy(&offloadReq.nsOffloadInfo.targetIPv6Addr[i],
+			&ipv6_addr[i][0], SIR_MAC_IPV6_ADDR_LEN);
+
+		offloadReq.nsOffloadInfo.targetIPv6AddrValid[i] =
+			SIR_IPV6_ADDR_VALID;
+		offloadReq.nsOffloadInfo.target_ipv6_addr_ac_type[i] =
+			ipv6_addr_type[i];
+
+		qdf_mem_copy(&offloadReq.params.hostIpv6Addr,
+			&offloadReq.nsOffloadInfo.targetIPv6Addr[i],
+			SIR_MAC_IPV6_ADDR_LEN);
+
+		hdd_info("Setting NSOffload with solicitedIp: "
+			"%pI6, targetIp: %pI6, Index %d",
+			&offloadReq.nsOffloadInfo.selfIPv6Addr[i],
+			&offloadReq.nsOffloadInfo.targetIPv6Addr[i], i);
+	}
+
+	hdd_info("configuredMcastBcastFilter: %d",
+		hdd_ctx->configuredMcastBcastFilter);
+	hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD, SIR_OFFLOAD_ENABLE);
+	offloadReq.offloadType =  SIR_IPV6_NS_OFFLOAD;
+	offloadReq.enableOrDisable = SIR_OFFLOAD_ENABLE;
+	qdf_copy_macaddr(&offloadReq.nsOffloadInfo.self_macaddr,
+			 &adapter->macAddressCurrent);
+
+	/* set number of ns offload address count */
+	offloadReq.num_ns_offload_count = count;
+
+	/* Configure the Firmware with this */
+	status = sme_set_host_offload(WLAN_HDD_GET_HAL_CTX(adapter),
+		adapter->sessionId, &offloadReq);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("Failed to enable HostOffload feature with status: %d",
+			status);
+	}
+}
+
+/**
+ * hdd_conf_ns_offload() - Configure NS offload
+ * @adapter:   pointer to the adapter
+ * @fenable:    flag to enable or disable
+ *              0 - disable
+ *              1 - enable
+ *
+ * Return: nothing
+ */
+static void hdd_conf_ns_offload(hdd_adapter_t *adapter, bool fenable)
+{
+	hdd_context_t *hdd_ctx;
 
 	ENTER();
 	hdd_notice(" fenable = %d", fenable);
 
-	pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 
 	/* In SAP/P2PGo mode, ARP/NS offload feature capability
 	 * is controlled by one bit.
 	 */
 
-	if ((QDF_SAP_MODE == pAdapter->device_mode ||
-		QDF_P2P_GO_MODE == pAdapter->device_mode) &&
-		!pHddCtx->ap_arpns_support) {
+	if ((QDF_SAP_MODE == adapter->device_mode ||
+		QDF_P2P_GO_MODE == adapter->device_mode) &&
+		!hdd_ctx->ap_arpns_support) {
 		hdd_notice("NS Offload is not supported in SAP/P2PGO mode");
 		return;
 	}
 
-	if (fenable) {
-		in6_dev = __in6_dev_get(pAdapter->dev);
-		if (NULL != in6_dev) {
-			/* Unicast Addresses */
-			ret = hdd_fill_ipv6_uc_addr(in6_dev, ipv6_addr,
-						ipv6_addr_type, &count);
-
-			if (0 > ret) {
-				hdd_notice(
-				"Reached max supported addresses and not enabling NS offload");
-				return;
-			}
-
-			/* Anycast Addresses */
-			ret = hdd_fill_ipv6_ac_addr(in6_dev, ipv6_addr,
-						ipv6_addr_type, &count);
+	if (fenable)
+		hdd_enable_ns_offload(adapter);
+	else
+		hdd_disable_ns_offload(adapter);
 
-			if (0 > ret) {
-				hdd_notice(
-				"Reached max supported addresses and not enabling NS offload");
-				return;
-			}
-
-			qdf_mem_zero(&offLoadRequest, sizeof(offLoadRequest));
-			for (i = 0; i < count; i++) {
-				/* Filling up the request structure
-				 * Filling the selfIPv6Addr with solicited address
-				 * A Solicited-Node multicast address is created by
-				 * taking the last 24 bits of a unicast or anycast
-				 * address and appending them to the prefix
-				 *
-				 * FF02:0000:0000:0000:0000:0001:FFXX:XXXX
-				 *
-				 * here XX is the unicast/anycast bits
-				 */
-				offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][0] = 0xFF;
-				offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][1] = 0x02;
-				offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][11] = 0x01;
-				offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][12] = 0xFF;
-				offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][13] =
-							ipv6_addr[i][13];
-				offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][14] =
-							ipv6_addr[i][14];
-				offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][15] =
-							ipv6_addr[i][15];
-				offLoadRequest.nsOffloadInfo.slotIdx = i;
-				qdf_mem_copy(&offLoadRequest.nsOffloadInfo.
-					targetIPv6Addr[i], &ipv6_addr[i][0],
-					SIR_MAC_IPV6_ADDR_LEN);
-
-				offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[i] =
-							SIR_IPV6_ADDR_VALID;
-				offLoadRequest.nsOffloadInfo.
-						target_ipv6_addr_ac_type[i] =
-							ipv6_addr_type[i];
-
-				qdf_mem_copy(&offLoadRequest.params.hostIpv6Addr,
-					&offLoadRequest.nsOffloadInfo.targetIPv6Addr[i],
-					SIR_MAC_IPV6_ADDR_LEN);
-
-				hdd_info("Setting NSOffload with solicitedIp: %pI6, targetIp: %pI6, Index %d",
-					&offLoadRequest.nsOffloadInfo.selfIPv6Addr[i],
-					&offLoadRequest.nsOffloadInfo.targetIPv6Addr[i], i);
-			}
-
-			hdd_info("configuredMcastBcastFilter: %d",
-				pHddCtx->configuredMcastBcastFilter);
-			hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
-				SIR_OFFLOAD_ENABLE);
-			offLoadRequest.offloadType =  SIR_IPV6_NS_OFFLOAD;
-			offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
-			qdf_copy_macaddr(&offLoadRequest.nsOffloadInfo.self_macaddr,
-					 &pAdapter->macAddressCurrent);
-			/* set number of ns offload address count */
-			offLoadRequest.num_ns_offload_count = count;
-			/* Configure the Firmware with this */
-			returnStatus = sme_set_host_offload(WLAN_HDD_GET_HAL_CTX(pAdapter),
-				pAdapter->sessionId, &offLoadRequest);
-			if (QDF_STATUS_SUCCESS != returnStatus) {
-				hdd_err("Failed to enable HostOffload feature with status: %d",
-					returnStatus);
-			}
-		} else {
-			hdd_err("IPv6 dev does not exist. Failed to request NSOffload");
-			return;
-		}
-	} else {
-		hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
-			SIR_OFFLOAD_DISABLE);
-		/* Disable NSOffload */
-		qdf_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq));
-		offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
-		offLoadRequest.offloadType =  SIR_IPV6_NS_OFFLOAD;
-
-		if (QDF_STATUS_SUCCESS !=
-			sme_set_host_offload(WLAN_HDD_GET_HAL_CTX(pAdapter),
-				pAdapter->sessionId, &offLoadRequest))
-				hdd_err("Failed to disable NS Offload");
-	}
 	EXIT();
 	return;
 }