/*
 * Copyright (c) 2013-2018 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
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#include <osdep.h>
#include <wmi.h>
#include <wmi_unified_priv.h>
#include <wmi_unified_p2p_api.h>

/**
 * send_set_p2pgo_noa_req_cmd_tlv() - send p2p go noa request to fw
 * @wmi_handle: wmi handle
 * @noa: p2p power save parameters
 *
 * Return: CDF status
 */
static QDF_STATUS send_set_p2pgo_noa_req_cmd_tlv(wmi_unified_t wmi_handle,
						 struct p2p_ps_params *noa)
{
	wmi_p2p_set_noa_cmd_fixed_param *cmd;
	wmi_p2p_noa_descriptor *noa_discriptor;
	wmi_buf_t buf;
	uint8_t *buf_ptr;
	uint16_t len;
	QDF_STATUS status;
	uint32_t duration;

	WMI_LOGD("%s: Enter", __func__);
	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*noa_discriptor);
	buf = wmi_buf_alloc(wmi_handle, len);
	if (!buf) {
		status = QDF_STATUS_E_FAILURE;
		goto end;
	}

	buf_ptr = (uint8_t *)wmi_buf_data(buf);
	cmd = (wmi_p2p_set_noa_cmd_fixed_param *)buf_ptr;
	WMITLV_SET_HDR(&cmd->tlv_header,
		       WMITLV_TAG_STRUC_wmi_p2p_set_noa_cmd_fixed_param,
		       WMITLV_GET_STRUCT_TLVLEN
			       (wmi_p2p_set_noa_cmd_fixed_param));
	duration = (noa->count == 1) ? noa->single_noa_duration : noa->duration;
	cmd->vdev_id = noa->session_id;
	cmd->enable = (duration) ? true : false;
	cmd->num_noa = 1;

	WMITLV_SET_HDR((buf_ptr + sizeof(wmi_p2p_set_noa_cmd_fixed_param)),
		       WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_p2p_noa_descriptor));
	noa_discriptor = (wmi_p2p_noa_descriptor *)(buf_ptr +
						    sizeof
						    (wmi_p2p_set_noa_cmd_fixed_param)
						     + WMI_TLV_HDR_SIZE);
	WMITLV_SET_HDR(&noa_discriptor->tlv_header,
		       WMITLV_TAG_STRUC_wmi_p2p_noa_descriptor,
		       WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_noa_descriptor));
	noa_discriptor->type_count = noa->count;
	noa_discriptor->duration = duration;
	noa_discriptor->interval = noa->interval;
	noa_discriptor->start_time = 0;

	WMI_LOGI("SET P2P GO NOA:vdev_id:%d count:%d duration:%d interval:%d",
		 cmd->vdev_id, noa->count, noa_discriptor->duration,
		 noa->interval);
	wmi_mtrace(WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID, cmd->vdev_id, 0);
	status = wmi_unified_cmd_send(wmi_handle, buf, len,
				      WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID);
	if (QDF_IS_STATUS_ERROR(status)) {
		WMI_LOGE("Failed to send WMI_FWTEST_P2P_SET_NOA_PARAM_CMDID");
		wmi_buf_free(buf);
	}

end:
	WMI_LOGD("%s: Exit", __func__);
	return status;
}

/**
 * send_set_p2pgo_oppps_req_cmd_tlv() - send p2p go opp power save request to fw
 * @wmi_handle: wmi handle
 * @noa: p2p opp power save parameters
 *
 * Return: CDF status
 */
static QDF_STATUS send_set_p2pgo_oppps_req_cmd_tlv(wmi_unified_t wmi_handle,
						   struct p2p_ps_params *oppps)
{
	wmi_p2p_set_oppps_cmd_fixed_param *cmd;
	wmi_buf_t buf;
	QDF_STATUS status;

	WMI_LOGD("%s: Enter", __func__);
	buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
	if (!buf) {
		status = QDF_STATUS_E_FAILURE;
		goto end;
	}

