/*
* 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.
*/
/*
* WiFi MAC Type plugin for the Nemo mac module
*
* This is a bit of mutant since we pretend to be mostly DL_ETHER.
*/
#include <sys/dld_impl.h>
#include <sys/mac_wifi.h>
#include <sys/ethernet.h>
#include <sys/byteorder.h>
/* statistics described in ieee802.11(5) */
};
"WiFi MAC plugin 1.4"
};
};
int
_init(void)
{
int err;
/*
* If `mtrp' is NULL, then this plugin is not compatible with
* the system's MAC Type plugin framework.
*/
return (ENOTSUP);
(void) mactype_unregister(MAC_PLUGIN_IDENT_WIFI);
}
return (err);
}
int
_fini(void)
{
int err;
return (err);
return (mod_remove(&mac_wifi_modlinkage));
}
int
{
}
/*
* MAC Type plugin operations
*/
static boolean_t
{
}
/* ARGSUSED */
static int
{
/* If it's not a group address, then it's a valid unicast address. */
}
/* ARGSUSED */
static int
{
/* The address must be a group address. */
if (!IEEE80211_IS_MULTICAST(addr))
return (EINVAL);
/* The address must not be the media broadcast address. */
return (EINVAL);
return (0);
}
/*
* Verify that `sap' is valid, and return the actual SAP to bind to in
* `*bind_sap'. The WiFI SAP space is identical to Ethernet.
*/
/* ARGSUSED */
static boolean_t
{
return (B_TRUE);
}
*bind_sap = DLS_SAP_LLC;
return (B_TRUE);
}
return (B_FALSE);
}
/*
* Create a template WiFi datalink header for `sap' packets between `saddr'
* and `daddr'. Any enabled modes and features relevant to building the
* header are passed via `pdata'. Return NULL on failure.
*/
/* ARGSUSED */
static mblk_t *
{
return (NULL);
return (NULL);
/*
* Fill in the fixed parts of the ieee80211_frame.
*/
case IEEE80211_M_STA:
break;
case IEEE80211_M_IBSS:
case IEEE80211_M_AHDEMO:
break;
case IEEE80211_M_HOSTAP:
break;
}
(struct ieee80211_qosframe *)wh;
}
switch (wdp->wd_secalloc) {
case WIFI_SEC_WEP:
/*
* Fill in the fixed parts of the WEP-portion of the frame.
*/
/*
* The actual contents of the WEP-portion of the packet
* are computed when the packet is sent -- for now, we
* just need to account for the size.
*/
break;
case WIFI_SEC_WPA:
break;
default:
break;
}
/*
* Fill in the fixed parts of the ieee80211_llc header.
*/
return (mp);
}
/*
* Use the provided `mp' (which is expected to point to a WiFi header), and
* fill in the provided `mhp'. Return an errno on failure.
*/
/* ARGSUSED */
static int
{
return (EINVAL);
/*
* Generally, QoS data field takes 2 bytes, but some special hardware,
* such as Atheros, will need the 802.11 header padded to a 32-bit
* boundary for 4-address and QoS frames, at this time, it's 4 bytes.
*/
/*
* When we receive frames from other hosts, the hardware will have
* already performed WEP decryption, and thus there will not be a WEP
* portion. However, when we receive a loopback copy of our own
* packets, it will still have a WEP portion. Skip past it to get to
* the LLC header.
*/
}
sizeof (struct ieee80211_llc))
return (EINVAL);
mhp->mhi_pktsize = 0;
/*
* Verify the LLC header is one of the known formats. As per MSFT's
* convention, if the header is using IEEE 802.1H encapsulation, then
* treat the LLC header as data. As per DL_ETHER custom when treating
* the LLC header as data, set the mhi_bindsap to be DLS_SAP_LLC, and
* assume mhi_origsap contains the data length.
*/
return (EINVAL);
}
case IEEE80211_FC1_DIR_NODS:
break;
case IEEE80211_FC1_DIR_TODS:
break;
case IEEE80211_FC1_DIR_FROMDS:
break;
case IEEE80211_FC1_DIR_DSTODS:
/* We don't support AP-to-AP mode yet */
return (ENOTSUP);
}
else
return (0);
}
/*
* Take the provided `mp' (which is expected to have an Ethernet header), and
* return a pointer to an mblk_t with a WiFi header. Note that the returned
* header will not be complete until the driver finishes filling it in prior
* to transmit. If the conversion cannot be performed, return NULL.
*/
static mblk_t *
{
return (NULL);
return (NULL);
/*
* The plugin framework guarantees that we have the only reference
* to the mblk_t, so we can safely modify it.
*/
return (llmp);
}
/*
* Take the provided `mp' (which is expected to have a WiFi header), and
* return a pointer to an mblk_t with an Ethernet header. If the conversion
* cannot be performed, return NULL.
*/
static mblk_t *
{
/*
* The plugin framework guarantees the header is properly
* formed, so this should never happen.
*/
return (NULL);
}
/*
* The plugin framework guarantees that we have the only reference to
* the mblk_t and the underlying dblk_t, so we can safely modify it.
*/
return (mp);
}
};