softmac_impl.h revision 6504182088d3042177dc001b147152e7c07756d5
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#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 struct softmac_lower_s {
struct softmac *sl_softmac;
queue_t *sl_wq;
/*
* sl_ctl_inprogress is used to serialize the control path. It will
* be set when either an ioctl or an M_{PC,}PROTO message is received
* from the upper layer, and will be cleared when processing done.
*/
kmutex_t sl_ctl_mutex;
kcondvar_t sl_ctl_cv;
boolean_t sl_ctl_inprogress;
/*
* When a control message is processed, either sl_pending_prim or
* sl_pending_ioctl will be set. They will be cleared when the
* acknowledgement of the specific control message is received
* from the underlying legacy driver.
*/
kmutex_t sl_mutex;
kcondvar_t sl_cv;
t_uscalar_t sl_pending_prim;
boolean_t sl_pending_ioctl;
mblk_t *sl_ack_mp;
ldi_handle_t sl_lh;
} softmac_lower_t;
typedef enum {
SOFTMAC_INITIALIZED,
SOFTMAC_READY
} softmac_lower_state_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;
/*
* smac_flag values.
*/
#define SOFTMAC_GLDV3 0x01
#define SOFTMAC_NOSUPP 0x02
#define SOFTMAC_NEED_RECREATE 0x04
#define SOFTMAC_NOTIFY_QUIT 0x08
#define SMAC_NONZERO_NODECNT(softmac) \
((softmac->smac_softmac[0] != NULL) + \
(softmac->smac_softmac[1] != NULL))
/*
* The softmac structure allows all minor nodes (at most two, style-1 and
* style-2) for the same device to be processed. A softmac_dev_t will be
* created for each minor node.
*
* We try to "register" the mac after all the softmac_dev_t's are processed so
* that even if DLPI operations fail (because of driver bugs) for one minor
* node, the other minor node can still be used to register the mac.
* (Specifically, an incorrect xxx_getinfo() implementation will cause style-2
* minor node mac registration to fail.)
*/
typedef struct softmac {
/*
* The following fields will be set when the softmac is created and
* will not change. No lock is required.
*/
char smac_devname[MAXNAMELEN];
major_t smac_umajor;
int smac_uppa;
uint32_t smac_cnt; /* # of minor nodes for this device */
/*
* The following fields are protected by smac_mutex.
*
* The smac_hold_cnt field increases when softmac_hold_device() is
* called to force the dls_vlan_t of the device to be created. The
* device pre-detach fails if this counter is not 0.
*/
softmac_state_t smac_state;
uint32_t smac_hold_cnt;
kmutex_t smac_mutex;
kcondvar_t smac_cv;
uint32_t smac_flags;
int smac_attacherr;
mac_handle_t smac_mh;
softmac_dev_t *smac_softmac[2];
/*
* Number of minor nodes whose post-attach routine has succeeded.
* This should be the same as the numbers of softmac_dev_t.
* Note that it does not imply SOFTMAC_ATTACH_DONE as the taskq might
* be still ongoing.
*/
uint32_t smac_attachok_cnt;
/*
* Number of softmac_dev_t left when pre-detach fails. This is used
* to indicate whether postattach is called because of a failed
* pre-detach.
*/
uint32_t smac_attached_left;
/*
* Thread handles the DL_NOTIFY_IND message from the lower stream.
*/
kthread_t *smac_notify_thread;
/*
* Head and tail of the DL_NOTIFY_IND messsages.
*/
mblk_t *smac_notify_head;
mblk_t *smac_notify_tail;
/*
* The remaining fields are used to register the MAC for a legacy
* device. They are set in softmac_mac_register() and do not change.
* One can access them when mac_register() is done without locks.
*/
/*
* media type is needed for create <link name, linkid> mapping, so
* it is set for GLDv3 device as well
*/
uint_t smac_media;
/* DLPI style of the underlying device */
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;
/* Notifications the underlying driver can support. */
uint32_t smac_notifications;
/*
* Capabilities of the underlying driver.
*/
uint32_t smac_capab_flags;
uint32_t smac_hcksum_txflags;
boolean_t smac_no_capability_req;
dl_capab_mdt_t smac_mdt_capab;
boolean_t smac_mdt;
/* Following fields protected by the mac perimeter */
softmac_lower_state_t smac_lower_state;
/* Lower stream structure */
softmac_lower_t *smac_lower;
} 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)
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_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(void);
extern void softmac_fini(void);
extern boolean_t softmac_busy(void);
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 *, mblk_t *);
extern void softmac_rput_process_data(softmac_lower_t *, mblk_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 *);
#ifdef __cplusplus
}
#endif
#endif /* _SYS_SOFTMAC_IMPL_H */