	cmd = (wmi_p2p_set_oppps_cmd_fixed_param *) wmi_buf_data(buf);
	WMITLV_SET_HDR(&cmd->tlv_header,
		       WMITLV_TAG_STRUC_wmi_p2p_set_oppps_cmd_fixed_param,
		       WMITLV_GET_STRUCT_TLVLEN(
					wmi_p2p_set_oppps_cmd_fixed_param));
	cmd->vdev_id = oppps->session_id;
	if (oppps->ctwindow)
		WMI_UNIFIED_OPPPS_ATTR_ENABLED_SET(cmd);

	WMI_UNIFIED_OPPPS_ATTR_CTWIN_SET(cmd, oppps->ctwindow);
	WMI_LOGI("SET P2P GO OPPPS:vdev_id:%d ctwindow:%d",
		 cmd->vdev_id, oppps->ctwindow);
	wmi_mtrace(WMI_P2P_SET_OPPPS_PARAM_CMDID, cmd->vdev_id, 0);
	status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd),
				      WMI_P2P_SET_OPPPS_PARAM_CMDID);
	if (QDF_IS_STATUS_ERROR(status)) {
		WMI_LOGE("Failed to send WMI_P2P_SET_OPPPS_PARAM_CMDID");
		wmi_buf_free(buf);
	}

end:
	WMI_LOGD("%s: Exit", __func__);
	return status;
}

/**
 * extract_p2p_noa_ev_param_tlv() - extract p2p noa information from event
 * @wmi_handle: wmi handle
 * @param evt_buf: pointer to event buffer
 * @param param: Pointer to hold p2p noa info
 *
 * Return: QDF_STATUS_SUCCESS for success or error code
 */
static QDF_STATUS extract_p2p_noa_ev_param_tlv(
	wmi_unified_t wmi_handle, void *evt_buf,
	struct p2p_noa_info *param)
{
	WMI_P2P_NOA_EVENTID_param_tlvs *param_tlvs;
	wmi_p2p_noa_event_fixed_param *fixed_param;
	uint8_t i;
	wmi_p2p_noa_info *wmi_noa_info;
	uint8_t *buf_ptr;
	uint32_t descriptors;

	param_tlvs = (WMI_P2P_NOA_EVENTID_param_tlvs *)evt_buf;
	if (!param_tlvs) {
		WMI_LOGE("%s: Invalid P2P NoA event buffer", __func__);
		return QDF_STATUS_E_INVAL;
	}

	if (!param) {
		WMI_LOGE("noa information param is null");
		return QDF_STATUS_E_INVAL;
	}

	fixed_param = param_tlvs->fixed_param;
	buf_ptr = (uint8_t *) fixed_param;
	buf_ptr += sizeof(wmi_p2p_noa_event_fixed_param);
	wmi_noa_info = (wmi_p2p_noa_info *) (buf_ptr);

	if (!WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(wmi_noa_info)) {
		WMI_LOGE("%s: noa attr is not modified", __func__);
		return QDF_STATUS_E_INVAL;
	}

	param->vdev_id = fixed_param->vdev_id;
	param->index =
		(uint8_t)WMI_UNIFIED_NOA_ATTR_INDEX_GET(wmi_noa_info);
	param->opps_ps =
		(uint8_t)WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(wmi_noa_info);
	param->ct_window =
		(uint8_t)WMI_UNIFIED_NOA_ATTR_CTWIN_GET(wmi_noa_info);
	descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(wmi_noa_info);
	param->num_desc = (uint8_t)descriptors;
	if (param->num_desc > WMI_P2P_MAX_NOA_DESCRIPTORS) {
		WMI_LOGE("%s: invalid num desc:%d", __func__,
			 param->num_desc);
		return QDF_STATUS_E_INVAL;
	}

