/*
 * RWL module  of
 * Broadcom 802.11bang Networking Device Driver
 *
 * Broadcom Proprietary and Confidential. Copyright (C) 2017,
 * All Rights Reserved.
 * 
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom;
 * the contents of this file may not be disclosed to third parties, copied
 * or duplicated in any form, in whole or in part, without the prior
 * written permission of Broadcom.
 *
 *
 * <<Broadcom-WL-IPTag/Proprietary:>>
 *
 * $Id: wlc_rwl.c 619400 2016-02-16 13:52:43Z $*
 *
 */

/**
 * @file
 * @brief
 * Remote WL utility support
 */


#include <wlc_cfg.h>

#ifndef WLRWL
#error "Cannot use this file without WLRWL defined"
#endif

#include <typedefs.h>
#include <bcmdefs.h>
#include <osl.h>
#include <bcmutils.h>
#include <siutils.h>
#include <wlioctl.h>
#include <proto/802.11.h>
#include <d11.h>
#include <wlc_rate.h>
#include <wlc_pub.h>
#include <wlc_bsscfg.h>
#include <wlc.h>
#include <wlc_phy_hal.h>
#include <wl_export.h>

#include <wlc_rwl.h>

enum {
	IOV_RWLVS_ACTION_FRAME, /* RWL Vendor specific queue */
	IOV_RWLDONGLE_DATA,
	IOV_DONGLE_FLAG,
	IOV_LAST
};

static const bcm_iovar_t rwl_iovars[] = {
	{"rwlwifivsaction", IOV_RWLVS_ACTION_FRAME,
	(0), 0, IOVT_BUFFER, RWL_WIFI_ACTION_FRAME_SIZE
	},
#ifdef RWL_DONGLE
	{"remote", IOV_RWLDONGLE_DATA, 0, 0, IOVT_BUFFER, 1040},
	{"dongleset", IOV_DONGLE_FLAG, 0, 0, IOVT_UINT32, 0},
#endif /* RWL_DONGLE */
	{NULL, 0, 0, 0, 0, 0 }
};

#ifdef RWL_DONGLE
int g_rwl_dongle_flag = 0;
#endif

/* rwl function prototypes */

static int wlc_rwl_doiovar(void *hdl, uint32 actionid,
	void *params, uint p_len, void *arg, uint len,
	uint val_size, struct wlc_if *wlcif);

rwl_info_t *
BCMATTACHFN(wlc_rwl_attach)(wlc_info_t *wlc)
{
	rwl_info_t *ri;
	wlc_pub_t *pub = wlc->pub;

	WL_TRACE(("wl: wlc_rwl_attach\n"));

	if ((ri = (rwl_info_t *)MALLOCZ(pub->osh, sizeof(rwl_info_t))) == NULL) {
		WL_ERROR(("wlc_rwl_attach: out of memory, malloced %d bytes", MALLOCED(pub->osh)));
		goto fail;
	}
	ri->wlc = (void*) wlc;
	ri->pub = pub;

	/* register module */
	if (wlc_module_register(pub, rwl_iovars, "rwl", ri, wlc_rwl_doiovar,
	                        NULL, NULL, NULL)) {
		WL_ERROR(("wl%d: rwl wlc_module_register() failed\n", pub->unit));
		goto fail;
	}

	return ri;

fail:
	if (ri) {
		MFREE(ri->pub->osh, ri, sizeof(rwl_info_t));
	}
	return NULL;
}

int
BCMATTACHFN(wlc_rwl_detach)(rwl_info_t *ri)
{
	wlc_info_t *wlc;
	rwl_request_t *cleanup_node = (rwl_request_t *)(NULL);

	WL_TRACE(("wl: %s: ri = %p\n", __FUNCTION__, OSL_OBFUSCATE_BUF(ri)));

	wlc = (wlc_info_t*) ri->wlc;
	wlc_module_unregister(ri->pub, "rwl", ri);

	/* Clean up the queue only during the driver cleanup */
	while (ri->rwl_first_action_node != NULL) {
		cleanup_node = ri->rwl_first_action_node->next_request;
		MFREE(wlc->osh, ri->rwl_first_action_node,
		sizeof(rwl_request_t));
		ri->rwl_first_action_node = cleanup_node;
	}

	MFREE(ri->pub->osh, ri, sizeof(rwl_info_t));

	return 0;
}

