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 2009 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/list.h> 31 #include <sys/ethernet.h> 32 #include <sys/stream.h> 33 #include <sys/dlpi.h> 34 #include <sys/dld.h> 35 #include <sys/dls_impl.h> 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 #define DLD_CONTROL_MINOR_NAME "ctl" 42 #define DLD_CONTROL_MINOR 0 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 /* 60 * The dld_str_t object definition and protection scheme for each member 61 * is described below. The framework locking mechanism details are described in 62 * mac_impl.h and mac.c 63 * 64 * Write Once Only (WO): Typically these are initialized when the end point 65 * is created or initialized and don't change subsequently 66 * 67 * Serializer (SL): Protected by the Serializer. All modify operations on an 68 * end point go through the serializer. Readers don't care about reading 69 * these fields atomically, or readers also use the serializer to see the 70 * values atomically. 71 * 72 * Lock: kmutex_t or kwrlock_t lock. Modify operations still go through the 73 * serializer, the lock helps synchronize readers with writers. 74 */ 75 76 struct dld_str_s { /* Protected by */ 77 /* 78 * Major number of the device 79 */ 80 major_t ds_major; /* WO */ 81 82 /* 83 * Ephemeral minor number for the object. 84 */ 85 minor_t ds_minor; /* WO */ 86 87 /* 88 * PPA number this stream is attached to. 89 */ 90 t_uscalar_t ds_ppa; /* SL */ 91 92 /* 93 * Read/write queues for the stream which the object represents. 94 */ 95 queue_t *ds_rq; /* WO */ 96 queue_t *ds_wq; /* WO */ 97 98 /* 99 * Stream is open to DLD_CONTROL (control node) or 100 * DLD_DLPI (DLS provider) node. 101 */ 102 uint_t ds_type; /* WO */ 103 104 /* 105 * The following fields are only used for DLD_DLPI type objects. 106 */ 107 108 /* 109 * Current DLPI state. 110 */ 111 t_uscalar_t ds_dlstate; /* SL */ 112 113 /* 114 * DLPI style 115 */ 116 t_uscalar_t ds_style; /* WO */ 117 118 /* 119 * Currently bound DLSAP. 120 */ 121 uint16_t ds_sap; /* SL */ 122 123 /* 124 * Handle of the MAC that is used by the data-link interface. 125 */ 126 mac_handle_t ds_mh; /* SL */ 127 mac_client_handle_t ds_mch; /* SL */ 128 129 /* 130 * Promiscuity level information. 131 */ 132 uint32_t ds_promisc; /* SL */ 133 mac_promisc_handle_t ds_mph; 134 mac_promisc_handle_t ds_vlan_mph; 135 136 /* 137 * Immutable information of the MAC which the channel is using. 138 */ 139 const mac_info_t *ds_mip; /* SL */ 140 141 /* 142 * Current packet priority. 143 */ 144 uint_t ds_pri; /* SL */ 145 146 /* 147 * Handle of our MAC notification callback. 148 */ 149 mac_notify_handle_t ds_mnh; /* SL */ 150 151 /* 152 * Set of enabled DL_NOTE... notifications. (See dlpi.h). 153 */ 154 uint32_t ds_notifications; /* SL */ 155 156 /* 157 * Mode: unitdata, fast-path or raw. 158 */ 159 dld_str_mode_t ds_mode; /* SL */ 160 161 /* 162 * Native mode state. 163 */ 164 boolean_t ds_native; /* SL */ 165 166 /* 167 * IP polling is operational if this flag is set. 168 */ 169 boolean_t ds_polling; /* SL */ 170 boolean_t ds_direct; /* SL */ 171 172 /* 173 * LSO is enabled if ds_lso is set. 174 */ 175 boolean_t ds_lso; /* SL */ 176 uint64_t ds_lso_max; /* SL */ 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; /* SL */ 184 185 /* 186 * Dummy mblk used for flow-control. 187 */ 188 mblk_t *ds_tx_flow_mp; /* ds_lock */ 189 190 /* 191 * List of queued DLPI requests. These will be processed 192 * by a taskq thread. This block is protected by ds_lock 193 */ 194 kmutex_t ds_lock; 195 krwlock_t ds_rw_lock; 196 kcondvar_t ds_datathr_cv; /* ds_lock */ 197 uint_t ds_datathr_cnt; /* ds_lock */ 198 mblk_t *ds_pending_head; /* ds_lock */ 199 mblk_t *ds_pending_tail; /* ds_lock */ 200 kcondvar_t ds_dlpi_pending_cv; /* ds_lock */ 201 uint32_t 202 ds_dlpi_pending : 1, /* ds_lock */ 203 ds_local : 1, 204 ds_pad : 30; /* ds_lock */ 205 206 dls_link_t *ds_dlp; /* SL */ 207 dls_multicst_addr_t *ds_dmap; /* ds_rw_lock */ 208 dls_rx_t ds_rx; /* ds_lock */ 209 void *ds_rx_arg; /* ds_lock */ 210 boolean_t ds_active; /* SL */ 211 dld_str_t *ds_next; /* SL */ 212 dls_head_t *ds_head; 213 dls_dl_handle_t ds_ddh; 214 list_node_t ds_tqlist; 215 }; 216 217 #define DLD_DATATHR_INC(dsp) { \ 218 ASSERT(MUTEX_HELD(&(dsp)->ds_lock)); \ 219 dsp->ds_datathr_cnt++; \ 220 } 221 222 #define DLD_DATATHR_DCR(dsp) { \ 223 mutex_enter(&(dsp)->ds_lock); \ 224 (dsp)->ds_datathr_cnt--; \ 225 if ((dsp)->ds_datathr_cnt == 0) \ 226 cv_broadcast(&(dsp)->ds_datathr_cv); \ 227 mutex_exit(&(dsp)->ds_lock); \ 228 } 229 230 /* 231 * dld_str.c module. 232 */ 233 234 extern void dld_str_init(void); 235 extern int dld_str_fini(void); 236 extern dld_str_t *dld_str_create(queue_t *, uint_t, major_t, 237 t_uscalar_t); 238 extern void dld_str_destroy(dld_str_t *); 239 extern int dld_str_attach(dld_str_t *, t_uscalar_t); 240 extern void dld_str_detach(dld_str_t *); 241 extern void dld_str_rx_raw(void *, mac_resource_handle_t, 242 mblk_t *, mac_header_info_t *); 243 extern void dld_str_rx_fastpath(void *, mac_resource_handle_t, 244 mblk_t *, mac_header_info_t *); 245 extern void dld_str_rx_unitdata(void *, mac_resource_handle_t, 246 mblk_t *, mac_header_info_t *); 247 extern void dld_str_notify_ind(dld_str_t *); 248 extern mac_tx_cookie_t str_mdata_fastpath_put(dld_str_t *, mblk_t *, 249 uintptr_t, uint16_t); 250 extern int dld_flow_ctl_callb(dld_str_t *, uint64_t, 251 int (*func)(), void *); 252 253 /* 254 * dld_proto.c 255 */ 256 extern void dld_proto(dld_str_t *, mblk_t *); 257 extern void dld_proto_unitdata_req(dld_str_t *, mblk_t *); 258 extern void dld_capabilities_disable(dld_str_t *); 259 extern void proto_unitdata_req(dld_str_t *, mblk_t *); 260 261 /* 262 * dld_flow.c 263 */ 264 extern void flow_rx_pkt_chain(void *, void *, mblk_t *); 265 266 /* 267 * dld_drv.c 268 */ 269 extern mac_handle_t dld_mac_open(char *dev_name, int *err); 270 #define dld_mac_close(mh) mac_close(mh) 271 272 /* 273 * Options: there should be a separate bit defined here for each 274 * DLD_PROP... defined in dld.h. 275 */ 276 #define DLD_OPT_NO_FASTPATH 0x00000001 277 #define DLD_OPT_NO_POLL 0x00000002 278 #define DLD_OPT_NO_ZEROCOPY 0x00000004 279 #define DLD_OPT_NO_SOFTRING 0x00000008 280 281 extern uint32_t dld_opt; 282 283 /* 284 * autopush information 285 */ 286 typedef struct dld_ap { 287 datalink_id_t da_linkid; 288 struct dlautopush da_ap; 289 290 #define da_anchor da_ap.dap_anchor 291 #define da_npush da_ap.dap_npush 292 #define da_aplist da_ap.dap_aplist 293 294 } dld_ap_t; 295 296 /* 297 * Useful macros. 298 */ 299 300 #define IMPLY(p, c) (!(p) || (c)) 301 302 #define DLD_SETQFULL(dsp) { \ 303 queue_t *q = (dsp)->ds_wq; \ 304 \ 305 mutex_enter(&(dsp)->ds_lock); \ 306 if ((dsp)->ds_tx_flow_mp != NULL) { \ 307 (void) putq(q, (dsp)->ds_tx_flow_mp); \ 308 (dsp)->ds_tx_flow_mp = NULL; \ 309 qenable((dsp)->ds_wq); \ 310 } \ 311 mutex_exit(&(dsp)->ds_lock); \ 312 } 313 314 /* 315 * This is called to check whether we can disable the flow control, and 316 * it is usually only needed in TX data-path when the dsp->ds_dlstate is 317 * DL_IDLE. Otherwise, it does not hurt to always disable the flow control. 318 */ 319 #define DLD_CLRQFULL(dsp) { \ 320 queue_t *q = (dsp)->ds_wq; \ 321 \ 322 mutex_enter(&(dsp)->ds_lock); \ 323 if ((dsp)->ds_dlstate != DL_IDLE || \ 324 !mac_tx_is_flow_blocked((dsp)->ds_mch, NULL)) { \ 325 if ((dsp)->ds_tx_flow_mp == NULL) \ 326 (dsp)->ds_tx_flow_mp = getq(q); \ 327 ASSERT((dsp)->ds_tx_flow_mp != NULL); \ 328 } \ 329 mutex_exit(&(dsp)->ds_lock); \ 330 } 331 332 #define DLD_TX(dsp, mp, f_hint, flag) \ 333 mac_tx(dsp->ds_mch, mp, f_hint, flag, NULL) 334 335 #ifdef DEBUG 336 #define DLD_DBG cmn_err 337 #else 338 #define DLD_DBG if (0) cmn_err 339 #endif 340 341 #ifdef __cplusplus 342 } 343 #endif 344 345 #endif /* _SYS_DLD_IMPL_H */ 346