/*
 * Copyright (c) 2019 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 *
 * PPP driver using uart_pipe. This is meant for network connectivity between
 * two network end points.
 */

#define LOG_LEVEL CONFIG_NET_PPP_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_ppp, LOG_LEVEL);

#include <stdio.h>

#include <zephyr/kernel.h>

#include <stdbool.h>
#include <errno.h>
#include <stddef.h>
#include <zephyr/net/ppp.h>
#include <zephyr/net/buf.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_core.h>
#include <zephyr/sys/ring_buffer.h>
#include <zephyr/sys/crc.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/drivers/console/uart_mux.h>
#include <zephyr/random/random.h>

#include "../../subsys/net/ip/net_stats.h"
#include "../../subsys/net/ip/net_private.h"

#define UART_BUF_LEN CONFIG_NET_PPP_UART_BUF_LEN
#define UART_TX_BUF_LEN CONFIG_NET_PPP_ASYNC_UART_TX_BUF_LEN

enum ppp_driver_state {
	STATE_HDLC_FRAME_START,
	STATE_HDLC_FRAME_ADDRESS,
	STATE_HDLC_FRAME_DATA,
};

#define PPP_WORKQ_PRIORITY CONFIG_NET_PPP_RX_PRIORITY
#define PPP_WORKQ_STACK_SIZE CONFIG_NET_PPP_RX_STACK_SIZE

K_KERNEL_STACK_DEFINE(ppp_workq, PPP_WORKQ_STACK_SIZE);

struct ppp_driver_context {
	const struct device *dev;
	struct net_if *iface;

	/* This net_pkt contains pkt that is being read */
	struct net_pkt *pkt;

	/* How much free space we have in the net_pkt */
	size_t available;

	/* ppp data is read into this buf */
	uint8_t buf[UART_BUF_LEN];
#if defined(CONFIG_NET_PPP_ASYNC_UART)
	/* with async we use 2 rx buffers */
	uint8_t buf2[UART_BUF_LEN];
	struct k_work_delayable uart_recovery_work;

	/* ppp buf use when sending data */
	uint8_t send_buf[UART_TX_BUF_LEN];
#else
	/* ppp buf use when sending data */
	uint8_t send_buf[UART_BUF_LEN];
#endif

	uint8_t mac_addr[6];
	struct net_linkaddr ll_addr;

	/* Flag that tells whether this instance is initialized or not */
	atomic_t modem_init_done;

	/* Incoming data is routed via ring buffer */
	struct ring_buf rx_ringbuf;
	uint8_t rx_buf[CONFIG_NET_PPP_RINGBUF_SIZE];

	/* ISR function callback worker */
	struct k_work cb_work;
	struct k_work_q cb_workq;

#if defined(CONFIG_NET_STATISTICS_PPP)
	struct net_stats_ppp stats;
#endif
	enum ppp_driver_state state;

#if defined(CONFIG_PPP_CLIENT_CLIENTSERVER)
	/* correctly received CLIENT bytes */
	uint8_t client_index;
#endif

	uint8_t init_done : 1;
	uint8_t next_escaped : 1;
};

static struct ppp_driver_context ppp_driver_context_data;

#if defined(CONFIG_NET_PPP_ASYNC_UART)
static bool rx_retry_pending;
static bool uart_recovery_pending;
static uint8_t *next_buf;

static K_SEM_DEFINE(uarte_tx_finished, 0, 1);