	WMI_LOGD("%s:index %u, opps_ps %u, ct_window %u, num_descriptors = %u",
		 __func__,
		 param->index, param->opps_ps, param->ct_window,
		 param->num_desc);
	for (i = 0; i < param->num_desc; i++) {
		param->noa_desc[i].type_count =
			(uint8_t)wmi_noa_info->noa_descriptors[i].
			type_count;
		param->noa_desc[i].duration =
			wmi_noa_info->noa_descriptors[i].duration;
		param->noa_desc[i].interval =
			wmi_noa_info->noa_descriptors[i].interval;
		param->noa_desc[i].start_time =
			wmi_noa_info->noa_descriptors[i].start_time;
		WMI_LOGD("%s:NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u",
			__func__, i, param->noa_desc[i].type_count,
			param->noa_desc[i].duration,
			param->noa_desc[i].interval,
			param->noa_desc[i].start_time);
	}

	return QDF_STATUS_SUCCESS;
}

static QDF_STATUS
send_set_mac_addr_rx_filter_cmd_tlv(wmi_unified_t wmi_handle,
				    struct p2p_set_mac_filter *param)
{
	wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *cmd;
	uint32_t len;
	wmi_buf_t buf;
	int ret;

	if (!wmi_handle) {
		WMI_LOGE("WMA context is invald!");
		return QDF_STATUS_E_INVAL;
	}

	len = sizeof(*cmd);
	buf = wmi_buf_alloc(wmi_handle, len);
	if (!buf) {
		WMI_LOGE("Failed allocate wmi buffer");
		return QDF_STATUS_E_NOMEM;
	}

	cmd = (wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param *)
		wmi_buf_data(buf);

	WMITLV_SET_HDR(
	   &cmd->tlv_header,
	   WMITLV_TAG_STRUC_wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param,
	WMITLV_GET_STRUCT_TLVLEN(
			wmi_vdev_add_mac_addr_to_rx_filter_cmd_fixed_param));

	cmd->vdev_id = param->vdev_id;
	cmd->freq = param->freq;
	WMI_CHAR_ARRAY_TO_MAC_ADDR(param->mac, &cmd->mac_addr);
	if (param->set)
		cmd->enable = 1;
	else
		cmd->enable = 0;
	WMI_LOGD("set random mac rx vdev %d freq %d set %d %pM",
		 param->vdev_id, param->freq, param->set, param->mac);
	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
				   WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_CMDID);
	if (ret) {
		WMI_LOGE("Failed to send action frame random mac cmd");
		wmi_buf_free(buf);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}

static QDF_STATUS extract_mac_addr_rx_filter_evt_param_tlv(
	wmi_unified_t wmi_handle, void *evt_buf,
	struct p2p_set_mac_filter_evt *param)
{
	WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID_param_tlvs *param_buf;
	wmi_vdev_add_mac_addr_to_rx_filter_status_event_fixed_param *event;

	param_buf =
		(WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_STATUS_EVENTID_param_tlvs *)
		evt_buf;
	if (!param_buf) {
		WMI_LOGE("Invalid action frame filter mac event");
		return QDF_STATUS_E_INVAL;
	}
	event = param_buf->fixed_param;
	if (!event) {
		WMI_LOGE("Invalid fixed param");
		return QDF_STATUS_E_INVAL;
	}
	param->vdev_id = event->vdev_id;
	param->status = event->status;

	return QDF_STATUS_SUCCESS;
}

#ifdef FEATURE_P2P_LISTEN_OFFLOAD
/**
 * send_p2p_lo_start_cmd_tlv() - send p2p lo start request to fw
 * @wmi_handle: wmi handle
 * @param: p2p listen offload start parameters
 *
 * Return: QDF status
 */
