Bläddra i källkod

qcacmn: Support Multicast Domain Name Server Offload

The purpose of the multicast Domain Name System (mDNS) is to resolve
host names to IP addresses within small networks that do not include
a local name server.

It utilizes essentially the same programming interfaces, packet formats
and operating semantics as the unicast DNS, and the advantage is zero
configuration service while no need for central or global server.
Based on mDNS, the DNS-SD (Service Discovery) allows clients to discover
a named list of services by type in a specified domain using standard
DNS queries.

Here, we provide the ability to advertise the available services by
responding to mDNS queries.

Change-Id: Ie6a3cd319d219c2f338d83f4bdbd704a090711c4
CRs-Fixed: 3008552
Aditya Kodukula 4 år sedan
förälder
incheckning
e668136ffc

+ 16 - 1
wmi/inc/wmi_unified_fwol_api.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -87,4 +87,19 @@ wmi_unified_send_dscp_tip_map_cmd(struct wmi_unified *wmi_handle,
 }
 #endif /* WLAN_SEND_DSCP_UP_MAP_TO_FW */
 
+#ifdef WLAN_FEATURE_MDNS_OFFLOAD
+/**
+ * wmi_unified_send_set_mdns_config_cmd() - Send WMI set mDNS config cmd
+ * @wmi_handle: wmi handle
+ * @mdns_info: mdns config info
+ *
+ * Send WMI set mDNS config command to firmware.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wmi_unified_send_set_mdns_config_cmd(struct wmi_unified *wmi_handle,
+				     struct mdns_config_info *mdns_info);
+#endif /* WLAN_FEATURE_MDNS_OFFLOAD */
+
 #endif /* _WMI_UNIFIED_FWOL_API_H_ */

+ 5 - 0
wmi/inc/wmi_unified_priv.h

@@ -2488,6 +2488,11 @@ QDF_STATUS (*send_dscp_tid_map_cmd)(wmi_unified_t wmi_handle,
 				     uint32_t *dscp_to_tid_map);
 #endif
 
