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

#ifndef ATSC30_PARSER_BB_PACKET_H
#define ATSC30_PARSER_BB_PACKET_H

#include <linux/types.h>

#include "bits_op.h"
#include "net_buf.h"
#include "alp_parser_common.h"

#define BB_PARSER_HEADER_SIZE		(5)

#define BB_RESERVE0_SHIFT		(3)
#define BB_RESERVE0_WIDTH		(5)
#define BB_SIGNALING_SHIFT		(2)
#define BB_SIGNALING_WIDTH		(1)
#define BB_PLP_ID_SHIFT			(0)
#define BB_PLP_ID_WIDTH			(2)

#define BB_RESERVE12_SHIFT		(13)
#define BB_RESERVE12_WIDTH		(3)
#define BB_L1_SHIFT			(0)
#define BB_L1_WIDTH			(13)

#define BB_RESERVE34_SHIFT		(13)
#define BB_RESERVE34_WIDTH		(3)
#define BB_L2_SHIFT			(0)
#define BB_L2_WIDTH			(13)

#define BB_GET_MASK_U32(width) \
	((width == 32) ? (0xFFFFFFFF) : ((((u32)1) << (width)) - 1))
#define BB_GET_FIELD_U32(data, width, shift) \
	(((data) >> (shift)) & BB_GET_MASK_U32(width))

#define BB_GET(field_name, data) \
	BB_GET_FIELD_U32( \
		data, \
		BB_## field_name ##_WIDTH, \
		BB_## field_name ##_SHIFT)

#define BB_GET_RESERVE0(byte0) \
	BB_GET(RESERVE0, byte0)
#define BB_GET_SIGNALING(byte0) \
	BB_GET(SIGNALING, byte0)
#define BB_GET_PLP_ID(byte0) \
	BB_GET(PLP_ID, byte0)

#define BB_GET_RESERVE12(byte12) \
	BB_GET(RESERVE12, byte12)
#define BB_GET_L1(byte12) \
	BB_GET(L1, byte12)

#define BB_GET_RESERVE34(byte34) \
	BB_GET(RESERVE34, byte34)
#define BB_GET_L2(byte34) \
	BB_GET(L2, byte34)

struct bb_header {
	// byte 0
	u8 reserve0;
	bool signaling;
	u8 plp_id;

	// byte 1,2
	u8 reserve12;
	u16 l1;

	// byte 3,4
	u8 reserve34;
	u16 l2;
};

ALP_RET_CODE_T bb_parser_parse_header(
		struct bb_header *const hdr,
		net_buf_t *const bb_pkt);

void bb_parser_dump_header(
		int log_level,
		struct bb_header *const hdr);

#endif /* ATSC30_PARSER_BB_PACKET_H */

