/*
 * BT-AMP support routines
 *
 * Copyright 1999-2016, Broadcom Corporation
 * All rights reserved,
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *    1. Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation
 *       and/or other materials provided with the distribution.
 *
 * This software is provided by the copyright holder "as is" and any express or
 * implied warranties, including, but not limited to, the implied warranties of
 * merchantability and fitness for a particular purpose are disclaimed. In no event
 * shall copyright holder be liable for any direct, indirect, incidental, special,
 * exemplary, or consequential damages (including, but not limited to, procurement
 * of substitute goods or services; loss of use, data, or profits; or business
 * interruption) however caused and on any theory of liability, whether in
 * contract, strict liability, or tort (including negligence or otherwise) arising
 * in any way out of the use of this software, even if advised of the possibility
 * of such damage
 *
 *
 * <<Broadcom-WL-IPTag/Open:>>
 *
 * $Id: dhd_bta.c 514727 2014-11-12 03:02:48Z $
 */
#error "WLBTAMP is not defined"

#include <typedefs.h>
#include <osl.h>
#include <bcmcdc.h>
#include <bcmutils.h>
#include <bcmendian.h>
#include <proto/802.11.h>
#include <proto/802.11_bta.h>
#include <proto/bt_amp_hci.h>
#include <dngl_stats.h>
#include <dhd.h>
#include <dhd_bus.h>
#include <dhd_proto.h>
#include <dhdioctl.h>
#include <dhd_dbg.h>

#include <dhd_bta.h>


#ifdef SEND_HCI_CMD_VIA_IOCTL
#define BTA_HCI_CMD_MAX_LEN HCI_CMD_PREAMBLE_SIZE + HCI_CMD_DATA_SIZE

/* Send HCI cmd via wl iovar HCI_cmd to the dongle. */
int
dhd_bta_docmd(dhd_pub_t *pub, void *cmd_buf, uint cmd_len)
{
	amp_hci_cmd_t *cmd = (amp_hci_cmd_t *)cmd_buf;
	uint8 buf[BTA_HCI_CMD_MAX_LEN + 16];
	uint len = sizeof(buf);
	wl_ioctl_t ioc;

	if (cmd_len < HCI_CMD_PREAMBLE_SIZE)
		return BCME_BADLEN;

	if ((uint)cmd->plen + HCI_CMD_PREAMBLE_SIZE > cmd_len)
		return BCME_BADLEN;

	len = bcm_mkiovar("HCI_cmd",
		(char *)cmd, (uint)cmd->plen + HCI_CMD_PREAMBLE_SIZE, (char *)buf, len);


	memset(&ioc, 0, sizeof(ioc));

	ioc.cmd = WLC_SET_VAR;
	ioc.buf = buf;
	ioc.len = len;
	ioc.set = TRUE;

	return dhd_wl_ioctl(pub, &ioc, ioc.buf, ioc.len);
}
#else /* !SEND_HCI_CMD_VIA_IOCTL */

static void
dhd_bta_flush_hcidata(dhd_pub_t *pub, uint16 llh)
{
	int prec;
	struct pktq *q;
	uint count = 0;

	q = dhd_bus_txq(pub->bus);
	if (q == NULL)
		return;

	DHD_BTA(("dhd: flushing HCI ACL data for logical link %u...\n", llh));

	dhd_os_sdlock_txq(pub);

	/* Walk through the txq and toss all HCI ACL data packets */
	PKTQ_PREC_ITER(q, prec) {
		void *head_pkt = NULL;

		while (pktq_ppeek(q, prec) != head_pkt) {
			void *pkt = pktq_pdeq(q, prec);
			int ifidx;

			dhd_prot_hdrpull(pub, &ifidx, pkt, NULL, NULL);

			if (PKTLEN(pub->osh, pkt) >= RFC1042_HDR_LEN) {
				struct ether_header *eh =
				        (struct ether_header *)PKTDATA(pub->osh, pkt);

				if (ntoh16(eh->ether_type) < ETHER_TYPE_MIN) {
					struct dot11_llc_snap_header *lsh =
					        (struct dot11_llc_snap_header *)&eh[1];

					if (bcmp(lsh, BT_SIG_SNAP_MPROT,
					         DOT11_LLC_SNAP_HDR_LEN - 2) == 0 &&
					    ntoh16(lsh->type) == BTA_PROT_L2CAP) {
						amp_hci_ACL_data_t *ACL_data =
						        (amp_hci_ACL_data_t *)&lsh[1];
						uint16 handle = ltoh16(ACL_data->handle);

						if (HCI_ACL_DATA_HANDLE(handle) == llh) {
							PKTFREE(pub->osh, pkt, TRUE);
							count ++;
							continue;
						}
					}
				}
			}

			dhd_prot_hdrpush(pub, ifidx, pkt);

			if (head_pkt == NULL)
				head_pkt = pkt;
			pktq_penq(q, prec, pkt);
		}
	}

	dhd_os_sdunlock_txq(pub);

	DHD_BTA(("dhd: flushed %u packet(s) for logical link %u...\n", count, llh));
}