void
BCMINITFN(wlc_rwl_init)(rwl_info_t *ri)
{
}

void
BCMUNINITFN(wlc_rwl_deinit)(rwl_info_t *ri)
{
}

void
wlc_rwl_up(wlc_info_t *wlc)
{
}

uint
wlc_rwl_down(wlc_info_t *wlc)
{
	return 0;
}

/* Handling RWL related iovars */
static int
wlc_rwl_doiovar(void *hdl, uint32 actionid,
	void *params, uint p_len, void *arg, uint len, uint val_size, struct wlc_if *wlcif)
{
	rwl_info_t *ri = (rwl_info_t *)hdl;
	int err = 0;
	int32 int_val;

	if (p_len >= (int)sizeof(int_val))
		bcopy(params, &int_val, sizeof(int_val));

	switch (actionid) {
		case IOV_GVAL(IOV_RWLVS_ACTION_FRAME):
		{
			dot11_action_wifi_vendor_specific_t *list;
			rwl_request_t *intermediate_node;
			list = (dot11_action_wifi_vendor_specific_t*)arg;
			if (ri->rwl_first_action_node != NULL) {
				/* pop from the list and copy to user buffer
				 * and move the node to next node
				 */
				bcopy((char*)&ri->rwl_first_action_node->action_frame,
				(char*)list, RWL_WIFI_ACTION_FRAME_SIZE);
				intermediate_node = ri->rwl_first_action_node->next_request;
				MFREE(ri->wlc->osh, ri->rwl_first_action_node,
				sizeof(rwl_request_t));
				ri->rwl_first_action_node = intermediate_node;
			}
			break;
		}

#ifdef RWL_DONGLE
	case IOV_GVAL(IOV_RWLDONGLE_DATA):
		/* Wait for serial protocol layer to set the packet_status bit
		  *  if bit set then copy the data in arg
		  *  reset the packet_status bit
		  * if not set send 0 to server application
		  */
		if (g_rwl_dongle_data.packet_status) {
			if (g_rwl_dongle_data.packet_buf != NULL) {
				bcopy(g_rwl_dongle_data.packet_buf, (char*)arg,
				 g_rwl_dongle_data.packet_len);
				MFREE(NULL, g_rwl_dongle_data.packet_buf,
				 g_rwl_dongle_data.packet_len);
			}
			g_rwl_dongle_data.packet_status = 0;
		} else {
			uint status = 0;
			bcopy(&status, arg, sizeof(status));
		}
		break;
	case IOV_SVAL(IOV_RWLDONGLE_DATA):
		/* Transmit the server response to client
		 * Code jumps to hnd_cons.c at this point
		 */
		remote_uart_tx(arg);
		break;
	case IOV_GVAL(IOV_DONGLE_FLAG):
		{
			*ret_int_ptr = g_rwl_dongle_flag;
			break;
		}
	case IOV_SVAL(IOV_DONGLE_FLAG):
		{
			g_rwl_dongle_flag = int_val;
			break;
		}
#endif /* RWL_DONGLE */

	default:
		err = BCME_UNSUPPORTED;
		break;
	}

	return err;
}

#ifdef WIFI_REFLECTOR
/* Allocate and initialize an wifi action frame */
static dot11_action_wifi_vendor_specific_t *
allocate_action_frame(wlc_info_t *wlc)
{
	dot11_action_wifi_vendor_specific_t *frame;

	if ((frame = (dot11_action_wifi_vendor_specific_t *)
	     MALLOC(wlc->osh, RWL_WIFI_ACTION_FRAME_SIZE)) == NULL)
		return NULL;

	frame->category  = DOT11_ACTION_CAT_VS;
	frame->OUI[0]    = RWL_WIFI_OUI_BYTE0;
	frame->OUI[1]    = RWL_WIFI_OUI_BYTE1;
	frame->OUI[2]    = RWL_WIFI_OUI_BYTE2;
	frame->type      = RWL_WIFI_DEFAULT_TYPE;
	frame->subtype   = RWL_WIFI_DEFAULT_SUBTYPE;

	return frame;
}