static void uart_callback(const struct device *dev,
			  struct uart_event *evt,
			  void *user_data)
{
	struct ppp_driver_context *context = user_data;
	uint8_t *p;
	int err, ret, len, space_left;

	switch (evt->type) {
	case UART_TX_DONE:
		LOG_DBG("UART_TX_DONE: sent %zu bytes", evt->data.tx.len);
		k_sem_give(&uarte_tx_finished);
		break;

	case UART_TX_ABORTED:
	{
		k_sem_give(&uarte_tx_finished);
		if (CONFIG_NET_PPP_ASYNC_UART_TX_TIMEOUT == 0) {
			LOG_WRN("UART TX aborted.");
			break;
		}
		struct uart_config uart_conf;

		err = uart_config_get(dev, &uart_conf);
		if (err) {
			LOG_ERR("uart_config_get() err: %d", err);
		} else if (uart_conf.baudrate / 10 * CONFIG_NET_PPP_ASYNC_UART_TX_TIMEOUT
			  / MSEC_PER_SEC > evt->data.tx.len * 2) {
			/* The abort likely did not happen because of missing bandwidth. */
			LOG_DBG("UART_TX_ABORTED");
		} else {
			LOG_WRN("UART TX aborted: Only %zu bytes were sent. You may want"
				" to change either CONFIG_NET_PPP_ASYNC_UART_TX_TIMEOUT"
				" (%d ms) or the UART baud rate (%u).", evt->data.tx.len,
				CONFIG_NET_PPP_ASYNC_UART_TX_TIMEOUT, uart_conf.baudrate);
		}
		break;
	}

	case UART_RX_RDY:
		len = evt->data.rx.len;
		p = evt->data.rx.buf + evt->data.rx.offset;

		LOG_DBG("Received data %d bytes", len);

		ret = ring_buf_put(&context->rx_ringbuf, p, len);
		if (ret < evt->data.rx.len) {
			LOG_WRN("Rx buffer doesn't have enough space. "
				"Bytes pending: %d, written only: %d. "
				"Disabling RX for now.",
				evt->data.rx.len, ret);

			/* No possibility to set flow ctrl ON towards PC,
			 * thus workrounding this lack in async API by turning
			 * rx off for now and re-enabling that later.
			 */
			if (!rx_retry_pending) {
				uart_rx_disable(dev);
				rx_retry_pending = true;
			}
		}

		space_left = ring_buf_space_get(&context->rx_ringbuf);
		if (!rx_retry_pending && space_left < (sizeof(context->rx_buf) / 8)) {
			/* Not much room left in buffer after a write to ring buffer.
			 * We submit a work, but enable flow ctrl also
			 * in this case to avoid packet losses.
			 */
			uart_rx_disable(dev);
			rx_retry_pending = true;
			LOG_WRN("%d written to RX buf, but after that only %d space left. "
				"Disabling RX for now.",
				ret, space_left);
		}

		k_work_submit_to_queue(&context->cb_workq, &context->cb_work);
		break;

	case UART_RX_BUF_REQUEST:
	{
		LOG_DBG("UART_RX_BUF_REQUEST: buf %p", (void *)next_buf);

		if (next_buf) {
			err = uart_rx_buf_rsp(dev, next_buf, sizeof(context->buf));
			if (err) {
				LOG_ERR("uart_rx_buf_rsp() err: %d", err);
			}
		}

		break;
	}

	case UART_RX_BUF_RELEASED:
		next_buf = evt->data.rx_buf.buf;
		LOG_DBG("UART_RX_BUF_RELEASED: buf %p", (void *)next_buf);
		break;

	case UART_RX_DISABLED:
		LOG_DBG("UART_RX_DISABLED - re-enabling in a while");

		if (rx_retry_pending && !uart_recovery_pending) {
			k_work_schedule(&context->uart_recovery_work,
					K_MSEC(CONFIG_NET_PPP_ASYNC_UART_RX_RECOVERY_TIMEOUT));
			rx_retry_pending = false;
			uart_recovery_pending = true;
		}
		break;

	case UART_RX_STOPPED:
		LOG_DBG("UART_RX_STOPPED: stop reason %d", evt->data.rx_stop.reason);

		if (evt->data.rx_stop.reason != 0) {
			rx_retry_pending = true;
		}
		break;
	}
}

static int ppp_async_uart_rx_enable(struct ppp_driver_context *context)
{
	int err;

	next_buf = context->buf2;
	err = uart_callback_set(context->dev, uart_callback, (void *)context);
	if (err) {
		LOG_ERR("Failed to set uart callback, err %d", err);
	}

	err = uart_rx_enable(context->dev, context->buf, sizeof(context->buf),
			     CONFIG_NET_PPP_ASYNC_UART_RX_ENABLE_TIMEOUT * USEC_PER_MSEC);
	if (err) {
		LOG_ERR("uart_rx_enable() failed, err %d", err);
	} else {
		LOG_DBG("RX enabled");
	}
	rx_retry_pending = false;
	return err;
}

static void uart_recovery(struct k_work *work)
{
	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
	struct ppp_driver_context *ppp =
		CONTAINER_OF(dwork, struct ppp_driver_context, uart_recovery_work);
	int ret;

	ret = ring_buf_space_get(&ppp->rx_ringbuf);
	if (ret >= (sizeof(ppp->rx_buf) / 2)) {
		ret = ppp_async_uart_rx_enable(ppp);
		if (ret) {
			LOG_ERR("ppp_async_uart_rx_enable() failed, err %d", ret);
		} else {
			LOG_DBG("UART RX recovered.");
		}
		uart_recovery_pending = false;
	} else {
		LOG_ERR("Rx buffer still doesn't have enough room %d to be re-enabled", ret);
		k_work_schedule(&ppp->uart_recovery_work,
				K_MSEC(CONFIG_NET_PPP_ASYNC_UART_RX_RECOVERY_TIMEOUT));
	}
}
#endif

