156f9a274Sfei feng - Sun Microsystems - Beijing China /*
2*0dc2366fSVenugopal Iyer * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
356f9a274Sfei feng - Sun Microsystems - Beijing China * Use is subject to license terms.
456f9a274Sfei feng - Sun Microsystems - Beijing China */
556f9a274Sfei feng - Sun Microsystems - Beijing China
656f9a274Sfei feng - Sun Microsystems - Beijing China /*
756f9a274Sfei feng - Sun Microsystems - Beijing China * Copyright (c) 2006 Sam Leffler, Errno Consulting
856f9a274Sfei feng - Sun Microsystems - Beijing China * Copyright (c) 2008-2009 Weongyo Jeong <weongyo@freebsd.org>
956f9a274Sfei feng - Sun Microsystems - Beijing China * All rights reserved.
1056f9a274Sfei feng - Sun Microsystems - Beijing China *
1156f9a274Sfei feng - Sun Microsystems - Beijing China * Redistribution and use in source and binary forms, with or without
1256f9a274Sfei feng - Sun Microsystems - Beijing China * modification, are permitted provided that the following conditions
1356f9a274Sfei feng - Sun Microsystems - Beijing China * are met:
1456f9a274Sfei feng - Sun Microsystems - Beijing China * 1. Redistributions of source code must retain the above copyright
1556f9a274Sfei feng - Sun Microsystems - Beijing China * notice, this list of conditions and the following disclaimer,
1656f9a274Sfei feng - Sun Microsystems - Beijing China * without modification.
1756f9a274Sfei feng - Sun Microsystems - Beijing China * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1856f9a274Sfei feng - Sun Microsystems - Beijing China * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
1956f9a274Sfei feng - Sun Microsystems - Beijing China * redistribution must be conditioned upon including a substantially
2056f9a274Sfei feng - Sun Microsystems - Beijing China * similar Disclaimer requirement for further binary redistribution.
2156f9a274Sfei feng - Sun Microsystems - Beijing China *
2256f9a274Sfei feng - Sun Microsystems - Beijing China * NO WARRANTY
2356f9a274Sfei feng - Sun Microsystems - Beijing China * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2456f9a274Sfei feng - Sun Microsystems - Beijing China * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2556f9a274Sfei feng - Sun Microsystems - Beijing China * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
2656f9a274Sfei feng - Sun Microsystems - Beijing China * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
2756f9a274Sfei feng - Sun Microsystems - Beijing China * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
2856f9a274Sfei feng - Sun Microsystems - Beijing China * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2956f9a274Sfei feng - Sun Microsystems - Beijing China * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3056f9a274Sfei feng - Sun Microsystems - Beijing China * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
3156f9a274Sfei feng - Sun Microsystems - Beijing China * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3256f9a274Sfei feng - Sun Microsystems - Beijing China * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
3356f9a274Sfei feng - Sun Microsystems - Beijing China * THE POSSIBILITY OF SUCH DAMAGES.
3456f9a274Sfei feng - Sun Microsystems - Beijing China */
3556f9a274Sfei feng - Sun Microsystems - Beijing China
3656f9a274Sfei feng - Sun Microsystems - Beijing China /*
3756f9a274Sfei feng - Sun Microsystems - Beijing China * This driver is distantly derived from a driver of the same name
3856f9a274Sfei feng - Sun Microsystems - Beijing China * by Damien Bergamini. The original copyright is included below:
3956f9a274Sfei feng - Sun Microsystems - Beijing China *
4056f9a274Sfei feng - Sun Microsystems - Beijing China * Copyright (c) 2006
4156f9a274Sfei feng - Sun Microsystems - Beijing China * Damien Bergamini <damien.bergamini@free.fr>
4256f9a274Sfei feng - Sun Microsystems - Beijing China *
4356f9a274Sfei feng - Sun Microsystems - Beijing China * Permission to use, copy, modify, and distribute this software for any
4456f9a274Sfei feng - Sun Microsystems - Beijing China * purpose with or without fee is hereby granted, provided that the above
4556f9a274Sfei feng - Sun Microsystems - Beijing China * copyright notice and this permission notice appear in all copies.
4656f9a274Sfei feng - Sun Microsystems - Beijing China *
4756f9a274Sfei feng - Sun Microsystems - Beijing China * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
4856f9a274Sfei feng - Sun Microsystems - Beijing China * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
4956f9a274Sfei feng - Sun Microsystems - Beijing China * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
5056f9a274Sfei feng - Sun Microsystems - Beijing China * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
5156f9a274Sfei feng - Sun Microsystems - Beijing China * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
5256f9a274Sfei feng - Sun Microsystems - Beijing China * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
5356f9a274Sfei feng - Sun Microsystems - Beijing China * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
5456f9a274Sfei feng - Sun Microsystems - Beijing China */
5556f9a274Sfei feng - Sun Microsystems - Beijing China
5656f9a274Sfei feng - Sun Microsystems - Beijing China
5756f9a274Sfei feng - Sun Microsystems - Beijing China #include <sys/types.h>
5856f9a274Sfei feng - Sun Microsystems - Beijing China #include <sys/cmn_err.h>
5956f9a274Sfei feng - Sun Microsystems - Beijing China #include <sys/strsubr.h>
6056f9a274Sfei feng - Sun Microsystems - Beijing China #include <sys/strsun.h>
6156f9a274Sfei feng - Sun Microsystems - Beijing China #include <sys/modctl.h>
6256f9a274Sfei feng - Sun Microsystems - Beijing China #include <sys/devops.h>
63*0dc2366fSVenugopal Iyer #include <sys/byteorder.h>
6456f9a274Sfei feng - Sun Microsystems - Beijing China #include <sys/mac_provider.h>
6556f9a274Sfei feng - Sun Microsystems - Beijing China #include <sys/mac_wifi.h>
6656f9a274Sfei feng - Sun Microsystems - Beijing China #include <sys/net80211.h>
6756f9a274Sfei feng - Sun Microsystems - Beijing China
6856f9a274Sfei feng - Sun Microsystems - Beijing China #define USBDRV_MAJOR_VER 2
6956f9a274Sfei feng - Sun Microsystems - Beijing China #define USBDRV_MINOR_VER 0
7056f9a274Sfei feng - Sun Microsystems - Beijing China #include <sys/usb/usba.h>
7156f9a274Sfei feng - Sun Microsystems - Beijing China #include <sys/usb/usba/usba_types.h>
7256f9a274Sfei feng - Sun Microsystems - Beijing China
7356f9a274Sfei feng - Sun Microsystems - Beijing China #include "uath_reg.h"
7456f9a274Sfei feng - Sun Microsystems - Beijing China #include "uath_var.h"
7556f9a274Sfei feng - Sun Microsystems - Beijing China
7656f9a274Sfei feng - Sun Microsystems - Beijing China static void *uath_soft_state_p = NULL;
7756f9a274Sfei feng - Sun Microsystems - Beijing China
7856f9a274Sfei feng - Sun Microsystems - Beijing China /*
7956f9a274Sfei feng - Sun Microsystems - Beijing China * Bit flags in the ral_dbg_flags
8056f9a274Sfei feng - Sun Microsystems - Beijing China */
8156f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_DBG_MSG 0x000001
8256f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_DBG_ERR 0x000002
8356f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_DBG_USB 0x000004
8456f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_DBG_TX 0x000008
8556f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_DBG_RX 0x000010
8656f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_DBG_FW 0x000020
8756f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_DBG_TX_CMD 0x000040
8856f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_DBG_RX_CMD 0x000080
8956f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_DBG_ALL 0x000fff
9056f9a274Sfei feng - Sun Microsystems - Beijing China
9156f9a274Sfei feng - Sun Microsystems - Beijing China uint32_t uath_dbg_flags = 0;
9256f9a274Sfei feng - Sun Microsystems - Beijing China
9356f9a274Sfei feng - Sun Microsystems - Beijing China #ifdef DEBUG
9456f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_DEBUG \
9556f9a274Sfei feng - Sun Microsystems - Beijing China uath_debug
9656f9a274Sfei feng - Sun Microsystems - Beijing China #else
9756f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_DEBUG
9856f9a274Sfei feng - Sun Microsystems - Beijing China #endif
9956f9a274Sfei feng - Sun Microsystems - Beijing China
10056f9a274Sfei feng - Sun Microsystems - Beijing China /*
10156f9a274Sfei feng - Sun Microsystems - Beijing China * Various supported device vendors/products.
10256f9a274Sfei feng - Sun Microsystems - Beijing China * UB51: AR5005UG 802.11b/g, UB52: AR5005UX 802.11b/g
10356f9a274Sfei feng - Sun Microsystems - Beijing China */
10456f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_FLAG_PRE_FIRMWARE (1 << 0)
10556f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_FLAG_ABG (1 << 1)
10656f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_FLAG_ERR (1 << 2)
10756f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_DEV(v, p, f) \
10856f9a274Sfei feng - Sun Microsystems - Beijing China { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, (f) }, \
10956f9a274Sfei feng - Sun Microsystems - Beijing China { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p##_NF }, \
11056f9a274Sfei feng - Sun Microsystems - Beijing China (f) | UATH_FLAG_PRE_FIRMWARE }
11156f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_DEV_UG(v, p) UATH_DEV(v, p, 0)
11256f9a274Sfei feng - Sun Microsystems - Beijing China #define UATH_DEV_UX(v, p) UATH_DEV(v, p, UATH_FLAG_ABG)
11356f9a274Sfei feng - Sun Microsystems - Beijing China
11456f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_devno {
11556f9a274Sfei feng - Sun Microsystems - Beijing China uint16_t vendor_id;
11656f9a274Sfei feng - Sun Microsystems - Beijing China uint16_t product_id;
11756f9a274Sfei feng - Sun Microsystems - Beijing China };
11856f9a274Sfei feng - Sun Microsystems - Beijing China
11956f9a274Sfei feng - Sun Microsystems - Beijing China static const struct uath_type {
12056f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_devno dev;
12156f9a274Sfei feng - Sun Microsystems - Beijing China uint8_t flags;
12256f9a274Sfei feng - Sun Microsystems - Beijing China } uath_devs[] = {
12356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(ACCTON, SMCWUSBTG2),
12456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(ATHEROS, AR5523),
12556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(ATHEROS2, AR5523_1),
12656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(ATHEROS2, AR5523_2),
12756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UX(ATHEROS2, AR5523_3),
12856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(CONCEPTRONIC, AR5523_1),
12956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UX(CONCEPTRONIC, AR5523_2),
13056f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UX(DLINK, DWLAG122),
13156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UX(DLINK, DWLAG132),
13256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(DLINK, DWLG132),
13356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(GIGASET, AR5523),
13456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(GIGASET, SMCWUSBTG),
13556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(GLOBALSUN, AR5523_1),
13656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UX(GLOBALSUN, AR5523_2),
13756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(IODATA, USBWNG54US),
13856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(MELCO, WLIU2KAMG54),
13956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UX(NETGEAR, WG111U),
14056f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(NETGEAR3, WG111T),
14156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(NETGEAR3, WPN111),
14256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(PHILIPS, SNU6500),
14356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UX(UMEDIA, AR5523_2),
14456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(UMEDIA, TEW444UBEU),
14556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(WISTRONNEWEB, AR5523_1),
14656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UX(WISTRONNEWEB, AR5523_2),
14756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEV_UG(ZCOM, AR5523)
14856f9a274Sfei feng - Sun Microsystems - Beijing China };
14956f9a274Sfei feng - Sun Microsystems - Beijing China
15056f9a274Sfei feng - Sun Microsystems - Beijing China static char uath_fwmod[] = "uathfw";
15156f9a274Sfei feng - Sun Microsystems - Beijing China static char uath_binmod[] = "uathbin";
15256f9a274Sfei feng - Sun Microsystems - Beijing China
15356f9a274Sfei feng - Sun Microsystems - Beijing China /*
15456f9a274Sfei feng - Sun Microsystems - Beijing China * Supported rates for 802.11b/g modes (in 500Kbps unit).
15556f9a274Sfei feng - Sun Microsystems - Beijing China */
15656f9a274Sfei feng - Sun Microsystems - Beijing China static const struct ieee80211_rateset uath_rateset_11b =
15756f9a274Sfei feng - Sun Microsystems - Beijing China { 4, { 2, 4, 11, 22 } };
15856f9a274Sfei feng - Sun Microsystems - Beijing China
15956f9a274Sfei feng - Sun Microsystems - Beijing China static const struct ieee80211_rateset uath_rateset_11g =
16056f9a274Sfei feng - Sun Microsystems - Beijing China { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
16156f9a274Sfei feng - Sun Microsystems - Beijing China
16256f9a274Sfei feng - Sun Microsystems - Beijing China /*
16356f9a274Sfei feng - Sun Microsystems - Beijing China * device operations
16456f9a274Sfei feng - Sun Microsystems - Beijing China */
16556f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_attach(dev_info_t *, ddi_attach_cmd_t);
16656f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_detach(dev_info_t *, ddi_detach_cmd_t);
16756f9a274Sfei feng - Sun Microsystems - Beijing China
16856f9a274Sfei feng - Sun Microsystems - Beijing China /*
16956f9a274Sfei feng - Sun Microsystems - Beijing China * Module Loading Data & Entry Points
17056f9a274Sfei feng - Sun Microsystems - Beijing China */
17156f9a274Sfei feng - Sun Microsystems - Beijing China DDI_DEFINE_STREAM_OPS(uath_dev_ops, nulldev, nulldev, uath_attach,
17256f9a274Sfei feng - Sun Microsystems - Beijing China uath_detach, nodev, NULL, D_MP, NULL, ddi_quiesce_not_needed);
17356f9a274Sfei feng - Sun Microsystems - Beijing China
17456f9a274Sfei feng - Sun Microsystems - Beijing China static struct modldrv uath_modldrv = {
17556f9a274Sfei feng - Sun Microsystems - Beijing China &mod_driverops, /* Type of module. This one is a driver */
17656f9a274Sfei feng - Sun Microsystems - Beijing China "Atheros AR5523 USB Driver v1.1", /* short description */
17756f9a274Sfei feng - Sun Microsystems - Beijing China &uath_dev_ops /* driver specific ops */
17856f9a274Sfei feng - Sun Microsystems - Beijing China };
17956f9a274Sfei feng - Sun Microsystems - Beijing China
18056f9a274Sfei feng - Sun Microsystems - Beijing China static struct modlinkage modlinkage = {
18156f9a274Sfei feng - Sun Microsystems - Beijing China MODREV_1,
18256f9a274Sfei feng - Sun Microsystems - Beijing China (void *)&uath_modldrv,
18356f9a274Sfei feng - Sun Microsystems - Beijing China NULL
18456f9a274Sfei feng - Sun Microsystems - Beijing China };
18556f9a274Sfei feng - Sun Microsystems - Beijing China
18656f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_m_stat(void *, uint_t, uint64_t *);
18756f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_m_start(void *);
18856f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_m_stop(void *);
18956f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_m_promisc(void *, boolean_t);
19056f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_m_multicst(void *, boolean_t, const uint8_t *);
19156f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_m_unicst(void *, const uint8_t *);
19256f9a274Sfei feng - Sun Microsystems - Beijing China static mblk_t *uath_m_tx(void *, mblk_t *);
19356f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_m_ioctl(void *, queue_t *, mblk_t *);
19456f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_m_setprop(void *, const char *, mac_prop_id_t,
19556f9a274Sfei feng - Sun Microsystems - Beijing China uint_t, const void *);
19656f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_m_getprop(void *, const char *, mac_prop_id_t,
197*0dc2366fSVenugopal Iyer uint_t, void *);
198*0dc2366fSVenugopal Iyer static void uath_m_propinfo(void *, const char *, mac_prop_id_t,
199*0dc2366fSVenugopal Iyer mac_prop_info_handle_t);
20056f9a274Sfei feng - Sun Microsystems - Beijing China
20156f9a274Sfei feng - Sun Microsystems - Beijing China static mac_callbacks_t uath_m_callbacks = {
202*0dc2366fSVenugopal Iyer MC_IOCTL | MC_SETPROP | MC_GETPROP | MC_PROPINFO,
20356f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_stat,
20456f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_start,
20556f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_stop,
20656f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_promisc,
20756f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_multicst,
20856f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_unicst,
20956f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_tx,
210*0dc2366fSVenugopal Iyer NULL,
21156f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_ioctl,
21256f9a274Sfei feng - Sun Microsystems - Beijing China NULL,
21356f9a274Sfei feng - Sun Microsystems - Beijing China NULL,
21456f9a274Sfei feng - Sun Microsystems - Beijing China NULL,
21556f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_setprop,
216*0dc2366fSVenugopal Iyer uath_m_getprop,
217*0dc2366fSVenugopal Iyer uath_m_propinfo
21856f9a274Sfei feng - Sun Microsystems - Beijing China };
21956f9a274Sfei feng - Sun Microsystems - Beijing China
22056f9a274Sfei feng - Sun Microsystems - Beijing China static usb_alt_if_data_t *
22156f9a274Sfei feng - Sun Microsystems - Beijing China uath_lookup_alt_if(usb_client_dev_data_t *,
22256f9a274Sfei feng - Sun Microsystems - Beijing China uint_t, uint_t, uint_t);
22356f9a274Sfei feng - Sun Microsystems - Beijing China static usb_ep_data_t *
22456f9a274Sfei feng - Sun Microsystems - Beijing China uath_lookup_ep_data(dev_info_t *,
22556f9a274Sfei feng - Sun Microsystems - Beijing China usb_client_dev_data_t *, uint_t, uint_t, uint8_t, uint8_t);
22656f9a274Sfei feng - Sun Microsystems - Beijing China static const char *
22756f9a274Sfei feng - Sun Microsystems - Beijing China uath_codename(int code);
22856f9a274Sfei feng - Sun Microsystems - Beijing China
22956f9a274Sfei feng - Sun Microsystems - Beijing China static uint_t uath_lookup(uint16_t, uint16_t);
23056f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_list_all_eps(usb_alt_if_data_t *);
23156f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_open_pipes(struct uath_softc *);
23256f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_close_pipes(struct uath_softc *);
23356f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_fw_send(struct uath_softc *,
23456f9a274Sfei feng - Sun Microsystems - Beijing China usb_pipe_handle_t, const void *, size_t);
23556f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_fw_ack(struct uath_softc *, int);
23656f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_loadsym(ddi_modhandle_t, char *, char **, size_t *);
23756f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_loadfirmware(struct uath_softc *);
23856f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_alloc_cmd_list(struct uath_softc *,
23956f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_cmd *, int, int);
24056f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_init_cmd_list(struct uath_softc *);
24156f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_free_cmd_list(struct uath_cmd *, int);
24256f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_host_available(struct uath_softc *);
24356f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_get_capability(struct uath_softc *, uint32_t, uint32_t *);
24456f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_get_devcap(struct uath_softc *);
24556f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_get_devstatus(struct uath_softc *, uint8_t *);
24656f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_get_status(struct uath_softc *, uint32_t, void *, int);
24756f9a274Sfei feng - Sun Microsystems - Beijing China
24856f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_cmd_lock_init(struct uath_cmd_lock *);
24956f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_cmd_lock_destroy(struct uath_cmd_lock *);
25056f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_cmd_lock_wait(struct uath_cmd_lock *, clock_t);
25156f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_cmd_lock_signal(struct uath_cmd_lock *);
25256f9a274Sfei feng - Sun Microsystems - Beijing China
25356f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_cmd_read(struct uath_softc *, uint32_t, const void *,
25456f9a274Sfei feng - Sun Microsystems - Beijing China int, void *, int, int);
25556f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_cmd_write(struct uath_softc *, uint32_t, const void *,
25656f9a274Sfei feng - Sun Microsystems - Beijing China int, int);
25756f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_cmdsend(struct uath_softc *, uint32_t,
25856f9a274Sfei feng - Sun Microsystems - Beijing China const void *, int, void *, int, int);
25956f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_rx_cmd_xfer(struct uath_softc *);
26056f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_tx_cmd_xfer(struct uath_softc *,
26156f9a274Sfei feng - Sun Microsystems - Beijing China usb_pipe_handle_t, const void *, uint_t);
26256f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_cmd_txeof(usb_pipe_handle_t, struct usb_bulk_req *);
26356f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_cmd_rxeof(usb_pipe_handle_t, usb_bulk_req_t *);
26456f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_cmdeof(struct uath_softc *, struct uath_cmd *);
26556f9a274Sfei feng - Sun Microsystems - Beijing China
26656f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_init_data_queue(struct uath_softc *);
26756f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_rx_data_xfer(struct uath_softc *sc);
26856f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_tx_data_xfer(struct uath_softc *, mblk_t *);
26956f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_data_txeof(usb_pipe_handle_t, usb_bulk_req_t *);
27056f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_data_rxeof(usb_pipe_handle_t, usb_bulk_req_t *);
27156f9a274Sfei feng - Sun Microsystems - Beijing China
27256f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_create_connection(struct uath_softc *, uint32_t);
27356f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_set_rates(struct uath_softc *,
27456f9a274Sfei feng - Sun Microsystems - Beijing China const struct ieee80211_rateset *);
27556f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_write_associd(struct uath_softc *);
27656f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_set_ledsteady(struct uath_softc *, int, int);
27756f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_set_ledblink(struct uath_softc *, int, int, int, int);
27856f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_update_rxstat(struct uath_softc *, uint32_t);
27956f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_send(ieee80211com_t *, mblk_t *, uint8_t);
28056f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_reconnect(dev_info_t *);
28156f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_disconnect(dev_info_t *);
28256f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_newstate(struct ieee80211com *, enum ieee80211_state, int);
28356f9a274Sfei feng - Sun Microsystems - Beijing China
28456f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_dataflush(struct uath_softc *);
28556f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_cmdflush(struct uath_softc *);
28656f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_flush(struct uath_softc *);
28756f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_set_ledstate(struct uath_softc *, int);
28856f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_set_chan(struct uath_softc *, struct ieee80211_channel *);
28956f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_reset_tx_queues(struct uath_softc *);
29056f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_wme_init(struct uath_softc *);
29156f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_config_multi(struct uath_softc *,
29256f9a274Sfei feng - Sun Microsystems - Beijing China uint32_t, const void *, int);
29356f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_config(struct uath_softc *, uint32_t, uint32_t);
29456f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_switch_channel(struct uath_softc *,
29556f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211_channel *);
29656f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_set_rxfilter(struct uath_softc *, uint32_t, uint32_t);
29756f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_init_locked(void *);
29856f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_stop_locked(void *);
29956f9a274Sfei feng - Sun Microsystems - Beijing China static int uath_init(struct uath_softc *);
30056f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_stop(struct uath_softc *);
30156f9a274Sfei feng - Sun Microsystems - Beijing China static void uath_resume(struct uath_softc *);
30256f9a274Sfei feng - Sun Microsystems - Beijing China
30356f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_debug(uint32_t dbg_flags,const int8_t * fmt,...)30456f9a274Sfei feng - Sun Microsystems - Beijing China uath_debug(uint32_t dbg_flags, const int8_t *fmt, ...)
30556f9a274Sfei feng - Sun Microsystems - Beijing China {
30656f9a274Sfei feng - Sun Microsystems - Beijing China va_list args;
30756f9a274Sfei feng - Sun Microsystems - Beijing China
30856f9a274Sfei feng - Sun Microsystems - Beijing China if (dbg_flags & uath_dbg_flags) {
30956f9a274Sfei feng - Sun Microsystems - Beijing China va_start(args, fmt);
31056f9a274Sfei feng - Sun Microsystems - Beijing China vcmn_err(CE_CONT, fmt, args);
31156f9a274Sfei feng - Sun Microsystems - Beijing China va_end(args);
31256f9a274Sfei feng - Sun Microsystems - Beijing China }
31356f9a274Sfei feng - Sun Microsystems - Beijing China }
31456f9a274Sfei feng - Sun Microsystems - Beijing China
31556f9a274Sfei feng - Sun Microsystems - Beijing China static uint_t
uath_lookup(uint16_t vendor_id,uint16_t product_id)31656f9a274Sfei feng - Sun Microsystems - Beijing China uath_lookup(uint16_t vendor_id, uint16_t product_id)
31756f9a274Sfei feng - Sun Microsystems - Beijing China {
31856f9a274Sfei feng - Sun Microsystems - Beijing China int i, size;
31956f9a274Sfei feng - Sun Microsystems - Beijing China
32056f9a274Sfei feng - Sun Microsystems - Beijing China size = sizeof (uath_devs) / sizeof (struct uath_type);
32156f9a274Sfei feng - Sun Microsystems - Beijing China
32256f9a274Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < size; i++) {
32356f9a274Sfei feng - Sun Microsystems - Beijing China if ((vendor_id == uath_devs[i].dev.vendor_id) &&
32456f9a274Sfei feng - Sun Microsystems - Beijing China (product_id == uath_devs[i].dev.product_id))
32556f9a274Sfei feng - Sun Microsystems - Beijing China return (uath_devs[i].flags);
32656f9a274Sfei feng - Sun Microsystems - Beijing China }
32756f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_FLAG_ERR);
32856f9a274Sfei feng - Sun Microsystems - Beijing China }
32956f9a274Sfei feng - Sun Microsystems - Beijing China
33056f9a274Sfei feng - Sun Microsystems - Beijing China /*
33156f9a274Sfei feng - Sun Microsystems - Beijing China * Return a specific alt_if from the device descriptor tree.
33256f9a274Sfei feng - Sun Microsystems - Beijing China */
33356f9a274Sfei feng - Sun Microsystems - Beijing China static usb_alt_if_data_t *
uath_lookup_alt_if(usb_client_dev_data_t * dev_data,uint_t config,uint_t interface,uint_t alt)33456f9a274Sfei feng - Sun Microsystems - Beijing China uath_lookup_alt_if(usb_client_dev_data_t *dev_data, uint_t config,
33556f9a274Sfei feng - Sun Microsystems - Beijing China uint_t interface, uint_t alt)
33656f9a274Sfei feng - Sun Microsystems - Beijing China {
33756f9a274Sfei feng - Sun Microsystems - Beijing China usb_cfg_data_t *cfg_data;
33856f9a274Sfei feng - Sun Microsystems - Beijing China usb_if_data_t *if_data;
33956f9a274Sfei feng - Sun Microsystems - Beijing China usb_alt_if_data_t *if_alt_data;
34056f9a274Sfei feng - Sun Microsystems - Beijing China
34156f9a274Sfei feng - Sun Microsystems - Beijing China /*
34256f9a274Sfei feng - Sun Microsystems - Beijing China * Assume everything is in the tree for now,
34356f9a274Sfei feng - Sun Microsystems - Beijing China * (USB_PARSE_LVL_ALL)
34456f9a274Sfei feng - Sun Microsystems - Beijing China * so we can directly index the array.
34556f9a274Sfei feng - Sun Microsystems - Beijing China */
34656f9a274Sfei feng - Sun Microsystems - Beijing China
34756f9a274Sfei feng - Sun Microsystems - Beijing China /* Descend to configuration, configs are 1-based */
34856f9a274Sfei feng - Sun Microsystems - Beijing China if (config < 1 || config > dev_data->dev_n_cfg)
34956f9a274Sfei feng - Sun Microsystems - Beijing China return (NULL);
35056f9a274Sfei feng - Sun Microsystems - Beijing China cfg_data = &dev_data->dev_cfg[config - 1];
35156f9a274Sfei feng - Sun Microsystems - Beijing China
35256f9a274Sfei feng - Sun Microsystems - Beijing China /* Descend to interface */
35356f9a274Sfei feng - Sun Microsystems - Beijing China if (interface > cfg_data->cfg_n_if - 1)
35456f9a274Sfei feng - Sun Microsystems - Beijing China return (NULL);
35556f9a274Sfei feng - Sun Microsystems - Beijing China if_data = &cfg_data->cfg_if[interface];
35656f9a274Sfei feng - Sun Microsystems - Beijing China
35756f9a274Sfei feng - Sun Microsystems - Beijing China /* Descend to alt */
35856f9a274Sfei feng - Sun Microsystems - Beijing China if (alt > if_data->if_n_alt - 1)
35956f9a274Sfei feng - Sun Microsystems - Beijing China return (NULL);
36056f9a274Sfei feng - Sun Microsystems - Beijing China if_alt_data = &if_data->if_alt[alt];
36156f9a274Sfei feng - Sun Microsystems - Beijing China
36256f9a274Sfei feng - Sun Microsystems - Beijing China return (if_alt_data);
36356f9a274Sfei feng - Sun Microsystems - Beijing China }
36456f9a274Sfei feng - Sun Microsystems - Beijing China
36556f9a274Sfei feng - Sun Microsystems - Beijing China /*
36656f9a274Sfei feng - Sun Microsystems - Beijing China * Print all endpoints of an alt_if.
36756f9a274Sfei feng - Sun Microsystems - Beijing China */
36856f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_list_all_eps(usb_alt_if_data_t * ifalt)36956f9a274Sfei feng - Sun Microsystems - Beijing China uath_list_all_eps(usb_alt_if_data_t *ifalt)
37056f9a274Sfei feng - Sun Microsystems - Beijing China {
37156f9a274Sfei feng - Sun Microsystems - Beijing China usb_ep_data_t *ep_data;
37256f9a274Sfei feng - Sun Microsystems - Beijing China usb_ep_descr_t *ep_descr;
37356f9a274Sfei feng - Sun Microsystems - Beijing China int i;
37456f9a274Sfei feng - Sun Microsystems - Beijing China
37556f9a274Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < ifalt->altif_n_ep; i++) {
37656f9a274Sfei feng - Sun Microsystems - Beijing China ep_data = &ifalt->altif_ep[i];
37756f9a274Sfei feng - Sun Microsystems - Beijing China ep_descr = &ep_data->ep_descr;
37856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_USB,
37956f9a274Sfei feng - Sun Microsystems - Beijing China "uath: uath_list_all_endpoint: "
38056f9a274Sfei feng - Sun Microsystems - Beijing China "ep addresa[%x] is %x",
38156f9a274Sfei feng - Sun Microsystems - Beijing China i, ep_descr->bEndpointAddress);
38256f9a274Sfei feng - Sun Microsystems - Beijing China }
38356f9a274Sfei feng - Sun Microsystems - Beijing China }
38456f9a274Sfei feng - Sun Microsystems - Beijing China
38556f9a274Sfei feng - Sun Microsystems - Beijing China static usb_ep_data_t *
uath_lookup_ep_data(dev_info_t * dip,usb_client_dev_data_t * dev_datap,uint_t interface,uint_t alternate,uint8_t address,uint8_t type)38656f9a274Sfei feng - Sun Microsystems - Beijing China uath_lookup_ep_data(dev_info_t *dip,
38756f9a274Sfei feng - Sun Microsystems - Beijing China usb_client_dev_data_t *dev_datap,
38856f9a274Sfei feng - Sun Microsystems - Beijing China uint_t interface,
38956f9a274Sfei feng - Sun Microsystems - Beijing China uint_t alternate,
39056f9a274Sfei feng - Sun Microsystems - Beijing China uint8_t address,
39156f9a274Sfei feng - Sun Microsystems - Beijing China uint8_t type)
39256f9a274Sfei feng - Sun Microsystems - Beijing China {
39356f9a274Sfei feng - Sun Microsystems - Beijing China usb_alt_if_data_t *altif_data;
39456f9a274Sfei feng - Sun Microsystems - Beijing China int i;
39556f9a274Sfei feng - Sun Microsystems - Beijing China
39656f9a274Sfei feng - Sun Microsystems - Beijing China if ((dip == NULL) || (dev_datap == NULL))
39756f9a274Sfei feng - Sun Microsystems - Beijing China return (NULL);
39856f9a274Sfei feng - Sun Microsystems - Beijing China
39956f9a274Sfei feng - Sun Microsystems - Beijing China altif_data = &dev_datap->dev_curr_cfg->
40056f9a274Sfei feng - Sun Microsystems - Beijing China cfg_if[interface].if_alt[alternate];
40156f9a274Sfei feng - Sun Microsystems - Beijing China
40256f9a274Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < altif_data->altif_n_ep; i++) {
40356f9a274Sfei feng - Sun Microsystems - Beijing China usb_ep_descr_t *ept = &altif_data->altif_ep[i].ep_descr;
40456f9a274Sfei feng - Sun Microsystems - Beijing China uint8_t ept_type = ept->bmAttributes & USB_EP_ATTR_MASK;
40556f9a274Sfei feng - Sun Microsystems - Beijing China uint8_t ept_address = ept->bEndpointAddress;
40656f9a274Sfei feng - Sun Microsystems - Beijing China
40756f9a274Sfei feng - Sun Microsystems - Beijing China if (ept->bLength == 0)
40856f9a274Sfei feng - Sun Microsystems - Beijing China continue;
40956f9a274Sfei feng - Sun Microsystems - Beijing China if ((ept_type == type) &&
41056f9a274Sfei feng - Sun Microsystems - Beijing China ((type == USB_EP_ATTR_CONTROL) || (address == ept_address)))
41156f9a274Sfei feng - Sun Microsystems - Beijing China return (&altif_data->altif_ep[i]);
41256f9a274Sfei feng - Sun Microsystems - Beijing China }
41356f9a274Sfei feng - Sun Microsystems - Beijing China return (NULL);
41456f9a274Sfei feng - Sun Microsystems - Beijing China }
41556f9a274Sfei feng - Sun Microsystems - Beijing China
41656f9a274Sfei feng - Sun Microsystems - Beijing China /*
41756f9a274Sfei feng - Sun Microsystems - Beijing China * Open communication pipes.
41856f9a274Sfei feng - Sun Microsystems - Beijing China * The following pipes are used by the AR5523:
41956f9a274Sfei feng - Sun Microsystems - Beijing China * ep0: 0x81 IN Rx cmd
42056f9a274Sfei feng - Sun Microsystems - Beijing China * ep1: 0x01 OUT Tx cmd
42156f9a274Sfei feng - Sun Microsystems - Beijing China * ep2: 0x82 IN Rx data
42256f9a274Sfei feng - Sun Microsystems - Beijing China * ep3: 0x02 OUT Tx data
42356f9a274Sfei feng - Sun Microsystems - Beijing China */
42456f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_open_pipes(struct uath_softc * sc)42556f9a274Sfei feng - Sun Microsystems - Beijing China uath_open_pipes(struct uath_softc *sc)
42656f9a274Sfei feng - Sun Microsystems - Beijing China {
42756f9a274Sfei feng - Sun Microsystems - Beijing China usb_ep_data_t *ep_node;
42856f9a274Sfei feng - Sun Microsystems - Beijing China usb_ep_descr_t *ep_descr;
42956f9a274Sfei feng - Sun Microsystems - Beijing China usb_pipe_policy_t policy;
43056f9a274Sfei feng - Sun Microsystems - Beijing China int err;
43156f9a274Sfei feng - Sun Microsystems - Beijing China
43256f9a274Sfei feng - Sun Microsystems - Beijing China #ifdef DEBUG
43356f9a274Sfei feng - Sun Microsystems - Beijing China usb_alt_if_data_t *altif_data;
43456f9a274Sfei feng - Sun Microsystems - Beijing China
43556f9a274Sfei feng - Sun Microsystems - Beijing China altif_data = uath_lookup_alt_if(sc->sc_udev, UATH_CONFIG_NO,
43656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_IFACE_INDEX, UATH_ALT_IF_INDEX);
43756f9a274Sfei feng - Sun Microsystems - Beijing China if (altif_data == NULL) {
43856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "alt_if not found");
43956f9a274Sfei feng - Sun Microsystems - Beijing China return (USB_FAILURE);
44056f9a274Sfei feng - Sun Microsystems - Beijing China }
44156f9a274Sfei feng - Sun Microsystems - Beijing China
44256f9a274Sfei feng - Sun Microsystems - Beijing China uath_list_all_eps(altif_data);
44356f9a274Sfei feng - Sun Microsystems - Beijing China #endif
44456f9a274Sfei feng - Sun Microsystems - Beijing China
44556f9a274Sfei feng - Sun Microsystems - Beijing China /*
44656f9a274Sfei feng - Sun Microsystems - Beijing China * XXX pipes numbers are hardcoded because we don't have any way
44756f9a274Sfei feng - Sun Microsystems - Beijing China * to distinguish the data pipes from the firmware command pipes
44856f9a274Sfei feng - Sun Microsystems - Beijing China * (both are bulk pipes) using the endpoints descriptors.
44956f9a274Sfei feng - Sun Microsystems - Beijing China */
45056f9a274Sfei feng - Sun Microsystems - Beijing China ep_node = uath_lookup_ep_data(sc->sc_dev, sc->sc_udev,
45156f9a274Sfei feng - Sun Microsystems - Beijing China 0, 0, 0x81, USB_EP_ATTR_BULK);
45256f9a274Sfei feng - Sun Microsystems - Beijing China ep_descr = &ep_node->ep_descr;
45356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_open_pipes(): "
45456f9a274Sfei feng - Sun Microsystems - Beijing China "find pipe %x\n", ep_descr->bEndpointAddress);
45556f9a274Sfei feng - Sun Microsystems - Beijing China
45656f9a274Sfei feng - Sun Microsystems - Beijing China bzero(&policy, sizeof (usb_pipe_policy_t));
45756f9a274Sfei feng - Sun Microsystems - Beijing China policy.pp_max_async_reqs = UATH_CMD_LIST_COUNT;
45856f9a274Sfei feng - Sun Microsystems - Beijing China
45956f9a274Sfei feng - Sun Microsystems - Beijing China err = usb_pipe_open(sc->sc_dev, &ep_node->ep_descr,
46056f9a274Sfei feng - Sun Microsystems - Beijing China &policy, USB_FLAGS_SLEEP, &sc->rx_cmd_pipe);
46156f9a274Sfei feng - Sun Microsystems - Beijing China if (err != USB_SUCCESS) {
46256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_open_pipes(): "
46356f9a274Sfei feng - Sun Microsystems - Beijing China "failed to open rx data pipe, err = %x\n",
46456f9a274Sfei feng - Sun Microsystems - Beijing China err);
46556f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
46656f9a274Sfei feng - Sun Microsystems - Beijing China }
46756f9a274Sfei feng - Sun Microsystems - Beijing China
46856f9a274Sfei feng - Sun Microsystems - Beijing China
46956f9a274Sfei feng - Sun Microsystems - Beijing China ep_node = uath_lookup_ep_data(sc->sc_dev, sc->sc_udev,
47056f9a274Sfei feng - Sun Microsystems - Beijing China 0, 0, 0x01, USB_EP_ATTR_BULK);
47156f9a274Sfei feng - Sun Microsystems - Beijing China ep_descr = &ep_node->ep_descr;
47256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_open_pipes(): "
47356f9a274Sfei feng - Sun Microsystems - Beijing China "find pipe %x\n",
47456f9a274Sfei feng - Sun Microsystems - Beijing China ep_descr->bEndpointAddress);
47556f9a274Sfei feng - Sun Microsystems - Beijing China
47656f9a274Sfei feng - Sun Microsystems - Beijing China bzero(&policy, sizeof (usb_pipe_policy_t));
47756f9a274Sfei feng - Sun Microsystems - Beijing China policy.pp_max_async_reqs = UATH_CMD_LIST_COUNT;
47856f9a274Sfei feng - Sun Microsystems - Beijing China
47956f9a274Sfei feng - Sun Microsystems - Beijing China err = usb_pipe_open(sc->sc_dev, &ep_node->ep_descr,
48056f9a274Sfei feng - Sun Microsystems - Beijing China &policy, USB_FLAGS_SLEEP, &sc->tx_cmd_pipe);
48156f9a274Sfei feng - Sun Microsystems - Beijing China if (err != USB_SUCCESS) {
48256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_open_pipes(): "
48356f9a274Sfei feng - Sun Microsystems - Beijing China "failed to open tx command pipe, err = %x\n",
48456f9a274Sfei feng - Sun Microsystems - Beijing China err);
48556f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
48656f9a274Sfei feng - Sun Microsystems - Beijing China }
48756f9a274Sfei feng - Sun Microsystems - Beijing China
48856f9a274Sfei feng - Sun Microsystems - Beijing China ep_node = uath_lookup_ep_data(sc->sc_dev, sc->sc_udev,
48956f9a274Sfei feng - Sun Microsystems - Beijing China 0, 0, 0x82, USB_EP_ATTR_BULK);
49056f9a274Sfei feng - Sun Microsystems - Beijing China ep_descr = &ep_node->ep_descr;
49156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_open_pipes(): "
49256f9a274Sfei feng - Sun Microsystems - Beijing China "find pipe %x\n",
49356f9a274Sfei feng - Sun Microsystems - Beijing China ep_descr->bEndpointAddress);
49456f9a274Sfei feng - Sun Microsystems - Beijing China
49556f9a274Sfei feng - Sun Microsystems - Beijing China bzero(&policy, sizeof (usb_pipe_policy_t));
49656f9a274Sfei feng - Sun Microsystems - Beijing China policy.pp_max_async_reqs = UATH_RX_DATA_LIST_COUNT;
49756f9a274Sfei feng - Sun Microsystems - Beijing China
49856f9a274Sfei feng - Sun Microsystems - Beijing China err = usb_pipe_open(sc->sc_dev, &ep_node->ep_descr,
49956f9a274Sfei feng - Sun Microsystems - Beijing China &policy, USB_FLAGS_SLEEP, &sc->rx_data_pipe);
50056f9a274Sfei feng - Sun Microsystems - Beijing China if (err != USB_SUCCESS) {
50156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_open_pipes(): "
50256f9a274Sfei feng - Sun Microsystems - Beijing China "failed to open tx pipe, err = %x\n",
50356f9a274Sfei feng - Sun Microsystems - Beijing China err);
50456f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
50556f9a274Sfei feng - Sun Microsystems - Beijing China }
50656f9a274Sfei feng - Sun Microsystems - Beijing China
50756f9a274Sfei feng - Sun Microsystems - Beijing China ep_node = uath_lookup_ep_data(sc->sc_dev, sc->sc_udev,
50856f9a274Sfei feng - Sun Microsystems - Beijing China 0, 0, 0x02, USB_EP_ATTR_BULK);
50956f9a274Sfei feng - Sun Microsystems - Beijing China ep_descr = &ep_node->ep_descr;
51056f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_open_pipes(): "
51156f9a274Sfei feng - Sun Microsystems - Beijing China "find pipe %x\n",
51256f9a274Sfei feng - Sun Microsystems - Beijing China ep_descr->bEndpointAddress);
51356f9a274Sfei feng - Sun Microsystems - Beijing China
51456f9a274Sfei feng - Sun Microsystems - Beijing China bzero(&policy, sizeof (usb_pipe_policy_t));
51556f9a274Sfei feng - Sun Microsystems - Beijing China policy.pp_max_async_reqs = UATH_TX_DATA_LIST_COUNT;
51656f9a274Sfei feng - Sun Microsystems - Beijing China
51756f9a274Sfei feng - Sun Microsystems - Beijing China err = usb_pipe_open(sc->sc_dev, &ep_node->ep_descr,
51856f9a274Sfei feng - Sun Microsystems - Beijing China &policy, USB_FLAGS_SLEEP, &sc->tx_data_pipe);
51956f9a274Sfei feng - Sun Microsystems - Beijing China if (err != USB_SUCCESS) {
52056f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_open_pipes(): "
52156f9a274Sfei feng - Sun Microsystems - Beijing China "failed to open rx command pipe, err = %x\n",
52256f9a274Sfei feng - Sun Microsystems - Beijing China err);
52356f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
52456f9a274Sfei feng - Sun Microsystems - Beijing China }
52556f9a274Sfei feng - Sun Microsystems - Beijing China
52656f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
52756f9a274Sfei feng - Sun Microsystems - Beijing China fail:
52856f9a274Sfei feng - Sun Microsystems - Beijing China uath_close_pipes(sc);
52956f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
53056f9a274Sfei feng - Sun Microsystems - Beijing China }
53156f9a274Sfei feng - Sun Microsystems - Beijing China
53256f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_close_pipes(struct uath_softc * sc)53356f9a274Sfei feng - Sun Microsystems - Beijing China uath_close_pipes(struct uath_softc *sc)
53456f9a274Sfei feng - Sun Microsystems - Beijing China {
53556f9a274Sfei feng - Sun Microsystems - Beijing China usb_flags_t flags = USB_FLAGS_SLEEP;
53656f9a274Sfei feng - Sun Microsystems - Beijing China
53756f9a274Sfei feng - Sun Microsystems - Beijing China if (sc->rx_cmd_pipe != NULL) {
53856f9a274Sfei feng - Sun Microsystems - Beijing China usb_pipe_reset(sc->sc_dev, sc->rx_cmd_pipe, flags, NULL, 0);
53956f9a274Sfei feng - Sun Microsystems - Beijing China usb_pipe_close(sc->sc_dev, sc->rx_cmd_pipe, flags, NULL, 0);
54056f9a274Sfei feng - Sun Microsystems - Beijing China sc->rx_cmd_pipe = NULL;
54156f9a274Sfei feng - Sun Microsystems - Beijing China }
54256f9a274Sfei feng - Sun Microsystems - Beijing China
54356f9a274Sfei feng - Sun Microsystems - Beijing China if (sc->tx_cmd_pipe != NULL) {
54456f9a274Sfei feng - Sun Microsystems - Beijing China usb_pipe_reset(sc->sc_dev, sc->tx_cmd_pipe, flags, NULL, 0);
54556f9a274Sfei feng - Sun Microsystems - Beijing China usb_pipe_close(sc->sc_dev, sc->tx_cmd_pipe, flags, NULL, 0);
54656f9a274Sfei feng - Sun Microsystems - Beijing China sc->tx_cmd_pipe = NULL;
54756f9a274Sfei feng - Sun Microsystems - Beijing China }
54856f9a274Sfei feng - Sun Microsystems - Beijing China
54956f9a274Sfei feng - Sun Microsystems - Beijing China if (sc->rx_data_pipe != NULL) {
55056f9a274Sfei feng - Sun Microsystems - Beijing China usb_pipe_reset(sc->sc_dev, sc->rx_data_pipe, flags, NULL, 0);
55156f9a274Sfei feng - Sun Microsystems - Beijing China usb_pipe_close(sc->sc_dev, sc->rx_data_pipe, flags, NULL, 0);
55256f9a274Sfei feng - Sun Microsystems - Beijing China sc->rx_data_pipe = NULL;
55356f9a274Sfei feng - Sun Microsystems - Beijing China }
55456f9a274Sfei feng - Sun Microsystems - Beijing China
55556f9a274Sfei feng - Sun Microsystems - Beijing China if (sc->tx_data_pipe != NULL) {
55656f9a274Sfei feng - Sun Microsystems - Beijing China usb_pipe_reset(sc->sc_dev, sc->tx_data_pipe, flags, NULL, 0);
55756f9a274Sfei feng - Sun Microsystems - Beijing China usb_pipe_close(sc->sc_dev, sc->tx_data_pipe, flags, NULL, 0);
55856f9a274Sfei feng - Sun Microsystems - Beijing China sc->tx_data_pipe = NULL;
55956f9a274Sfei feng - Sun Microsystems - Beijing China }
56056f9a274Sfei feng - Sun Microsystems - Beijing China
56156f9a274Sfei feng - Sun Microsystems - Beijing China }
56256f9a274Sfei feng - Sun Microsystems - Beijing China
56356f9a274Sfei feng - Sun Microsystems - Beijing China static const char *
uath_codename(int code)56456f9a274Sfei feng - Sun Microsystems - Beijing China uath_codename(int code)
56556f9a274Sfei feng - Sun Microsystems - Beijing China {
56656f9a274Sfei feng - Sun Microsystems - Beijing China #define N(a) (sizeof (a)/sizeof (a[0]))
56756f9a274Sfei feng - Sun Microsystems - Beijing China static const char *names[] = {
56856f9a274Sfei feng - Sun Microsystems - Beijing China "0x00",
56956f9a274Sfei feng - Sun Microsystems - Beijing China "HOST_AVAILABLE",
57056f9a274Sfei feng - Sun Microsystems - Beijing China "BIND",
57156f9a274Sfei feng - Sun Microsystems - Beijing China "TARGET_RESET",
57256f9a274Sfei feng - Sun Microsystems - Beijing China "TARGET_GET_CAPABILITY",
57356f9a274Sfei feng - Sun Microsystems - Beijing China "TARGET_SET_CONFIG",
57456f9a274Sfei feng - Sun Microsystems - Beijing China "TARGET_GET_STATUS",
57556f9a274Sfei feng - Sun Microsystems - Beijing China "TARGET_GET_STATS",
57656f9a274Sfei feng - Sun Microsystems - Beijing China "TARGET_START",
57756f9a274Sfei feng - Sun Microsystems - Beijing China "TARGET_STOP",
57856f9a274Sfei feng - Sun Microsystems - Beijing China "TARGET_ENABLE",
57956f9a274Sfei feng - Sun Microsystems - Beijing China "TARGET_DISABLE",
58056f9a274Sfei feng - Sun Microsystems - Beijing China "CREATE_CONNECTION",
58156f9a274Sfei feng - Sun Microsystems - Beijing China "UPDATE_CONNECT_ATTR",
58256f9a274Sfei feng - Sun Microsystems - Beijing China "DELETE_CONNECT",
58356f9a274Sfei feng - Sun Microsystems - Beijing China "SEND",
58456f9a274Sfei feng - Sun Microsystems - Beijing China "FLUSH",
58556f9a274Sfei feng - Sun Microsystems - Beijing China "STATS_UPDATE",
58656f9a274Sfei feng - Sun Microsystems - Beijing China "BMISS",
58756f9a274Sfei feng - Sun Microsystems - Beijing China "DEVICE_AVAIL",
58856f9a274Sfei feng - Sun Microsystems - Beijing China "SEND_COMPLETE",
58956f9a274Sfei feng - Sun Microsystems - Beijing China "DATA_AVAIL",
59056f9a274Sfei feng - Sun Microsystems - Beijing China "SET_PWR_MODE",
59156f9a274Sfei feng - Sun Microsystems - Beijing China "BMISS_ACK",
59256f9a274Sfei feng - Sun Microsystems - Beijing China "SET_LED_STEADY",
59356f9a274Sfei feng - Sun Microsystems - Beijing China "SET_LED_BLINK",
59456f9a274Sfei feng - Sun Microsystems - Beijing China "SETUP_BEACON_DESC",
59556f9a274Sfei feng - Sun Microsystems - Beijing China "BEACON_INIT",
59656f9a274Sfei feng - Sun Microsystems - Beijing China "RESET_KEY_CACHE",
59756f9a274Sfei feng - Sun Microsystems - Beijing China "RESET_KEY_CACHE_ENTRY",
59856f9a274Sfei feng - Sun Microsystems - Beijing China "SET_KEY_CACHE_ENTRY",
59956f9a274Sfei feng - Sun Microsystems - Beijing China "SET_DECOMP_MASK",
60056f9a274Sfei feng - Sun Microsystems - Beijing China "SET_REGULATORY_DOMAIN",
60156f9a274Sfei feng - Sun Microsystems - Beijing China "SET_LED_STATE",
60256f9a274Sfei feng - Sun Microsystems - Beijing China "WRITE_ASSOCID",
60356f9a274Sfei feng - Sun Microsystems - Beijing China "SET_STA_BEACON_TIMERS",
60456f9a274Sfei feng - Sun Microsystems - Beijing China "GET_TSF",
60556f9a274Sfei feng - Sun Microsystems - Beijing China "RESET_TSF",
60656f9a274Sfei feng - Sun Microsystems - Beijing China "SET_ADHOC_MODE",
60756f9a274Sfei feng - Sun Microsystems - Beijing China "SET_BASIC_RATE",
60856f9a274Sfei feng - Sun Microsystems - Beijing China "MIB_CONTROL",
60956f9a274Sfei feng - Sun Microsystems - Beijing China "GET_CHANNEL_DATA",
61056f9a274Sfei feng - Sun Microsystems - Beijing China "GET_CUR_RSSI",
61156f9a274Sfei feng - Sun Microsystems - Beijing China "SET_ANTENNA_SWITCH",
61256f9a274Sfei feng - Sun Microsystems - Beijing China "0x2c", "0x2d", "0x2e",
61356f9a274Sfei feng - Sun Microsystems - Beijing China "USE_SHORT_SLOT_TIME",
61456f9a274Sfei feng - Sun Microsystems - Beijing China "SET_POWER_MODE",
61556f9a274Sfei feng - Sun Microsystems - Beijing China "SETUP_PSPOLL_DESC",
61656f9a274Sfei feng - Sun Microsystems - Beijing China "SET_RX_MULTICAST_FILTER",
61756f9a274Sfei feng - Sun Microsystems - Beijing China "RX_FILTER",
61856f9a274Sfei feng - Sun Microsystems - Beijing China "PER_CALIBRATION",
61956f9a274Sfei feng - Sun Microsystems - Beijing China "RESET",
62056f9a274Sfei feng - Sun Microsystems - Beijing China "DISABLE",
62156f9a274Sfei feng - Sun Microsystems - Beijing China "PHY_DISABLE",
62256f9a274Sfei feng - Sun Microsystems - Beijing China "SET_TX_POWER_LIMIT",
62356f9a274Sfei feng - Sun Microsystems - Beijing China "SET_TX_QUEUE_PARAMS",
62456f9a274Sfei feng - Sun Microsystems - Beijing China "SETUP_TX_QUEUE",
62556f9a274Sfei feng - Sun Microsystems - Beijing China "RELEASE_TX_QUEUE",
62656f9a274Sfei feng - Sun Microsystems - Beijing China };
62756f9a274Sfei feng - Sun Microsystems - Beijing China static char buf[8];
62856f9a274Sfei feng - Sun Microsystems - Beijing China
62956f9a274Sfei feng - Sun Microsystems - Beijing China if (code < N(names))
63056f9a274Sfei feng - Sun Microsystems - Beijing China return (names[code]);
63156f9a274Sfei feng - Sun Microsystems - Beijing China if (code == WDCMSG_SET_DEFAULT_KEY)
63256f9a274Sfei feng - Sun Microsystems - Beijing China return ("SET_DEFAULT_KEY");
63356f9a274Sfei feng - Sun Microsystems - Beijing China
63456f9a274Sfei feng - Sun Microsystems - Beijing China (void) snprintf(buf, sizeof (buf), "0x%02x", code);
63556f9a274Sfei feng - Sun Microsystems - Beijing China return (buf);
63656f9a274Sfei feng - Sun Microsystems - Beijing China #undef N
63756f9a274Sfei feng - Sun Microsystems - Beijing China }
63856f9a274Sfei feng - Sun Microsystems - Beijing China
63956f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_fw_send(struct uath_softc * sc,usb_pipe_handle_t pipe,const void * data,size_t len)64056f9a274Sfei feng - Sun Microsystems - Beijing China uath_fw_send(struct uath_softc *sc, usb_pipe_handle_t pipe,
64156f9a274Sfei feng - Sun Microsystems - Beijing China const void *data, size_t len)
64256f9a274Sfei feng - Sun Microsystems - Beijing China {
64356f9a274Sfei feng - Sun Microsystems - Beijing China usb_bulk_req_t *send_req;
64456f9a274Sfei feng - Sun Microsystems - Beijing China mblk_t *mblk;
64556f9a274Sfei feng - Sun Microsystems - Beijing China int res;
64656f9a274Sfei feng - Sun Microsystems - Beijing China
64756f9a274Sfei feng - Sun Microsystems - Beijing China send_req = usb_alloc_bulk_req(sc->sc_dev, len, USB_FLAGS_SLEEP);
64856f9a274Sfei feng - Sun Microsystems - Beijing China
64956f9a274Sfei feng - Sun Microsystems - Beijing China send_req->bulk_len = (int)len;
65056f9a274Sfei feng - Sun Microsystems - Beijing China send_req->bulk_attributes = USB_ATTRS_AUTOCLEARING;
65156f9a274Sfei feng - Sun Microsystems - Beijing China send_req->bulk_timeout = UATH_CMD_TIMEOUT;
65256f9a274Sfei feng - Sun Microsystems - Beijing China
65356f9a274Sfei feng - Sun Microsystems - Beijing China mblk = send_req->bulk_data;
65456f9a274Sfei feng - Sun Microsystems - Beijing China bcopy(data, mblk->b_wptr, len);
65556f9a274Sfei feng - Sun Microsystems - Beijing China mblk->b_wptr += len;
65656f9a274Sfei feng - Sun Microsystems - Beijing China
65756f9a274Sfei feng - Sun Microsystems - Beijing China res = usb_pipe_bulk_xfer(pipe, send_req, USB_FLAGS_SLEEP);
65856f9a274Sfei feng - Sun Microsystems - Beijing China if (res != USB_SUCCESS) {
65956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_FW, "uath: uath_fw_send(): "
66056f9a274Sfei feng - Sun Microsystems - Beijing China "Error %x writing data to bulk/out pipe", res);
66156f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_FAILURE);
66256f9a274Sfei feng - Sun Microsystems - Beijing China }
66356f9a274Sfei feng - Sun Microsystems - Beijing China
66456f9a274Sfei feng - Sun Microsystems - Beijing China usb_free_bulk_req(send_req);
66556f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
66656f9a274Sfei feng - Sun Microsystems - Beijing China }
66756f9a274Sfei feng - Sun Microsystems - Beijing China
66856f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_fw_ack(struct uath_softc * sc,int len)66956f9a274Sfei feng - Sun Microsystems - Beijing China uath_fw_ack(struct uath_softc *sc, int len)
67056f9a274Sfei feng - Sun Microsystems - Beijing China {
67156f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_fwblock *rxblock;
67256f9a274Sfei feng - Sun Microsystems - Beijing China usb_bulk_req_t *req;
67356f9a274Sfei feng - Sun Microsystems - Beijing China mblk_t *mp;
67456f9a274Sfei feng - Sun Microsystems - Beijing China int err;
67556f9a274Sfei feng - Sun Microsystems - Beijing China
67656f9a274Sfei feng - Sun Microsystems - Beijing China req = usb_alloc_bulk_req(sc->sc_dev, len, USB_FLAGS_SLEEP);
67756f9a274Sfei feng - Sun Microsystems - Beijing China if (req == NULL) {
67856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_FW,
67956f9a274Sfei feng - Sun Microsystems - Beijing China "uath: uath_fw_ack(): "
68056f9a274Sfei feng - Sun Microsystems - Beijing China "uath_rx_transfer(): failed to allocate req");
68156f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_FAILURE);
68256f9a274Sfei feng - Sun Microsystems - Beijing China }
68356f9a274Sfei feng - Sun Microsystems - Beijing China
68456f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_len = len;
68556f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_client_private = (usb_opaque_t)sc;
68656f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_timeout = 0;
68756f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_attributes = USB_ATTRS_SHORT_XFER_OK
68856f9a274Sfei feng - Sun Microsystems - Beijing China | USB_ATTRS_AUTOCLEARING;
68956f9a274Sfei feng - Sun Microsystems - Beijing China
69056f9a274Sfei feng - Sun Microsystems - Beijing China err = usb_pipe_bulk_xfer(sc->rx_cmd_pipe, req, USB_FLAGS_SLEEP);
69156f9a274Sfei feng - Sun Microsystems - Beijing China if (err != USB_SUCCESS) {
69256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_FW, "uath: uath_fw_ack(): "
69356f9a274Sfei feng - Sun Microsystems - Beijing China "failed to do rx xfer, %d", err);
69456f9a274Sfei feng - Sun Microsystems - Beijing China usb_free_bulk_req(req);
69556f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_FAILURE);
69656f9a274Sfei feng - Sun Microsystems - Beijing China }
69756f9a274Sfei feng - Sun Microsystems - Beijing China
69856f9a274Sfei feng - Sun Microsystems - Beijing China mp = req->bulk_data;
69956f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_data = NULL;
70056f9a274Sfei feng - Sun Microsystems - Beijing China
70156f9a274Sfei feng - Sun Microsystems - Beijing China rxblock = (struct uath_fwblock *)mp->b_rptr;
70256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_FW, "uath: uath_fw_ack() "
70356f9a274Sfei feng - Sun Microsystems - Beijing China "rxblock flags=0x%x total=%d\n",
70456f9a274Sfei feng - Sun Microsystems - Beijing China BE_32(rxblock->flags), BE_32(rxblock->rxtotal));
70556f9a274Sfei feng - Sun Microsystems - Beijing China
70656f9a274Sfei feng - Sun Microsystems - Beijing China freemsg(mp);
70756f9a274Sfei feng - Sun Microsystems - Beijing China usb_free_bulk_req(req);
70856f9a274Sfei feng - Sun Microsystems - Beijing China
70956f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
71056f9a274Sfei feng - Sun Microsystems - Beijing China }
71156f9a274Sfei feng - Sun Microsystems - Beijing China
71256f9a274Sfei feng - Sun Microsystems - Beijing China /*
71356f9a274Sfei feng - Sun Microsystems - Beijing China * find uath firmware module's "_start" "_end" symbols
71456f9a274Sfei feng - Sun Microsystems - Beijing China * and get its size.
71556f9a274Sfei feng - Sun Microsystems - Beijing China */
71656f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_loadsym(ddi_modhandle_t modp,char * sym,char ** start,size_t * len)71756f9a274Sfei feng - Sun Microsystems - Beijing China uath_loadsym(ddi_modhandle_t modp, char *sym, char **start, size_t *len)
71856f9a274Sfei feng - Sun Microsystems - Beijing China {
71956f9a274Sfei feng - Sun Microsystems - Beijing China char start_sym[64];
72056f9a274Sfei feng - Sun Microsystems - Beijing China char end_sym[64];
72156f9a274Sfei feng - Sun Microsystems - Beijing China char *p, *end;
72256f9a274Sfei feng - Sun Microsystems - Beijing China int rv;
72356f9a274Sfei feng - Sun Microsystems - Beijing China size_t n;
72456f9a274Sfei feng - Sun Microsystems - Beijing China
72556f9a274Sfei feng - Sun Microsystems - Beijing China (void) snprintf(start_sym, sizeof (start_sym), "%s_start", sym);
72656f9a274Sfei feng - Sun Microsystems - Beijing China (void) snprintf(end_sym, sizeof (end_sym), "%s_end", sym);
72756f9a274Sfei feng - Sun Microsystems - Beijing China
72856f9a274Sfei feng - Sun Microsystems - Beijing China p = (char *)ddi_modsym(modp, start_sym, &rv);
72956f9a274Sfei feng - Sun Microsystems - Beijing China if (p == NULL || rv != 0) {
73056f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_loadsym(): "
73156f9a274Sfei feng - Sun Microsystems - Beijing China "mod %s: symbol %s not found\n", uath_fwmod, start_sym);
73256f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_FAILURE);
73356f9a274Sfei feng - Sun Microsystems - Beijing China }
73456f9a274Sfei feng - Sun Microsystems - Beijing China
73556f9a274Sfei feng - Sun Microsystems - Beijing China end = (char *)ddi_modsym(modp, end_sym, &rv);
73656f9a274Sfei feng - Sun Microsystems - Beijing China if (end == NULL || rv != 0) {
73756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_loadsym(): "
73856f9a274Sfei feng - Sun Microsystems - Beijing China "mod %s: symbol %s not found\n", uath_fwmod, end_sym);
73956f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_FAILURE);
74056f9a274Sfei feng - Sun Microsystems - Beijing China }
74156f9a274Sfei feng - Sun Microsystems - Beijing China
74256f9a274Sfei feng - Sun Microsystems - Beijing China n = _PTRDIFF(end, p);
74356f9a274Sfei feng - Sun Microsystems - Beijing China *start = p;
74456f9a274Sfei feng - Sun Microsystems - Beijing China *len = n;
74556f9a274Sfei feng - Sun Microsystems - Beijing China
74656f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
74756f9a274Sfei feng - Sun Microsystems - Beijing China }
74856f9a274Sfei feng - Sun Microsystems - Beijing China
74956f9a274Sfei feng - Sun Microsystems - Beijing China /*
75056f9a274Sfei feng - Sun Microsystems - Beijing China * Load the MIPS R4000 microcode into the device. Once the image is loaded,
75156f9a274Sfei feng - Sun Microsystems - Beijing China * the device will detach itself from the bus and reattach later with a new
75256f9a274Sfei feng - Sun Microsystems - Beijing China * product Id (a la ezusb). XXX this could also be implemented in userland
75356f9a274Sfei feng - Sun Microsystems - Beijing China * through /dev/ugen.
75456f9a274Sfei feng - Sun Microsystems - Beijing China */
75556f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_loadfirmware(struct uath_softc * sc)75656f9a274Sfei feng - Sun Microsystems - Beijing China uath_loadfirmware(struct uath_softc *sc)
75756f9a274Sfei feng - Sun Microsystems - Beijing China {
75856f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_fwblock txblock;
75956f9a274Sfei feng - Sun Microsystems - Beijing China ddi_modhandle_t modp;
76056f9a274Sfei feng - Sun Microsystems - Beijing China char *fw_index, *fw_image = NULL;
76156f9a274Sfei feng - Sun Microsystems - Beijing China size_t fw_size, len;
76256f9a274Sfei feng - Sun Microsystems - Beijing China int err = DDI_SUCCESS, rv = 0;
76356f9a274Sfei feng - Sun Microsystems - Beijing China
76456f9a274Sfei feng - Sun Microsystems - Beijing China modp = ddi_modopen(uath_fwmod, KRTLD_MODE_FIRST, &rv);
76556f9a274Sfei feng - Sun Microsystems - Beijing China if (modp == NULL) {
76656f9a274Sfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "uath: uath_loadfirmware(): "
76756f9a274Sfei feng - Sun Microsystems - Beijing China "module %s not found\n", uath_fwmod);
76856f9a274Sfei feng - Sun Microsystems - Beijing China goto label;
76956f9a274Sfei feng - Sun Microsystems - Beijing China }
77056f9a274Sfei feng - Sun Microsystems - Beijing China
77156f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_loadsym(modp, uath_binmod, &fw_index, &fw_size);
77256f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
77356f9a274Sfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "uath: uath_loadfirmware(): "
77456f9a274Sfei feng - Sun Microsystems - Beijing China "could not get firmware\n");
77556f9a274Sfei feng - Sun Microsystems - Beijing China goto label;
77656f9a274Sfei feng - Sun Microsystems - Beijing China }
77756f9a274Sfei feng - Sun Microsystems - Beijing China
77856f9a274Sfei feng - Sun Microsystems - Beijing China fw_image = (char *)kmem_alloc(fw_size, KM_SLEEP);
77956f9a274Sfei feng - Sun Microsystems - Beijing China if (fw_image == NULL) {
78056f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_loadfirmware(): "
78156f9a274Sfei feng - Sun Microsystems - Beijing China "failed to alloc firmware memory\n");
78256f9a274Sfei feng - Sun Microsystems - Beijing China err = UATH_FAILURE;
78356f9a274Sfei feng - Sun Microsystems - Beijing China goto label;
78456f9a274Sfei feng - Sun Microsystems - Beijing China }
78556f9a274Sfei feng - Sun Microsystems - Beijing China
78656f9a274Sfei feng - Sun Microsystems - Beijing China (void) memcpy(fw_image, fw_index, fw_size);
78756f9a274Sfei feng - Sun Microsystems - Beijing China fw_index = fw_image;
78856f9a274Sfei feng - Sun Microsystems - Beijing China len = fw_size;
78956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "loading firmware size = %lu\n", fw_size);
79056f9a274Sfei feng - Sun Microsystems - Beijing China
79156f9a274Sfei feng - Sun Microsystems - Beijing China /* bzero(txblock, sizeof (struct uath_fwblock)); */
79256f9a274Sfei feng - Sun Microsystems - Beijing China txblock.flags = BE_32(UATH_WRITE_BLOCK);
79356f9a274Sfei feng - Sun Microsystems - Beijing China txblock.total = BE_32(fw_size);
79456f9a274Sfei feng - Sun Microsystems - Beijing China
79556f9a274Sfei feng - Sun Microsystems - Beijing China while (len > 0) {
79656f9a274Sfei feng - Sun Microsystems - Beijing China size_t mlen = min(len, UATH_MAX_FWBLOCK_SIZE);
79756f9a274Sfei feng - Sun Microsystems - Beijing China
79856f9a274Sfei feng - Sun Microsystems - Beijing China txblock.remain = BE_32(len - mlen);
79956f9a274Sfei feng - Sun Microsystems - Beijing China txblock.len = BE_32(mlen);
80056f9a274Sfei feng - Sun Microsystems - Beijing China
80156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_FW, "uath: uath_loadfirmware(): "
80256f9a274Sfei feng - Sun Microsystems - Beijing China "sending firmware block: %d bytes sending\n", mlen);
80356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_FW, "uath: uath_loadfirmware(): "
80456f9a274Sfei feng - Sun Microsystems - Beijing China "sending firmware block: %d bytes remaining\n",
80556f9a274Sfei feng - Sun Microsystems - Beijing China len - mlen);
80656f9a274Sfei feng - Sun Microsystems - Beijing China
80756f9a274Sfei feng - Sun Microsystems - Beijing China /* send firmware block meta-data */
80856f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_fw_send(sc, sc->tx_cmd_pipe, &txblock,
80956f9a274Sfei feng - Sun Microsystems - Beijing China sizeof (struct uath_fwblock));
81056f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
81156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_FW, "uath: uath_loadfirmware(): "
81256f9a274Sfei feng - Sun Microsystems - Beijing China "send block meta-data error");
81356f9a274Sfei feng - Sun Microsystems - Beijing China goto label;
81456f9a274Sfei feng - Sun Microsystems - Beijing China }
81556f9a274Sfei feng - Sun Microsystems - Beijing China
81656f9a274Sfei feng - Sun Microsystems - Beijing China /* send firmware block data */
81756f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_fw_send(sc, sc->tx_data_pipe, fw_index, mlen);
81856f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
81956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_FW, "uath: uath_loadfirmware() "
82056f9a274Sfei feng - Sun Microsystems - Beijing China "send block data err");
82156f9a274Sfei feng - Sun Microsystems - Beijing China goto label;
82256f9a274Sfei feng - Sun Microsystems - Beijing China }
82356f9a274Sfei feng - Sun Microsystems - Beijing China
82456f9a274Sfei feng - Sun Microsystems - Beijing China /* wait for ack from firmware */
82556f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_fw_ack(sc, sizeof (struct uath_fwblock));
82656f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
82756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_FW, "uath: uath_loadfirmware() "
82856f9a274Sfei feng - Sun Microsystems - Beijing China "rx block ack err");
82956f9a274Sfei feng - Sun Microsystems - Beijing China goto label;
83056f9a274Sfei feng - Sun Microsystems - Beijing China }
83156f9a274Sfei feng - Sun Microsystems - Beijing China
83256f9a274Sfei feng - Sun Microsystems - Beijing China fw_index += mlen;
83356f9a274Sfei feng - Sun Microsystems - Beijing China len -= mlen;
83456f9a274Sfei feng - Sun Microsystems - Beijing China }
83556f9a274Sfei feng - Sun Microsystems - Beijing China
83656f9a274Sfei feng - Sun Microsystems - Beijing China label:
83756f9a274Sfei feng - Sun Microsystems - Beijing China if (fw_image != NULL)
83856f9a274Sfei feng - Sun Microsystems - Beijing China kmem_free(fw_image, fw_size);
83956f9a274Sfei feng - Sun Microsystems - Beijing China fw_image = fw_index = NULL;
84056f9a274Sfei feng - Sun Microsystems - Beijing China if (modp != NULL)
84156f9a274Sfei feng - Sun Microsystems - Beijing China (void) ddi_modclose(modp);
84256f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
84356f9a274Sfei feng - Sun Microsystems - Beijing China }
84456f9a274Sfei feng - Sun Microsystems - Beijing China
84556f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_alloc_cmd_list(struct uath_softc * sc,struct uath_cmd cmds[],int ncmd,int maxsz)84656f9a274Sfei feng - Sun Microsystems - Beijing China uath_alloc_cmd_list(struct uath_softc *sc, struct uath_cmd cmds[],
84756f9a274Sfei feng - Sun Microsystems - Beijing China int ncmd, int maxsz)
84856f9a274Sfei feng - Sun Microsystems - Beijing China {
84956f9a274Sfei feng - Sun Microsystems - Beijing China int i, err;
85056f9a274Sfei feng - Sun Microsystems - Beijing China
85156f9a274Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < ncmd; i++) {
85256f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_cmd *cmd = &cmds[i];
85356f9a274Sfei feng - Sun Microsystems - Beijing China
85456f9a274Sfei feng - Sun Microsystems - Beijing China cmd->sc = sc; /* backpointer for callbacks */
85556f9a274Sfei feng - Sun Microsystems - Beijing China cmd->msgid = i;
85656f9a274Sfei feng - Sun Microsystems - Beijing China cmd->buf = kmem_zalloc(maxsz, KM_NOSLEEP);
85756f9a274Sfei feng - Sun Microsystems - Beijing China if (cmd->buf == NULL) {
85856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_alloc_cmd_list(): "
85956f9a274Sfei feng - Sun Microsystems - Beijing China "could not allocate xfer buffer\n");
86056f9a274Sfei feng - Sun Microsystems - Beijing China err = DDI_ENOMEM;
86156f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
86256f9a274Sfei feng - Sun Microsystems - Beijing China }
86356f9a274Sfei feng - Sun Microsystems - Beijing China }
86456f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
86556f9a274Sfei feng - Sun Microsystems - Beijing China
86656f9a274Sfei feng - Sun Microsystems - Beijing China fail:
86756f9a274Sfei feng - Sun Microsystems - Beijing China uath_free_cmd_list(cmds, ncmd);
86856f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
86956f9a274Sfei feng - Sun Microsystems - Beijing China }
87056f9a274Sfei feng - Sun Microsystems - Beijing China
87156f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_init_cmd_list(struct uath_softc * sc)87256f9a274Sfei feng - Sun Microsystems - Beijing China uath_init_cmd_list(struct uath_softc *sc)
87356f9a274Sfei feng - Sun Microsystems - Beijing China {
87456f9a274Sfei feng - Sun Microsystems - Beijing China int i;
87556f9a274Sfei feng - Sun Microsystems - Beijing China
87656f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_cmdid = sc->rx_cmd_queued = sc->tx_cmd_queued = 0;
87756f9a274Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < UATH_CMD_LIST_COUNT; i++) {
87856f9a274Sfei feng - Sun Microsystems - Beijing China if (uath_rx_cmd_xfer(sc) != UATH_SUCCESS) {
87956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_init_cmd_list(): "
88056f9a274Sfei feng - Sun Microsystems - Beijing China "failed to init cmd list %x\n", i);
88156f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_FAILURE);
88256f9a274Sfei feng - Sun Microsystems - Beijing China }
88356f9a274Sfei feng - Sun Microsystems - Beijing China }
88456f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
88556f9a274Sfei feng - Sun Microsystems - Beijing China }
88656f9a274Sfei feng - Sun Microsystems - Beijing China
88756f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_free_cmd_list(struct uath_cmd cmds[],int ncmd)88856f9a274Sfei feng - Sun Microsystems - Beijing China uath_free_cmd_list(struct uath_cmd cmds[], int ncmd)
88956f9a274Sfei feng - Sun Microsystems - Beijing China {
89056f9a274Sfei feng - Sun Microsystems - Beijing China int i;
89156f9a274Sfei feng - Sun Microsystems - Beijing China
89256f9a274Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < ncmd; i++)
89356f9a274Sfei feng - Sun Microsystems - Beijing China if (cmds[i].buf != NULL) {
89456f9a274Sfei feng - Sun Microsystems - Beijing China kmem_free(cmds[i].buf, UATH_MAX_CMDSZ);
89556f9a274Sfei feng - Sun Microsystems - Beijing China cmds[i].buf = NULL;
89656f9a274Sfei feng - Sun Microsystems - Beijing China }
89756f9a274Sfei feng - Sun Microsystems - Beijing China }
89856f9a274Sfei feng - Sun Microsystems - Beijing China
89956f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_host_available(struct uath_softc * sc)90056f9a274Sfei feng - Sun Microsystems - Beijing China uath_host_available(struct uath_softc *sc)
90156f9a274Sfei feng - Sun Microsystems - Beijing China {
90256f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_cmd_host_available setup;
90356f9a274Sfei feng - Sun Microsystems - Beijing China
90456f9a274Sfei feng - Sun Microsystems - Beijing China /* inform target the host is available */
90556f9a274Sfei feng - Sun Microsystems - Beijing China setup.sw_ver_major = BE_32(ATH_SW_VER_MAJOR);
90656f9a274Sfei feng - Sun Microsystems - Beijing China setup.sw_ver_minor = BE_32(ATH_SW_VER_MINOR);
90756f9a274Sfei feng - Sun Microsystems - Beijing China setup.sw_ver_patch = BE_32(ATH_SW_VER_PATCH);
90856f9a274Sfei feng - Sun Microsystems - Beijing China setup.sw_ver_build = BE_32(ATH_SW_VER_BUILD);
90956f9a274Sfei feng - Sun Microsystems - Beijing China return (uath_cmd_read(sc, WDCMSG_HOST_AVAILABLE,
91056f9a274Sfei feng - Sun Microsystems - Beijing China &setup, sizeof (setup), NULL, 0, 0));
91156f9a274Sfei feng - Sun Microsystems - Beijing China }
91256f9a274Sfei feng - Sun Microsystems - Beijing China
91356f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_get_capability(struct uath_softc * sc,uint32_t cap,uint32_t * val)91456f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(struct uath_softc *sc, uint32_t cap, uint32_t *val)
91556f9a274Sfei feng - Sun Microsystems - Beijing China {
91656f9a274Sfei feng - Sun Microsystems - Beijing China int err;
91756f9a274Sfei feng - Sun Microsystems - Beijing China
91856f9a274Sfei feng - Sun Microsystems - Beijing China cap = BE_32(cap);
91956f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_cmd_read(sc, WDCMSG_TARGET_GET_CAPABILITY, &cap,
92056f9a274Sfei feng - Sun Microsystems - Beijing China sizeof (cap), val, sizeof (uint32_t), UATH_CMD_FLAG_MAGIC);
92156f9a274Sfei feng - Sun Microsystems - Beijing China if (err == UATH_SUCCESS)
92256f9a274Sfei feng - Sun Microsystems - Beijing China *val = BE_32(*val);
92356f9a274Sfei feng - Sun Microsystems - Beijing China else
92456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_get_capability(): "
92556f9a274Sfei feng - Sun Microsystems - Beijing China "could not read capability %u\n", BE_32(cap));
92656f9a274Sfei feng - Sun Microsystems - Beijing China }
92756f9a274Sfei feng - Sun Microsystems - Beijing China
92856f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_get_devcap(struct uath_softc * sc)92956f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_devcap(struct uath_softc *sc)
93056f9a274Sfei feng - Sun Microsystems - Beijing China {
93156f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_devcap *cap = &sc->sc_devcap;
93256f9a274Sfei feng - Sun Microsystems - Beijing China
93356f9a274Sfei feng - Sun Microsystems - Beijing China /* collect device capabilities */
93456f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_TARGET_VERSION,
93556f9a274Sfei feng - Sun Microsystems - Beijing China &cap->targetVersion);
93656f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_TARGET_REVISION,
93756f9a274Sfei feng - Sun Microsystems - Beijing China &cap->targetRevision);
93856f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_MAC_VERSION,
93956f9a274Sfei feng - Sun Microsystems - Beijing China &cap->macVersion);
94056f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_MAC_REVISION,
94156f9a274Sfei feng - Sun Microsystems - Beijing China &cap->macRevision);
94256f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_PHY_REVISION,
94356f9a274Sfei feng - Sun Microsystems - Beijing China &cap->phyRevision);
94456f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_ANALOG_5GHz_REVISION,
94556f9a274Sfei feng - Sun Microsystems - Beijing China &cap->analog5GhzRevision);
94656f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_ANALOG_2GHz_REVISION,
94756f9a274Sfei feng - Sun Microsystems - Beijing China &cap->analog2GhzRevision);
94856f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_REG_DOMAIN,
94956f9a274Sfei feng - Sun Microsystems - Beijing China &cap->regDomain);
95056f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_REG_CAP_BITS,
95156f9a274Sfei feng - Sun Microsystems - Beijing China &cap->regCapBits);
95256f9a274Sfei feng - Sun Microsystems - Beijing China
95356f9a274Sfei feng - Sun Microsystems - Beijing China /* NB: not supported in rev 1.5 */
95456f9a274Sfei feng - Sun Microsystems - Beijing China /* uath_get_capability(sc, CAP_COUNTRY_CODE, cap->countryCode); */
95556f9a274Sfei feng - Sun Microsystems - Beijing China
95656f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_WIRELESS_MODES,
95756f9a274Sfei feng - Sun Microsystems - Beijing China &cap->wirelessModes);
95856f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_CHAN_SPREAD_SUPPORT,
95956f9a274Sfei feng - Sun Microsystems - Beijing China &cap->chanSpreadSupport);
96056f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_COMPRESS_SUPPORT,
96156f9a274Sfei feng - Sun Microsystems - Beijing China &cap->compressSupport);
96256f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_BURST_SUPPORT,
96356f9a274Sfei feng - Sun Microsystems - Beijing China &cap->burstSupport);
96456f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_FAST_FRAMES_SUPPORT,
96556f9a274Sfei feng - Sun Microsystems - Beijing China &cap->fastFramesSupport);
96656f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_CHAP_TUNING_SUPPORT,
96756f9a274Sfei feng - Sun Microsystems - Beijing China &cap->chapTuningSupport);
96856f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_TURBOG_SUPPORT,
96956f9a274Sfei feng - Sun Microsystems - Beijing China &cap->turboGSupport);
97056f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_TURBO_PRIME_SUPPORT,
97156f9a274Sfei feng - Sun Microsystems - Beijing China &cap->turboPrimeSupport);
97256f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_DEVICE_TYPE,
97356f9a274Sfei feng - Sun Microsystems - Beijing China &cap->deviceType);
97456f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_WME_SUPPORT,
97556f9a274Sfei feng - Sun Microsystems - Beijing China &cap->wmeSupport);
97656f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_TOTAL_QUEUES,
97756f9a274Sfei feng - Sun Microsystems - Beijing China &cap->numTxQueues);
97856f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_CONNECTION_ID_MAX,
97956f9a274Sfei feng - Sun Microsystems - Beijing China &cap->connectionIdMax);
98056f9a274Sfei feng - Sun Microsystems - Beijing China
98156f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_LOW_5GHZ_CHAN,
98256f9a274Sfei feng - Sun Microsystems - Beijing China &cap->low5GhzChan);
98356f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_HIGH_5GHZ_CHAN,
98456f9a274Sfei feng - Sun Microsystems - Beijing China &cap->high5GhzChan);
98556f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_LOW_2GHZ_CHAN,
98656f9a274Sfei feng - Sun Microsystems - Beijing China &cap->low2GhzChan);
98756f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_HIGH_2GHZ_CHAN,
98856f9a274Sfei feng - Sun Microsystems - Beijing China &cap->high2GhzChan);
98956f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_TWICE_ANTENNAGAIN_5G,
99056f9a274Sfei feng - Sun Microsystems - Beijing China &cap->twiceAntennaGain5G);
99156f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_TWICE_ANTENNAGAIN_2G,
99256f9a274Sfei feng - Sun Microsystems - Beijing China &cap->twiceAntennaGain2G);
99356f9a274Sfei feng - Sun Microsystems - Beijing China
99456f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_CIPHER_AES_CCM,
99556f9a274Sfei feng - Sun Microsystems - Beijing China &cap->supportCipherAES_CCM);
99656f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_CIPHER_TKIP,
99756f9a274Sfei feng - Sun Microsystems - Beijing China &cap->supportCipherTKIP);
99856f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_capability(sc, CAP_MIC_TKIP,
99956f9a274Sfei feng - Sun Microsystems - Beijing China &cap->supportMicTKIP);
100056f9a274Sfei feng - Sun Microsystems - Beijing China
100156f9a274Sfei feng - Sun Microsystems - Beijing China cap->supportCipherWEP = 1; /* NB: always available */
100256f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
100356f9a274Sfei feng - Sun Microsystems - Beijing China }
100456f9a274Sfei feng - Sun Microsystems - Beijing China
100556f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_get_status(struct uath_softc * sc,uint32_t which,void * odata,int olen)100656f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_status(struct uath_softc *sc, uint32_t which, void *odata, int olen)
100756f9a274Sfei feng - Sun Microsystems - Beijing China {
100856f9a274Sfei feng - Sun Microsystems - Beijing China int err;
100956f9a274Sfei feng - Sun Microsystems - Beijing China
101056f9a274Sfei feng - Sun Microsystems - Beijing China which = BE_32(which);
101156f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_cmd_read(sc, WDCMSG_TARGET_GET_STATUS,
101256f9a274Sfei feng - Sun Microsystems - Beijing China &which, sizeof (which), odata, olen, UATH_CMD_FLAG_MAGIC);
101356f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS)
101456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_get_status(): "
101556f9a274Sfei feng - Sun Microsystems - Beijing China "could not read EEPROM offset 0x%02x\n", BE_32(which));
101656f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
101756f9a274Sfei feng - Sun Microsystems - Beijing China }
101856f9a274Sfei feng - Sun Microsystems - Beijing China
101956f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_get_devstatus(struct uath_softc * sc,uint8_t macaddr[IEEE80211_ADDR_LEN])102056f9a274Sfei feng - Sun Microsystems - Beijing China uath_get_devstatus(struct uath_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
102156f9a274Sfei feng - Sun Microsystems - Beijing China {
102256f9a274Sfei feng - Sun Microsystems - Beijing China int err;
102356f9a274Sfei feng - Sun Microsystems - Beijing China
102456f9a274Sfei feng - Sun Microsystems - Beijing China /* retrieve MAC address */
102556f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_get_status(sc, ST_MAC_ADDR, macaddr, IEEE80211_ADDR_LEN);
102656f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
102756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_get_devstatus(): "
102856f9a274Sfei feng - Sun Microsystems - Beijing China "could not read MAC address\n");
102956f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
103056f9a274Sfei feng - Sun Microsystems - Beijing China }
103156f9a274Sfei feng - Sun Microsystems - Beijing China
103256f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_get_status(sc, ST_SERIAL_NUMBER,
103356f9a274Sfei feng - Sun Microsystems - Beijing China &sc->sc_serial[0], sizeof (sc->sc_serial));
103456f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
103556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_get_devstatus(): "
103656f9a274Sfei feng - Sun Microsystems - Beijing China "could not read device serial number\n");
103756f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
103856f9a274Sfei feng - Sun Microsystems - Beijing China }
103956f9a274Sfei feng - Sun Microsystems - Beijing China
104056f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
104156f9a274Sfei feng - Sun Microsystems - Beijing China }
104256f9a274Sfei feng - Sun Microsystems - Beijing China
104356f9a274Sfei feng - Sun Microsystems - Beijing China /*
104456f9a274Sfei feng - Sun Microsystems - Beijing China * uath_cmd_lock: a special signal structure that is used for notification
104556f9a274Sfei feng - Sun Microsystems - Beijing China * that a callback function has been called.
104656f9a274Sfei feng - Sun Microsystems - Beijing China */
104756f9a274Sfei feng - Sun Microsystems - Beijing China
104856f9a274Sfei feng - Sun Microsystems - Beijing China /* Initializes the uath_cmd_lock structure. */
104956f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_cmd_lock_init(struct uath_cmd_lock * lock)105056f9a274Sfei feng - Sun Microsystems - Beijing China uath_cmd_lock_init(struct uath_cmd_lock *lock)
105156f9a274Sfei feng - Sun Microsystems - Beijing China {
105256f9a274Sfei feng - Sun Microsystems - Beijing China ASSERT(lock != NULL);
105356f9a274Sfei feng - Sun Microsystems - Beijing China mutex_init(&lock->mutex, NULL, MUTEX_DRIVER, NULL);
105456f9a274Sfei feng - Sun Microsystems - Beijing China cv_init(&lock->cv, NULL, CV_DRIVER, NULL);
105556f9a274Sfei feng - Sun Microsystems - Beijing China lock->done = B_FALSE;
105656f9a274Sfei feng - Sun Microsystems - Beijing China }
105756f9a274Sfei feng - Sun Microsystems - Beijing China
105856f9a274Sfei feng - Sun Microsystems - Beijing China /* Deinitalizes the uath_cb_lock structure. */
105956f9a274Sfei feng - Sun Microsystems - Beijing China void
uath_cmd_lock_destroy(struct uath_cmd_lock * lock)106056f9a274Sfei feng - Sun Microsystems - Beijing China uath_cmd_lock_destroy(struct uath_cmd_lock *lock)
106156f9a274Sfei feng - Sun Microsystems - Beijing China {
106256f9a274Sfei feng - Sun Microsystems - Beijing China ASSERT(lock != NULL);
106356f9a274Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&lock->mutex);
106456f9a274Sfei feng - Sun Microsystems - Beijing China cv_destroy(&lock->cv);
106556f9a274Sfei feng - Sun Microsystems - Beijing China }
106656f9a274Sfei feng - Sun Microsystems - Beijing China
106756f9a274Sfei feng - Sun Microsystems - Beijing China /*
106856f9a274Sfei feng - Sun Microsystems - Beijing China * Wait on lock until someone calls the "signal" function or the timeout
106956f9a274Sfei feng - Sun Microsystems - Beijing China * expires. Note: timeout is in microseconds.
107056f9a274Sfei feng - Sun Microsystems - Beijing China */
107156f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_cmd_lock_wait(struct uath_cmd_lock * lock,clock_t timeout)107256f9a274Sfei feng - Sun Microsystems - Beijing China uath_cmd_lock_wait(struct uath_cmd_lock *lock, clock_t timeout)
107356f9a274Sfei feng - Sun Microsystems - Beijing China {
107456f9a274Sfei feng - Sun Microsystems - Beijing China int res, cv_res;
107556f9a274Sfei feng - Sun Microsystems - Beijing China clock_t etime;
107656f9a274Sfei feng - Sun Microsystems - Beijing China
107756f9a274Sfei feng - Sun Microsystems - Beijing China ASSERT(lock != NULL);
107856f9a274Sfei feng - Sun Microsystems - Beijing China mutex_enter(&lock->mutex);
107956f9a274Sfei feng - Sun Microsystems - Beijing China
108056f9a274Sfei feng - Sun Microsystems - Beijing China if (timeout < 0) {
108156f9a274Sfei feng - Sun Microsystems - Beijing China /* no timeout - wait as long as needed */
108256f9a274Sfei feng - Sun Microsystems - Beijing China while (lock->done == B_FALSE)
108356f9a274Sfei feng - Sun Microsystems - Beijing China cv_wait(&lock->cv, &lock->mutex);
108456f9a274Sfei feng - Sun Microsystems - Beijing China } else {
108556f9a274Sfei feng - Sun Microsystems - Beijing China /* wait with timeout (given in usec) */
108656f9a274Sfei feng - Sun Microsystems - Beijing China etime = ddi_get_lbolt() + drv_usectohz(timeout);
108756f9a274Sfei feng - Sun Microsystems - Beijing China while (lock->done == B_FALSE) {
108856f9a274Sfei feng - Sun Microsystems - Beijing China cv_res = cv_timedwait_sig(&lock->cv,
108956f9a274Sfei feng - Sun Microsystems - Beijing China &lock->mutex, etime);
109056f9a274Sfei feng - Sun Microsystems - Beijing China if (cv_res <= 0) break;
109156f9a274Sfei feng - Sun Microsystems - Beijing China }
109256f9a274Sfei feng - Sun Microsystems - Beijing China }
109356f9a274Sfei feng - Sun Microsystems - Beijing China
109456f9a274Sfei feng - Sun Microsystems - Beijing China res = (lock->done == B_TRUE) ? UATH_SUCCESS : UATH_FAILURE;
109556f9a274Sfei feng - Sun Microsystems - Beijing China mutex_exit(&lock->mutex);
109656f9a274Sfei feng - Sun Microsystems - Beijing China
109756f9a274Sfei feng - Sun Microsystems - Beijing China return (res);
109856f9a274Sfei feng - Sun Microsystems - Beijing China }
109956f9a274Sfei feng - Sun Microsystems - Beijing China
110056f9a274Sfei feng - Sun Microsystems - Beijing China /* Signal that the job (eg. callback) is done and unblock anyone who waits. */
110156f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_cmd_lock_signal(struct uath_cmd_lock * lock)110256f9a274Sfei feng - Sun Microsystems - Beijing China uath_cmd_lock_signal(struct uath_cmd_lock *lock)
110356f9a274Sfei feng - Sun Microsystems - Beijing China {
110456f9a274Sfei feng - Sun Microsystems - Beijing China ASSERT(lock != NULL);
110556f9a274Sfei feng - Sun Microsystems - Beijing China
110656f9a274Sfei feng - Sun Microsystems - Beijing China mutex_enter(&lock->mutex);
110756f9a274Sfei feng - Sun Microsystems - Beijing China lock->done = B_TRUE;
110856f9a274Sfei feng - Sun Microsystems - Beijing China cv_broadcast(&lock->cv);
110956f9a274Sfei feng - Sun Microsystems - Beijing China mutex_exit(&lock->mutex);
111056f9a274Sfei feng - Sun Microsystems - Beijing China }
111156f9a274Sfei feng - Sun Microsystems - Beijing China
111256f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_cmd_read(struct uath_softc * sc,uint32_t code,const void * idata,int ilen,void * odata,int olen,int flags)111356f9a274Sfei feng - Sun Microsystems - Beijing China uath_cmd_read(struct uath_softc *sc, uint32_t code, const void *idata,
111456f9a274Sfei feng - Sun Microsystems - Beijing China int ilen, void *odata, int olen, int flags)
111556f9a274Sfei feng - Sun Microsystems - Beijing China {
111656f9a274Sfei feng - Sun Microsystems - Beijing China flags |= UATH_CMD_FLAG_READ;
111756f9a274Sfei feng - Sun Microsystems - Beijing China return (uath_cmdsend(sc, code, idata, ilen, odata, olen, flags));
111856f9a274Sfei feng - Sun Microsystems - Beijing China }
111956f9a274Sfei feng - Sun Microsystems - Beijing China
112056f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_cmd_write(struct uath_softc * sc,uint32_t code,const void * data,int len,int flags)112156f9a274Sfei feng - Sun Microsystems - Beijing China uath_cmd_write(struct uath_softc *sc, uint32_t code, const void *data,
112256f9a274Sfei feng - Sun Microsystems - Beijing China int len, int flags)
112356f9a274Sfei feng - Sun Microsystems - Beijing China {
112456f9a274Sfei feng - Sun Microsystems - Beijing China flags &= ~UATH_CMD_FLAG_READ;
112556f9a274Sfei feng - Sun Microsystems - Beijing China return (uath_cmdsend(sc, code, data, len, NULL, 0, flags));
112656f9a274Sfei feng - Sun Microsystems - Beijing China }
112756f9a274Sfei feng - Sun Microsystems - Beijing China
112856f9a274Sfei feng - Sun Microsystems - Beijing China /*
112956f9a274Sfei feng - Sun Microsystems - Beijing China * Low-level function to send read or write commands to the firmware.
113056f9a274Sfei feng - Sun Microsystems - Beijing China */
113156f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_cmdsend(struct uath_softc * sc,uint32_t code,const void * idata,int ilen,void * odata,int olen,int flags)113256f9a274Sfei feng - Sun Microsystems - Beijing China uath_cmdsend(struct uath_softc *sc, uint32_t code, const void *idata, int ilen,
113356f9a274Sfei feng - Sun Microsystems - Beijing China void *odata, int olen, int flags)
113456f9a274Sfei feng - Sun Microsystems - Beijing China {
113556f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_cmd_hdr *hdr;
113656f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_cmd *cmd;
113756f9a274Sfei feng - Sun Microsystems - Beijing China int err;
113856f9a274Sfei feng - Sun Microsystems - Beijing China
113956f9a274Sfei feng - Sun Microsystems - Beijing China /* grab a xfer */
114056f9a274Sfei feng - Sun Microsystems - Beijing China cmd = &sc->sc_cmd[sc->sc_cmdid];
114156f9a274Sfei feng - Sun Microsystems - Beijing China
114256f9a274Sfei feng - Sun Microsystems - Beijing China cmd->flags = flags;
114356f9a274Sfei feng - Sun Microsystems - Beijing China /* always bulk-out a multiple of 4 bytes */
114456f9a274Sfei feng - Sun Microsystems - Beijing China cmd->buflen = (sizeof (struct uath_cmd_hdr) + ilen + 3) & ~3;
114556f9a274Sfei feng - Sun Microsystems - Beijing China
114656f9a274Sfei feng - Sun Microsystems - Beijing China hdr = (struct uath_cmd_hdr *)cmd->buf;
114756f9a274Sfei feng - Sun Microsystems - Beijing China bzero(hdr, sizeof (struct uath_cmd_hdr));
114856f9a274Sfei feng - Sun Microsystems - Beijing China hdr->len = BE_32(cmd->buflen);
114956f9a274Sfei feng - Sun Microsystems - Beijing China hdr->code = BE_32(code);
115056f9a274Sfei feng - Sun Microsystems - Beijing China hdr->msgid = cmd->msgid; /* don't care about endianness */
115156f9a274Sfei feng - Sun Microsystems - Beijing China hdr->magic = BE_32((cmd->flags & UATH_CMD_FLAG_MAGIC) ? 1 << 24 : 0);
115256f9a274Sfei feng - Sun Microsystems - Beijing China bcopy(idata, (uint8_t *)(hdr + 1), ilen);
115356f9a274Sfei feng - Sun Microsystems - Beijing China
115456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_TX_CMD, "uath: uath_cmdsend(): "
115556f9a274Sfei feng - Sun Microsystems - Beijing China "queue %x send %s [flags 0x%x] olen %d\n",
115656f9a274Sfei feng - Sun Microsystems - Beijing China cmd->msgid, uath_codename(code), cmd->flags, olen);
115756f9a274Sfei feng - Sun Microsystems - Beijing China
115856f9a274Sfei feng - Sun Microsystems - Beijing China cmd->odata = odata;
115956f9a274Sfei feng - Sun Microsystems - Beijing China if (odata == NULL)
116056f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_TX_CMD, "uath: uath_cmdsend(): "
116156f9a274Sfei feng - Sun Microsystems - Beijing China "warning - odata is NULL\n");
116256f9a274Sfei feng - Sun Microsystems - Beijing China else if (olen < UATH_MAX_CMDSZ - sizeof (*hdr) + sizeof (uint32_t))
116356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_TX_CMD, "uath: uath_cmdsend(): "
116456f9a274Sfei feng - Sun Microsystems - Beijing China "warning - olen %x is short\n, olen");
116556f9a274Sfei feng - Sun Microsystems - Beijing China cmd->olen = olen;
116656f9a274Sfei feng - Sun Microsystems - Beijing China
116756f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_tx_cmd_xfer(sc, sc->tx_cmd_pipe, cmd->buf, cmd->buflen);
116856f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
116956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_cmdsend(): "
117056f9a274Sfei feng - Sun Microsystems - Beijing China "Error writing command\n");
117156f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_FAILURE);
117256f9a274Sfei feng - Sun Microsystems - Beijing China }
117356f9a274Sfei feng - Sun Microsystems - Beijing China
117456f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_cmdid = (sc->sc_cmdid + 1) % UATH_CMD_LIST_COUNT;
117556f9a274Sfei feng - Sun Microsystems - Beijing China
117656f9a274Sfei feng - Sun Microsystems - Beijing China if (cmd->flags & UATH_CMD_FLAG_READ) {
117756f9a274Sfei feng - Sun Microsystems - Beijing China /* wait at most two seconds for command reply */
117856f9a274Sfei feng - Sun Microsystems - Beijing China uath_cmd_lock_init(&sc->rlock);
117956f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_cmd_lock_wait(&sc->rlock, 2000000);
118056f9a274Sfei feng - Sun Microsystems - Beijing China cmd->odata = NULL; /* in case reply comes too late */
118156f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
118256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_cmdsend(): "
118356f9a274Sfei feng - Sun Microsystems - Beijing China "timeout waiting for reply, "
118456f9a274Sfei feng - Sun Microsystems - Beijing China "to cmd 0x%x (%u), queue %x\n",
118556f9a274Sfei feng - Sun Microsystems - Beijing China code, code, cmd->msgid);
118656f9a274Sfei feng - Sun Microsystems - Beijing China err = UATH_FAILURE;
118756f9a274Sfei feng - Sun Microsystems - Beijing China } else if (cmd->olen != olen) {
118856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_cmdsend(): "
118956f9a274Sfei feng - Sun Microsystems - Beijing China "unexpected reply data count "
119056f9a274Sfei feng - Sun Microsystems - Beijing China "to cmd 0x%x (%x), got %u, expected %u\n",
119156f9a274Sfei feng - Sun Microsystems - Beijing China code, cmd->msgid, cmd->olen, olen);
119256f9a274Sfei feng - Sun Microsystems - Beijing China err = UATH_FAILURE;
119356f9a274Sfei feng - Sun Microsystems - Beijing China }
119456f9a274Sfei feng - Sun Microsystems - Beijing China uath_cmd_lock_destroy(&sc->rlock);
119556f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
119656f9a274Sfei feng - Sun Microsystems - Beijing China }
119756f9a274Sfei feng - Sun Microsystems - Beijing China
119856f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
119956f9a274Sfei feng - Sun Microsystems - Beijing China }
120056f9a274Sfei feng - Sun Microsystems - Beijing China
120156f9a274Sfei feng - Sun Microsystems - Beijing China /* ARGSUSED */
120256f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_cmd_txeof(usb_pipe_handle_t pipe,struct usb_bulk_req * req)120356f9a274Sfei feng - Sun Microsystems - Beijing China uath_cmd_txeof(usb_pipe_handle_t pipe, struct usb_bulk_req *req)
120456f9a274Sfei feng - Sun Microsystems - Beijing China {
120556f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc = (struct uath_softc *)req->bulk_client_private;
120656f9a274Sfei feng - Sun Microsystems - Beijing China
120756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_TX_CMD, "uath: uath_cmd_txeof(): "
120856f9a274Sfei feng - Sun Microsystems - Beijing China "cr:%s(%d), flags:0x%x, tx queued %d\n",
120956f9a274Sfei feng - Sun Microsystems - Beijing China usb_str_cr(req->bulk_completion_reason),
121056f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_completion_reason,
121156f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_cb_flags,
121256f9a274Sfei feng - Sun Microsystems - Beijing China sc->tx_cmd_queued);
121356f9a274Sfei feng - Sun Microsystems - Beijing China
121456f9a274Sfei feng - Sun Microsystems - Beijing China if (req->bulk_completion_reason != USB_CR_OK)
121556f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_tx_err++;
121656f9a274Sfei feng - Sun Microsystems - Beijing China
121756f9a274Sfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_txlock_cmd);
121856f9a274Sfei feng - Sun Microsystems - Beijing China sc->tx_cmd_queued--;
121956f9a274Sfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_txlock_cmd);
122056f9a274Sfei feng - Sun Microsystems - Beijing China usb_free_bulk_req(req);
122156f9a274Sfei feng - Sun Microsystems - Beijing China }
122256f9a274Sfei feng - Sun Microsystems - Beijing China
122356f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_tx_cmd_xfer(struct uath_softc * sc,usb_pipe_handle_t pipe,const void * data,uint_t len)122456f9a274Sfei feng - Sun Microsystems - Beijing China uath_tx_cmd_xfer(struct uath_softc *sc,
122556f9a274Sfei feng - Sun Microsystems - Beijing China usb_pipe_handle_t pipe, const void *data, uint_t len)
122656f9a274Sfei feng - Sun Microsystems - Beijing China {
122756f9a274Sfei feng - Sun Microsystems - Beijing China usb_bulk_req_t *send_req;
122856f9a274Sfei feng - Sun Microsystems - Beijing China mblk_t *mblk;
122956f9a274Sfei feng - Sun Microsystems - Beijing China int res;
123056f9a274Sfei feng - Sun Microsystems - Beijing China
123156f9a274Sfei feng - Sun Microsystems - Beijing China send_req = usb_alloc_bulk_req(sc->sc_dev, len, USB_FLAGS_SLEEP);
123256f9a274Sfei feng - Sun Microsystems - Beijing China
123356f9a274Sfei feng - Sun Microsystems - Beijing China send_req->bulk_client_private = (usb_opaque_t)sc;
123456f9a274Sfei feng - Sun Microsystems - Beijing China send_req->bulk_len = (int)len;
123556f9a274Sfei feng - Sun Microsystems - Beijing China send_req->bulk_attributes = USB_ATTRS_AUTOCLEARING;
123656f9a274Sfei feng - Sun Microsystems - Beijing China send_req->bulk_timeout = UATH_CMD_TIMEOUT;
123756f9a274Sfei feng - Sun Microsystems - Beijing China send_req->bulk_cb = uath_cmd_txeof;
123856f9a274Sfei feng - Sun Microsystems - Beijing China send_req->bulk_exc_cb = uath_cmd_txeof;
123956f9a274Sfei feng - Sun Microsystems - Beijing China send_req->bulk_completion_reason = 0;
124056f9a274Sfei feng - Sun Microsystems - Beijing China send_req->bulk_cb_flags = 0;
124156f9a274Sfei feng - Sun Microsystems - Beijing China
124256f9a274Sfei feng - Sun Microsystems - Beijing China mblk = send_req->bulk_data;
124356f9a274Sfei feng - Sun Microsystems - Beijing China bcopy(data, mblk->b_rptr, len);
124456f9a274Sfei feng - Sun Microsystems - Beijing China mblk->b_wptr += len;
124556f9a274Sfei feng - Sun Microsystems - Beijing China
124656f9a274Sfei feng - Sun Microsystems - Beijing China res = usb_pipe_bulk_xfer(pipe, send_req, USB_FLAGS_NOSLEEP);
124756f9a274Sfei feng - Sun Microsystems - Beijing China if (res != UATH_SUCCESS) {
124856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_tx_cmd_xfer(): "
124956f9a274Sfei feng - Sun Microsystems - Beijing China "Error %x writing cmd to bulk/out pipe", res);
125056f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_FAILURE);
125156f9a274Sfei feng - Sun Microsystems - Beijing China }
125256f9a274Sfei feng - Sun Microsystems - Beijing China
125356f9a274Sfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_txlock_cmd);
125456f9a274Sfei feng - Sun Microsystems - Beijing China sc->tx_cmd_queued++;
125556f9a274Sfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_txlock_cmd);
125656f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
125756f9a274Sfei feng - Sun Microsystems - Beijing China }
125856f9a274Sfei feng - Sun Microsystems - Beijing China
125956f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_cmdeof(struct uath_softc * sc,struct uath_cmd * cmd)126056f9a274Sfei feng - Sun Microsystems - Beijing China uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd)
126156f9a274Sfei feng - Sun Microsystems - Beijing China {
126256f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_cmd_hdr *hdr;
126356f9a274Sfei feng - Sun Microsystems - Beijing China int dlen;
126456f9a274Sfei feng - Sun Microsystems - Beijing China
126556f9a274Sfei feng - Sun Microsystems - Beijing China hdr = (struct uath_cmd_hdr *)cmd->buf;
126656f9a274Sfei feng - Sun Microsystems - Beijing China
126756f9a274Sfei feng - Sun Microsystems - Beijing China hdr->code = BE_32(hdr->code);
126856f9a274Sfei feng - Sun Microsystems - Beijing China hdr->len = BE_32(hdr->len);
126956f9a274Sfei feng - Sun Microsystems - Beijing China hdr->magic = BE_32(hdr->magic); /* target status on return */
127056f9a274Sfei feng - Sun Microsystems - Beijing China
127156f9a274Sfei feng - Sun Microsystems - Beijing China /* NB: msgid is passed thru w/o byte swapping */
127256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX_CMD, "uath: uath_cmdeof(): "
127356f9a274Sfei feng - Sun Microsystems - Beijing China "%s: [ix %x] len=%x status %x\n",
127456f9a274Sfei feng - Sun Microsystems - Beijing China uath_codename(hdr->code),
127556f9a274Sfei feng - Sun Microsystems - Beijing China hdr->msgid,
127656f9a274Sfei feng - Sun Microsystems - Beijing China hdr->len,
127756f9a274Sfei feng - Sun Microsystems - Beijing China hdr->magic);
127856f9a274Sfei feng - Sun Microsystems - Beijing China
127956f9a274Sfei feng - Sun Microsystems - Beijing China switch (hdr->code & 0xff) {
128056f9a274Sfei feng - Sun Microsystems - Beijing China /* reply to a read command */
128156f9a274Sfei feng - Sun Microsystems - Beijing China default:
128256f9a274Sfei feng - Sun Microsystems - Beijing China dlen = hdr->len - sizeof (*hdr);
128356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX_CMD, "uath: uath_cmdeof(): "
128456f9a274Sfei feng - Sun Microsystems - Beijing China "code %x data len %u\n",
128556f9a274Sfei feng - Sun Microsystems - Beijing China hdr->code & 0xff, dlen);
128656f9a274Sfei feng - Sun Microsystems - Beijing China
128756f9a274Sfei feng - Sun Microsystems - Beijing China /*
128856f9a274Sfei feng - Sun Microsystems - Beijing China * The first response from the target after the
128956f9a274Sfei feng - Sun Microsystems - Beijing China * HOST_AVAILABLE has an invalid msgid so we must
129056f9a274Sfei feng - Sun Microsystems - Beijing China * treat it specially.
129156f9a274Sfei feng - Sun Microsystems - Beijing China */
129256f9a274Sfei feng - Sun Microsystems - Beijing China if ((hdr->msgid < UATH_CMD_LIST_COUNT) && (hdr->code != 0x13)) {
129356f9a274Sfei feng - Sun Microsystems - Beijing China uint32_t *rp = (uint32_t *)(hdr + 1);
129456f9a274Sfei feng - Sun Microsystems - Beijing China uint_t olen;
129556f9a274Sfei feng - Sun Microsystems - Beijing China
129656f9a274Sfei feng - Sun Microsystems - Beijing China if (!(sizeof (*hdr) <= hdr->len &&
129756f9a274Sfei feng - Sun Microsystems - Beijing China hdr->len < UATH_MAX_CMDSZ)) {
129856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX_CMD,
129956f9a274Sfei feng - Sun Microsystems - Beijing China "uath: uath_cmdeof(): "
130056f9a274Sfei feng - Sun Microsystems - Beijing China "invalid WDC msg length %u; "
130156f9a274Sfei feng - Sun Microsystems - Beijing China "msg ignored\n",
130256f9a274Sfei feng - Sun Microsystems - Beijing China hdr->len);
130356f9a274Sfei feng - Sun Microsystems - Beijing China return;
130456f9a274Sfei feng - Sun Microsystems - Beijing China }
130556f9a274Sfei feng - Sun Microsystems - Beijing China
130656f9a274Sfei feng - Sun Microsystems - Beijing China /*
130756f9a274Sfei feng - Sun Microsystems - Beijing China * Calculate return/receive payload size; the
130856f9a274Sfei feng - Sun Microsystems - Beijing China * first word, if present, always gives the
130956f9a274Sfei feng - Sun Microsystems - Beijing China * number of bytes--unless it's 0 in which
131056f9a274Sfei feng - Sun Microsystems - Beijing China * case a single 32-bit word should be present.
131156f9a274Sfei feng - Sun Microsystems - Beijing China */
131256f9a274Sfei feng - Sun Microsystems - Beijing China if (dlen >= sizeof (uint32_t)) {
131356f9a274Sfei feng - Sun Microsystems - Beijing China olen = BE_32(rp[0]);
131456f9a274Sfei feng - Sun Microsystems - Beijing China dlen -= sizeof (uint32_t);
131556f9a274Sfei feng - Sun Microsystems - Beijing China if (olen == 0) {
131656f9a274Sfei feng - Sun Microsystems - Beijing China /* convention is 0 =>'s one word */
131756f9a274Sfei feng - Sun Microsystems - Beijing China olen = sizeof (uint32_t);
131856f9a274Sfei feng - Sun Microsystems - Beijing China /* XXX KASSERT(olen == dlen ) */
131956f9a274Sfei feng - Sun Microsystems - Beijing China }
132056f9a274Sfei feng - Sun Microsystems - Beijing China } else
132156f9a274Sfei feng - Sun Microsystems - Beijing China olen = 0;
132256f9a274Sfei feng - Sun Microsystems - Beijing China
132356f9a274Sfei feng - Sun Microsystems - Beijing China if (cmd->odata != NULL) {
132456f9a274Sfei feng - Sun Microsystems - Beijing China /* NB: cmd->olen validated in uath_cmd */
132556f9a274Sfei feng - Sun Microsystems - Beijing China if (olen > cmd->olen) {
132656f9a274Sfei feng - Sun Microsystems - Beijing China /* XXX complain? */
132756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX_CMD,
132856f9a274Sfei feng - Sun Microsystems - Beijing China "uath: uath_cmdeof(): "
132956f9a274Sfei feng - Sun Microsystems - Beijing China "cmd 0x%x olen %u cmd olen %u\n",
133056f9a274Sfei feng - Sun Microsystems - Beijing China hdr->code, olen, cmd->olen);
133156f9a274Sfei feng - Sun Microsystems - Beijing China olen = cmd->olen;
133256f9a274Sfei feng - Sun Microsystems - Beijing China }
133356f9a274Sfei feng - Sun Microsystems - Beijing China if (olen > dlen) {
133456f9a274Sfei feng - Sun Microsystems - Beijing China /* XXX complain, shouldn't happen */
133556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX_CMD,
133656f9a274Sfei feng - Sun Microsystems - Beijing China "uath: uath_cmdeof(): "
133756f9a274Sfei feng - Sun Microsystems - Beijing China "cmd 0x%x olen %u dlen %u\n",
133856f9a274Sfei feng - Sun Microsystems - Beijing China hdr->code, olen, dlen);
133956f9a274Sfei feng - Sun Microsystems - Beijing China olen = dlen;
134056f9a274Sfei feng - Sun Microsystems - Beijing China }
134156f9a274Sfei feng - Sun Microsystems - Beijing China /* XXX have submitter do this */
134256f9a274Sfei feng - Sun Microsystems - Beijing China /* copy answer into caller's supplied buffer */
134356f9a274Sfei feng - Sun Microsystems - Beijing China bcopy(&rp[1], cmd->odata, olen);
134456f9a274Sfei feng - Sun Microsystems - Beijing China cmd->olen = olen;
134556f9a274Sfei feng - Sun Microsystems - Beijing China }
134656f9a274Sfei feng - Sun Microsystems - Beijing China }
134756f9a274Sfei feng - Sun Microsystems - Beijing China
134856f9a274Sfei feng - Sun Microsystems - Beijing China /* Just signal that something happened */
134956f9a274Sfei feng - Sun Microsystems - Beijing China uath_cmd_lock_signal(&sc->rlock);
135056f9a274Sfei feng - Sun Microsystems - Beijing China break;
135156f9a274Sfei feng - Sun Microsystems - Beijing China
135256f9a274Sfei feng - Sun Microsystems - Beijing China case WDCMSG_TARGET_START:
135356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX_CMD, "uath: uath_cmdeof(): "
135456f9a274Sfei feng - Sun Microsystems - Beijing China "receive TARGET STAERT\n");
135556f9a274Sfei feng - Sun Microsystems - Beijing China
135656f9a274Sfei feng - Sun Microsystems - Beijing China if (hdr->msgid >= UATH_CMD_LIST_COUNT) {
135756f9a274Sfei feng - Sun Microsystems - Beijing China /* XXX */
135856f9a274Sfei feng - Sun Microsystems - Beijing China return;
135956f9a274Sfei feng - Sun Microsystems - Beijing China }
136056f9a274Sfei feng - Sun Microsystems - Beijing China dlen = hdr->len - sizeof (*hdr);
136156f9a274Sfei feng - Sun Microsystems - Beijing China if (dlen != sizeof (uint32_t)) {
136256f9a274Sfei feng - Sun Microsystems - Beijing China /* XXX something wrong */
136356f9a274Sfei feng - Sun Microsystems - Beijing China return;
136456f9a274Sfei feng - Sun Microsystems - Beijing China }
136556f9a274Sfei feng - Sun Microsystems - Beijing China /* XXX have submitter do this */
136656f9a274Sfei feng - Sun Microsystems - Beijing China /* copy answer into caller's supplied buffer */
136756f9a274Sfei feng - Sun Microsystems - Beijing China bcopy(hdr + 1, cmd->odata, sizeof (uint32_t));
136856f9a274Sfei feng - Sun Microsystems - Beijing China cmd->olen = sizeof (uint32_t);
136956f9a274Sfei feng - Sun Microsystems - Beijing China
137056f9a274Sfei feng - Sun Microsystems - Beijing China /* wake up caller */
137156f9a274Sfei feng - Sun Microsystems - Beijing China uath_cmd_lock_signal(&sc->rlock);
137256f9a274Sfei feng - Sun Microsystems - Beijing China break;
137356f9a274Sfei feng - Sun Microsystems - Beijing China
137456f9a274Sfei feng - Sun Microsystems - Beijing China case WDCMSG_SEND_COMPLETE:
137556f9a274Sfei feng - Sun Microsystems - Beijing China /* this notification is sent when UATH_TX_NOTIFY is set */
137656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX_CMD, "uath: uath_cmdeof(): "
137756f9a274Sfei feng - Sun Microsystems - Beijing China "receive Tx notification\n");
137856f9a274Sfei feng - Sun Microsystems - Beijing China break;
137956f9a274Sfei feng - Sun Microsystems - Beijing China
138056f9a274Sfei feng - Sun Microsystems - Beijing China case WDCMSG_TARGET_GET_STATS:
138156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX_CMD, "uath: uath_cmdeof(): "
138256f9a274Sfei feng - Sun Microsystems - Beijing China "received device statistics\n");
138356f9a274Sfei feng - Sun Microsystems - Beijing China break;
138456f9a274Sfei feng - Sun Microsystems - Beijing China }
138556f9a274Sfei feng - Sun Microsystems - Beijing China }
138656f9a274Sfei feng - Sun Microsystems - Beijing China
138756f9a274Sfei feng - Sun Microsystems - Beijing China /* ARGSUSED */
138856f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_cmd_rxeof(usb_pipe_handle_t pipe,usb_bulk_req_t * req)138956f9a274Sfei feng - Sun Microsystems - Beijing China uath_cmd_rxeof(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
139056f9a274Sfei feng - Sun Microsystems - Beijing China {
139156f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc = (struct uath_softc *)req->bulk_client_private;
139256f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_cmd_hdr *hdr;
139356f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_cmd *cmd;
139456f9a274Sfei feng - Sun Microsystems - Beijing China mblk_t *m, *mp;
139556f9a274Sfei feng - Sun Microsystems - Beijing China int len;
139656f9a274Sfei feng - Sun Microsystems - Beijing China
139756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX_CMD, "uath: uath_cmd_rxeof(): "
139856f9a274Sfei feng - Sun Microsystems - Beijing China "cr:%s(%d), flags:0x%x, rx queued %d\n",
139956f9a274Sfei feng - Sun Microsystems - Beijing China usb_str_cr(req->bulk_completion_reason),
140056f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_completion_reason,
140156f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_cb_flags,
140256f9a274Sfei feng - Sun Microsystems - Beijing China sc->rx_cmd_queued);
140356f9a274Sfei feng - Sun Microsystems - Beijing China
140456f9a274Sfei feng - Sun Microsystems - Beijing China m = req->bulk_data;
140556f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_data = NULL;
140656f9a274Sfei feng - Sun Microsystems - Beijing China
140756f9a274Sfei feng - Sun Microsystems - Beijing China if (req->bulk_completion_reason != USB_CR_OK) {
140856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX_CMD, "uath: uath_cmd_rxeof(): "
140956f9a274Sfei feng - Sun Microsystems - Beijing China "USB CR is not OK\n");
141056f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
141156f9a274Sfei feng - Sun Microsystems - Beijing China }
141256f9a274Sfei feng - Sun Microsystems - Beijing China
141356f9a274Sfei feng - Sun Microsystems - Beijing China if (m->b_cont != NULL) {
141456f9a274Sfei feng - Sun Microsystems - Beijing China /* Fragmented message, concatenate */
141556f9a274Sfei feng - Sun Microsystems - Beijing China mp = msgpullup(m, -1);
141656f9a274Sfei feng - Sun Microsystems - Beijing China freemsg(m);
141756f9a274Sfei feng - Sun Microsystems - Beijing China m = mp;
141856f9a274Sfei feng - Sun Microsystems - Beijing China mp = NULL;
141956f9a274Sfei feng - Sun Microsystems - Beijing China }
142056f9a274Sfei feng - Sun Microsystems - Beijing China
142156f9a274Sfei feng - Sun Microsystems - Beijing China len = msgdsize(m);
142256f9a274Sfei feng - Sun Microsystems - Beijing China if (len < sizeof (struct uath_cmd_hdr)) {
142356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX_CMD, "uath: uath_rx_cmdeof(): "
142456f9a274Sfei feng - Sun Microsystems - Beijing China "short xfer error\n");
142556f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
142656f9a274Sfei feng - Sun Microsystems - Beijing China }
142756f9a274Sfei feng - Sun Microsystems - Beijing China
142856f9a274Sfei feng - Sun Microsystems - Beijing China hdr = (struct uath_cmd_hdr *)m->b_rptr;
142956f9a274Sfei feng - Sun Microsystems - Beijing China if (BE_32(hdr->code) == 0x13)
143056f9a274Sfei feng - Sun Microsystems - Beijing China cmd = &sc->sc_cmd[0];
143156f9a274Sfei feng - Sun Microsystems - Beijing China else
143256f9a274Sfei feng - Sun Microsystems - Beijing China cmd = &sc->sc_cmd[hdr->msgid];
143356f9a274Sfei feng - Sun Microsystems - Beijing China
143456f9a274Sfei feng - Sun Microsystems - Beijing China bcopy(m->b_rptr, cmd->buf, len);
143556f9a274Sfei feng - Sun Microsystems - Beijing China uath_cmdeof(sc, cmd);
143656f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_rx_cmd_xfer(sc);
143756f9a274Sfei feng - Sun Microsystems - Beijing China fail:
143856f9a274Sfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_rxlock_cmd);
143956f9a274Sfei feng - Sun Microsystems - Beijing China sc->rx_cmd_queued--;
144056f9a274Sfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_rxlock_cmd);
144156f9a274Sfei feng - Sun Microsystems - Beijing China if (m) freemsg(m);
144256f9a274Sfei feng - Sun Microsystems - Beijing China usb_free_bulk_req(req);
144356f9a274Sfei feng - Sun Microsystems - Beijing China }
144456f9a274Sfei feng - Sun Microsystems - Beijing China
144556f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_rx_cmd_xfer(struct uath_softc * sc)144656f9a274Sfei feng - Sun Microsystems - Beijing China uath_rx_cmd_xfer(struct uath_softc *sc)
144756f9a274Sfei feng - Sun Microsystems - Beijing China {
144856f9a274Sfei feng - Sun Microsystems - Beijing China usb_bulk_req_t *req;
144956f9a274Sfei feng - Sun Microsystems - Beijing China int err;
145056f9a274Sfei feng - Sun Microsystems - Beijing China
145156f9a274Sfei feng - Sun Microsystems - Beijing China req = usb_alloc_bulk_req(sc->sc_dev, UATH_MAX_CMDSZ, USB_FLAGS_SLEEP);
145256f9a274Sfei feng - Sun Microsystems - Beijing China if (req == NULL) {
145356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_rx_cmd_xfer(): "
145456f9a274Sfei feng - Sun Microsystems - Beijing China "failed to allocate req");
145556f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_FAILURE);
145656f9a274Sfei feng - Sun Microsystems - Beijing China }
145756f9a274Sfei feng - Sun Microsystems - Beijing China
145856f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_len = UATH_MAX_CMDSZ;
145956f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_client_private = (usb_opaque_t)sc;
146056f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_cb = uath_cmd_rxeof;
146156f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_exc_cb = uath_cmd_rxeof;
146256f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_timeout = 0;
146356f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_completion_reason = 0;
146456f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_cb_flags = 0;
146556f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_attributes = USB_ATTRS_SHORT_XFER_OK
146656f9a274Sfei feng - Sun Microsystems - Beijing China | USB_ATTRS_AUTOCLEARING;
146756f9a274Sfei feng - Sun Microsystems - Beijing China
146856f9a274Sfei feng - Sun Microsystems - Beijing China err = usb_pipe_bulk_xfer(sc->rx_cmd_pipe, req, USB_FLAGS_NOSLEEP);
146956f9a274Sfei feng - Sun Microsystems - Beijing China if (err != USB_SUCCESS) {
147056f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_rx_cmd_xfer(): "
147156f9a274Sfei feng - Sun Microsystems - Beijing China "failed to do rx xfer, %d", err);
147256f9a274Sfei feng - Sun Microsystems - Beijing China usb_free_bulk_req(req);
147356f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_FAILURE);
147456f9a274Sfei feng - Sun Microsystems - Beijing China }
147556f9a274Sfei feng - Sun Microsystems - Beijing China
147656f9a274Sfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_rxlock_cmd);
147756f9a274Sfei feng - Sun Microsystems - Beijing China sc->rx_cmd_queued++;
147856f9a274Sfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_rxlock_cmd);
147956f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
148056f9a274Sfei feng - Sun Microsystems - Beijing China }
148156f9a274Sfei feng - Sun Microsystems - Beijing China
148256f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_init_data_queue(struct uath_softc * sc)148356f9a274Sfei feng - Sun Microsystems - Beijing China uath_init_data_queue(struct uath_softc *sc)
148456f9a274Sfei feng - Sun Microsystems - Beijing China {
148556f9a274Sfei feng - Sun Microsystems - Beijing China sc->tx_data_queued = sc->rx_data_queued = 0;
148656f9a274Sfei feng - Sun Microsystems - Beijing China }
148756f9a274Sfei feng - Sun Microsystems - Beijing China
148856f9a274Sfei feng - Sun Microsystems - Beijing China /* ARGSUSED */
148956f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_data_txeof(usb_pipe_handle_t pipe,usb_bulk_req_t * req)149056f9a274Sfei feng - Sun Microsystems - Beijing China uath_data_txeof(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
149156f9a274Sfei feng - Sun Microsystems - Beijing China {
149256f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc = (struct uath_softc *)req->bulk_client_private;
149356f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
149456f9a274Sfei feng - Sun Microsystems - Beijing China
149556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_TX, "uath: uath_data_txeof(): "
149656f9a274Sfei feng - Sun Microsystems - Beijing China "uath_txeof(): cr:%s(%d), flags:0x%x, tx_data_queued %d\n",
149756f9a274Sfei feng - Sun Microsystems - Beijing China usb_str_cr(req->bulk_completion_reason),
149856f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_completion_reason,
149956f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_cb_flags,
150056f9a274Sfei feng - Sun Microsystems - Beijing China sc->tx_data_queued);
150156f9a274Sfei feng - Sun Microsystems - Beijing China
150256f9a274Sfei feng - Sun Microsystems - Beijing China if (req->bulk_completion_reason != USB_CR_OK)
150356f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_tx_err++;
150456f9a274Sfei feng - Sun Microsystems - Beijing China
150556f9a274Sfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_txlock_data);
150656f9a274Sfei feng - Sun Microsystems - Beijing China sc->tx_data_queued--;
150756f9a274Sfei feng - Sun Microsystems - Beijing China
150856f9a274Sfei feng - Sun Microsystems - Beijing China if (sc->sc_need_sched) {
150956f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_need_sched = 0;
151056f9a274Sfei feng - Sun Microsystems - Beijing China mac_tx_update(ic->ic_mach);
151156f9a274Sfei feng - Sun Microsystems - Beijing China }
151256f9a274Sfei feng - Sun Microsystems - Beijing China
151356f9a274Sfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_txlock_data);
151456f9a274Sfei feng - Sun Microsystems - Beijing China usb_free_bulk_req(req);
151556f9a274Sfei feng - Sun Microsystems - Beijing China }
151656f9a274Sfei feng - Sun Microsystems - Beijing China
151756f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_tx_data_xfer(struct uath_softc * sc,mblk_t * mp)151856f9a274Sfei feng - Sun Microsystems - Beijing China uath_tx_data_xfer(struct uath_softc *sc, mblk_t *mp)
151956f9a274Sfei feng - Sun Microsystems - Beijing China {
152056f9a274Sfei feng - Sun Microsystems - Beijing China usb_bulk_req_t *req;
152156f9a274Sfei feng - Sun Microsystems - Beijing China int err;
152256f9a274Sfei feng - Sun Microsystems - Beijing China
152356f9a274Sfei feng - Sun Microsystems - Beijing China req = usb_alloc_bulk_req(sc->sc_dev, 0, USB_FLAGS_SLEEP);
152456f9a274Sfei feng - Sun Microsystems - Beijing China if (req == NULL) {
152556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_TX, "uath: uath_tx_data_xfer(): "
152656f9a274Sfei feng - Sun Microsystems - Beijing China "uath_tx_data_xfer(): failed to allocate req");
152756f9a274Sfei feng - Sun Microsystems - Beijing China freemsg(mp);
152856f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_FAILURE);
152956f9a274Sfei feng - Sun Microsystems - Beijing China }
153056f9a274Sfei feng - Sun Microsystems - Beijing China
153156f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_len = msgdsize(mp);
153256f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_data = mp;
153356f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_client_private = (usb_opaque_t)sc;
153456f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_timeout = UATH_DATA_TIMEOUT;
153556f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_attributes = USB_ATTRS_AUTOCLEARING;
153656f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_cb = uath_data_txeof;
153756f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_exc_cb = uath_data_txeof;
153856f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_completion_reason = 0;
153956f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_cb_flags = 0;
154056f9a274Sfei feng - Sun Microsystems - Beijing China
154156f9a274Sfei feng - Sun Microsystems - Beijing China if ((err = usb_pipe_bulk_xfer(sc->tx_data_pipe, req, 0)) !=
154256f9a274Sfei feng - Sun Microsystems - Beijing China USB_SUCCESS) {
154356f9a274Sfei feng - Sun Microsystems - Beijing China
154456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_TX, "uath: uath_tx_data_xfer(): "
154556f9a274Sfei feng - Sun Microsystems - Beijing China "failed to do tx xfer, %d", err);
154656f9a274Sfei feng - Sun Microsystems - Beijing China usb_free_bulk_req(req);
154756f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_FAILURE);
154856f9a274Sfei feng - Sun Microsystems - Beijing China }
154956f9a274Sfei feng - Sun Microsystems - Beijing China
155056f9a274Sfei feng - Sun Microsystems - Beijing China sc->tx_data_queued++;
155156f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
155256f9a274Sfei feng - Sun Microsystems - Beijing China }
155356f9a274Sfei feng - Sun Microsystems - Beijing China
155456f9a274Sfei feng - Sun Microsystems - Beijing China /* ARGSUSED */
155556f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_data_rxeof(usb_pipe_handle_t pipe,usb_bulk_req_t * req)155656f9a274Sfei feng - Sun Microsystems - Beijing China uath_data_rxeof(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
155756f9a274Sfei feng - Sun Microsystems - Beijing China {
155856f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc = (struct uath_softc *)req->bulk_client_private;
155956f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
156056f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_chunk *chunk;
156156f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_rx_desc *desc;
156256f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211_frame *wh;
156356f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211_node *ni;
156456f9a274Sfei feng - Sun Microsystems - Beijing China
156556f9a274Sfei feng - Sun Microsystems - Beijing China mblk_t *m, *mp;
156656f9a274Sfei feng - Sun Microsystems - Beijing China uint8_t *rxbuf;
156756f9a274Sfei feng - Sun Microsystems - Beijing China int actlen, pktlen;
156856f9a274Sfei feng - Sun Microsystems - Beijing China
156956f9a274Sfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_rxlock_data);
157056f9a274Sfei feng - Sun Microsystems - Beijing China
157156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX, "uath: uath_data_rxeof(): "
157256f9a274Sfei feng - Sun Microsystems - Beijing China "cr:%s(%d), flags:0x%x, rx_data_queued %d\n",
157356f9a274Sfei feng - Sun Microsystems - Beijing China usb_str_cr(req->bulk_completion_reason),
157456f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_completion_reason,
157556f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_cb_flags,
157656f9a274Sfei feng - Sun Microsystems - Beijing China sc->rx_data_queued);
157756f9a274Sfei feng - Sun Microsystems - Beijing China
157856f9a274Sfei feng - Sun Microsystems - Beijing China mp = req->bulk_data;
157956f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_data = NULL;
158056f9a274Sfei feng - Sun Microsystems - Beijing China
158156f9a274Sfei feng - Sun Microsystems - Beijing China if (req->bulk_completion_reason != USB_CR_OK) {
158256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX, "uath: uath_data_rxeof(): "
158356f9a274Sfei feng - Sun Microsystems - Beijing China "USB CR is not OK\n");
158456f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_rx_err++;
158556f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
158656f9a274Sfei feng - Sun Microsystems - Beijing China }
158756f9a274Sfei feng - Sun Microsystems - Beijing China
158856f9a274Sfei feng - Sun Microsystems - Beijing China rxbuf = (uint8_t *)mp->b_rptr;
158956f9a274Sfei feng - Sun Microsystems - Beijing China actlen = (uintptr_t)mp->b_wptr - (uintptr_t)mp->b_rptr;
159056f9a274Sfei feng - Sun Microsystems - Beijing China if (actlen < UATH_MIN_RXBUFSZ) {
159156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX, "uath_data_rxeof(): "
159256f9a274Sfei feng - Sun Microsystems - Beijing China "wrong recv size %d\n", actlen);
159356f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_rx_err++;
159456f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
159556f9a274Sfei feng - Sun Microsystems - Beijing China }
159656f9a274Sfei feng - Sun Microsystems - Beijing China
159756f9a274Sfei feng - Sun Microsystems - Beijing China chunk = (struct uath_chunk *)rxbuf;
159856f9a274Sfei feng - Sun Microsystems - Beijing China if (chunk->seqnum == 0 && chunk->flags == 0 && chunk->length == 0) {
159956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX, "uath: uath_data_rxeof(): "
160056f9a274Sfei feng - Sun Microsystems - Beijing China "strange response\n");
160156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_RESET_INTRX(sc);
160256f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_rx_err++;
160356f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
160456f9a274Sfei feng - Sun Microsystems - Beijing China }
160556f9a274Sfei feng - Sun Microsystems - Beijing China
160656f9a274Sfei feng - Sun Microsystems - Beijing China if (chunk->seqnum != sc->sc_intrx_nextnum) {
160756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX, "uath: uath_data_rxeof(): "
160856f9a274Sfei feng - Sun Microsystems - Beijing China "invalid seqnum %d, expected %d\n",
160956f9a274Sfei feng - Sun Microsystems - Beijing China chunk->seqnum, sc->sc_intrx_nextnum);
161056f9a274Sfei feng - Sun Microsystems - Beijing China UATH_STAT_INC(sc, st_badchunkseqnum);
161156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_RESET_INTRX(sc);
161256f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_rx_err++;
161356f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
161456f9a274Sfei feng - Sun Microsystems - Beijing China }
161556f9a274Sfei feng - Sun Microsystems - Beijing China
161656f9a274Sfei feng - Sun Microsystems - Beijing China /* check multi-chunk frames */
161756f9a274Sfei feng - Sun Microsystems - Beijing China if ((chunk->seqnum == 0 && !(chunk->flags & UATH_CFLAGS_FINAL)) ||
161856f9a274Sfei feng - Sun Microsystems - Beijing China (chunk->seqnum != 0 && (chunk->flags & UATH_CFLAGS_FINAL)) ||
161956f9a274Sfei feng - Sun Microsystems - Beijing China chunk->flags & UATH_CFLAGS_RXMSG) {
162056f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX, "uath: uath_data_rxeof(): "
162156f9a274Sfei feng - Sun Microsystems - Beijing China "receive multi-chunk frames "
162256f9a274Sfei feng - Sun Microsystems - Beijing China "chunk seqnum %x, flags %x, length %u\n",
162356f9a274Sfei feng - Sun Microsystems - Beijing China chunk->seqnum, chunk->flags, BE_16(chunk->length));
162456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_STAT_INC(sc, st_multichunk);
162556f9a274Sfei feng - Sun Microsystems - Beijing China }
162656f9a274Sfei feng - Sun Microsystems - Beijing China
162756f9a274Sfei feng - Sun Microsystems - Beijing China
162856f9a274Sfei feng - Sun Microsystems - Beijing China /* if the frame is not final continue the transfer */
162956f9a274Sfei feng - Sun Microsystems - Beijing China if (!(chunk->flags & UATH_CFLAGS_FINAL))
163056f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_intrx_nextnum++;
163156f9a274Sfei feng - Sun Microsystems - Beijing China
163256f9a274Sfei feng - Sun Microsystems - Beijing China /*
163356f9a274Sfei feng - Sun Microsystems - Beijing China * if the frame is not set UATH_CFLAGS_RXMSG, then rx descriptor is
163456f9a274Sfei feng - Sun Microsystems - Beijing China * located at the end, 32-bit aligned
163556f9a274Sfei feng - Sun Microsystems - Beijing China */
163656f9a274Sfei feng - Sun Microsystems - Beijing China desc = (chunk->flags & UATH_CFLAGS_RXMSG) ?
163756f9a274Sfei feng - Sun Microsystems - Beijing China (struct uath_rx_desc *)(chunk + 1) :
163856f9a274Sfei feng - Sun Microsystems - Beijing China (struct uath_rx_desc *)(((uint8_t *)chunk) +
163956f9a274Sfei feng - Sun Microsystems - Beijing China sizeof (struct uath_chunk) + BE_16(chunk->length) -
164056f9a274Sfei feng - Sun Microsystems - Beijing China sizeof (struct uath_rx_desc));
164156f9a274Sfei feng - Sun Microsystems - Beijing China
164256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX, "uath: uath_data_rxeof(): "
164356f9a274Sfei feng - Sun Microsystems - Beijing China "frame len %u code %u status %u rate %u antenna %u "
164456f9a274Sfei feng - Sun Microsystems - Beijing China "rssi %d channel %u phyerror %u connix %u "
164556f9a274Sfei feng - Sun Microsystems - Beijing China "decrypterror %u keycachemiss %u\n",
164656f9a274Sfei feng - Sun Microsystems - Beijing China BE_32(desc->framelen), BE_32(desc->code), BE_32(desc->status),
164756f9a274Sfei feng - Sun Microsystems - Beijing China BE_32(desc->rate), BE_32(desc->antenna), BE_32(desc->rssi),
164856f9a274Sfei feng - Sun Microsystems - Beijing China BE_32(desc->channel), BE_32(desc->phyerror), BE_32(desc->connix),
164956f9a274Sfei feng - Sun Microsystems - Beijing China BE_32(desc->decrypterror), BE_32(desc->keycachemiss));
165056f9a274Sfei feng - Sun Microsystems - Beijing China
165156f9a274Sfei feng - Sun Microsystems - Beijing China if (BE_32(desc->len) > IEEE80211_MAX_LEN) {
165256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX, "uath: uath_data_rxeof(): "
165356f9a274Sfei feng - Sun Microsystems - Beijing China "bad descriptor (len=%d)\n", BE_32(desc->len));
165456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_STAT_INC(sc, st_toobigrxpkt);
165556f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
165656f9a274Sfei feng - Sun Microsystems - Beijing China }
165756f9a274Sfei feng - Sun Microsystems - Beijing China
165856f9a274Sfei feng - Sun Microsystems - Beijing China uath_update_rxstat(sc, BE_32(desc->status));
165956f9a274Sfei feng - Sun Microsystems - Beijing China
166056f9a274Sfei feng - Sun Microsystems - Beijing China pktlen = BE_32(desc->framelen) - UATH_RX_DUMMYSIZE;
166156f9a274Sfei feng - Sun Microsystems - Beijing China
166256f9a274Sfei feng - Sun Microsystems - Beijing China if ((m = allocb(pktlen, BPRI_MED)) == NULL) {
166356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_RX, "uath: uath_data_rxeof(): "
166456f9a274Sfei feng - Sun Microsystems - Beijing China "allocate mblk failed.\n");
166556f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_rx_nobuf++;
166656f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
166756f9a274Sfei feng - Sun Microsystems - Beijing China }
166856f9a274Sfei feng - Sun Microsystems - Beijing China bcopy((rxbuf + sizeof (struct uath_chunk)), m->b_rptr, pktlen);
166956f9a274Sfei feng - Sun Microsystems - Beijing China
167056f9a274Sfei feng - Sun Microsystems - Beijing China m->b_wptr = m->b_rptr + pktlen;
167156f9a274Sfei feng - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)m->b_rptr;
167256f9a274Sfei feng - Sun Microsystems - Beijing China ni = ieee80211_find_rxnode(ic, wh);
167356f9a274Sfei feng - Sun Microsystems - Beijing China
167456f9a274Sfei feng - Sun Microsystems - Beijing China /* send the frame to the 802.11 layer */
167556f9a274Sfei feng - Sun Microsystems - Beijing China (void) ieee80211_input(ic, m, ni, (int)BE_32(desc->rssi), 0);
167656f9a274Sfei feng - Sun Microsystems - Beijing China
167756f9a274Sfei feng - Sun Microsystems - Beijing China /* node is no longer needed */
167856f9a274Sfei feng - Sun Microsystems - Beijing China ieee80211_free_node(ni);
167956f9a274Sfei feng - Sun Microsystems - Beijing China fail:
168056f9a274Sfei feng - Sun Microsystems - Beijing China sc->rx_data_queued--;
168156f9a274Sfei feng - Sun Microsystems - Beijing China if (mp) freemsg(mp);
168256f9a274Sfei feng - Sun Microsystems - Beijing China usb_free_bulk_req(req);
168356f9a274Sfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_rxlock_data);
168456f9a274Sfei feng - Sun Microsystems - Beijing China if (UATH_IS_RUNNING(sc) && !UATH_IS_SUSPEND(sc)) {
168556f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_rx_data_xfer(sc);
168656f9a274Sfei feng - Sun Microsystems - Beijing China }
168756f9a274Sfei feng - Sun Microsystems - Beijing China }
168856f9a274Sfei feng - Sun Microsystems - Beijing China
168956f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_rx_data_xfer(struct uath_softc * sc)169056f9a274Sfei feng - Sun Microsystems - Beijing China uath_rx_data_xfer(struct uath_softc *sc)
169156f9a274Sfei feng - Sun Microsystems - Beijing China {
169256f9a274Sfei feng - Sun Microsystems - Beijing China usb_bulk_req_t *req;
169356f9a274Sfei feng - Sun Microsystems - Beijing China int err;
169456f9a274Sfei feng - Sun Microsystems - Beijing China
169556f9a274Sfei feng - Sun Microsystems - Beijing China req = usb_alloc_bulk_req(sc->sc_dev,
169656f9a274Sfei feng - Sun Microsystems - Beijing China IEEE80211_MAX_LEN, USB_FLAGS_SLEEP);
169756f9a274Sfei feng - Sun Microsystems - Beijing China if (req == NULL) {
169856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_rx_data_xfer(): "
169956f9a274Sfei feng - Sun Microsystems - Beijing China "failed to allocate req");
170056f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
170156f9a274Sfei feng - Sun Microsystems - Beijing China }
170256f9a274Sfei feng - Sun Microsystems - Beijing China
170356f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_len = IEEE80211_MAX_LEN;
170456f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_cb = uath_data_rxeof;
170556f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_exc_cb = uath_data_rxeof;
170656f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_client_private = (usb_opaque_t)sc;
170756f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_timeout = 0;
170856f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_completion_reason = 0;
170956f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_cb_flags = 0;
171056f9a274Sfei feng - Sun Microsystems - Beijing China req->bulk_attributes = USB_ATTRS_SHORT_XFER_OK
171156f9a274Sfei feng - Sun Microsystems - Beijing China | USB_ATTRS_AUTOCLEARING;
171256f9a274Sfei feng - Sun Microsystems - Beijing China
171356f9a274Sfei feng - Sun Microsystems - Beijing China err = usb_pipe_bulk_xfer(sc->rx_data_pipe, req, 0);
171456f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
171556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_rx_data_xfer(): "
171656f9a274Sfei feng - Sun Microsystems - Beijing China "failed to do rx xfer, %d", err);
171756f9a274Sfei feng - Sun Microsystems - Beijing China usb_free_bulk_req(req);
171856f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_FAILURE);
171956f9a274Sfei feng - Sun Microsystems - Beijing China }
172056f9a274Sfei feng - Sun Microsystems - Beijing China
172156f9a274Sfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_rxlock_data);
172256f9a274Sfei feng - Sun Microsystems - Beijing China sc->rx_data_queued++;
172356f9a274Sfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_rxlock_data);
172456f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
172556f9a274Sfei feng - Sun Microsystems - Beijing China }
172656f9a274Sfei feng - Sun Microsystems - Beijing China
172756f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_update_rxstat(struct uath_softc * sc,uint32_t status)172856f9a274Sfei feng - Sun Microsystems - Beijing China uath_update_rxstat(struct uath_softc *sc, uint32_t status)
172956f9a274Sfei feng - Sun Microsystems - Beijing China {
173056f9a274Sfei feng - Sun Microsystems - Beijing China
173156f9a274Sfei feng - Sun Microsystems - Beijing China switch (status) {
173256f9a274Sfei feng - Sun Microsystems - Beijing China case UATH_STATUS_STOP_IN_PROGRESS:
173356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_STAT_INC(sc, st_stopinprogress);
173456f9a274Sfei feng - Sun Microsystems - Beijing China break;
173556f9a274Sfei feng - Sun Microsystems - Beijing China case UATH_STATUS_CRC_ERR:
173656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_STAT_INC(sc, st_crcerr);
173756f9a274Sfei feng - Sun Microsystems - Beijing China break;
173856f9a274Sfei feng - Sun Microsystems - Beijing China case UATH_STATUS_PHY_ERR:
173956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_STAT_INC(sc, st_phyerr);
174056f9a274Sfei feng - Sun Microsystems - Beijing China break;
174156f9a274Sfei feng - Sun Microsystems - Beijing China case UATH_STATUS_DECRYPT_CRC_ERR:
174256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_STAT_INC(sc, st_decrypt_crcerr);
174356f9a274Sfei feng - Sun Microsystems - Beijing China break;
174456f9a274Sfei feng - Sun Microsystems - Beijing China case UATH_STATUS_DECRYPT_MIC_ERR:
174556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_STAT_INC(sc, st_decrypt_micerr);
174656f9a274Sfei feng - Sun Microsystems - Beijing China break;
174756f9a274Sfei feng - Sun Microsystems - Beijing China case UATH_STATUS_DECOMP_ERR:
174856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_STAT_INC(sc, st_decomperr);
174956f9a274Sfei feng - Sun Microsystems - Beijing China break;
175056f9a274Sfei feng - Sun Microsystems - Beijing China case UATH_STATUS_KEY_ERR:
175156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_STAT_INC(sc, st_keyerr);
175256f9a274Sfei feng - Sun Microsystems - Beijing China break;
175356f9a274Sfei feng - Sun Microsystems - Beijing China case UATH_STATUS_ERR:
175456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_STAT_INC(sc, st_err);
175556f9a274Sfei feng - Sun Microsystems - Beijing China break;
175656f9a274Sfei feng - Sun Microsystems - Beijing China default:
175756f9a274Sfei feng - Sun Microsystems - Beijing China break;
175856f9a274Sfei feng - Sun Microsystems - Beijing China }
175956f9a274Sfei feng - Sun Microsystems - Beijing China }
176056f9a274Sfei feng - Sun Microsystems - Beijing China
176156f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_next_scan(void * arg)176256f9a274Sfei feng - Sun Microsystems - Beijing China uath_next_scan(void *arg)
176356f9a274Sfei feng - Sun Microsystems - Beijing China {
176456f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc = arg;
176556f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
176656f9a274Sfei feng - Sun Microsystems - Beijing China
176756f9a274Sfei feng - Sun Microsystems - Beijing China if (ic->ic_state == IEEE80211_S_SCAN)
176856f9a274Sfei feng - Sun Microsystems - Beijing China ieee80211_next_scan(ic);
176956f9a274Sfei feng - Sun Microsystems - Beijing China
177056f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_scan_id = 0;
177156f9a274Sfei feng - Sun Microsystems - Beijing China }
177256f9a274Sfei feng - Sun Microsystems - Beijing China
177356f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_create_connection(struct uath_softc * sc,uint32_t connid)177456f9a274Sfei feng - Sun Microsystems - Beijing China uath_create_connection(struct uath_softc *sc, uint32_t connid)
177556f9a274Sfei feng - Sun Microsystems - Beijing China {
177656f9a274Sfei feng - Sun Microsystems - Beijing China const struct ieee80211_rateset *rs;
177756f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
177856f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211_node *ni = ic->ic_bss;
177956f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_cmd_create_connection create;
178056f9a274Sfei feng - Sun Microsystems - Beijing China int err;
178156f9a274Sfei feng - Sun Microsystems - Beijing China
178256f9a274Sfei feng - Sun Microsystems - Beijing China bzero(&create, sizeof (create));
178356f9a274Sfei feng - Sun Microsystems - Beijing China create.connid = BE_32(connid);
178456f9a274Sfei feng - Sun Microsystems - Beijing China create.bssid = BE_32(0);
178556f9a274Sfei feng - Sun Microsystems - Beijing China /* XXX packed or not? */
178656f9a274Sfei feng - Sun Microsystems - Beijing China create.size = BE_32(sizeof (struct uath_cmd_rateset));
178756f9a274Sfei feng - Sun Microsystems - Beijing China
178856f9a274Sfei feng - Sun Microsystems - Beijing China rs = &ni->in_rates;
178956f9a274Sfei feng - Sun Microsystems - Beijing China create.connattr.rateset.length = rs->ir_nrates;
179056f9a274Sfei feng - Sun Microsystems - Beijing China bcopy(rs->ir_rates, &create.connattr.rateset.set[0],
179156f9a274Sfei feng - Sun Microsystems - Beijing China rs->ir_nrates);
179256f9a274Sfei feng - Sun Microsystems - Beijing China
179356f9a274Sfei feng - Sun Microsystems - Beijing China /* XXX turbo */
179456f9a274Sfei feng - Sun Microsystems - Beijing China if (UATH_IS_CHAN_A(ni->in_chan))
179556f9a274Sfei feng - Sun Microsystems - Beijing China create.connattr.wlanmode = BE_32(WLAN_MODE_11a);
179656f9a274Sfei feng - Sun Microsystems - Beijing China else if (UATH_IS_CHAN_ANYG(ni->in_chan))
179756f9a274Sfei feng - Sun Microsystems - Beijing China create.connattr.wlanmode = BE_32(WLAN_MODE_11g);
179856f9a274Sfei feng - Sun Microsystems - Beijing China else
179956f9a274Sfei feng - Sun Microsystems - Beijing China create.connattr.wlanmode = BE_32(WLAN_MODE_11b);
180056f9a274Sfei feng - Sun Microsystems - Beijing China
180156f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_cmd_write(sc, WDCMSG_CREATE_CONNECTION, &create,
180256f9a274Sfei feng - Sun Microsystems - Beijing China sizeof (create), 0);
180356f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
180456f9a274Sfei feng - Sun Microsystems - Beijing China }
180556f9a274Sfei feng - Sun Microsystems - Beijing China
180656f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_set_rates(struct uath_softc * sc,const struct ieee80211_rateset * rs)180756f9a274Sfei feng - Sun Microsystems - Beijing China uath_set_rates(struct uath_softc *sc, const struct ieee80211_rateset *rs)
180856f9a274Sfei feng - Sun Microsystems - Beijing China {
180956f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_cmd_rates rates;
181056f9a274Sfei feng - Sun Microsystems - Beijing China int err;
181156f9a274Sfei feng - Sun Microsystems - Beijing China
181256f9a274Sfei feng - Sun Microsystems - Beijing China bzero(&rates, sizeof (rates));
181356f9a274Sfei feng - Sun Microsystems - Beijing China rates.connid = BE_32(UATH_ID_BSS); /* XXX */
181456f9a274Sfei feng - Sun Microsystems - Beijing China rates.size = BE_32(sizeof (struct uath_cmd_rateset));
181556f9a274Sfei feng - Sun Microsystems - Beijing China /* XXX bounds check rs->rs_nrates */
181656f9a274Sfei feng - Sun Microsystems - Beijing China rates.rateset.length = rs->ir_nrates;
181756f9a274Sfei feng - Sun Microsystems - Beijing China bcopy(rs->ir_rates, &rates.rateset.set[0], rs->ir_nrates);
181856f9a274Sfei feng - Sun Microsystems - Beijing China
181956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_set_rates(): "
182056f9a274Sfei feng - Sun Microsystems - Beijing China "setting supported rates nrates=%d\n", rs->ir_nrates);
182156f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_cmd_write(sc, WDCMSG_SET_BASIC_RATE,
182256f9a274Sfei feng - Sun Microsystems - Beijing China &rates, sizeof (rates), 0);
182356f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
182456f9a274Sfei feng - Sun Microsystems - Beijing China }
182556f9a274Sfei feng - Sun Microsystems - Beijing China
182656f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_write_associd(struct uath_softc * sc)182756f9a274Sfei feng - Sun Microsystems - Beijing China uath_write_associd(struct uath_softc *sc)
182856f9a274Sfei feng - Sun Microsystems - Beijing China {
182956f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
183056f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211_node *ni = ic->ic_bss;
183156f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_cmd_set_associd associd;
183256f9a274Sfei feng - Sun Microsystems - Beijing China int err;
183356f9a274Sfei feng - Sun Microsystems - Beijing China
183456f9a274Sfei feng - Sun Microsystems - Beijing China bzero(&associd, sizeof (associd));
183556f9a274Sfei feng - Sun Microsystems - Beijing China associd.defaultrateix = BE_32(1); /* XXX */
183656f9a274Sfei feng - Sun Microsystems - Beijing China associd.associd = BE_32(ni->in_associd);
183756f9a274Sfei feng - Sun Microsystems - Beijing China associd.timoffset = BE_32(0x3b); /* XXX */
183856f9a274Sfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(associd.bssid, ni->in_bssid);
183956f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_cmd_write(sc, WDCMSG_WRITE_ASSOCID, &associd,
184056f9a274Sfei feng - Sun Microsystems - Beijing China sizeof (associd), 0);
184156f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
184256f9a274Sfei feng - Sun Microsystems - Beijing China }
184356f9a274Sfei feng - Sun Microsystems - Beijing China
184456f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_set_ledsteady(struct uath_softc * sc,int lednum,int ledmode)184556f9a274Sfei feng - Sun Microsystems - Beijing China uath_set_ledsteady(struct uath_softc *sc, int lednum, int ledmode)
184656f9a274Sfei feng - Sun Microsystems - Beijing China {
184756f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_cmd_ledsteady led;
184856f9a274Sfei feng - Sun Microsystems - Beijing China int err;
184956f9a274Sfei feng - Sun Microsystems - Beijing China
185056f9a274Sfei feng - Sun Microsystems - Beijing China led.lednum = BE_32(lednum);
185156f9a274Sfei feng - Sun Microsystems - Beijing China led.ledmode = BE_32(ledmode);
185256f9a274Sfei feng - Sun Microsystems - Beijing China
185356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_set_ledsteady(): "
185456f9a274Sfei feng - Sun Microsystems - Beijing China "set %s led %s (steady)\n",
185556f9a274Sfei feng - Sun Microsystems - Beijing China (lednum == UATH_LED_LINK) ? "link" : "activity",
185656f9a274Sfei feng - Sun Microsystems - Beijing China ledmode ? "on" : "off");
185756f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_cmd_write(sc, WDCMSG_SET_LED_STEADY, &led, sizeof (led), 0);
185856f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
185956f9a274Sfei feng - Sun Microsystems - Beijing China }
186056f9a274Sfei feng - Sun Microsystems - Beijing China
186156f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_set_ledblink(struct uath_softc * sc,int lednum,int ledmode,int blinkrate,int slowmode)186256f9a274Sfei feng - Sun Microsystems - Beijing China uath_set_ledblink(struct uath_softc *sc, int lednum, int ledmode,
186356f9a274Sfei feng - Sun Microsystems - Beijing China int blinkrate, int slowmode)
186456f9a274Sfei feng - Sun Microsystems - Beijing China {
186556f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_cmd_ledblink led;
186656f9a274Sfei feng - Sun Microsystems - Beijing China int err;
186756f9a274Sfei feng - Sun Microsystems - Beijing China
186856f9a274Sfei feng - Sun Microsystems - Beijing China led.lednum = BE_32(lednum);
186956f9a274Sfei feng - Sun Microsystems - Beijing China led.ledmode = BE_32(ledmode);
187056f9a274Sfei feng - Sun Microsystems - Beijing China led.blinkrate = BE_32(blinkrate);
187156f9a274Sfei feng - Sun Microsystems - Beijing China led.slowmode = BE_32(slowmode);
187256f9a274Sfei feng - Sun Microsystems - Beijing China
187356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_set_ledblink(): "
187456f9a274Sfei feng - Sun Microsystems - Beijing China "set %s led %s (blink)\n",
187556f9a274Sfei feng - Sun Microsystems - Beijing China (lednum == UATH_LED_LINK) ? "link" : "activity",
187656f9a274Sfei feng - Sun Microsystems - Beijing China ledmode ? "on" : "off");
187756f9a274Sfei feng - Sun Microsystems - Beijing China
187856f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_cmd_write(sc, WDCMSG_SET_LED_BLINK,
187956f9a274Sfei feng - Sun Microsystems - Beijing China &led, sizeof (led), 0);
188056f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
188156f9a274Sfei feng - Sun Microsystems - Beijing China }
188256f9a274Sfei feng - Sun Microsystems - Beijing China
188356f9a274Sfei feng - Sun Microsystems - Beijing China
188456f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_newstate(struct ieee80211com * ic,enum ieee80211_state nstate,int arg)188556f9a274Sfei feng - Sun Microsystems - Beijing China uath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
188656f9a274Sfei feng - Sun Microsystems - Beijing China {
188756f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc = (struct uath_softc *)ic;
188856f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211_node *ni = ic->ic_bss;
188956f9a274Sfei feng - Sun Microsystems - Beijing China enum ieee80211_state ostate;
189056f9a274Sfei feng - Sun Microsystems - Beijing China int err;
189156f9a274Sfei feng - Sun Microsystems - Beijing China
189256f9a274Sfei feng - Sun Microsystems - Beijing China ostate = ic->ic_state;
189356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_newstate(): "
189456f9a274Sfei feng - Sun Microsystems - Beijing China "%d -> %d\n", ostate, nstate);
189556f9a274Sfei feng - Sun Microsystems - Beijing China
189656f9a274Sfei feng - Sun Microsystems - Beijing China if (sc->sc_scan_id != 0) {
189756f9a274Sfei feng - Sun Microsystems - Beijing China (void) untimeout(sc->sc_scan_id);
189856f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_scan_id = 0;
189956f9a274Sfei feng - Sun Microsystems - Beijing China }
190056f9a274Sfei feng - Sun Microsystems - Beijing China
190156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LOCK(sc);
190256f9a274Sfei feng - Sun Microsystems - Beijing China
190356f9a274Sfei feng - Sun Microsystems - Beijing China if (UATH_IS_DISCONNECT(sc) && (nstate != IEEE80211_S_INIT)) {
190456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
190556f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
190656f9a274Sfei feng - Sun Microsystems - Beijing China }
190756f9a274Sfei feng - Sun Microsystems - Beijing China
190856f9a274Sfei feng - Sun Microsystems - Beijing China if (UATH_IS_SUSPEND(sc) && (nstate != IEEE80211_S_INIT)) {
190956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
191056f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
191156f9a274Sfei feng - Sun Microsystems - Beijing China }
191256f9a274Sfei feng - Sun Microsystems - Beijing China
191356f9a274Sfei feng - Sun Microsystems - Beijing China switch (nstate) {
191456f9a274Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_INIT:
191556f9a274Sfei feng - Sun Microsystems - Beijing China if (ostate == IEEE80211_S_RUN) {
191656f9a274Sfei feng - Sun Microsystems - Beijing China /* turn link and activity LEDs off */
191756f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_set_ledstate(sc, 0);
191856f9a274Sfei feng - Sun Microsystems - Beijing China }
191956f9a274Sfei feng - Sun Microsystems - Beijing China break;
192056f9a274Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_SCAN:
192156f9a274Sfei feng - Sun Microsystems - Beijing China if (uath_switch_channel(sc, ic->ic_curchan) != UATH_SUCCESS) {
192256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_newstate(): "
192356f9a274Sfei feng - Sun Microsystems - Beijing China "could not switch channel\n");
192456f9a274Sfei feng - Sun Microsystems - Beijing China break;
192556f9a274Sfei feng - Sun Microsystems - Beijing China }
192656f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_scan_id = timeout(uath_next_scan, (void *)sc,
192756f9a274Sfei feng - Sun Microsystems - Beijing China drv_usectohz(250000));
192856f9a274Sfei feng - Sun Microsystems - Beijing China break;
192956f9a274Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_AUTH:
193056f9a274Sfei feng - Sun Microsystems - Beijing China /* XXX good place? set RTS threshold */
193156f9a274Sfei feng - Sun Microsystems - Beijing China uath_config(sc, CFG_USER_RTS_THRESHOLD, ic->ic_rtsthreshold);
193256f9a274Sfei feng - Sun Microsystems - Beijing China
193356f9a274Sfei feng - Sun Microsystems - Beijing China if (uath_switch_channel(sc, ni->in_chan) != 0) {
193456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_newstate(): "
193556f9a274Sfei feng - Sun Microsystems - Beijing China "could not switch channel\n");
193656f9a274Sfei feng - Sun Microsystems - Beijing China break;
193756f9a274Sfei feng - Sun Microsystems - Beijing China }
193856f9a274Sfei feng - Sun Microsystems - Beijing China if (uath_create_connection(sc, UATH_ID_BSS) != 0) {
193956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_newstate(): "
194056f9a274Sfei feng - Sun Microsystems - Beijing China "could not create connection\n");
194156f9a274Sfei feng - Sun Microsystems - Beijing China break;
194256f9a274Sfei feng - Sun Microsystems - Beijing China }
194356f9a274Sfei feng - Sun Microsystems - Beijing China break;
194456f9a274Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_ASSOC:
194556f9a274Sfei feng - Sun Microsystems - Beijing China if (uath_set_rates(sc, &ni->in_rates) != 0) {
194656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_newstate(): "
194756f9a274Sfei feng - Sun Microsystems - Beijing China "could not set negotiated rate set\n");
194856f9a274Sfei feng - Sun Microsystems - Beijing China break;
194956f9a274Sfei feng - Sun Microsystems - Beijing China }
195056f9a274Sfei feng - Sun Microsystems - Beijing China break;
195156f9a274Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_RUN:
195256f9a274Sfei feng - Sun Microsystems - Beijing China /* XXX monitor mode doesn't be supported */
195356f9a274Sfei feng - Sun Microsystems - Beijing China if (ic->ic_opmode == IEEE80211_M_MONITOR) {
195456f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_set_ledstate(sc, 1);
195556f9a274Sfei feng - Sun Microsystems - Beijing China break;
195656f9a274Sfei feng - Sun Microsystems - Beijing China }
195756f9a274Sfei feng - Sun Microsystems - Beijing China
195856f9a274Sfei feng - Sun Microsystems - Beijing China /*
195956f9a274Sfei feng - Sun Microsystems - Beijing China * Tx rate is controlled by firmware, report the maximum
196056f9a274Sfei feng - Sun Microsystems - Beijing China * negotiated rate in ifconfig output.
196156f9a274Sfei feng - Sun Microsystems - Beijing China */
196256f9a274Sfei feng - Sun Microsystems - Beijing China ni->in_txrate = ni->in_rates.ir_nrates - 1;
196356f9a274Sfei feng - Sun Microsystems - Beijing China
196456f9a274Sfei feng - Sun Microsystems - Beijing China if (uath_write_associd(sc) != 0) {
196556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_newstate(): "
196656f9a274Sfei feng - Sun Microsystems - Beijing China "could not write association id\n");
196756f9a274Sfei feng - Sun Microsystems - Beijing China break;
196856f9a274Sfei feng - Sun Microsystems - Beijing China }
196956f9a274Sfei feng - Sun Microsystems - Beijing China /* turn link LED on */
197056f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_set_ledsteady(sc, UATH_LED_LINK, UATH_LED_ON);
197156f9a274Sfei feng - Sun Microsystems - Beijing China /* make activity LED blink */
197256f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_set_ledblink(sc, UATH_LED_ACTIVITY,
197356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LED_ON, 1, 2);
197456f9a274Sfei feng - Sun Microsystems - Beijing China /* set state to associated */
197556f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_set_ledstate(sc, 1);
197656f9a274Sfei feng - Sun Microsystems - Beijing China break;
197756f9a274Sfei feng - Sun Microsystems - Beijing China }
197856f9a274Sfei feng - Sun Microsystems - Beijing China
197956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
198056f9a274Sfei feng - Sun Microsystems - Beijing China
198156f9a274Sfei feng - Sun Microsystems - Beijing China err = sc->sc_newstate(ic, nstate, arg);
198256f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
198356f9a274Sfei feng - Sun Microsystems - Beijing China }
198456f9a274Sfei feng - Sun Microsystems - Beijing China
198556f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_send(ieee80211com_t * ic,mblk_t * mp,uint8_t type)198656f9a274Sfei feng - Sun Microsystems - Beijing China uath_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type)
198756f9a274Sfei feng - Sun Microsystems - Beijing China {
198856f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc = (struct uath_softc *)ic;
198956f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_chunk *chunk;
199056f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_tx_desc *desc;
199156f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211_frame *wh;
199256f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211_node *ni = NULL;
199356f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211_key *k;
199456f9a274Sfei feng - Sun Microsystems - Beijing China
199556f9a274Sfei feng - Sun Microsystems - Beijing China mblk_t *m, *m0;
199656f9a274Sfei feng - Sun Microsystems - Beijing China int err, off, mblen;
199756f9a274Sfei feng - Sun Microsystems - Beijing China int pktlen, framelen, msglen;
199856f9a274Sfei feng - Sun Microsystems - Beijing China
199956f9a274Sfei feng - Sun Microsystems - Beijing China err = UATH_SUCCESS;
200056f9a274Sfei feng - Sun Microsystems - Beijing China
200156f9a274Sfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_txlock_data);
200256f9a274Sfei feng - Sun Microsystems - Beijing China
200356f9a274Sfei feng - Sun Microsystems - Beijing China if (UATH_IS_SUSPEND(sc)) {
200456f9a274Sfei feng - Sun Microsystems - Beijing China err = 0;
200556f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
200656f9a274Sfei feng - Sun Microsystems - Beijing China }
200756f9a274Sfei feng - Sun Microsystems - Beijing China
200856f9a274Sfei feng - Sun Microsystems - Beijing China if (sc->tx_data_queued > UATH_TX_DATA_LIST_COUNT) {
200956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_TX, "uath: uath_send(): "
201056f9a274Sfei feng - Sun Microsystems - Beijing China "no TX buffer available!\n");
201156f9a274Sfei feng - Sun Microsystems - Beijing China if ((type & IEEE80211_FC0_TYPE_MASK) ==
201256f9a274Sfei feng - Sun Microsystems - Beijing China IEEE80211_FC0_TYPE_DATA) {
201356f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_need_sched = 1;
201456f9a274Sfei feng - Sun Microsystems - Beijing China }
201556f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_tx_nobuf++;
201656f9a274Sfei feng - Sun Microsystems - Beijing China err = ENOMEM;
201756f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
201856f9a274Sfei feng - Sun Microsystems - Beijing China }
201956f9a274Sfei feng - Sun Microsystems - Beijing China
202056f9a274Sfei feng - Sun Microsystems - Beijing China m = allocb(UATH_MAX_TXBUFSZ, BPRI_MED);
202156f9a274Sfei feng - Sun Microsystems - Beijing China if (m == NULL) {
202256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_TX, "uath: uath_send(): "
202356f9a274Sfei feng - Sun Microsystems - Beijing China "can't alloc mblk.\n");
202456f9a274Sfei feng - Sun Microsystems - Beijing China err = DDI_FAILURE;
202556f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
202656f9a274Sfei feng - Sun Microsystems - Beijing China }
202756f9a274Sfei feng - Sun Microsystems - Beijing China
202856f9a274Sfei feng - Sun Microsystems - Beijing China /* skip TX descriptor */
202956f9a274Sfei feng - Sun Microsystems - Beijing China m->b_rptr += sizeof (struct uath_chunk) + sizeof (struct uath_tx_desc);
203056f9a274Sfei feng - Sun Microsystems - Beijing China m->b_wptr += sizeof (struct uath_chunk) + sizeof (struct uath_tx_desc);
203156f9a274Sfei feng - Sun Microsystems - Beijing China
203256f9a274Sfei feng - Sun Microsystems - Beijing China for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) {
203356f9a274Sfei feng - Sun Microsystems - Beijing China mblen = (uintptr_t)m0->b_wptr - (uintptr_t)m0->b_rptr;
203456f9a274Sfei feng - Sun Microsystems - Beijing China (void) memcpy(m->b_rptr + off, m0->b_rptr, mblen);
203556f9a274Sfei feng - Sun Microsystems - Beijing China off += mblen;
203656f9a274Sfei feng - Sun Microsystems - Beijing China }
203756f9a274Sfei feng - Sun Microsystems - Beijing China m->b_wptr += off;
203856f9a274Sfei feng - Sun Microsystems - Beijing China
203956f9a274Sfei feng - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)m->b_rptr;
204056f9a274Sfei feng - Sun Microsystems - Beijing China
204156f9a274Sfei feng - Sun Microsystems - Beijing China ni = ieee80211_find_txnode(ic, wh->i_addr1);
204256f9a274Sfei feng - Sun Microsystems - Beijing China if (ni == NULL) {
204356f9a274Sfei feng - Sun Microsystems - Beijing China err = DDI_FAILURE;
204456f9a274Sfei feng - Sun Microsystems - Beijing China freemsg(m);
204556f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
204656f9a274Sfei feng - Sun Microsystems - Beijing China }
204756f9a274Sfei feng - Sun Microsystems - Beijing China
204856f9a274Sfei feng - Sun Microsystems - Beijing China if ((type & IEEE80211_FC0_TYPE_MASK) ==
204956f9a274Sfei feng - Sun Microsystems - Beijing China IEEE80211_FC0_TYPE_DATA) {
205056f9a274Sfei feng - Sun Microsystems - Beijing China (void) ieee80211_encap(ic, m, ni);
205156f9a274Sfei feng - Sun Microsystems - Beijing China }
205256f9a274Sfei feng - Sun Microsystems - Beijing China
205356f9a274Sfei feng - Sun Microsystems - Beijing China if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
205456f9a274Sfei feng - Sun Microsystems - Beijing China k = ieee80211_crypto_encap(ic, m);
205556f9a274Sfei feng - Sun Microsystems - Beijing China if (k == NULL) {
205656f9a274Sfei feng - Sun Microsystems - Beijing China freemsg(m);
205756f9a274Sfei feng - Sun Microsystems - Beijing China err = DDI_FAILURE;
205856f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
205956f9a274Sfei feng - Sun Microsystems - Beijing China }
206056f9a274Sfei feng - Sun Microsystems - Beijing China /* packet header may have moved, reset our local pointer */
206156f9a274Sfei feng - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)m->b_rptr;
206256f9a274Sfei feng - Sun Microsystems - Beijing China }
206356f9a274Sfei feng - Sun Microsystems - Beijing China
206456f9a274Sfei feng - Sun Microsystems - Beijing China pktlen = (uintptr_t)m->b_wptr - (uintptr_t)m->b_rptr;
206556f9a274Sfei feng - Sun Microsystems - Beijing China framelen = pktlen + IEEE80211_CRC_LEN;
206656f9a274Sfei feng - Sun Microsystems - Beijing China msglen = framelen + sizeof (struct uath_tx_desc);
206756f9a274Sfei feng - Sun Microsystems - Beijing China
206856f9a274Sfei feng - Sun Microsystems - Beijing China m->b_rptr -= sizeof (struct uath_chunk) + sizeof (struct uath_tx_desc);
206956f9a274Sfei feng - Sun Microsystems - Beijing China
207056f9a274Sfei feng - Sun Microsystems - Beijing China chunk = (struct uath_chunk *)m->b_rptr;
207156f9a274Sfei feng - Sun Microsystems - Beijing China desc = (struct uath_tx_desc *)(chunk + 1);
207256f9a274Sfei feng - Sun Microsystems - Beijing China
207356f9a274Sfei feng - Sun Microsystems - Beijing China /* one chunk only for now */
207456f9a274Sfei feng - Sun Microsystems - Beijing China chunk->seqnum = 0;
207556f9a274Sfei feng - Sun Microsystems - Beijing China chunk->flags = UATH_CFLAGS_FINAL;
207656f9a274Sfei feng - Sun Microsystems - Beijing China chunk->length = BE_16(msglen);
207756f9a274Sfei feng - Sun Microsystems - Beijing China
207856f9a274Sfei feng - Sun Microsystems - Beijing China /* fill Tx descriptor */
207956f9a274Sfei feng - Sun Microsystems - Beijing China desc->msglen = BE_32(msglen);
208056f9a274Sfei feng - Sun Microsystems - Beijing China /* NB: to get UATH_TX_NOTIFY reply, `msgid' must be larger than 0 */
208156f9a274Sfei feng - Sun Microsystems - Beijing China desc->msgid = sc->sc_msgid; /* don't care about endianness */
208256f9a274Sfei feng - Sun Microsystems - Beijing China desc->type = BE_32(WDCMSG_SEND);
208356f9a274Sfei feng - Sun Microsystems - Beijing China switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
208456f9a274Sfei feng - Sun Microsystems - Beijing China case IEEE80211_FC0_TYPE_CTL:
208556f9a274Sfei feng - Sun Microsystems - Beijing China case IEEE80211_FC0_TYPE_MGT:
208656f9a274Sfei feng - Sun Microsystems - Beijing China /* NB: force all management frames to highest queue */
208756f9a274Sfei feng - Sun Microsystems - Beijing China if (ni->in_flags & UATH_NODE_QOS) {
208856f9a274Sfei feng - Sun Microsystems - Beijing China /* NB: force all management frames to highest queue */
208956f9a274Sfei feng - Sun Microsystems - Beijing China desc->txqid = BE_32(WME_AC_VO | UATH_TXQID_MINRATE);
209056f9a274Sfei feng - Sun Microsystems - Beijing China } else
209156f9a274Sfei feng - Sun Microsystems - Beijing China desc->txqid = BE_32(WME_AC_BE | UATH_TXQID_MINRATE);
209256f9a274Sfei feng - Sun Microsystems - Beijing China break;
209356f9a274Sfei feng - Sun Microsystems - Beijing China case IEEE80211_FC0_TYPE_DATA:
209456f9a274Sfei feng - Sun Microsystems - Beijing China /* XXX multicast frames should honor mcastrate */
209556f9a274Sfei feng - Sun Microsystems - Beijing China desc->txqid = BE_32(WME_AC_BE);
209656f9a274Sfei feng - Sun Microsystems - Beijing China break;
209756f9a274Sfei feng - Sun Microsystems - Beijing China default:
209856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_TX, "uath: uath_send(): "
209956f9a274Sfei feng - Sun Microsystems - Beijing China "bogus frame type 0x%x (%s)\n",
210056f9a274Sfei feng - Sun Microsystems - Beijing China wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK);
210156f9a274Sfei feng - Sun Microsystems - Beijing China err = EIO;
210256f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
210356f9a274Sfei feng - Sun Microsystems - Beijing China }
210456f9a274Sfei feng - Sun Microsystems - Beijing China
210556f9a274Sfei feng - Sun Microsystems - Beijing China if (ic->ic_state == IEEE80211_S_AUTH ||
210656f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_state == IEEE80211_S_ASSOC ||
210756f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_state == IEEE80211_S_RUN)
210856f9a274Sfei feng - Sun Microsystems - Beijing China desc->connid = BE_32(UATH_ID_BSS);
210956f9a274Sfei feng - Sun Microsystems - Beijing China else
211056f9a274Sfei feng - Sun Microsystems - Beijing China desc->connid = BE_32(UATH_ID_INVALID);
211156f9a274Sfei feng - Sun Microsystems - Beijing China desc->flags = BE_32(0 /* no UATH_TX_NOTIFY */);
211256f9a274Sfei feng - Sun Microsystems - Beijing China desc->buflen = BE_32(pktlen);
211356f9a274Sfei feng - Sun Microsystems - Beijing China
211456f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_tx_data_xfer(sc, m);
211556f9a274Sfei feng - Sun Microsystems - Beijing China
211656f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_msgid = (sc->sc_msgid + 1) % UATH_TX_DATA_LIST_COUNT;
211756f9a274Sfei feng - Sun Microsystems - Beijing China
211856f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_stats.is_tx_frags++;
211956f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_stats.is_tx_bytes += pktlen;
212056f9a274Sfei feng - Sun Microsystems - Beijing China
212156f9a274Sfei feng - Sun Microsystems - Beijing China fail:
212256f9a274Sfei feng - Sun Microsystems - Beijing China if (ni != NULL)
212356f9a274Sfei feng - Sun Microsystems - Beijing China ieee80211_free_node(ni);
212456f9a274Sfei feng - Sun Microsystems - Beijing China if ((mp) &&
212556f9a274Sfei feng - Sun Microsystems - Beijing China ((type & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA ||
212656f9a274Sfei feng - Sun Microsystems - Beijing China err == 0)) {
212756f9a274Sfei feng - Sun Microsystems - Beijing China freemsg(mp);
212856f9a274Sfei feng - Sun Microsystems - Beijing China }
212956f9a274Sfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_txlock_data);
213056f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
213156f9a274Sfei feng - Sun Microsystems - Beijing China }
213256f9a274Sfei feng - Sun Microsystems - Beijing China
213356f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_reconnect(dev_info_t * devinfo)213456f9a274Sfei feng - Sun Microsystems - Beijing China uath_reconnect(dev_info_t *devinfo)
213556f9a274Sfei feng - Sun Microsystems - Beijing China {
213656f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc;
213756f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic;
213856f9a274Sfei feng - Sun Microsystems - Beijing China int err;
213956f9a274Sfei feng - Sun Microsystems - Beijing China uint16_t vendor_id, product_id;
214056f9a274Sfei feng - Sun Microsystems - Beijing China
214156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_reconnect(): "
214256f9a274Sfei feng - Sun Microsystems - Beijing China "uath online\n");
214356f9a274Sfei feng - Sun Microsystems - Beijing China
214456f9a274Sfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(uath_soft_state_p, ddi_get_instance(devinfo));
214556f9a274Sfei feng - Sun Microsystems - Beijing China ASSERT(sc != NULL);
214656f9a274Sfei feng - Sun Microsystems - Beijing China ic = (struct ieee80211com *)&sc->sc_ic;
214756f9a274Sfei feng - Sun Microsystems - Beijing China
214856f9a274Sfei feng - Sun Microsystems - Beijing China if (!UATH_IS_RECONNECT(sc)) {
214956f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_open_pipes(sc);
215056f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
215156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_reconnect(): "
215256f9a274Sfei feng - Sun Microsystems - Beijing China "could not open pipes\n");
215356f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
215456f9a274Sfei feng - Sun Microsystems - Beijing China }
215556f9a274Sfei feng - Sun Microsystems - Beijing China
215656f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_loadfirmware(sc);
215756f9a274Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
215856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_reconnect(): "
215956f9a274Sfei feng - Sun Microsystems - Beijing China "could not download firmware\n");
216056f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
216156f9a274Sfei feng - Sun Microsystems - Beijing China }
216256f9a274Sfei feng - Sun Microsystems - Beijing China
216356f9a274Sfei feng - Sun Microsystems - Beijing China uath_close_pipes(sc);
216456f9a274Sfei feng - Sun Microsystems - Beijing China usb_client_detach(sc->sc_dev, sc->sc_udev);
216556f9a274Sfei feng - Sun Microsystems - Beijing China
216656f9a274Sfei feng - Sun Microsystems - Beijing China /* reset device */
216756f9a274Sfei feng - Sun Microsystems - Beijing China err = usb_reset_device(sc->sc_dev, USB_RESET_LVL_DEFAULT);
216856f9a274Sfei feng - Sun Microsystems - Beijing China if (err != USB_SUCCESS) {
216956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_reconnect(): "
217056f9a274Sfei feng - Sun Microsystems - Beijing China "could not reset device %x\n", err);
217156f9a274Sfei feng - Sun Microsystems - Beijing China }
217256f9a274Sfei feng - Sun Microsystems - Beijing China
217356f9a274Sfei feng - Sun Microsystems - Beijing China err = usb_client_attach(devinfo, USBDRV_VERSION, 0);
217456f9a274Sfei feng - Sun Microsystems - Beijing China if (err != USB_SUCCESS) {
217556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_reconnect(): "
217656f9a274Sfei feng - Sun Microsystems - Beijing China "usb_client_attach failed\n");
217756f9a274Sfei feng - Sun Microsystems - Beijing China }
217856f9a274Sfei feng - Sun Microsystems - Beijing China
217956f9a274Sfei feng - Sun Microsystems - Beijing China err = usb_get_dev_data(devinfo, &sc->sc_udev,
218056f9a274Sfei feng - Sun Microsystems - Beijing China USB_PARSE_LVL_ALL, 0);
218156f9a274Sfei feng - Sun Microsystems - Beijing China if (err != USB_SUCCESS) {
218256f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_udev = NULL;
218356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_reconnect(): "
218456f9a274Sfei feng - Sun Microsystems - Beijing China "usb_get_dev_data failed\n");
218556f9a274Sfei feng - Sun Microsystems - Beijing China }
218656f9a274Sfei feng - Sun Microsystems - Beijing China
218756f9a274Sfei feng - Sun Microsystems - Beijing China vendor_id = sc->sc_udev->dev_descr->idVendor;
218856f9a274Sfei feng - Sun Microsystems - Beijing China product_id = sc->sc_udev->dev_descr->idProduct;
218956f9a274Sfei feng - Sun Microsystems - Beijing China sc->dev_flags = uath_lookup(vendor_id, product_id);
219056f9a274Sfei feng - Sun Microsystems - Beijing China if (sc->dev_flags == UATH_FLAG_ERR) {
219156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_reconnect(): "
219256f9a274Sfei feng - Sun Microsystems - Beijing China "HW does not match\n");
219356f9a274Sfei feng - Sun Microsystems - Beijing China }
219456f9a274Sfei feng - Sun Microsystems - Beijing China
219556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_reconnect(): "
219656f9a274Sfei feng - Sun Microsystems - Beijing China "vendorId = %x,deviceID = %x, flags = %x\n",
219756f9a274Sfei feng - Sun Microsystems - Beijing China vendor_id, product_id, sc->dev_flags);
219856f9a274Sfei feng - Sun Microsystems - Beijing China
219956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LOCK(sc);
220056f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_flags |= UATH_FLAG_RECONNECT;
220156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
220256f9a274Sfei feng - Sun Microsystems - Beijing China
220356f9a274Sfei feng - Sun Microsystems - Beijing China } else {
220456f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_open_pipes(sc);
220556f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
220656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_reconnect(): "
220756f9a274Sfei feng - Sun Microsystems - Beijing China "could not open pipes\n");
220856f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
220956f9a274Sfei feng - Sun Microsystems - Beijing China }
221056f9a274Sfei feng - Sun Microsystems - Beijing China
221156f9a274Sfei feng - Sun Microsystems - Beijing China /*
221256f9a274Sfei feng - Sun Microsystems - Beijing China * Allocate xfers for firmware commands.
221356f9a274Sfei feng - Sun Microsystems - Beijing China */
221456f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_alloc_cmd_list(sc, sc->sc_cmd, UATH_CMD_LIST_COUNT,
221556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_MAX_CMDSZ);
221656f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
221756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_reconnect(): "
221856f9a274Sfei feng - Sun Microsystems - Beijing China "could not allocate Tx command list\n");
221956f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
222056f9a274Sfei feng - Sun Microsystems - Beijing China }
222156f9a274Sfei feng - Sun Microsystems - Beijing China
222256f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_init_cmd_list(sc);
222356f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
222456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_reconnect(): "
222556f9a274Sfei feng - Sun Microsystems - Beijing China "could not init RX command list\n");
222656f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
222756f9a274Sfei feng - Sun Microsystems - Beijing China }
222856f9a274Sfei feng - Sun Microsystems - Beijing China
222956f9a274Sfei feng - Sun Microsystems - Beijing China /*
223056f9a274Sfei feng - Sun Microsystems - Beijing China * We're now ready to send+receive firmware commands.
223156f9a274Sfei feng - Sun Microsystems - Beijing China */
223256f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_host_available(sc);
223356f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
223456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_reconnect(): "
223556f9a274Sfei feng - Sun Microsystems - Beijing China "could not initialize adapter\n");
223656f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
223756f9a274Sfei feng - Sun Microsystems - Beijing China }
223856f9a274Sfei feng - Sun Microsystems - Beijing China
223956f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_get_devcap(sc);
224056f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
224156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_reconnect(): "
224256f9a274Sfei feng - Sun Microsystems - Beijing China "could not get device capabilities\n");
224356f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
224456f9a274Sfei feng - Sun Microsystems - Beijing China }
224556f9a274Sfei feng - Sun Microsystems - Beijing China
224656f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_get_devstatus(sc, ic->ic_macaddr);
224756f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
224856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_reconnect(): "
224956f9a274Sfei feng - Sun Microsystems - Beijing China "could not get dev status\n");
225056f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
225156f9a274Sfei feng - Sun Microsystems - Beijing China }
225256f9a274Sfei feng - Sun Microsystems - Beijing China
225356f9a274Sfei feng - Sun Microsystems - Beijing China err = usb_check_same_device(sc->sc_dev, NULL, USB_LOG_L2, -1,
225456f9a274Sfei feng - Sun Microsystems - Beijing China USB_CHK_BASIC, NULL);
225556f9a274Sfei feng - Sun Microsystems - Beijing China if (err != USB_SUCCESS) {
225656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_reconnect(): "
225756f9a274Sfei feng - Sun Microsystems - Beijing China "different device connected %x\n", err);
225856f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
225956f9a274Sfei feng - Sun Microsystems - Beijing China }
226056f9a274Sfei feng - Sun Microsystems - Beijing China
226156f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_init(sc);
226256f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
226356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_reconnect(): "
226456f9a274Sfei feng - Sun Microsystems - Beijing China "device re-connect failed\n");
226556f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
226656f9a274Sfei feng - Sun Microsystems - Beijing China }
226756f9a274Sfei feng - Sun Microsystems - Beijing China
226856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LOCK(sc);
226956f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_flags &= ~UATH_FLAG_RECONNECT;
227056f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_flags &= ~UATH_FLAG_DISCONNECT;
227156f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_flags |= UATH_FLAG_RUNNING;
227256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
227356f9a274Sfei feng - Sun Microsystems - Beijing China }
227456f9a274Sfei feng - Sun Microsystems - Beijing China
227556f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
227656f9a274Sfei feng - Sun Microsystems - Beijing China }
227756f9a274Sfei feng - Sun Microsystems - Beijing China
227856f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_disconnect(dev_info_t * devinfo)227956f9a274Sfei feng - Sun Microsystems - Beijing China uath_disconnect(dev_info_t *devinfo)
228056f9a274Sfei feng - Sun Microsystems - Beijing China {
228156f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc;
228256f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic;
228356f9a274Sfei feng - Sun Microsystems - Beijing China
228456f9a274Sfei feng - Sun Microsystems - Beijing China /*
228556f9a274Sfei feng - Sun Microsystems - Beijing China * We can't call uath_stop() here, since the hardware is removed,
228656f9a274Sfei feng - Sun Microsystems - Beijing China * we can't access the register anymore.
228756f9a274Sfei feng - Sun Microsystems - Beijing China */
228856f9a274Sfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(uath_soft_state_p, ddi_get_instance(devinfo));
228956f9a274Sfei feng - Sun Microsystems - Beijing China ASSERT(sc != NULL);
229056f9a274Sfei feng - Sun Microsystems - Beijing China
229156f9a274Sfei feng - Sun Microsystems - Beijing China if (sc->sc_flags & UATH_FLAG_RECONNECT) {
229256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_disconnect(): "
229356f9a274Sfei feng - Sun Microsystems - Beijing China "stage 0 in re-connect\n");
229456f9a274Sfei feng - Sun Microsystems - Beijing China uath_close_pipes(sc);
229556f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
229656f9a274Sfei feng - Sun Microsystems - Beijing China }
229756f9a274Sfei feng - Sun Microsystems - Beijing China
229856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LOCK(sc);
229956f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_flags |= UATH_FLAG_DISCONNECT;
230056f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
230156f9a274Sfei feng - Sun Microsystems - Beijing China
230256f9a274Sfei feng - Sun Microsystems - Beijing China ic = (struct ieee80211com *)&sc->sc_ic;
230356f9a274Sfei feng - Sun Microsystems - Beijing China ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
230456f9a274Sfei feng - Sun Microsystems - Beijing China
230556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LOCK(sc);
230656f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_flags &= ~UATH_FLAG_RUNNING; /* STOP */
230756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
230856f9a274Sfei feng - Sun Microsystems - Beijing China
230956f9a274Sfei feng - Sun Microsystems - Beijing China /* abort and free xfers */
231056f9a274Sfei feng - Sun Microsystems - Beijing China uath_free_cmd_list(sc->sc_cmd, UATH_CMD_LIST_COUNT);
231156f9a274Sfei feng - Sun Microsystems - Beijing China
231256f9a274Sfei feng - Sun Microsystems - Beijing China /* close Tx/Rx pipes */
231356f9a274Sfei feng - Sun Microsystems - Beijing China uath_close_pipes(sc);
231456f9a274Sfei feng - Sun Microsystems - Beijing China
231556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_disconnect(): "
231656f9a274Sfei feng - Sun Microsystems - Beijing China "offline success\n");
231756f9a274Sfei feng - Sun Microsystems - Beijing China
231856f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
231956f9a274Sfei feng - Sun Microsystems - Beijing China }
232056f9a274Sfei feng - Sun Microsystems - Beijing China
232156f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_dataflush(struct uath_softc * sc)232256f9a274Sfei feng - Sun Microsystems - Beijing China uath_dataflush(struct uath_softc *sc)
232356f9a274Sfei feng - Sun Microsystems - Beijing China {
232456f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_chunk *chunk;
232556f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_tx_desc *desc;
232656f9a274Sfei feng - Sun Microsystems - Beijing China uint8_t *buf;
232756f9a274Sfei feng - Sun Microsystems - Beijing China int err;
232856f9a274Sfei feng - Sun Microsystems - Beijing China
232956f9a274Sfei feng - Sun Microsystems - Beijing China buf = kmem_alloc(UATH_MAX_TXBUFSZ, KM_NOSLEEP);
233056f9a274Sfei feng - Sun Microsystems - Beijing China if (buf == NULL) {
233156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_dataflush(): "
233256f9a274Sfei feng - Sun Microsystems - Beijing China "no bufs\n");
233356f9a274Sfei feng - Sun Microsystems - Beijing China return (ENOBUFS);
233456f9a274Sfei feng - Sun Microsystems - Beijing China }
233556f9a274Sfei feng - Sun Microsystems - Beijing China
233656f9a274Sfei feng - Sun Microsystems - Beijing China chunk = (struct uath_chunk *)buf;
233756f9a274Sfei feng - Sun Microsystems - Beijing China desc = (struct uath_tx_desc *)(chunk + 1);
233856f9a274Sfei feng - Sun Microsystems - Beijing China
233956f9a274Sfei feng - Sun Microsystems - Beijing China /* one chunk only */
234056f9a274Sfei feng - Sun Microsystems - Beijing China chunk->seqnum = 0;
234156f9a274Sfei feng - Sun Microsystems - Beijing China chunk->flags = UATH_CFLAGS_FINAL;
234256f9a274Sfei feng - Sun Microsystems - Beijing China chunk->length = BE_16(sizeof (struct uath_tx_desc));
234356f9a274Sfei feng - Sun Microsystems - Beijing China
234456f9a274Sfei feng - Sun Microsystems - Beijing China bzero(desc, sizeof (struct uath_tx_desc));
234556f9a274Sfei feng - Sun Microsystems - Beijing China desc->msglen = BE_32(sizeof (struct uath_tx_desc));
234656f9a274Sfei feng - Sun Microsystems - Beijing China desc->msgid = sc->sc_msgid; /* don't care about endianness */
234756f9a274Sfei feng - Sun Microsystems - Beijing China desc->type = BE_32(WDCMSG_FLUSH);
234856f9a274Sfei feng - Sun Microsystems - Beijing China desc->txqid = BE_32(0);
234956f9a274Sfei feng - Sun Microsystems - Beijing China desc->connid = BE_32(0);
235056f9a274Sfei feng - Sun Microsystems - Beijing China desc->flags = BE_32(0);
235156f9a274Sfei feng - Sun Microsystems - Beijing China
235256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_dataflush(): "
235356f9a274Sfei feng - Sun Microsystems - Beijing China "send flush ix %d\n", desc->msgid);
235456f9a274Sfei feng - Sun Microsystems - Beijing China
235556f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_fw_send(sc, sc->tx_data_pipe, buf,
235656f9a274Sfei feng - Sun Microsystems - Beijing China sizeof (struct uath_chunk) + sizeof (struct uath_tx_desc));
235756f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
235856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_dataflush(): "
235956f9a274Sfei feng - Sun Microsystems - Beijing China "data flush error");
236056f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_FAILURE);
236156f9a274Sfei feng - Sun Microsystems - Beijing China }
236256f9a274Sfei feng - Sun Microsystems - Beijing China
236356f9a274Sfei feng - Sun Microsystems - Beijing China kmem_free(buf, UATH_MAX_TXBUFSZ);
236456f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_msgid = (sc->sc_msgid + 1) % UATH_TX_DATA_LIST_COUNT;
236556f9a274Sfei feng - Sun Microsystems - Beijing China
236656f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
236756f9a274Sfei feng - Sun Microsystems - Beijing China }
236856f9a274Sfei feng - Sun Microsystems - Beijing China
236956f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_cmdflush(struct uath_softc * sc)237056f9a274Sfei feng - Sun Microsystems - Beijing China uath_cmdflush(struct uath_softc *sc)
237156f9a274Sfei feng - Sun Microsystems - Beijing China {
237256f9a274Sfei feng - Sun Microsystems - Beijing China return (uath_cmd_write(sc, WDCMSG_FLUSH, NULL, 0, 0));
237356f9a274Sfei feng - Sun Microsystems - Beijing China }
237456f9a274Sfei feng - Sun Microsystems - Beijing China
237556f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_flush(struct uath_softc * sc)237656f9a274Sfei feng - Sun Microsystems - Beijing China uath_flush(struct uath_softc *sc)
237756f9a274Sfei feng - Sun Microsystems - Beijing China {
237856f9a274Sfei feng - Sun Microsystems - Beijing China int err;
237956f9a274Sfei feng - Sun Microsystems - Beijing China
238056f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_dataflush(sc);
238156f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS)
238256f9a274Sfei feng - Sun Microsystems - Beijing China goto failed;
238356f9a274Sfei feng - Sun Microsystems - Beijing China
238456f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_cmdflush(sc);
238556f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS)
238656f9a274Sfei feng - Sun Microsystems - Beijing China goto failed;
238756f9a274Sfei feng - Sun Microsystems - Beijing China
238856f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
238956f9a274Sfei feng - Sun Microsystems - Beijing China failed:
239056f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
239156f9a274Sfei feng - Sun Microsystems - Beijing China }
239256f9a274Sfei feng - Sun Microsystems - Beijing China
239356f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_set_ledstate(struct uath_softc * sc,int connected)239456f9a274Sfei feng - Sun Microsystems - Beijing China uath_set_ledstate(struct uath_softc *sc, int connected)
239556f9a274Sfei feng - Sun Microsystems - Beijing China {
239656f9a274Sfei feng - Sun Microsystems - Beijing China int err;
239756f9a274Sfei feng - Sun Microsystems - Beijing China
239856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_set_ledstate(): "
239956f9a274Sfei feng - Sun Microsystems - Beijing China "set led state %sconnected\n", connected ? "" : "!");
240056f9a274Sfei feng - Sun Microsystems - Beijing China
240156f9a274Sfei feng - Sun Microsystems - Beijing China connected = BE_32(connected);
240256f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_cmd_write(sc, WDCMSG_SET_LED_STATE,
240356f9a274Sfei feng - Sun Microsystems - Beijing China &connected, sizeof (connected), 0);
240456f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
240556f9a274Sfei feng - Sun Microsystems - Beijing China }
240656f9a274Sfei feng - Sun Microsystems - Beijing China
240756f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_config_multi(struct uath_softc * sc,uint32_t reg,const void * data,int len)240856f9a274Sfei feng - Sun Microsystems - Beijing China uath_config_multi(struct uath_softc *sc, uint32_t reg, const void *data,
240956f9a274Sfei feng - Sun Microsystems - Beijing China int len)
241056f9a274Sfei feng - Sun Microsystems - Beijing China {
241156f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_write_mac write;
241256f9a274Sfei feng - Sun Microsystems - Beijing China int err;
241356f9a274Sfei feng - Sun Microsystems - Beijing China
241456f9a274Sfei feng - Sun Microsystems - Beijing China write.reg = BE_32(reg);
241556f9a274Sfei feng - Sun Microsystems - Beijing China write.len = BE_32(len);
241656f9a274Sfei feng - Sun Microsystems - Beijing China bcopy(data, write.data, len);
241756f9a274Sfei feng - Sun Microsystems - Beijing China
241856f9a274Sfei feng - Sun Microsystems - Beijing China /* properly handle the case where len is zero (reset) */
241956f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_cmd_write(sc, WDCMSG_TARGET_SET_CONFIG, &write,
242056f9a274Sfei feng - Sun Microsystems - Beijing China (len == 0) ? sizeof (uint32_t) : 2 * sizeof (uint32_t) + len, 0);
242156f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
242256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_config_multi(): "
242356f9a274Sfei feng - Sun Microsystems - Beijing China "could not write %d bytes to register 0x%02x\n", len, reg);
242456f9a274Sfei feng - Sun Microsystems - Beijing China }
242556f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
242656f9a274Sfei feng - Sun Microsystems - Beijing China }
242756f9a274Sfei feng - Sun Microsystems - Beijing China
242856f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_config(struct uath_softc * sc,uint32_t reg,uint32_t val)242956f9a274Sfei feng - Sun Microsystems - Beijing China uath_config(struct uath_softc *sc, uint32_t reg, uint32_t val)
243056f9a274Sfei feng - Sun Microsystems - Beijing China {
243156f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_write_mac write;
243256f9a274Sfei feng - Sun Microsystems - Beijing China int err;
243356f9a274Sfei feng - Sun Microsystems - Beijing China
243456f9a274Sfei feng - Sun Microsystems - Beijing China write.reg = BE_32(reg);
243556f9a274Sfei feng - Sun Microsystems - Beijing China write.len = BE_32(0); /* 0 = single write */
243656f9a274Sfei feng - Sun Microsystems - Beijing China *(uint32_t *)write.data = BE_32(val);
243756f9a274Sfei feng - Sun Microsystems - Beijing China
243856f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_cmd_write(sc, WDCMSG_TARGET_SET_CONFIG, &write,
243956f9a274Sfei feng - Sun Microsystems - Beijing China 3 * sizeof (uint32_t), 0);
244056f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
244156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_config(): "
244256f9a274Sfei feng - Sun Microsystems - Beijing China "could not write register 0x%02x\n",
244356f9a274Sfei feng - Sun Microsystems - Beijing China reg);
244456f9a274Sfei feng - Sun Microsystems - Beijing China }
244556f9a274Sfei feng - Sun Microsystems - Beijing China }
244656f9a274Sfei feng - Sun Microsystems - Beijing China
244756f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_switch_channel(struct uath_softc * sc,struct ieee80211_channel * c)244856f9a274Sfei feng - Sun Microsystems - Beijing China uath_switch_channel(struct uath_softc *sc, struct ieee80211_channel *c)
244956f9a274Sfei feng - Sun Microsystems - Beijing China {
245056f9a274Sfei feng - Sun Microsystems - Beijing China int err;
245156f9a274Sfei feng - Sun Microsystems - Beijing China
245256f9a274Sfei feng - Sun Microsystems - Beijing China /* set radio frequency */
245356f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_set_chan(sc, c);
245456f9a274Sfei feng - Sun Microsystems - Beijing China if (err) {
245556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_switch_channel(): "
245656f9a274Sfei feng - Sun Microsystems - Beijing China "could not set channel\n");
245756f9a274Sfei feng - Sun Microsystems - Beijing China goto failed;
245856f9a274Sfei feng - Sun Microsystems - Beijing China }
245956f9a274Sfei feng - Sun Microsystems - Beijing China
246056f9a274Sfei feng - Sun Microsystems - Beijing China /* reset Tx rings */
246156f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_reset_tx_queues(sc);
246256f9a274Sfei feng - Sun Microsystems - Beijing China if (err) {
246356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_switch_channel(): "
246456f9a274Sfei feng - Sun Microsystems - Beijing China "could not reset Tx queues\n");
246556f9a274Sfei feng - Sun Microsystems - Beijing China goto failed;
246656f9a274Sfei feng - Sun Microsystems - Beijing China }
246756f9a274Sfei feng - Sun Microsystems - Beijing China
246856f9a274Sfei feng - Sun Microsystems - Beijing China /* set Tx rings WME properties */
246956f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_wme_init(sc);
247056f9a274Sfei feng - Sun Microsystems - Beijing China if (err) {
247156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_switch_channel(): "
247256f9a274Sfei feng - Sun Microsystems - Beijing China "could not init Tx queues\n");
247356f9a274Sfei feng - Sun Microsystems - Beijing China goto failed;
247456f9a274Sfei feng - Sun Microsystems - Beijing China }
247556f9a274Sfei feng - Sun Microsystems - Beijing China
247656f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_set_ledstate(sc, 0);
247756f9a274Sfei feng - Sun Microsystems - Beijing China if (err) {
247856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_switch_channel(): "
247956f9a274Sfei feng - Sun Microsystems - Beijing China "could not set led state\n");
248056f9a274Sfei feng - Sun Microsystems - Beijing China goto failed;
248156f9a274Sfei feng - Sun Microsystems - Beijing China }
248256f9a274Sfei feng - Sun Microsystems - Beijing China
248356f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_flush(sc);
248456f9a274Sfei feng - Sun Microsystems - Beijing China if (err) {
248556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_switch_channel(): "
248656f9a274Sfei feng - Sun Microsystems - Beijing China "could not flush pipes\n");
248756f9a274Sfei feng - Sun Microsystems - Beijing China goto failed;
248856f9a274Sfei feng - Sun Microsystems - Beijing China }
248956f9a274Sfei feng - Sun Microsystems - Beijing China
249056f9a274Sfei feng - Sun Microsystems - Beijing China failed:
249156f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
249256f9a274Sfei feng - Sun Microsystems - Beijing China }
249356f9a274Sfei feng - Sun Microsystems - Beijing China
249456f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_set_rxfilter(struct uath_softc * sc,uint32_t bits,uint32_t op)249556f9a274Sfei feng - Sun Microsystems - Beijing China uath_set_rxfilter(struct uath_softc *sc, uint32_t bits, uint32_t op)
249656f9a274Sfei feng - Sun Microsystems - Beijing China {
249756f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_cmd_rx_filter rxfilter;
249856f9a274Sfei feng - Sun Microsystems - Beijing China
249956f9a274Sfei feng - Sun Microsystems - Beijing China rxfilter.bits = BE_32(bits);
250056f9a274Sfei feng - Sun Microsystems - Beijing China rxfilter.op = BE_32(op);
250156f9a274Sfei feng - Sun Microsystems - Beijing China
250256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_set_rxfilter(): "
250356f9a274Sfei feng - Sun Microsystems - Beijing China "setting Rx filter=0x%x flags=0x%x\n", bits, op);
250456f9a274Sfei feng - Sun Microsystems - Beijing China
250556f9a274Sfei feng - Sun Microsystems - Beijing China return ((uath_cmd_write(sc, WDCMSG_RX_FILTER, &rxfilter,
250656f9a274Sfei feng - Sun Microsystems - Beijing China sizeof (rxfilter), 0)));
250756f9a274Sfei feng - Sun Microsystems - Beijing China }
250856f9a274Sfei feng - Sun Microsystems - Beijing China
250956f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_set_chan(struct uath_softc * sc,struct ieee80211_channel * c)251056f9a274Sfei feng - Sun Microsystems - Beijing China uath_set_chan(struct uath_softc *sc, struct ieee80211_channel *c)
251156f9a274Sfei feng - Sun Microsystems - Beijing China {
251256f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
251356f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_cmd_reset reset;
251456f9a274Sfei feng - Sun Microsystems - Beijing China
251556f9a274Sfei feng - Sun Microsystems - Beijing China bzero(&reset, sizeof (reset));
251656f9a274Sfei feng - Sun Microsystems - Beijing China if (IEEE80211_IS_CHAN_2GHZ(c))
251756f9a274Sfei feng - Sun Microsystems - Beijing China reset.flags |= BE_32(UATH_CHAN_2GHZ);
251856f9a274Sfei feng - Sun Microsystems - Beijing China if (IEEE80211_IS_CHAN_5GHZ(c))
251956f9a274Sfei feng - Sun Microsystems - Beijing China reset.flags |= BE_32(UATH_CHAN_5GHZ);
252056f9a274Sfei feng - Sun Microsystems - Beijing China /* NB: 11g =>'s 11b so don't specify both OFDM and CCK */
252156f9a274Sfei feng - Sun Microsystems - Beijing China if (UATH_IS_CHAN_OFDM(c))
252256f9a274Sfei feng - Sun Microsystems - Beijing China reset.flags |= BE_32(UATH_CHAN_OFDM);
252356f9a274Sfei feng - Sun Microsystems - Beijing China else if (UATH_IS_CHAN_CCK(c))
252456f9a274Sfei feng - Sun Microsystems - Beijing China reset.flags |= BE_32(UATH_CHAN_CCK);
252556f9a274Sfei feng - Sun Microsystems - Beijing China /* turbo can be used in either 2GHz or 5GHz */
252656f9a274Sfei feng - Sun Microsystems - Beijing China if (c->ich_flags & IEEE80211_CHAN_TURBO)
252756f9a274Sfei feng - Sun Microsystems - Beijing China reset.flags |= BE_32(UATH_CHAN_TURBO);
252856f9a274Sfei feng - Sun Microsystems - Beijing China
252956f9a274Sfei feng - Sun Microsystems - Beijing China reset.freq = BE_32(c->ich_freq);
253056f9a274Sfei feng - Sun Microsystems - Beijing China reset.maxrdpower = BE_32(50); /* XXX */
253156f9a274Sfei feng - Sun Microsystems - Beijing China reset.channelchange = BE_32(1);
253256f9a274Sfei feng - Sun Microsystems - Beijing China reset.keeprccontent = BE_32(0);
253356f9a274Sfei feng - Sun Microsystems - Beijing China
253456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_set_chan(): "
253556f9a274Sfei feng - Sun Microsystems - Beijing China "set channel %d, flags 0x%x freq %u\n",
253656f9a274Sfei feng - Sun Microsystems - Beijing China ieee80211_chan2ieee(ic, c),
253756f9a274Sfei feng - Sun Microsystems - Beijing China BE_32(reset.flags), BE_32(reset.freq));
253856f9a274Sfei feng - Sun Microsystems - Beijing China
253956f9a274Sfei feng - Sun Microsystems - Beijing China return (uath_cmd_write(sc, WDCMSG_RESET, &reset, sizeof (reset), 0));
254056f9a274Sfei feng - Sun Microsystems - Beijing China }
254156f9a274Sfei feng - Sun Microsystems - Beijing China
254256f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_reset_tx_queues(struct uath_softc * sc)254356f9a274Sfei feng - Sun Microsystems - Beijing China uath_reset_tx_queues(struct uath_softc *sc)
254456f9a274Sfei feng - Sun Microsystems - Beijing China {
254556f9a274Sfei feng - Sun Microsystems - Beijing China int ac, err;
254656f9a274Sfei feng - Sun Microsystems - Beijing China
254756f9a274Sfei feng - Sun Microsystems - Beijing China for (ac = 0; ac < 4; ac++) {
254856f9a274Sfei feng - Sun Microsystems - Beijing China const uint32_t qid = BE_32(ac);
254956f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_cmd_write(sc, WDCMSG_RELEASE_TX_QUEUE, &qid,
255056f9a274Sfei feng - Sun Microsystems - Beijing China sizeof (qid), 0);
255156f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS)
255256f9a274Sfei feng - Sun Microsystems - Beijing China break;
255356f9a274Sfei feng - Sun Microsystems - Beijing China }
255456f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
255556f9a274Sfei feng - Sun Microsystems - Beijing China }
255656f9a274Sfei feng - Sun Microsystems - Beijing China
255756f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_wme_init(struct uath_softc * sc)255856f9a274Sfei feng - Sun Microsystems - Beijing China uath_wme_init(struct uath_softc *sc)
255956f9a274Sfei feng - Sun Microsystems - Beijing China {
256056f9a274Sfei feng - Sun Microsystems - Beijing China /* XXX get from net80211 */
256156f9a274Sfei feng - Sun Microsystems - Beijing China static const struct uath_wme_settings uath_wme_11g[4] = {
256256f9a274Sfei feng - Sun Microsystems - Beijing China { 7, 4, 10, 0, 0 }, /* Background */
256356f9a274Sfei feng - Sun Microsystems - Beijing China { 3, 4, 10, 0, 0 }, /* Best-Effort */
256456f9a274Sfei feng - Sun Microsystems - Beijing China { 3, 3, 4, 26, 0 }, /* Video */
256556f9a274Sfei feng - Sun Microsystems - Beijing China { 2, 2, 3, 47, 0 } /* Voice */
256656f9a274Sfei feng - Sun Microsystems - Beijing China };
256756f9a274Sfei feng - Sun Microsystems - Beijing China
256856f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_cmd_txq_setup qinfo;
256956f9a274Sfei feng - Sun Microsystems - Beijing China int ac, err;
257056f9a274Sfei feng - Sun Microsystems - Beijing China
257156f9a274Sfei feng - Sun Microsystems - Beijing China for (ac = 0; ac < 4; ac++) {
257256f9a274Sfei feng - Sun Microsystems - Beijing China qinfo.qid = BE_32(ac);
257356f9a274Sfei feng - Sun Microsystems - Beijing China qinfo.len = BE_32(sizeof (qinfo.attr));
257456f9a274Sfei feng - Sun Microsystems - Beijing China qinfo.attr.priority = BE_32(ac); /* XXX */
257556f9a274Sfei feng - Sun Microsystems - Beijing China qinfo.attr.aifs = BE_32(uath_wme_11g[ac].aifsn);
257656f9a274Sfei feng - Sun Microsystems - Beijing China qinfo.attr.logcwmin = BE_32(uath_wme_11g[ac].logcwmin);
257756f9a274Sfei feng - Sun Microsystems - Beijing China qinfo.attr.logcwmax = BE_32(uath_wme_11g[ac].logcwmax);
257856f9a274Sfei feng - Sun Microsystems - Beijing China qinfo.attr.mode = BE_32(uath_wme_11g[ac].acm);
257956f9a274Sfei feng - Sun Microsystems - Beijing China qinfo.attr.qflags = BE_32(1);
258056f9a274Sfei feng - Sun Microsystems - Beijing China qinfo.attr.bursttime =
258156f9a274Sfei feng - Sun Microsystems - Beijing China BE_32(UATH_TXOP_TO_US(uath_wme_11g[ac].txop));
258256f9a274Sfei feng - Sun Microsystems - Beijing China
258356f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_cmd_write(sc, WDCMSG_SETUP_TX_QUEUE, &qinfo,
258456f9a274Sfei feng - Sun Microsystems - Beijing China sizeof (qinfo), 0);
258556f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS)
258656f9a274Sfei feng - Sun Microsystems - Beijing China break;
258756f9a274Sfei feng - Sun Microsystems - Beijing China }
258856f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
258956f9a274Sfei feng - Sun Microsystems - Beijing China }
259056f9a274Sfei feng - Sun Microsystems - Beijing China
259156f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_stop_locked(void * arg)259256f9a274Sfei feng - Sun Microsystems - Beijing China uath_stop_locked(void *arg)
259356f9a274Sfei feng - Sun Microsystems - Beijing China {
259456f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc = (struct uath_softc *)arg;
259556f9a274Sfei feng - Sun Microsystems - Beijing China
259656f9a274Sfei feng - Sun Microsystems - Beijing China /* flush data & control requests into the target */
259756f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_flush(sc);
259856f9a274Sfei feng - Sun Microsystems - Beijing China
259956f9a274Sfei feng - Sun Microsystems - Beijing China /* set a LED status to the disconnected. */
260056f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_set_ledstate(sc, 0);
260156f9a274Sfei feng - Sun Microsystems - Beijing China
260256f9a274Sfei feng - Sun Microsystems - Beijing China /* stop the target */
260356f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_cmd_write(sc, WDCMSG_TARGET_STOP, NULL, 0, 0);
260456f9a274Sfei feng - Sun Microsystems - Beijing China
260556f9a274Sfei feng - Sun Microsystems - Beijing China /* abort any pending transfers */
260656f9a274Sfei feng - Sun Microsystems - Beijing China usb_pipe_reset(sc->sc_dev, sc->rx_data_pipe, USB_FLAGS_SLEEP, NULL, 0);
260756f9a274Sfei feng - Sun Microsystems - Beijing China usb_pipe_reset(sc->sc_dev, sc->tx_data_pipe, USB_FLAGS_SLEEP, NULL, 0);
260856f9a274Sfei feng - Sun Microsystems - Beijing China usb_pipe_reset(sc->sc_dev, sc->tx_cmd_pipe, USB_FLAGS_SLEEP, NULL, 0);
260956f9a274Sfei feng - Sun Microsystems - Beijing China }
261056f9a274Sfei feng - Sun Microsystems - Beijing China
261156f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_init_locked(void * arg)261256f9a274Sfei feng - Sun Microsystems - Beijing China uath_init_locked(void *arg)
261356f9a274Sfei feng - Sun Microsystems - Beijing China {
261456f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc = arg;
261556f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
261656f9a274Sfei feng - Sun Microsystems - Beijing China uint32_t val;
261756f9a274Sfei feng - Sun Microsystems - Beijing China int i, err;
261856f9a274Sfei feng - Sun Microsystems - Beijing China
261956f9a274Sfei feng - Sun Microsystems - Beijing China if (UATH_IS_RUNNING(sc))
262056f9a274Sfei feng - Sun Microsystems - Beijing China uath_stop_locked(sc);
262156f9a274Sfei feng - Sun Microsystems - Beijing China
262256f9a274Sfei feng - Sun Microsystems - Beijing China uath_init_data_queue(sc);
262356f9a274Sfei feng - Sun Microsystems - Beijing China
262456f9a274Sfei feng - Sun Microsystems - Beijing China /* reset variables */
262556f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_intrx_nextnum = sc->sc_msgid = 0;
262656f9a274Sfei feng - Sun Microsystems - Beijing China
262756f9a274Sfei feng - Sun Microsystems - Beijing China val = BE_32(0);
262856f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_cmd_write(sc, WDCMSG_BIND, &val, sizeof (val), 0);
262956f9a274Sfei feng - Sun Microsystems - Beijing China
263056f9a274Sfei feng - Sun Microsystems - Beijing China /* set MAC address */
263156f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_config_multi(sc, CFG_MAC_ADDR,
263256f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr, IEEE80211_ADDR_LEN);
263356f9a274Sfei feng - Sun Microsystems - Beijing China
263456f9a274Sfei feng - Sun Microsystems - Beijing China /* XXX honor net80211 state */
263556f9a274Sfei feng - Sun Microsystems - Beijing China uath_config(sc, CFG_RATE_CONTROL_ENABLE, 0x00000001);
263656f9a274Sfei feng - Sun Microsystems - Beijing China uath_config(sc, CFG_DIVERSITY_CTL, 0x00000001);
263756f9a274Sfei feng - Sun Microsystems - Beijing China uath_config(sc, CFG_ABOLT, 0x0000003f);
263856f9a274Sfei feng - Sun Microsystems - Beijing China uath_config(sc, CFG_WME_ENABLED, 0x00000001);
263956f9a274Sfei feng - Sun Microsystems - Beijing China
264056f9a274Sfei feng - Sun Microsystems - Beijing China uath_config(sc, CFG_SERVICE_TYPE, 1);
264156f9a274Sfei feng - Sun Microsystems - Beijing China uath_config(sc, CFG_TP_SCALE, 0x00000000);
264256f9a274Sfei feng - Sun Microsystems - Beijing China uath_config(sc, CFG_TPC_HALF_DBM5, 0x0000003c);
264356f9a274Sfei feng - Sun Microsystems - Beijing China uath_config(sc, CFG_TPC_HALF_DBM2, 0x0000003c);
264456f9a274Sfei feng - Sun Microsystems - Beijing China uath_config(sc, CFG_OVERRD_TX_POWER, 0x00000000);
264556f9a274Sfei feng - Sun Microsystems - Beijing China uath_config(sc, CFG_GMODE_PROTECTION, 0x00000000);
264656f9a274Sfei feng - Sun Microsystems - Beijing China uath_config(sc, CFG_GMODE_PROTECT_RATE_INDEX, 0x00000003);
264756f9a274Sfei feng - Sun Microsystems - Beijing China uath_config(sc, CFG_PROTECTION_TYPE, 0x00000000);
264856f9a274Sfei feng - Sun Microsystems - Beijing China uath_config(sc, CFG_MODE_CTS, 0x00000002);
264956f9a274Sfei feng - Sun Microsystems - Beijing China
265056f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_cmd_read(sc, WDCMSG_TARGET_START, NULL, 0,
265156f9a274Sfei feng - Sun Microsystems - Beijing China &val, sizeof (val), UATH_CMD_FLAG_MAGIC);
265256f9a274Sfei feng - Sun Microsystems - Beijing China if (err) {
265356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_init_locked(): "
265456f9a274Sfei feng - Sun Microsystems - Beijing China "could not start target\n");
265556f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
265656f9a274Sfei feng - Sun Microsystems - Beijing China }
265756f9a274Sfei feng - Sun Microsystems - Beijing China
265856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_init_locked(): "
265956f9a274Sfei feng - Sun Microsystems - Beijing China "%s returns handle: 0x%x\n",
266056f9a274Sfei feng - Sun Microsystems - Beijing China uath_codename(WDCMSG_TARGET_START), BE_32(val));
266156f9a274Sfei feng - Sun Microsystems - Beijing China
266256f9a274Sfei feng - Sun Microsystems - Beijing China /* set default channel */
266356f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_switch_channel(sc, ic->ic_curchan);
266456f9a274Sfei feng - Sun Microsystems - Beijing China if (err) {
266556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_init_locked(): "
266656f9a274Sfei feng - Sun Microsystems - Beijing China "could not switch channel, error %d\n", err);
266756f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
266856f9a274Sfei feng - Sun Microsystems - Beijing China }
266956f9a274Sfei feng - Sun Microsystems - Beijing China
267056f9a274Sfei feng - Sun Microsystems - Beijing China val = BE_32(TARGET_DEVICE_AWAKE);
267156f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_cmd_write(sc, WDCMSG_SET_PWR_MODE, &val, sizeof (val), 0);
267256f9a274Sfei feng - Sun Microsystems - Beijing China /* XXX? check */
267356f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_cmd_write(sc, WDCMSG_RESET_KEY_CACHE, NULL, 0, 0);
267456f9a274Sfei feng - Sun Microsystems - Beijing China
267556f9a274Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < UATH_RX_DATA_LIST_COUNT; i++) {
267656f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_rx_data_xfer(sc);
267756f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
267856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_init_locked(): "
267956f9a274Sfei feng - Sun Microsystems - Beijing China "could not alloc rx xfer %x\n", i);
268056f9a274Sfei feng - Sun Microsystems - Beijing China goto fail;
268156f9a274Sfei feng - Sun Microsystems - Beijing China }
268256f9a274Sfei feng - Sun Microsystems - Beijing China }
268356f9a274Sfei feng - Sun Microsystems - Beijing China
268456f9a274Sfei feng - Sun Microsystems - Beijing China /* enable Rx */
268556f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_set_rxfilter(sc, 0x0, UATH_FILTER_OP_INIT);
268656f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_set_rxfilter(sc,
268756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_FILTER_RX_UCAST | UATH_FILTER_RX_MCAST |
268856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_FILTER_RX_BCAST | UATH_FILTER_RX_BEACON,
268956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_FILTER_OP_SET);
269056f9a274Sfei feng - Sun Microsystems - Beijing China
269156f9a274Sfei feng - Sun Microsystems - Beijing China return (UATH_SUCCESS);
269256f9a274Sfei feng - Sun Microsystems - Beijing China
269356f9a274Sfei feng - Sun Microsystems - Beijing China fail:
269456f9a274Sfei feng - Sun Microsystems - Beijing China uath_stop_locked(sc);
269556f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
269656f9a274Sfei feng - Sun Microsystems - Beijing China }
269756f9a274Sfei feng - Sun Microsystems - Beijing China
269856f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_init(struct uath_softc * sc)269956f9a274Sfei feng - Sun Microsystems - Beijing China uath_init(struct uath_softc *sc)
270056f9a274Sfei feng - Sun Microsystems - Beijing China {
270156f9a274Sfei feng - Sun Microsystems - Beijing China int err;
270256f9a274Sfei feng - Sun Microsystems - Beijing China
270356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LOCK(sc);
270456f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_init_locked(sc);
270556f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
270656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_init(): "
270756f9a274Sfei feng - Sun Microsystems - Beijing China "failed to initialize uath hardware\n");
270856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
270956f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
271056f9a274Sfei feng - Sun Microsystems - Beijing China }
271156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
271256f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
271356f9a274Sfei feng - Sun Microsystems - Beijing China }
271456f9a274Sfei feng - Sun Microsystems - Beijing China
271556f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_stop(struct uath_softc * sc)271656f9a274Sfei feng - Sun Microsystems - Beijing China uath_stop(struct uath_softc *sc)
271756f9a274Sfei feng - Sun Microsystems - Beijing China {
271856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_stop(): "
271956f9a274Sfei feng - Sun Microsystems - Beijing China "uath stop now\n");
272056f9a274Sfei feng - Sun Microsystems - Beijing China
272156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LOCK(sc);
272256f9a274Sfei feng - Sun Microsystems - Beijing China uath_stop_locked(sc);
272356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
272456f9a274Sfei feng - Sun Microsystems - Beijing China }
272556f9a274Sfei feng - Sun Microsystems - Beijing China
272656f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_resume(struct uath_softc * sc)272756f9a274Sfei feng - Sun Microsystems - Beijing China uath_resume(struct uath_softc *sc)
272856f9a274Sfei feng - Sun Microsystems - Beijing China {
272956f9a274Sfei feng - Sun Microsystems - Beijing China int err;
273056f9a274Sfei feng - Sun Microsystems - Beijing China
273156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_resume(): "
273256f9a274Sfei feng - Sun Microsystems - Beijing China "uath resume now\n");
273356f9a274Sfei feng - Sun Microsystems - Beijing China
273456f9a274Sfei feng - Sun Microsystems - Beijing China /* check device changes after suspend */
273556f9a274Sfei feng - Sun Microsystems - Beijing China if (usb_check_same_device(sc->sc_dev, NULL, USB_LOG_L2, -1,
273656f9a274Sfei feng - Sun Microsystems - Beijing China USB_CHK_BASIC | USB_CHK_CFG, NULL) != USB_SUCCESS) {
273756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_resume: "
273856f9a274Sfei feng - Sun Microsystems - Beijing China "no or different device connected\n");
273956f9a274Sfei feng - Sun Microsystems - Beijing China return;
274056f9a274Sfei feng - Sun Microsystems - Beijing China }
274156f9a274Sfei feng - Sun Microsystems - Beijing China
274256f9a274Sfei feng - Sun Microsystems - Beijing China /*
274356f9a274Sfei feng - Sun Microsystems - Beijing China * initialize hardware
274456f9a274Sfei feng - Sun Microsystems - Beijing China */
274556f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_init_cmd_list(sc);
274656f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
274756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_resume(): "
274856f9a274Sfei feng - Sun Microsystems - Beijing China "could not init RX command list\n");
274956f9a274Sfei feng - Sun Microsystems - Beijing China return;
275056f9a274Sfei feng - Sun Microsystems - Beijing China }
275156f9a274Sfei feng - Sun Microsystems - Beijing China
275256f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_init(sc);
275356f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
275456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_resume(): "
275556f9a274Sfei feng - Sun Microsystems - Beijing China "hardware init failed\n");
275656f9a274Sfei feng - Sun Microsystems - Beijing China uath_stop(sc);
275756f9a274Sfei feng - Sun Microsystems - Beijing China return;
275856f9a274Sfei feng - Sun Microsystems - Beijing China }
275956f9a274Sfei feng - Sun Microsystems - Beijing China
276056f9a274Sfei feng - Sun Microsystems - Beijing China ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
276156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LOCK(sc);
276256f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_flags &= ~UATH_FLAG_SUSPEND;
276356f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_flags |= UATH_FLAG_RUNNING;
276456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
276556f9a274Sfei feng - Sun Microsystems - Beijing China }
276656f9a274Sfei feng - Sun Microsystems - Beijing China
276756f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_m_start(void * arg)276856f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_start(void *arg)
276956f9a274Sfei feng - Sun Microsystems - Beijing China {
277056f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc = (struct uath_softc *)arg;
277156f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
277256f9a274Sfei feng - Sun Microsystems - Beijing China int err;
277356f9a274Sfei feng - Sun Microsystems - Beijing China
277456f9a274Sfei feng - Sun Microsystems - Beijing China /*
277556f9a274Sfei feng - Sun Microsystems - Beijing China * initialize hardware
277656f9a274Sfei feng - Sun Microsystems - Beijing China */
277756f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_init(sc);
277856f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
277956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_m_start(): "
278056f9a274Sfei feng - Sun Microsystems - Beijing China "device configuration failed\n");
278156f9a274Sfei feng - Sun Microsystems - Beijing China uath_stop(sc);
278256f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
278356f9a274Sfei feng - Sun Microsystems - Beijing China }
278456f9a274Sfei feng - Sun Microsystems - Beijing China
278556f9a274Sfei feng - Sun Microsystems - Beijing China ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
278656f9a274Sfei feng - Sun Microsystems - Beijing China
278756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LOCK(sc);
278856f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_flags |= UATH_FLAG_RUNNING;
278956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
279056f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
279156f9a274Sfei feng - Sun Microsystems - Beijing China }
279256f9a274Sfei feng - Sun Microsystems - Beijing China
279356f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_m_stop(void * arg)279456f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_stop(void *arg)
279556f9a274Sfei feng - Sun Microsystems - Beijing China {
279656f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc = (struct uath_softc *)arg;
279756f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
279856f9a274Sfei feng - Sun Microsystems - Beijing China
279956f9a274Sfei feng - Sun Microsystems - Beijing China ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
280056f9a274Sfei feng - Sun Microsystems - Beijing China
280156f9a274Sfei feng - Sun Microsystems - Beijing China if (!UATH_IS_DISCONNECT(sc))
280256f9a274Sfei feng - Sun Microsystems - Beijing China uath_stop(sc);
280356f9a274Sfei feng - Sun Microsystems - Beijing China
280456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LOCK(sc);
280556f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_flags &= ~UATH_FLAG_RUNNING;
280656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
280756f9a274Sfei feng - Sun Microsystems - Beijing China }
280856f9a274Sfei feng - Sun Microsystems - Beijing China
280956f9a274Sfei feng - Sun Microsystems - Beijing China static void
uath_m_ioctl(void * arg,queue_t * wq,mblk_t * mp)281056f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_ioctl(void* arg, queue_t *wq, mblk_t *mp)
281156f9a274Sfei feng - Sun Microsystems - Beijing China {
281256f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc = (struct uath_softc *)arg;
281356f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
281456f9a274Sfei feng - Sun Microsystems - Beijing China int err;
281556f9a274Sfei feng - Sun Microsystems - Beijing China
281656f9a274Sfei feng - Sun Microsystems - Beijing China err = ieee80211_ioctl(ic, wq, mp);
281756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LOCK(sc);
281856f9a274Sfei feng - Sun Microsystems - Beijing China if (err == ENETRESET) {
281956f9a274Sfei feng - Sun Microsystems - Beijing China if (ic->ic_des_esslen) {
282056f9a274Sfei feng - Sun Microsystems - Beijing China if (UATH_IS_RUNNING(sc)) {
282156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
282256f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_init(sc);
282356f9a274Sfei feng - Sun Microsystems - Beijing China (void) ieee80211_new_state(ic,
282456f9a274Sfei feng - Sun Microsystems - Beijing China IEEE80211_S_SCAN, -1);
282556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LOCK(sc);
282656f9a274Sfei feng - Sun Microsystems - Beijing China }
282756f9a274Sfei feng - Sun Microsystems - Beijing China }
282856f9a274Sfei feng - Sun Microsystems - Beijing China }
282956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
283056f9a274Sfei feng - Sun Microsystems - Beijing China }
283156f9a274Sfei feng - Sun Microsystems - Beijing China
283256f9a274Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/
283356f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_m_unicst(void * arg,const uint8_t * macaddr)283456f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_unicst(void *arg, const uint8_t *macaddr)
283556f9a274Sfei feng - Sun Microsystems - Beijing China {
283656f9a274Sfei feng - Sun Microsystems - Beijing China return (0);
283756f9a274Sfei feng - Sun Microsystems - Beijing China }
283856f9a274Sfei feng - Sun Microsystems - Beijing China
283956f9a274Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/
284056f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_m_multicst(void * arg,boolean_t add,const uint8_t * mca)284156f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_multicst(void *arg, boolean_t add, const uint8_t *mca)
284256f9a274Sfei feng - Sun Microsystems - Beijing China {
284356f9a274Sfei feng - Sun Microsystems - Beijing China return (0);
284456f9a274Sfei feng - Sun Microsystems - Beijing China }
284556f9a274Sfei feng - Sun Microsystems - Beijing China
284656f9a274Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/
284756f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_m_promisc(void * arg,boolean_t on)284856f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_promisc(void *arg, boolean_t on)
284956f9a274Sfei feng - Sun Microsystems - Beijing China {
285056f9a274Sfei feng - Sun Microsystems - Beijing China return (0);
285156f9a274Sfei feng - Sun Microsystems - Beijing China }
285256f9a274Sfei feng - Sun Microsystems - Beijing China
285356f9a274Sfei feng - Sun Microsystems - Beijing China /*
285456f9a274Sfei feng - Sun Microsystems - Beijing China * callback functions for /get/set properties
285556f9a274Sfei feng - Sun Microsystems - Beijing China */
285656f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_m_setprop(void * arg,const char * pr_name,mac_prop_id_t wldp_pr_num,uint_t wldp_length,const void * wldp_buf)285756f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
285856f9a274Sfei feng - Sun Microsystems - Beijing China uint_t wldp_length, const void *wldp_buf)
285956f9a274Sfei feng - Sun Microsystems - Beijing China {
286056f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc = (struct uath_softc *)arg;
286156f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
286256f9a274Sfei feng - Sun Microsystems - Beijing China int err;
286356f9a274Sfei feng - Sun Microsystems - Beijing China
286456f9a274Sfei feng - Sun Microsystems - Beijing China err = ieee80211_setprop(ic, pr_name, wldp_pr_num,
286556f9a274Sfei feng - Sun Microsystems - Beijing China wldp_length, wldp_buf);
286656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LOCK(sc);
286756f9a274Sfei feng - Sun Microsystems - Beijing China if (err == ENETRESET) {
286856f9a274Sfei feng - Sun Microsystems - Beijing China if (ic->ic_des_esslen && UATH_IS_RUNNING(sc)) {
286956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
287056f9a274Sfei feng - Sun Microsystems - Beijing China (void) uath_init(sc);
287156f9a274Sfei feng - Sun Microsystems - Beijing China (void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
287256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LOCK(sc);
287356f9a274Sfei feng - Sun Microsystems - Beijing China }
287456f9a274Sfei feng - Sun Microsystems - Beijing China err = 0;
287556f9a274Sfei feng - Sun Microsystems - Beijing China }
287656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
287756f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
287856f9a274Sfei feng - Sun Microsystems - Beijing China }
287956f9a274Sfei feng - Sun Microsystems - Beijing China
288056f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_m_getprop(void * arg,const char * pr_name,mac_prop_id_t wldp_pr_num,uint_t wldp_length,void * wldp_buf)288156f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2882*0dc2366fSVenugopal Iyer uint_t wldp_length, void *wldp_buf)
288356f9a274Sfei feng - Sun Microsystems - Beijing China {
288456f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc = (struct uath_softc *)arg;
288556f9a274Sfei feng - Sun Microsystems - Beijing China int err;
288656f9a274Sfei feng - Sun Microsystems - Beijing China
288756f9a274Sfei feng - Sun Microsystems - Beijing China err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_num,
2888*0dc2366fSVenugopal Iyer wldp_length, wldp_buf);
288956f9a274Sfei feng - Sun Microsystems - Beijing China return (err);
289056f9a274Sfei feng - Sun Microsystems - Beijing China }
289156f9a274Sfei feng - Sun Microsystems - Beijing China
2892*0dc2366fSVenugopal Iyer static void
uath_m_propinfo(void * arg,const char * pr_name,mac_prop_id_t wldp_pr_num,mac_prop_info_handle_t prh)2893*0dc2366fSVenugopal Iyer uath_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2894*0dc2366fSVenugopal Iyer mac_prop_info_handle_t prh)
2895*0dc2366fSVenugopal Iyer {
2896*0dc2366fSVenugopal Iyer struct uath_softc *sc = (struct uath_softc *)arg;
2897*0dc2366fSVenugopal Iyer
2898*0dc2366fSVenugopal Iyer ieee80211_propinfo(&sc->sc_ic, pr_name, wldp_pr_num, prh);
2899*0dc2366fSVenugopal Iyer }
2900*0dc2366fSVenugopal Iyer
290156f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_m_stat(void * arg,uint_t stat,uint64_t * val)290256f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_stat(void *arg, uint_t stat, uint64_t *val)
290356f9a274Sfei feng - Sun Microsystems - Beijing China {
290456f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc = (struct uath_softc *)arg;
290556f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
290656f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211_node *ni = NULL;
290756f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211_rateset *rs = NULL;
290856f9a274Sfei feng - Sun Microsystems - Beijing China
290956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LOCK(sc);
291056f9a274Sfei feng - Sun Microsystems - Beijing China switch (stat) {
291156f9a274Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_IFSPEED:
291256f9a274Sfei feng - Sun Microsystems - Beijing China ni = ic->ic_bss;
291356f9a274Sfei feng - Sun Microsystems - Beijing China rs = &ni->in_rates;
291456f9a274Sfei feng - Sun Microsystems - Beijing China *val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ?
291556f9a274Sfei feng - Sun Microsystems - Beijing China (rs->ir_rates[ni->in_txrate] & IEEE80211_RATE_VAL)
291656f9a274Sfei feng - Sun Microsystems - Beijing China : ic->ic_fixed_rate) * 5000000ull;
291756f9a274Sfei feng - Sun Microsystems - Beijing China break;
291856f9a274Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_NOXMTBUF:
291956f9a274Sfei feng - Sun Microsystems - Beijing China *val = sc->sc_tx_nobuf;
292056f9a274Sfei feng - Sun Microsystems - Beijing China break;
292156f9a274Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_NORCVBUF:
292256f9a274Sfei feng - Sun Microsystems - Beijing China *val = sc->sc_rx_nobuf;
292356f9a274Sfei feng - Sun Microsystems - Beijing China break;
292456f9a274Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_IERRORS:
292556f9a274Sfei feng - Sun Microsystems - Beijing China *val = sc->sc_rx_err;
292656f9a274Sfei feng - Sun Microsystems - Beijing China break;
292756f9a274Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_RBYTES:
292856f9a274Sfei feng - Sun Microsystems - Beijing China *val = ic->ic_stats.is_rx_bytes;
292956f9a274Sfei feng - Sun Microsystems - Beijing China break;
293056f9a274Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_IPACKETS:
293156f9a274Sfei feng - Sun Microsystems - Beijing China *val = ic->ic_stats.is_rx_frags;
293256f9a274Sfei feng - Sun Microsystems - Beijing China break;
293356f9a274Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_OBYTES:
293456f9a274Sfei feng - Sun Microsystems - Beijing China *val = ic->ic_stats.is_tx_bytes;
293556f9a274Sfei feng - Sun Microsystems - Beijing China break;
293656f9a274Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_OPACKETS:
293756f9a274Sfei feng - Sun Microsystems - Beijing China *val = ic->ic_stats.is_tx_frags;
293856f9a274Sfei feng - Sun Microsystems - Beijing China break;
293956f9a274Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_OERRORS:
294056f9a274Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_TX_FAILED:
294156f9a274Sfei feng - Sun Microsystems - Beijing China *val = sc->sc_tx_err;
294256f9a274Sfei feng - Sun Microsystems - Beijing China break;
294356f9a274Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_TX_RETRANS:
294456f9a274Sfei feng - Sun Microsystems - Beijing China *val = sc->sc_tx_retries;
294556f9a274Sfei feng - Sun Microsystems - Beijing China break;
294656f9a274Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_FCS_ERRORS:
294756f9a274Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_WEP_ERRORS:
294856f9a274Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_TX_FRAGS:
294956f9a274Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_MCAST_TX:
295056f9a274Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_RTS_SUCCESS:
295156f9a274Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_RTS_FAILURE:
295256f9a274Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_ACK_FAILURE:
295356f9a274Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_RX_FRAGS:
295456f9a274Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_MCAST_RX:
295556f9a274Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_RX_DUPS:
295656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
295756f9a274Sfei feng - Sun Microsystems - Beijing China return (ieee80211_stat(ic, stat, val));
295856f9a274Sfei feng - Sun Microsystems - Beijing China default:
295956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
296056f9a274Sfei feng - Sun Microsystems - Beijing China return (ENOTSUP);
296156f9a274Sfei feng - Sun Microsystems - Beijing China }
296256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
296356f9a274Sfei feng - Sun Microsystems - Beijing China
296456f9a274Sfei feng - Sun Microsystems - Beijing China return (0);
296556f9a274Sfei feng - Sun Microsystems - Beijing China }
296656f9a274Sfei feng - Sun Microsystems - Beijing China
296756f9a274Sfei feng - Sun Microsystems - Beijing China static mblk_t *
uath_m_tx(void * arg,mblk_t * mp)296856f9a274Sfei feng - Sun Microsystems - Beijing China uath_m_tx(void *arg, mblk_t *mp)
296956f9a274Sfei feng - Sun Microsystems - Beijing China {
297056f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc = (struct uath_softc *)arg;
297156f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic;
297256f9a274Sfei feng - Sun Microsystems - Beijing China mblk_t *next;
297356f9a274Sfei feng - Sun Microsystems - Beijing China
297456f9a274Sfei feng - Sun Microsystems - Beijing China /*
297556f9a274Sfei feng - Sun Microsystems - Beijing China * No data frames go out unless we're associated; this
297656f9a274Sfei feng - Sun Microsystems - Beijing China * should not happen as the 802.11 layer does not enable
297756f9a274Sfei feng - Sun Microsystems - Beijing China * the xmit queue until we enter the RUN state.
297856f9a274Sfei feng - Sun Microsystems - Beijing China */
297956f9a274Sfei feng - Sun Microsystems - Beijing China if ((ic->ic_state != IEEE80211_S_RUN) ||
298056f9a274Sfei feng - Sun Microsystems - Beijing China UATH_IS_SUSPEND(sc)) {
298156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_m_tx(): "
298256f9a274Sfei feng - Sun Microsystems - Beijing China "discard, state %u\n", ic->ic_state);
298356f9a274Sfei feng - Sun Microsystems - Beijing China freemsgchain(mp);
298456f9a274Sfei feng - Sun Microsystems - Beijing China return (NULL);
298556f9a274Sfei feng - Sun Microsystems - Beijing China }
298656f9a274Sfei feng - Sun Microsystems - Beijing China
298756f9a274Sfei feng - Sun Microsystems - Beijing China while (mp != NULL) {
298856f9a274Sfei feng - Sun Microsystems - Beijing China next = mp->b_next;
298956f9a274Sfei feng - Sun Microsystems - Beijing China mp->b_next = NULL;
299056f9a274Sfei feng - Sun Microsystems - Beijing China if (uath_send(ic, mp, IEEE80211_FC0_TYPE_DATA) != DDI_SUCCESS) {
299156f9a274Sfei feng - Sun Microsystems - Beijing China mp->b_next = next;
299256f9a274Sfei feng - Sun Microsystems - Beijing China break;
299356f9a274Sfei feng - Sun Microsystems - Beijing China }
299456f9a274Sfei feng - Sun Microsystems - Beijing China mp = next;
299556f9a274Sfei feng - Sun Microsystems - Beijing China }
299656f9a274Sfei feng - Sun Microsystems - Beijing China return (mp);
299756f9a274Sfei feng - Sun Microsystems - Beijing China }
299856f9a274Sfei feng - Sun Microsystems - Beijing China
299956f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_attach(dev_info_t * devinfo,ddi_attach_cmd_t cmd)300056f9a274Sfei feng - Sun Microsystems - Beijing China uath_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
300156f9a274Sfei feng - Sun Microsystems - Beijing China {
300256f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc;
300356f9a274Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic;
300456f9a274Sfei feng - Sun Microsystems - Beijing China
300556f9a274Sfei feng - Sun Microsystems - Beijing China int i, err, instance;
300656f9a274Sfei feng - Sun Microsystems - Beijing China char strbuf[32];
300756f9a274Sfei feng - Sun Microsystems - Beijing China uint16_t vendor_id, product_id;
300856f9a274Sfei feng - Sun Microsystems - Beijing China
300956f9a274Sfei feng - Sun Microsystems - Beijing China wifi_data_t wd = { 0 };
301056f9a274Sfei feng - Sun Microsystems - Beijing China mac_register_t *macp;
301156f9a274Sfei feng - Sun Microsystems - Beijing China
301256f9a274Sfei feng - Sun Microsystems - Beijing China switch (cmd) {
301356f9a274Sfei feng - Sun Microsystems - Beijing China case DDI_ATTACH:
301456f9a274Sfei feng - Sun Microsystems - Beijing China break;
301556f9a274Sfei feng - Sun Microsystems - Beijing China case DDI_RESUME:
301656f9a274Sfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(uath_soft_state_p,
301756f9a274Sfei feng - Sun Microsystems - Beijing China ddi_get_instance(devinfo));
301856f9a274Sfei feng - Sun Microsystems - Beijing China ASSERT(sc != NULL);
301956f9a274Sfei feng - Sun Microsystems - Beijing China uath_resume(sc);
302056f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
302156f9a274Sfei feng - Sun Microsystems - Beijing China default:
302256f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
302356f9a274Sfei feng - Sun Microsystems - Beijing China }
302456f9a274Sfei feng - Sun Microsystems - Beijing China
302556f9a274Sfei feng - Sun Microsystems - Beijing China instance = ddi_get_instance(devinfo);
302656f9a274Sfei feng - Sun Microsystems - Beijing China err = ddi_soft_state_zalloc(uath_soft_state_p, instance);
302756f9a274Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
302856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_attach(): "
302956f9a274Sfei feng - Sun Microsystems - Beijing China "ddi_soft_state_zalloc failed\n");
303056f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
303156f9a274Sfei feng - Sun Microsystems - Beijing China }
303256f9a274Sfei feng - Sun Microsystems - Beijing China
303356f9a274Sfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(uath_soft_state_p, instance);
303456f9a274Sfei feng - Sun Microsystems - Beijing China ic = (ieee80211com_t *)&sc->sc_ic;
303556f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_dev = devinfo;
303656f9a274Sfei feng - Sun Microsystems - Beijing China
303756f9a274Sfei feng - Sun Microsystems - Beijing China err = usb_client_attach(devinfo, USBDRV_VERSION, 0);
303856f9a274Sfei feng - Sun Microsystems - Beijing China if (err != USB_SUCCESS) {
303956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_attach(): "
304056f9a274Sfei feng - Sun Microsystems - Beijing China "usb_client_attach failed\n");
304156f9a274Sfei feng - Sun Microsystems - Beijing China goto fail1;
304256f9a274Sfei feng - Sun Microsystems - Beijing China }
304356f9a274Sfei feng - Sun Microsystems - Beijing China
304456f9a274Sfei feng - Sun Microsystems - Beijing China err = usb_get_dev_data(devinfo, &sc->sc_udev, USB_PARSE_LVL_ALL, 0);
304556f9a274Sfei feng - Sun Microsystems - Beijing China if (err != USB_SUCCESS) {
304656f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_udev = NULL;
304756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_attach(): "
304856f9a274Sfei feng - Sun Microsystems - Beijing China "usb_get_dev_data failed\n");
304956f9a274Sfei feng - Sun Microsystems - Beijing China goto fail2;
305056f9a274Sfei feng - Sun Microsystems - Beijing China }
305156f9a274Sfei feng - Sun Microsystems - Beijing China
305256f9a274Sfei feng - Sun Microsystems - Beijing China vendor_id = sc->sc_udev->dev_descr->idVendor;
305356f9a274Sfei feng - Sun Microsystems - Beijing China product_id = sc->sc_udev->dev_descr->idProduct;
305456f9a274Sfei feng - Sun Microsystems - Beijing China sc->dev_flags = uath_lookup(vendor_id, product_id);
305556f9a274Sfei feng - Sun Microsystems - Beijing China if (sc->dev_flags == UATH_FLAG_ERR) {
305656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_attach(): "
305756f9a274Sfei feng - Sun Microsystems - Beijing China "HW does not match\n");
305856f9a274Sfei feng - Sun Microsystems - Beijing China goto fail2;
305956f9a274Sfei feng - Sun Microsystems - Beijing China }
306056f9a274Sfei feng - Sun Microsystems - Beijing China
306156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_attach(): "
306256f9a274Sfei feng - Sun Microsystems - Beijing China "vendorId = %x,deviceID = %x, flags = %x\n",
306356f9a274Sfei feng - Sun Microsystems - Beijing China vendor_id, product_id, sc->dev_flags);
306456f9a274Sfei feng - Sun Microsystems - Beijing China
306556f9a274Sfei feng - Sun Microsystems - Beijing China /*
306656f9a274Sfei feng - Sun Microsystems - Beijing China * We must open the pipes early because they're used to upload the
306756f9a274Sfei feng - Sun Microsystems - Beijing China * firmware (pre-firmware devices) or to send firmware commands.
306856f9a274Sfei feng - Sun Microsystems - Beijing China */
306956f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_open_pipes(sc);
307056f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
307156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_attach(): "
307256f9a274Sfei feng - Sun Microsystems - Beijing China "could not open pipes\n");
307356f9a274Sfei feng - Sun Microsystems - Beijing China goto fail3;
307456f9a274Sfei feng - Sun Microsystems - Beijing China }
307556f9a274Sfei feng - Sun Microsystems - Beijing China
307656f9a274Sfei feng - Sun Microsystems - Beijing China if (sc->dev_flags & UATH_FLAG_PRE_FIRMWARE) {
307756f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_loadfirmware(sc);
307856f9a274Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) {
307956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_attach(): "
308056f9a274Sfei feng - Sun Microsystems - Beijing China "could not read firmware %s, err %d\n",
308156f9a274Sfei feng - Sun Microsystems - Beijing China "uath-ar5523", err);
308256f9a274Sfei feng - Sun Microsystems - Beijing China goto fail3;
308356f9a274Sfei feng - Sun Microsystems - Beijing China }
308456f9a274Sfei feng - Sun Microsystems - Beijing China
308556f9a274Sfei feng - Sun Microsystems - Beijing China uath_close_pipes(sc);
308656f9a274Sfei feng - Sun Microsystems - Beijing China usb_client_detach(sc->sc_dev, sc->sc_udev);
308756f9a274Sfei feng - Sun Microsystems - Beijing China
308856f9a274Sfei feng - Sun Microsystems - Beijing China err = usb_reset_device(devinfo, USB_RESET_LVL_REATTACH);
308956f9a274Sfei feng - Sun Microsystems - Beijing China if (err != USB_SUCCESS) {
309056f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_attach(): "
309156f9a274Sfei feng - Sun Microsystems - Beijing China "could not re-attach, err %d\n", err);
309256f9a274Sfei feng - Sun Microsystems - Beijing China goto fail1;
309356f9a274Sfei feng - Sun Microsystems - Beijing China }
309456f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
309556f9a274Sfei feng - Sun Microsystems - Beijing China }
309656f9a274Sfei feng - Sun Microsystems - Beijing China
309756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_attach(): "
309856f9a274Sfei feng - Sun Microsystems - Beijing China "firmware download and re-attach successfully\n");
309956f9a274Sfei feng - Sun Microsystems - Beijing China
310056f9a274Sfei feng - Sun Microsystems - Beijing China /*
310156f9a274Sfei feng - Sun Microsystems - Beijing China * Only post-firmware devices here.
310256f9a274Sfei feng - Sun Microsystems - Beijing China */
310356f9a274Sfei feng - Sun Microsystems - Beijing China mutex_init(&sc->sc_genlock, NULL, MUTEX_DRIVER, NULL);
310456f9a274Sfei feng - Sun Microsystems - Beijing China mutex_init(&sc->sc_rxlock_cmd, NULL, MUTEX_DRIVER, NULL);
310556f9a274Sfei feng - Sun Microsystems - Beijing China mutex_init(&sc->sc_txlock_cmd, NULL, MUTEX_DRIVER, NULL);
310656f9a274Sfei feng - Sun Microsystems - Beijing China mutex_init(&sc->sc_rxlock_data, NULL, MUTEX_DRIVER, NULL);
310756f9a274Sfei feng - Sun Microsystems - Beijing China mutex_init(&sc->sc_txlock_data, NULL, MUTEX_DRIVER, NULL);
310856f9a274Sfei feng - Sun Microsystems - Beijing China
310956f9a274Sfei feng - Sun Microsystems - Beijing China /*
311056f9a274Sfei feng - Sun Microsystems - Beijing China * Allocate xfers for firmware commands.
311156f9a274Sfei feng - Sun Microsystems - Beijing China */
311256f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_alloc_cmd_list(sc, sc->sc_cmd, UATH_CMD_LIST_COUNT,
311356f9a274Sfei feng - Sun Microsystems - Beijing China UATH_MAX_CMDSZ);
311456f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
311556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_attach(): "
311656f9a274Sfei feng - Sun Microsystems - Beijing China "could not allocate Tx command list\n");
311756f9a274Sfei feng - Sun Microsystems - Beijing China goto fail4;
311856f9a274Sfei feng - Sun Microsystems - Beijing China }
311956f9a274Sfei feng - Sun Microsystems - Beijing China
312056f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_init_cmd_list(sc);
312156f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
312256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_attach(): "
312356f9a274Sfei feng - Sun Microsystems - Beijing China "could not init RX command list\n");
312456f9a274Sfei feng - Sun Microsystems - Beijing China goto fail5;
312556f9a274Sfei feng - Sun Microsystems - Beijing China }
312656f9a274Sfei feng - Sun Microsystems - Beijing China
312756f9a274Sfei feng - Sun Microsystems - Beijing China /*
312856f9a274Sfei feng - Sun Microsystems - Beijing China * We're now ready to send+receive firmware commands.
312956f9a274Sfei feng - Sun Microsystems - Beijing China */
313056f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_host_available(sc);
313156f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
313256f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_attach(): "
313356f9a274Sfei feng - Sun Microsystems - Beijing China "could not initialize adapter\n");
313456f9a274Sfei feng - Sun Microsystems - Beijing China goto fail5;
313556f9a274Sfei feng - Sun Microsystems - Beijing China }
313656f9a274Sfei feng - Sun Microsystems - Beijing China
313756f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_get_devcap(sc);
313856f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
313956f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_attach(): "
314056f9a274Sfei feng - Sun Microsystems - Beijing China "could not get device capabilities\n");
314156f9a274Sfei feng - Sun Microsystems - Beijing China goto fail5;
314256f9a274Sfei feng - Sun Microsystems - Beijing China }
314356f9a274Sfei feng - Sun Microsystems - Beijing China
314456f9a274Sfei feng - Sun Microsystems - Beijing China err = uath_get_devstatus(sc, ic->ic_macaddr);
314556f9a274Sfei feng - Sun Microsystems - Beijing China if (err != UATH_SUCCESS) {
314656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_attach(): "
314756f9a274Sfei feng - Sun Microsystems - Beijing China "could not get dev status\n");
314856f9a274Sfei feng - Sun Microsystems - Beijing China goto fail5;
314956f9a274Sfei feng - Sun Microsystems - Beijing China }
315056f9a274Sfei feng - Sun Microsystems - Beijing China
315156f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_attach(): "
315256f9a274Sfei feng - Sun Microsystems - Beijing China "MAC address is: %x:%x:%x:%x:%x:%x\n",
315356f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[0], ic->ic_macaddr[1], ic->ic_macaddr[2],
315456f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[3], ic->ic_macaddr[4], ic->ic_macaddr[5]);
315556f9a274Sfei feng - Sun Microsystems - Beijing China
315656f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
315756f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
315856f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_state = IEEE80211_S_INIT;
315956f9a274Sfei feng - Sun Microsystems - Beijing China
316056f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_maxrssi = 40;
316156f9a274Sfei feng - Sun Microsystems - Beijing China
316256f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_xmit = uath_send;
316356f9a274Sfei feng - Sun Microsystems - Beijing China
316456f9a274Sfei feng - Sun Microsystems - Beijing China /* set device capabilities */
316556f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_caps =
316656f9a274Sfei feng - Sun Microsystems - Beijing China IEEE80211_C_TXPMGT | /* tx power management */
316756f9a274Sfei feng - Sun Microsystems - Beijing China IEEE80211_C_SHPREAMBLE | /* short preamble supported */
316856f9a274Sfei feng - Sun Microsystems - Beijing China IEEE80211_C_SHSLOT; /* short slot time supported */
316956f9a274Sfei feng - Sun Microsystems - Beijing China
317056f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_caps |= IEEE80211_C_WPA; /* Support WPA/WPA2 */
317156f9a274Sfei feng - Sun Microsystems - Beijing China
317256f9a274Sfei feng - Sun Microsystems - Beijing China /* set supported .11b and .11g rates */
317356f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_sup_rates[IEEE80211_MODE_11B] = uath_rateset_11b;
317456f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_sup_rates[IEEE80211_MODE_11G] = uath_rateset_11g;
317556f9a274Sfei feng - Sun Microsystems - Beijing China
317656f9a274Sfei feng - Sun Microsystems - Beijing China /* set supported .11b and .11g channels (1 through 11) */
317756f9a274Sfei feng - Sun Microsystems - Beijing China for (i = 1; i <= 11; i++) {
317856f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_sup_channels[i].ich_freq =
317956f9a274Sfei feng - Sun Microsystems - Beijing China ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
318056f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_sup_channels[i].ich_flags =
318156f9a274Sfei feng - Sun Microsystems - Beijing China IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
318256f9a274Sfei feng - Sun Microsystems - Beijing China IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
318356f9a274Sfei feng - Sun Microsystems - Beijing China }
318456f9a274Sfei feng - Sun Microsystems - Beijing China
318556f9a274Sfei feng - Sun Microsystems - Beijing China ieee80211_attach(ic);
318656f9a274Sfei feng - Sun Microsystems - Beijing China
318756f9a274Sfei feng - Sun Microsystems - Beijing China /* register WPA door */
318856f9a274Sfei feng - Sun Microsystems - Beijing China ieee80211_register_door(ic, ddi_driver_name(devinfo),
318956f9a274Sfei feng - Sun Microsystems - Beijing China ddi_get_instance(devinfo));
319056f9a274Sfei feng - Sun Microsystems - Beijing China
319156f9a274Sfei feng - Sun Microsystems - Beijing China /* override state transition machine */
319256f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_newstate = ic->ic_newstate;
319356f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_newstate = uath_newstate;
319456f9a274Sfei feng - Sun Microsystems - Beijing China ieee80211_media_init(ic);
319556f9a274Sfei feng - Sun Microsystems - Beijing China ic->ic_def_txkey = 0;
319656f9a274Sfei feng - Sun Microsystems - Beijing China
319756f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_flags = 0;
319856f9a274Sfei feng - Sun Microsystems - Beijing China
319956f9a274Sfei feng - Sun Microsystems - Beijing China /*
320056f9a274Sfei feng - Sun Microsystems - Beijing China * Provide initial settings for the WiFi plugin; whenever this
320156f9a274Sfei feng - Sun Microsystems - Beijing China * information changes, we need to call mac_plugindata_update()
320256f9a274Sfei feng - Sun Microsystems - Beijing China */
320356f9a274Sfei feng - Sun Microsystems - Beijing China wd.wd_opmode = ic->ic_opmode;
320456f9a274Sfei feng - Sun Microsystems - Beijing China wd.wd_secalloc = WIFI_SEC_NONE;
320556f9a274Sfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid);
320656f9a274Sfei feng - Sun Microsystems - Beijing China
320756f9a274Sfei feng - Sun Microsystems - Beijing China if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
320856f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath_attach(): "
320956f9a274Sfei feng - Sun Microsystems - Beijing China "MAC version mismatch\n");
321056f9a274Sfei feng - Sun Microsystems - Beijing China goto fail5;
321156f9a274Sfei feng - Sun Microsystems - Beijing China }
321256f9a274Sfei feng - Sun Microsystems - Beijing China
321356f9a274Sfei feng - Sun Microsystems - Beijing China macp->m_type_ident = MAC_PLUGIN_IDENT_WIFI;
321456f9a274Sfei feng - Sun Microsystems - Beijing China macp->m_driver = sc;
321556f9a274Sfei feng - Sun Microsystems - Beijing China macp->m_dip = devinfo;
321656f9a274Sfei feng - Sun Microsystems - Beijing China macp->m_src_addr = ic->ic_macaddr;
321756f9a274Sfei feng - Sun Microsystems - Beijing China macp->m_callbacks = &uath_m_callbacks;
321856f9a274Sfei feng - Sun Microsystems - Beijing China macp->m_min_sdu = 0;
321956f9a274Sfei feng - Sun Microsystems - Beijing China macp->m_max_sdu = IEEE80211_MTU;
322056f9a274Sfei feng - Sun Microsystems - Beijing China macp->m_pdata = &wd;
322156f9a274Sfei feng - Sun Microsystems - Beijing China macp->m_pdata_size = sizeof (wd);
322256f9a274Sfei feng - Sun Microsystems - Beijing China
322356f9a274Sfei feng - Sun Microsystems - Beijing China err = mac_register(macp, &ic->ic_mach);
322456f9a274Sfei feng - Sun Microsystems - Beijing China mac_free(macp);
322556f9a274Sfei feng - Sun Microsystems - Beijing China if (err != 0) {
322656f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath_attach(): "
322756f9a274Sfei feng - Sun Microsystems - Beijing China "mac_register() error %x\n", err);
322856f9a274Sfei feng - Sun Microsystems - Beijing China goto fail5;
322956f9a274Sfei feng - Sun Microsystems - Beijing China };
323056f9a274Sfei feng - Sun Microsystems - Beijing China
323156f9a274Sfei feng - Sun Microsystems - Beijing China err = usb_register_hotplug_cbs(devinfo,
323256f9a274Sfei feng - Sun Microsystems - Beijing China uath_disconnect, uath_reconnect);
323356f9a274Sfei feng - Sun Microsystems - Beijing China if (err != USB_SUCCESS) {
323456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_attach(): "
323556f9a274Sfei feng - Sun Microsystems - Beijing China "failed to register events\n");
323656f9a274Sfei feng - Sun Microsystems - Beijing China goto fail6;
323756f9a274Sfei feng - Sun Microsystems - Beijing China }
323856f9a274Sfei feng - Sun Microsystems - Beijing China
323956f9a274Sfei feng - Sun Microsystems - Beijing China /*
324056f9a274Sfei feng - Sun Microsystems - Beijing China * Create minor node of type DDI_NT_NET_WIFI
324156f9a274Sfei feng - Sun Microsystems - Beijing China */
324256f9a274Sfei feng - Sun Microsystems - Beijing China (void) snprintf(strbuf, sizeof (strbuf), "%s%d",
324356f9a274Sfei feng - Sun Microsystems - Beijing China "uath", instance);
324456f9a274Sfei feng - Sun Microsystems - Beijing China err = ddi_create_minor_node(devinfo, strbuf, S_IFCHR,
324556f9a274Sfei feng - Sun Microsystems - Beijing China instance + 1, DDI_NT_NET_WIFI, 0);
324656f9a274Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS)
324756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_ERR, "uath: uath_attach(): "
324856f9a274Sfei feng - Sun Microsystems - Beijing China "ddi_create_minor_node() failed\n");
324956f9a274Sfei feng - Sun Microsystems - Beijing China
325056f9a274Sfei feng - Sun Microsystems - Beijing China /*
325156f9a274Sfei feng - Sun Microsystems - Beijing China * Notify link is down now
325256f9a274Sfei feng - Sun Microsystems - Beijing China */
325356f9a274Sfei feng - Sun Microsystems - Beijing China mac_link_update(ic->ic_mach, LINK_STATE_DOWN);
325456f9a274Sfei feng - Sun Microsystems - Beijing China
325556f9a274Sfei feng - Sun Microsystems - Beijing China UATH_DEBUG(UATH_DBG_MSG, "uath: uath_attach(): "
325656f9a274Sfei feng - Sun Microsystems - Beijing China "attach success\n");
325756f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
325856f9a274Sfei feng - Sun Microsystems - Beijing China
325956f9a274Sfei feng - Sun Microsystems - Beijing China fail6:
326056f9a274Sfei feng - Sun Microsystems - Beijing China (void) mac_unregister(ic->ic_mach);
326156f9a274Sfei feng - Sun Microsystems - Beijing China fail5:
326256f9a274Sfei feng - Sun Microsystems - Beijing China uath_free_cmd_list(sc->sc_cmd, UATH_CMD_LIST_COUNT);
326356f9a274Sfei feng - Sun Microsystems - Beijing China fail4:
326456f9a274Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_genlock);
326556f9a274Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_rxlock_cmd);
326656f9a274Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_rxlock_data);
326756f9a274Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_txlock_cmd);
326856f9a274Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_txlock_data);
326956f9a274Sfei feng - Sun Microsystems - Beijing China fail3:
327056f9a274Sfei feng - Sun Microsystems - Beijing China uath_close_pipes(sc);
327156f9a274Sfei feng - Sun Microsystems - Beijing China fail2:
327256f9a274Sfei feng - Sun Microsystems - Beijing China usb_client_detach(sc->sc_dev, sc->sc_udev);
327356f9a274Sfei feng - Sun Microsystems - Beijing China fail1:
327456f9a274Sfei feng - Sun Microsystems - Beijing China ddi_soft_state_free(uath_soft_state_p, ddi_get_instance(devinfo));
327556f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
327656f9a274Sfei feng - Sun Microsystems - Beijing China }
327756f9a274Sfei feng - Sun Microsystems - Beijing China
327856f9a274Sfei feng - Sun Microsystems - Beijing China static int
uath_detach(dev_info_t * devinfo,ddi_detach_cmd_t cmd)327956f9a274Sfei feng - Sun Microsystems - Beijing China uath_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
328056f9a274Sfei feng - Sun Microsystems - Beijing China {
328156f9a274Sfei feng - Sun Microsystems - Beijing China struct uath_softc *sc;
328256f9a274Sfei feng - Sun Microsystems - Beijing China
328356f9a274Sfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(uath_soft_state_p, ddi_get_instance(devinfo));
328456f9a274Sfei feng - Sun Microsystems - Beijing China ASSERT(sc != NULL);
328556f9a274Sfei feng - Sun Microsystems - Beijing China
328656f9a274Sfei feng - Sun Microsystems - Beijing China switch (cmd) {
328756f9a274Sfei feng - Sun Microsystems - Beijing China case DDI_DETACH:
328856f9a274Sfei feng - Sun Microsystems - Beijing China break;
328956f9a274Sfei feng - Sun Microsystems - Beijing China case DDI_SUSPEND:
329056f9a274Sfei feng - Sun Microsystems - Beijing China if (UATH_IS_RUNNING(sc)) {
329156f9a274Sfei feng - Sun Microsystems - Beijing China ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
329256f9a274Sfei feng - Sun Microsystems - Beijing China uath_stop(sc);
329356f9a274Sfei feng - Sun Microsystems - Beijing China }
329456f9a274Sfei feng - Sun Microsystems - Beijing China UATH_LOCK(sc);
329556f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_flags &= ~UATH_FLAG_RUNNING;
329656f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_flags |= UATH_FLAG_SUSPEND;
329756f9a274Sfei feng - Sun Microsystems - Beijing China UATH_UNLOCK(sc);
329856f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
329956f9a274Sfei feng - Sun Microsystems - Beijing China default:
330056f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
330156f9a274Sfei feng - Sun Microsystems - Beijing China }
330256f9a274Sfei feng - Sun Microsystems - Beijing China
330356f9a274Sfei feng - Sun Microsystems - Beijing China if (sc->dev_flags & UATH_FLAG_PRE_FIRMWARE) {
330456f9a274Sfei feng - Sun Microsystems - Beijing China ddi_soft_state_free(uath_soft_state_p,
330556f9a274Sfei feng - Sun Microsystems - Beijing China ddi_get_instance(devinfo));
330656f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
330756f9a274Sfei feng - Sun Microsystems - Beijing China }
330856f9a274Sfei feng - Sun Microsystems - Beijing China
330956f9a274Sfei feng - Sun Microsystems - Beijing China if (!UATH_IS_DISCONNECT(sc) && UATH_IS_RUNNING(sc))
331056f9a274Sfei feng - Sun Microsystems - Beijing China uath_stop(sc);
331156f9a274Sfei feng - Sun Microsystems - Beijing China
331256f9a274Sfei feng - Sun Microsystems - Beijing China uath_free_cmd_list(sc->sc_cmd, UATH_CMD_LIST_COUNT);
331356f9a274Sfei feng - Sun Microsystems - Beijing China
331456f9a274Sfei feng - Sun Microsystems - Beijing China if (mac_disable(sc->sc_ic.ic_mach) != 0)
331556f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
331656f9a274Sfei feng - Sun Microsystems - Beijing China
331756f9a274Sfei feng - Sun Microsystems - Beijing China /*
331856f9a274Sfei feng - Sun Microsystems - Beijing China * Unregister from the MAC layer subsystem
331956f9a274Sfei feng - Sun Microsystems - Beijing China */
332056f9a274Sfei feng - Sun Microsystems - Beijing China if (mac_unregister(sc->sc_ic.ic_mach) != 0)
332156f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE);
332256f9a274Sfei feng - Sun Microsystems - Beijing China
332356f9a274Sfei feng - Sun Microsystems - Beijing China /*
332456f9a274Sfei feng - Sun Microsystems - Beijing China * detach ieee80211 layer
332556f9a274Sfei feng - Sun Microsystems - Beijing China */
332656f9a274Sfei feng - Sun Microsystems - Beijing China ieee80211_detach(&sc->sc_ic);
332756f9a274Sfei feng - Sun Microsystems - Beijing China
332856f9a274Sfei feng - Sun Microsystems - Beijing China /* close Tx/Rx pipes */
332956f9a274Sfei feng - Sun Microsystems - Beijing China uath_close_pipes(sc);
333056f9a274Sfei feng - Sun Microsystems - Beijing China usb_unregister_hotplug_cbs(devinfo);
333156f9a274Sfei feng - Sun Microsystems - Beijing China
333256f9a274Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_genlock);
333356f9a274Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_rxlock_cmd);
333456f9a274Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_rxlock_data);
333556f9a274Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_txlock_cmd);
333656f9a274Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_txlock_data);
333756f9a274Sfei feng - Sun Microsystems - Beijing China
333856f9a274Sfei feng - Sun Microsystems - Beijing China /* pipes will be close in uath_stop() */
333956f9a274Sfei feng - Sun Microsystems - Beijing China usb_client_detach(devinfo, sc->sc_udev);
334056f9a274Sfei feng - Sun Microsystems - Beijing China sc->sc_udev = NULL;
334156f9a274Sfei feng - Sun Microsystems - Beijing China
334256f9a274Sfei feng - Sun Microsystems - Beijing China ddi_remove_minor_node(devinfo, NULL);
334356f9a274Sfei feng - Sun Microsystems - Beijing China ddi_soft_state_free(uath_soft_state_p, ddi_get_instance(devinfo));
334456f9a274Sfei feng - Sun Microsystems - Beijing China
334556f9a274Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS);
334656f9a274Sfei feng - Sun Microsystems - Beijing China }
334756f9a274Sfei feng - Sun Microsystems - Beijing China
334856f9a274Sfei feng - Sun Microsystems - Beijing China int
_info(struct modinfo * modinfop)334956f9a274Sfei feng - Sun Microsystems - Beijing China _info(struct modinfo *modinfop)
335056f9a274Sfei feng - Sun Microsystems - Beijing China {
335156f9a274Sfei feng - Sun Microsystems - Beijing China return (mod_info(&modlinkage, modinfop));
335256f9a274Sfei feng - Sun Microsystems - Beijing China }
335356f9a274Sfei feng - Sun Microsystems - Beijing China
335456f9a274Sfei feng - Sun Microsystems - Beijing China int
_init(void)335556f9a274Sfei feng - Sun Microsystems - Beijing China _init(void)
335656f9a274Sfei feng - Sun Microsystems - Beijing China {
335756f9a274Sfei feng - Sun Microsystems - Beijing China int status;
335856f9a274Sfei feng - Sun Microsystems - Beijing China
335956f9a274Sfei feng - Sun Microsystems - Beijing China status = ddi_soft_state_init(&uath_soft_state_p,
336056f9a274Sfei feng - Sun Microsystems - Beijing China sizeof (struct uath_softc), 1);
336156f9a274Sfei feng - Sun Microsystems - Beijing China if (status != 0)
336256f9a274Sfei feng - Sun Microsystems - Beijing China return (status);
336356f9a274Sfei feng - Sun Microsystems - Beijing China
336456f9a274Sfei feng - Sun Microsystems - Beijing China mac_init_ops(&uath_dev_ops, "uath");
336556f9a274Sfei feng - Sun Microsystems - Beijing China status = mod_install(&modlinkage);
336656f9a274Sfei feng - Sun Microsystems - Beijing China if (status != 0) {
336756f9a274Sfei feng - Sun Microsystems - Beijing China mac_fini_ops(&uath_dev_ops);
336856f9a274Sfei feng - Sun Microsystems - Beijing China ddi_soft_state_fini(&uath_soft_state_p);
336956f9a274Sfei feng - Sun Microsystems - Beijing China }
337056f9a274Sfei feng - Sun Microsystems - Beijing China return (status);
337156f9a274Sfei feng - Sun Microsystems - Beijing China }
337256f9a274Sfei feng - Sun Microsystems - Beijing China
337356f9a274Sfei feng - Sun Microsystems - Beijing China int
_fini(void)337456f9a274Sfei feng - Sun Microsystems - Beijing China _fini(void)
337556f9a274Sfei feng - Sun Microsystems - Beijing China {
337656f9a274Sfei feng - Sun Microsystems - Beijing China int status;
337756f9a274Sfei feng - Sun Microsystems - Beijing China
337856f9a274Sfei feng - Sun Microsystems - Beijing China status = mod_remove(&modlinkage);
337956f9a274Sfei feng - Sun Microsystems - Beijing China if (status == 0) {
338056f9a274Sfei feng - Sun Microsystems - Beijing China mac_fini_ops(&uath_dev_ops);
338156f9a274Sfei feng - Sun Microsystems - Beijing China ddi_soft_state_fini(&uath_soft_state_p);
338256f9a274Sfei feng - Sun Microsystems - Beijing China }
338356f9a274Sfei feng - Sun Microsystems - Beijing China return (status);
338456f9a274Sfei feng - Sun Microsystems - Beijing China }
3385