/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * drivers/net/ethernet/rocker/rocker_tlv.h - Rocker switch device driver
 * Copyright (c) 2014-2016 Jiri Pirko <jiri@mellanox.com>
 * Copyright (c) 2014 Scott Feldman <sfeldma@gmail.com>
 */

#ifndef _ROCKER_TLV_H
#define _ROCKER_TLV_H

#include <linux/types.h>

#include "rocker_hw.h"
#include "rocker.h"

#define ROCKER_TLV_ALIGNTO 8U
#define ROCKER_TLV_ALIGN(len) \
	(((len) + ROCKER_TLV_ALIGNTO - 1) & ~(ROCKER_TLV_ALIGNTO - 1))
#define ROCKER_TLV_HDRLEN ROCKER_TLV_ALIGN(sizeof(struct rocker_tlv))

/*  <------- ROCKER_TLV_HDRLEN -------> <--- ROCKER_TLV_ALIGN(payload) --->
 * +-----------------------------+- - -+- - - - - - - - - - - - - - -+- - -+
 * |             Header          | Pad |           Payload           | Pad |
 * |      (struct rocker_tlv)    | ing |                             | ing |
 * +-----------------------------+- - -+- - - - - - - - - - - - - - -+- - -+
 *  <--------------------------- tlv->len -------------------------->
 */

static inline struct rocker_tlv *rocker_tlv_next(const struct rocker_tlv *tlv,
						 int *remaining)
{
	int totlen = ROCKER_TLV_ALIGN(tlv->len);

	*remaining -= totlen;
	return (struct rocker_tlv *) ((char *) tlv + totlen);
}

static inline int rocker_tlv_ok(const struct rocker_tlv *tlv, int remaining)
{
	return remaining >= (int) ROCKER_TLV_HDRLEN &&
	       tlv->len >= ROCKER_TLV_HDRLEN &&
	       tlv->len <= remaining;
}

#define rocker_tlv_for_each(pos, head, len, rem)	\
	for (pos = head, rem = len;			\
	     rocker_tlv_ok(pos, rem);			\
	     pos = rocker_tlv_next(pos, &(rem)))

#define rocker_tlv_for_each_nested(pos, tlv, rem)	\
	rocker_tlv_for_each(pos, rocker_tlv_data(tlv),	\
			    rocker_tlv_len(tlv), rem)

static inline int rocker_tlv_attr_size(int payload)
{
	return ROCKER_TLV_HDRLEN + payload;
}

static inline int rocker_tlv_total_size(int payload)
{
	return ROCKER_TLV_ALIGN(rocker_tlv_attr_size(payload));
}

static inline int rocker_tlv_padlen(int payload)
{
	return rocker_tlv_total_size(payload) - rocker_tlv_attr_size(payload);
}

static inline int rocker_tlv_type(const struct rocker_tlv *tlv)
{
	return tlv->type;
}

static inline void *rocker_tlv_data(const struct rocker_tlv *tlv)
{
	return (char *) tlv + ROCKER_TLV_HDRLEN;
}

static inline int rocker_tlv_len(const struct rocker_tlv *tlv)
{
	return tlv->len - ROCKER_TLV_HDRLEN;
}

static inline u8 rocker_tlv_get_u8(const struct rocker_tlv *tlv)
{
	return *(u8 *) rocker_tlv_data(tlv);
}

static inline u16 rocker_tlv_get_u16(const struct rocker_tlv *tlv)
{
	return *(u16 *) rocker_tlv_data(tlv);
}

static inline __be16 rocker_tlv_get_be16(const struct rocker_tlv *tlv)
{
	return *(__be16 *) rocker_tlv_data(tlv);
}

static inline u32 rocker_tlv_get_u32(const struct rocker_tlv *tlv)
{
	return *(u32 *) rocker_tlv_data(tlv);
}

static inline u64 rocker_tlv_get_u64(const struct rocker_tlv *tlv)
{
	return *(u64 *) rocker_tlv_data(tlv);
}

void rocker_tlv_parse(const struct rocker_tlv **tb, int maxtype,
		      const char *buf, int buf_len);

static inline void rocker_tlv_parse_nested(const struct rocker_tlv **tb,
					   int maxtype,
					   const struct rocker_tlv *tlv)
{
	rocker_tlv_parse(tb, maxtype, rocker_tlv_data(tlv),
			 rocker_tlv_len(tlv));
}

static inline void
rocker_tlv_parse_desc(const struct rocker_tlv **tb, int maxtype,
		      const struct rocker_desc_info *desc_info)
{
	rocker_tlv_parse(tb, maxtype, desc_info->data,
			 desc_info->desc->tlv_size);
}

static inline struct rocker_tlv *
rocker_tlv_start(struct rocker_desc_info *desc_info)
{
	return (struct rocker_tlv *) ((char *) desc_info->data +
					       desc_info->tlv_size);
}

int rocker_tlv_put(struct rocker_desc_info *desc_info,
		   int attrtype, int attrlen, const void *data);

static inline int
rocker_tlv_put_u8(struct rocker_desc_info *desc_info, int attrtype, u8 value)
{
	u8 tmp = value; /* work around GCC PR81715 */

	return rocker_tlv_put(desc_info, attrtype, sizeof(u8), &tmp);
}

static inline int
rocker_tlv_put_u16(struct rocker_desc_info *desc_info, int attrtype, u16 value)
{
	u16 tmp = value;

	return rocker_tlv_put(desc_info, attrtype, sizeof(u16), &tmp);
}

static inline int
rocker_tlv_put_be16(struct rocker_desc_info *desc_info, int attrtype, __be16 value)
{
	__be16 tmp = value;

	return rocker_tlv_put(desc_info, attrtype, sizeof(__be16), &tmp);
}

static inline int
rocker_tlv_put_u32(struct rocker_desc_info *desc_info, int attrtype, u32 value)
{
	u32 tmp = value;

	return rocker_tlv_put(desc_info, attrtype, sizeof(u32), &tmp);
}

static inline int
rocker_tlv_put_be32(struct rocker_desc_info *desc_info, int attrtype, __be32 value)
{
	__be32 tmp = value;

	return rocker_tlv_put(desc_info, attrtype, sizeof(__be32), &tmp);
}

static inline int
rocker_tlv_put_u64(struct rocker_desc_info *desc_info, int attrtype, u64 value)
{
	u64 tmp = value;

	return rocker_tlv_put(desc_info, attrtype, sizeof(u64), &tmp);
}

static inline struct rocker_tlv *
rocker_tlv_nest_start(struct rocker_desc_info *desc_info, int attrtype)
{
	struct rocker_tlv *start = rocker_tlv_start(desc_info);

	if (rocker_tlv_put(desc_info, attrtype, 0, NULL) < 0)
		return NULL;

	return start;
}

static inline void rocker_tlv_nest_end(struct rocker_desc_info *desc_info,
				       struct rocker_tlv *start)
{
	start->len = (char *) rocker_tlv_start(desc_info) - (char *) start;
}

static inline void rocker_tlv_nest_cancel(struct rocker_desc_info *desc_info,
					  const struct rocker_tlv *start)
{
	desc_info->tlv_size = (const char *) start - desc_info->data;
}

#endif