static int ppp_save_byte(struct ppp_driver_context *ppp, uint8_t byte)
{
	int ret;

	if (!ppp->pkt) {
		ppp->pkt = net_pkt_rx_alloc_with_buffer(
			ppp->iface,
			CONFIG_NET_BUF_DATA_SIZE,
			AF_UNSPEC, 0, K_NO_WAIT);
		if (!ppp->pkt) {
			LOG_ERR("[%p] cannot allocate pkt", ppp);
			return -ENOMEM;
		}

		net_pkt_cursor_init(ppp->pkt);

		ppp->available = net_pkt_available_buffer(ppp->pkt);
	}

	/* Extra debugging can be enabled separately if really
	 * needed. Normally it would just print too much data.
	 */
	if (0) {
		LOG_DBG("Saving byte %02x", byte);
	}

	/* This is not very intuitive but we must allocate new buffer
	 * before we write a byte to last available cursor position.
	 */
	if (ppp->available == 1) {
		ret = net_pkt_alloc_buffer(ppp->pkt,
					   CONFIG_NET_BUF_DATA_SIZE,
					   AF_UNSPEC, K_NO_WAIT);
		if (ret < 0) {
			LOG_ERR("[%p] cannot allocate new data buffer", ppp);
			goto out_of_mem;
		}

		ppp->available = net_pkt_available_buffer(ppp->pkt);
	}

	if (ppp->available) {
		ret = net_pkt_write_u8(ppp->pkt, byte);
		if (ret < 0) {
			LOG_ERR("[%p] Cannot write to pkt %p (%d)",
				ppp, ppp->pkt, ret);
			goto out_of_mem;
		}

		ppp->available--;
	}

	return 0;

out_of_mem:
	net_pkt_unref(ppp->pkt);
	ppp->pkt = NULL;
	return -ENOMEM;
}

static const char *ppp_driver_state_str(enum ppp_driver_state state)
{
#if (CONFIG_NET_PPP_LOG_LEVEL >= LOG_LEVEL_DBG)
	switch (state) {
	case STATE_HDLC_FRAME_START:
		return "START";
	case STATE_HDLC_FRAME_ADDRESS:
		return "ADDRESS";
	case STATE_HDLC_FRAME_DATA:
		return "DATA";
	}
#else
	ARG_UNUSED(state);
#endif

	return "";
}

static void ppp_change_state(struct ppp_driver_context *ctx,
			     enum ppp_driver_state new_state)
{
	NET_ASSERT(ctx);

	if (ctx->state == new_state) {
		return;
	}

	NET_ASSERT(new_state >= STATE_HDLC_FRAME_START &&
		   new_state <= STATE_HDLC_FRAME_DATA);

	NET_DBG("[%p] state %s (%d) => %s (%d)",
		ctx, ppp_driver_state_str(ctx->state), ctx->state,
		ppp_driver_state_str(new_state), new_state);

	ctx->state = new_state;
}

static int ppp_send_flush(struct ppp_driver_context *ppp, int off)
{
	if (IS_ENABLED(CONFIG_NET_TEST)) {
		return 0;
	}
	uint8_t *buf = ppp->send_buf;

	/* If we're using gsm_mux, We don't want to use poll_out because sending
	 * one byte at a time causes each byte to get wrapped in muxing headers.
	 * But we can safely call uart_fifo_fill outside of ISR context when
	 * muxing because uart_mux implements it in software.
	 */
	if (IS_ENABLED(CONFIG_GSM_MUX)) {
		(void)uart_fifo_fill(ppp->dev, buf, off);
	} else if (IS_ENABLED(CONFIG_NET_PPP_ASYNC_UART)) {
#if defined(CONFIG_NET_PPP_ASYNC_UART)
		int ret;
		const int32_t timeout = CONFIG_NET_PPP_ASYNC_UART_TX_TIMEOUT
					? CONFIG_NET_PPP_ASYNC_UART_TX_TIMEOUT * USEC_PER_MSEC
					: SYS_FOREVER_US;

		k_sem_take(&uarte_tx_finished, K_FOREVER);

		ret = uart_tx(ppp->dev, buf, off, timeout);
		if (ret) {
			LOG_ERR("uart_tx() failed, err %d", ret);
			k_sem_give(&uarte_tx_finished);
		}
#endif
	} else {
		while (off--) {
			uart_poll_out(ppp->dev, *buf++);
		}
	}

	return 0;
}

