10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51804Sericheng * Common Development and Distribution License (the "License"). 61804Sericheng * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 228833SVenu.Iyer@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #ifndef _SYS_DLD_IMPL_H 270Sstevel@tonic-gate #define _SYS_DLD_IMPL_H 280Sstevel@tonic-gate 290Sstevel@tonic-gate #include <sys/types.h> 308275SEric Cheng #include <sys/list.h> 310Sstevel@tonic-gate #include <sys/ethernet.h> 320Sstevel@tonic-gate #include <sys/stream.h> 330Sstevel@tonic-gate #include <sys/dlpi.h> 340Sstevel@tonic-gate #include <sys/dld.h> 358275SEric Cheng #include <sys/dls_impl.h> 360Sstevel@tonic-gate 370Sstevel@tonic-gate #ifdef __cplusplus 380Sstevel@tonic-gate extern "C" { 390Sstevel@tonic-gate #endif 400Sstevel@tonic-gate 417408SSebastien.Roy@Sun.COM #define DLD_CONTROL_MINOR_NAME "ctl" 427408SSebastien.Roy@Sun.COM #define DLD_CONTROL_MINOR 0 437408SSebastien.Roy@Sun.COM 440Sstevel@tonic-gate #define DLD_CONTROL 0x00000001 450Sstevel@tonic-gate #define DLD_DLPI 0x00000002 460Sstevel@tonic-gate 470Sstevel@tonic-gate typedef enum { 480Sstevel@tonic-gate DLD_UNITDATA, 490Sstevel@tonic-gate DLD_FASTPATH, 500Sstevel@tonic-gate DLD_RAW 510Sstevel@tonic-gate } dld_str_mode_t; 520Sstevel@tonic-gate 530Sstevel@tonic-gate typedef enum { 540Sstevel@tonic-gate DLD_UNINITIALIZED, 550Sstevel@tonic-gate DLD_PASSIVE, 560Sstevel@tonic-gate DLD_ACTIVE 570Sstevel@tonic-gate } dld_passivestate_t; 580Sstevel@tonic-gate 598275SEric Cheng /* 608275SEric Cheng * The dld_str_t object definition and protection scheme for each member 618275SEric Cheng * is described below. The framework locking mechanism details are described in 628275SEric Cheng * mac_impl.h and mac.c 638275SEric Cheng * 648275SEric Cheng * Write Once Only (WO): Typically these are initialized when the end point 658275SEric Cheng * is created or initialized and don't change subsequently 668275SEric Cheng * 678275SEric Cheng * Serializer (SL): Protected by the Serializer. All modify operations on an 688275SEric Cheng * end point go through the serializer. Readers don't care about reading 698275SEric Cheng * these fields atomically, or readers also use the serializer to see the 708275SEric Cheng * values atomically. 718275SEric Cheng * 728275SEric Cheng * Lock: kmutex_t or kwrlock_t lock. Modify operations still go through the 738275SEric Cheng * serializer, the lock helps synchronize readers with writers. 748275SEric Cheng */ 750Sstevel@tonic-gate 768275SEric Cheng struct dld_str_s { /* Protected by */ 770Sstevel@tonic-gate /* 78269Sericheng * Major number of the device 79269Sericheng */ 808275SEric Cheng major_t ds_major; /* WO */ 81269Sericheng 82269Sericheng /* 830Sstevel@tonic-gate * Ephemeral minor number for the object. 840Sstevel@tonic-gate */ 858275SEric Cheng minor_t ds_minor; /* WO */ 868275SEric Cheng 878275SEric Cheng /* 888275SEric Cheng * PPA number this stream is attached to. 898275SEric Cheng */ 908275SEric Cheng t_uscalar_t ds_ppa; /* SL */ 910Sstevel@tonic-gate 920Sstevel@tonic-gate /* 930Sstevel@tonic-gate * Read/write queues for the stream which the object represents. 940Sstevel@tonic-gate */ 958275SEric Cheng queue_t *ds_rq; /* WO */ 968275SEric Cheng queue_t *ds_wq; /* WO */ 97269Sericheng 98269Sericheng /* 990Sstevel@tonic-gate * Stream is open to DLD_CONTROL (control node) or 1000Sstevel@tonic-gate * DLD_DLPI (DLS provider) node. 1010Sstevel@tonic-gate */ 1028275SEric Cheng uint_t ds_type; /* WO */ 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate /* 1050Sstevel@tonic-gate * The following fields are only used for DLD_DLPI type objects. 1060Sstevel@tonic-gate */ 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate /* 1090Sstevel@tonic-gate * Current DLPI state. 1100Sstevel@tonic-gate */ 1119002SCathy.Zhou@Sun.COM t_uscalar_t ds_dlstate; /* SL */ 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate /* 114269Sericheng * DLPI style 115269Sericheng */ 1168275SEric Cheng t_uscalar_t ds_style; /* WO */ 117269Sericheng 118269Sericheng /* 1190Sstevel@tonic-gate * Currently bound DLSAP. 1200Sstevel@tonic-gate */ 1218275SEric Cheng uint16_t ds_sap; /* SL */ 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate /* 1240Sstevel@tonic-gate * Handle of the MAC that is used by the data-link interface. 1250Sstevel@tonic-gate */ 1268275SEric Cheng mac_handle_t ds_mh; /* SL */ 1278275SEric Cheng mac_client_handle_t ds_mch; /* SL */ 1280Sstevel@tonic-gate 1290Sstevel@tonic-gate /* 1300Sstevel@tonic-gate * Promiscuity level information. 1310Sstevel@tonic-gate */ 1328275SEric Cheng uint32_t ds_promisc; /* SL */ 1338275SEric Cheng mac_promisc_handle_t ds_mph; 1348275SEric Cheng mac_promisc_handle_t ds_vlan_mph; 1350Sstevel@tonic-gate 1360Sstevel@tonic-gate /* 1370Sstevel@tonic-gate * Immutable information of the MAC which the channel is using. 1380Sstevel@tonic-gate */ 1398275SEric Cheng const mac_info_t *ds_mip; /* SL */ 1400Sstevel@tonic-gate 1410Sstevel@tonic-gate /* 1420Sstevel@tonic-gate * Current packet priority. 1430Sstevel@tonic-gate */ 1448275SEric Cheng uint_t ds_pri; /* SL */ 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate /* 1470Sstevel@tonic-gate * Handle of our MAC notification callback. 1480Sstevel@tonic-gate */ 1498275SEric Cheng mac_notify_handle_t ds_mnh; /* SL */ 1500Sstevel@tonic-gate 1510Sstevel@tonic-gate /* 1520Sstevel@tonic-gate * Set of enabled DL_NOTE... notifications. (See dlpi.h). 1530Sstevel@tonic-gate */ 1548275SEric Cheng uint32_t ds_notifications; /* SL */ 1550Sstevel@tonic-gate 1560Sstevel@tonic-gate /* 1570Sstevel@tonic-gate * Mode: unitdata, fast-path or raw. 1580Sstevel@tonic-gate */ 1598275SEric Cheng dld_str_mode_t ds_mode; /* SL */ 1600Sstevel@tonic-gate 1610Sstevel@tonic-gate /* 1623147Sxc151355 * Native mode state. 1633147Sxc151355 */ 1648275SEric Cheng boolean_t ds_native; /* SL */ 1653147Sxc151355 1663147Sxc151355 /* 1670Sstevel@tonic-gate * IP polling is operational if this flag is set. 1680Sstevel@tonic-gate */ 1698275SEric Cheng boolean_t ds_polling; /* SL */ 1708275SEric Cheng boolean_t ds_direct; /* SL */ 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate /* 1733115Syl150051 * LSO is enabled if ds_lso is set. 1743115Syl150051 */ 1758275SEric Cheng boolean_t ds_lso; /* SL */ 1768275SEric Cheng uint64_t ds_lso_max; /* SL */ 1773115Syl150051 1783115Syl150051 /* 1790Sstevel@tonic-gate * State of DLPI user: may be active (regular network layer), 1800Sstevel@tonic-gate * passive (snoop-like monitoring), or unknown (not yet 1810Sstevel@tonic-gate * determined). 1820Sstevel@tonic-gate */ 1838275SEric Cheng dld_passivestate_t ds_passivestate; /* SL */ 1840Sstevel@tonic-gate 1850Sstevel@tonic-gate /* 186269Sericheng * Dummy mblk used for flow-control. 187269Sericheng */ 1888275SEric Cheng mblk_t *ds_tx_flow_mp; /* ds_lock */ 1895895Syz147064 1905895Syz147064 /* 1918275SEric Cheng * List of queued DLPI requests. These will be processed 1928275SEric Cheng * by a taskq thread. This block is protected by ds_lock 1935895Syz147064 */ 1948275SEric Cheng kmutex_t ds_lock; 1958275SEric Cheng krwlock_t ds_rw_lock; 1968275SEric Cheng kcondvar_t ds_datathr_cv; /* ds_lock */ 1978275SEric Cheng uint_t ds_datathr_cnt; /* ds_lock */ 1988275SEric Cheng mblk_t *ds_pending_head; /* ds_lock */ 1998275SEric Cheng mblk_t *ds_pending_tail; /* ds_lock */ 2008275SEric Cheng kcondvar_t ds_dlpi_pending_cv; /* ds_lock */ 2018275SEric Cheng uint32_t 2028275SEric Cheng ds_dlpi_pending : 1, /* ds_lock */ 2038275SEric Cheng ds_local : 1, 2048275SEric Cheng ds_pad : 30; /* ds_lock */ 2055895Syz147064 2068275SEric Cheng dls_link_t *ds_dlp; /* SL */ 2078275SEric Cheng dls_multicst_addr_t *ds_dmap; /* ds_rw_lock */ 2088275SEric Cheng dls_rx_t ds_rx; /* ds_lock */ 2098275SEric Cheng void *ds_rx_arg; /* ds_lock */ 2109073SCathy.Zhou@Sun.COM uint_t ds_nactive; /* SL */ 2118275SEric Cheng dld_str_t *ds_next; /* SL */ 2128275SEric Cheng dls_head_t *ds_head; 2138275SEric Cheng dls_dl_handle_t ds_ddh; 2148275SEric Cheng list_node_t ds_tqlist; 2159073SCathy.Zhou@Sun.COM 2169073SCathy.Zhou@Sun.COM /* 2179073SCathy.Zhou@Sun.COM * driver private data set by the driver when calling dld_str_open(). 2189073SCathy.Zhou@Sun.COM */ 2199073SCathy.Zhou@Sun.COM void *ds_private; 220*10491SRishi.Srivatsavai@Sun.COM 221*10491SRishi.Srivatsavai@Sun.COM boolean_t ds_lowlink; /* SL */ 2227378SShuguo.Yang@Sun.COM }; 2230Sstevel@tonic-gate 2249073SCathy.Zhou@Sun.COM 2258275SEric Cheng #define DLD_DATATHR_INC(dsp) { \ 2268275SEric Cheng ASSERT(MUTEX_HELD(&(dsp)->ds_lock)); \ 2278275SEric Cheng dsp->ds_datathr_cnt++; \ 2285895Syz147064 } 2295895Syz147064 2308275SEric Cheng #define DLD_DATATHR_DCR(dsp) { \ 2318275SEric Cheng mutex_enter(&(dsp)->ds_lock); \ 2328275SEric Cheng (dsp)->ds_datathr_cnt--; \ 2338275SEric Cheng if ((dsp)->ds_datathr_cnt == 0) \ 2348275SEric Cheng cv_broadcast(&(dsp)->ds_datathr_cv); \ 2358275SEric Cheng mutex_exit(&(dsp)->ds_lock); \ 2365895Syz147064 } 2375895Syz147064 2380Sstevel@tonic-gate /* 2390Sstevel@tonic-gate * dld_str.c module. 2400Sstevel@tonic-gate */ 2410Sstevel@tonic-gate 2420Sstevel@tonic-gate extern void dld_str_init(void); 2430Sstevel@tonic-gate extern int dld_str_fini(void); 244269Sericheng extern dld_str_t *dld_str_create(queue_t *, uint_t, major_t, 245269Sericheng t_uscalar_t); 2460Sstevel@tonic-gate extern void dld_str_destroy(dld_str_t *); 247269Sericheng extern int dld_str_attach(dld_str_t *, t_uscalar_t); 2480Sstevel@tonic-gate extern void dld_str_detach(dld_str_t *); 2490Sstevel@tonic-gate extern void dld_str_rx_raw(void *, mac_resource_handle_t, 2502760Sdg199075 mblk_t *, mac_header_info_t *); 2510Sstevel@tonic-gate extern void dld_str_rx_fastpath(void *, mac_resource_handle_t, 2522760Sdg199075 mblk_t *, mac_header_info_t *); 2530Sstevel@tonic-gate extern void dld_str_rx_unitdata(void *, mac_resource_handle_t, 2542760Sdg199075 mblk_t *, mac_header_info_t *); 2550Sstevel@tonic-gate extern void dld_str_notify_ind(dld_str_t *); 2568275SEric Cheng extern mac_tx_cookie_t str_mdata_fastpath_put(dld_str_t *, mblk_t *, 2578275SEric Cheng uintptr_t, uint16_t); 2588275SEric Cheng extern int dld_flow_ctl_callb(dld_str_t *, uint64_t, 2598275SEric Cheng int (*func)(), void *); 260269Sericheng 2610Sstevel@tonic-gate /* 2620Sstevel@tonic-gate * dld_proto.c 2630Sstevel@tonic-gate */ 2648275SEric Cheng extern void dld_proto(dld_str_t *, mblk_t *); 2658275SEric Cheng extern void dld_proto_unitdata_req(dld_str_t *, mblk_t *); 2665113Syz147064 extern void dld_capabilities_disable(dld_str_t *); 2678275SEric Cheng extern void proto_unitdata_req(dld_str_t *, mblk_t *); 2688275SEric Cheng 2698275SEric Cheng /* 2708275SEric Cheng * dld_flow.c 2718275SEric Cheng */ 2728275SEric Cheng extern void flow_rx_pkt_chain(void *, void *, mblk_t *); 2738275SEric Cheng 2748275SEric Cheng /* 2758275SEric Cheng * dld_drv.c 2768275SEric Cheng */ 2778275SEric Cheng extern mac_handle_t dld_mac_open(char *dev_name, int *err); 2788275SEric Cheng #define dld_mac_close(mh) mac_close(mh) 2790Sstevel@tonic-gate 2800Sstevel@tonic-gate /* 2810Sstevel@tonic-gate * Options: there should be a separate bit defined here for each 2828275SEric Cheng * DLD_PROP... defined in dld.h. 2830Sstevel@tonic-gate */ 284269Sericheng #define DLD_OPT_NO_FASTPATH 0x00000001 285269Sericheng #define DLD_OPT_NO_POLL 0x00000002 286269Sericheng #define DLD_OPT_NO_ZEROCOPY 0x00000004 2874114Sja97890 #define DLD_OPT_NO_SOFTRING 0x00000008 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate extern uint32_t dld_opt; 2900Sstevel@tonic-gate 2910Sstevel@tonic-gate /* 2925895Syz147064 * autopush information 2935895Syz147064 */ 2945895Syz147064 typedef struct dld_ap { 2955895Syz147064 datalink_id_t da_linkid; 2965895Syz147064 struct dlautopush da_ap; 2975895Syz147064 2985895Syz147064 #define da_anchor da_ap.dap_anchor 2995895Syz147064 #define da_npush da_ap.dap_npush 3005895Syz147064 #define da_aplist da_ap.dap_aplist 3015895Syz147064 3025895Syz147064 } dld_ap_t; 3035895Syz147064 3045895Syz147064 /* 3050Sstevel@tonic-gate * Useful macros. 3060Sstevel@tonic-gate */ 3070Sstevel@tonic-gate 3080Sstevel@tonic-gate #define IMPLY(p, c) (!(p) || (c)) 3090Sstevel@tonic-gate 3108275SEric Cheng #define DLD_SETQFULL(dsp) { \ 3118275SEric Cheng queue_t *q = (dsp)->ds_wq; \ 3128275SEric Cheng \ 3138275SEric Cheng mutex_enter(&(dsp)->ds_lock); \ 3148275SEric Cheng if ((dsp)->ds_tx_flow_mp != NULL) { \ 3158275SEric Cheng (void) putq(q, (dsp)->ds_tx_flow_mp); \ 3168275SEric Cheng (dsp)->ds_tx_flow_mp = NULL; \ 3178275SEric Cheng qenable((dsp)->ds_wq); \ 3188275SEric Cheng } \ 3198275SEric Cheng mutex_exit(&(dsp)->ds_lock); \ 3208275SEric Cheng } 3218275SEric Cheng 3229002SCathy.Zhou@Sun.COM /* 3239002SCathy.Zhou@Sun.COM * This is called to check whether we can disable the flow control, and 3249002SCathy.Zhou@Sun.COM * it is usually only needed in TX data-path when the dsp->ds_dlstate is 3259002SCathy.Zhou@Sun.COM * DL_IDLE. Otherwise, it does not hurt to always disable the flow control. 3269002SCathy.Zhou@Sun.COM */ 3279002SCathy.Zhou@Sun.COM #define DLD_CLRQFULL(dsp) { \ 3289002SCathy.Zhou@Sun.COM queue_t *q = (dsp)->ds_wq; \ 3299002SCathy.Zhou@Sun.COM \ 3309002SCathy.Zhou@Sun.COM mutex_enter(&(dsp)->ds_lock); \ 3319002SCathy.Zhou@Sun.COM if ((dsp)->ds_dlstate != DL_IDLE || \ 3329002SCathy.Zhou@Sun.COM !mac_tx_is_flow_blocked((dsp)->ds_mch, NULL)) { \ 3339002SCathy.Zhou@Sun.COM if ((dsp)->ds_tx_flow_mp == NULL) \ 3349002SCathy.Zhou@Sun.COM (dsp)->ds_tx_flow_mp = getq(q); \ 3359002SCathy.Zhou@Sun.COM ASSERT((dsp)->ds_tx_flow_mp != NULL); \ 3369002SCathy.Zhou@Sun.COM } \ 3379002SCathy.Zhou@Sun.COM mutex_exit(&(dsp)->ds_lock); \ 3388275SEric Cheng } 3398275SEric Cheng 3408833SVenu.Iyer@Sun.COM #define DLD_TX(dsp, mp, f_hint, flag) \ 3418275SEric Cheng mac_tx(dsp->ds_mch, mp, f_hint, flag, NULL) 3428275SEric Cheng 343269Sericheng #ifdef DEBUG 344269Sericheng #define DLD_DBG cmn_err 345269Sericheng #else 346269Sericheng #define DLD_DBG if (0) cmn_err 347269Sericheng #endif 348269Sericheng 3490Sstevel@tonic-gate #ifdef __cplusplus 3500Sstevel@tonic-gate } 3510Sstevel@tonic-gate #endif 3520Sstevel@tonic-gate 3530Sstevel@tonic-gate #endif /* _SYS_DLD_IMPL_H */ 354