#ifndef _SYS_DLD_IMPL_H
#define _SYS_DLD_IMPL_H
#include <sys/types.h>
#include <sys/list.h>
#include <sys/ethernet.h>
#include <sys/stream.h>
#include <sys/dlpi.h>
#include <sys/dld.h>
#include <sys/dls_impl.h>
#ifdef __cplusplus
extern "C" {
#endif
#define DLD_CONTROL_MINOR_NAME "ctl"
#define DLD_CONTROL_MINOR 0
#define DLD_CONTROL 0x00000001
#define DLD_DLPI 0x00000002
typedef enum {
DLD_UNITDATA,
DLD_FASTPATH,
DLD_RAW
} dld_str_mode_t;
typedef enum {
DLD_UNINITIALIZED,
DLD_PASSIVE,
DLD_ACTIVE
} dld_passivestate_t;
struct dld_str_s {
major_t ds_major;
minor_t ds_minor;
t_uscalar_t ds_ppa;
queue_t *ds_rq;
queue_t *ds_wq;
uint_t ds_type;
t_uscalar_t ds_dlstate;
t_uscalar_t ds_style;
uint16_t ds_sap;
mac_handle_t ds_mh;
mac_client_handle_t ds_mch;
uint32_t ds_promisc;
mac_promisc_handle_t ds_mph;
mac_promisc_handle_t ds_vlan_mph;
const mac_info_t *ds_mip;
uint_t ds_pri;
mac_notify_handle_t ds_mnh;
uint32_t ds_notifications;
dld_str_mode_t ds_mode;
boolean_t ds_native;
boolean_t ds_polling;
boolean_t ds_direct;
boolean_t ds_lso;
uint64_t ds_lso_max;
dld_passivestate_t ds_passivestate;
mblk_t *ds_tx_flow_mp;
kmutex_t ds_lock;
krwlock_t ds_rw_lock;
kcondvar_t ds_datathr_cv;
uint_t ds_datathr_cnt;
mblk_t *ds_pending_head;
mblk_t *ds_pending_tail;
kcondvar_t ds_dlpi_pending_cv;
uint32_t
ds_dlpi_pending : 1,
ds_local : 1,
ds_pad : 30;
dls_link_t *ds_dlp;
dls_multicst_addr_t *ds_dmap;
dls_rx_t ds_rx;
void *ds_rx_arg;
uint_t ds_nactive;
dld_str_t *ds_next;
dls_head_t *ds_head;
dls_dl_handle_t ds_ddh;
list_node_t ds_tqlist;
void *ds_private;
boolean_t ds_lowlink;
boolean_t ds_nonip;
};
#define DLD_DATATHR_INC(dsp) { \
ASSERT(MUTEX_HELD(&(dsp)->ds_lock)); \
dsp->ds_datathr_cnt++; \
}
#define DLD_DATATHR_DCR(dsp) { \
mutex_enter(&(dsp)->ds_lock); \
(dsp)->ds_datathr_cnt--; \
if ((dsp)->ds_datathr_cnt == 0) \
cv_broadcast(&(dsp)->ds_datathr_cv); \
mutex_exit(&(dsp)->ds_lock); \
}
extern void dld_str_init(void);
extern int dld_str_fini(void);
extern dld_str_t *dld_str_create(queue_t *, uint_t, major_t,
t_uscalar_t);
extern void dld_str_destroy(dld_str_t *);
extern int dld_str_attach(dld_str_t *, t_uscalar_t);
extern void dld_str_detach(dld_str_t *);
extern void dld_str_rx_raw(void *, mac_resource_handle_t,
mblk_t *, mac_header_info_t *);
extern void dld_str_rx_fastpath(void *, mac_resource_handle_t,
mblk_t *, mac_header_info_t *);
extern void dld_str_rx_unitdata(void *, mac_resource_handle_t,
mblk_t *, mac_header_info_t *);
extern void dld_str_notify_ind(dld_str_t *);
extern mac_tx_cookie_t str_mdata_fastpath_put(dld_str_t *, mblk_t *,
uintptr_t, uint16_t);
extern int dld_flow_ctl_callb(dld_str_t *, uint64_t,
int (*func)(), void *);
extern void dld_proto(dld_str_t *, mblk_t *);
extern void dld_proto_unitdata_req(dld_str_t *, mblk_t *);
extern void dld_capabilities_disable(dld_str_t *);
extern void proto_unitdata_req(dld_str_t *, mblk_t *);
extern void flow_rx_pkt_chain(void *, void *, mblk_t *);
extern mac_handle_t dld_mac_open(char *dev_name, int *err);
#define dld_mac_close(mh) mac_close(mh)
#define DLD_OPT_NO_FASTPATH 0x00000001
#define DLD_OPT_NO_POLL 0x00000002
#define DLD_OPT_NO_ZEROCOPY 0x00000004
#define DLD_OPT_NO_SOFTRING 0x00000008
extern uint32_t dld_opt;
typedef struct dld_ap {
datalink_id_t da_linkid;
struct dlautopush da_ap;
#define da_anchor da_ap.dap_anchor
#define da_npush da_ap.dap_npush
#define da_aplist da_ap.dap_aplist
} dld_ap_t;
#define DLD_SETQFULL(dsp) { \
queue_t *q = (dsp)->ds_wq; \
\
mutex_enter(&(dsp)->ds_lock); \
if ((dsp)->ds_tx_flow_mp != NULL) { \
(void) putq(q, (dsp)->ds_tx_flow_mp); \
(dsp)->ds_tx_flow_mp = NULL; \
qenable((dsp)->ds_wq); \
} \
mutex_exit(&(dsp)->ds_lock); \
}
#define DLD_CLRQFULL(dsp) { \
queue_t *q = (dsp)->ds_wq; \
\
mutex_enter(&(dsp)->ds_lock); \
if ((dsp)->ds_dlstate != DL_IDLE || \
!mac_tx_is_flow_blocked((dsp)->ds_mch, 0)) { \
if ((dsp)->ds_tx_flow_mp == NULL) \
(dsp)->ds_tx_flow_mp = getq(q); \
ASSERT((dsp)->ds_tx_flow_mp != NULL); \
} \
mutex_exit(&(dsp)->ds_lock); \
}
#define DLD_TX(dsp, mp, f_hint, flag) \
mac_tx(dsp->ds_mch, mp, f_hint, flag, NULL)
#ifdef DEBUG
#define DLD_DBG cmn_err
#else
#define DLD_DBG if (0) cmn_err
#endif
#ifdef __cplusplus
}
#endif
#endif