4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/strsubr.h>
28 #include <sys/softmac_impl.h>
31 softmac_m_tx(void *arg
, mblk_t
*mp
)
33 queue_t
*wq
= ((softmac_t
*)arg
)->smac_lower
->sl_wq
;
36 * Optimize for the most common case.
38 if (mp
->b_next
== NULL
) {
39 if (!SOFTMAC_CANPUTNEXT(wq
))
42 mp
->b_flag
|= MSGNOLOOP
;
48 mblk_t
*next
= mp
->b_next
;
50 if (!SOFTMAC_CANPUTNEXT(wq
))
53 mp
->b_flag
|= MSGNOLOOP
;
61 softmac_rput_process_data(softmac_lower_t
*slp
, mblk_t
*mp
)
64 * When packets arrive, the softmac might not be fully started.
66 ASSERT((slp
->sl_softmac
!= NULL
));
67 ASSERT((mp
->b_next
== NULL
) && (mp
->b_prev
== NULL
));
71 uint32_t start
, stuff
, end
, value
, flags
;
73 if ((tmp
= copymsg(mp
)) == NULL
) {
74 cmn_err(CE_WARN
, "softmac_rput_process_data: "
78 mac_hcksum_get(mp
, &start
, &stuff
, &end
, &value
, &flags
);
79 mac_hcksum_set(tmp
, start
, stuff
, end
, value
, flags
);
84 mac_rx(slp
->sl_softmac
->smac_mh
, NULL
, mp
);
91 #define ACKTIMEOUT (10 * hz)
94 dlpi_get_errno(t_uscalar_t error
, t_uscalar_t unix_errno
)
96 return (error
== DL_SYSERR
? unix_errno
: EINVAL
);
100 softmac_output(softmac_lower_t
*slp
, mblk_t
*mp
, t_uscalar_t dl_prim
,
101 t_uscalar_t ack
, mblk_t
**mpp
)
103 union DL_primitives
*dlp
;
104 mac_perim_handle_t mph
;
107 mac_perim_enter_by_mh(slp
->sl_softmac
->smac_mh
, &mph
);
109 ASSERT(!slp
->sl_pending_ioctl
);
110 ASSERT(slp
->sl_pending_prim
== DL_PRIM_INVAL
);
113 * Record the pending DLPI primitive.
115 mutex_enter(&slp
->sl_mutex
);
116 slp
->sl_pending_prim
= dl_prim
;
117 mutex_exit(&slp
->sl_mutex
);
119 putnext(slp
->sl_wq
, mp
);
121 mutex_enter(&slp
->sl_mutex
);
122 while (slp
->sl_pending_prim
!= DL_PRIM_INVAL
) {
123 if (cv_reltimedwait(&slp
->sl_cv
, &slp
->sl_mutex
, ACKTIMEOUT
,
124 TR_CLOCK_TICK
) == -1)
129 slp
->sl_ack_mp
= NULL
;
132 * If we timed out, sl_ack_mp will still be NULL, but sl_pending_prim
133 * won't be set to DL_PRIM_INVAL.
135 ASSERT(mp
!= NULL
|| slp
->sl_pending_prim
!= DL_PRIM_INVAL
);
137 slp
->sl_pending_prim
= DL_PRIM_INVAL
;
138 mutex_exit(&slp
->sl_mutex
);
141 dlp
= (union DL_primitives
*)mp
->b_rptr
;
143 if (dlp
->dl_primitive
== DL_ERROR_ACK
) {
144 err
= dlpi_get_errno(dlp
->error_ack
.dl_errno
,
145 dlp
->error_ack
.dl_unix_errno
);
147 ASSERT(dlp
->dl_primitive
== ack
);
163 softmac_ioctl_tx(softmac_lower_t
*slp
, mblk_t
*mp
, mblk_t
**mpp
)
165 mac_perim_handle_t mph
;
167 mac_perim_enter_by_mh(slp
->sl_softmac
->smac_mh
, &mph
);
170 * Record that ioctl processing is currently in progress.
172 mutex_enter(&slp
->sl_mutex
);
173 slp
->sl_pending_ioctl
= B_TRUE
;
174 mutex_exit(&slp
->sl_mutex
);
176 putnext(slp
->sl_wq
, mp
);
178 mutex_enter(&slp
->sl_mutex
);
179 while (slp
->sl_pending_ioctl
)
180 cv_wait(&slp
->sl_cv
, &slp
->sl_mutex
);
182 slp
->sl_ack_mp
= NULL
;
183 mutex_exit(&slp
->sl_mutex
);
185 ASSERT(mpp
!= NULL
&& mp
!= NULL
);
192 softmac_mexchange_error_ack(mblk_t
**mpp
, t_uscalar_t error_primitive
,
193 t_uscalar_t error
, t_uscalar_t unix_errno
)
195 union DL_primitives
*dlp
;
197 if ((*mpp
= mexchange(NULL
, *mpp
, sizeof (dl_error_ack_t
), M_PCPROTO
,
198 DL_ERROR_ACK
)) == NULL
)
201 dlp
= (union DL_primitives
*)(*mpp
)->b_rptr
;
202 dlp
->error_ack
.dl_error_primitive
= error_primitive
;
203 dlp
->error_ack
.dl_errno
= error
;
204 dlp
->error_ack
.dl_unix_errno
= unix_errno
;
210 softmac_proto_tx(softmac_lower_t
*slp
, mblk_t
*mp
, mblk_t
**mpp
)
215 dl_prim
= ((union DL_primitives
*)mp
->b_rptr
)->dl_primitive
;
217 ASSERT(slp
->sl_softmac
!= NULL
);
220 case DL_ENABMULTI_REQ
:
221 case DL_DISABMULTI_REQ
:
222 case DL_SET_PHYS_ADDR_REQ
:
225 case DL_PROMISCON_REQ
:
226 case DL_PROMISCOFF_REQ
:
227 err
= softmac_output(slp
, mp
, dl_prim
, DL_OK_ACK
, mpp
);
230 err
= softmac_output(slp
, mp
, dl_prim
, DL_BIND_ACK
, mpp
);
233 err
= softmac_output(slp
, mp
, dl_prim
, DL_NOTIFY_ACK
, mpp
);
236 err
= softmac_output(slp
, mp
, dl_prim
, DL_CONTROL_ACK
, mpp
);
238 case DL_CAPABILITY_REQ
:
239 err
= softmac_output(slp
, mp
, dl_prim
, DL_CAPABILITY_ACK
, mpp
);
244 err
= softmac_mexchange_error_ack(mpp
, dl_prim
,