/* SPDX-License-Identifier: AGPL-3.0-or-later * Copyright (c) 2022 Red Hat GmbH * Author: Stefano Brivio */ #ifndef PACKET_H #define PACKET_H /** * struct desc - Generic offset-based descriptor within buffer * @offset: Offset of descriptor relative to buffer start, 32-bit limit * @len: Length of descriptor, host order, 16-bit limit */ struct desc { uint32_t offset; uint16_t len; }; /** * struct pool - Generic pool of packets stored in a buffer * @buf: Buffer storing packet descriptors * @buf_size: Total size of buffer * @size: Number of usable descriptors for the pool * @count: Number of used descriptors for the pool * @pkt: Descriptors: see macros below */ struct pool { char *buf; size_t buf_size; size_t size; size_t count; struct desc pkt[1]; }; void packet_add_do(struct pool *p, size_t len, const char *start, const char *func, int line); void *packet_get_do(const struct pool *p, const size_t index, size_t offset, size_t len, size_t *left, const char *func, int line); void pool_flush(struct pool *p); #define packet_add(p, len, start) \ packet_add_do(p, len, start, __func__, __LINE__) #define packet_get(p, index, offset, len, left) \ packet_get_do(p, index, offset, len, left, __func__, __LINE__) #define packet_get_try(p, index, offset, len, left) \ packet_get_do(p, index, offset, len, left, NULL, 0) #define PACKET_POOL_DECL(_name, _size, _buf) \ struct _name ## _t { \ char *buf; \ size_t buf_size; \ size_t size; \ size_t count; \ struct desc pkt[_size]; \ } #define PACKET_POOL_INIT_NOCAST(_size, _buf, _buf_size) \ { \ .buf_size = _buf_size, \ .buf = _buf, \ .size = _size, \ } #define PACKET_POOL(name, size, buf, buf_size) \ PACKET_POOL_DECL(name, size, buf) name = \ PACKET_POOL_INIT_NOCAST(size, buf, buf_size) #define PACKET_INIT(name, size, buf, buf_size) \ (struct name ## _t) PACKET_POOL_INIT_NOCAST(size, buf, buf_size) #define PACKET_POOL_NOINIT(name, size, buf) \ PACKET_POOL_DECL(name, size, buf) name ## _storage; \ static struct pool *name = (struct pool *)&name ## _storage #define PACKET_POOL_P(name, size, buf, buf_size) \ PACKET_POOL(name ## _storage, size, buf, buf_size); \ struct pool *name = (struct pool *)&name ## _storage #endif /* PACKET_H */