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 /* 22*11474SJonathan.Adams@Sun.COM * Copyright 2010 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; 22010491SRishi.Srivatsavai@Sun.COM 22110491SRishi.Srivatsavai@Sun.COM boolean_t ds_lowlink; /* SL */ 22211021SEric.Cheng@Sun.COM boolean_t ds_nonip; /* SL */ 2237378SShuguo.Yang@Sun.COM }; 2240Sstevel@tonic-gate 2259073SCathy.Zhou@Sun.COM 2268275SEric Cheng #define DLD_DATATHR_INC(dsp) { \ 2278275SEric Cheng ASSERT(MUTEX_HELD(&(dsp)->ds_lock)); \ 2288275SEric Cheng dsp->ds_datathr_cnt++; \ 2295895Syz147064 } 2305895Syz147064 2318275SEric Cheng #define DLD_DATATHR_DCR(dsp) { \ 2328275SEric Cheng mutex_enter(&(dsp)->ds_lock); \ 2338275SEric Cheng (dsp)->ds_datathr_cnt--; \ 2348275SEric Cheng if ((dsp)->ds_datathr_cnt == 0) \ 2358275SEric Cheng cv_broadcast(&(dsp)->ds_datathr_cv); \ 2368275SEric Cheng mutex_exit(&(dsp)->ds_lock); \ 2375895Syz147064 } 2385895Syz147064 2390Sstevel@tonic-gate /* 2400Sstevel@tonic-gate * dld_str.c module. 2410Sstevel@tonic-gate */ 2420Sstevel@tonic-gate 2430Sstevel@tonic-gate extern void dld_str_init(void); 2440Sstevel@tonic-gate extern int dld_str_fini(void); 245269Sericheng extern dld_str_t *dld_str_create(queue_t *, uint_t, major_t, 246269Sericheng t_uscalar_t); 2470Sstevel@tonic-gate extern void dld_str_destroy(dld_str_t *); 248269Sericheng extern int dld_str_attach(dld_str_t *, t_uscalar_t); 2490Sstevel@tonic-gate extern void dld_str_detach(dld_str_t *); 2500Sstevel@tonic-gate extern void dld_str_rx_raw(void *, mac_resource_handle_t, 2512760Sdg199075 mblk_t *, mac_header_info_t *); 2520Sstevel@tonic-gate extern void dld_str_rx_fastpath(void *, mac_resource_handle_t, 2532760Sdg199075 mblk_t *, mac_header_info_t *); 2540Sstevel@tonic-gate extern void dld_str_rx_unitdata(void *, mac_resource_handle_t, 2552760Sdg199075 mblk_t *, mac_header_info_t *); 2560Sstevel@tonic-gate extern void dld_str_notify_ind(dld_str_t *); 2578275SEric Cheng extern mac_tx_cookie_t str_mdata_fastpath_put(dld_str_t *, mblk_t *, 2588275SEric Cheng uintptr_t, uint16_t); 2598275SEric Cheng extern int dld_flow_ctl_callb(dld_str_t *, uint64_t, 2608275SEric Cheng int (*func)(), void *); 261269Sericheng 2620Sstevel@tonic-gate /* 2630Sstevel@tonic-gate * dld_proto.c 2640Sstevel@tonic-gate */ 2658275SEric Cheng extern void dld_proto(dld_str_t *, mblk_t *); 2668275SEric Cheng extern void dld_proto_unitdata_req(dld_str_t *, mblk_t *); 2675113Syz147064 extern void dld_capabilities_disable(dld_str_t *); 2688275SEric Cheng extern void proto_unitdata_req(dld_str_t *, mblk_t *); 2698275SEric Cheng 2708275SEric Cheng /* 2718275SEric Cheng * dld_flow.c 2728275SEric Cheng */ 2738275SEric Cheng extern void flow_rx_pkt_chain(void *, void *, mblk_t *); 2748275SEric Cheng 2758275SEric Cheng /* 2768275SEric Cheng * dld_drv.c 2778275SEric Cheng */ 2788275SEric Cheng extern mac_handle_t dld_mac_open(char *dev_name, int *err); 2798275SEric Cheng #define dld_mac_close(mh) mac_close(mh) 2800Sstevel@tonic-gate 2810Sstevel@tonic-gate /* 2820Sstevel@tonic-gate * Options: there should be a separate bit defined here for each 2838275SEric Cheng * DLD_PROP... defined in dld.h. 2840Sstevel@tonic-gate */ 285269Sericheng #define DLD_OPT_NO_FASTPATH 0x00000001 286269Sericheng #define DLD_OPT_NO_POLL 0x00000002 287269Sericheng #define DLD_OPT_NO_ZEROCOPY 0x00000004 2884114Sja97890 #define DLD_OPT_NO_SOFTRING 0x00000008 2890Sstevel@tonic-gate 2900Sstevel@tonic-gate extern uint32_t dld_opt; 2910Sstevel@tonic-gate 2920Sstevel@tonic-gate /* 2935895Syz147064 * autopush information 2945895Syz147064 */ 2955895Syz147064 typedef struct dld_ap { 2965895Syz147064 datalink_id_t da_linkid; 2975895Syz147064 struct dlautopush da_ap; 2985895Syz147064 2995895Syz147064 #define da_anchor da_ap.dap_anchor 3005895Syz147064 #define da_npush da_ap.dap_npush 3015895Syz147064 #define da_aplist da_ap.dap_aplist 3025895Syz147064 3035895Syz147064 } dld_ap_t; 3045895Syz147064 3055895Syz147064 /* 3060Sstevel@tonic-gate * Useful macros. 3070Sstevel@tonic-gate */ 3080Sstevel@tonic-gate 3098275SEric Cheng #define DLD_SETQFULL(dsp) { \ 3108275SEric Cheng queue_t *q = (dsp)->ds_wq; \ 3118275SEric Cheng \ 3128275SEric Cheng mutex_enter(&(dsp)->ds_lock); \ 3138275SEric Cheng if ((dsp)->ds_tx_flow_mp != NULL) { \ 3148275SEric Cheng (void) putq(q, (dsp)->ds_tx_flow_mp); \ 3158275SEric Cheng (dsp)->ds_tx_flow_mp = NULL; \ 3168275SEric Cheng qenable((dsp)->ds_wq); \ 3178275SEric Cheng } \ 3188275SEric Cheng mutex_exit(&(dsp)->ds_lock); \ 3198275SEric Cheng } 3208275SEric Cheng 3219002SCathy.Zhou@Sun.COM /* 3229002SCathy.Zhou@Sun.COM * This is called to check whether we can disable the flow control, and 3239002SCathy.Zhou@Sun.COM * it is usually only needed in TX data-path when the dsp->ds_dlstate is 3249002SCathy.Zhou@Sun.COM * DL_IDLE. Otherwise, it does not hurt to always disable the flow control. 3259002SCathy.Zhou@Sun.COM */ 3269002SCathy.Zhou@Sun.COM #define DLD_CLRQFULL(dsp) { \ 3279002SCathy.Zhou@Sun.COM queue_t *q = (dsp)->ds_wq; \ 3289002SCathy.Zhou@Sun.COM \ 3299002SCathy.Zhou@Sun.COM mutex_enter(&(dsp)->ds_lock); \ 3309002SCathy.Zhou@Sun.COM if ((dsp)->ds_dlstate != DL_IDLE || \ 3319002SCathy.Zhou@Sun.COM !mac_tx_is_flow_blocked((dsp)->ds_mch, NULL)) { \ 3329002SCathy.Zhou@Sun.COM if ((dsp)->ds_tx_flow_mp == NULL) \ 3339002SCathy.Zhou@Sun.COM (dsp)->ds_tx_flow_mp = getq(q); \ 3349002SCathy.Zhou@Sun.COM ASSERT((dsp)->ds_tx_flow_mp != NULL); \ 3359002SCathy.Zhou@Sun.COM } \ 3369002SCathy.Zhou@Sun.COM mutex_exit(&(dsp)->ds_lock); \ 3378275SEric Cheng } 3388275SEric Cheng 3398833SVenu.Iyer@Sun.COM #define DLD_TX(dsp, mp, f_hint, flag) \ 3408275SEric Cheng mac_tx(dsp->ds_mch, mp, f_hint, flag, NULL) 3418275SEric Cheng 342269Sericheng #ifdef DEBUG 343269Sericheng #define DLD_DBG cmn_err 344269Sericheng #else 345269Sericheng #define DLD_DBG if (0) cmn_err 346269Sericheng #endif 347269Sericheng 3480Sstevel@tonic-gate #ifdef __cplusplus 3490Sstevel@tonic-gate } 3500Sstevel@tonic-gate #endif 3510Sstevel@tonic-gate 3520Sstevel@tonic-gate #endif /* _SYS_DLD_IMPL_H */ 353