+#ifdef WLAN_FEATURE_MDNS_OFFLOAD
+QDF_STATUS (*send_set_mdns_config_cmd)(wmi_unified_t wmi_handle,
+				       struct mdns_config_info *mdns_info);
+#endif /* WLAN_FEATURE_MDNS_OFFLOAD */
+
 QDF_STATUS (*send_pdev_get_pn_cmd)(wmi_unified_t wmi_handle,
 				   struct peer_request_pn_param *pn_params);
 QDF_STATUS (*extract_get_pn_data)(wmi_unified_t wmi_handle,

+ 14 - 1
wmi/src/wmi_unified_fwol_api.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -71,3 +71,16 @@ wmi_unified_send_dscp_tip_map_cmd(struct wmi_unified *wmi_handle,
 	return QDF_STATUS_E_FAILURE;
 }
 #endif /* WLAN_SEND_DSCP_UP_MAP_TO_FW */
+
+#ifdef WLAN_FEATURE_MDNS_OFFLOAD
+QDF_STATUS
+wmi_unified_send_set_mdns_config_cmd(struct wmi_unified *wmi_handle,
+				     struct mdns_config_info *mdns_info)
+{
+	if (wmi_handle->ops->send_set_mdns_config_cmd)
+		return wmi_handle->ops->send_set_mdns_config_cmd(wmi_handle,
+								 mdns_info);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* WLAN_FEATURE_MDNS_OFFLOAD */

+ 222 - 1
wmi/src/wmi_unified_fwol_tlv.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -207,11 +207,232 @@ static void wmi_fwol_attach_dscp_tid_tlv(struct wmi_ops *ops)
 }
 #endif /* WLAN_SEND_DSCP_UP_MAP_TO_FW */
 
+#ifdef WLAN_FEATURE_MDNS_OFFLOAD
+/**
+ * send_set_mdns_fqdn_cmd_tlv() - send set mDNS FQDN cmd to fw
+ * @wmi_handle: wmi handle
+ * @mdns_info: mDNS config info
+ *
+ * Send WMI_MDNS_SET_FQDN_CMDID to fw.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+send_set_mdns_fqdn_cmd_tlv(wmi_unified_t wmi_handle,
+			   struct mdns_config_info *mdns_info)
+{
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	wmi_mdns_set_fqdn_cmd_fixed_param *cmd;
+	uint16_t len = sizeof(*cmd);
+	uint16_t fqdn_len_aligned;
+	QDF_STATUS ret;
+
+	fqdn_len_aligned = roundup(mdns_info->fqdn_len, sizeof(uint32_t));
+	if (fqdn_len_aligned < mdns_info->fqdn_len) {
+		wmi_err_rl("integer overflow while rounding up data_len");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (fqdn_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) {
+		wmi_err_rl("wmi_max_msg_size overflow for given data_len");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	len += WMI_TLV_HDR_SIZE + fqdn_len_aligned;
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		wmi_err_rl("Failed to allocate wmi buffer");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = wmi_buf_data(buf);
+	cmd = (wmi_mdns_set_fqdn_cmd_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_mdns_set_fqdn_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+		       (wmi_mdns_set_fqdn_cmd_fixed_param));
+	cmd->vdev_id = mdns_info->vdev_id;
+	cmd->type = mdns_info->fqdn_type;
+	cmd->fqdn_len = mdns_info->fqdn_len;
+	buf_ptr += sizeof(*cmd);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, fqdn_len_aligned);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	qdf_mem_copy(buf_ptr, mdns_info->fqdn_data, cmd->fqdn_len);
+
+	wmi_mtrace(WMI_MDNS_SET_FQDN_CMDID, mdns_info->vdev_id,
+		   mdns_info->fqdn_type);
+
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_MDNS_SET_FQDN_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret))
+		wmi_buf_free(buf);
+
+	return ret;
+}
+
+/**
+ * send_set_mdns_response_cmd_tlv() - send set mDNS response cmd to fw
+ * @wmi_handle: wmi handle
+ * @mdns_info: mDNS config info
+ *
+ * Send WMI_MDNS_SET_RESPONSE_CMDID to fw.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+send_set_mdns_response_cmd_tlv(wmi_unified_t wmi_handle,
+			       struct mdns_config_info *mdns_info)
+{
+	wmi_buf_t buf;
+	uint8_t *buf_ptr;
+	wmi_mdns_set_resp_cmd_fixed_param *cmd;
+	uint16_t len = sizeof(*cmd);
+	uint16_t resp_len_aligned;
+	QDF_STATUS ret;
+
+	resp_len_aligned = roundup(mdns_info->answer_payload_len, sizeof(uint32_t));
+	if (resp_len_aligned < mdns_info->answer_payload_len) {
+		wmi_err_rl("integer overflow while rounding up data_len");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (resp_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) {
+		wmi_err_rl("wmi_max_msg_size overflow for given data_len");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	len += WMI_TLV_HDR_SIZE + resp_len_aligned;
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		wmi_err_rl("Failed to allocate wmi buffer");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	buf_ptr = wmi_buf_data(buf);
+	cmd = (wmi_mdns_set_resp_cmd_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_mdns_set_resp_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+		       (wmi_mdns_set_resp_cmd_fixed_param));
+	cmd->vdev_id = mdns_info->vdev_id;
+	cmd->AR_count = mdns_info->resource_record_count;
+	cmd->resp_len = mdns_info->answer_payload_len;
+	buf_ptr += sizeof(*cmd);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, resp_len_aligned);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	qdf_mem_copy(buf_ptr, mdns_info->answer_payload_data, cmd->resp_len);
+
+	wmi_mtrace(WMI_MDNS_SET_RESPONSE_CMDID, mdns_info->vdev_id, 0);
+
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_MDNS_SET_RESPONSE_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret))
+		wmi_buf_free(buf);
+
+	return ret;
+}
+
+/**
+ * send_set_mdns_offload_cmd_tlv() - send set mDNS offload cmd to fw
+ * @wmi_handle: wmi handle
+ * @mdns_info: mDNS config info
+ *
+ * Send WMI_MDNS_OFFLOAD_ENABLE_CMDID to fw.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+send_set_mdns_offload_cmd_tlv(wmi_unified_t wmi_handle,
+			      struct mdns_config_info *mdns_info)
+{
+	wmi_buf_t buf;
+	wmi_mdns_offload_cmd_fixed_param *cmd;
+	uint16_t len = sizeof(*cmd);
+	QDF_STATUS ret;
+
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		wmi_err_rl("Failed to allocate wmi buffer");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_mdns_offload_cmd_fixed_param *)wmi_buf_data(buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_mdns_offload_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+		       (wmi_mdns_offload_cmd_fixed_param));
+	cmd->vdev_id = mdns_info->vdev_id;
+	cmd->enable = mdns_info->enable;
+
+	wmi_mtrace(WMI_MDNS_OFFLOAD_ENABLE_CMDID, mdns_info->vdev_id, 0);
+
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_MDNS_OFFLOAD_ENABLE_CMDID);
+	if (QDF_IS_STATUS_ERROR(ret))
+		wmi_buf_free(buf);
+
+	return ret;
+}
+
+/**
+ * send_set_mdns_config_cmd_tlv() - send set mDNS config cmd to fw
+ * @wmi_handle: wmi handle
+ * @mdns_info: mdns config info
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+send_set_mdns_config_cmd_tlv(wmi_unified_t wmi_handle,
+			     struct mdns_config_info *mdns_info)
+{
+	QDF_STATUS ret;
+
+	if (!mdns_info->enable) {
+		ret = send_set_mdns_offload_cmd_tlv(wmi_handle, mdns_info);
+		if (QDF_IS_STATUS_ERROR(ret))
+			wmi_err_rl("Failed to send mDNS offload command. ret = %d", ret);
+
+		return ret;
+	}
+
+	ret = send_set_mdns_fqdn_cmd_tlv(wmi_handle, mdns_info);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		wmi_err_rl("Failed to send set fqdn command. ret = %d", ret);
+		return ret;
+	}
+
+	ret = send_set_mdns_response_cmd_tlv(wmi_handle, mdns_info);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		wmi_err_rl("Failed to send set mDNS response command. ret = %d", ret);
+		return ret;
+	}
+
+	ret = send_set_mdns_offload_cmd_tlv(wmi_handle, mdns_info);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		wmi_err_rl("Failed to send set mDNS offload  command. ret = %d", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static void wmi_fwol_attach_mdns_tlv(struct wmi_ops *ops)
+{
+	ops->send_set_mdns_config_cmd = send_set_mdns_config_cmd_tlv;
+}
+#else
+static void wmi_fwol_attach_mdns_tlv(struct wmi_ops *ops)
+{
+}
+#endif /* WLAN_FEATURE_MDNS_OFFLOAD */
+
 void wmi_fwol_attach_tlv(wmi_unified_t wmi_handle)
 {
 	struct wmi_ops *ops = wmi_handle->ops;
 
 	wmi_fwol_attach_elna_tlv(ops);
 	wmi_fwol_attach_dscp_tid_tlv(ops);
+	wmi_fwol_attach_mdns_tlv(ops);
 
 }