1771fa900SAdrien Mazarguil /*- 2771fa900SAdrien Mazarguil * BSD LICENSE 3771fa900SAdrien Mazarguil * 4771fa900SAdrien Mazarguil * Copyright 2015 6WIND S.A. 5771fa900SAdrien Mazarguil * Copyright 2015 Mellanox. 6771fa900SAdrien Mazarguil * 7771fa900SAdrien Mazarguil * Redistribution and use in source and binary forms, with or without 8771fa900SAdrien Mazarguil * modification, are permitted provided that the following conditions 9771fa900SAdrien Mazarguil * are met: 10771fa900SAdrien Mazarguil * 11771fa900SAdrien Mazarguil * * Redistributions of source code must retain the above copyright 12771fa900SAdrien Mazarguil * notice, this list of conditions and the following disclaimer. 13771fa900SAdrien Mazarguil * * Redistributions in binary form must reproduce the above copyright 14771fa900SAdrien Mazarguil * notice, this list of conditions and the following disclaimer in 15771fa900SAdrien Mazarguil * the documentation and/or other materials provided with the 16771fa900SAdrien Mazarguil * distribution. 17771fa900SAdrien Mazarguil * * Neither the name of 6WIND S.A. nor the names of its 18771fa900SAdrien Mazarguil * contributors may be used to endorse or promote products derived 19771fa900SAdrien Mazarguil * from this software without specific prior written permission. 20771fa900SAdrien Mazarguil * 21771fa900SAdrien Mazarguil * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22771fa900SAdrien Mazarguil * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23771fa900SAdrien Mazarguil * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24771fa900SAdrien Mazarguil * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25771fa900SAdrien Mazarguil * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26771fa900SAdrien Mazarguil * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27771fa900SAdrien Mazarguil * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28771fa900SAdrien Mazarguil * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29771fa900SAdrien Mazarguil * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30771fa900SAdrien Mazarguil * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31771fa900SAdrien Mazarguil * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32771fa900SAdrien Mazarguil */ 33771fa900SAdrien Mazarguil 34771fa900SAdrien Mazarguil #ifndef RTE_PMD_MLX5_UTILS_H_ 35771fa900SAdrien Mazarguil #define RTE_PMD_MLX5_UTILS_H_ 36771fa900SAdrien Mazarguil 37771fa900SAdrien Mazarguil #include <stddef.h> 38771fa900SAdrien Mazarguil #include <stdio.h> 39771fa900SAdrien Mazarguil #include <limits.h> 40771fa900SAdrien Mazarguil #include <assert.h> 41771fa900SAdrien Mazarguil #include <errno.h> 42771fa900SAdrien Mazarguil 43771fa900SAdrien Mazarguil #include "mlx5_defs.h" 44771fa900SAdrien Mazarguil 45771fa900SAdrien Mazarguil /* Bit-field manipulation. */ 46771fa900SAdrien Mazarguil #define BITFIELD_DECLARE(bf, type, size) \ 47771fa900SAdrien Mazarguil type bf[(((size_t)(size) / (sizeof(type) * CHAR_BIT)) + \ 48771fa900SAdrien Mazarguil !!((size_t)(size) % (sizeof(type) * CHAR_BIT)))] 49771fa900SAdrien Mazarguil #define BITFIELD_DEFINE(bf, type, size) \ 50771fa900SAdrien Mazarguil BITFIELD_DECLARE((bf), type, (size)) = { 0 } 51771fa900SAdrien Mazarguil #define BITFIELD_SET(bf, b) \ 52771fa900SAdrien Mazarguil (assert((size_t)(b) < (sizeof(bf) * CHAR_BIT)), \ 53771fa900SAdrien Mazarguil (void)((bf)[((b) / (sizeof((bf)[0]) * CHAR_BIT))] |= \ 54771fa900SAdrien Mazarguil ((size_t)1 << ((b) % (sizeof((bf)[0]) * CHAR_BIT))))) 55771fa900SAdrien Mazarguil #define BITFIELD_RESET(bf, b) \ 56771fa900SAdrien Mazarguil (assert((size_t)(b) < (sizeof(bf) * CHAR_BIT)), \ 57771fa900SAdrien Mazarguil (void)((bf)[((b) / (sizeof((bf)[0]) * CHAR_BIT))] &= \ 58771fa900SAdrien Mazarguil ~((size_t)1 << ((b) % (sizeof((bf)[0]) * CHAR_BIT))))) 59771fa900SAdrien Mazarguil #define BITFIELD_ISSET(bf, b) \ 60771fa900SAdrien Mazarguil (assert((size_t)(b) < (sizeof(bf) * CHAR_BIT)), \ 61771fa900SAdrien Mazarguil !!(((bf)[((b) / (sizeof((bf)[0]) * CHAR_BIT))] & \ 62771fa900SAdrien Mazarguil ((size_t)1 << ((b) % (sizeof((bf)[0]) * CHAR_BIT)))))) 63771fa900SAdrien Mazarguil 64771fa900SAdrien Mazarguil /* Save and restore errno around argument evaluation. */ 65771fa900SAdrien Mazarguil #define ERRNO_SAFE(x) ((errno = (int []){ errno, ((x), 0) }[0])) 66771fa900SAdrien Mazarguil 67771fa900SAdrien Mazarguil /* 68771fa900SAdrien Mazarguil * Helper macros to work around __VA_ARGS__ limitations in a C99 compliant 69771fa900SAdrien Mazarguil * manner. 70771fa900SAdrien Mazarguil */ 71771fa900SAdrien Mazarguil #define PMD_DRV_LOG_STRIP(a, b) a 72771fa900SAdrien Mazarguil #define PMD_DRV_LOG_OPAREN ( 73771fa900SAdrien Mazarguil #define PMD_DRV_LOG_CPAREN ) 74771fa900SAdrien Mazarguil #define PMD_DRV_LOG_COMMA , 75771fa900SAdrien Mazarguil 76771fa900SAdrien Mazarguil /* Return the file name part of a path. */ 77771fa900SAdrien Mazarguil static inline const char * 78771fa900SAdrien Mazarguil pmd_drv_log_basename(const char *s) 79771fa900SAdrien Mazarguil { 80771fa900SAdrien Mazarguil const char *n = s; 81771fa900SAdrien Mazarguil 82771fa900SAdrien Mazarguil while (*n) 83771fa900SAdrien Mazarguil if (*(n++) == '/') 84771fa900SAdrien Mazarguil s = n; 85771fa900SAdrien Mazarguil return s; 86771fa900SAdrien Mazarguil } 87771fa900SAdrien Mazarguil 88771fa900SAdrien Mazarguil /* 89771fa900SAdrien Mazarguil * When debugging is enabled (NDEBUG not defined), file, line and function 90771fa900SAdrien Mazarguil * information replace the driver name (MLX5_DRIVER_NAME) in log messages. 91771fa900SAdrien Mazarguil */ 92771fa900SAdrien Mazarguil #ifndef NDEBUG 93771fa900SAdrien Mazarguil 94771fa900SAdrien Mazarguil #define PMD_DRV_LOG___(level, ...) \ 95771fa900SAdrien Mazarguil ERRNO_SAFE(RTE_LOG(level, PMD, __VA_ARGS__)) 96771fa900SAdrien Mazarguil #define PMD_DRV_LOG__(level, ...) \ 97771fa900SAdrien Mazarguil PMD_DRV_LOG___(level, "%s:%u: %s(): " __VA_ARGS__) 98771fa900SAdrien Mazarguil #define PMD_DRV_LOG_(level, s, ...) \ 99771fa900SAdrien Mazarguil PMD_DRV_LOG__(level, \ 100771fa900SAdrien Mazarguil s "\n" PMD_DRV_LOG_COMMA \ 101771fa900SAdrien Mazarguil pmd_drv_log_basename(__FILE__) PMD_DRV_LOG_COMMA \ 102771fa900SAdrien Mazarguil __LINE__ PMD_DRV_LOG_COMMA \ 103771fa900SAdrien Mazarguil __func__, \ 104771fa900SAdrien Mazarguil __VA_ARGS__) 105771fa900SAdrien Mazarguil 106771fa900SAdrien Mazarguil #else /* NDEBUG */ 107771fa900SAdrien Mazarguil 108771fa900SAdrien Mazarguil #define PMD_DRV_LOG___(level, ...) \ 109771fa900SAdrien Mazarguil ERRNO_SAFE(RTE_LOG(level, PMD, MLX5_DRIVER_NAME ": " __VA_ARGS__)) 110771fa900SAdrien Mazarguil #define PMD_DRV_LOG__(level, ...) \ 111771fa900SAdrien Mazarguil PMD_DRV_LOG___(level, __VA_ARGS__) 112771fa900SAdrien Mazarguil #define PMD_DRV_LOG_(level, s, ...) \ 113771fa900SAdrien Mazarguil PMD_DRV_LOG__(level, s "\n", __VA_ARGS__) 114771fa900SAdrien Mazarguil 115771fa900SAdrien Mazarguil #endif /* NDEBUG */ 116771fa900SAdrien Mazarguil 117771fa900SAdrien Mazarguil /* Generic printf()-like logging macro with automatic line feed. */ 118771fa900SAdrien Mazarguil #define PMD_DRV_LOG(level, ...) \ 119771fa900SAdrien Mazarguil PMD_DRV_LOG_(level, \ 120771fa900SAdrien Mazarguil __VA_ARGS__ PMD_DRV_LOG_STRIP PMD_DRV_LOG_OPAREN, \ 121771fa900SAdrien Mazarguil PMD_DRV_LOG_CPAREN) 122771fa900SAdrien Mazarguil 123771fa900SAdrien Mazarguil /* 124771fa900SAdrien Mazarguil * Like assert(), DEBUG() becomes a no-op and claim_zero() does not perform 125771fa900SAdrien Mazarguil * any check when debugging is disabled. 126771fa900SAdrien Mazarguil */ 127771fa900SAdrien Mazarguil #ifndef NDEBUG 128771fa900SAdrien Mazarguil 129771fa900SAdrien Mazarguil #define DEBUG(...) PMD_DRV_LOG(DEBUG, __VA_ARGS__) 130771fa900SAdrien Mazarguil #define claim_zero(...) assert((__VA_ARGS__) == 0) 131771fa900SAdrien Mazarguil 132771fa900SAdrien Mazarguil #else /* NDEBUG */ 133771fa900SAdrien Mazarguil 134771fa900SAdrien Mazarguil #define DEBUG(...) (void)0 135771fa900SAdrien Mazarguil #define claim_zero(...) (__VA_ARGS__) 136771fa900SAdrien Mazarguil 137771fa900SAdrien Mazarguil #endif /* NDEBUG */ 138771fa900SAdrien Mazarguil 139771fa900SAdrien Mazarguil #define INFO(...) PMD_DRV_LOG(INFO, __VA_ARGS__) 140771fa900SAdrien Mazarguil #define WARN(...) PMD_DRV_LOG(WARNING, __VA_ARGS__) 141771fa900SAdrien Mazarguil #define ERROR(...) PMD_DRV_LOG(ERR, __VA_ARGS__) 142771fa900SAdrien Mazarguil 1432e22920bSAdrien Mazarguil /* Convenience macros for accessing mbuf fields. */ 1442e22920bSAdrien Mazarguil #define NEXT(m) ((m)->next) 1452e22920bSAdrien Mazarguil #define DATA_LEN(m) ((m)->data_len) 1462e22920bSAdrien Mazarguil #define PKT_LEN(m) ((m)->pkt_len) 1472e22920bSAdrien Mazarguil #define DATA_OFF(m) ((m)->data_off) 1482e22920bSAdrien Mazarguil #define SET_DATA_OFF(m, o) ((m)->data_off = (o)) 1492e22920bSAdrien Mazarguil #define NB_SEGS(m) ((m)->nb_segs) 1502e22920bSAdrien Mazarguil #define PORT(m) ((m)->port) 1512e22920bSAdrien Mazarguil 15267fa62bcSAdrien Mazarguil /* Transpose flags. Useful to convert IBV to DPDK flags. */ 15367fa62bcSAdrien Mazarguil #define TRANSPOSE(val, from, to) \ 15467fa62bcSAdrien Mazarguil (((from) >= (to)) ? \ 15567fa62bcSAdrien Mazarguil (((val) & (from)) / ((from) / (to))) : \ 15667fa62bcSAdrien Mazarguil (((val) & (from)) * ((to) / (from)))) 15767fa62bcSAdrien Mazarguil 158771fa900SAdrien Mazarguil /* Allocate a buffer on the stack and fill it with a printf format string. */ 159771fa900SAdrien Mazarguil #define MKSTR(name, ...) \ 160771fa900SAdrien Mazarguil char name[snprintf(NULL, 0, __VA_ARGS__) + 1]; \ 161771fa900SAdrien Mazarguil \ 162771fa900SAdrien Mazarguil snprintf(name, sizeof(name), __VA_ARGS__) 163771fa900SAdrien Mazarguil 164*634efbc2SNelio Laranjeiro /** 165*634efbc2SNelio Laranjeiro * Return nearest power of two above input value. 166*634efbc2SNelio Laranjeiro * 167*634efbc2SNelio Laranjeiro * @param v 168*634efbc2SNelio Laranjeiro * Input value. 169*634efbc2SNelio Laranjeiro * 170*634efbc2SNelio Laranjeiro * @return 171*634efbc2SNelio Laranjeiro * Nearest power of two above input value. 172*634efbc2SNelio Laranjeiro */ 173*634efbc2SNelio Laranjeiro static inline unsigned int 174*634efbc2SNelio Laranjeiro log2above(unsigned int v) 175*634efbc2SNelio Laranjeiro { 176*634efbc2SNelio Laranjeiro unsigned int l; 177*634efbc2SNelio Laranjeiro unsigned int r; 178*634efbc2SNelio Laranjeiro 179*634efbc2SNelio Laranjeiro for (l = 0, r = 0; (v >> 1); ++l, v >>= 1) 180*634efbc2SNelio Laranjeiro r |= (v & 1); 181*634efbc2SNelio Laranjeiro return (l + r); 182*634efbc2SNelio Laranjeiro } 183*634efbc2SNelio Laranjeiro 184771fa900SAdrien Mazarguil #endif /* RTE_PMD_MLX5_UTILS_H_ */ 185