/*
 * Copyright (c) 2017 Linaro Ltd
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(usb_eem, CONFIG_USB_DEVICE_NETWORK_LOG_LEVEL);

#include <zephyr/net/net_pkt.h>
#include <zephyr/net/ethernet.h>
#include <net_private.h>

#include <zephyr/usb/usb_device.h>
#include <zephyr/usb/class/usb_cdc.h>

#include "netusb.h"

static uint8_t sentinel[] = { 0xde, 0xad, 0xbe, 0xef };

#define EEM_FRAME_SIZE (NET_ETH_MAX_FRAME_SIZE + sizeof(sentinel) + \
			sizeof(uint16_t)) /* EEM header */

static uint8_t tx_buf[EEM_FRAME_SIZE], rx_buf[EEM_FRAME_SIZE];

struct usb_cdc_eem_config {
	struct usb_if_descriptor if0;
	struct usb_ep_descriptor if0_in_ep;
	struct usb_ep_descriptor if0_out_ep;
} __packed;

USBD_CLASS_DESCR_DEFINE(primary, 0) struct usb_cdc_eem_config cdc_eem_cfg = {
	/* Interface descriptor 0 */
	/* CDC Communication interface */
	.if0 = {
		.bLength = sizeof(struct usb_if_descriptor),
		.bDescriptorType = USB_DESC_INTERFACE,
		.bInterfaceNumber = 0,
		.bAlternateSetting = 0,
		.bNumEndpoints = 2,
		.bInterfaceClass = USB_BCC_CDC_CONTROL,
		.bInterfaceSubClass = EEM_SUBCLASS,
		.bInterfaceProtocol = EEM_PROTOCOL,
		.iInterface = 0,
	},

	/* Data Endpoint IN */
	.if0_in_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_DESC_ENDPOINT,
		.bEndpointAddress = CDC_EEM_IN_EP_ADDR,
		.bmAttributes = USB_DC_EP_BULK,
		.wMaxPacketSize =
			sys_cpu_to_le16(CONFIG_CDC_EEM_BULK_EP_MPS),
		.bInterval = 0x00,
	},

	/* Data Endpoint OUT */
	.if0_out_ep = {
		.bLength = sizeof(struct usb_ep_descriptor),
		.bDescriptorType = USB_DESC_ENDPOINT,
		.bEndpointAddress = CDC_EEM_OUT_EP_ADDR,
		.bmAttributes = USB_DC_EP_BULK,
		.wMaxPacketSize =
			sys_cpu_to_le16(CONFIG_CDC_EEM_BULK_EP_MPS),
		.bInterval = 0x00,
	},
};

static uint8_t eem_get_first_iface_number(void)
{
	return cdc_eem_cfg.if0.bInterfaceNumber;
}

#define EEM_OUT_EP_IDX		0
#define EEM_IN_EP_IDX		1

static struct usb_ep_cfg_data eem_ep_data[] = {
	{
		/* Use transfer API */
		.ep_cb = usb_transfer_ep_callback,
		.ep_addr = CDC_EEM_OUT_EP_ADDR
	},
	{
		/* Use transfer API */
		.ep_cb = usb_transfer_ep_callback,
		.ep_addr = CDC_EEM_IN_EP_ADDR
	},
};

static inline uint16_t eem_pkt_size(uint16_t hdr)
{
	if (hdr & BIT(15)) {
		return hdr & 0x07ff;
	} else {
		return hdr & 0x3fff;
	}
}

static int eem_send(struct net_pkt *pkt)
{
	uint16_t *hdr = (uint16_t *)&tx_buf[0];
	int ret, len, b_idx = 0;

	/* With EEM, it's possible to send multiple ethernet packets in one
	 * transfer, we don't do that for now.
	 */
	len = net_pkt_get_len(pkt) + sizeof(sentinel);

	if (len + sizeof(uint16_t) > sizeof(tx_buf)) {
		LOG_WRN("Trying to send too large packet, drop");
		return -ENOMEM;
	}

	/* Add EEM header */
	*hdr = sys_cpu_to_le16(0x3FFF & len);
	b_idx += sizeof(uint16_t);

	if (net_pkt_read(pkt, &tx_buf[b_idx], net_pkt_get_len(pkt))) {
		return -ENOBUFS;
	}

	b_idx += len - sizeof(sentinel);

	/* Add crc-sentinel */
	memcpy(&tx_buf[b_idx], sentinel, sizeof(sentinel));
	b_idx += sizeof(sentinel);

	/* transfer data to host */
	ret = usb_transfer_sync(eem_ep_data[EEM_IN_EP_IDX].ep_addr,
				tx_buf, b_idx,
				USB_TRANS_WRITE);
	if (ret != b_idx) {
		LOG_ERR("Transfer failure");
		return -EIO;
	}

	return 0;
}

