1e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 2*0dc2366fSVenugopal Iyer * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 3e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Use is subject to license terms. 4e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 5e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 6e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 7e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Copyright (c) 2007 by Lukas Turek <turek@ksvi.mff.cuni.cz> 8e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Copyright (c) 2007 by Jiri Svoboda <jirik.svoboda@seznam.cz> 9e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Copyright (c) 2007 by Martin Krulis <martin.krulis@matfyz.cz> 10e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr> 11e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Copyright (c) 2006 by Florian Stoehr <ich@florian-stoehr.de> 12e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 13e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Permission to use, copy, modify, and distribute this software for any 14e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * purpose with or without fee is hereby granted, provided that the above 15e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * copyright notice and this permission notice appear in all copies. 16e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 17e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 18e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 19e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 20e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 21e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 22e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 23e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 24e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 25e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 26e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 27e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 28e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * ZD1211 wLAN driver 29e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Driver major routines 30e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 31e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 32e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include <sys/byteorder.h> 33e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include <sys/ddi.h> 34e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include <sys/sunddi.h> 35e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include <sys/conf.h> 36e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include <sys/modctl.h> 37e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include <sys/mac_provider.h> 38e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include <sys/mac_wifi.h> 39e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include <sys/strsun.h> 40e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include <sys/ksynch.h> 41e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 42e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include "zyd.h" 43e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #include "zyd_reg.h" 44e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 45e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int zyd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 46e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int zyd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 47e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 48e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int zyd_m_stat(void *arg, uint_t stat, uint64_t *val); 49e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int zyd_m_start(void *arg); 50e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static void zyd_m_stop(void *arg); 51e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int zyd_m_unicst(void *arg, const uint8_t *macaddr); 52e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int zyd_m_multicst(void *arg, boolean_t add, const uint8_t *m); 53e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int zyd_m_promisc(void *arg, boolean_t on); 54e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static void zyd_m_ioctl(void *arg, queue_t *wq, mblk_t *mp); 55e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static mblk_t *zyd_m_tx(void *arg, mblk_t *mp); 56e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int zyd_m_getprop(void *arg, const char *pr_name, 57*0dc2366fSVenugopal Iyer mac_prop_id_t wldp_pr_num, uint_t wldp_length, void *wldp_buf); 58*0dc2366fSVenugopal Iyer static void zyd_m_propinfo(void *arg, const char *pr_name, 59*0dc2366fSVenugopal Iyer mac_prop_id_t wldp_pr_num, mac_prop_info_handle_t mph); 60e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int zyd_m_setprop(void *arg, const char *pr_name, 61e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mac_prop_id_t wldp_pr_num, uint_t wldp_length, const void *wldp_buf); 62e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 63e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int zyd_newstate(struct ieee80211com *ic, 64e8da18d8Spengcheng chen - Sun Microsystems - Beijing China enum ieee80211_state state, int arg); 65e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 66e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Driver identification */ 67e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static char zyd_ident[] = ZYD_DRV_DESC " " ZYD_DRV_REV; 68e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 69e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Global state pointer for managing per-device soft states */ 70e8da18d8Spengcheng chen - Sun Microsystems - Beijing China void *zyd_ssp; 71e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 72e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 73e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Mac Call Back entries 74e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 75e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static mac_callbacks_t zyd_m_callbacks = { 76*0dc2366fSVenugopal Iyer MC_IOCTL | MC_SETPROP | MC_GETPROP | MC_PROPINFO, 77e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_stat, /* Get the value of a statistic */ 78e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_start, /* Start the device */ 79e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_stop, /* Stop the device */ 80e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_promisc, /* Enable or disable promiscuous mode */ 81e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_multicst, /* Enable or disable a multicast addr */ 82e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_unicst, /* Set the unicast MAC address */ 83e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_tx, /* Transmit a packet */ 84*0dc2366fSVenugopal Iyer NULL, 85e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_ioctl, /* Process an unknown ioctl */ 86e8da18d8Spengcheng chen - Sun Microsystems - Beijing China NULL, /* mc_getcapab */ 87e8da18d8Spengcheng chen - Sun Microsystems - Beijing China NULL, 88e8da18d8Spengcheng chen - Sun Microsystems - Beijing China NULL, 89e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_setprop, 90*0dc2366fSVenugopal Iyer zyd_m_getprop, 91*0dc2366fSVenugopal Iyer zyd_m_propinfo 92e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }; 93e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 94e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 95e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Module Loading Data & Entry Points 96e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 97e8da18d8Spengcheng chen - Sun Microsystems - Beijing China DDI_DEFINE_STREAM_OPS(zyd_devops, /* name */ 98e8da18d8Spengcheng chen - Sun Microsystems - Beijing China nulldev, /* identify */ 99e8da18d8Spengcheng chen - Sun Microsystems - Beijing China nulldev, /* probe */ 100e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_attach, /* attach */ 101e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_detach, /* detach */ 102e8da18d8Spengcheng chen - Sun Microsystems - Beijing China nodev, /* reset */ 103e8da18d8Spengcheng chen - Sun Microsystems - Beijing China NULL, /* getinfo */ 104e8da18d8Spengcheng chen - Sun Microsystems - Beijing China D_MP, /* flag */ 105e8da18d8Spengcheng chen - Sun Microsystems - Beijing China NULL, /* stream_tab */ 106e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ddi_quiesce_not_needed /* quiesce */ 107e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ); 108e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 109e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static struct modldrv zyd_modldrv = { 110e8da18d8Spengcheng chen - Sun Microsystems - Beijing China &mod_driverops, /* drv_modops */ 111e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_ident, /* drv_linkinfo */ 112e8da18d8Spengcheng chen - Sun Microsystems - Beijing China &zyd_devops /* drv_dev_ops */ 113e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }; 114e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 115e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static struct modlinkage zyd_ml = { 116e8da18d8Spengcheng chen - Sun Microsystems - Beijing China MODREV_1, /* ml_rev */ 117e8da18d8Spengcheng chen - Sun Microsystems - Beijing China {&zyd_modldrv, NULL} /* ml_linkage */ 118e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }; 119e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 120e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 121e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Wireless-specific structures 122e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 123e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static const struct ieee80211_rateset zyd_rateset_11b = { 124e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 4, {2, 4, 11, 22} /* units are 0.5Mbit! */ 125e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }; 126e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 127e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static const struct ieee80211_rateset zyd_rateset_11g = { 128e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 12, {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108} 129e8da18d8Spengcheng chen - Sun Microsystems - Beijing China }; 130e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 131e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 132e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #ifdef DEBUG 133e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint32_t zyd_dbg_flags; 134e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 135e8da18d8Spengcheng chen - Sun Microsystems - Beijing China void 136e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_dbg(uint32_t dbg_mask, const int8_t *fmt, ...) 137e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 138e8da18d8Spengcheng chen - Sun Microsystems - Beijing China va_list args; 139e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 140e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (dbg_mask & zyd_dbg_flags) { 141e8da18d8Spengcheng chen - Sun Microsystems - Beijing China va_start(args, fmt); 142e8da18d8Spengcheng chen - Sun Microsystems - Beijing China vcmn_err(CE_CONT, fmt, args); 143e8da18d8Spengcheng chen - Sun Microsystems - Beijing China va_end(args); 144e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 145e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 146e8da18d8Spengcheng chen - Sun Microsystems - Beijing China #endif 147e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 148e8da18d8Spengcheng chen - Sun Microsystems - Beijing China void 149e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_warn(const int8_t *fmt, ...) 150e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 151e8da18d8Spengcheng chen - Sun Microsystems - Beijing China va_list args; 152e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 153e8da18d8Spengcheng chen - Sun Microsystems - Beijing China va_start(args, fmt); 154e8da18d8Spengcheng chen - Sun Microsystems - Beijing China vcmn_err(CE_WARN, fmt, args); 155e8da18d8Spengcheng chen - Sun Microsystems - Beijing China va_end(args); 156e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 157e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 158e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 159e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Internal functions 160e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 161e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static uint8_t 162e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_plcp_signal(uint16_t rate) 163e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 164e8da18d8Spengcheng chen - Sun Microsystems - Beijing China switch (rate) { 165e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* CCK rates (returned values are device-dependent) */ 166e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case 2: 167e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (0x0); 168e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case 4: 169e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (0x1); 170e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case 11: 171e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (0x2); 172e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case 22: 173e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (0x3); 174e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 175e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 176e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case 12: 177e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (0xb); 178e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case 18: 179e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (0xf); 180e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case 24: 181e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (0xa); 182e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case 36: 183e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (0xe); 184e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case 48: 185e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (0x9); 186e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case 72: 187e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (0xd); 188e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case 96: 189e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (0x8); 190e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case 108: 191e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (0xc); 192e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 193e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* unsupported rates (should not get there) */ 194e8da18d8Spengcheng chen - Sun Microsystems - Beijing China default: 195e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (0xff); 196e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 197e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 198e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 199e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 200e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Timeout function for scanning. 201e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 202e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Called at the end of each scanning round. 203e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 204e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static void 205e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_next_scan(void *arg) 206e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 207e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_softc *sc = arg; 208e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->ic; 209e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 210e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_SCAN, "scan timer: fired\n")); 211e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 212e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (ic->ic_state == IEEE80211_S_SCAN) { 213e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_next_scan(ic); 214e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } else { 215e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_SCAN, "scan timer: no work\n")); 216e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 217e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 218e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 219e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 220e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Extract a 802.11 frame from the received packet and forward it to net80211. 221e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 222e8da18d8Spengcheng chen - Sun Microsystems - Beijing China void 223e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_receive(struct zyd_softc *sc, const uint8_t *buf, uint16_t len) 224e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 225e8da18d8Spengcheng chen - Sun Microsystems - Beijing China const struct zyd_rx_stat *stat; 226e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->ic; 227e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct ieee80211_frame *wh; 228e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct ieee80211_node *in; 229e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int rlen; /* Actual frame length */ 230e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint8_t rssi; 231e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mblk_t *m; 232e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 233e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (len < ZYD_MIN_FRAGSZ) { 234e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Packet is too short, silently drop it */ 235e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->rx_err++; 236e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return; 237e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 238e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 239e8da18d8Spengcheng chen - Sun Microsystems - Beijing China stat = (const struct zyd_rx_stat *) 240e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (buf + len - sizeof (struct zyd_rx_stat)); 241e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (stat->flags & ZYD_RX_ERROR) { 242e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Frame is corrupted, silently drop it */ 243e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->rx_err++; 244e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return; 245e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 246e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 247e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* compute actual frame length */ 248e8da18d8Spengcheng chen - Sun Microsystems - Beijing China rlen = len - sizeof (struct zyd_plcphdr) - 249e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sizeof (struct zyd_rx_stat) - IEEE80211_CRC_LEN; 250e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 251e8da18d8Spengcheng chen - Sun Microsystems - Beijing China m = allocb(rlen, BPRI_MED); 252e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (m == NULL) { 253e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->rx_nobuf++; 254e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return; 255e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 256e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 257e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Copy frame to new buffer */ 258e8da18d8Spengcheng chen - Sun Microsystems - Beijing China bcopy(buf + sizeof (struct zyd_plcphdr), m->b_wptr, rlen); 259e8da18d8Spengcheng chen - Sun Microsystems - Beijing China m->b_wptr += rlen; 260e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 261e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Send frame to net80211 stack */ 262e8da18d8Spengcheng chen - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)m->b_rptr; 263e8da18d8Spengcheng chen - Sun Microsystems - Beijing China in = ieee80211_find_rxnode(ic, wh); 264e8da18d8Spengcheng chen - Sun Microsystems - Beijing China rssi = (stat->rssi < 25) ? 230 : (255 - stat->rssi) / 2; 265e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 266e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) ieee80211_input(ic, m, in, (int32_t)rssi, 0); 267e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 268e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_free_node(in); 269e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 270e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 271e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 272e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * xxx_send callback for net80211. 273e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 274e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Transmit a 802.11 frame. 275e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 276e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Constructs a packet from zyd_tx_header and 802.11 frame data 277e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * and sends it to the chip. 278e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 279e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*ARGSUSED*/ 280e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int 281e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type) 282e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 283e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_softc *sc = ZYD_IC_TO_SOFTC(ic); 284e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_tx_header *buf_hdr; 285e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct ieee80211_frame *wh; 286e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct ieee80211_node *in; 287e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct ieee80211_key *k; 288e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mblk_t *m, *m0; 289e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int len, off, mblen; 290e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint16_t frame_size, additional_size, rate; 291e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint8_t service; 292e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int res; 293e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 294e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(mp->b_next == NULL); 295e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 296e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* device not ready, drop all frames */ 297e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (!sc->usb.connected || sc->suspended || !sc->running) { 298e8da18d8Spengcheng chen - Sun Microsystems - Beijing China freemsg(mp); 299e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (type == IEEE80211_FC0_TYPE_DATA) 300e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS); 301e8da18d8Spengcheng chen - Sun Microsystems - Beijing China else 302e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE); 303e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 304e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 305e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* device queue overrun */ 306e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (sc->tx_queued >= ZYD_TX_LIST_COUNT) { 307e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* drop management frames */ 308e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (type != IEEE80211_FC0_TYPE_DATA) { 309e8da18d8Spengcheng chen - Sun Microsystems - Beijing China freemsg(mp); 310e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } else { 311e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) zyd_serial_enter(sc, ZYD_NO_SIG); 312e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->resched = B_TRUE; 313e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(sc); 314e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 315e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE); 316e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 317e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 318e8da18d8Spengcheng chen - Sun Microsystems - Beijing China m = allocb(msgdsize(mp) + sizeof (struct zyd_tx_header) + 32, 319e8da18d8Spengcheng chen - Sun Microsystems - Beijing China BPRI_MED); 320e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (m == NULL) { 321e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->tx_nobuf++; 322e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) zyd_serial_enter(sc, ZYD_NO_SIG); 323e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->resched = B_TRUE; 324e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(sc); 325e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE); 326e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 327e8da18d8Spengcheng chen - Sun Microsystems - Beijing China m->b_rptr += sizeof (struct zyd_tx_header); 328e8da18d8Spengcheng chen - Sun Microsystems - Beijing China m->b_wptr = m->b_rptr; 329e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 330e8da18d8Spengcheng chen - Sun Microsystems - Beijing China for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) { 331e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mblen = MBLKL(m0); 332e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) memcpy(m->b_rptr + off, m0->b_rptr, mblen); 333e8da18d8Spengcheng chen - Sun Microsystems - Beijing China off += mblen; 334e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 335e8da18d8Spengcheng chen - Sun Microsystems - Beijing China m->b_wptr += off; 336e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 337e8da18d8Spengcheng chen - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)m->b_rptr; 338e8da18d8Spengcheng chen - Sun Microsystems - Beijing China in = ieee80211_find_txnode(ic, wh->i_addr1); 339e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 340e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (in == NULL) { 341e8da18d8Spengcheng chen - Sun Microsystems - Beijing China freemsg(m); 342e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->tx_err++; 343e8da18d8Spengcheng chen - Sun Microsystems - Beijing China freemsg(mp); 344e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS); 345e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 346e8da18d8Spengcheng chen - Sun Microsystems - Beijing China in->in_inact = 0; 347e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 348e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (type == IEEE80211_FC0_TYPE_DATA) 349e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) ieee80211_encap(ic, m, in); 350e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 351e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 352e8da18d8Spengcheng chen - Sun Microsystems - Beijing China k = ieee80211_crypto_encap(ic, m); 353e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (k == NULL) { 354e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->tx_err++; 355e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_free_node(in); 356e8da18d8Spengcheng chen - Sun Microsystems - Beijing China freemsg(m); 357e8da18d8Spengcheng chen - Sun Microsystems - Beijing China freemsg(mp); 358e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS); 359e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 360e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* packet header may have moved, reset our local pointer */ 361e8da18d8Spengcheng chen - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)m->b_rptr; 362e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 363e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 364e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 365e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * pickup a rate. May need work to make adaptive - at present, 366e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * picks best rate for mode. 367e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 368e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (type == IEEE80211_FC0_TYPE_MGT) { 369e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* mgmt frames are sent at 1M */ 370e8da18d8Spengcheng chen - Sun Microsystems - Beijing China rate = (uint16_t)in->in_rates.ir_rates[0]; 371e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } else if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) { 372e8da18d8Spengcheng chen - Sun Microsystems - Beijing China rate = (uint16_t)ic->ic_sup_rates[ic->ic_curmode]. 373e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ir_rates[ic->ic_fixed_rate]; 374e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } else { 375e8da18d8Spengcheng chen - Sun Microsystems - Beijing China rate = (uint16_t)ic->ic_sup_rates[ic->ic_curmode]. 376e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ir_rates[in->in_txrate]; 377e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 378e8da18d8Spengcheng chen - Sun Microsystems - Beijing China rate &= IEEE80211_RATE_VAL; 379e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (rate == 0) /* should not happen */ 380e8da18d8Spengcheng chen - Sun Microsystems - Beijing China rate = 2; 381e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 382e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Get total length of frame */ 383e8da18d8Spengcheng chen - Sun Microsystems - Beijing China len = msgsize(m); 384e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 385e8da18d8Spengcheng chen - Sun Microsystems - Beijing China m->b_rptr -= sizeof (struct zyd_tx_header); 386e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr = (struct zyd_tx_header *)m->b_rptr; 387e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 388e8da18d8Spengcheng chen - Sun Microsystems - Beijing China frame_size = (uint16_t)len + 4; /* include CRC32 */ 389e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->frame_size = LE_16(frame_size); 390e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 391e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 392e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Compute "packet size". What the 10 stands for, 393e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * nobody knows. 394e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 395e8da18d8Spengcheng chen - Sun Microsystems - Beijing China additional_size = sizeof (struct zyd_tx_header) + 10; 396e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (sc->mac_rev == ZYD_ZD1211) 397e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->packet_size = LE_16(frame_size + additional_size); 398e8da18d8Spengcheng chen - Sun Microsystems - Beijing China else 399e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->packet_size = LE_16(additional_size); 400e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 401e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->rate_mod_flags = LE_8(zyd_plcp_signal(rate)); 402e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->type_flags = LE_8(ZYD_TX_FLAG_BACKOFF); 403e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 404e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* multicast frames are not sent at OFDM rates in 802.11b/g */ 405e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (frame_size > ic->ic_rtsthreshold) { 406e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->type_flags |= ZYD_TX_FLAG_RTS; 407e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } else if (ZYD_RATE_IS_OFDM(rate) && 408e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (ic->ic_flags & IEEE80211_F_USEPROT)) { 409e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) 410e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->type_flags |= 411e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_TX_FLAG_CTS_TO_SELF; 412e8da18d8Spengcheng chen - Sun Microsystems - Beijing China else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) 413e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->type_flags |= ZYD_TX_FLAG_RTS; 414e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 415e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } else 416e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->type_flags |= ZYD_TX_FLAG_MULTICAST; 417e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 418e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if ((type == IEEE80211_FC0_TYPE_CTL) && 419e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) 420e8da18d8Spengcheng chen - Sun Microsystems - Beijing China == IEEE80211_FC0_SUBTYPE_PS_POLL) 421e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->type_flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL); 422e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 423e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (ZYD_RATE_IS_OFDM(rate)) { 424e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->rate_mod_flags |= ZYD_TX_RMF_OFDM; 425e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (ic->ic_curmode == IEEE80211_MODE_11A) 426e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->rate_mod_flags |= ZYD_TX_RMF_5GHZ; 427e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) 428e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->rate_mod_flags |= ZYD_TX_RMF_SH_PREAMBLE; 429e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 430e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 431e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Compute frame duration and length-extension service flag. 432e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 433e8da18d8Spengcheng chen - Sun Microsystems - Beijing China service = 0x00; 434e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 435e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->frame_duration = LE_16((16 * frame_size + rate - 1) / rate); 436e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->service = service; 437e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->next_frame_duration = LE_16(0); 438e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 439e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (rate == 22) { 440e8da18d8Spengcheng chen - Sun Microsystems - Beijing China const int remainder = (16 * frame_size) % 22; 441e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (remainder != 0 && remainder < 7) 442e8da18d8Spengcheng chen - Sun Microsystems - Beijing China buf_hdr->service |= ZYD_TX_SERVICE_LENGTH_EXTENSION; 443e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 444e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 445e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = zyd_usb_send_packet(&sc->usb, m); 446e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (res != ZYD_SUCCESS) { 447e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->tx_err++; 448e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } else { 449e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) zyd_serial_enter(sc, ZYD_NO_SIG); 450e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->tx_queued++; 451e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(sc); 452e8da18d8Spengcheng chen - Sun Microsystems - Beijing China freemsg(mp); 453e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ic->ic_stats.is_tx_frags++; 454e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ic->ic_stats.is_tx_bytes += len; 455e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 456e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 457e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_free_node(in); 458e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 459e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS); 460e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 461e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 462e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 463e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Register with the MAC layer. 464e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 465e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static zyd_res 466e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_mac_init(struct zyd_softc *sc) 467e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 468e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->ic; 469e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mac_register_t *macp; 470e8da18d8Spengcheng chen - Sun Microsystems - Beijing China wifi_data_t wd = { 0 }; 471e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int err; 472e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 473e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 474e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Initialize mac structure 475e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 476e8da18d8Spengcheng chen - Sun Microsystems - Beijing China macp = mac_alloc(MAC_VERSION); 477e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (macp == NULL) { 478e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to allocate MAC structure\n"); 479e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE); 480e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 481e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 482e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 483e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Initialize pointer to device specific functions 484e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 485e8da18d8Spengcheng chen - Sun Microsystems - Beijing China wd.wd_secalloc = WIFI_SEC_NONE; 486e8da18d8Spengcheng chen - Sun Microsystems - Beijing China wd.wd_opmode = sc->ic.ic_opmode; 487e8da18d8Spengcheng chen - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_macaddr); 488e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 489e8da18d8Spengcheng chen - Sun Microsystems - Beijing China macp->m_type_ident = MAC_PLUGIN_IDENT_WIFI; 490e8da18d8Spengcheng chen - Sun Microsystems - Beijing China macp->m_driver = sc; 491e8da18d8Spengcheng chen - Sun Microsystems - Beijing China macp->m_dip = sc->dip; 492e8da18d8Spengcheng chen - Sun Microsystems - Beijing China macp->m_src_addr = ic->ic_macaddr; 493e8da18d8Spengcheng chen - Sun Microsystems - Beijing China macp->m_callbacks = &zyd_m_callbacks; 494e8da18d8Spengcheng chen - Sun Microsystems - Beijing China macp->m_min_sdu = 0; 495e8da18d8Spengcheng chen - Sun Microsystems - Beijing China macp->m_max_sdu = IEEE80211_MTU; 496e8da18d8Spengcheng chen - Sun Microsystems - Beijing China macp->m_pdata = &wd; 497e8da18d8Spengcheng chen - Sun Microsystems - Beijing China macp->m_pdata_size = sizeof (wd); 498e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 499e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 500e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Register the macp to mac 501e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 502e8da18d8Spengcheng chen - Sun Microsystems - Beijing China err = mac_register(macp, &sc->ic.ic_mach); 503e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mac_free(macp); 504e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 505e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 506e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to register MAC structure\n"); 507e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_FAILURE); 508e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 509e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 510e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ZYD_SUCCESS); 511e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 512e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 513e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 514e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Register with net80211. 515e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 516e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static void 517e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_wifi_init(struct zyd_softc *sc) 518e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 519e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->ic; 520e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int i; 521e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 522e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 523e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Initialize the WiFi part, which will be used by generic layer 524e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 525e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ic->ic_phytype = IEEE80211_T_OFDM; 526e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ic->ic_opmode = IEEE80211_M_STA; 527e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ic->ic_state = IEEE80211_S_INIT; 528e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ic->ic_maxrssi = 255; 529e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ic->ic_xmit = zyd_send; 530e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 531e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* set device capabilities */ 532e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ic->ic_caps = IEEE80211_C_TXPMGT | /* tx power management */ 533e8da18d8Spengcheng chen - Sun Microsystems - Beijing China IEEE80211_C_SHPREAMBLE | /* short preamble supported */ 534e8da18d8Spengcheng chen - Sun Microsystems - Beijing China IEEE80211_C_SHSLOT | IEEE80211_C_WPA; /* Support WPA/WPA2 */ 535e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 536e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Copy MAC address */ 537e8da18d8Spengcheng chen - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(ic->ic_macaddr, sc->macaddr); 538e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 539e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 540e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * set supported .11b and .11g rates 541e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 542e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ic->ic_sup_rates[IEEE80211_MODE_11B] = zyd_rateset_11b; 543e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ic->ic_sup_rates[IEEE80211_MODE_11G] = zyd_rateset_11g; 544e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 545e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 546e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * set supported .11b and .11g channels(1 through 14) 547e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 548e8da18d8Spengcheng chen - Sun Microsystems - Beijing China for (i = 1; i <= 14; i++) { 549e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ic->ic_sup_channels[i].ich_freq = 550e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); 551e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ic->ic_sup_channels[i].ich_flags = 552e8da18d8Spengcheng chen - Sun Microsystems - Beijing China IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | 553e8da18d8Spengcheng chen - Sun Microsystems - Beijing China IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; 554e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 555e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 556e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 557e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Init generic layer (it cannot fail) 558e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 559e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_attach(ic); 560e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 561e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* register WPA door */ 562e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_register_door(ic, ddi_driver_name(sc->dip), 563e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ddi_get_instance(sc->dip)); 564e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 565e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Must be after attach! */ 566e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->newstate = ic->ic_newstate; 567e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ic->ic_newstate = zyd_newstate; 568e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 569e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_media_init(ic); 570e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ic->ic_def_txkey = 0; 571e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 572e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 573e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 574e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Device operations 575e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 576e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 577e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Binding the driver to a device. 578e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 579e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Concurrency: Until zyd_attach() returns with success, 580e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * the only other entry point that can be executed is getinfo(). 581e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Thus no locking here yet. 582e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 583e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int 584e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 585e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 586e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_softc *sc; 587e8da18d8Spengcheng chen - Sun Microsystems - Beijing China char strbuf[32]; 588e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int instance; 589e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int err; 590e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 591e8da18d8Spengcheng chen - Sun Microsystems - Beijing China switch (cmd) { 592e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case DDI_ATTACH: 593e8da18d8Spengcheng chen - Sun Microsystems - Beijing China break; 594e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 595e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case DDI_RESUME: 596e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc = ddi_get_soft_state(zyd_ssp, ddi_get_instance(dip)); 597e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(sc != NULL); 598e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 599e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) zyd_resume(sc); 600e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS); 601e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 602e8da18d8Spengcheng chen - Sun Microsystems - Beijing China default: 603e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE); 604e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 605e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 606e8da18d8Spengcheng chen - Sun Microsystems - Beijing China instance = ddi_get_instance(dip); 607e8da18d8Spengcheng chen - Sun Microsystems - Beijing China err = ddi_soft_state_zalloc(zyd_ssp, instance); 608e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 609e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 610e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to allocate soft state\n"); 611e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE); 612e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 613e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 614e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc = ddi_get_soft_state(zyd_ssp, instance); 615e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->dip = dip; 616e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->timeout_id = 0; 617e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 618e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_usb_init(sc) != ZYD_SUCCESS) { 619e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ddi_soft_state_free(zyd_ssp, instance); 620e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE); 621e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 622e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 623e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_hw_init(sc) != ZYD_SUCCESS) { 624e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_deinit(sc); 625e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ddi_soft_state_free(zyd_ssp, instance); 626e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE); 627e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 628e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 629e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_wifi_init(sc); 630e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 631e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_mac_init(sc) != DDI_SUCCESS) { 632e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_detach(&sc->ic); 633e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_deinit(sc); 634e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ddi_soft_state_free(zyd_ssp, instance); 635e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE); 636e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 637e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 638e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 639e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Create minor node of type DDI_NT_NET_WIFI 640e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 641e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) snprintf(strbuf, sizeof (strbuf), ZYD_DRV_NAME"%d", instance); 642e8da18d8Spengcheng chen - Sun Microsystems - Beijing China err = ddi_create_minor_node(dip, strbuf, S_IFCHR, 643e8da18d8Spengcheng chen - Sun Microsystems - Beijing China instance + 1, DDI_NT_NET_WIFI, 0); 644e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) 645e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("failed to create minor node\n"); 646e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 647e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* initialize locking */ 648e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_init(sc); 649e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 650e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS); 651e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 652e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 653e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 654e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Detach the driver from a device. 655e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 656e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Concurrency: Will be called only after a successful attach 657e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * (and not concurrently). 658e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 659e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int 660e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 661e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 662e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_softc *sc = NULL; 663e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 664e8da18d8Spengcheng chen - Sun Microsystems - Beijing China switch (cmd) { 665e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case DDI_DETACH: 666e8da18d8Spengcheng chen - Sun Microsystems - Beijing China break; 667e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 668e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case DDI_SUSPEND: 669e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc = ddi_get_soft_state(zyd_ssp, ddi_get_instance(dip)); 670e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(sc != NULL); 671e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 672e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (zyd_suspend(sc)); 673e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 674e8da18d8Spengcheng chen - Sun Microsystems - Beijing China default: 675e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE); 676e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 677e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 678e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc = ddi_get_soft_state(zyd_ssp, ddi_get_instance(dip)); 679e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(sc != NULL); 680e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 681e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (mac_disable(sc->ic.ic_mach) != 0) 682e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE); 683e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 684e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Unregister from the MAC layer subsystem 685e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 686e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) mac_unregister(sc->ic.ic_mach); 687e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 688e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 689e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Detach ieee80211 690e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 691e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_detach(&sc->ic); 692e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 693e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_hw_deinit(sc); 694e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_usb_deinit(sc); 695e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 696e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* At this point it should be safe to release & destroy the locks */ 697e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_deinit(sc); 698e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 699e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ddi_remove_minor_node(dip, NULL); 700e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ddi_soft_state_free(zyd_ssp, ddi_get_instance(dip)); 701e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS); 702e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 703e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 704e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 705e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Mac Call Back functions 706e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 707e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 708e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 709e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Read device statistic information. 710e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 711e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int 712e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_stat(void *arg, uint_t stat, uint64_t *val) 713e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 714e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_softc *sc = (struct zyd_softc *)arg; 715e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211com_t *ic = &sc->ic; 716e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_node_t *in; 717e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 718e8da18d8Spengcheng chen - Sun Microsystems - Beijing China switch (stat) { 719e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case MAC_STAT_IFSPEED: 720e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (!sc->usb.connected || sc->suspended || !sc->running) 721e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ENOTSUP); 722e8da18d8Spengcheng chen - Sun Microsystems - Beijing China in = ieee80211_ref_node(ic->ic_bss); 723e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ? 724e8da18d8Spengcheng chen - Sun Microsystems - Beijing China IEEE80211_RATE(in->in_txrate) : 725e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ic->ic_fixed_rate) / 2 * 1000000; 726e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_free_node(in); 727e8da18d8Spengcheng chen - Sun Microsystems - Beijing China break; 728e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case MAC_STAT_NOXMTBUF: 729e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *val = sc->tx_nobuf; 730e8da18d8Spengcheng chen - Sun Microsystems - Beijing China break; 731e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case MAC_STAT_NORCVBUF: 732e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *val = sc->rx_nobuf; 733e8da18d8Spengcheng chen - Sun Microsystems - Beijing China break; 734e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case MAC_STAT_IERRORS: 735e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *val = sc->rx_err; 736e8da18d8Spengcheng chen - Sun Microsystems - Beijing China break; 737e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case MAC_STAT_RBYTES: 738e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *val = ic->ic_stats.is_rx_bytes; 739e8da18d8Spengcheng chen - Sun Microsystems - Beijing China break; 740e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case MAC_STAT_IPACKETS: 741e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *val = ic->ic_stats.is_rx_frags; 742e8da18d8Spengcheng chen - Sun Microsystems - Beijing China break; 743e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case MAC_STAT_OBYTES: 744e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *val = ic->ic_stats.is_tx_bytes; 745e8da18d8Spengcheng chen - Sun Microsystems - Beijing China break; 746e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case MAC_STAT_OPACKETS: 747e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *val = ic->ic_stats.is_tx_frags; 748e8da18d8Spengcheng chen - Sun Microsystems - Beijing China break; 749e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case MAC_STAT_OERRORS: 750e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case WIFI_STAT_TX_FAILED: 751e8da18d8Spengcheng chen - Sun Microsystems - Beijing China *val = sc->tx_err; 752e8da18d8Spengcheng chen - Sun Microsystems - Beijing China break; 753e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case WIFI_STAT_TX_RETRANS: 754e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case WIFI_STAT_FCS_ERRORS: 755e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case WIFI_STAT_WEP_ERRORS: 756e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case WIFI_STAT_TX_FRAGS: 757e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case WIFI_STAT_MCAST_TX: 758e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case WIFI_STAT_RTS_SUCCESS: 759e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case WIFI_STAT_RTS_FAILURE: 760e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case WIFI_STAT_ACK_FAILURE: 761e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case WIFI_STAT_RX_FRAGS: 762e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case WIFI_STAT_MCAST_RX: 763e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case WIFI_STAT_RX_DUPS: 764e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ieee80211_stat(ic, stat, val)); 765e8da18d8Spengcheng chen - Sun Microsystems - Beijing China default: 766e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ENOTSUP); 767e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 768e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (0); 769e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 770e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 771e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 772e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Start the device. 773e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 774e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Concurrency: Presumably fully concurrent, must lock. 775e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 776e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int 777e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_start(void *arg) 778e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 779e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_softc *sc = (struct zyd_softc *)arg; 780e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 781e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) zyd_serial_enter(sc, ZYD_NO_SIG); 782e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if ((!sc->usb.connected) || (zyd_hw_start(sc) != ZYD_SUCCESS)) { 783e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(sc); 784e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE); 785e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 786e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(sc); 787e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 788e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_new_state(&sc->ic, IEEE80211_S_INIT, -1); 789e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->running = B_TRUE; 790e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 791e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS); 792e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 793e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 794e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 795e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Stop the device. 796e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 797e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static void 798e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_stop(void *arg) 799e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 800e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_softc *sc = (struct zyd_softc *)arg; 801e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 802e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->running = B_FALSE; 803e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_new_state(&sc->ic, IEEE80211_S_INIT, -1); 804e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 805e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) zyd_serial_enter(sc, ZYD_NO_SIG); 806e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->resched = B_FALSE; 807e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_hw_stop(sc); 808e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(sc); 809e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 810e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 811e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 812e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Change the MAC address of the device. 813e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 814e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*ARGSUSED*/ 815e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int 816e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_unicst(void *arg, const uint8_t *macaddr) 817e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 818e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE); 819e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 820e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 821e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 822e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Enable/disable multicast. 823e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 824e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*ARGSUSED*/ 825e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int 826e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_multicst(void *arg, boolean_t add, const uint8_t *m) 827e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 828e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_GLD, "multicast not implemented\n")); 829e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS); 830e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 831e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 832e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 833e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Enable/disable promiscuous mode. 834e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 835e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*ARGSUSED*/ 836e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int 837e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_promisc(void *arg, boolean_t on) 838e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 839e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_GLD, "promiscuous not implemented\n")); 840e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS); 841e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 842e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 843e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 844e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * IOCTL request. 845e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 846e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static void 847e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_ioctl(void *arg, queue_t *wq, mblk_t *mp) 848e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 849e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_softc *sc = (struct zyd_softc *)arg; 850e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->ic; 851e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 852e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (!sc->usb.connected || sc->suspended || !sc->running) { 853e8da18d8Spengcheng chen - Sun Microsystems - Beijing China miocnak(wq, mp, 0, ENXIO); 854e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return; 855e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 856e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 857e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (ieee80211_ioctl(ic, wq, mp) == ENETRESET) { 858e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (sc->running && ic->ic_des_esslen) { 859e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_stop(sc); 860e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_m_start(sc) != DDI_SUCCESS) 861e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return; 862e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 863e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 864e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 865e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 866e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 867e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 868e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * callback functions for /get/set properties 869e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 870e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int 871e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 872e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint_t wldp_length, const void *wldp_buf) 873e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 874e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_softc *sc = (struct zyd_softc *)arg; 875e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->ic; 876e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int err; 877e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 878e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (!sc->usb.connected || sc->suspended || !sc->running) { 879e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (ENXIO); 880e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 881e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 882e8da18d8Spengcheng chen - Sun Microsystems - Beijing China err = ieee80211_setprop(ic, pr_name, wldp_pr_num, wldp_length, 883e8da18d8Spengcheng chen - Sun Microsystems - Beijing China wldp_buf); 884e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (err == ENETRESET) { 885e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (sc->running && ic->ic_des_esslen) { 886e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_stop(sc); 887e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_m_start(sc) != DDI_SUCCESS) 888e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE); 889e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 890e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 891e8da18d8Spengcheng chen - Sun Microsystems - Beijing China err = 0; 892e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 893e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 894e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (err); 895e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 896e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 897e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int 898e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 899*0dc2366fSVenugopal Iyer uint_t wldp_length, void *wldp_buf) 900e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 901e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_softc *sc = (struct zyd_softc *)arg; 902e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int err; 903e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 904e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (!sc->usb.connected || sc->suspended || !sc->running) { 905e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_FAILURE); 906e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 907e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 908e8da18d8Spengcheng chen - Sun Microsystems - Beijing China err = ieee80211_getprop(&sc->ic, pr_name, wldp_pr_num, 909*0dc2366fSVenugopal Iyer wldp_length, wldp_buf); 910e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 911e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (err); 912e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 913e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 914*0dc2366fSVenugopal Iyer static void 915*0dc2366fSVenugopal Iyer zyd_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 916*0dc2366fSVenugopal Iyer mac_prop_info_handle_t mph) 917*0dc2366fSVenugopal Iyer { 918*0dc2366fSVenugopal Iyer struct zyd_softc *sc = (struct zyd_softc *)arg; 919*0dc2366fSVenugopal Iyer 920*0dc2366fSVenugopal Iyer ieee80211_propinfo(&sc->ic, pr_name, wldp_pr_num, mph); 921*0dc2366fSVenugopal Iyer } 922*0dc2366fSVenugopal Iyer 923e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 924e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Transmit a data frame. 925e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 926e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static mblk_t * 927e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_m_tx(void *arg, mblk_t *mp) 928e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 929e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_softc *sc = (struct zyd_softc *)arg; 930e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->ic; 931e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mblk_t *next; 932e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 933e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(mp != NULL); 934e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 935e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* not associated, drop data frames */ 936e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (ic->ic_state != IEEE80211_S_RUN) { 937e8da18d8Spengcheng chen - Sun Microsystems - Beijing China freemsg(mp); 938e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (DDI_SUCCESS); 939e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 940e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 941e8da18d8Spengcheng chen - Sun Microsystems - Beijing China while (mp != NULL) { 942e8da18d8Spengcheng chen - Sun Microsystems - Beijing China next = mp->b_next; 943e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mp->b_next = NULL; 944e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 945e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (zyd_send(ic, mp, IEEE80211_FC0_TYPE_DATA) != DDI_SUCCESS) { 946e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mp->b_next = next; 947e8da18d8Spengcheng chen - Sun Microsystems - Beijing China break; 948e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 949e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mp = next; 950e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 951e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 952e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (mp); 953e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 954e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 955e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 956e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * xxx_newstate callback for net80211. 957e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 958e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Called by net80211 whenever the ieee80211 state changes. 959e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 960e8da18d8Spengcheng chen - Sun Microsystems - Beijing China static int 961e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 962e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 963e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct zyd_softc *sc = ZYD_IC_TO_SOFTC(ic); 964e8da18d8Spengcheng chen - Sun Microsystems - Beijing China struct ieee80211_node *in; 965e8da18d8Spengcheng chen - Sun Microsystems - Beijing China uint_t chan; 966e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 967e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (sc->timeout_id != 0) { 968e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) untimeout(sc->timeout_id); 969e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->timeout_id = 0; 970e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 971e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 972e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (!sc->usb.connected || sc->suspended || !sc->running) { 973e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (sc->newstate(ic, nstate, arg)); 974e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 975e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 976e8da18d8Spengcheng chen - Sun Microsystems - Beijing China switch (nstate) { 977e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case IEEE80211_S_SCAN: 978e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_DEBUG((ZYD_DBG_SCAN, "scan timer: starting next\n")); 979e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->timeout_id = timeout(zyd_next_scan, sc, 980e8da18d8Spengcheng chen - Sun Microsystems - Beijing China drv_usectohz(ZYD_DWELL_TIME)); 981e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /*FALLTHRU*/ 982e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case IEEE80211_S_AUTH: 983e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case IEEE80211_S_ASSOC: 984e8da18d8Spengcheng chen - Sun Microsystems - Beijing China case IEEE80211_S_RUN: 985e8da18d8Spengcheng chen - Sun Microsystems - Beijing China chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 986e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (chan == 0 || chan == IEEE80211_CHAN_ANY) { 987e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ZYD_WARN("invalid channel number\n"); 988e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (0); 989e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 990e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) zyd_serial_enter(sc, ZYD_SER_SIG); 991e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_hw_set_channel(sc, chan); 992e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(sc); 993e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 994e8da18d8Spengcheng chen - Sun Microsystems - Beijing China in = ic->ic_bss; 995e8da18d8Spengcheng chen - Sun Microsystems - Beijing China in->in_txrate = in->in_rates.ir_nrates - 1; 996e8da18d8Spengcheng chen - Sun Microsystems - Beijing China default: 997e8da18d8Spengcheng chen - Sun Microsystems - Beijing China break; 998e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 999e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1000e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (sc->newstate(ic, nstate, arg)); 1001e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1002e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1003e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 1004e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * USB-safe synchronization. 1005e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Debugging routines. 1006e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 1007e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Kmutexes should never be held when making calls to USBA 1008e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * or when sleeping. Thus, we implement our own "mutex" on top 1009e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * of kmutexes and kcondvars. 1010e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 1011e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Usage: Any (possibly concurrent) access to the soft state or device must 1012e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * be serialized with a pair of zyd_serial_enter()/zyd_serial_exit(). 1013e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 1014e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 1015e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Initialize the serialization object. 1016e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 1017e8da18d8Spengcheng chen - Sun Microsystems - Beijing China void 1018e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_init(struct zyd_softc *sc) 1019e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 1020e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mutex_init(&sc->serial.lock, NULL, MUTEX_DRIVER, 1021e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->usb.cdata->dev_iblock_cookie); 1022e8da18d8Spengcheng chen - Sun Microsystems - Beijing China cv_init(&sc->serial.wait, NULL, CV_DRIVER, NULL); 1023e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1024e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->serial.held = B_FALSE; 1025e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->serial.initialized = B_TRUE; 1026e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1027e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1028e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 1029e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Wait for the serialization object. 1030e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 1031e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * If wait_sig is ZYD_SER_SIG, the function may return 1032e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * a signal is received. In this case, the serialization object 1033e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * is not acquired (but the mutex is) and the return value is ZYD_FAILURE. 1034e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 1035e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * In any other case the function returns ZYD_SUCCESS and the 1036e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * serialization object is acquired. 1037e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 1038e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_res 1039e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_enter(struct zyd_softc *sc, boolean_t wait_sig) 1040e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 1041e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_res res; 1042e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1043e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mutex_enter(&sc->serial.lock); 1044e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1045e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = ZYD_SUCCESS; 1046e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1047e8da18d8Spengcheng chen - Sun Microsystems - Beijing China while (sc->serial.held != B_FALSE) { 1048e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (wait_sig == ZYD_SER_SIG) { 1049e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = cv_wait_sig(&sc->serial.wait, &sc->serial.lock); 1050e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } else { 1051e8da18d8Spengcheng chen - Sun Microsystems - Beijing China cv_wait(&sc->serial.wait, &sc->serial.lock); 1052e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1053e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1054e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->serial.held = B_TRUE; 1055e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1056e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mutex_exit(&sc->serial.lock); 1057e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1058e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (res); 1059e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1060e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1061e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 1062e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Release the serialization object. 1063e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 1064e8da18d8Spengcheng chen - Sun Microsystems - Beijing China void 1065e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_exit(struct zyd_softc *sc) 1066e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 1067e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mutex_enter(&sc->serial.lock); 1068e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->serial.held = B_FALSE; 1069e8da18d8Spengcheng chen - Sun Microsystems - Beijing China cv_broadcast(&sc->serial.wait); 1070e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mutex_exit(&sc->serial.lock); 1071e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1072e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1073e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 1074e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Destroy the serialization object. 1075e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 1076e8da18d8Spengcheng chen - Sun Microsystems - Beijing China void 1077e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_serial_deinit(struct zyd_softc *sc) 1078e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 1079e8da18d8Spengcheng chen - Sun Microsystems - Beijing China cv_destroy(&sc->serial.wait); 1080e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mutex_destroy(&sc->serial.lock); 1081e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1082e8da18d8Spengcheng chen - Sun Microsystems - Beijing China sc->serial.initialized = B_FALSE; 1083e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1084e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1085e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1086e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 1087e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * zyd_cb_lock: a special signal structure that is used for notification 1088e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * that a callback function has been called. 1089e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 1090e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1091e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Initializes the zyd_cb_lock structure. */ 1092e8da18d8Spengcheng chen - Sun Microsystems - Beijing China void 1093e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_cb_lock_init(struct zyd_cb_lock *lock) 1094e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 1095e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(lock != NULL); 1096e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mutex_init(&lock->mutex, NULL, MUTEX_DRIVER, NULL); 1097e8da18d8Spengcheng chen - Sun Microsystems - Beijing China cv_init(&lock->cv, NULL, CV_DRIVER, NULL); 1098e8da18d8Spengcheng chen - Sun Microsystems - Beijing China lock->done = B_FALSE; 1099e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1100e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1101e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Deinitalizes the zyd_cb_lock structure. */ 1102e8da18d8Spengcheng chen - Sun Microsystems - Beijing China void 1103e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_cb_lock_destroy(struct zyd_cb_lock *lock) 1104e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 1105e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(lock != NULL); 1106e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mutex_destroy(&lock->mutex); 1107e8da18d8Spengcheng chen - Sun Microsystems - Beijing China cv_destroy(&lock->cv); 1108e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1109e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1110e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 1111e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Wait on lock until someone calls the "signal" function or the timeout 1112e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * expires. Note: timeout is in microseconds. 1113e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 1114e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_res 1115e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_cb_lock_wait(struct zyd_cb_lock *lock, clock_t timeout) 1116e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 1117e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_res res; 1118e8da18d8Spengcheng chen - Sun Microsystems - Beijing China clock_t etime; 1119e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int cv_res; 1120e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1121e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(lock != NULL); 1122e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1123e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mutex_enter(&lock->mutex); 1124e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1125e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (timeout < 0) { 1126e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* no timeout - wait as long as needed */ 1127e8da18d8Spengcheng chen - Sun Microsystems - Beijing China while (lock->done == B_FALSE) 1128e8da18d8Spengcheng chen - Sun Microsystems - Beijing China (void) cv_wait(&lock->cv, &lock->mutex); 1129e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } else { 1130e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* wait with timeout (given in usec) */ 1131e8da18d8Spengcheng chen - Sun Microsystems - Beijing China etime = ddi_get_lbolt() + drv_usectohz(timeout); 1132e8da18d8Spengcheng chen - Sun Microsystems - Beijing China while (lock->done == B_FALSE) { 1133e8da18d8Spengcheng chen - Sun Microsystems - Beijing China cv_res = 1134e8da18d8Spengcheng chen - Sun Microsystems - Beijing China cv_timedwait_sig(&lock->cv, &lock->mutex, etime); 1135e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (cv_res <= 0) 1136e8da18d8Spengcheng chen - Sun Microsystems - Beijing China break; 1137e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1138e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1139e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1140e8da18d8Spengcheng chen - Sun Microsystems - Beijing China res = (lock->done == B_TRUE) ? ZYD_SUCCESS : ZYD_FAILURE; 1141e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1142e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mutex_exit(&lock->mutex); 1143e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1144e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (res); 1145e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1146e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1147e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* Signal that the job (eg. callback) is done and unblock anyone who waits. */ 1148e8da18d8Spengcheng chen - Sun Microsystems - Beijing China void 1149e8da18d8Spengcheng chen - Sun Microsystems - Beijing China zyd_cb_lock_signal(struct zyd_cb_lock *lock) 1150e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 1151e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ASSERT(lock != NULL); 1152e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1153e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mutex_enter(&lock->mutex); 1154e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1155e8da18d8Spengcheng chen - Sun Microsystems - Beijing China lock->done = B_TRUE; 1156e8da18d8Spengcheng chen - Sun Microsystems - Beijing China cv_broadcast(&lock->cv); 1157e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1158e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mutex_exit(&lock->mutex); 1159e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1160e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1161e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 1162e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Loadable module configuration entry points 1163e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 1164e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1165e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 1166e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * _init module entry point. 1167e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 1168e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Called when the module is being loaded into memory. 1169e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 1170e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int 1171e8da18d8Spengcheng chen - Sun Microsystems - Beijing China _init(void) 1172e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 1173e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int err; 1174e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1175e8da18d8Spengcheng chen - Sun Microsystems - Beijing China err = ddi_soft_state_init(&zyd_ssp, sizeof (struct zyd_softc), 1); 1176e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1177e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) 1178e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (err); 1179e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1180e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mac_init_ops(&zyd_devops, ZYD_DRV_NAME); 1181e8da18d8Spengcheng chen - Sun Microsystems - Beijing China err = mod_install(&zyd_ml); 1182e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1183e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1184e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mac_fini_ops(&zyd_devops); 1185e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ddi_soft_state_fini(&zyd_ssp); 1186e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1187e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1188e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (err); 1189e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1190e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1191e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 1192e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * _info module entry point. 1193e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 1194e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Called to obtain information about the module. 1195e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 1196e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int 1197e8da18d8Spengcheng chen - Sun Microsystems - Beijing China _info(struct modinfo *modinfop) 1198e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 1199e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (mod_info(&zyd_ml, modinfop)); 1200e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1201e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1202e8da18d8Spengcheng chen - Sun Microsystems - Beijing China /* 1203e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * _fini module entry point. 1204e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * 1205e8da18d8Spengcheng chen - Sun Microsystems - Beijing China * Called when the module is being unloaded. 1206e8da18d8Spengcheng chen - Sun Microsystems - Beijing China */ 1207e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int 1208e8da18d8Spengcheng chen - Sun Microsystems - Beijing China _fini(void) 1209e8da18d8Spengcheng chen - Sun Microsystems - Beijing China { 1210e8da18d8Spengcheng chen - Sun Microsystems - Beijing China int err; 1211e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1212e8da18d8Spengcheng chen - Sun Microsystems - Beijing China err = mod_remove(&zyd_ml); 1213e8da18d8Spengcheng chen - Sun Microsystems - Beijing China if (err == DDI_SUCCESS) { 1214e8da18d8Spengcheng chen - Sun Microsystems - Beijing China mac_fini_ops(&zyd_devops); 1215e8da18d8Spengcheng chen - Sun Microsystems - Beijing China ddi_soft_state_fini(&zyd_ssp); 1216e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1217e8da18d8Spengcheng chen - Sun Microsystems - Beijing China 1218e8da18d8Spengcheng chen - Sun Microsystems - Beijing China return (err); 1219e8da18d8Spengcheng chen - Sun Microsystems - Beijing China } 1220