/* Handle HCI cmd locally.
 * Return 0: continue to send the cmd across SDIO
 *        < 0: stop, fail
 *        > 0: stop, succuess
 */
static int
_dhd_bta_docmd(dhd_pub_t *pub, amp_hci_cmd_t *cmd)
{
	int status = 0;

	switch (ltoh16_ua((uint8 *)&cmd->opcode)) {
	case HCI_Enhanced_Flush: {
		eflush_cmd_parms_t *cmdparms = (eflush_cmd_parms_t *)cmd->parms;
		dhd_bta_flush_hcidata(pub, ltoh16_ua(cmdparms->llh));
		break;
	}
	default:
		break;
	}

	return status;
}

/* Send HCI cmd encapsulated in BT-SIG frame via data channel to the dongle. */
int
dhd_bta_docmd(dhd_pub_t *pub, void *cmd_buf, uint cmd_len)
{
	amp_hci_cmd_t *cmd = (amp_hci_cmd_t *)cmd_buf;
	struct ether_header *eh;
	struct dot11_llc_snap_header *lsh;
	osl_t *osh = pub->osh;
	uint len;
	void *p;
	int status;

	if (cmd_len < HCI_CMD_PREAMBLE_SIZE) {
		DHD_ERROR(("dhd_bta_docmd: short command, cmd_len %u\n", cmd_len));
		return BCME_BADLEN;
	}

	if ((len = (uint)cmd->plen + HCI_CMD_PREAMBLE_SIZE) > cmd_len) {
		DHD_ERROR(("dhd_bta_docmd: malformed command, len %u cmd_len %u\n",
		           len, cmd_len));
		/* return BCME_BADLEN; */
	}

	p = PKTGET(osh, pub->hdrlen + RFC1042_HDR_LEN + len, TRUE);
	if (p == NULL) {
		DHD_ERROR(("dhd_bta_docmd: out of memory\n"));
		return BCME_NOMEM;
	}


	/* intercept and handle the HCI cmd locally */
	if ((status = _dhd_bta_docmd(pub, cmd)) > 0)
		return 0;
	else if (status < 0)
		return status;

	/* copy in HCI cmd */
	PKTPULL(osh, p, pub->hdrlen + RFC1042_HDR_LEN);
	bcopy(cmd, PKTDATA(osh, p), len);

	/* copy in partial Ethernet header with BT-SIG LLC/SNAP header */
	PKTPUSH(osh, p, RFC1042_HDR_LEN);
	eh = (struct ether_header *)PKTDATA(osh, p);
	bzero(eh->ether_dhost, ETHER_ADDR_LEN);
	ETHER_SET_LOCALADDR(eh->ether_dhost);
	bcopy(&pub->mac, eh->ether_shost, ETHER_ADDR_LEN);
	eh->ether_type = hton16(len + DOT11_LLC_SNAP_HDR_LEN);
	lsh = (struct dot11_llc_snap_header *)&eh[1];
	bcopy(BT_SIG_SNAP_MPROT, lsh, DOT11_LLC_SNAP_HDR_LEN - 2);
	lsh->type = 0;

	return dhd_sendpkt(pub, 0, p);
}
#endif /* !SEND_HCI_CMD_VIA_IOCTL */

