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