summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/softmac_impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/sys/softmac_impl.h')
-rw-r--r--usr/src/uts/common/sys/softmac_impl.h244
1 files changed, 213 insertions, 31 deletions
diff --git a/usr/src/uts/common/sys/softmac_impl.h b/usr/src/uts/common/sys/softmac_impl.h
index 9cdb49de31..83caa23c82 100644
--- a/usr/src/uts/common/sys/softmac_impl.h
+++ b/usr/src/uts/common/sys/softmac_impl.h
@@ -44,9 +44,20 @@
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;
/*
* sl_ctl_inprogress is used to serialize the control path. It will
@@ -68,8 +79,6 @@ typedef struct softmac_lower_s {
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 {
@@ -110,55 +119,53 @@ typedef struct softmac_dev_s {
* 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.)
+ *
+ * Locking description:
+ * WO: write once, valid the life time.
*/
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 */
+ char smac_devname[MAXNAMELEN]; /* WO */
+ major_t smac_umajor; /* WO */
+ int smac_uppa; /* WO */
+ uint32_t smac_cnt; /* WO, # of minor nodes */
+ kmutex_t smac_mutex;
+ kcondvar_t smac_cv;
+ softmac_state_t smac_state; /* smac_mutex */
/*
- * 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;
+ uint32_t smac_hold_cnt; /* smac_mutex */
+ uint32_t smac_flags; /* smac_mutex */
+ int smac_attacherr; /* smac_mutex */
mac_handle_t smac_mh;
- softmac_dev_t *smac_softmac[2];
+ softmac_dev_t *smac_softmac[2]; /* smac_mutex */
+
/*
* 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;
+ uint32_t smac_attachok_cnt; /* smac_mutex */
/*
* 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;
+ uint32_t smac_attached_left; /* smac_mutex */
/*
* Thread handles the DL_NOTIFY_IND message from the lower stream.
*/
- kthread_t *smac_notify_thread;
+ kthread_t *smac_notify_thread; /* smac_mutex */
/*
* Head and tail of the DL_NOTIFY_IND messsages.
*/
- mblk_t *smac_notify_head;
- mblk_t *smac_notify_tail;
+ mblk_t *smac_notify_head; /* smac_mutex */
+ mblk_t *smac_notify_tail; /* smac_mutex */
/*
* The remaining fields are used to register the MAC for a legacy
@@ -193,10 +200,34 @@ typedef struct softmac {
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 */
+ /*
+ * Lower stream structure, accessed by the MAC provider API. The GLDv3
+ * framework assures it's validity.
+ */
softmac_lower_t *smac_lower;
+
+ kmutex_t smac_active_mutex;
+ /*
+ * Set by xxx_active_set() when aggregation is created.
+ */
+ boolean_t smac_active; /* smac_active_mutex */
+ /*
+ * Numbers of the bounded streams in the fast-path mode.
+ */
+ uint32_t smac_nactive; /* smac_active_mutex */
+
+ kmutex_t smac_fp_mutex;
+ kcondvar_t smac_fp_cv;
+ /*
+ * numbers of clients that request to disable fastpath.
+ */
+ uint32_t smac_fp_disable_clients; /* smac_fp_mutex */
+ boolean_t smac_fastpath_admin_disabled; /* smac_fp_mutex */
+
+ /*
+ * stream list over this softmac.
+ */
+ list_t smac_sup_list; /* smac_fp_mutex */
} softmac_t;
typedef struct smac_ioc_start_s {
@@ -206,20 +237,157 @@ typedef struct smac_ioc_start_s {
#define SMAC_IOC ('S' << 24 | 'M' << 16 | 'C' << 8)
#define SMAC_IOC_START (SMAC_IOC | 0x01)
+/*
+ * The su_mode of a non-IP/ARP stream is UNKNOWN, and the su_mode of an IP/ARP
+ * stream is either SLOWPATH or FASTPATH.
+ */
+#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)
+
+
+/*
+ * Locking description:
+ *
+ * WO: Set once and valid for life;
+ * SL: Serialized by the control path (softmac_wput_nondata_task())
+ */
+typedef struct softmac_upper_s {
+ softmac_t *su_softmac; /* WO */
+ queue_t *su_rq; /* WO */
+ queue_t *su_wq; /* WO */
+
+ /*
+ * List of upper streams that has pending DLPI messages to be processed.
+ */
+ list_node_t su_taskq_list_node; /* softmac_taskq_lock */
+
+ /*
+ * non-NULL for IP/ARP streams in the fast-path mode
+ */
+ softmac_lower_t *su_slp; /* SL & su_mutex */
+
+ /*
+ * List of all IP/ARP upperstreams on the same softmac (including
+ * the ones in both data-path modes).
+ */
+ list_node_t su_list_node; /* smac_fp_mutex */
+
+ /*
+ * List of datapath switch requests.
+ */
+ list_t su_req_list; /* smac_fp_mutex */
+
+ /*
+ * Place holder of RX callbacks used to handles data messages comes
+ * from the dedicated-lower-stream associated with the IP/ARP stream.
+ * Another RX callback is softmac_drop_rxinfo, which is a global
+ * variable.
+ */
+ softmac_lower_rxinfo_t su_rxinfo; /* WO */
+ softmac_lower_rxinfo_t su_direct_rxinfo; /* WO */
+
+ /*
+ * Used to serialize the DLPI operation and fastpath<->slowpath
+ * switching over operation.
+ */
+ kmutex_t su_disp_mutex;
+ kcondvar_t su_disp_cv;
+ mblk_t *su_pending_head; /* su_disp_mutex */
+ mblk_t *su_pending_tail; /* su_disp_mutex */
+ boolean_t su_dlpi_pending; /* su_disp_mutex */
+ boolean_t su_closing; /* su_disp_mutex */
+
+ uint32_t su_bound : 1, /* SL */
+ su_active : 1, /* SL */
+ su_direct : 1; /* SL */
+
+ /*
+ * Used for fastpath data path.
+ */
+ kmutex_t su_mutex;
+ kcondvar_t su_cv;
+ mblk_t *su_tx_flow_mp; /* su_mutex */
+ boolean_t su_tx_busy; /* su_mutex */
+ /*
+ * Number of softmac_srv() operation in fastpath processing.
+ */
+ uint32_t su_tx_inprocess; /* su_mutex */
+ /*
+ * SOFTMAC_SLOWPATH or SOFTMAC_FASTPATH
+ */
+ uint32_t su_mode; /* SL & su_mutex */
+
+ /*
+ * Whether this stream is already scheduled in softmac_taskq_list.
+ */
+ boolean_t su_taskq_scheduled; /* softmac_taskq_lock */
+} 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; \
+ } \
+}
+
+/*
+ * A macro to check whether the write-queue of the lower stream is full
+ * and packets need to be enqueued.
+ *
+ * Because softmac is pushed right above the underlying device and
+ * _I_INSERT/_I_REMOVE is not processed in the lower stream, it is
+ * safe to directly access the q_next pointer.
+ */
+#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(void);
-extern void softmac_fini(void);
-extern boolean_t softmac_busy(void);
+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 *, mblk_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 *);
@@ -231,6 +399,20 @@ 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