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
zyd_dbg(uint32_t dbg_mask,const int8_t * fmt,...)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
zyd_warn(const int8_t * fmt,...)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
zyd_plcp_signal(uint16_t rate)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
zyd_next_scan(void * arg)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
zyd_receive(struct zyd_softc * sc,const uint8_t * buf,uint16_t len)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
zyd_send(ieee80211com_t * ic,mblk_t * mp,uint8_t type)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
zyd_mac_init(struct zyd_softc * sc)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
zyd_wifi_init(struct zyd_softc * sc)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
zyd_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)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
zyd_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)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
zyd_m_stat(void * arg,uint_t stat,uint64_t * val)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
zyd_m_start(void * arg)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
zyd_m_stop(void * arg)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
zyd_m_unicst(void * arg,const uint8_t * macaddr)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
zyd_m_multicst(void * arg,boolean_t add,const uint8_t * m)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
zyd_m_promisc(void * arg,boolean_t on)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
zyd_m_ioctl(void * arg,queue_t * wq,mblk_t * mp)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
zyd_m_setprop(void * arg,const char * pr_name,mac_prop_id_t wldp_pr_num,uint_t wldp_length,const void * wldp_buf)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
zyd_m_getprop(void * arg,const char * pr_name,mac_prop_id_t wldp_pr_num,uint_t wldp_length,void * wldp_buf)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
zyd_m_propinfo(void * arg,const char * pr_name,mac_prop_id_t wldp_pr_num,mac_prop_info_handle_t mph)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 *
zyd_m_tx(void * arg,mblk_t * mp)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
zyd_newstate(struct ieee80211com * ic,enum ieee80211_state nstate,int arg)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
zyd_serial_init(struct zyd_softc * sc)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
zyd_serial_enter(struct zyd_softc * sc,boolean_t wait_sig)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
zyd_serial_exit(struct zyd_softc * sc)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
zyd_serial_deinit(struct zyd_softc * sc)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
zyd_cb_lock_init(struct zyd_cb_lock * lock)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
zyd_cb_lock_destroy(struct zyd_cb_lock * lock)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
zyd_cb_lock_wait(struct zyd_cb_lock * lock,clock_t timeout)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
zyd_cb_lock_signal(struct zyd_cb_lock * lock)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
_init(void)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
_info(struct modinfo * modinfop)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
_fini(void)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