summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys
diff options
context:
space:
mode:
authorCathy Zhou <Cathy.Zhou@Sun.COM>2009-03-17 20:14:50 -0700
committerCathy Zhou <Cathy.Zhou@Sun.COM>2009-03-17 20:14:50 -0700
commit5d460eafffba936e81c4dd5ebe0f59b238f09121 (patch)
treeec942dd0b37946b807039b9f42e69a8f54c30b7d /usr/src/uts/common/sys
parentf91909144addd198e09d1842e5354bfa62d96691 (diff)
downloadillumos-gate-5d460eafffba936e81c4dd5ebe0f59b238f09121.tar.gz
PSARC/2008/242 Data Fast-Path for Softmac
6649224 fast-path needed to improve legacy network interface performance after UV 6649898 the smac_lock and smac_mutex fields in softmac_t should be given a more descriptive name 6799767 DLD capability is not correctly updated if it is renegotiated
Diffstat (limited to 'usr/src/uts/common/sys')
-rw-r--r--usr/src/uts/common/sys/dld.h3
-rw-r--r--usr/src/uts/common/sys/dld_impl.h8
-rw-r--r--usr/src/uts/common/sys/dlpi.h19
-rw-r--r--usr/src/uts/common/sys/dls_impl.h2
-rw-r--r--usr/src/uts/common/sys/mac.h18
-rw-r--r--usr/src/uts/common/sys/mac_client_priv.h1
-rw-r--r--usr/src/uts/common/sys/mac_impl.h5
-rw-r--r--usr/src/uts/common/sys/mac_provider.h18
-rw-r--r--usr/src/uts/common/sys/softmac_impl.h244
9 files changed, 267 insertions, 51 deletions
diff --git a/usr/src/uts/common/sys/dld.h b/usr/src/uts/common/sys/dld.h
index 3094fa1a09..5fede27bb2 100644
--- a/usr/src/uts/common/sys/dld.h
+++ b/usr/src/uts/common/sys/dld.h
@@ -411,6 +411,9 @@ int dld_open(queue_t *, dev_t *, int, int, cred_t *);
int dld_close(queue_t *);
void dld_wput(queue_t *, mblk_t *);
void dld_wsrv(queue_t *);
+int dld_str_open(queue_t *, dev_t *, void *);
+int dld_str_close(queue_t *);
+void *dld_str_private(queue_t *);
void dld_init_ops(struct dev_ops *, const char *);
void dld_fini_ops(struct dev_ops *);
int dld_autopush(dev_t *, struct dlautopush *);
diff --git a/usr/src/uts/common/sys/dld_impl.h b/usr/src/uts/common/sys/dld_impl.h
index 79aa82ba75..68caa4f459 100644
--- a/usr/src/uts/common/sys/dld_impl.h
+++ b/usr/src/uts/common/sys/dld_impl.h
@@ -207,13 +207,19 @@ struct dld_str_s { /* Protected by */
dls_multicst_addr_t *ds_dmap; /* ds_rw_lock */
dls_rx_t ds_rx; /* ds_lock */
void *ds_rx_arg; /* ds_lock */
- boolean_t ds_active; /* SL */
+ uint_t ds_nactive; /* SL */
dld_str_t *ds_next; /* SL */
dls_head_t *ds_head;
dls_dl_handle_t ds_ddh;
list_node_t ds_tqlist;
+
+ /*
+ * driver private data set by the driver when calling dld_str_open().
+ */
+ void *ds_private;
};
+
#define DLD_DATATHR_INC(dsp) { \
ASSERT(MUTEX_HELD(&(dsp)->ds_lock)); \
dsp->ds_datathr_cnt++; \
diff --git a/usr/src/uts/common/sys/dlpi.h b/usr/src/uts/common/sys/dlpi.h
index e67f604630..11293ac6d3 100644
--- a/usr/src/uts/common/sys/dlpi.h
+++ b/usr/src/uts/common/sys/dlpi.h
@@ -104,6 +104,7 @@ typedef struct dl_ipnetinfo {
#define DL_CONTROL_ACK 0x113 /* Device specific control ack */
#define DL_PASSIVE_REQ 0x114 /* Allow access to aggregated link */
#define DL_INTR_MODE_REQ 0x115 /* Request Rx processing in INTR mode */
+#define DL_NOTIFY_CONF 0x116 /* Notification from upstream */
/*
* Primitives used for Connectionless Service
@@ -385,7 +386,7 @@ typedef struct dl_ipnetinfo {
#define DL_PROMISC_MULTI 0x03 /* promiscuous mode for multicast */
/*
- * DLPI notification codes for DL_NOTIFY primitives.
+ * DLPI notification codes for DL_NOTIFY_REQ primitives.
* Bit-wise distinct since DL_NOTIFY_REQ and DL_NOTIFY_ACK carry multiple
* notification codes.
*/
@@ -400,6 +401,12 @@ typedef struct dl_ipnetinfo {
#define DL_NOTE_SPEED 0x0100 /* Approximate link speed */
#define DL_NOTE_FASTPATH_FLUSH 0x0200 /* Fast Path info changes */
#define DL_NOTE_CAPAB_RENEG 0x0400 /* Initiate capability renegotiation */
+#define DL_NOTE_REPLUMB 0x0800 /* Inform the link to replumb */
+
+/*
+ * DLPI notification codes for DL_NOTIFY_CONF primitives.
+ */
+#define DL_NOTE_REPLUMB_DONE 0x0001 /* Indicate replumb has done */
/*
* DLPI Quality Of Service definition for use in QOS structure definitions.
@@ -1017,6 +1024,14 @@ typedef struct {
} dl_notify_ind_t;
/*
+ * DL_NOTIFY_CONF, M_PROTO type
+ */
+typedef struct {
+ t_uscalar_t dl_primitive; /* set to DL_NOTIFY_CONF */
+ uint32_t dl_notification; /* Which notification? */
+} dl_notify_conf_t;
+
+/*
* DL_AGGR_REQ, M_PROTO type
*/
typedef struct {
@@ -1507,6 +1522,7 @@ union DL_primitives {
dl_notify_req_t notify_req;
dl_notify_ack_t notify_ack;
dl_notify_ind_t notify_ind;
+ dl_notify_conf_t notify_conf;
dl_aggr_req_t aggr_req;
dl_aggr_ind_t aggr_ind;
dl_unaggr_req_t unaggr_req;
@@ -1574,6 +1590,7 @@ union DL_primitives {
#define DL_NOTIFY_REQ_SIZE sizeof (dl_notify_req_t)
#define DL_NOTIFY_ACK_SIZE sizeof (dl_notify_ack_t)
#define DL_NOTIFY_IND_SIZE sizeof (dl_notify_ind_t)
+#define DL_NOTIFY_CONF_SIZE sizeof (dl_notify_conf_t)
#define DL_AGGR_REQ_SIZE sizeof (dl_aggr_req_t)
#define DL_AGGR_IND_SIZE sizeof (dl_aggr_ind_t)
#define DL_UNAGGR_REQ_SIZE sizeof (dl_unaggr_req_t)
diff --git a/usr/src/uts/common/sys/dls_impl.h b/usr/src/uts/common/sys/dls_impl.h
index 33162a4d5c..dafd451954 100644
--- a/usr/src/uts/common/sys/dls_impl.h
+++ b/usr/src/uts/common/sys/dls_impl.h
@@ -119,7 +119,7 @@ extern void dls_rx_promisc(void *, mac_resource_handle_t, mblk_t *,
extern void dls_rx_vlan_promisc(void *, mac_resource_handle_t,
mblk_t *, boolean_t);
extern int dls_active_set(dld_str_t *);
-extern void dls_active_clear(dld_str_t *);
+extern void dls_active_clear(dld_str_t *, boolean_t);
extern void dls_mgmt_init(void);
extern void dls_mgmt_fini(void);
diff --git a/usr/src/uts/common/sys/mac.h b/usr/src/uts/common/sys/mac.h
index 1756644b6c..2cfe7443e5 100644
--- a/usr/src/uts/common/sys/mac.h
+++ b/usr/src/uts/common/sys/mac.h
@@ -260,20 +260,6 @@ typedef struct mac_info_s {
} mac_info_t;
/*
- * Information for legacy devices.
- */
-typedef struct mac_capab_legacy_s {
- /*
- * Notifications that the legacy device does not support.
- */
- uint32_t ml_unsup_note;
- /*
- * dev_t of the legacy device; can be held to force attach.
- */
- dev_t ml_dev;
-} mac_capab_legacy_t;
-
-/*
* When VNICs are created on top of the NIC, there are two levels
* of MAC layer, a lower MAC, which is the MAC layer at the level of the
* physical NIC, and an upper MAC, which is the MAC layer at the level
@@ -569,13 +555,15 @@ extern void mac_margin_get(mac_handle_t, uint32_t *);
extern int mac_margin_remove(mac_handle_t, uint32_t);
extern int mac_margin_add(mac_handle_t, uint32_t *,
boolean_t);
+extern int mac_fastpath_disable(mac_handle_t);
+extern void mac_fastpath_enable(mac_handle_t);
extern mactype_register_t *mactype_alloc(uint_t);
extern void mactype_free(mactype_register_t *);
extern int mactype_register(mactype_register_t *);
extern int mactype_unregister(const char *);
-extern void mac_start_logusage(mac_logtype_t, uint_t);
+extern int mac_start_logusage(mac_logtype_t, uint_t);
extern void mac_stop_logusage(mac_logtype_t);
extern mac_handle_t mac_get_lower_mac_handle(mac_handle_t);
diff --git a/usr/src/uts/common/sys/mac_client_priv.h b/usr/src/uts/common/sys/mac_client_priv.h
index c1b999bb31..20e3afa82a 100644
--- a/usr/src/uts/common/sys/mac_client_priv.h
+++ b/usr/src/uts/common/sys/mac_client_priv.h
@@ -63,6 +63,7 @@ extern void mac_ioctl(mac_handle_t, queue_t *, mblk_t *);
extern link_state_t mac_link_get(mac_handle_t);
extern void mac_resource_set(mac_client_handle_t, mac_resource_add_t, void *);
extern dev_info_t *mac_devinfo_get(mac_handle_t);
+extern void *mac_driver(mac_handle_t);
extern boolean_t mac_capab_get(mac_handle_t, mac_capab_t, void *);
extern boolean_t mac_sap_verify(mac_handle_t, uint32_t, uint32_t *);
extern mblk_t *mac_header(mac_handle_t, const uint8_t *, uint32_t, mblk_t *,
diff --git a/usr/src/uts/common/sys/mac_impl.h b/usr/src/uts/common/sys/mac_impl.h
index ee5557b113..9a02c07b54 100644
--- a/usr/src/uts/common/sys/mac_impl.h
+++ b/usr/src/uts/common/sys/mac_impl.h
@@ -457,9 +457,10 @@ struct mac_impl_s {
mac_resource_props_t mi_resource_props; /* SL */
minor_t mi_minor; /* WO */
- dev_t mi_phy_dev; /* WO */
uint32_t mi_oref; /* SL */
- uint32_t mi_unsup_note; /* WO */
+ mac_capab_legacy_t mi_capab_legacy; /* WO */
+ dev_t mi_phy_dev; /* WO */
+
/*
* List of margin value requests added by mac clients. This list is
* sorted: the first one has the greatest value.
diff --git a/usr/src/uts/common/sys/mac_provider.h b/usr/src/uts/common/sys/mac_provider.h
index 5522a6c884..6713912b63 100644
--- a/usr/src/uts/common/sys/mac_provider.h
+++ b/usr/src/uts/common/sys/mac_provider.h
@@ -145,6 +145,24 @@ typedef struct mac_capab_multifactaddr_s {
} mac_capab_multifactaddr_t;
/*
+ * Info and callbacks of legacy devices.
+ */
+typedef struct mac_capab_legacy_s {
+ /*
+ * Notifications that the legacy device does not support.
+ */
+ uint32_t ml_unsup_note;
+ /*
+ * dev_t of the legacy device; can be held to force attach.
+ */
+ dev_t ml_dev;
+ boolean_t (*ml_active_set)(void *);
+ void (*ml_active_clear)(void *);
+ int (*ml_fastpath_disable)(void *);
+ void (*ml_fastpath_enable)(void *);
+} mac_capab_legacy_t;
+
+/*
* MAC driver entry point types.
*/
typedef int (*mac_getstat_t)(void *, uint_t, uint64_t *);
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