/* Send out the action frame */
static int
rwl_send_wifi_response(wlc_info_t *wlc,
                       dot11_action_wifi_vendor_specific_t *response,
                       const struct ether_addr * dest_addr_ptr)
{
	uint32 err = 0;

#ifdef WIFI_ACT_FRAME
	wl_action_frame_t *action_frame;

	if ((action_frame = (wl_action_frame_t *)
	     MALLOC(wlc->osh, sizeof(wl_action_frame_t))) == NULL)
		return BCME_NOMEM;

	memcpy(&action_frame->data, response, RWL_WIFI_ACTION_FRAME_SIZE);

	/* Set the dest addr */
	memcpy(&action_frame->da, dest_addr_ptr, ETHER_ADDR_LEN);

	/* set the length */
	action_frame->len = RWL_WIFI_ACTION_FRAME_SIZE;

	wlc_send_action_frame(wlc, wlc->cfg, NULL, (void *)action_frame);

	MFREE(wlc->osh, action_frame, sizeof(wl_action_frame_t));
#endif /* WIFI_ACT_FRAME */

	return err;
}

/* Function to specify the client that an invalid wl command has been received
 * This command cannot be processed by the In-dongle reflector.
 */
static int
rwl_wifi_send_error(wlc_info_t *wlc, const struct ether_addr * dest_addr_ptr)
{
	int err;
	dot11_action_wifi_vendor_specific_t *response;
	rem_ioctl_t rem_cdc, *rem_ptr = &rem_cdc;
	const char *errmsg = "In-dongle does not support shell/DHD/ASD\n";

	if ((response = allocate_action_frame(wlc)) == NULL)
		return BCME_NOMEM;

	rem_ptr->msg.cmd = -1;
	rem_ptr->msg.len = rem_ptr->data_len = strlen(errmsg) + 1;
	rem_ptr->msg.flags = REMOTE_REPLY;

	memcpy(&response->data[RWL_WIFI_CDC_HEADER_OFFSET], rem_ptr, REMOTE_SIZE);
	memcpy(&response->data[REMOTE_SIZE], errmsg, rem_ptr->data_len);

	err = rwl_send_wifi_response(wlc, response, dest_addr_ptr);

	MFREE(wlc->osh, response, sizeof(dot11_action_wifi_vendor_specific_t));

	return err;
}

/* Function which responds to the findserver command when sent by the client
 * application. The client sends out packet in every channel available.
 * we recieve the packet on a particular channel we respond back by sending
 * our channel number
 */
static int
rwl_wifi_findserver_response(wlc_info_t *wlc,
                             dot11_action_wifi_vendor_specific_t *response,
                             const struct ether_addr * dest_addr_ptr)
{
	int err;
	channel_info_t ci;
	uint32 tx_count;

	/* Query the server channel */
	response->type = RWL_WIFI_FOUND_PEER;

	err = wlc_ioctl(wlc, WLC_GET_CHANNEL, &ci, sizeof(ci), NULL);
	if (err)
		return err;

	/* Match the client channel with our channel */
	if (response->data[RWL_WIFI_CLIENT_CHANNEL_OFFSET] == ci.hw_channel) {
		response->data[RWL_WIFI_SERVER_CHANNEL_OFFSET] = ci.hw_channel;
		for (tx_count = 0; tx_count < RWL_WIFI_SEND; ++tx_count) {
			err = rwl_send_wifi_response(wlc, response, dest_addr_ptr);
			if (err)
				break;
		}
	}

	return err;
}

/* Function which responds to the set command sent by the client.
 * We call wlc_ioctl to set the specified value and send back the
 * results of setting to the client
 */