static int ppp_send_bytes(struct ppp_driver_context *ppp,
			  const uint8_t *data, int len, int off)
{
	int i;

	for (i = 0; i < len; i++) {
		ppp->send_buf[off++] = data[i];

		if (off >= sizeof(ppp->send_buf)) {
			off = ppp_send_flush(ppp, off);
		}
	}

	return off;
}

#if defined(CONFIG_PPP_CLIENT_CLIENTSERVER)

#define CLIENT "CLIENT"
#define CLIENTSERVER "CLIENTSERVER"

static void ppp_handle_client(struct ppp_driver_context *ppp, uint8_t byte)
{
	static const char *client = CLIENT;
	static const char *clientserver = CLIENTSERVER;
	int offset;

	if (ppp->client_index >= (sizeof(CLIENT) - 1)) {
		ppp->client_index = 0;
	}

	if (byte != client[ppp->client_index]) {
		ppp->client_index = 0;
		if (byte != client[ppp->client_index]) {
			return;
		}
	}

	++ppp->client_index;
	if (ppp->client_index >= (sizeof(CLIENT) - 1)) {
		LOG_DBG("Received complete CLIENT string");
		offset = ppp_send_bytes(ppp, clientserver,
					sizeof(CLIENTSERVER) - 1, 0);
		(void)ppp_send_flush(ppp, offset);
		ppp->client_index = 0;
	}

}
#endif

static int ppp_input_byte(struct ppp_driver_context *ppp, uint8_t byte)
{
	int ret = -EAGAIN;

	switch (ppp->state) {
	case STATE_HDLC_FRAME_START:
		/* Synchronizing the flow with HDLC flag field */
		if (byte == 0x7e) {
			/* Note that we do not save the sync flag */
			LOG_DBG("Sync byte (0x%02x) start", byte);
			ppp_change_state(ppp, STATE_HDLC_FRAME_ADDRESS);
#if defined(CONFIG_PPP_CLIENT_CLIENTSERVER)
		} else {
			ppp_handle_client(ppp, byte);
#endif
		}

		break;

	case STATE_HDLC_FRAME_ADDRESS:
		if (byte != 0xff) {
			/* Check if we need to sync again */
			if (byte == 0x7e) {
				/* Just skip to the start of the pkt byte */
				return -EAGAIN;
			}

			LOG_DBG("Invalid (0x%02x) byte, expecting Address",
				byte);

			/* If address is != 0xff, then ignore this
			 * frame. RFC 1662 ch 3.1
			 */
			ppp_change_state(ppp, STATE_HDLC_FRAME_START);
		} else {
			LOG_DBG("Address byte (0x%02x) start", byte);

			ppp_change_state(ppp, STATE_HDLC_FRAME_DATA);

			/* Save the address field so that we can calculate
			 * the FCS. The address field will not be passed
			 * to upper stack.
			 */
			ret = ppp_save_byte(ppp, byte);
			if (ret < 0) {
				ppp_change_state(ppp, STATE_HDLC_FRAME_START);
			}

			ret = -EAGAIN;
		}

		break;

	case STATE_HDLC_FRAME_DATA:
		/* If the next frame starts, then send this one
		 * up in the network stack.
		 */
		if (byte == 0x7e) {
			LOG_DBG("End of pkt (0x%02x)", byte);
			ppp_change_state(ppp, STATE_HDLC_FRAME_ADDRESS);
			ret = 0;
		} else {
			if (byte == 0x7d) {
				/* RFC 1662, ch. 4.2 */
				ppp->next_escaped = true;
				break;
			}

			if (ppp->next_escaped) {
				/* RFC 1662, ch. 4.2 */
				byte ^= 0x20;
				ppp->next_escaped = false;
			}

			ret = ppp_save_byte(ppp, byte);
			if (ret < 0) {
				ppp_change_state(ppp, STATE_HDLC_FRAME_START);
			}

			ret = -EAGAIN;
		}

		break;

	default:
		LOG_ERR("[%p] Invalid state %d", ppp, ppp->state);
		break;
	}

	return ret;
}

