dld_str.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Data-Link Driver
*/
#include <sys/dld_impl.h>
static int str_constructor(void *, void *, int);
static void str_destructor(void *, void *);
static void str_notify_promisc_on_phys(dld_str_t *);
static void str_notify_promisc_off_phys(dld_str_t *);
static void str_notify_link_up(dld_str_t *);
static void str_notify_link_down(dld_str_t *);
static void str_notify_capab_reneg(dld_str_t *);
static void str_notify(void *, mac_notify_type_t);
static kmem_cache_t *str_cachep;
typedef struct str_msg_info {
const char *smi_txt;
/*
* Normal priority message jump table.
*/
str_msg_info_t str_mi[] = {
};
/*
* High priority message jump table.
*/
str_msg_info_t str_pmi[] = {
};
/*
* Initialize this module's data structures.
*/
void
dld_str_init(void)
{
/*
* Create dld_str_t object cache.
*/
}
/*
* Tear down this module's data structures.
*/
int
dld_str_fini(void)
{
/*
* Make sure that there are no objects in use.
*/
if (str_count != 0)
return (EBUSY);
/*
* Destroy object cache.
*/
return (0);
}
/*
* Create a new dld_str_t object.
*/
{
/*
* Allocate an object from the cache.
*/
/*
* Initialize the queue pointers.
*/
return (dsp);
}
/*
* Destroy a dld_str_t object.
*/
void
{
/*
* Clear the queue pointers.
*/
/*
* Clear down notifications.
*/
dsp->ds_notifications = 0;
/*
* Free the object back to the cache.
*/
}
/*
* kmem_cache contructor function: see kmem_cache_create(9f).
*/
/*ARGSUSED*/
static int
{
/*
* Take a copy of the global message handler jump tables.
*/
return (-1);
return (-1);
}
/*
* Allocate a new minor number.
*/
return (-1);
}
/*
* Initialize the DLPI state machine.
*/
return (0);
}
/*
* kmem_cache destructor function.
*/
/*ARGSUSED*/
static void
{
/*
* Make sure the DLPI state machine was reset.
*/
/*
* Make sure the data-link interface was closed.
*/
/*
* Make sure enabled notifications are cleared.
*/
/*
* Make sure polling is disabled.
*/
/*
* Make sure M_DATA message handling is disabled.
*/
/*
* Release the minor number.
*/
/*
* Clear down the jump tables.
*/
}
/*
* Called from put(9e) to process a streams message.
*/
void
{
/*
* Look up the message handler from the appropriate jump table.
*/
/*
* Clear the priority bit to index into the jump table.
*/
/*
* Check the message is not out of range for the jump table.
*/
if (type >= STR_PMI_COUNT)
goto unknown;
/*
* Get the handler from the jump table.
*/
/*
* OR the priorty bit back in to restore the original message
* type.
*/
} else {
/*
* Check the message is not out of range for the jump table.
*/
if (type >= STR_MI_COUNT)
goto unknown;
/*
* Get the handler from the jump table.
*/
}
return;
}
/*
* Called from srv(9e) to process a streams message.
*/
void
{
/*
* Look up the message handler from the appropriate jump table.
*/
/*
* Clear the priority bit to index into the jump table.
*/
/*
* Check the message is not out of range for the jump table.
*/
if (type >= STR_PMI_COUNT)
goto unknown;
/*
* Get the handler from the jump table.
*/
/*
* OR the priorty bit back in to restore the original message
* type.
*/
} else {
/*
* Check the message is not out of range for the jump table.
*/
if (type >= STR_MI_COUNT)
goto unknown;
/*
* Get the handler from the jump table.
*/
}
return;
}
/*
* M_DATA put (IP fast-path mode)
*/
static void
{
/*
* If something is already queued then we must queue to avoid
* re-ordering.
*/
return;
}
/*
* Attempt to transmit the packet.
*/
qenable(q);
}
}
/*
* M_DATA put (raw mode)
*/
static void
{
struct ether_header *ehp;
if (size < sizeof (struct ether_header))
goto discard;
hdrlen = sizeof (struct ether_header);
struct ether_vlan_header *evhp;
if (size < sizeof (struct ether_vlan_header))
goto discard;
/*
* Replace vtag with our own
*/
hdrlen = sizeof (struct ether_vlan_header);
}
/*
* Check the packet is not too big and that any remaining
* fragment list is composed entirely of M_DATA messages. (We
* know the first fragment was M_DATA otherwise we could not
* have got here).
*/
goto discard;
}
goto discard;
/*
* If something is already queued then we must queue to avoid
* re-ordering.
*/
return;
}
/*
* Attempt to transmit the packet.
*/
qenable(q);
}
return;
}
/*
* M_DATA srv
*/
static void
{
/*
* Attempt to transmit the packet.
*/
return;
qenable(q);
}
/*
* M_PROTO put
*/
static void
{
}
/*
* M_PCPROTO put
*/
static void
{
}
/*
* M_IOCTL put
*/
static void
{
}
/*
* M_FLUSH put
*/
/*ARGSUSED*/
static void
{
}
else
}
/*
* M_* put.
*/
/*ARGSUSED*/
static void
{
}
/*
* M_* put.
*/
/*ARGSUSED*/
static void
{
}
/*
* Process DL_ATTACH_REQ (style 2) or open(2) (style 1).
*/
int
{
int err;
/*
* Open a channel.
*/
return (err);
/*
* Cache the MAC interface handle, a pointer to the immutable MAC
* information and the current and 'factory' MAC address.
*/
/*
* Cache the interface VLAN identifier. (This will be VLAN_ID_NONE for
* a non-VLAN interface).
*/
/*
* Set the default packet priority.
*/
/*
* Add a notify function so that the we get updates from the MAC.
*/
return (0);
}
/*
* Process DL_DETACH_REQ (style 2) or close(2) (style 1). Can also be called
* from close(2) for style 2.
*/
void
{
/*
* Remove the notify function.
*/
/*
* Make sure the M_DATA handler is reset.
*/
/*
* Clear the polling flag.
*/
/*
* Close the channel.
*/
}
/*
* Enable raw mode for this stream. This mode is mutually exclusive with
*/
void
{
/*
* Enable M_DATA message handling.
*/
}
/*
* Enable fast-path for this stream.
*/
void
{
/*
* Enable M_DATA message handling.
*/
}
/*
* Disable fast-path or raw mode.
*/
void
{
/*
* Disable M_DATA message handling.
*/
}
/*
* Raw mode receive function.
*/
/*ARGSUSED*/
void
{
do {
/*
* Get the pointer to the next packet in the chain and then
* clear b_next before the packet gets passed on.
*/
/*
* Wind back b_rptr to point at the MAC header.
*/
if (header_length == sizeof (struct ether_vlan_header)) {
/*
* Strip off the vtag
*/
2 * ETHERADDRL);
}
/*
* Pass the packet on.
*/
/*
* Move on to the next packet in the chain.
*/
}
/*
* Fast-path receive function.
*/
/*ARGSUSED*/
void
{
do {
/*
* Get the pointer to the next packet in the chain and then
* clear b_next before the packet gets passed on.
*/
/*
* Pass the packet on.
*/
/*
* Move on to the next packet in the chain.
*/
}
/*
* Default receive function (send DL_UNITDATA_IND messages).
*/
/*ARGSUSED*/
void
{
do {
/*
* Get the pointer to the next packet in the chain and then
* clear b_next before the packet gets passed on.
*/
/*
* Wind back b_rptr to point at the MAC header.
*/
/*
* Create the DL_UNITDATA_IND M_PROTO.
*/
return;
}
/*
* Advance b_rptr to point at the payload again.
*/
/*
* Prepend the DL_UNITDATA_IND.
*/
/*
* Send the message.
*/
/*
* Move on to the next packet in the chain.
*/
}
/*
* Generate DL_NOTIFY_IND messages to notify the DLPI consumer of the
* current state of the interface.
*/
void
{
}
typedef struct dl_unitdata_ind_wrapper {
/*
* Create a DL_UNITDATA_IND M_PROTO message.
*/
static mblk_t *
{
/*
* Get the packet header information.
*/
/*
* Allocate a message large enough to contain the wrapper structure
* defined above.
*/
sizeof (dl_unitdata_ind_wrapper_t), M_PROTO,
DL_UNITDATA_IND)) == NULL)
return (NULL);
/*
* Copy in the destination address.
*/
/*
* Set the destination DLSAP to our bound DLSAP value.
*/
/*
* If the destination address was a group address then
* dl_group_address field should be non-zero.
*/
/*
* Copy in the source address.
*/
/*
* Set the source DLSAP to the packet ethertype.
*/
return (nmp);
}
/*
* DL_NOTIFY_IND: DL_NOTE_PROMISC_ON_PHYS
*/
static void
{
return;
return;
}
/*
* DL_NOTIFY_IND: DL_NOTE_PROMISC_OFF_PHYS
*/
static void
{
return;
return;
}
/*
* DL_NOTIFY_IND: DL_NOTE_PHYS_ADDR
*/
static void
{
return;
return;
}
/*
* DL_NOTIFY_IND: DL_NOTE_LINK_UP
*/
static void
{
return;
return;
}
/*
* DL_NOTIFY_IND: DL_NOTE_LINK_DOWN
*/
static void
{
return;
return;
}
/*
* DL_NOTIFY_IND: DL_NOTE_SPEED
*/
static void
{
return;
return;
}
/*
* DL_NOTIFY_IND: DL_NOTE_CAPAB_RENEG
*/
static void
{
return;
return;
}
/*
* MAC notification callback.
*/
static void
{
switch (type) {
case MAC_NOTE_TX:
enableok(q);
qenable(q);
break;
case MAC_NOTE_DEVPROMISC:
/*
* Send the appropriate DL_NOTIFY_IND.
*/
else
break;
case MAC_NOTE_PROMISC:
break;
case MAC_NOTE_UNICST:
/*
* This notification is sent whenever the MAC unicast address
* changes. We need to re-cache the address.
*/
/*
* Send the appropriate DL_NOTIFY_IND.
*/
break;
case MAC_NOTE_LINK:
/*
* This notification is sent every time the MAC driver
* updates the link state.
*/
case LINK_STATE_UP:
/*
* The link is up so send the appropriate
* DL_NOTIFY_IND.
*/
/*
* If we can find the link speed then send a
* DL_NOTIFY_IND for that too.
*/
}
break;
case LINK_STATE_DOWN:
/*
* The link is down so send the appropriate
* DL_NOTIFY_IND.
*/
break;
default:
break;
}
break;
case MAC_NOTE_RESOURCE:
/*
* This notification is sent whenever the MAC resources
* change. We need to renegotiate the capabilities.
* Send the appropriate DL_NOTIFY_IND.
*/
break;
default:
break;
}
}
/*
* Put a chain of packets back on the queue.
*/
static void
{
/*
* Reverse the order of the chain.
*/
}
/*
* Walk the reversed chain and put each message back on the
* queue.
*/
}
}