/*
* 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
* 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.
*/
#include <sys/softmac_impl.h>
int
{
/*
* create notify req message and send it down
*/
return (ENOMEM);
}
int
{
/*
* create bind req message and send it down
*/
return (ENOMEM);
bind->dl_conn_mgmt = 0;
bind->dl_max_conind = 0;
bind->dl_xidtest_flg = 0;
}
int
{
/*
* create unbind req message and send it down
*/
return (ENOMEM);
}
int
{
/*
* create promisc message and send it down
*/
if (on) {
} else {
}
return (ENOMEM);
if (on)
else
}
int
{
}
int
{
/*
* create multicst message and send it down
*/
if (add) {
} else {
}
return (ENOMEM);
if (add) {
} else {
}
}
int
{
/*
* create set_phys_addr message and send it down
*/
return (ENOMEM);
}
void
{
}
static void
{
switch (dlnip->dl_notification) {
case DL_NOTE_PHYS_ADDR:
break;
break;
}
break;
case DL_NOTE_LINK_UP:
break;
case DL_NOTE_LINK_DOWN:
break;
}
}
void
{
"softmac_notify_thread");
/*
* Quit the thread if smac_mh is unregistered.
*/
continue;
}
}
}
/*
* The softmac is being destroyed, simply free all of the DL_NOTIFY_IND
* messages left in the queue which did not have the chance to be
* processed.
*/
thread_exit();
}
static void
{
} else {
}
}
static void
{
const char *ackname;
return;
}
return;
}
}
void
{
const char *primstr;
if (len < sizeof (t_uscalar_t)) {
goto exit;
}
switch (dlp->dl_primitive) {
case DL_OK_ACK:
if (len < DL_OK_ACK_SIZE)
goto runt;
return;
case DL_ERROR_ACK:
if (len < DL_ERROR_ACK_SIZE)
goto runt;
return;
case DL_NOTIFY_IND:
if (len < DL_NOTIFY_IND_SIZE)
goto runt;
/*
* Enqueue all the DL_NOTIFY_IND messages and process them
* in another separate thread to avoid deadlock. Here is an
* example of the deadlock scenario:
*
* Thread A: mac_promisc_set()->softmac_m_promisc()
*
* The softmac driver waits for the ACK of the
* DL_PROMISC_PHYS request with the MAC perimeter;
*
* Thread B:
*
* The driver handles the DL_PROMISC_PHYS request. Before
* it sends back the ACK, it could first send a
* DL_NOTE_PROMISC_ON_PHYS notification.
*
* Since DL_NOTIFY_IND could eventually cause softmac to call
* mac_xxx_update(), which requires MAC perimeter, this would
* cause deadlock between the two threads. Enqueuing the
* DL_NOTIFY_IND message and defer its processing would
* avoid the potential deadlock.
*/
return;
case DL_NOTIFY_ACK:
return;
case DL_CAPABILITY_ACK:
return;
case DL_BIND_ACK:
return;
case DL_CONTROL_ACK:
return;
case DL_UNITDATA_IND:
case DL_PHYS_ADDR_ACK:
/*
* a. Because the stream is in DLIOCRAW mode,
* DL_UNITDATA_IND messages are not expected.
* b. The lower stream should not receive DL_PHYS_ADDR_REQ,
* so DL_PHYS_ADDR_ACK messages are also unexpected.
*/
default:
break;
}
exit:
return;
runt:
}
void
{
case M_PROTO:
case M_PCPROTO:
/*
* If this is a shared-lower-stream, pass it to softmac to
* process.
*/
break;
}
/*
* Dedicated-lower-stream.
*/
switch (dlp->dl_primitive) {
case DL_OK_ACK:
if (len < DL_OK_ACK_SIZE)
goto runt;
/*
* If this is a DL_OK_ACK for a DL_UNBIND_REQ, pass it
* to softmac to process, otherwise directly pass it to
* the upper stream.
*/
break;
}
break;
case DL_ERROR_ACK:
if (len < DL_ERROR_ACK_SIZE)
goto runt;
/*
* If this is a DL_ERROR_ACK for a DL_UNBIND_REQ, pass
* it to softmac to process, otherwise directly pass it
* to the upper stream.
*/
break;
}
break;
case DL_BIND_ACK:
case DL_CAPABILITY_ACK:
break;
default:
break;
}
break;
case M_FLUSH:
break;
case M_IOCACK:
case M_IOCNAK:
case M_COPYIN:
case M_COPYOUT:
break;
}
if (!slp->sl_pending_ioctl) {
break;
}
break;
default:
break;
}
return;
runt:
}