static bool ppp_check_fcs(struct ppp_driver_context *ppp)
{
	struct net_buf *buf;
	uint16_t crc;

	buf = ppp->pkt->buffer;
	if (!buf) {
		return false;
	}

	crc = crc16_ccitt(0xffff, buf->data, buf->len);

	buf = buf->frags;

	while (buf) {
		crc = crc16_ccitt(crc, buf->data, buf->len);
		buf = buf->frags;
	}

	if (crc != 0xf0b8) {
		LOG_DBG("Invalid FCS (0x%x)", crc);
#if defined(CONFIG_NET_STATISTICS_PPP)
		ppp->stats.chkerr++;
#endif
		return false;
	}

	return true;
}

static void ppp_process_msg(struct ppp_driver_context *ppp)
{
	if (LOG_LEVEL >= LOG_LEVEL_DBG) {
		net_pkt_hexdump(ppp->pkt, "recv ppp");
	}

	if (IS_ENABLED(CONFIG_NET_PPP_VERIFY_FCS) && !ppp_check_fcs(ppp)) {
#if defined(CONFIG_NET_STATISTICS_PPP)
		ppp->stats.drop++;
		ppp->stats.pkts.rx++;
#endif
		net_pkt_unref(ppp->pkt);
	} else {
		/* Remove the Address (0xff), Control (0x03) and
		 * FCS fields (16-bit) as the PPP L2 layer does not need
		 * those bytes.
		 */
		uint16_t addr_and_ctrl = net_buf_pull_be16(ppp->pkt->buffer);

		/* Currently we do not support compressed Address and Control
		 * fields so they must always be present.
		 */
		if (addr_and_ctrl != (0xff << 8 | 0x03)) {
#if defined(CONFIG_NET_STATISTICS_PPP)
			ppp->stats.drop++;
			ppp->stats.pkts.rx++;
#endif
			net_pkt_unref(ppp->pkt);
		} else {
			/* Remove FCS bytes (2) */
			net_pkt_remove_tail(ppp->pkt, 2);

			/* Make sure we now start reading from PPP header in
			 * PPP L2 recv()
			 */
			net_pkt_cursor_init(ppp->pkt);
			net_pkt_set_overwrite(ppp->pkt, true);

			if (net_recv_data(ppp->iface, ppp->pkt) < 0) {
				net_pkt_unref(ppp->pkt);
			}
		}
	}

	ppp->pkt = NULL;
}

#if defined(CONFIG_NET_TEST)
static uint8_t *ppp_recv_cb(uint8_t *buf, size_t *off)
{
	struct ppp_driver_context *ppp =
		CONTAINER_OF(buf, struct ppp_driver_context, buf[0]);
	size_t i, len = *off;

	for (i = 0; i < *off; i++) {
		if (0) {
			/* Extra debugging can be enabled separately if really
			 * needed. Normally it would just print too much data.
			 */
			LOG_DBG("[%zd] %02x", i, buf[i]);
		}

		if (ppp_input_byte(ppp, buf[i]) == 0) {
			/* Ignore empty or too short frames */
			if (ppp->pkt && net_pkt_get_len(ppp->pkt) > 3) {
				ppp_process_msg(ppp);
				break;
			}
		}
	}

	if (i == *off) {
		*off = 0;
	} else {
		*off = len - i - 1;

		memmove(&buf[0], &buf[i + 1], *off);
	}

	return buf;
}

void ppp_driver_feed_data(uint8_t *data, int data_len)
{
	struct ppp_driver_context *ppp = &ppp_driver_context_data;
	size_t recv_off = 0;

	/* We are expecting that the tests are feeding data in large
	 * chunks so we can reset the uart buffer here.
	 */
	memset(ppp->buf, 0, UART_BUF_LEN);

	ppp_change_state(ppp, STATE_HDLC_FRAME_START);

	while (data_len > 0) {
		int data_to_copy = MIN(data_len, UART_BUF_LEN);
		int remaining;

		LOG_DBG("Feeding %d bytes", data_to_copy);

		memcpy(ppp->buf, data, data_to_copy);

		recv_off = data_to_copy;

		(void)ppp_recv_cb(ppp->buf, &recv_off);

		remaining = data_to_copy - recv_off;

		LOG_DBG("We copied %d bytes", remaining);

		data_len -= remaining;
		data += remaining;
	}
}
#endif

