197f17497SC.J. Collier/*-
297f17497SC.J. Collier *   BSD LICENSE
397f17497SC.J. Collier *
497f17497SC.J. Collier *   Copyright 2015 6WIND S.A.
597f17497SC.J. Collier *   Copyright 2015 Mellanox.
697f17497SC.J. Collier *
797f17497SC.J. Collier *   Redistribution and use in source and binary forms, with or without
897f17497SC.J. Collier *   modification, are permitted provided that the following conditions
997f17497SC.J. Collier *   are met:
1097f17497SC.J. Collier *
1197f17497SC.J. Collier *     * Redistributions of source code must retain the above copyright
1297f17497SC.J. Collier *       notice, this list of conditions and the following disclaimer.
1397f17497SC.J. Collier *     * Redistributions in binary form must reproduce the above copyright
1497f17497SC.J. Collier *       notice, this list of conditions and the following disclaimer in
1597f17497SC.J. Collier *       the documentation and/or other materials provided with the
1697f17497SC.J. Collier *       distribution.
1797f17497SC.J. Collier *     * Neither the name of 6WIND S.A. nor the names of its
1897f17497SC.J. Collier *       contributors may be used to endorse or promote products derived
1997f17497SC.J. Collier *       from this software without specific prior written permission.
2097f17497SC.J. Collier *
2197f17497SC.J. Collier *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2297f17497SC.J. Collier *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2397f17497SC.J. Collier *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2497f17497SC.J. Collier *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2597f17497SC.J. Collier *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2697f17497SC.J. Collier *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2797f17497SC.J. Collier *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2897f17497SC.J. Collier *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2997f17497SC.J. Collier *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3097f17497SC.J. Collier *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3197f17497SC.J. Collier *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3297f17497SC.J. Collier */
3397f17497SC.J. Collier
3497f17497SC.J. Collier#ifndef RTE_PMD_MLX5_UTILS_H_
3597f17497SC.J. Collier#define RTE_PMD_MLX5_UTILS_H_
3697f17497SC.J. Collier
3797f17497SC.J. Collier#include <stddef.h>
3847d9763aSLuca Boccassi#include <stdint.h>
3997f17497SC.J. Collier#include <stdio.h>
4097f17497SC.J. Collier#include <limits.h>
4197f17497SC.J. Collier#include <assert.h>
4297f17497SC.J. Collier#include <errno.h>
4397f17497SC.J. Collier
4497f17497SC.J. Collier#include "mlx5_defs.h"
4597f17497SC.J. Collier
46f7a9461eSLuca Boccassi/*
47f7a9461eSLuca Boccassi * Compilation workaround for PPC64 when AltiVec is fully enabled, e.g. std=c11.
48f7a9461eSLuca Boccassi * Otherwise there would be a type conflict between stdbool and altivec.
49f7a9461eSLuca Boccassi */
50f7a9461eSLuca Boccassi#if defined(__PPC64__) && !defined(__APPLE_ALTIVEC__)
51f7a9461eSLuca Boccassi#undef bool
52f7a9461eSLuca Boccassi/* redefine as in stdbool.h */
53f7a9461eSLuca Boccassi#define bool _Bool
54f7a9461eSLuca Boccassi#endif
55f7a9461eSLuca Boccassi
5697f17497SC.J. Collier/* Bit-field manipulation. */
5797f17497SC.J. Collier#define BITFIELD_DECLARE(bf, type, size) \
5897f17497SC.J. Collier	type bf[(((size_t)(size) / (sizeof(type) * CHAR_BIT)) + \
5997f17497SC.J. Collier		 !!((size_t)(size) % (sizeof(type) * CHAR_BIT)))]
6097f17497SC.J. Collier#define BITFIELD_DEFINE(bf, type, size) \
6197f17497SC.J. Collier	BITFIELD_DECLARE((bf), type, (size)) = { 0 }
6297f17497SC.J. Collier#define BITFIELD_SET(bf, b) \
6397f17497SC.J. Collier	(assert((size_t)(b) < (sizeof(bf) * CHAR_BIT)), \
6497f17497SC.J. Collier	 (void)((bf)[((b) / (sizeof((bf)[0]) * CHAR_BIT))] |= \
6597f17497SC.J. Collier		((size_t)1 << ((b) % (sizeof((bf)[0]) * CHAR_BIT)))))
6697f17497SC.J. Collier#define BITFIELD_RESET(bf, b) \
6797f17497SC.J. Collier	(assert((size_t)(b) < (sizeof(bf) * CHAR_BIT)), \
6897f17497SC.J. Collier	 (void)((bf)[((b) / (sizeof((bf)[0]) * CHAR_BIT))] &= \
6997f17497SC.J. Collier		~((size_t)1 << ((b) % (sizeof((bf)[0]) * CHAR_BIT)))))
7097f17497SC.J. Collier#define BITFIELD_ISSET(bf, b) \
7197f17497SC.J. Collier	(assert((size_t)(b) < (sizeof(bf) * CHAR_BIT)), \
7297f17497SC.J. Collier	 !!(((bf)[((b) / (sizeof((bf)[0]) * CHAR_BIT))] & \
7397f17497SC.J. Collier	     ((size_t)1 << ((b) % (sizeof((bf)[0]) * CHAR_BIT))))))
7497f17497SC.J. Collier
7547d9763aSLuca Boccassi/* Convert a bit number to the corresponding 64-bit mask */
7647d9763aSLuca Boccassi#define MLX5_BITSHIFT(v) (UINT64_C(1) << (v))
7747d9763aSLuca Boccassi
7897f17497SC.J. Collier/* Save and restore errno around argument evaluation. */
7997f17497SC.J. Collier#define ERRNO_SAFE(x) ((errno = (int []){ errno, ((x), 0) }[0]))
8097f17497SC.J. Collier
8197f17497SC.J. Collier/*
8297f17497SC.J. Collier * Helper macros to work around __VA_ARGS__ limitations in a C99 compliant
8397f17497SC.J. Collier * manner.
8497f17497SC.J. Collier */
8597f17497SC.J. Collier#define PMD_DRV_LOG_STRIP(a, b) a
8697f17497SC.J. Collier#define PMD_DRV_LOG_OPAREN (
8797f17497SC.J. Collier#define PMD_DRV_LOG_CPAREN )
8897f17497SC.J. Collier#define PMD_DRV_LOG_COMMA ,
8997f17497SC.J. Collier
9097f17497SC.J. Collier/* Return the file name part of a path. */
9197f17497SC.J. Collierstatic inline const char *
9297f17497SC.J. Collierpmd_drv_log_basename(const char *s)
9397f17497SC.J. Collier{
9497f17497SC.J. Collier	const char *n = s;
9597f17497SC.J. Collier
9697f17497SC.J. Collier	while (*n)
9797f17497SC.J. Collier		if (*(n++) == '/')
9897f17497SC.J. Collier			s = n;
9997f17497SC.J. Collier	return s;
10097f17497SC.J. Collier}
10197f17497SC.J. Collier
10297f17497SC.J. Collier/*
10397f17497SC.J. Collier * When debugging is enabled (NDEBUG not defined), file, line and function
10497f17497SC.J. Collier * information replace the driver name (MLX5_DRIVER_NAME) in log messages.
10597f17497SC.J. Collier */
10697f17497SC.J. Collier#ifndef NDEBUG
10797f17497SC.J. Collier
10897f17497SC.J. Collier#define PMD_DRV_LOG___(level, ...) \
10997f17497SC.J. Collier	ERRNO_SAFE(RTE_LOG(level, PMD, __VA_ARGS__))
11097f17497SC.J. Collier#define PMD_DRV_LOG__(level, ...) \
11197f17497SC.J. Collier	PMD_DRV_LOG___(level, "%s:%u: %s(): " __VA_ARGS__)
11297f17497SC.J. Collier#define PMD_DRV_LOG_(level, s, ...) \
11397f17497SC.J. Collier	PMD_DRV_LOG__(level, \
11497f17497SC.J. Collier		s "\n" PMD_DRV_LOG_COMMA \
11597f17497SC.J. Collier		pmd_drv_log_basename(__FILE__) PMD_DRV_LOG_COMMA \
11697f17497SC.J. Collier		__LINE__ PMD_DRV_LOG_COMMA \
11797f17497SC.J. Collier		__func__, \
11897f17497SC.J. Collier		__VA_ARGS__)
11997f17497SC.J. Collier
12097f17497SC.J. Collier#else /* NDEBUG */
12197f17497SC.J. Collier
12297f17497SC.J. Collier#define PMD_DRV_LOG___(level, ...) \
12397f17497SC.J. Collier	ERRNO_SAFE(RTE_LOG(level, PMD, MLX5_DRIVER_NAME ": " __VA_ARGS__))
12497f17497SC.J. Collier#define PMD_DRV_LOG__(level, ...) \
12597f17497SC.J. Collier	PMD_DRV_LOG___(level, __VA_ARGS__)
12697f17497SC.J. Collier#define PMD_DRV_LOG_(level, s, ...) \
12797f17497SC.J. Collier	PMD_DRV_LOG__(level, s "\n", __VA_ARGS__)
12897f17497SC.J. Collier
12997f17497SC.J. Collier#endif /* NDEBUG */
13097f17497SC.J. Collier
13197f17497SC.J. Collier/* Generic printf()-like logging macro with automatic line feed. */
13297f17497SC.J. Collier#define PMD_DRV_LOG(level, ...) \
13397f17497SC.J. Collier	PMD_DRV_LOG_(level, \
13497f17497SC.J. Collier		__VA_ARGS__ PMD_DRV_LOG_STRIP PMD_DRV_LOG_OPAREN, \
13597f17497SC.J. Collier		PMD_DRV_LOG_CPAREN)
13697f17497SC.J. Collier
13797f17497SC.J. Collier/*
13897f17497SC.J. Collier * Like assert(), DEBUG() becomes a no-op and claim_zero() does not perform
13997f17497SC.J. Collier * any check when debugging is disabled.
14097f17497SC.J. Collier */
14197f17497SC.J. Collier#ifndef NDEBUG
14297f17497SC.J. Collier
14397f17497SC.J. Collier#define DEBUG(...) PMD_DRV_LOG(DEBUG, __VA_ARGS__)
14497f17497SC.J. Collier#define claim_zero(...) assert((__VA_ARGS__) == 0)
14597f17497SC.J. Collier
14697f17497SC.J. Collier#else /* NDEBUG */
14797f17497SC.J. Collier
14897f17497SC.J. Collier#define DEBUG(...) (void)0
14997f17497SC.J. Collier#define claim_zero(...) (__VA_ARGS__)
15097f17497SC.J. Collier
15197f17497SC.J. Collier#endif /* NDEBUG */
15297f17497SC.J. Collier
15397f17497SC.J. Collier#define INFO(...) PMD_DRV_LOG(INFO, __VA_ARGS__)
15497f17497SC.J. Collier#define WARN(...) PMD_DRV_LOG(WARNING, __VA_ARGS__)
15597f17497SC.J. Collier#define ERROR(...) PMD_DRV_LOG(ERR, __VA_ARGS__)
15697f17497SC.J. Collier
15797f17497SC.J. Collier/* Convenience macros for accessing mbuf fields. */
15897f17497SC.J. Collier#define NEXT(m) ((m)->next)
15997f17497SC.J. Collier#define DATA_LEN(m) ((m)->data_len)
16097f17497SC.J. Collier#define PKT_LEN(m) ((m)->pkt_len)
16197f17497SC.J. Collier#define DATA_OFF(m) ((m)->data_off)
16297f17497SC.J. Collier#define SET_DATA_OFF(m, o) ((m)->data_off = (o))
16397f17497SC.J. Collier#define NB_SEGS(m) ((m)->nb_segs)
16497f17497SC.J. Collier#define PORT(m) ((m)->port)
16597f17497SC.J. Collier
16697f17497SC.J. Collier/* Transpose flags. Useful to convert IBV to DPDK flags. */
16797f17497SC.J. Collier#define TRANSPOSE(val, from, to) \
16897f17497SC.J. Collier	(((from) >= (to)) ? \
16997f17497SC.J. Collier	 (((val) & (from)) / ((from) / (to))) : \
17097f17497SC.J. Collier	 (((val) & (from)) * ((to) / (from))))
17197f17497SC.J. Collier
17297f17497SC.J. Collier/* Allocate a buffer on the stack and fill it with a printf format string. */
17397f17497SC.J. Collier#define MKSTR(name, ...) \
17497f17497SC.J. Collier	char name[snprintf(NULL, 0, __VA_ARGS__) + 1]; \
17597f17497SC.J. Collier	\
17697f17497SC.J. Collier	snprintf(name, sizeof(name), __VA_ARGS__)
17797f17497SC.J. Collier
17897f17497SC.J. Collier/**
17997f17497SC.J. Collier * Return nearest power of two above input value.
18097f17497SC.J. Collier *
18197f17497SC.J. Collier * @param v
18297f17497SC.J. Collier *   Input value.
18397f17497SC.J. Collier *
18497f17497SC.J. Collier * @return
18597f17497SC.J. Collier *   Nearest power of two above input value.
18697f17497SC.J. Collier */
18797f17497SC.J. Collierstatic inline unsigned int
18897f17497SC.J. Collierlog2above(unsigned int v)
18997f17497SC.J. Collier{
19097f17497SC.J. Collier	unsigned int l;
19197f17497SC.J. Collier	unsigned int r;
19297f17497SC.J. Collier
19397f17497SC.J. Collier	for (l = 0, r = 0; (v >> 1); ++l, v >>= 1)
19497f17497SC.J. Collier		r |= (v & 1);
19597f17497SC.J. Collier	return l + r;
19697f17497SC.J. Collier}
19797f17497SC.J. Collier
19897f17497SC.J. Collier#endif /* RTE_PMD_MLX5_UTILS_H_ */
199