static int
rwl_wifi_set_cmd_response(wlc_info_t *wlc,
                          rem_packet_t *rem_packet_ptr,
                          const struct ether_addr * dest_addr_ptr)
{
	int err;
	rem_ioctl_t rem_cdc, *rem_ptr = &rem_cdc;
	rem_ioctl_t *rem_ioctl_ptr = (rem_ioctl_t *)&(rem_packet_ptr->rem_cdc);

	dot11_action_wifi_vendor_specific_t *rem_wifi_send = allocate_action_frame(wlc);

	if (rem_wifi_send == NULL)
		return BCME_NOMEM;

	/* Execute the command locally */

	err = wlc_ioctl(wlc, rem_ioctl_ptr->msg.cmd, rem_packet_ptr->message,
	                rem_ioctl_ptr->msg.len, NULL);

	rem_ptr->msg.cmd = err;
	rem_ptr->msg.len = 0;
	rem_ptr->msg.flags = REMOTE_REPLY;
	rem_ptr->data_len = 0;

	memcpy(&rem_wifi_send->data[RWL_WIFI_CDC_HEADER_OFFSET], rem_ptr, REMOTE_SIZE);

	err = rwl_send_wifi_response(wlc, rem_wifi_send, dest_addr_ptr);

	MFREE(wlc->osh, rem_wifi_send, sizeof(*rem_wifi_send));

	return err;
}

/* This function responds to the remote wl get command.
 * On reception of packet we call wlc_ioctl() to get the results.
 * If the result fits into a single packet we send it directly
 * else we fragment the results and send it though multiple packets
 */
static int
rwl_wifi_get_cmd_response(wlc_info_t *wlc,
                          rem_packet_t *rem_packet_ptr,
                          const struct ether_addr * dest_addr_ptr)
{
	int err;
	uint32 tx_count;
	uint32 totalframes;
	uchar *buf;
	rem_ioctl_t rem_cdc, *rem_ptr = &rem_cdc;
	rem_ioctl_t *rem_ioctl_ptr = (rem_ioctl_t *)&(rem_packet_ptr->rem_cdc);
	dot11_action_wifi_vendor_specific_t *rem_wifi_send = allocate_action_frame(wlc);

	if (rem_wifi_send == NULL)
		return BCME_NOMEM;

	if ((buf = MALLOC(wlc->osh, rem_ioctl_ptr->msg.len)) == NULL) {
		MFREE(wlc->osh, rem_wifi_send, sizeof(*rem_wifi_send));
		return BCME_NOMEM;
	}

	/* Execute the command locally */
	memcpy(buf, rem_packet_ptr->message, rem_ioctl_ptr->data_len);
	err = wlc_ioctl(wlc, rem_ioctl_ptr->msg.cmd, (void*)buf,
	                rem_ioctl_ptr->msg.len, NULL);

	rem_ptr->msg.cmd = err;
	rem_ptr->msg.len = rem_ioctl_ptr->msg.len;
	rem_ptr->msg.flags = REMOTE_REPLY;
	rem_ptr->data_len = rem_ioctl_ptr->msg.len;

	if (rem_ioctl_ptr->msg.len > RWL_WIFI_FRAG_DATA_SIZE) {
		totalframes = rem_ptr->msg.len / RWL_WIFI_FRAG_DATA_SIZE;
		memcpy(&rem_wifi_send->data[RWL_WIFI_CDC_HEADER_OFFSET], rem_ptr, REMOTE_SIZE);
		memcpy((char*)&rem_wifi_send->data[REMOTE_SIZE], &buf[0], RWL_WIFI_FRAG_DATA_SIZE);
		rem_wifi_send->type = RWL_ACTION_WIFI_FRAG_TYPE;
		rem_wifi_send->subtype = RWL_WIFI_DEFAULT_SUBTYPE;

		if ((err = rwl_send_wifi_response (wlc, rem_wifi_send, dest_addr_ptr)) != 0)
			goto exit;

		/* Send remaining bytes in fragments */
		for (tx_count = 1; tx_count < totalframes; tx_count++) {
			rem_wifi_send->type = RWL_ACTION_WIFI_FRAG_TYPE;
			rem_wifi_send->subtype = tx_count;
			/* First frame onwards , buf contains only data */
			memcpy((char*)&rem_wifi_send->data,
			       &buf[tx_count*RWL_WIFI_FRAG_DATA_SIZE], RWL_WIFI_FRAG_DATA_SIZE);
			if ((err = rwl_send_wifi_response (wlc,
			                                   rem_wifi_send,
			                                   dest_addr_ptr)) != 0) {
				goto exit;
			}

		}
		/* Check for remaining bytes to send */
		if ((totalframes * RWL_WIFI_FRAG_DATA_SIZE) != rem_ptr->msg.len) {
			rem_wifi_send->type = RWL_ACTION_WIFI_FRAG_TYPE;
			rem_wifi_send->subtype = tx_count;
			memcpy((char*)&rem_wifi_send->data,
			       &buf[tx_count*RWL_WIFI_FRAG_DATA_SIZE],
			       (rem_ptr->msg.len - (tx_count*RWL_WIFI_FRAG_DATA_SIZE)));
			err = rwl_send_wifi_response(wlc, rem_wifi_send, dest_addr_ptr);
		}
	} else {
		/* Packet fits into a single frame; send it off at one go */
		memcpy(&rem_wifi_send->data[RWL_WIFI_CDC_HEADER_OFFSET], rem_ptr, REMOTE_SIZE);
		memcpy((char*)&rem_wifi_send->data[REMOTE_SIZE],
		       buf, rem_ioctl_ptr->msg.len);

		err = rwl_send_wifi_response(wlc, rem_wifi_send, dest_addr_ptr);
	}
exit:
	MFREE(wlc->osh, rem_wifi_send,
		sizeof(dot11_action_wifi_vendor_specific_t));

	MFREE(wlc->osh, buf, rem_ioctl_ptr->msg.len);

	return err;
}
#endif /* WIFI_REFLECTOR */

