xref: /illumos-gate/usr/src/uts/common/sys/dld_impl.h (revision 8648b7db)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5c0192a57Sericheng  * Common Development and Distribution License (the "License").
6c0192a57Sericheng  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
2256f33205SJonathan Adams  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #ifndef	_SYS_DLD_IMPL_H
277c478bd9Sstevel@tonic-gate #define	_SYS_DLD_IMPL_H
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <sys/types.h>
30da14cebeSEric Cheng #include <sys/list.h>
317c478bd9Sstevel@tonic-gate #include <sys/ethernet.h>
327c478bd9Sstevel@tonic-gate #include <sys/stream.h>
337c478bd9Sstevel@tonic-gate #include <sys/dlpi.h>
347c478bd9Sstevel@tonic-gate #include <sys/dld.h>
35da14cebeSEric Cheng #include <sys/dls_impl.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
387c478bd9Sstevel@tonic-gate extern "C" {
397c478bd9Sstevel@tonic-gate #endif
407c478bd9Sstevel@tonic-gate 
41eae72b5bSSebastien Roy #define	DLD_CONTROL_MINOR_NAME	"ctl"
42eae72b5bSSebastien Roy #define	DLD_CONTROL_MINOR	0
43eae72b5bSSebastien Roy 
447c478bd9Sstevel@tonic-gate #define	DLD_CONTROL	0x00000001
457c478bd9Sstevel@tonic-gate #define	DLD_DLPI	0x00000002
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate typedef enum {
487c478bd9Sstevel@tonic-gate 	DLD_UNITDATA,
497c478bd9Sstevel@tonic-gate 	DLD_FASTPATH,
507c478bd9Sstevel@tonic-gate 	DLD_RAW
517c478bd9Sstevel@tonic-gate } dld_str_mode_t;
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate typedef enum {
547c478bd9Sstevel@tonic-gate 	DLD_UNINITIALIZED,
557c478bd9Sstevel@tonic-gate 	DLD_PASSIVE,
567c478bd9Sstevel@tonic-gate 	DLD_ACTIVE
577c478bd9Sstevel@tonic-gate } dld_passivestate_t;
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate /*
60da14cebeSEric Cheng  * The dld_str_t object definition and protection scheme for each member
61da14cebeSEric Cheng  * is described below. The framework locking mechanism details are described in
62da14cebeSEric Cheng  * mac_impl.h and mac.c
63da14cebeSEric Cheng  *
64da14cebeSEric Cheng  * Write Once Only (WO): Typically these are initialized when the end point
65da14cebeSEric Cheng  * is created or initialized and don't change subsequently
66da14cebeSEric Cheng  *
67da14cebeSEric Cheng  * Serializer (SL): Protected by the Serializer. All modify operations on an
68da14cebeSEric Cheng  * end point go through the serializer. Readers don't care about reading
69da14cebeSEric Cheng  * these fields atomically, or readers also use the serializer to see the
70da14cebeSEric Cheng  * values atomically.
71da14cebeSEric Cheng  *
72da14cebeSEric Cheng  * Lock: kmutex_t or kwrlock_t lock. Modify operations still go through the
73da14cebeSEric Cheng  * serializer, the lock helps synchronize readers with writers.
747c478bd9Sstevel@tonic-gate  */
75da14cebeSEric Cheng 
76da14cebeSEric Cheng struct dld_str_s {					/* Protected by */
777c478bd9Sstevel@tonic-gate 	/*
78210db224Sericheng 	 * Major number of the device
79210db224Sericheng 	 */
80da14cebeSEric Cheng 	major_t			ds_major;		/* WO */
81210db224Sericheng 
82210db224Sericheng 	/*
837c478bd9Sstevel@tonic-gate 	 * Ephemeral minor number for the object.
847c478bd9Sstevel@tonic-gate 	 */
85da14cebeSEric Cheng 	minor_t			ds_minor;		/* WO */
86da14cebeSEric Cheng 
87da14cebeSEric Cheng 	/*
88da14cebeSEric Cheng 	 * PPA number this stream is attached to.
89da14cebeSEric Cheng 	 */
90da14cebeSEric Cheng 	t_uscalar_t		ds_ppa;			/* SL */
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	/*
937c478bd9Sstevel@tonic-gate 	 * Read/write queues for the stream which the object represents.
947c478bd9Sstevel@tonic-gate 	 */
95da14cebeSEric Cheng 	queue_t			*ds_rq;			/* WO */
96da14cebeSEric Cheng 	queue_t			*ds_wq;			/* WO */
97210db224Sericheng 
98210db224Sericheng 	/*
997c478bd9Sstevel@tonic-gate 	 * Stream is open to DLD_CONTROL (control node) or
1007c478bd9Sstevel@tonic-gate 	 * DLD_DLPI (DLS provider) node.
1017c478bd9Sstevel@tonic-gate 	 */
102da14cebeSEric Cheng 	uint_t			ds_type;		/* WO */
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate 	/*
1057c478bd9Sstevel@tonic-gate 	 * The following fields are only used for DLD_DLPI type objects.
1067c478bd9Sstevel@tonic-gate 	 */
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate 	/*
1097c478bd9Sstevel@tonic-gate 	 * Current DLPI state.
1107c478bd9Sstevel@tonic-gate 	 */
11110972ddeSCathy Zhou 	t_uscalar_t		ds_dlstate;		/* SL */
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate 	/*
114210db224Sericheng 	 * DLPI style
115210db224Sericheng 	 */
116da14cebeSEric Cheng 	t_uscalar_t		ds_style;		/* WO */
117210db224Sericheng 
118210db224Sericheng 	/*
1197c478bd9Sstevel@tonic-gate 	 * Currently bound DLSAP.
1207c478bd9Sstevel@tonic-gate 	 */
121da14cebeSEric Cheng 	uint16_t		ds_sap;			/* SL */
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 	/*
1247c478bd9Sstevel@tonic-gate 	 * Handle of the MAC that is used by the data-link interface.
1257c478bd9Sstevel@tonic-gate 	 */
126da14cebeSEric Cheng 	mac_handle_t		ds_mh;			/* SL */
127da14cebeSEric Cheng 	mac_client_handle_t	ds_mch;			/* SL */
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 	/*
1307c478bd9Sstevel@tonic-gate 	 * Promiscuity level information.
1317c478bd9Sstevel@tonic-gate 	 */
132da14cebeSEric Cheng 	uint32_t		ds_promisc;		/* SL */
133da14cebeSEric Cheng 	mac_promisc_handle_t	ds_mph;
134da14cebeSEric Cheng 	mac_promisc_handle_t	ds_vlan_mph;
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	/*
1377c478bd9Sstevel@tonic-gate 	 * Immutable information of the MAC which the channel is using.
1387c478bd9Sstevel@tonic-gate 	 */
139da14cebeSEric Cheng 	const mac_info_t	*ds_mip;		/* SL */
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate 	/*
1427c478bd9Sstevel@tonic-gate 	 * Current packet priority.
1437c478bd9Sstevel@tonic-gate 	 */
144da14cebeSEric Cheng 	uint_t			ds_pri;			/* SL */
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate 	/*
1477c478bd9Sstevel@tonic-gate 	 * Handle of our MAC notification callback.
1487c478bd9Sstevel@tonic-gate 	 */
149da14cebeSEric Cheng 	mac_notify_handle_t	ds_mnh;			/* SL */
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate 	/*
1527c478bd9Sstevel@tonic-gate 	 * Set of enabled DL_NOTE... notifications. (See dlpi.h).
1537c478bd9Sstevel@tonic-gate 	 */
154da14cebeSEric Cheng 	uint32_t		ds_notifications;	/* SL */
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 	/*
1577c478bd9Sstevel@tonic-gate 	 * Mode: unitdata, fast-path or raw.
1587c478bd9Sstevel@tonic-gate 	 */
159da14cebeSEric Cheng 	dld_str_mode_t		ds_mode;		/* SL */
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate 	/*
1620ba2cbe9Sxc151355 	 * Native mode state.
1630ba2cbe9Sxc151355 	 */
164da14cebeSEric Cheng 	boolean_t		ds_native;		/* SL */
1650ba2cbe9Sxc151355 
1660ba2cbe9Sxc151355 	/*
1677c478bd9Sstevel@tonic-gate 	 * IP polling is operational if this flag is set.
1687c478bd9Sstevel@tonic-gate 	 */
169da14cebeSEric Cheng 	boolean_t		ds_polling;		/* SL */
170da14cebeSEric Cheng 	boolean_t		ds_direct;		/* SL */
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 	/*
1738347601bSyl150051 	 * LSO is enabled if ds_lso is set.
1748347601bSyl150051 	 */
175da14cebeSEric Cheng 	boolean_t		ds_lso;			/* SL */
176da14cebeSEric Cheng 	uint64_t		ds_lso_max;		/* SL */
1778347601bSyl150051 
1788347601bSyl150051 	/*
1797c478bd9Sstevel@tonic-gate 	 * State of DLPI user: may be active (regular network layer),
1807c478bd9Sstevel@tonic-gate 	 * passive (snoop-like monitoring), or unknown (not yet
1817c478bd9Sstevel@tonic-gate 	 * determined).
1827c478bd9Sstevel@tonic-gate 	 */
183da14cebeSEric Cheng 	dld_passivestate_t	ds_passivestate;	/* SL */
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate 	/*
186210db224Sericheng 	 * Dummy mblk used for flow-control.
1877c478bd9Sstevel@tonic-gate 	 */
188da14cebeSEric Cheng 	mblk_t			*ds_tx_flow_mp;		/* ds_lock */
189210db224Sericheng 
190210db224Sericheng 	/*
191da14cebeSEric Cheng 	 * List of queued DLPI requests. These will be processed
192da14cebeSEric Cheng 	 * by a taskq thread. This block is protected by ds_lock
193210db224Sericheng 	 */
194da14cebeSEric Cheng 	kmutex_t		ds_lock;
195da14cebeSEric Cheng 	krwlock_t		ds_rw_lock;
196da14cebeSEric Cheng 	kcondvar_t		ds_datathr_cv;		/* ds_lock */
197da14cebeSEric Cheng 	uint_t			ds_datathr_cnt;		/* ds_lock */
198da14cebeSEric Cheng 	mblk_t			*ds_pending_head;	/* ds_lock */
199da14cebeSEric Cheng 	mblk_t			*ds_pending_tail;	/* ds_lock */
200da14cebeSEric Cheng 	kcondvar_t		ds_dlpi_pending_cv;	/* ds_lock */
201da14cebeSEric Cheng 	uint32_t
202da14cebeSEric Cheng 				ds_dlpi_pending : 1,	/* ds_lock */
203da14cebeSEric Cheng 				ds_local	: 1,
204da14cebeSEric Cheng 				ds_pad		: 30;	/* ds_lock */
205210db224Sericheng 
206da14cebeSEric Cheng 	dls_link_t		*ds_dlp;		/* SL */
207da14cebeSEric Cheng 	dls_multicst_addr_t	*ds_dmap;		/* ds_rw_lock */
208da14cebeSEric Cheng 	dls_rx_t		ds_rx;			/* ds_lock */
209da14cebeSEric Cheng 	void			*ds_rx_arg;		/* ds_lock */
2105d460eafSCathy Zhou 	uint_t			ds_nactive;		/* SL */
211da14cebeSEric Cheng 	dld_str_t		*ds_next;		/* SL */
212da14cebeSEric Cheng 	dls_head_t		*ds_head;
213da14cebeSEric Cheng 	dls_dl_handle_t		ds_ddh;
214da14cebeSEric Cheng 	list_node_t		ds_tqlist;
2155d460eafSCathy Zhou 
2165d460eafSCathy Zhou 	/*
2175d460eafSCathy Zhou 	 * driver private data set by the driver when calling dld_str_open().
2185d460eafSCathy Zhou 	 */
2195d460eafSCathy Zhou 	void			*ds_private;
2204eaa4710SRishi Srivatsavai 
2214eaa4710SRishi Srivatsavai 	boolean_t		ds_lowlink;		/* SL */
2228d4cf8d8S 	boolean_t		ds_nonip;		/* SL */
22348b73645SShu-Guo Yang };
2247c478bd9Sstevel@tonic-gate 
2255d460eafSCathy Zhou 
226da14cebeSEric Cheng #define	DLD_DATATHR_INC(dsp)	{		\
227da14cebeSEric Cheng 	ASSERT(MUTEX_HELD(&(dsp)->ds_lock));	\
228da14cebeSEric Cheng 	dsp->ds_datathr_cnt++;			\
229d62bc4baSyz147064 }
230d62bc4baSyz147064 
231da14cebeSEric Cheng #define	DLD_DATATHR_DCR(dsp)	{		\
232da14cebeSEric Cheng 	mutex_enter(&(dsp)->ds_lock);		\
233da14cebeSEric Cheng 	(dsp)->ds_datathr_cnt--;		\
234da14cebeSEric Cheng 	if ((dsp)->ds_datathr_cnt == 0)		\
235da14cebeSEric Cheng 		cv_broadcast(&(dsp)->ds_datathr_cv);	\
236da14cebeSEric Cheng 	mutex_exit(&(dsp)->ds_lock);		\
237d62bc4baSyz147064 }
238d62bc4baSyz147064 
2397c478bd9Sstevel@tonic-gate /*
2407c478bd9Sstevel@tonic-gate  * dld_str.c module.
2417c478bd9Sstevel@tonic-gate  */
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate extern void		dld_str_init(void);
2447c478bd9Sstevel@tonic-gate extern int		dld_str_fini(void);
245210db224Sericheng extern dld_str_t	*dld_str_create(queue_t *, uint_t, major_t,
246210db224Sericheng     t_uscalar_t);
2477c478bd9Sstevel@tonic-gate extern void		dld_str_destroy(dld_str_t *);
248210db224Sericheng extern int		dld_str_attach(dld_str_t *, t_uscalar_t);
2497c478bd9Sstevel@tonic-gate extern void		dld_str_detach(dld_str_t *);
2507c478bd9Sstevel@tonic-gate extern void		dld_str_rx_raw(void *, mac_resource_handle_t,
251605445d5Sdg199075     mblk_t *, mac_header_info_t *);
2527c478bd9Sstevel@tonic-gate extern void		dld_str_rx_fastpath(void *, mac_resource_handle_t,
253605445d5Sdg199075     mblk_t *, mac_header_info_t *);
2547c478bd9Sstevel@tonic-gate extern void		dld_str_rx_unitdata(void *, mac_resource_handle_t,
255605445d5Sdg199075     mblk_t *, mac_header_info_t *);
2567c478bd9Sstevel@tonic-gate extern void		dld_str_notify_ind(dld_str_t *);
257da14cebeSEric Cheng extern mac_tx_cookie_t	str_mdata_fastpath_put(dld_str_t *, mblk_t *,
258da14cebeSEric Cheng     uintptr_t, uint16_t);
259da14cebeSEric Cheng extern int		dld_flow_ctl_callb(dld_str_t *, uint64_t,
260da14cebeSEric Cheng     int (*func)(), void *);
261210db224Sericheng 
2627c478bd9Sstevel@tonic-gate /*
2637c478bd9Sstevel@tonic-gate  * dld_proto.c
2647c478bd9Sstevel@tonic-gate  */
265da14cebeSEric Cheng extern void		dld_proto(dld_str_t *, mblk_t *);
266da14cebeSEric Cheng extern void		dld_proto_unitdata_req(dld_str_t *, mblk_t *);
2678fb46f24Syz147064 extern void		dld_capabilities_disable(dld_str_t *);
268da14cebeSEric Cheng extern void		proto_unitdata_req(dld_str_t *, mblk_t *);
269da14cebeSEric Cheng 
270da14cebeSEric Cheng /*
271da14cebeSEric Cheng  * dld_flow.c
272da14cebeSEric Cheng  */
273da14cebeSEric Cheng extern void		flow_rx_pkt_chain(void *, void *, mblk_t *);
274da14cebeSEric Cheng 
275da14cebeSEric Cheng /*
276da14cebeSEric Cheng  * dld_drv.c
277da14cebeSEric Cheng  */
278da14cebeSEric Cheng extern mac_handle_t	dld_mac_open(char *dev_name, int *err);
279da14cebeSEric Cheng #define	dld_mac_close(mh) mac_close(mh)
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate /*
2827c478bd9Sstevel@tonic-gate  * Options: there should be a separate bit defined here for each
2837c478bd9Sstevel@tonic-gate  *          DLD_PROP... defined in dld.h.
2847c478bd9Sstevel@tonic-gate  */
285210db224Sericheng #define	DLD_OPT_NO_FASTPATH	0x00000001
286210db224Sericheng #define	DLD_OPT_NO_POLL		0x00000002
287210db224Sericheng #define	DLD_OPT_NO_ZEROCOPY	0x00000004
2889c175129Sja97890 #define	DLD_OPT_NO_SOFTRING	0x00000008
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate extern uint32_t		dld_opt;
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate /*
293d62bc4baSyz147064  * autopush information
294d62bc4baSyz147064  */
295d62bc4baSyz147064 typedef struct dld_ap {
296d62bc4baSyz147064 	datalink_id_t		da_linkid;
297d62bc4baSyz147064 	struct dlautopush	da_ap;
298d62bc4baSyz147064 
299d62bc4baSyz147064 #define	da_anchor		da_ap.dap_anchor
300d62bc4baSyz147064 #define	da_npush		da_ap.dap_npush
301d62bc4baSyz147064 #define	da_aplist		da_ap.dap_aplist
302d62bc4baSyz147064 
303d62bc4baSyz147064 } dld_ap_t;
304d62bc4baSyz147064 
305d62bc4baSyz147064 /*
3067c478bd9Sstevel@tonic-gate  * Useful macros.
3077c478bd9Sstevel@tonic-gate  */
3087c478bd9Sstevel@tonic-gate 
309da14cebeSEric Cheng #define	DLD_SETQFULL(dsp) {						\
310da14cebeSEric Cheng 	queue_t *q = (dsp)->ds_wq;					\
311da14cebeSEric Cheng 									\
312da14cebeSEric Cheng 	mutex_enter(&(dsp)->ds_lock);					\
313da14cebeSEric Cheng 	if ((dsp)->ds_tx_flow_mp != NULL) {				\
314da14cebeSEric Cheng 		(void) putq(q, (dsp)->ds_tx_flow_mp);			\
315da14cebeSEric Cheng 		(dsp)->ds_tx_flow_mp = NULL;				\
316da14cebeSEric Cheng 		qenable((dsp)->ds_wq);					\
317da14cebeSEric Cheng 	}								\
318da14cebeSEric Cheng 	mutex_exit(&(dsp)->ds_lock);					\
319da14cebeSEric Cheng }
320da14cebeSEric Cheng 
32110972ddeSCathy Zhou /*
32210972ddeSCathy Zhou  * This is called to check whether we can disable the flow control, and
32310972ddeSCathy Zhou  * it is usually only needed in TX data-path when the dsp->ds_dlstate is
32410972ddeSCathy Zhou  * DL_IDLE. Otherwise, it does not hurt to always disable the flow control.
32510972ddeSCathy Zhou  */
326da14cebeSEric Cheng #define	DLD_CLRQFULL(dsp) {					\
327da14cebeSEric Cheng 	queue_t *q = (dsp)->ds_wq;				\
328da14cebeSEric Cheng 								\
329da14cebeSEric Cheng 	mutex_enter(&(dsp)->ds_lock);				\
33010972ddeSCathy Zhou 	if ((dsp)->ds_dlstate != DL_IDLE ||			\
331*8648b7dbSToomas Soome 	    !mac_tx_is_flow_blocked((dsp)->ds_mch, 0)) {	\
332da14cebeSEric Cheng 		if ((dsp)->ds_tx_flow_mp == NULL)		\
333da14cebeSEric Cheng 			(dsp)->ds_tx_flow_mp = getq(q);		\
334da14cebeSEric Cheng 		ASSERT((dsp)->ds_tx_flow_mp != NULL);		\
335da14cebeSEric Cheng 	}							\
336da14cebeSEric Cheng 	mutex_exit(&(dsp)->ds_lock);				\
337da14cebeSEric Cheng }
338da14cebeSEric Cheng 
339da14cebeSEric Cheng #define	DLD_TX(dsp, mp, f_hint, flag)				\
340da14cebeSEric Cheng 	mac_tx(dsp->ds_mch, mp, f_hint, flag, NULL)
341da14cebeSEric Cheng 
342210db224Sericheng #ifdef DEBUG
343210db224Sericheng #define	DLD_DBG		cmn_err
344210db224Sericheng #else
345210db224Sericheng #define	DLD_DBG		if (0) cmn_err
346210db224Sericheng #endif
347210db224Sericheng 
3487c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
3497c478bd9Sstevel@tonic-gate }
3507c478bd9Sstevel@tonic-gate #endif
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate #endif	/* _SYS_DLD_IMPL_H */
353