1*9207f9d2SChandrakanth patil /* 2*9207f9d2SChandrakanth patil * Copyright (c) 2024, Broadcom. All rights reserved. The term 3*9207f9d2SChandrakanth patil * Broadcom refers to Broadcom Limited and/or its subsidiaries. 4*9207f9d2SChandrakanth patil * 5*9207f9d2SChandrakanth patil * Redistribution and use in source and binary forms, with or without 6*9207f9d2SChandrakanth patil * modification, are permitted provided that the following conditions 7*9207f9d2SChandrakanth patil * are met: 8*9207f9d2SChandrakanth patil * 9*9207f9d2SChandrakanth patil * 1. Redistributions of source code must retain the above copyright 10*9207f9d2SChandrakanth patil * notice, this list of conditions and the following disclaimer. 11*9207f9d2SChandrakanth patil * 2. Redistributions in binary form must reproduce the above copyright 12*9207f9d2SChandrakanth patil * notice, this list of conditions and the following disclaimer in 13*9207f9d2SChandrakanth patil * the documentation and/or other materials provided with the 14*9207f9d2SChandrakanth patil * distribution. 15*9207f9d2SChandrakanth patil * 16*9207f9d2SChandrakanth patil * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' 17*9207f9d2SChandrakanth patil * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18*9207f9d2SChandrakanth patil * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19*9207f9d2SChandrakanth patil * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 20*9207f9d2SChandrakanth patil * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21*9207f9d2SChandrakanth patil * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22*9207f9d2SChandrakanth patil * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23*9207f9d2SChandrakanth patil * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24*9207f9d2SChandrakanth patil * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25*9207f9d2SChandrakanth patil * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26*9207f9d2SChandrakanth patil * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27*9207f9d2SChandrakanth patil * 28*9207f9d2SChandrakanth patil */ 29*9207f9d2SChandrakanth patil 30*9207f9d2SChandrakanth patil #ifndef __BNXT_RE_LIST_H__ 31*9207f9d2SChandrakanth patil #define __BNXT_RE_LIST_H__ 32*9207f9d2SChandrakanth patil 33*9207f9d2SChandrakanth patil struct bnxt_re_list_node { 34*9207f9d2SChandrakanth patil struct bnxt_re_list_node *next, *prev; 35*9207f9d2SChandrakanth patil uint8_t valid; 36*9207f9d2SChandrakanth patil }; 37*9207f9d2SChandrakanth patil 38*9207f9d2SChandrakanth patil struct bnxt_re_list_head { 39*9207f9d2SChandrakanth patil struct bnxt_re_list_node node; 40*9207f9d2SChandrakanth patil pthread_mutex_t lock; 41*9207f9d2SChandrakanth patil }; 42*9207f9d2SChandrakanth patil 43*9207f9d2SChandrakanth patil #define DBLY_LIST_HEAD_INIT(name) { { true, &(name.node), &(name.node) } , \ 44*9207f9d2SChandrakanth patil PTHREAD_MUTEX_INITIALIZER } 45*9207f9d2SChandrakanth patil 46*9207f9d2SChandrakanth patil #define DBLY_LIST_HEAD(name) \ 47*9207f9d2SChandrakanth patil struct bnxt_re_list_head name = DBLY_LIST_HEAD_INIT(name); \ 48*9207f9d2SChandrakanth patil 49*9207f9d2SChandrakanth patil #define INIT_DBLY_LIST_NODE(ptr) do { \ 50*9207f9d2SChandrakanth patil (ptr)->next = (ptr); (ptr)->prev = (ptr); (ptr)->valid = false; \ 51*9207f9d2SChandrakanth patil } while (0) 52*9207f9d2SChandrakanth patil 53*9207f9d2SChandrakanth patil #define INIT_DBLY_LIST_HEAD(ptr) INIT_DBLY_LIST_NODE(ptr.node) 54*9207f9d2SChandrakanth patil 55*9207f9d2SChandrakanth patil static inline void __list_add_node(struct bnxt_re_list_node *new, 56*9207f9d2SChandrakanth patil struct bnxt_re_list_node *prev, 57*9207f9d2SChandrakanth patil struct bnxt_re_list_node *next) 58*9207f9d2SChandrakanth patil { 59*9207f9d2SChandrakanth patil next->prev = new; 60*9207f9d2SChandrakanth patil new->next = next; 61*9207f9d2SChandrakanth patil new->prev = prev; 62*9207f9d2SChandrakanth patil prev->next = new; 63*9207f9d2SChandrakanth patil } 64*9207f9d2SChandrakanth patil 65*9207f9d2SChandrakanth patil static inline void list_add_node_tail(struct bnxt_re_list_node *new, 66*9207f9d2SChandrakanth patil struct bnxt_re_list_head *head) 67*9207f9d2SChandrakanth patil { 68*9207f9d2SChandrakanth patil __list_add_node(new, head->node.prev, &head->node); 69*9207f9d2SChandrakanth patil new->valid = true; 70*9207f9d2SChandrakanth patil } 71*9207f9d2SChandrakanth patil 72*9207f9d2SChandrakanth patil static inline void __list_del_node(struct bnxt_re_list_node *prev, 73*9207f9d2SChandrakanth patil struct bnxt_re_list_node *next) 74*9207f9d2SChandrakanth patil { 75*9207f9d2SChandrakanth patil next->prev = prev; 76*9207f9d2SChandrakanth patil prev->next = next; 77*9207f9d2SChandrakanth patil } 78*9207f9d2SChandrakanth patil 79*9207f9d2SChandrakanth patil static inline void list_del_node(struct bnxt_re_list_node *entry) 80*9207f9d2SChandrakanth patil { 81*9207f9d2SChandrakanth patil __list_del_node(entry->prev, entry->next); 82*9207f9d2SChandrakanth patil entry->next = entry->prev = 0; 83*9207f9d2SChandrakanth patil entry->valid = false; 84*9207f9d2SChandrakanth patil } 85*9207f9d2SChandrakanth patil 86*9207f9d2SChandrakanth patil #define bnxt_re_list_empty(head) \ 87*9207f9d2SChandrakanth patil (((head)->node.next == &(head)->node) && \ 88*9207f9d2SChandrakanth patil ((head)->node.prev == &(head)->node)) 89*9207f9d2SChandrakanth patil 90*9207f9d2SChandrakanth patil #define list_lock(head) pthread_mutex_lock(&((head)->lock)) 91*9207f9d2SChandrakanth patil #define list_unlock(head) pthread_mutex_unlock(&((head)->lock)) 92*9207f9d2SChandrakanth patil 93*9207f9d2SChandrakanth patil #define list_node(ptr, type, member) \ 94*9207f9d2SChandrakanth patil ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) 95*9207f9d2SChandrakanth patil 96*9207f9d2SChandrakanth patil #define list_node_valid(node) (node)->valid 97*9207f9d2SChandrakanth patil 98*9207f9d2SChandrakanth patil /** 99*9207f9d2SChandrakanth patil * list_for_each_node_safe - iterate over a list safe against removal of list entry 100*9207f9d2SChandrakanth patil * @pos: the &struct bnxt_re_list_head to use as a loop counter. 101*9207f9d2SChandrakanth patil * @n: another &struct bnxt_re_list_head to use as temporary storage 102*9207f9d2SChandrakanth patil * @head: the head for your list. 103*9207f9d2SChandrakanth patil */ 104*9207f9d2SChandrakanth patil #define list_for_each_node_safe(pos, n, head) \ 105*9207f9d2SChandrakanth patil for (pos = (head)->node.next, n = pos->next; pos != &((head)->node); \ 106*9207f9d2SChandrakanth patil pos = n, n = pos->next) 107*9207f9d2SChandrakanth patil 108*9207f9d2SChandrakanth patil static inline void bnxt_re_list_add_node(struct bnxt_re_list_node *node, 109*9207f9d2SChandrakanth patil struct bnxt_re_list_head *head) 110*9207f9d2SChandrakanth patil { 111*9207f9d2SChandrakanth patil if (!list_node_valid(node)) 112*9207f9d2SChandrakanth patil list_add_node_tail(node, head); 113*9207f9d2SChandrakanth patil } 114*9207f9d2SChandrakanth patil 115*9207f9d2SChandrakanth patil static inline void bnxt_re_list_del_node(struct bnxt_re_list_node *node, 116*9207f9d2SChandrakanth patil struct bnxt_re_list_head *head) 117*9207f9d2SChandrakanth patil { 118*9207f9d2SChandrakanth patil if (list_node_valid(node)) 119*9207f9d2SChandrakanth patil list_del_node(node); 120*9207f9d2SChandrakanth patil } 121*9207f9d2SChandrakanth patil 122*9207f9d2SChandrakanth patil #endif /* __bnxt_re_LIST_H__ */ 123