static QDF_STATUS send_p2p_lo_start_cmd_tlv(wmi_unified_t wmi_handle,
					    struct p2p_lo_start *param)
{
	wmi_buf_t buf;
	wmi_p2p_lo_start_cmd_fixed_param *cmd;
	int32_t len = sizeof(*cmd);
	uint8_t *buf_ptr;
	QDF_STATUS status;
	int device_types_len_aligned;
	int probe_resp_len_aligned;

	if (!param) {
		WMI_LOGE("lo start param is null");
		return QDF_STATUS_E_INVAL;
	}

	WMI_LOGD("%s: vdev_id:%d", __func__, param->vdev_id);

	device_types_len_aligned =
		qdf_roundup(param->dev_types_len,
			    sizeof(uint32_t));
	probe_resp_len_aligned =
		qdf_roundup(param->probe_resp_len,
			    sizeof(uint32_t));

	len += 2 * WMI_TLV_HDR_SIZE + device_types_len_aligned +
			probe_resp_len_aligned;

	buf = wmi_buf_alloc(wmi_handle, len);
	if (!buf) {
		return QDF_STATUS_E_NOMEM;
	}

	cmd = (wmi_p2p_lo_start_cmd_fixed_param *)wmi_buf_data(buf);
	buf_ptr = (uint8_t *) wmi_buf_data(buf);

	WMITLV_SET_HDR(&cmd->tlv_header,
		 WMITLV_TAG_STRUC_wmi_p2p_lo_start_cmd_fixed_param,
		 WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_lo_start_cmd_fixed_param));

	cmd->vdev_id = param->vdev_id;
	cmd->ctl_flags = param->ctl_flags;
	cmd->channel = param->freq;
	cmd->period = param->period;
	cmd->interval = param->interval;
	cmd->count = param->count;
	cmd->device_types_len = param->dev_types_len;
	cmd->prob_resp_len = param->probe_resp_len;

	buf_ptr += sizeof(wmi_p2p_lo_start_cmd_fixed_param);
	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
		       device_types_len_aligned);
	buf_ptr += WMI_TLV_HDR_SIZE;
	qdf_mem_copy(buf_ptr, param->device_types,
		     param->dev_types_len);

	buf_ptr += device_types_len_aligned;
	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
		       probe_resp_len_aligned);
	buf_ptr += WMI_TLV_HDR_SIZE;
	qdf_mem_copy(buf_ptr, param->probe_resp_tmplt,
		     param->probe_resp_len);

	WMI_LOGD("%s: Sending WMI_P2P_LO_START command, channel=%d, period=%d, interval=%d, count=%d", __func__,
		 cmd->channel, cmd->period, cmd->interval, cmd->count);

	wmi_mtrace(WMI_P2P_LISTEN_OFFLOAD_START_CMDID, cmd->vdev_id, 0);
	status = wmi_unified_cmd_send(wmi_handle,
				      buf, len,
				      WMI_P2P_LISTEN_OFFLOAD_START_CMDID);
	if (status != QDF_STATUS_SUCCESS) {
		WMI_LOGE("%s: Failed to send p2p lo start: %d",
			 __func__, status);
		wmi_buf_free(buf);
		return status;
	}

	WMI_LOGD("%s: Successfully sent WMI_P2P_LO_START", __func__);

	return QDF_STATUS_SUCCESS;
}

/**
 * send_p2p_lo_stop_cmd_tlv() - send p2p lo stop request to fw
 * @wmi_handle: wmi handle
 * @param: p2p listen offload stop parameters
 *
 * Return: QDF status
 */