static void eem_read_cb(uint8_t ep, int size, void *priv)
{
	uint8_t *ptr = rx_buf;

	do {
		uint16_t eem_hdr, eem_size;
		struct net_pkt *pkt;

		if (size < sizeof(uint16_t)) {
			break;
		}

		eem_hdr = sys_get_le16(ptr);
		eem_size = eem_pkt_size(eem_hdr);

		if (eem_size + sizeof(uint16_t) > size) {
			/* eem pkt greater than transferred data */
			LOG_ERR("pkt size error");
			break;
		}

		size -= sizeof(uint16_t);
		ptr += sizeof(uint16_t);

		if (eem_hdr & BIT(15)) {
			/* EEM Command, do nothing for now */
			goto done;
		}

		LOG_DBG("hdr 0x%x, eem_size %d, size %d",
			eem_hdr, eem_size, size);

		if (!size || !eem_size) {
			LOG_DBG("no payload");
			break;
		}

		pkt = net_pkt_rx_alloc_with_buffer(netusb_net_iface(),
						   eem_size - sizeof(sentinel),
						   AF_UNSPEC, 0, K_FOREVER);
		if (!pkt) {
			LOG_ERR("Unable to alloc pkt");
			break;
		}

		/* copy payload and discard 32-bit sentinel */
		if (net_pkt_write(pkt, ptr, eem_size - sizeof(sentinel))) {
			LOG_ERR("Unable to write into pkt");
			net_pkt_unref(pkt);
			break;
		}

		netusb_recv(pkt);

done:
		size -= eem_size;
		ptr += eem_size;
	} while (size);

	usb_transfer(eem_ep_data[EEM_OUT_EP_IDX].ep_addr, rx_buf,
		     sizeof(rx_buf), USB_TRANS_READ, eem_read_cb, NULL);
}

static int eem_connect(bool connected)
{
	if (connected) {
		eem_read_cb(eem_ep_data[EEM_OUT_EP_IDX].ep_addr, 0, NULL);
	} else {
		/* Cancel any transfer */
		usb_cancel_transfer(eem_ep_data[EEM_OUT_EP_IDX].ep_addr);
		usb_cancel_transfer(eem_ep_data[EEM_IN_EP_IDX].ep_addr);
	}

	return 0;
}

static struct netusb_function eem_function = {
	.connect_media = eem_connect,
	.send_pkt = eem_send,
};

static inline void eem_status_interface(const uint8_t *desc)
{
	const struct usb_if_descriptor *if_desc = (void *)desc;
	uint8_t iface_num = if_desc->bInterfaceNumber;

	LOG_DBG("");

	if (iface_num != eem_get_first_iface_number()) {
		return;
	}

	netusb_enable(&eem_function);
}

static void eem_status_cb(struct usb_cfg_data *cfg,
			  enum usb_dc_status_code status,
			  const uint8_t *param)
{
	ARG_UNUSED(cfg);

	/* Check the USB status and do needed action if required */
	switch (status) {
	case USB_DC_DISCONNECTED:
		LOG_DBG("USB device disconnected");
		netusb_disable();
		break;

	case USB_DC_INTERFACE:
		LOG_DBG("USB interface selected");
		eem_status_interface(param);
		break;

	case USB_DC_ERROR:
	case USB_DC_RESET:
	case USB_DC_CONNECTED:
	case USB_DC_CONFIGURED:
	case USB_DC_SUSPEND:
	case USB_DC_RESUME:
		LOG_DBG("USB unhandled state: %d", status);
		break;

	case USB_DC_SOF:
		break;

	case USB_DC_UNKNOWN:
	default:
		LOG_DBG("USB unknown state: %d", status);
		break;
	}
}

static void eem_interface_config(struct usb_desc_header *head,
				 uint8_t bInterfaceNumber)
{
	ARG_UNUSED(head);

	cdc_eem_cfg.if0.bInterfaceNumber = bInterfaceNumber;
}

USBD_DEFINE_CFG_DATA(cdc_eem_config) = {
	.usb_device_description = NULL,
	.interface_config = eem_interface_config,
	.interface_descriptor = &cdc_eem_cfg.if0,
	.cb_usb_status = eem_status_cb,
	.interface = {
		.class_handler = NULL,
		.custom_handler = NULL,
		.vendor_handler = NULL,
	},
	.num_endpoints = ARRAY_SIZE(eem_ep_data),
	.endpoint = eem_ep_data,
};
