1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _SYS_DLD_IMPL_H 28 #define _SYS_DLD_IMPL_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <sys/types.h> 33 #include <sys/ethernet.h> 34 #include <sys/stream.h> 35 #include <sys/dlpi.h> 36 #include <sys/mac.h> 37 #include <sys/dls.h> 38 #include <sys/dld.h> 39 40 #ifdef __cplusplus 41 extern "C" { 42 #endif 43 44 #define DLD_CONTROL 0x00000001 45 #define DLD_DLPI 0x00000002 46 47 typedef enum { 48 DLD_UNITDATA, 49 DLD_FASTPATH, 50 DLD_RAW 51 } dld_str_mode_t; 52 53 typedef enum { 54 DLD_UNINITIALIZED, 55 DLD_PASSIVE, 56 DLD_ACTIVE 57 } dld_passivestate_t; 58 59 typedef struct dld_str dld_str_t; 60 61 /* 62 * dld_str_t object definition. 63 */ 64 struct dld_str { 65 /* 66 * Major number of the device 67 */ 68 major_t ds_major; 69 70 /* 71 * Ephemeral minor number for the object. 72 */ 73 minor_t ds_minor; 74 75 /* 76 * Read/write queues for the stream which the object represents. 77 */ 78 queue_t *ds_rq; 79 queue_t *ds_wq; 80 81 /* 82 * Lock to protect this structure. 83 */ 84 krwlock_t ds_lock; 85 86 /* 87 * Stream is open to DLD_CONTROL (control node) or 88 * DLD_DLPI (DLS provider) node. 89 */ 90 uint_t ds_type; 91 92 /* 93 * The following fields are only used for DLD_DLPI type objects. 94 */ 95 96 /* 97 * Current DLPI state. 98 */ 99 t_uscalar_t ds_dlstate; 100 101 /* 102 * DLPI style 103 */ 104 t_uscalar_t ds_style; 105 106 /* 107 * Currently bound DLSAP. 108 */ 109 uint16_t ds_sap; 110 111 /* 112 * Handle of the data-link channel that is used by this object. 113 */ 114 dls_channel_t ds_dc; 115 116 /* 117 * Handle of the MAC that is used by the data-link interface. 118 */ 119 mac_handle_t ds_mh; 120 121 /* 122 * VLAN identifier of the data-link interface. 123 */ 124 uint16_t ds_vid; 125 126 /* 127 * Promiscuity level information. 128 */ 129 uint32_t ds_promisc; 130 131 /* 132 * Immutable information of the MAC which the channel is using. 133 */ 134 const mac_info_t *ds_mip; 135 136 /* 137 * Current packet priority. 138 */ 139 uint_t ds_pri; 140 141 /* 142 * Handle of our MAC notification callback. 143 */ 144 mac_notify_handle_t ds_mnh; 145 146 /* 147 * Set of enabled DL_NOTE... notifications. (See dlpi.h). 148 */ 149 uint32_t ds_notifications; 150 151 /* 152 * Cached MAC unicast addresses. 153 */ 154 uint8_t ds_fact_addr[MAXADDRLEN]; 155 uint8_t ds_curr_addr[MAXADDRLEN]; 156 157 /* 158 * Mode: unitdata, fast-path or raw. 159 */ 160 dld_str_mode_t ds_mode; 161 162 /* 163 * IP polling is operational if this flag is set. 164 */ 165 boolean_t ds_polling; 166 boolean_t ds_soft_ring; 167 168 /* 169 * State of DLPI user: may be active (regular network layer), 170 * passive (snoop-like monitoring), or unknown (not yet 171 * determined). 172 */ 173 dld_passivestate_t ds_passivestate; 174 175 /* 176 * Dummy mblk used for flow-control. 177 */ 178 mblk_t *ds_tx_flow_mp; 179 180 /* 181 * Internal transmit queue and its parameters. 182 */ 183 kmutex_t ds_tx_list_lock; 184 mblk_t *ds_tx_list_head; 185 mblk_t *ds_tx_list_tail; 186 uint_t ds_tx_cnt; 187 uint_t ds_tx_msgcnt; 188 boolean_t ds_tx_qbusy; 189 190 /* 191 * Number of threads currently in dld. If there is a pending 192 * request, it is placed in ds_pending_req and the operation 193 * will finish when dld becomes single-threaded. 194 */ 195 kmutex_t ds_thr_lock; 196 uint_t ds_thr; 197 uint_t ds_pending_cnt; 198 mblk_t *ds_pending_req; 199 task_func_t *ds_pending_op; 200 kcondvar_t ds_pending_cv; 201 } dld_str; 202 203 /* 204 * dld_str.c module. 205 */ 206 207 extern void dld_str_init(void); 208 extern int dld_str_fini(void); 209 extern dld_str_t *dld_str_create(queue_t *, uint_t, major_t, 210 t_uscalar_t); 211 extern void dld_str_destroy(dld_str_t *); 212 extern int dld_str_attach(dld_str_t *, t_uscalar_t); 213 extern void dld_str_detach(dld_str_t *); 214 extern void dld_str_rx_raw(void *, mac_resource_handle_t, 215 mblk_t *, size_t); 216 extern void dld_str_rx_fastpath(void *, mac_resource_handle_t, 217 mblk_t *, size_t); 218 extern void dld_str_rx_unitdata(void *, mac_resource_handle_t, 219 mblk_t *, size_t); 220 extern void dld_tx_flush(dld_str_t *); 221 extern void dld_tx_enqueue(dld_str_t *, mblk_t *, boolean_t); 222 extern void dld_str_notify_ind(dld_str_t *); 223 224 extern void str_mdata_fastpath_put(dld_str_t *, mblk_t *); 225 extern void str_mdata_raw_put(dld_str_t *, mblk_t *); 226 227 /* 228 * dld_proto.c 229 */ 230 extern void dld_proto(dld_str_t *, mblk_t *); 231 extern void dld_finish_pending_ops(dld_str_t *); 232 233 /* 234 * Options: there should be a separate bit defined here for each 235 * DLD_PROP... defined in dld.h. 236 */ 237 #define DLD_OPT_NO_FASTPATH 0x00000001 238 #define DLD_OPT_NO_POLL 0x00000002 239 #define DLD_OPT_NO_ZEROCOPY 0x00000004 240 241 extern uint32_t dld_opt; 242 243 /* 244 * Useful macros. 245 */ 246 247 #define IMPLY(p, c) (!(p) || (c)) 248 #define AGGR_DEV "aggr0" 249 250 #define DLD_ENTER(dsp) { \ 251 mutex_enter(&dsp->ds_thr_lock); \ 252 ++dsp->ds_thr; \ 253 ASSERT(dsp->ds_thr != 0); \ 254 mutex_exit(&dsp->ds_thr_lock); \ 255 } 256 257 #define DLD_EXIT(dsp) { \ 258 mutex_enter(&dsp->ds_thr_lock); \ 259 ASSERT(dsp->ds_thr > 0); \ 260 if (--dsp->ds_thr == 0 && dsp->ds_pending_req != NULL) \ 261 dld_finish_pending_ops(dsp); \ 262 else \ 263 mutex_exit(&dsp->ds_thr_lock); \ 264 } 265 266 #define DLD_WAKEUP(dsp) { \ 267 mutex_enter(&dsp->ds_thr_lock); \ 268 ASSERT(dsp->ds_pending_cnt > 0); \ 269 if (--dsp->ds_pending_cnt == 0) \ 270 cv_signal(&dsp->ds_pending_cv); \ 271 mutex_exit(&dsp->ds_thr_lock); \ 272 } 273 274 #ifdef DEBUG 275 #define DLD_DBG cmn_err 276 #else 277 #define DLD_DBG if (0) cmn_err 278 #endif 279 280 #ifdef __cplusplus 281 } 282 #endif 283 284 #endif /* _SYS_DLD_IMPL_H */ 285