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