/* If the management frame is an RWL action frame then the action frame will be queued.
 * This queued frame will be read by the application.
 */
void
wlc_recv_wifi_mgmtact(rwl_info_t *rwlh, uint8 *body, const struct ether_addr *sa)
{

#ifdef WIFI_REFLECTOR
	rem_packet_t *rem_packet_ptr;
	rem_ioctl_t *rem_ioctl_ptr;
#endif
	rwl_request_t *rwl_new_action_node =
	(rwl_request_t *)(NULL);
	wlc_info_t *wlc = (wlc_info_t*) rwlh->wlc;

	if ((rwl_new_action_node = (rwl_request_t*)MALLOC(wlc->osh,
		sizeof(rwl_request_t))) == NULL) {
		return;
	}

	bcopy((char*)body, (char*)&rwl_new_action_node->action_frame, RWL_WIFI_ACTION_FRAME_SIZE);
#ifdef WIFI_REFLECTOR
	rem_packet_ptr = (rem_packet_t *)&(rwl_new_action_node->action_frame.data[0]);
	rem_ioctl_ptr = (rem_ioctl_t *)&(rem_packet_ptr->rem_cdc);

	/* Do not queue the packets if it is an RWL command.
	 * Just parse, process and send back the results depending
	 * upon the query packet. Do not queue any packets, as
	 * after a certain number of packets the dongle memory would
	 * be exhausted.
	 */
	if (rem_ioctl_ptr->msg.flags & REMOTE_FINDSERVER_CMD)
		rwl_wifi_findserver_response(wlc, &rwl_new_action_node->action_frame, sa);
	else if (rem_ioctl_ptr->msg.flags & REMOTE_SET_CMD)
		rwl_wifi_set_cmd_response(wlc, rem_packet_ptr, sa);
	else if (rem_ioctl_ptr->msg.flags & REMOTE_GET_CMD)
		rwl_wifi_get_cmd_response(wlc, rem_packet_ptr, sa);
	else
		rwl_wifi_send_error(wlc, sa);

	MFREE(wlc->osh, rwl_new_action_node, sizeof(rwl_request_t));
	return;

#endif /* WIFI_REFLECTOR */
	if (rwlh->rwl_first_action_node == NULL) {
		 rwlh->rwl_first_action_node = rwl_new_action_node;
		 rwlh->rwl_last_action_node = rwlh->rwl_first_action_node;
		 rwlh->rwl_first_action_node->next_request = NULL;
	} else {
		/* insert the all incoming frame at the end of the queue */
		rwlh->rwl_last_action_node->next_request = rwl_new_action_node;
		rwlh->rwl_last_action_node = rwl_new_action_node;
		rwlh->rwl_last_action_node->next_request = NULL;
	}
}
