Эх сурвалжийг харах

qcacld-3.0: Add LFR Subnet Detection support

Add LFR subnet detection support to protocol stack and
device access layers. In LFR3, the device may perform multiple
roams (may be across multiple IP subnets) without the knowledge
of wlan host. The LFR subnet detection feature enables the device
to regain IP connectivity if the firmware has roamed across the
subnets which otherwise is not possible without disconnect and
reconnect.

Change-Id: I60959af8b6ed330313a7f08f8aa1edfb63938bb8
CRs-Fixed: 876335
Ravi Joshi 9 жил өмнө
parent
commit
9e891bad23

+ 41 - 0
core/sme/src/common/sme_api.c

@@ -14703,6 +14703,47 @@ CDF_STATUS sme_soc_set_dual_mac_config(tHalHandle hal,
 	return CDF_STATUS_SUCCESS;
 }
 
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+/**
+ * sme_gateway_param_update() - to update gateway parameters with WMA
+ * @Hal: hal handle
+ * @gw_params: request parameters from HDD
+ *
+ * Return: CDF_STATUS
+ *
+ * This routine will update gateway parameters to WMA
+ */
+CDF_STATUS sme_gateway_param_update(tHalHandle Hal,
+			      struct gateway_param_update_req *gw_params)
+{
+	CDF_STATUS cdf_status;
+	cds_msg_t cds_message;
+	struct gateway_param_update_req *request_buf;
+
+	request_buf = cdf_mem_malloc(sizeof(*request_buf));
+	if (NULL == request_buf) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			FL("Not able to allocate memory for gw param update request"));
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	*request_buf = *gw_params;
+
+	cds_message.type = WMA_GW_PARAM_UPDATE_REQ;
+	cds_message.reserved = 0;
+	cds_message.bodyptr = request_buf;
+	cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
+	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			FL("Not able to post WMA_GW_PARAM_UPDATE_REQ message to HAL"));
+		cdf_mem_free(request_buf);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	return CDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
+
 /**
  * sme_set_peer_authorized() - call peer authorized callback
  * @peer_addr: peer mac address

+ 5 - 0
core/wma/src/wma_main.c

@@ -5280,6 +5280,11 @@ CDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg)
 			(struct wma_lro_config_cmd_t *)msg->bodyptr);
 		cdf_mem_free(msg->bodyptr);
 		break;
+	case WMA_GW_PARAM_UPDATE_REQ:
+		wma_set_gateway_params(wma_handle,
+			(struct gateway_param_update_req *)msg->bodyptr);
+		cdf_mem_free(msg->bodyptr);
+		break;
 	default:
 		WMA_LOGD("unknow msg type %x", msg->type);
 		/* Do Nothing? MSG Body should be freed at here */

+ 61 - 0
core/wma/src/wma_scan_roam.c

@@ -6969,3 +6969,64 @@ CDF_STATUS wma_get_scan_id(uint32_t *scan_id)
 	return CDF_STATUS_SUCCESS;
 }
 
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+/**
+ * wma_set_gateway_params() - set gateway parameters
+ * @wma: WMA handle
+ * @req: gateway parameter update request structure
+ *
+ * This function reads the incoming @req and fill in the destination
+ * WMI structure and sends down the gateway configs down to the firmware
+ *
+ * Return: CDF_STATUS
+ */
+CDF_STATUS wma_set_gateway_params(tp_wma_handle wma,
+					struct gateway_param_update_req *req)
+{
+	wmi_roam_subnet_change_config_fixed_param *cmd;
+	wmi_buf_t buf;
+	int ret;
+	int len = sizeof(*cmd);
+
+	buf = wmi_buf_alloc(wma->wmi_handle, len);
+	if (!buf) {
+		WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_roam_subnet_change_config_fixed_param *) wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		WMITLV_TAG_STRUC_wmi_roam_subnet_change_config_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN(
+			wmi_roam_subnet_change_config_fixed_param));
+
+	cmd->vdev_id = req->session_id;
+	cdf_mem_copy(&cmd->inet_gw_ip_v4_addr, req->ipv4_addr,
+		CDF_IPV4_ADDR_SIZE);
+	cdf_mem_copy(&cmd->inet_gw_ip_v6_addr, req->ipv6_addr,
+		CDF_IPV6_ADDR_SIZE);
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(req->gw_mac_addr.bytes,
+		&cmd->inet_gw_mac_addr);
+	cmd->max_retries = req->max_retries;
+	cmd->timeout = req->timeout;
+	cmd->num_skip_subnet_change_detection_bssid_list = 0;
+	cmd->flag = 0;
+	if (req->ipv4_addr_type)
+		WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP4_ENABLED(cmd->flag);
+
+	if (req->ipv6_addr_type)
+		WMI_SET_ROAM_SUBNET_CHANGE_FLAG_IP6_ENABLED(cmd->flag);
+
+	ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+				WMI_ROAM_SUBNET_CHANGE_CONFIG_CMDID);
+	if (ret != EOK) {
+		WMA_LOGE("Failed to send gw config parameter to fw, ret: %d",
+			ret);
+		wmi_buf_free(buf);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	return CDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
+