Home | History | Annotate | Download | only in sys
      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 	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	IMPLY(p, c)	(!(p) || (c))
    310 
    311 #define	DLD_SETQFULL(dsp) {						\
    312 	queue_t *q = (dsp)->ds_wq;					\
    313 									\
    314 	mutex_enter(&(dsp)->ds_lock);					\
    315 	if ((dsp)->ds_tx_flow_mp != NULL) {				\
    316 		(void) putq(q, (dsp)->ds_tx_flow_mp);			\
    317 		(dsp)->ds_tx_flow_mp = NULL;				\
    318 		qenable((dsp)->ds_wq);					\
    319 	}								\
    320 	mutex_exit(&(dsp)->ds_lock);					\
    321 }
    322 
    323 /*
    324  * This is called to check whether we can disable the flow control, and
    325  * it is usually only needed in TX data-path when the dsp->ds_dlstate is
    326  * DL_IDLE. Otherwise, it does not hurt to always disable the flow control.
    327  */
    328 #define	DLD_CLRQFULL(dsp) {					\
    329 	queue_t *q = (dsp)->ds_wq;				\
    330 								\
    331 	mutex_enter(&(dsp)->ds_lock);				\
    332 	if ((dsp)->ds_dlstate != DL_IDLE ||			\
    333 	    !mac_tx_is_flow_blocked((dsp)->ds_mch, NULL)) {	\
    334 		if ((dsp)->ds_tx_flow_mp == NULL)		\
    335 			(dsp)->ds_tx_flow_mp = getq(q);		\
    336 		ASSERT((dsp)->ds_tx_flow_mp != NULL);		\
    337 	}							\
    338 	mutex_exit(&(dsp)->ds_lock);				\
    339 }
    340 
    341 #define	DLD_TX(dsp, mp, f_hint, flag)				\
    342 	mac_tx(dsp->ds_mch, mp, f_hint, flag, NULL)
    343 
    344 #ifdef DEBUG
    345 #define	DLD_DBG		cmn_err
    346 #else
    347 #define	DLD_DBG		if (0) cmn_err
    348 #endif
    349 
    350 #ifdef	__cplusplus
    351 }
    352 #endif
    353 
    354 #endif	/* _SYS_DLD_IMPL_H */
    355