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 2008 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 #include <sys/types.h> 30 #include <sys/conf.h> 31 #include <sys/ethernet.h> 32 #include <sys/stream.h> 33 #include <sys/dlpi.h> 34 #include <sys/mac.h> 35 #include <sys/dls.h> 36 #include <sys/dld.h> 37 38 #ifdef __cplusplus 39 extern "C" { 40 #endif 41 42 #define DLD_CONTROL 0x00000001 43 #define DLD_DLPI 0x00000002 44 45 typedef enum { 46 DLD_UNITDATA, 47 DLD_FASTPATH, 48 DLD_RAW 49 } dld_str_mode_t; 50 51 typedef enum { 52 DLD_UNINITIALIZED, 53 DLD_PASSIVE, 54 DLD_ACTIVE 55 } dld_passivestate_t; 56 57 typedef struct dld_str dld_str_t; 58 typedef void (*dld_tx_t)(struct dld_str *, mblk_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 * Read/write queues for the stream which the object represents. 76 */ 77 queue_t *ds_rq; 78 queue_t *ds_wq; 79 80 /* 81 * Lock to protect this structure. 82 */ 83 krwlock_t ds_lock; 84 85 /* 86 * Stream is open to DLD_CONTROL (control node) or 87 * DLD_DLPI (DLS provider) node. 88 */ 89 uint_t ds_type; 90 91 /* 92 * The following fields are only used for DLD_DLPI type objects. 93 */ 94 95 /* 96 * Current DLPI state. 97 */ 98 t_uscalar_t ds_dlstate; 99 100 /* 101 * DLPI style 102 */ 103 t_uscalar_t ds_style; 104 105 /* 106 * Currently bound DLSAP. 107 */ 108 uint16_t ds_sap; 109 110 /* 111 * Handle of the data-link channel that is used by this object. 112 */ 113 dls_channel_t ds_dc; 114 115 /* 116 * Handle of the MAC that is used by the data-link interface. 117 */ 118 mac_handle_t ds_mh; 119 120 /* 121 * VLAN identifier of the data-link interface. 122 */ 123 uint16_t ds_vid; 124 125 /* 126 * Promiscuity level information. 127 */ 128 uint32_t ds_promisc; 129 130 /* 131 * Immutable information of the MAC which the channel is using. 132 */ 133 const mac_info_t *ds_mip; 134 135 /* 136 * Current packet priority. 137 */ 138 uint_t ds_pri; 139 140 /* 141 * Handle of our MAC notification callback. 142 */ 143 mac_notify_handle_t ds_mnh; 144 145 /* 146 * Set of enabled DL_NOTE... notifications. (See dlpi.h). 147 */ 148 uint32_t ds_notifications; 149 150 /* 151 * Cached MAC unicast addresses. 152 */ 153 uint8_t ds_fact_addr[MAXMACADDRLEN]; 154 uint8_t ds_curr_addr[MAXMACADDRLEN]; 155 156 /* 157 * Mode: unitdata, fast-path or raw. 158 */ 159 dld_str_mode_t ds_mode; 160 161 /* 162 * Native mode state. 163 */ 164 boolean_t ds_native; 165 166 /* 167 * IP polling is operational if this flag is set. 168 */ 169 boolean_t ds_polling; 170 boolean_t ds_soft_ring; 171 172 /* 173 * LSO is enabled if ds_lso is set. 174 */ 175 boolean_t ds_lso; 176 uint64_t ds_lso_max; 177 178 /* 179 * State of DLPI user: may be active (regular network layer), 180 * passive (snoop-like monitoring), or unknown (not yet 181 * determined). 182 */ 183 dld_passivestate_t ds_passivestate; 184 185 /* 186 * Dummy mblk used for flow-control. 187 */ 188 mblk_t *ds_tx_flow_mp; 189 190 /* 191 * Internal transmit queue and its parameters. 192 */ 193 kmutex_t ds_tx_list_lock; 194 mblk_t *ds_tx_list_head; 195 mblk_t *ds_tx_list_tail; 196 uint_t ds_tx_cnt; 197 uint_t ds_tx_msgcnt; 198 timeout_id_t ds_tx_qdepth_tid; 199 boolean_t ds_tx_qbusy; 200 201 dld_tx_t ds_tx; 202 dld_tx_t ds_unitdata_tx; 203 kmutex_t ds_tx_lock; 204 kcondvar_t ds_tx_cv; 205 uint32_t ds_intx_cnt; 206 boolean_t ds_detaching; 207 208 /* 209 * Pending control messages to be processed. 210 */ 211 mblk_t *ds_pending_head; 212 mblk_t *ds_pending_tail; 213 214 taskqid_t ds_tid; 215 kmutex_t ds_disp_lock; 216 kcondvar_t ds_disp_cv; 217 boolean_t ds_closing; 218 219 /* 220 * Used to process ioctl message for control node. See comments 221 * above dld_ioctl(). 222 */ 223 void (*ds_ioctl)(queue_t *, mblk_t *); 224 }; 225 226 #define DLD_TX_ENTER(dsp) { \ 227 mutex_enter(&(dsp)->ds_tx_lock); \ 228 (dsp)->ds_intx_cnt++; \ 229 mutex_exit(&(dsp)->ds_tx_lock); \ 230 } 231 232 #define DLD_TX_EXIT(dsp) { \ 233 mutex_enter(&(dsp)->ds_tx_lock); \ 234 if ((--(dsp)->ds_intx_cnt == 0) && (dsp)->ds_detaching) \ 235 cv_signal(&(dsp)->ds_tx_cv); \ 236 mutex_exit(&(dsp)->ds_tx_lock); \ 237 } 238 239 /* 240 * Quiesce the traffic. 241 */ 242 #define DLD_TX_QUIESCE(dsp) { \ 243 mutex_enter(&(dsp)->ds_tx_lock); \ 244 (dsp)->ds_tx = (dsp)->ds_unitdata_tx = NULL; \ 245 (dsp)->ds_detaching = B_TRUE; \ 246 while ((dsp)->ds_intx_cnt != 0) \ 247 cv_wait(&(dsp)->ds_tx_cv, &(dsp)->ds_tx_lock); \ 248 (dsp)->ds_detaching = B_FALSE; \ 249 mutex_exit(&(dsp)->ds_tx_lock); \ 250 } 251 252 /* 253 * dld_str.c module. 254 */ 255 256 extern void dld_str_init(void); 257 extern int dld_str_fini(void); 258 extern dld_str_t *dld_str_create(queue_t *, uint_t, major_t, 259 t_uscalar_t); 260 extern void dld_str_destroy(dld_str_t *); 261 extern int dld_str_attach(dld_str_t *, t_uscalar_t); 262 extern void dld_str_detach(dld_str_t *); 263 extern void dld_str_rx_raw(void *, mac_resource_handle_t, 264 mblk_t *, mac_header_info_t *); 265 extern void dld_str_rx_fastpath(void *, mac_resource_handle_t, 266 mblk_t *, mac_header_info_t *); 267 extern void dld_str_rx_unitdata(void *, mac_resource_handle_t, 268 mblk_t *, mac_header_info_t *); 269 270 extern void dld_tx_flush(dld_str_t *); 271 extern void dld_str_notify_ind(dld_str_t *); 272 extern void dld_tx_single(dld_str_t *, mblk_t *); 273 extern void str_mdata_fastpath_put(dld_str_t *, mblk_t *); 274 extern void str_mdata_raw_put(dld_str_t *, mblk_t *); 275 276 extern void dld_ioctl(queue_t *, mblk_t *); 277 extern void dld_finish_pending_task(dld_str_t *); 278 279 /* 280 * dld_proto.c 281 */ 282 extern void dld_wput_proto_nondata(dld_str_t *, mblk_t *); 283 extern void dld_wput_proto_data(dld_str_t *, mblk_t *); 284 extern void dld_capabilities_disable(dld_str_t *); 285 286 /* 287 * Options: there should be a separate bit defined here for each 288 * DLD_PROP... defined in dld.h. 289 */ 290 #define DLD_OPT_NO_FASTPATH 0x00000001 291 #define DLD_OPT_NO_POLL 0x00000002 292 #define DLD_OPT_NO_ZEROCOPY 0x00000004 293 #define DLD_OPT_NO_SOFTRING 0x00000008 294 295 extern uint32_t dld_opt; 296 297 /* 298 * autopush information 299 */ 300 typedef struct dld_ap { 301 datalink_id_t da_linkid; 302 struct dlautopush da_ap; 303 304 #define da_anchor da_ap.dap_anchor 305 #define da_npush da_ap.dap_npush 306 #define da_aplist da_ap.dap_aplist 307 308 } dld_ap_t; 309 310 /* 311 * Useful macros. 312 */ 313 314 #define IMPLY(p, c) (!(p) || (c)) 315 316 #ifdef DEBUG 317 #define DLD_DBG cmn_err 318 #else 319 #define DLD_DBG if (0) cmn_err 320 #endif 321 322 #ifdef __cplusplus 323 } 324 #endif 325 326 #endif /* _SYS_DLD_IMPL_H */ 327