/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/*
 * Copyright (c) 2021 MediaTek Inc.
 */

#ifndef ALP_ROHC_PACKETS_H
#define ALP_ROHC_PACKETS_H

#include <linux/types.h>
#include "net_buf.h"

#define ROHC_LARGE_CID_MAX 255U
#define ROHC_SMALL_CID_MAX 15U

#define ROHC_PACKET_IS_ADD_CID_OCT(x) \
	((((x)>>4) & 0x0F) == 0x0E)
#define ROHC_PACKET_GET_CID_FROM_ADD_CID_OCT(x) \
	((x) & 0x0F)

#define ROHC_PACKET_IS_IR_PACKET(x) \
	((x) == (u8)ROHC_IR_PREAMBLE_CODE)
#define ROHC_PACKET_IS_IR_NO_D_PACKET(x) \
	((x) == (u8)ROHC_IR_NO_D_PREAMBLE_CODE)
#define ROHC_PACKET_IS_IR_DYN_PACKET(x) \
	((x) == (u8)ROHC_IR_DYN_PREAMBLE_CODE)
#define ROHC_PACKET_IS_UOR_2_PACKET(x) \
	(((x) & 0xE0) == (u8)ROHC_UOR_2_PREAMBLE_CODE)
#define ROHC_PACKET_IS_UO_1_PACKET(x) \
	(((x) & 0xC0) == (u8)ROHC_UO_1_PREAMBLE_CODE)
#define ROHC_PACKET_IS_UO_0_PACKET(x) \
	(((x) & 0x80) == (u8)ROHC_UO_0_PREAMBLE_CODE)

#define ROHC_PACKET_IS_IR_X_packet(t) \
	(((t) == ROHC_PACKET_IR) \
		|| ((t) == ROHC_PACKET_IR_DYN))

typedef enum {
	ROHC_CID_TYPE_LARGE,
	ROHC_CID_TYPE_SMALL,
} rohc_cid_type_t;

typedef enum {
	ROHC_PACKET_IR = 0,
	ROHC_PACKET_IR_NO_D = 1, /* IR packet without dynamic chain */
	ROHC_PACKET_IR_DYN = 2,
	ROHC_PACKET_UOR_2 = 3,
	ROHC_PACKET_UO_1 = 4,
	ROHC_PACKET_UO_0 = 5,
	ROHC_PACKET_UNKNOWN,
} rohc_packet_t;

enum packet_header_bits {
	UO_0_SN_BITS = 0x4,
	UO_1_SN_BITS = 0x5,
	UO_1_IP_ID_BITS = 0x6,
	UOR_2_SN_BITS = 0x5,
};

enum packet_type_preamble {
	ROHC_IR_PREAMBLE_CODE = 0xFD, //0x1111,1101
	ROHC_IR_NO_D_PREAMBLE_CODE = 0xFC, //0x1111,1100
	ROHC_IR_DYN_PREAMBLE_CODE = 0xF8, //0x1111,1000
	ROHC_UOR_2_PREAMBLE_CODE = 0xC0, //0x110 sn[4:0]
	ROHC_UO_1_PREAMBLE_CODE = 0x80, //0x10 IP-ID[5:0]
	ROHC_UO_0_PREAMBLE_CODE = 0x00, //0x0 sn[6:3] crc[2:0]
};

bool rohc_packet_decode_rohc_cid(
		net_buf_t rohc_pkt,
		rohc_cid_type_t cid_type,
		u8 *cid,
		u8 *non_cid_1st_oct,
		u8 *non_cid_2nd_oct_idx);

rohc_packet_t rohc_packet_decode_packet_type(
		u8 pkt_type_oct);

const char *rohc_packet_type_2_str(
		rohc_packet_t packet_type);

#endif /* ALP_ROHC_PACKETS_H */
