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 uint_t ds_nactive; /* 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 * driver private data set by the driver when calling dld_str_open(). 218 */ 219 void *ds_private; 220 221 boolean_t ds_lowlink; /* SL */ 222 }; 223 224 225 #define DLD_DATATHR_INC(dsp) { \ 226 ASSERT(MUTEX_HELD(&(dsp)->ds_lock)); \ 227 dsp->ds_datathr_cnt++; \ 228 } 229 230 #define DLD_DATATHR_DCR(dsp) { \ 231 mutex_enter(&(dsp)->ds_lock); \ 232 (dsp)->ds_datathr_cnt--; \ 233 if ((dsp)->ds_datathr_cnt == 0) \ 234 cv_broadcast(&(dsp)->ds_datathr_cv); \ 235 mutex_exit(&(dsp)->ds_lock); \ 236 } 237 238 /* 239 * dld_str.c module. 240 */ 241 242 extern void dld_str_init(void); 243 extern int dld_str_fini(void); 244 extern dld_str_t *dld_str_create(queue_t *, uint_t, major_t, 245 t_uscalar_t); 246 extern void dld_str_destroy(dld_str_t *); 247 extern int dld_str_attach(dld_str_t *, t_uscalar_t); 248 extern void dld_str_detach(dld_str_t *); 249 extern void dld_str_rx_raw(void *, mac_resource_handle_t, 250 mblk_t *, mac_header_info_t *); 251 extern void dld_str_rx_fastpath(void *, mac_resource_handle_t, 252 mblk_t *, mac_header_info_t *); 253 extern void dld_str_rx_unitdata(void *, mac_resource_handle_t, 254 mblk_t *, mac_header_info_t *); 255 extern void dld_str_notify_ind(dld_str_t *); 256 extern mac_tx_cookie_t str_mdata_fastpath_put(dld_str_t *, mblk_t *, 257 uintptr_t, uint16_t); 258 extern int dld_flow_ctl_callb(dld_str_t *, uint64_t, 259 int (*func)(), void *); 260 261 /* 262 * dld_proto.c 263 */ 264 extern void dld_proto(dld_str_t *, mblk_t *); 265 extern void dld_proto_unitdata_req(dld_str_t *, mblk_t *); 266 extern void dld_capabilities_disable(dld_str_t *); 267 extern void proto_unitdata_req(dld_str_t *, mblk_t *); 268 269 /* 270 * dld_flow.c 271 */ 272 extern void flow_rx_pkt_chain(void *, void *, mblk_t *); 273 274 /* 275 * dld_drv.c 276 */ 277 extern mac_handle_t dld_mac_open(char *dev_name, int *err); 278 #define dld_mac_close(mh) mac_close(mh) 279 280 /* 281 * Options: there should be a separate bit defined here for each 282 * DLD_PROP... defined in dld.h. 283 */ 284 #define DLD_OPT_NO_FASTPATH 0x00000001 285 #define DLD_OPT_NO_POLL 0x00000002 286 #define DLD_OPT_NO_ZEROCOPY 0x00000004 287 #define DLD_OPT_NO_SOFTRING 0x00000008 288 289 extern uint32_t dld_opt; 290 291 /* 292 * autopush information 293 */ 294 typedef struct dld_ap { 295 datalink_id_t da_linkid; 296 struct dlautopush da_ap; 297 298 #define da_anchor da_ap.dap_anchor 299 #define da_npush da_ap.dap_npush 300 #define da_aplist da_ap.dap_aplist 301 302 } dld_ap_t; 303 304 /* 305 * Useful macros. 306 */ 307 308 #define IMPLY(p, c) (!(p) || (c)) 309 310 #define DLD_SETQFULL(dsp) { \ 311 queue_t *q = (dsp)->ds_wq; \ 312 \ 313 mutex_enter(&(dsp)->ds_lock); \ 314 if ((dsp)->ds_tx_flow_mp != NULL) { \ 315 (void) putq(q, (dsp)->ds_tx_flow_mp); \ 316 (dsp)->ds_tx_flow_mp = NULL; \ 317 qenable((dsp)->ds_wq); \ 318 } \ 319 mutex_exit(&(dsp)->ds_lock); \ 320 } 321 322 /* 323 * This is called to check whether we can disable the flow control, and 324 * it is usually only needed in TX data-path when the dsp->ds_dlstate is 325 * DL_IDLE. Otherwise, it does not hurt to always disable the flow control. 326 */ 327 #define DLD_CLRQFULL(dsp) { \ 328 queue_t *q = (dsp)->ds_wq; \ 329 \ 330 mutex_enter(&(dsp)->ds_lock); \ 331 if ((dsp)->ds_dlstate != DL_IDLE || \ 332 !mac_tx_is_flow_blocked((dsp)->ds_mch, NULL)) { \ 333 if ((dsp)->ds_tx_flow_mp == NULL) \ 334 (dsp)->ds_tx_flow_mp = getq(q); \ 335 ASSERT((dsp)->ds_tx_flow_mp != NULL); \ 336 } \ 337 mutex_exit(&(dsp)->ds_lock); \ 338 } 339 340 #define DLD_TX(dsp, mp, f_hint, flag) \ 341 mac_tx(dsp->ds_mch, mp, f_hint, flag, NULL) 342 343 #ifdef DEBUG 344 #define DLD_DBG cmn_err 345 #else 346 #define DLD_DBG if (0) cmn_err 347 #endif 348 349 #ifdef __cplusplus 350 } 351 #endif 352 353 #endif /* _SYS_DLD_IMPL_H */ 354