static QDF_STATUS send_p2p_lo_stop_cmd_tlv(wmi_unified_t wmi_handle,
					   uint8_t vdev_id)
{
	wmi_buf_t buf;
	wmi_p2p_lo_stop_cmd_fixed_param *cmd;
	int32_t len;
	QDF_STATUS status;

	WMI_LOGD("%s: vdev_id:%d", __func__, vdev_id);

	len = sizeof(*cmd);
	buf = wmi_buf_alloc(wmi_handle, len);
	if (!buf) {
		return QDF_STATUS_E_NOMEM;
	}
	cmd = (wmi_p2p_lo_stop_cmd_fixed_param *)wmi_buf_data(buf);

	WMITLV_SET_HDR(&cmd->tlv_header,
		WMITLV_TAG_STRUC_wmi_p2p_lo_stop_cmd_fixed_param,
		WMITLV_GET_STRUCT_TLVLEN(wmi_p2p_lo_stop_cmd_fixed_param));

	cmd->vdev_id = vdev_id;

	WMI_LOGD("%s: Sending WMI_P2P_LO_STOP command", __func__);

	wmi_mtrace(WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID, cmd->vdev_id, 0);
	status = wmi_unified_cmd_send(wmi_handle,
				      buf, len,
				      WMI_P2P_LISTEN_OFFLOAD_STOP_CMDID);
	if (status != QDF_STATUS_SUCCESS) {
		WMI_LOGE("%s: Failed to send p2p lo stop: %d",
			 __func__, status);
		wmi_buf_free(buf);
		return status;
	}

	WMI_LOGD("%s: Successfully sent WMI_P2P_LO_STOP", __func__);

	return QDF_STATUS_SUCCESS;
}

/**
 * extract_p2p_lo_stop_ev_param_tlv() - extract p2p lo stop
 * information from event
 * @wmi_handle: wmi handle
 * @param evt_buf: pointer to event buffer
 * @param param: Pointer to hold p2p lo stop event information
 *
 * Return: QDF_STATUS_SUCCESS for success or error code
 */
static QDF_STATUS extract_p2p_lo_stop_ev_param_tlv(
	wmi_unified_t wmi_handle, void *evt_buf,
	struct p2p_lo_event *param)
{
	WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *param_tlvs;
	wmi_p2p_lo_stopped_event_fixed_param *lo_param;

	param_tlvs = (WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID_param_tlvs *)
					evt_buf;
	if (!param_tlvs) {
		WMI_LOGE("%s: Invalid P2P lo stop event buffer", __func__);
		return QDF_STATUS_E_INVAL;
	}

	if (!param) {
		WMI_LOGE("lo stop event param is null");
		return QDF_STATUS_E_INVAL;
	}

	lo_param = param_tlvs->fixed_param;
	param->vdev_id = lo_param->vdev_id;
	param->reason_code = lo_param->reason;
	WMI_LOGD("%s: vdev_id:%d, reason:%d", __func__,
		 param->vdev_id, param->reason_code);

	return QDF_STATUS_SUCCESS;
}

void wmi_p2p_listen_offload_attach_tlv(wmi_unified_t wmi_handle)
{
	struct wmi_ops *ops = wmi_handle->ops;

	ops->send_p2p_lo_start_cmd = send_p2p_lo_start_cmd_tlv;
	ops->send_p2p_lo_stop_cmd = send_p2p_lo_stop_cmd_tlv;
	ops->extract_p2p_lo_stop_ev_param =
			extract_p2p_lo_stop_ev_param_tlv;
}
#endif /* FEATURE_P2P_LISTEN_OFFLOAD */

void wmi_p2p_attach_tlv(wmi_unified_t wmi_handle)
{
	struct wmi_ops *ops = wmi_handle->ops;

	ops->send_set_p2pgo_oppps_req_cmd = send_set_p2pgo_oppps_req_cmd_tlv;
	ops->send_set_p2pgo_noa_req_cmd = send_set_p2pgo_noa_req_cmd_tlv;
	ops->extract_p2p_noa_ev_param = extract_p2p_noa_ev_param_tlv;
	ops->set_mac_addr_rx_filter = send_set_mac_addr_rx_filter_cmd_tlv,
	ops->extract_mac_addr_rx_filter_evt_param =
				extract_mac_addr_rx_filter_evt_param_tlv,
	wmi_p2p_listen_offload_attach_tlv(wmi_handle);
}

