#ifndef _SYS_SOFTMAC_IMPL_H
#define _SYS_SOFTMAC_IMPL_H
#include <sys/types.h>
#include <sys/ethernet.h>
#include <sys/taskq.h>
#include <sys/sunddi.h>
#include <sys/sunldi.h>
#include <sys/strsun.h>
#include <sys/stream.h>
#include <sys/dlpi.h>
#include <sys/mac.h>
#include <sys/mac_provider.h>
#include <sys/mac_client.h>
#include <sys/mac_client_priv.h>
#include <sys/mac_ether.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*softmac_rx_t)(void *, mac_resource_handle_t, mblk_t *,
mac_header_info_t *);
typedef struct softmac_lower_rxinfo_s {
softmac_rx_t slr_rx;
void *slr_arg;
} softmac_lower_rxinfo_t;
typedef struct softmac_lower_s {
ldi_handle_t sl_lh;
struct softmac *sl_softmac;
queue_t *sl_wq;
struct softmac_upper_s *sl_sup;
softmac_lower_rxinfo_t *sl_rxinfo;
kmutex_t sl_mutex;
kcondvar_t sl_cv;
t_uscalar_t sl_pending_prim;
boolean_t sl_pending_ioctl;
mblk_t *sl_ack_mp;
} softmac_lower_t;
typedef enum {
SOFTMAC_UNINIT,
SOFTMAC_ATTACH_INPROG,
SOFTMAC_ATTACH_DONE,
SOFTMAC_DETACH_INPROG,
} softmac_state_t;
typedef struct softmac_dev_s {
dev_t sd_dev;
} softmac_dev_t;
#define SOFTMAC_GLDV3 0x01
#define SOFTMAC_NOSUPP 0x02
#define SOFTMAC_NEED_RECREATE 0x04
#define SOFTMAC_NOTIFY_QUIT 0x08
#define SOFTMAC_NOTIFY_DONE 0x10
#define SMAC_NONZERO_NODECNT(softmac) \
((softmac->smac_softmac[0] != NULL) + \
(softmac->smac_softmac[1] != NULL))
typedef struct softmac {
char smac_devname[MAXNAMELEN];
major_t smac_umajor;
int smac_uppa;
uint32_t smac_cnt;
kmutex_t smac_mutex;
kcondvar_t smac_cv;
softmac_state_t smac_state;
uint32_t smac_hold_cnt;
uint32_t smac_flags;
int smac_attacherr;
mac_handle_t smac_mh;
softmac_dev_t *smac_softmac[2];
uint32_t smac_attachok_cnt;
uint32_t smac_attached_left;
kthread_t *smac_notify_thread;
mblk_t *smac_notify_head;
mblk_t *smac_notify_tail;
uint_t smac_media;
int smac_style;
dev_t smac_dev;
size_t smac_saplen;
size_t smac_addrlen;
uchar_t smac_unicst_addr[MAXMACADDRLEN];
uint_t smac_min_sdu;
uint_t smac_max_sdu;
uint32_t smac_margin;
uint32_t smac_notifications;
uint32_t smac_capab_flags;
uint32_t smac_hcksum_txflags;
boolean_t smac_no_capability_req;
softmac_lower_t *smac_lower;
kmutex_t smac_active_mutex;
boolean_t smac_active;
uint32_t smac_nactive;
kmutex_t smac_fp_mutex;
kcondvar_t smac_fp_cv;
uint32_t smac_fp_disable_clients;
boolean_t smac_fastpath_admin_disabled;
list_t smac_sup_list;
} softmac_t;
typedef struct smac_ioc_start_s {
softmac_lower_t *si_slp;
} smac_ioc_start_t;
#define SMAC_IOC ('S' << 24 | 'M' << 16 | 'C' << 8)
#define SMAC_IOC_START (SMAC_IOC | 0x01)
#define SOFTMAC_UNKNOWN 0x00
#define SOFTMAC_SLOWPATH 0x01
#define SOFTMAC_FASTPATH 0x02
typedef struct softmac_switch_req_s {
list_node_t ssq_req_list_node;
uint32_t ssq_expected_mode;
} softmac_switch_req_t;
#define DATAPATH_MODE(softmac) \
((((softmac)->smac_fp_disable_clients != 0) || \
(softmac)->smac_fastpath_admin_disabled) ? SOFTMAC_SLOWPATH : \
SOFTMAC_FASTPATH)
typedef struct softmac_upper_s {
softmac_t *su_softmac;
queue_t *su_rq;
queue_t *su_wq;
list_node_t su_taskq_list_node;
softmac_lower_t *su_slp;
list_node_t su_list_node;
list_t su_req_list;
softmac_lower_rxinfo_t su_rxinfo;
softmac_lower_rxinfo_t su_direct_rxinfo;
kmutex_t su_disp_mutex;
kcondvar_t su_disp_cv;
mblk_t *su_pending_head;
mblk_t *su_pending_tail;
boolean_t su_dlpi_pending;
boolean_t su_closing;
uint32_t su_bound : 1,
su_active : 1,
su_direct : 1,
su_is_arp : 1,
su_pad_to_32:28;
kmutex_t su_mutex;
kcondvar_t su_cv;
mblk_t *su_tx_flow_mp;
boolean_t su_tx_busy;
uint32_t su_tx_inprocess;
uint32_t su_mode;
boolean_t su_taskq_scheduled;
mac_tx_notify_t su_tx_notify_func;
void *su_tx_notify_arg;
} softmac_upper_t;
#define SOFTMAC_EQ_PENDING(sup, mp) { \
if ((sup)->su_pending_head == NULL) { \
(sup)->su_pending_head = (sup)->su_pending_tail = (mp); \
} else { \
(sup)->su_pending_tail->b_next = (mp); \
(sup)->su_pending_tail = (mp); \
} \
}
#define SOFTMAC_DQ_PENDING(sup, mpp) { \
if ((sup)->su_pending_head == NULL) { \
*(mpp) = NULL; \
} else { \
*(mpp) = (sup)->su_pending_head; \
if (((sup)->su_pending_head = (*(mpp))->b_next) == NULL)\
(sup)->su_pending_tail = NULL; \
(*(mpp))->b_next = NULL; \
} \
}
#define SOFTMAC_CANPUTNEXT(q) \
(!((q)->q_next->q_nfsrv->q_flag & QFULL) || canput((q)->q_next))
extern dev_info_t *softmac_dip;
#define SOFTMAC_DEV_NAME "softmac"
extern int softmac_send_bind_req(softmac_lower_t *, uint_t);
extern int softmac_send_unbind_req(softmac_lower_t *);
extern int softmac_send_notify_req(softmac_lower_t *, uint32_t);
extern int softmac_send_promisc_req(softmac_lower_t *, t_uscalar_t,
boolean_t);
extern void softmac_init();
extern void softmac_fini();
extern void softmac_fp_init();
extern void softmac_fp_fini();
extern boolean_t softmac_busy();
extern int softmac_fill_capab(ldi_handle_t, softmac_t *);
extern int softmac_capab_enable(softmac_lower_t *);
extern void softmac_rput_process_notdata(queue_t *, softmac_upper_t *,
mblk_t *);
extern void softmac_rput_process_data(softmac_lower_t *, mblk_t *);
extern int softmac_output(softmac_lower_t *, mblk_t *, t_uscalar_t,
t_uscalar_t, mblk_t **);
extern int softmac_mexchange_error_ack(mblk_t **, t_uscalar_t,
t_uscalar_t, t_uscalar_t);
extern int softmac_m_promisc(void *, boolean_t);
extern int softmac_m_multicst(void *, boolean_t, const uint8_t *);
extern int softmac_m_unicst(void *, const uint8_t *);
extern void softmac_m_ioctl(void *, queue_t *, mblk_t *);
extern int softmac_m_stat(void *, uint_t, uint64_t *);
extern mblk_t *softmac_m_tx(void *, mblk_t *);
extern int softmac_proto_tx(softmac_lower_t *, mblk_t *, mblk_t **);
extern void softmac_ioctl_tx(softmac_lower_t *, mblk_t *, mblk_t **);
extern void softmac_notify_thread(void *);
extern int softmac_hold(dev_t, softmac_t **);
extern void softmac_rele(softmac_t *);
extern int softmac_lower_setup(softmac_t *, softmac_upper_t *,
softmac_lower_t **);
extern boolean_t softmac_active_set(void *);
extern void softmac_active_clear(void *);
extern int softmac_fastpath_disable(void *);
extern void softmac_fastpath_enable(void *);
extern int softmac_datapath_switch(softmac_t *, boolean_t, boolean_t);
extern void softmac_wput_data(softmac_upper_t *, mblk_t *);
extern void softmac_wput_nondata(softmac_upper_t *, mblk_t *);
extern void softmac_upperstream_close(softmac_upper_t *);
#ifdef __cplusplus
}
#endif
#endif