1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #ifndef _SYS_MULTIDATA_IMPL_H 28*0Sstevel@tonic-gate #define _SYS_MULTIDATA_IMPL_H 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gate #ifdef __cplusplus 33*0Sstevel@tonic-gate extern "C" { 34*0Sstevel@tonic-gate #endif 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gate /* 37*0Sstevel@tonic-gate * Multidata: implementation-private data structure and declarations. 38*0Sstevel@tonic-gate */ 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gate /* 41*0Sstevel@tonic-gate * Structure used for insque/remque circular list operations. 42*0Sstevel@tonic-gate */ 43*0Sstevel@tonic-gate typedef struct ql_s { 44*0Sstevel@tonic-gate struct ql_s *ql_next; /* pointer to next list element */ 45*0Sstevel@tonic-gate struct ql_s *ql_prev; /* pointer to previous list element */ 46*0Sstevel@tonic-gate } ql_t; 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gate #define QL_INIT(q) { \ 49*0Sstevel@tonic-gate ((ql_t *)(q))->ql_next = (ql_t *)(q); \ 50*0Sstevel@tonic-gate ((ql_t *)(q))->ql_prev = (ql_t *)(q); \ 51*0Sstevel@tonic-gate } 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate typedef struct pdesc_slab_s pdesc_slab_t; 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gate /* 56*0Sstevel@tonic-gate * Attribute hash bucket structure. 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate typedef struct patbkt_s { 59*0Sstevel@tonic-gate kmutex_t pbkt_lock; /* per-bucket lock */ 60*0Sstevel@tonic-gate ql_t pbkt_pattr_q; /* list of attributes */ 61*0Sstevel@tonic-gate uint_t pbkt_tbl_sz; /* table size (if this is first bucket) */ 62*0Sstevel@tonic-gate } patbkt_t; 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate /* 65*0Sstevel@tonic-gate * Attribute structure. 66*0Sstevel@tonic-gate */ 67*0Sstevel@tonic-gate #define PATTR_MAGIC 0x50615472 /* "PaTr" */ 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate struct pattr_s { 70*0Sstevel@tonic-gate pattr_t *pat_next; /* pointer to next attribute in bucket */ 71*0Sstevel@tonic-gate pattr_t *pat_prev; /* pointer to previous attribute in bucket */ 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gate uint_t pat_magic; /* set to PATTR_MAGIC */ 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate kmutex_t *pat_lock; /* pointer to per-bucket lock */ 76*0Sstevel@tonic-gate multidata_t *pat_mmd; /* back pointer to Multidata */ 77*0Sstevel@tonic-gate uint_t pat_buflen; /* length of this structure + attribute */ 78*0Sstevel@tonic-gate uint_t pat_type; /* type of encapsulated attribute */ 79*0Sstevel@tonic-gate uint_t pat_flags; /* misc. flags */ 80*0Sstevel@tonic-gate }; 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate /* 83*0Sstevel@tonic-gate * Values for pat_flags. 84*0Sstevel@tonic-gate */ 85*0Sstevel@tonic-gate #define PATTR_REM_DEFER 0x1 /* entry is marked unusable but still exists */ 86*0Sstevel@tonic-gate #define PATTR_PERSIST 0x2 /* entry can't be removed */ 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate #define Q2PATTR(p) \ 89*0Sstevel@tonic-gate ((pattr_t *)((caddr_t)(p) - offsetof(pattr_t, pat_next))) 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate /* 92*0Sstevel@tonic-gate * Packet descriptor structure. 93*0Sstevel@tonic-gate */ 94*0Sstevel@tonic-gate #define PDESC_MAGIC 0x506b5464 /* "PkTd" */ 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate struct pdesc_s { 97*0Sstevel@tonic-gate pdesc_t *pd_next; /* pointer to next descriptor */ 98*0Sstevel@tonic-gate pdesc_t *pd_prev; /* pointer to previous descriptor */ 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate uint_t pd_magic; /* set to PDESC_MAGIC */ 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate pdesc_slab_t *pd_slab; /* back pointer to descriptor slab */ 103*0Sstevel@tonic-gate patbkt_t *pd_pattbl; /* hash table of local attributes */ 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gate pdescinfo_t pd_pdi; /* embedded descriptor info structure */ 106*0Sstevel@tonic-gate 107*0Sstevel@tonic-gate #define pd_flags pd_pdi.flags 108*0Sstevel@tonic-gate }; 109*0Sstevel@tonic-gate 110*0Sstevel@tonic-gate /* 111*0Sstevel@tonic-gate * Additional internal flags for pd_flags (see multidata.h for the rest). 112*0Sstevel@tonic-gate */ 113*0Sstevel@tonic-gate #define PDESC_REM_DEFER 0x1000 /* entry is marked unusable but still exists */ 114*0Sstevel@tonic-gate #define PDESC_HAS_REF (PDESC_HBUF_REF | PDESC_PBUF_REF) 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate #define Q2PD(p) \ 117*0Sstevel@tonic-gate ((pdesc_t *)((caddr_t)(p) - offsetof(pdesc_t, pd_next))) 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate #define PDI_COPY(pd_src, pd_dst) { \ 120*0Sstevel@tonic-gate (pd_dst)->flags = (pd_src)->flags & PDESC_HAS_REF; \ 121*0Sstevel@tonic-gate if ((pd_dst)->flags & PDESC_HBUF_REF) { \ 122*0Sstevel@tonic-gate (pd_dst)->hdr_base = (pd_src)->hdr_base; \ 123*0Sstevel@tonic-gate (pd_dst)->hdr_rptr = (pd_src)->hdr_rptr; \ 124*0Sstevel@tonic-gate (pd_dst)->hdr_wptr = (pd_src)->hdr_wptr; \ 125*0Sstevel@tonic-gate (pd_dst)->hdr_lim = (pd_src)->hdr_lim; \ 126*0Sstevel@tonic-gate } else { \ 127*0Sstevel@tonic-gate (pd_dst)->hdr_base = NULL; \ 128*0Sstevel@tonic-gate (pd_dst)->hdr_rptr = NULL; \ 129*0Sstevel@tonic-gate (pd_dst)->hdr_wptr = NULL; \ 130*0Sstevel@tonic-gate (pd_dst)->hdr_lim = NULL; \ 131*0Sstevel@tonic-gate } \ 132*0Sstevel@tonic-gate \ 133*0Sstevel@tonic-gate if ((pd_dst)->flags & PDESC_PBUF_REF) { \ 134*0Sstevel@tonic-gate int i; \ 135*0Sstevel@tonic-gate \ 136*0Sstevel@tonic-gate (pd_dst)->pld_cnt = (pd_src)->pld_cnt; \ 137*0Sstevel@tonic-gate for (i = 0; i < (pd_dst)->pld_cnt; i++) { \ 138*0Sstevel@tonic-gate (pd_dst)->pld_ary[i].pld_pbuf_idx = \ 139*0Sstevel@tonic-gate (pd_src)->pld_ary[i].pld_pbuf_idx; \ 140*0Sstevel@tonic-gate (pd_dst)->pld_ary[i].pld_rptr = \ 141*0Sstevel@tonic-gate (pd_src)->pld_ary[i].pld_rptr; \ 142*0Sstevel@tonic-gate (pd_dst)->pld_ary[i].pld_wptr = \ 143*0Sstevel@tonic-gate (pd_src)->pld_ary[i].pld_wptr; \ 144*0Sstevel@tonic-gate } \ 145*0Sstevel@tonic-gate } else { \ 146*0Sstevel@tonic-gate (pd_dst)->pld_cnt = 0; \ 147*0Sstevel@tonic-gate } \ 148*0Sstevel@tonic-gate } 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate /* 151*0Sstevel@tonic-gate * Packet descriptor slab structure. 152*0Sstevel@tonic-gate */ 153*0Sstevel@tonic-gate struct pdesc_slab_s { 154*0Sstevel@tonic-gate pdesc_slab_t *pds_next; /* pointer to next descriptor slab */ 155*0Sstevel@tonic-gate pdesc_slab_t *pds_prev; /* pointer to previous descriptor slab */ 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate multidata_t *pds_mmd; /* back pointer to Multidata */ 158*0Sstevel@tonic-gate uint_t pds_used; /* always-increasing index to array */ 159*0Sstevel@tonic-gate uint_t pds_sz; /* size of descriptor array */ 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate pdesc_t pds_free_desc[1]; /* array of available descriptors */ 162*0Sstevel@tonic-gate }; 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate #define Q2PDSLAB(p) \ 165*0Sstevel@tonic-gate ((pdesc_slab_t *)((caddr_t)(p) - offsetof(pdesc_slab_t, pds_next))) 166*0Sstevel@tonic-gate 167*0Sstevel@tonic-gate #define PDESC_SLAB_SIZE(npd) \ 168*0Sstevel@tonic-gate ((size_t)(&((pdesc_slab_t *)0)->pds_free_desc[npd])) 169*0Sstevel@tonic-gate 170*0Sstevel@tonic-gate /* 171*0Sstevel@tonic-gate * Multidata metadata structure. 172*0Sstevel@tonic-gate */ 173*0Sstevel@tonic-gate #define MULTIDATA_MAGIC 0x4d645461 /* "MdTa" */ 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gate struct multidata_s { 176*0Sstevel@tonic-gate uint_t mmd_magic; /* set to MULTIDATA_MAGIC */ 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gate dblk_t *mmd_dp; /* back pointer to wrapper dblk structure */ 179*0Sstevel@tonic-gate mblk_t *mmd_hbuf; /* pointer to header buffer mblk */ 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gate patbkt_t *mmd_pattbl; /* hash table of global attributes */ 182*0Sstevel@tonic-gate 183*0Sstevel@tonic-gate kmutex_t mmd_pd_slab_lock; /* lock to protect the following items */ 184*0Sstevel@tonic-gate uint_t mmd_pbuf_cnt; /* number of data buffer */ 185*0Sstevel@tonic-gate mblk_t *mmd_pbuf[MULTIDATA_MAX_PBUFS]; /* data buffer mblk(s) */ 186*0Sstevel@tonic-gate ql_t mmd_pd_slab_q; /* list of packet descriptor slabs */ 187*0Sstevel@tonic-gate ql_t mmd_pd_q; /* list of packet descriptors */ 188*0Sstevel@tonic-gate uint_t mmd_slab_cnt; /* number of packet descriptor slabs */ 189*0Sstevel@tonic-gate uint_t mmd_pd_cnt; /* number of in-use packet desciptors */ 190*0Sstevel@tonic-gate uint_t mmd_hbuf_ref; /* descriptors referring to header buffer */ 191*0Sstevel@tonic-gate uint_t mmd_pbuf_ref; /* descriptors referring to payload buffer(s) */ 192*0Sstevel@tonic-gate }; 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gate /* 195*0Sstevel@tonic-gate * Smaller and private version of pdescinfo_t used specifically for tcp, 196*0Sstevel@tonic-gate * which allows for only two payload spans per packet. Any changes made 197*0Sstevel@tonic-gate * to the pdescinfo_t structure must be reflected here as well. 198*0Sstevel@tonic-gate */ 199*0Sstevel@tonic-gate typedef struct tcp_pdescinfo_s { 200*0Sstevel@tonic-gate uint_t flags; /* misc. flags */ 201*0Sstevel@tonic-gate uchar_t *hdr_base; /* start address of header area */ 202*0Sstevel@tonic-gate uchar_t *hdr_rptr; /* start address of header data */ 203*0Sstevel@tonic-gate uchar_t *hdr_wptr; /* end address of header data */ 204*0Sstevel@tonic-gate uchar_t *hdr_lim; /* end address of header area */ 205*0Sstevel@tonic-gate uint_t pld_cnt; /* number of payload area */ 206*0Sstevel@tonic-gate struct pld_ary_s pld_ary[2]; 207*0Sstevel@tonic-gate } tcp_pdescinfo_t; 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate #ifdef _KERNEL 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gate extern void mmd_init(void); 212*0Sstevel@tonic-gate extern mblk_t *mmd_copy(mblk_t *, int); 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gate #endif /* _KERNEL */ 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate #ifdef __cplusplus 217*0Sstevel@tonic-gate } 218*0Sstevel@tonic-gate #endif 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate #endif /* _SYS_MULTIDATA_IMPL_H */ 221