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