static bool calc_fcs(struct net_pkt *pkt, uint16_t *fcs, uint16_t protocol)
{
	struct net_buf *buf;
	uint16_t crc;
	uint16_t c;

	buf = pkt->buffer;
	if (!buf) {
		return false;
	}

	/* HDLC Address and Control fields */
	c = sys_cpu_to_be16(0xff << 8 | 0x03);

	crc = crc16_ccitt(0xffff, (const uint8_t *)&c, sizeof(c));

	if (protocol > 0) {
		crc = crc16_ccitt(crc, (const uint8_t *)&protocol,
				  sizeof(protocol));
	}

	while (buf) {
		crc = crc16_ccitt(crc, buf->data, buf->len);
		buf = buf->frags;
	}

	crc ^= 0xffff;
	*fcs = crc;

	return true;
}

static uint16_t ppp_escape_byte(uint8_t byte, int *offset)
{
	if (byte == 0x7e || byte == 0x7d || byte < 0x20) {
		*offset = 0;
		return (0x7d << 8) | (byte ^ 0x20);
	}

	*offset = 1;
	return byte;
}

static int ppp_send(const struct device *dev, struct net_pkt *pkt)
{
	struct ppp_driver_context *ppp = dev->data;
	struct net_buf *buf = pkt->buffer;
	uint16_t protocol = 0;
	int send_off = 0;
	uint32_t sync_addr_ctrl;
	uint16_t fcs, escaped;
	uint8_t byte;
	int i, offset;

#if defined(CONFIG_NET_TEST)
	return 0;
#endif

	ARG_UNUSED(dev);

	if (!buf) {
		/* No data? */
		return -ENODATA;
	}

	/* If the packet is a normal network packet, we must add the protocol
	 * value here.
	 */
	if (!net_pkt_is_ppp(pkt)) {
		if (net_pkt_family(pkt) == AF_INET) {
			protocol = htons(PPP_IP);
		} else if (net_pkt_family(pkt) == AF_INET6) {
			protocol = htons(PPP_IPV6);
		}  else {
			return -EPROTONOSUPPORT;
		}
	}

	if (!calc_fcs(pkt, &fcs, protocol)) {
		return -ENOMEM;
	}

	/* Sync, Address & Control fields */
	sync_addr_ctrl = sys_cpu_to_be32(0x7e << 24 | 0xff << 16 |
					 0x7d << 8 | 0x23);
	send_off = ppp_send_bytes(ppp, (const uint8_t *)&sync_addr_ctrl,
				  sizeof(sync_addr_ctrl), send_off);

	if (protocol > 0) {
		escaped = htons(ppp_escape_byte(protocol, &offset));
		send_off = ppp_send_bytes(ppp, (uint8_t *)&escaped + offset,
					  offset ? 1 : 2,
					  send_off);

		escaped = htons(ppp_escape_byte(protocol >> 8, &offset));
		send_off = ppp_send_bytes(ppp, (uint8_t *)&escaped + offset,
					  offset ? 1 : 2,
					  send_off);
	}

	/* Note that we do not print the first four bytes and FCS bytes at the
	 * end so that we do not need to allocate separate net_buf just for
	 * that purpose.
	 */
	if (LOG_LEVEL >= LOG_LEVEL_DBG) {
		net_pkt_hexdump(pkt, "send ppp");
	}

	while (buf) {
		for (i = 0; i < buf->len; i++) {
			/* Escape illegal bytes */
			escaped = htons(ppp_escape_byte(buf->data[i], &offset));
			send_off = ppp_send_bytes(ppp,
						  (uint8_t *)&escaped + offset,
						  offset ? 1 : 2,
						  send_off);
		}

		buf = buf->frags;
	}

	escaped = htons(ppp_escape_byte(fcs, &offset));
	send_off = ppp_send_bytes(ppp, (uint8_t *)&escaped + offset,
				  offset ? 1 : 2,
				  send_off);

	escaped = htons(ppp_escape_byte(fcs >> 8, &offset));
	send_off = ppp_send_bytes(ppp, (uint8_t *)&escaped + offset,
				  offset ? 1 : 2,
				  send_off);

	byte = 0x7e;
	send_off = ppp_send_bytes(ppp, &byte, 1, send_off);

	(void)ppp_send_flush(ppp, send_off);

	return 0;
}