/* Send HCI ACL data to dongle via data channel */
int
dhd_bta_tx_hcidata(dhd_pub_t *pub, void *data_buf, uint data_len)
{
	amp_hci_ACL_data_t *data = (amp_hci_ACL_data_t *)data_buf;
	struct ether_header *eh;
	struct dot11_llc_snap_header *lsh;
	osl_t *osh = pub->osh;
	uint len;
	void *p;

	if (data_len < HCI_ACL_DATA_PREAMBLE_SIZE) {
		DHD_ERROR(("dhd_bta_tx_hcidata: short data_buf, data_len %u\n", data_len));
		return BCME_BADLEN;
	}

	if ((len = (uint)ltoh16(data->dlen) + HCI_ACL_DATA_PREAMBLE_SIZE) > data_len) {
		DHD_ERROR(("dhd_bta_tx_hcidata: malformed hci data, len %u data_len %u\n",
		           len, data_len));
		/* return BCME_BADLEN; */
	}

	p = PKTGET(osh, pub->hdrlen + RFC1042_HDR_LEN + len, TRUE);
	if (p == NULL) {
		DHD_ERROR(("dhd_bta_tx_hcidata: out of memory\n"));
		return BCME_NOMEM;
	}


	/* copy in HCI ACL data header and HCI ACL data */
	PKTPULL(osh, p, pub->hdrlen + RFC1042_HDR_LEN);
	bcopy(data, PKTDATA(osh, p), len);

	/* copy in partial Ethernet header with BT-SIG LLC/SNAP header */
	PKTPUSH(osh, p, RFC1042_HDR_LEN);
	eh = (struct ether_header *)PKTDATA(osh, p);
	bzero(eh->ether_dhost, ETHER_ADDR_LEN);
	bcopy(&pub->mac, eh->ether_shost, ETHER_ADDR_LEN);
	eh->ether_type = hton16(len + DOT11_LLC_SNAP_HDR_LEN);
	lsh = (struct dot11_llc_snap_header *)&eh[1];
	bcopy(BT_SIG_SNAP_MPROT, lsh, DOT11_LLC_SNAP_HDR_LEN - 2);
	lsh->type = HTON16(BTA_PROT_L2CAP);

	return dhd_sendpkt(pub, 0, p);
}

/* txcomplete callback */
void
dhd_bta_tx_hcidata_complete(dhd_pub_t *dhdp, void *txp, bool success)
{
	uint8 *pktdata = (uint8 *)PKTDATA(dhdp->osh, txp);
	amp_hci_ACL_data_t *ACL_data = (amp_hci_ACL_data_t *)(pktdata + RFC1042_HDR_LEN);
	uint16 handle = ltoh16(ACL_data->handle);
	uint16 llh = HCI_ACL_DATA_HANDLE(handle);

	wl_event_msg_t event;
	uint8 data[HCI_EVT_PREAMBLE_SIZE + sizeof(num_completed_data_blocks_evt_parms_t)];
	amp_hci_event_t *evt;
	num_completed_data_blocks_evt_parms_t *parms;

	uint16 len = HCI_EVT_PREAMBLE_SIZE + sizeof(num_completed_data_blocks_evt_parms_t);

	/* update the event struct */
	memset(&event, 0, sizeof(event));
	event.version = hton16(BCM_EVENT_MSG_VERSION);
	event.event_type = hton32(WLC_E_BTA_HCI_EVENT);
	event.status = 0;
	event.reason = 0;
	event.auth_type = 0;
	event.datalen = hton32(len);
	event.flags = 0;

	/* generate Number of Completed Blocks event */
	evt = (amp_hci_event_t *)data;
	evt->ecode = HCI_Number_of_Completed_Data_Blocks;
	evt->plen = sizeof(num_completed_data_blocks_evt_parms_t);

	parms = (num_completed_data_blocks_evt_parms_t *)evt->parms;
	htol16_ua_store(dhdp->maxdatablks, (uint8 *)&parms->num_blocks);
	parms->num_handles = 1;
	htol16_ua_store(llh, (uint8 *)&parms->completed[0].handle);
	parms->completed[0].pkts = 1;
	parms->completed[0].blocks = 1;

	dhd_sendup_event_common(dhdp, &event, data);
}

/* event callback */
void
dhd_bta_doevt(dhd_pub_t *dhdp, void *data_buf, uint data_len)
{
	amp_hci_event_t *evt = (amp_hci_event_t *)data_buf;

	ASSERT(dhdp);
	ASSERT(evt);

	switch (evt->ecode) {
	case HCI_Command_Complete: {
		cmd_complete_parms_t *parms = (cmd_complete_parms_t *)evt->parms;
		switch (ltoh16_ua((uint8 *)&parms->opcode)) {
		case HCI_Read_Data_Block_Size: {
			read_data_block_size_evt_parms_t *parms2 =
			        (read_data_block_size_evt_parms_t *)parms->parms;
			dhdp->maxdatablks = ltoh16_ua((uint8 *)&parms2->data_block_num);
			break;
		}
		}
		break;
	}

	case HCI_Flush_Occurred: {
		flush_occurred_evt_parms_t *evt_parms = (flush_occurred_evt_parms_t *)evt->parms;
		dhd_bta_flush_hcidata(dhdp, ltoh16_ua((uint8 *)&evt_parms->handle));
		break;
	}
	default:
		break;
	}
}
