summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRavi Joshi <ravij@qca.qualcomm.com>2015-11-09 19:03:46 -0800
committerSatish Singh <ssing@codeaurora.org>2015-12-28 22:35:54 -0800
commit9e891bad232cbe0a01ae6edfbeb500b058d74ca6 (patch)
tree4c987b377689354f475d36bff0148b5df758e12f
parent742495dd303dab6547975fe0c3cf64177cd5d251 (diff)
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
-rw-r--r--core/sme/src/common/sme_api.c41
-rw-r--r--core/wma/src/wma_main.c5
-rw-r--r--core/wma/src/wma_scan_roam.c61
3 files changed, 107 insertions, 0 deletions
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index 5618a8fdd746..2cf8fbb92381 100644
--- a/core/sme/src/common/sme_api.c
+++ b/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
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index 9ecbdecc7637..b185e7e25070 100644
--- a/core/wma/src/wma_main.c
+++ b/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 */
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index 56318d6e8e6a..f170cca1c1a4 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/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 */
+