#if !defined(CONFIG_NET_TEST)
static int ppp_consume_ringbuf(struct ppp_driver_context *ppp)
{
	uint8_t *data;
	size_t len, tmp;
	int ret;

	len = ring_buf_get_claim(&ppp->rx_ringbuf, &data,
				 CONFIG_NET_PPP_RINGBUF_SIZE);
	if (len == 0) {
		LOG_DBG("Ringbuf %p is empty!", &ppp->rx_ringbuf);
		return 0;
	}

	/* This will print too much data, enable only if really needed */
	if (0) {
		LOG_HEXDUMP_DBG(data, len, ppp->dev->name);
	}

	tmp = len;

	do {
		if (ppp_input_byte(ppp, *data++) == 0) {
			/* Ignore empty or too short frames */
			if (ppp->pkt && net_pkt_get_len(ppp->pkt) > 3) {
				ppp_process_msg(ppp);
			}
		}
	} while (--tmp);

	ret = ring_buf_get_finish(&ppp->rx_ringbuf, len);
	if (ret < 0) {
		LOG_DBG("Cannot flush ring buffer (%d)", ret);
	}

	return -EAGAIN;
}

static void ppp_isr_cb_work(struct k_work *work)
{
	struct ppp_driver_context *ppp =
		CONTAINER_OF(work, struct ppp_driver_context, cb_work);
	int ret = -EAGAIN;

	while (ret == -EAGAIN) {
		ret = ppp_consume_ringbuf(ppp);
	}
}
#endif /* !CONFIG_NET_TEST */

static int ppp_driver_init(const struct device *dev)
{
	struct ppp_driver_context *ppp = dev->data;

	LOG_DBG("[%p] dev %p", ppp, dev);

#if !defined(CONFIG_NET_TEST)
	ring_buf_init(&ppp->rx_ringbuf, sizeof(ppp->rx_buf), ppp->rx_buf);
	k_work_init(&ppp->cb_work, ppp_isr_cb_work);

	k_work_queue_start(&ppp->cb_workq, ppp_workq,
			   K_KERNEL_STACK_SIZEOF(ppp_workq),
			   K_PRIO_COOP(PPP_WORKQ_PRIORITY), NULL);
	k_thread_name_set(&ppp->cb_workq.thread, "ppp_workq");
#if defined(CONFIG_NET_PPP_ASYNC_UART)
	k_work_init_delayable(&ppp->uart_recovery_work, uart_recovery);
#endif
#endif
	ppp->pkt = NULL;
	ppp_change_state(ppp, STATE_HDLC_FRAME_START);
#if defined(CONFIG_PPP_CLIENT_CLIENTSERVER)
	ppp->client_index = 0;
#endif

	return 0;
}

static inline struct net_linkaddr *ppp_get_mac(struct ppp_driver_context *ppp)
{
	ppp->ll_addr.addr = ppp->mac_addr;
	ppp->ll_addr.len = sizeof(ppp->mac_addr);

	return &ppp->ll_addr;
}

static void ppp_iface_init(struct net_if *iface)
{
	struct ppp_driver_context *ppp = net_if_get_device(iface)->data;
	struct net_linkaddr *ll_addr;

	LOG_DBG("[%p] iface %p", ppp, iface);

	net_ppp_init(iface);

	if (ppp->init_done) {
		return;
	}

	ppp->init_done = true;
	ppp->iface = iface;

	/* The mac address is not really used but network interface expects
	 * to find one.
	 */
	ll_addr = ppp_get_mac(ppp);

	if (CONFIG_PPP_MAC_ADDR[0] != 0) {
		if (net_bytes_from_str(ppp->mac_addr, sizeof(ppp->mac_addr),
				       CONFIG_PPP_MAC_ADDR) < 0) {
			goto use_random_mac;
		}
	} else {
use_random_mac:
		/* 00-00-5E-00-53-xx Documentation RFC 7042 */
		ppp->mac_addr[0] = 0x00;
		ppp->mac_addr[1] = 0x00;
		ppp->mac_addr[2] = 0x5E;
		ppp->mac_addr[3] = 0x00;
		ppp->mac_addr[4] = 0x53;
		ppp->mac_addr[5] = sys_rand32_get();
	}

	net_if_set_link_addr(iface, ll_addr->addr, ll_addr->len,
			     NET_LINK_ETHERNET);

	memset(ppp->buf, 0, sizeof(ppp->buf));

	/* If we have a GSM modem with PPP support or interface autostart is disabled
	 * from Kconfig, then do not start the interface automatically but only
	 * after the modem is ready or when manually started.
	 */
	if (IS_ENABLED(CONFIG_MODEM_GSM_PPP) ||
	    IS_ENABLED(CONFIG_PPP_NET_IF_NO_AUTO_START)) {
		net_if_flag_set(iface, NET_IF_NO_AUTO_START);
	}
}

#if defined(CONFIG_NET_STATISTICS_PPP)
static struct net_stats_ppp *ppp_get_stats(const struct device *dev)
{
	struct ppp_driver_context *context = dev->data;

	return &context->stats;
}
#endif

#if !defined(CONFIG_NET_TEST) && !defined(CONFIG_NET_PPP_ASYNC_UART)
static void ppp_uart_flush(const struct device *dev)
{
	uint8_t c;

	while (uart_fifo_read(dev, &c, 1) > 0) {
		continue;
	}
}

static void ppp_uart_isr(const struct device *uart, void *user_data)
{
	struct ppp_driver_context *context = user_data;
	int rx = 0, ret;

	/* get all of the data off UART as fast as we can */
	while (uart_irq_update(uart) && uart_irq_rx_ready(uart)) {
		rx = uart_fifo_read(uart, context->buf, sizeof(context->buf));
		if (rx <= 0) {
			continue;
		}

		ret = ring_buf_put(&context->rx_ringbuf, context->buf, rx);
		if (ret < rx) {
			LOG_ERR("Rx buffer doesn't have enough space. "
				"Bytes pending: %d, written: %d",
				rx, ret);
			break;
		}

		k_work_submit_to_queue(&context->cb_workq, &context->cb_work);
	}
}
#endif /* !CONFIG_NET_TEST && !CONFIG_NET_PPP_ASYNC_UART */

static int ppp_start(const struct device *dev)
{
	struct ppp_driver_context *context = dev->data;

	/* Init the PPP UART only once. This should only be done after
	 * the GSM muxing is setup and enabled. GSM modem will call this
	 * after everything is ready to be connected.
	 */
#if !defined(CONFIG_NET_TEST)
	if (atomic_cas(&context->modem_init_done, false, true)) {
		/* Now try to figure out what device to open. If GSM muxing
		 * is enabled, then use it. If not, then check if modem
		 * configuration is enabled, and use that. If none are enabled,
		 * then use our own config.
		 */
#if defined(CONFIG_GSM_MUX)
		const struct device *mux;

		mux = uart_mux_find(CONFIG_GSM_MUX_DLCI_PPP);
		if (mux == NULL) {
			LOG_ERR("Cannot find GSM mux dev for DLCI %d",
				CONFIG_GSM_MUX_DLCI_PPP);
			return -ENOENT;
		}

		context->dev = mux;
#elif IS_ENABLED(CONFIG_MODEM_GSM_PPP)
		context->dev = DEVICE_DT_GET(DT_BUS(DT_INST(0, zephyr_gsm_ppp)));
#else
		/* dts chosen zephyr,ppp-uart case */
		context->dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_ppp_uart));
#endif
		LOG_DBG("Initializing PPP to use %s", context->dev->name);

		if (!device_is_ready(context->dev)) {
			LOG_ERR("Device %s is not ready", context->dev->name);
			return -ENODEV;
		}
#if defined(CONFIG_NET_PPP_ASYNC_UART)
		k_sem_give(&uarte_tx_finished);
		ppp_async_uart_rx_enable(context);
#else
		uart_irq_rx_disable(context->dev);
		uart_irq_tx_disable(context->dev);
		ppp_uart_flush(context->dev);
		uart_irq_callback_user_data_set(context->dev, ppp_uart_isr,
						context);
		uart_irq_rx_enable(context->dev);
#endif
	}
#endif /* !CONFIG_NET_TEST */

	net_if_carrier_on(context->iface);
	return 0;
}

static int ppp_stop(const struct device *dev)
{
	struct ppp_driver_context *context = dev->data;

	net_if_carrier_off(context->iface);
#if defined(CONFIG_NET_PPP_ASYNC_UART)
	uart_rx_disable(context->dev);
#endif
	context->modem_init_done = false;
	return 0;
}

static const struct ppp_api ppp_if_api = {
	.iface_api.init = ppp_iface_init,

	.send = ppp_send,
	.start = ppp_start,
	.stop = ppp_stop,
#if defined(CONFIG_NET_STATISTICS_PPP)
	.get_stats = ppp_get_stats,
#endif
};

NET_DEVICE_INIT(ppp, CONFIG_NET_PPP_DRV_NAME, ppp_driver_init,
		NULL, &ppp_driver_context_data, NULL,
		CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &ppp_if_api,
		PPP_L2, NET_L2_GET_CTX_TYPE(PPP_L2), PPP_MTU);
