1d8d81063Sfei feng - Sun Microsystems - Beijing China /* 20dc2366fSVenugopal Iyer * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 3d8d81063Sfei feng - Sun Microsystems - Beijing China * Use is subject to license terms. 4d8d81063Sfei feng - Sun Microsystems - Beijing China */ 5d8d81063Sfei feng - Sun Microsystems - Beijing China 6d8d81063Sfei feng - Sun Microsystems - Beijing China /* 7d8d81063Sfei feng - Sun Microsystems - Beijing China * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting 8d8d81063Sfei feng - Sun Microsystems - Beijing China * Copyright (c) 2007-2008 Marvell Semiconductor, Inc. 9d8d81063Sfei feng - Sun Microsystems - Beijing China * All rights reserved. 10d8d81063Sfei feng - Sun Microsystems - Beijing China * 11d8d81063Sfei feng - Sun Microsystems - Beijing China * Redistribution and use in source and binary forms, with or without 12d8d81063Sfei feng - Sun Microsystems - Beijing China * modification, are permitted provided that the following conditions 13d8d81063Sfei feng - Sun Microsystems - Beijing China * are met: 14d8d81063Sfei feng - Sun Microsystems - Beijing China * 1. Redistributions of source code must retain the above copyright 15d8d81063Sfei feng - Sun Microsystems - Beijing China * notice, this list of conditions and the following disclaimer, 16d8d81063Sfei feng - Sun Microsystems - Beijing China * without modification. 17d8d81063Sfei feng - Sun Microsystems - Beijing China * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18d8d81063Sfei feng - Sun Microsystems - Beijing China * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 19d8d81063Sfei feng - Sun Microsystems - Beijing China * redistribution must be conditioned upon including a substantially 20d8d81063Sfei feng - Sun Microsystems - Beijing China * similar Disclaimer requirement for further binary redistribution. 21d8d81063Sfei feng - Sun Microsystems - Beijing China * 22d8d81063Sfei feng - Sun Microsystems - Beijing China * NO WARRANTY 23d8d81063Sfei feng - Sun Microsystems - Beijing China * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24d8d81063Sfei feng - Sun Microsystems - Beijing China * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25d8d81063Sfei feng - Sun Microsystems - Beijing China * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 26d8d81063Sfei feng - Sun Microsystems - Beijing China * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 27d8d81063Sfei feng - Sun Microsystems - Beijing China * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 28d8d81063Sfei feng - Sun Microsystems - Beijing China * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29d8d81063Sfei feng - Sun Microsystems - Beijing China * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30d8d81063Sfei feng - Sun Microsystems - Beijing China * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 31d8d81063Sfei feng - Sun Microsystems - Beijing China * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32d8d81063Sfei feng - Sun Microsystems - Beijing China * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 33d8d81063Sfei feng - Sun Microsystems - Beijing China * THE POSSIBILITY OF SUCH DAMAGES. 34d8d81063Sfei feng - Sun Microsystems - Beijing China */ 35d8d81063Sfei feng - Sun Microsystems - Beijing China 36*d3351b34SJohn Levon /* 37*d3351b34SJohn Levon * Copyright 2019 Joyent, Inc. 38*d3351b34SJohn Levon */ 39*d3351b34SJohn Levon 40d8d81063Sfei feng - Sun Microsystems - Beijing China /* 41d8d81063Sfei feng - Sun Microsystems - Beijing China * Driver for the Marvell 88W8363 Wireless LAN controller. 42d8d81063Sfei feng - Sun Microsystems - Beijing China */ 43d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/stat.h> 44d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/dlpi.h> 45d8d81063Sfei feng - Sun Microsystems - Beijing China #include <inet/common.h> 46d8d81063Sfei feng - Sun Microsystems - Beijing China #include <inet/mi.h> 47d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/stream.h> 48d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/errno.h> 49d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/stropts.h> 50d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/stat.h> 51d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/sunddi.h> 52d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/strsubr.h> 53d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/strsun.h> 54d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/pci.h> 55d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/mac_provider.h> 56d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/mac_wifi.h> 57d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/net80211.h> 58d8d81063Sfei feng - Sun Microsystems - Beijing China #include <inet/wifi_ioctl.h> 59d8d81063Sfei feng - Sun Microsystems - Beijing China 60d8d81063Sfei feng - Sun Microsystems - Beijing China #include "mwl_var.h" 61d8d81063Sfei feng - Sun Microsystems - Beijing China 62d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd); 63d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd); 64d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_quiesce(dev_info_t *devinfo); 65d8d81063Sfei feng - Sun Microsystems - Beijing China 66d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DEFINE_STREAM_OPS(mwl_dev_ops, nulldev, nulldev, mwl_attach, mwl_detach, 67d8d81063Sfei feng - Sun Microsystems - Beijing China nodev, NULL, D_MP, NULL, mwl_quiesce); 68d8d81063Sfei feng - Sun Microsystems - Beijing China 69d8d81063Sfei feng - Sun Microsystems - Beijing China static struct modldrv mwl_modldrv = { 70d8d81063Sfei feng - Sun Microsystems - Beijing China &mod_driverops, /* Type of module. This one is a driver */ 71d8d81063Sfei feng - Sun Microsystems - Beijing China "Marvell 88W8363 WiFi driver v1.1", /* short description */ 72d8d81063Sfei feng - Sun Microsystems - Beijing China &mwl_dev_ops /* driver specific ops */ 73d8d81063Sfei feng - Sun Microsystems - Beijing China }; 74d8d81063Sfei feng - Sun Microsystems - Beijing China 75d8d81063Sfei feng - Sun Microsystems - Beijing China static struct modlinkage modlinkage = { 76d8d81063Sfei feng - Sun Microsystems - Beijing China MODREV_1, (void *)&mwl_modldrv, NULL 77d8d81063Sfei feng - Sun Microsystems - Beijing China }; 78d8d81063Sfei feng - Sun Microsystems - Beijing China 79d8d81063Sfei feng - Sun Microsystems - Beijing China static void *mwl_soft_state_p = NULL; 80d8d81063Sfei feng - Sun Microsystems - Beijing China 81d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_m_stat(void *, uint_t, uint64_t *); 82d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_m_start(void *); 83d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_m_stop(void *); 84d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_m_promisc(void *, boolean_t); 85d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_m_multicst(void *, boolean_t, const uint8_t *); 86d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_m_unicst(void *, const uint8_t *); 87d8d81063Sfei feng - Sun Microsystems - Beijing China static mblk_t *mwl_m_tx(void *, mblk_t *); 88d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_m_ioctl(void *, queue_t *, mblk_t *); 89d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_m_setprop(void *arg, const char *pr_name, 90d8d81063Sfei feng - Sun Microsystems - Beijing China mac_prop_id_t wldp_pr_num, 91d8d81063Sfei feng - Sun Microsystems - Beijing China uint_t wldp_length, const void *wldp_buf); 92d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_m_getprop(void *arg, const char *pr_name, 930dc2366fSVenugopal Iyer mac_prop_id_t wldp_pr_num, uint_t wldp_length, 940dc2366fSVenugopal Iyer void *wldp_buf); 950dc2366fSVenugopal Iyer static void mwl_m_propinfo(void *, const char *, mac_prop_id_t, 960dc2366fSVenugopal Iyer mac_prop_info_handle_t); 97d8d81063Sfei feng - Sun Microsystems - Beijing China 98d8d81063Sfei feng - Sun Microsystems - Beijing China static mac_callbacks_t mwl_m_callbacks = { 990dc2366fSVenugopal Iyer MC_IOCTL | MC_SETPROP | MC_GETPROP | MC_PROPINFO, 100d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_stat, 101d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_start, 102d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_stop, 103d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_promisc, 104d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_multicst, 105d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_unicst, 106d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_tx, 1070dc2366fSVenugopal Iyer NULL, 108d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_ioctl, 109d8d81063Sfei feng - Sun Microsystems - Beijing China NULL, 110d8d81063Sfei feng - Sun Microsystems - Beijing China NULL, 111d8d81063Sfei feng - Sun Microsystems - Beijing China NULL, 112d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_setprop, 1130dc2366fSVenugopal Iyer mwl_m_getprop, 1140dc2366fSVenugopal Iyer mwl_m_propinfo 115d8d81063Sfei feng - Sun Microsystems - Beijing China }; 116d8d81063Sfei feng - Sun Microsystems - Beijing China 117d8d81063Sfei feng - Sun Microsystems - Beijing China #define MWL_DBG_ATTACH (1 << 0) 118d8d81063Sfei feng - Sun Microsystems - Beijing China #define MWL_DBG_DMA (1 << 1) 119d8d81063Sfei feng - Sun Microsystems - Beijing China #define MWL_DBG_FW (1 << 2) 120d8d81063Sfei feng - Sun Microsystems - Beijing China #define MWL_DBG_HW (1 << 3) 121d8d81063Sfei feng - Sun Microsystems - Beijing China #define MWL_DBG_INTR (1 << 4) 122d8d81063Sfei feng - Sun Microsystems - Beijing China #define MWL_DBG_RX (1 << 5) 123d8d81063Sfei feng - Sun Microsystems - Beijing China #define MWL_DBG_TX (1 << 6) 124d8d81063Sfei feng - Sun Microsystems - Beijing China #define MWL_DBG_CMD (1 << 7) 125d8d81063Sfei feng - Sun Microsystems - Beijing China #define MWL_DBG_CRYPTO (1 << 8) 126d8d81063Sfei feng - Sun Microsystems - Beijing China #define MWL_DBG_SR (1 << 9) 127d8d81063Sfei feng - Sun Microsystems - Beijing China #define MWL_DBG_MSG (1 << 10) 128d8d81063Sfei feng - Sun Microsystems - Beijing China 129d8d81063Sfei feng - Sun Microsystems - Beijing China uint32_t mwl_dbg_flags = 0x0; 130d8d81063Sfei feng - Sun Microsystems - Beijing China 131d8d81063Sfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 132d8d81063Sfei feng - Sun Microsystems - Beijing China #define MWL_DBG \ 133d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_debug 134d8d81063Sfei feng - Sun Microsystems - Beijing China #else 135*d3351b34SJohn Levon #define MWL_DBG(...) (void)(0) 136d8d81063Sfei feng - Sun Microsystems - Beijing China #endif 137d8d81063Sfei feng - Sun Microsystems - Beijing China 138d8d81063Sfei feng - Sun Microsystems - Beijing China /* 139d8d81063Sfei feng - Sun Microsystems - Beijing China * PIO access attributes for registers 140d8d81063Sfei feng - Sun Microsystems - Beijing China */ 141d8d81063Sfei feng - Sun Microsystems - Beijing China static ddi_device_acc_attr_t mwl_reg_accattr = { 142d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DEVICE_ATTR_V0, 143d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_STRUCTURE_LE_ACC, 144d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_STRICTORDER_ACC, 145d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DEFAULT_ACC 146d8d81063Sfei feng - Sun Microsystems - Beijing China }; 147d8d81063Sfei feng - Sun Microsystems - Beijing China 148d8d81063Sfei feng - Sun Microsystems - Beijing China static ddi_device_acc_attr_t mwl_cmdbuf_accattr = { 149d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DEVICE_ATTR_V0, 150d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_NEVERSWAP_ACC, 151d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_STRICTORDER_ACC, 152d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DEFAULT_ACC 153d8d81063Sfei feng - Sun Microsystems - Beijing China }; 154d8d81063Sfei feng - Sun Microsystems - Beijing China 155d8d81063Sfei feng - Sun Microsystems - Beijing China /* 156d8d81063Sfei feng - Sun Microsystems - Beijing China * DMA access attributes for descriptors and bufs: NOT to be byte swapped. 157d8d81063Sfei feng - Sun Microsystems - Beijing China */ 158d8d81063Sfei feng - Sun Microsystems - Beijing China static ddi_device_acc_attr_t mwl_desc_accattr = { 159d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DEVICE_ATTR_V0, 160d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_NEVERSWAP_ACC, 161d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_STRICTORDER_ACC, 162d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DEFAULT_ACC 163d8d81063Sfei feng - Sun Microsystems - Beijing China }; 164d8d81063Sfei feng - Sun Microsystems - Beijing China 165d8d81063Sfei feng - Sun Microsystems - Beijing China static ddi_device_acc_attr_t mwl_buf_accattr = { 166d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DEVICE_ATTR_V0, 167d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_NEVERSWAP_ACC, 168d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_STRICTORDER_ACC, 169d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DEFAULT_ACC 170d8d81063Sfei feng - Sun Microsystems - Beijing China }; 171d8d81063Sfei feng - Sun Microsystems - Beijing China 172d8d81063Sfei feng - Sun Microsystems - Beijing China /* 173d8d81063Sfei feng - Sun Microsystems - Beijing China * Describes the chip's DMA engine 174d8d81063Sfei feng - Sun Microsystems - Beijing China */ 175d8d81063Sfei feng - Sun Microsystems - Beijing China static ddi_dma_attr_t mwl_dma_attr = { 176d8d81063Sfei feng - Sun Microsystems - Beijing China DMA_ATTR_V0, /* dma_attr version */ 177d8d81063Sfei feng - Sun Microsystems - Beijing China 0x0000000000000000ull, /* dma_attr_addr_lo */ 178d8d81063Sfei feng - Sun Microsystems - Beijing China 0xFFFFFFFF, /* dma_attr_addr_hi */ 179d8d81063Sfei feng - Sun Microsystems - Beijing China 0x00000000FFFFFFFFull, /* dma_attr_count_max */ 180d8d81063Sfei feng - Sun Microsystems - Beijing China 0x0000000000000001ull, /* dma_attr_align */ 181d8d81063Sfei feng - Sun Microsystems - Beijing China 0x00000FFF, /* dma_attr_burstsizes */ 182d8d81063Sfei feng - Sun Microsystems - Beijing China 0x00000001, /* dma_attr_minxfer */ 183d8d81063Sfei feng - Sun Microsystems - Beijing China 0x000000000000FFFFull, /* dma_attr_maxxfer */ 184d8d81063Sfei feng - Sun Microsystems - Beijing China 0xFFFFFFFFFFFFFFFFull, /* dma_attr_seg */ 185d8d81063Sfei feng - Sun Microsystems - Beijing China 1, /* dma_attr_sgllen */ 186d8d81063Sfei feng - Sun Microsystems - Beijing China 0x00000001, /* dma_attr_granular */ 187d8d81063Sfei feng - Sun Microsystems - Beijing China 0 /* dma_attr_flags */ 188d8d81063Sfei feng - Sun Microsystems - Beijing China }; 189d8d81063Sfei feng - Sun Microsystems - Beijing China 190d8d81063Sfei feng - Sun Microsystems - Beijing China /* 191d8d81063Sfei feng - Sun Microsystems - Beijing China * Supported rates for 802.11a/b/g modes (in 500Kbps unit). 192d8d81063Sfei feng - Sun Microsystems - Beijing China */ 193d8d81063Sfei feng - Sun Microsystems - Beijing China static const struct ieee80211_rateset mwl_rateset_11b = 194d8d81063Sfei feng - Sun Microsystems - Beijing China { 4, { 2, 4, 11, 22 } }; 195d8d81063Sfei feng - Sun Microsystems - Beijing China 196d8d81063Sfei feng - Sun Microsystems - Beijing China static const struct ieee80211_rateset mwl_rateset_11g = 197d8d81063Sfei feng - Sun Microsystems - Beijing China { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } }; 198d8d81063Sfei feng - Sun Microsystems - Beijing China 199d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_alloc_dma_mem(dev_info_t *, ddi_dma_attr_t *, size_t, 200d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_device_acc_attr_t *, uint_t, uint_t, 201d8d81063Sfei feng - Sun Microsystems - Beijing China struct dma_area *); 202d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_free_dma_mem(struct dma_area *); 203d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_alloc_cmdbuf(struct mwl_softc *); 204d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_free_cmdbuf(struct mwl_softc *); 205d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_alloc_rx_ring(struct mwl_softc *, int); 206d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_free_rx_ring(struct mwl_softc *); 207d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_alloc_tx_ring(struct mwl_softc *, struct mwl_tx_ring *, 208d8d81063Sfei feng - Sun Microsystems - Beijing China int); 209d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_free_tx_ring(struct mwl_softc *, struct mwl_tx_ring *); 210d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_setupdma(struct mwl_softc *); 211d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_txq_init(struct mwl_softc *, struct mwl_tx_ring *, int); 212d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_tx_setup(struct mwl_softc *, int, int); 213d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_setup_txq(struct mwl_softc *); 214d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_fwload(struct mwl_softc *, void *); 215d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_loadsym(ddi_modhandle_t, char *, char **, size_t *); 216d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwlFwReset(struct mwl_softc *); 217d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwlPokeSdramController(struct mwl_softc *, int); 218d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwlTriggerPciCmd(struct mwl_softc *); 219d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwlWaitFor(struct mwl_softc *, uint32_t); 220d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwlSendBlock(struct mwl_softc *, int, const void *, size_t); 221d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwlSendBlock2(struct mwl_softc *, const void *, size_t); 222d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwlSendCmd(struct mwl_softc *); 223d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwlExecuteCmd(struct mwl_softc *, unsigned short); 224d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwlWaitForCmdComplete(struct mwl_softc *, uint16_t); 225d8d81063Sfei feng - Sun Microsystems - Beijing China static void dumpresult(struct mwl_softc *, int); 226d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwlResetHalState(struct mwl_softc *); 227d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwlGetPwrCalTable(struct mwl_softc *); 228d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwlGetCalTable(struct mwl_softc *, uint8_t, uint8_t); 229d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwlGetPwrCalTable(struct mwl_softc *); 230d8d81063Sfei feng - Sun Microsystems - Beijing China static void dumpcaldata(const char *, const uint8_t *, int); 231d8d81063Sfei feng - Sun Microsystems - Beijing China static void get2Ghz(MWL_HAL_CHANNELINFO *, const uint8_t *, int); 232d8d81063Sfei feng - Sun Microsystems - Beijing China static void get5Ghz(MWL_HAL_CHANNELINFO *, const uint8_t *, int); 233d8d81063Sfei feng - Sun Microsystems - Beijing China static void setmaxtxpow(struct mwl_hal_channel *, int, int); 234d8d81063Sfei feng - Sun Microsystems - Beijing China static uint16_t ieee2mhz(int); 235d8d81063Sfei feng - Sun Microsystems - Beijing China static const char * 236d8d81063Sfei feng - Sun Microsystems - Beijing China mwlcmdname(int); 237d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_gethwspecs(struct mwl_softc *); 238d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_getchannels(struct mwl_softc *); 239d8d81063Sfei feng - Sun Microsystems - Beijing China static void getchannels(struct mwl_softc *, int, int *, 240d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_channel *); 241d8d81063Sfei feng - Sun Microsystems - Beijing China static void addchannels(struct mwl_channel *, int, int *, 242d8d81063Sfei feng - Sun Microsystems - Beijing China const MWL_HAL_CHANNELINFO *, int); 243d8d81063Sfei feng - Sun Microsystems - Beijing China static void addht40channels(struct mwl_channel *, int, int *, 244d8d81063Sfei feng - Sun Microsystems - Beijing China const MWL_HAL_CHANNELINFO *, int); 245d8d81063Sfei feng - Sun Microsystems - Beijing China static const struct mwl_channel * 246d8d81063Sfei feng - Sun Microsystems - Beijing China findchannel(const struct mwl_channel *, int, 247d8d81063Sfei feng - Sun Microsystems - Beijing China int, int); 248d8d81063Sfei feng - Sun Microsystems - Beijing China static void addchan(struct mwl_channel *, int, int, int, int); 249d8d81063Sfei feng - Sun Microsystems - Beijing China 250d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_chan_set(struct mwl_softc *, struct mwl_channel *); 251d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_mapchan(MWL_HAL_CHANNEL *, const struct mwl_channel *); 252d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_setcurchanrates(struct mwl_softc *); 253d8d81063Sfei feng - Sun Microsystems - Beijing China const struct ieee80211_rateset * 254d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_get_suprates(struct ieee80211com *, 255d8d81063Sfei feng - Sun Microsystems - Beijing China const struct mwl_channel *); 256d8d81063Sfei feng - Sun Microsystems - Beijing China static uint32_t cvtChannelFlags(const MWL_HAL_CHANNEL *); 257d8d81063Sfei feng - Sun Microsystems - Beijing China static const struct mwl_hal_channel * 258d8d81063Sfei feng - Sun Microsystems - Beijing China findhalchannel(const struct mwl_softc *, 259d8d81063Sfei feng - Sun Microsystems - Beijing China const MWL_HAL_CHANNEL *); 260d8d81063Sfei feng - Sun Microsystems - Beijing China enum ieee80211_phymode 261d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_chan2mode(const struct mwl_channel *); 262d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_map2regioncode(const struct mwl_regdomain *); 263d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_startrecv(struct mwl_softc *); 264d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_mode_init(struct mwl_softc *); 265d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_hal_intrset(struct mwl_softc *, uint32_t); 266d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_hal_getisr(struct mwl_softc *, uint32_t *); 267d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_sethwdma(struct mwl_softc *, 268d8d81063Sfei feng - Sun Microsystems - Beijing China const struct mwl_hal_txrxdma *); 269d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_getchannelinfo(struct mwl_softc *, int, int, 270d8d81063Sfei feng - Sun Microsystems - Beijing China const MWL_HAL_CHANNELINFO **); 271d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_setmac_locked(struct mwl_softc *, const uint8_t *); 272d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_keyreset(struct mwl_softc *, const MWL_HAL_KEYVAL *, 273d8d81063Sfei feng - Sun Microsystems - Beijing China const uint8_t mac[IEEE80211_ADDR_LEN]); 274d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_keyset(struct mwl_softc *, const MWL_HAL_KEYVAL *, 275d8d81063Sfei feng - Sun Microsystems - Beijing China const uint8_t mac[IEEE80211_ADDR_LEN]); 276d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_newstation(struct mwl_softc *, const uint8_t *, 277d8d81063Sfei feng - Sun Microsystems - Beijing China uint16_t, uint16_t, const MWL_HAL_PEERINFO *, int, int); 278d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_setantenna(struct mwl_softc *, MWL_HAL_ANTENNA, int); 279d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_setradio(struct mwl_softc *, int, MWL_HAL_PREAMBLE); 280d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_setwmm(struct mwl_softc *, int); 281d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_setchannel(struct mwl_softc *, const MWL_HAL_CHANNEL *); 282d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_settxpower(struct mwl_softc *, const MWL_HAL_CHANNEL *, 283d8d81063Sfei feng - Sun Microsystems - Beijing China uint8_t); 284d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_settxrate(struct mwl_softc *, MWL_HAL_TXRATE_HANDLING, 285d8d81063Sfei feng - Sun Microsystems - Beijing China const MWL_HAL_TXRATE *); 286d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_settxrate_auto(struct mwl_softc *, 287d8d81063Sfei feng - Sun Microsystems - Beijing China const MWL_HAL_TXRATE *); 288d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_setrateadaptmode(struct mwl_softc *, uint16_t); 289d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_setoptimizationlevel(struct mwl_softc *, int); 290d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_setregioncode(struct mwl_softc *, int); 291d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_setassocid(struct mwl_softc *, const uint8_t *, 292d8d81063Sfei feng - Sun Microsystems - Beijing China uint16_t); 293d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_setrates(struct ieee80211com *); 294d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_setrtsthreshold(struct mwl_softc *, int); 295d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_setcsmode(struct mwl_softc *, MWL_HAL_CSMODE); 296d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_setpromisc(struct mwl_softc *, int); 297d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_start(struct mwl_softc *); 298d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_setinframode(struct mwl_softc *); 299d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_hal_stop(struct mwl_softc *); 300d8d81063Sfei feng - Sun Microsystems - Beijing China static struct ieee80211_node * 301d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_node_alloc(struct ieee80211com *); 302d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_node_free(struct ieee80211_node *); 303d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_key_alloc(struct ieee80211com *, 304d8d81063Sfei feng - Sun Microsystems - Beijing China const struct ieee80211_key *, 305d8d81063Sfei feng - Sun Microsystems - Beijing China ieee80211_keyix *, ieee80211_keyix *); 306d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_key_delete(struct ieee80211com *, 307d8d81063Sfei feng - Sun Microsystems - Beijing China const struct ieee80211_key *); 308d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_key_set(struct ieee80211com *, const struct ieee80211_key *, 309d8d81063Sfei feng - Sun Microsystems - Beijing China const uint8_t mac[IEEE80211_ADDR_LEN]); 310d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_setanywepkey(struct ieee80211com *, const uint8_t *); 311d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_setglobalkeys(struct ieee80211com *c); 312d8d81063Sfei feng - Sun Microsystems - Beijing China static int addgroupflags(MWL_HAL_KEYVAL *, const struct ieee80211_key *); 313d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_hal_txstart(struct mwl_softc *, int); 314d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_send(ieee80211com_t *, mblk_t *, uint8_t); 315d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_next_scan(void *); 316d8d81063Sfei feng - Sun Microsystems - Beijing China static MWL_HAL_PEERINFO * 317d8d81063Sfei feng - Sun Microsystems - Beijing China mkpeerinfo(MWL_HAL_PEERINFO *, const struct ieee80211_node *); 318d8d81063Sfei feng - Sun Microsystems - Beijing China static uint32_t get_rate_bitmap(const struct ieee80211_rateset *); 319d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_newstate(struct ieee80211com *, enum ieee80211_state, int); 320d8d81063Sfei feng - Sun Microsystems - Beijing China static int cvtrssi(uint8_t); 321d8d81063Sfei feng - Sun Microsystems - Beijing China static uint_t mwl_intr(caddr_t, caddr_t); 322d8d81063Sfei feng - Sun Microsystems - Beijing China static uint_t mwl_softintr(caddr_t, caddr_t); 323d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_tx_intr(struct mwl_softc *); 324d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_rx_intr(struct mwl_softc *); 325d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_init(struct mwl_softc *); 326d8d81063Sfei feng - Sun Microsystems - Beijing China static void mwl_stop(struct mwl_softc *); 327d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_resume(struct mwl_softc *); 328d8d81063Sfei feng - Sun Microsystems - Beijing China 329d8d81063Sfei feng - Sun Microsystems - Beijing China 330d8d81063Sfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 331d8d81063Sfei feng - Sun Microsystems - Beijing China static void 332d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_debug(uint32_t dbg_flags, const int8_t *fmt, ...) 333d8d81063Sfei feng - Sun Microsystems - Beijing China { 334d8d81063Sfei feng - Sun Microsystems - Beijing China va_list args; 335d8d81063Sfei feng - Sun Microsystems - Beijing China 336d8d81063Sfei feng - Sun Microsystems - Beijing China if (dbg_flags & mwl_dbg_flags) { 337d8d81063Sfei feng - Sun Microsystems - Beijing China va_start(args, fmt); 338d8d81063Sfei feng - Sun Microsystems - Beijing China vcmn_err(CE_CONT, fmt, args); 339d8d81063Sfei feng - Sun Microsystems - Beijing China va_end(args); 340d8d81063Sfei feng - Sun Microsystems - Beijing China } 341d8d81063Sfei feng - Sun Microsystems - Beijing China } 342d8d81063Sfei feng - Sun Microsystems - Beijing China #endif 343d8d81063Sfei feng - Sun Microsystems - Beijing China 344d8d81063Sfei feng - Sun Microsystems - Beijing China /* 345d8d81063Sfei feng - Sun Microsystems - Beijing China * Allocate an DMA memory and a DMA handle for accessing it 346d8d81063Sfei feng - Sun Microsystems - Beijing China */ 347d8d81063Sfei feng - Sun Microsystems - Beijing China static int 348d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_alloc_dma_mem(dev_info_t *devinfo, ddi_dma_attr_t *dma_attr, 349d8d81063Sfei feng - Sun Microsystems - Beijing China size_t memsize, ddi_device_acc_attr_t *attr_p, uint_t alloc_flags, 350d8d81063Sfei feng - Sun Microsystems - Beijing China uint_t bind_flags, struct dma_area *dma_p) 351d8d81063Sfei feng - Sun Microsystems - Beijing China { 352d8d81063Sfei feng - Sun Microsystems - Beijing China int err; 353d8d81063Sfei feng - Sun Microsystems - Beijing China 354d8d81063Sfei feng - Sun Microsystems - Beijing China /* 355d8d81063Sfei feng - Sun Microsystems - Beijing China * Allocate handle 356d8d81063Sfei feng - Sun Microsystems - Beijing China */ 357d8d81063Sfei feng - Sun Microsystems - Beijing China err = ddi_dma_alloc_handle(devinfo, dma_attr, 358d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl); 359d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 360d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_dma_mem(): " 361d8d81063Sfei feng - Sun Microsystems - Beijing China "failed to alloc handle\n"); 362d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail1; 363d8d81063Sfei feng - Sun Microsystems - Beijing China } 364d8d81063Sfei feng - Sun Microsystems - Beijing China 365d8d81063Sfei feng - Sun Microsystems - Beijing China /* 366d8d81063Sfei feng - Sun Microsystems - Beijing China * Allocate memory 367d8d81063Sfei feng - Sun Microsystems - Beijing China */ 368d8d81063Sfei feng - Sun Microsystems - Beijing China err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, attr_p, 369d8d81063Sfei feng - Sun Microsystems - Beijing China alloc_flags, DDI_DMA_SLEEP, NULL, &dma_p->mem_va, 370d8d81063Sfei feng - Sun Microsystems - Beijing China &dma_p->alength, &dma_p->acc_hdl); 371d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 372d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_dma_mem(): " 373d8d81063Sfei feng - Sun Microsystems - Beijing China "failed to alloc mem\n"); 374d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail2; 375d8d81063Sfei feng - Sun Microsystems - Beijing China } 376d8d81063Sfei feng - Sun Microsystems - Beijing China 377d8d81063Sfei feng - Sun Microsystems - Beijing China /* 378d8d81063Sfei feng - Sun Microsystems - Beijing China * Bind the two together 379d8d81063Sfei feng - Sun Microsystems - Beijing China */ 380d8d81063Sfei feng - Sun Microsystems - Beijing China err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL, 381d8d81063Sfei feng - Sun Microsystems - Beijing China dma_p->mem_va, dma_p->alength, bind_flags, 382d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SLEEP, NULL, &dma_p->cookie, &dma_p->ncookies); 383d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != DDI_DMA_MAPPED) { 384d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_dma_mem(): " 385d8d81063Sfei feng - Sun Microsystems - Beijing China "failed to bind handle\n"); 386d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail3; 387d8d81063Sfei feng - Sun Microsystems - Beijing China } 388d8d81063Sfei feng - Sun Microsystems - Beijing China 389d8d81063Sfei feng - Sun Microsystems - Beijing China if (dma_p->ncookies != 1) { 390d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_dma_mem(): " 391d8d81063Sfei feng - Sun Microsystems - Beijing China "failed to alloc cookies\n"); 392d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail4; 393d8d81063Sfei feng - Sun Microsystems - Beijing China } 394d8d81063Sfei feng - Sun Microsystems - Beijing China 395d8d81063Sfei feng - Sun Microsystems - Beijing China dma_p->nslots = ~0U; 396d8d81063Sfei feng - Sun Microsystems - Beijing China dma_p->size = ~0U; 397d8d81063Sfei feng - Sun Microsystems - Beijing China dma_p->token = ~0U; 398d8d81063Sfei feng - Sun Microsystems - Beijing China dma_p->offset = 0; 399d8d81063Sfei feng - Sun Microsystems - Beijing China 400d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS); 401d8d81063Sfei feng - Sun Microsystems - Beijing China 402d8d81063Sfei feng - Sun Microsystems - Beijing China fail4: 403d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_unbind_handle(dma_p->dma_hdl); 404d8d81063Sfei feng - Sun Microsystems - Beijing China fail3: 405d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_dma_mem_free(&dma_p->acc_hdl); 406d8d81063Sfei feng - Sun Microsystems - Beijing China fail2: 407d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_dma_free_handle(&dma_p->dma_hdl); 408d8d81063Sfei feng - Sun Microsystems - Beijing China fail1: 409d8d81063Sfei feng - Sun Microsystems - Beijing China return (err); 410d8d81063Sfei feng - Sun Microsystems - Beijing China } 411d8d81063Sfei feng - Sun Microsystems - Beijing China 412d8d81063Sfei feng - Sun Microsystems - Beijing China static void 413d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_dma_mem(struct dma_area *dma_p) 414d8d81063Sfei feng - Sun Microsystems - Beijing China { 415d8d81063Sfei feng - Sun Microsystems - Beijing China if (dma_p->dma_hdl != NULL) { 416d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_unbind_handle(dma_p->dma_hdl); 417d8d81063Sfei feng - Sun Microsystems - Beijing China if (dma_p->acc_hdl != NULL) { 418d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_dma_mem_free(&dma_p->acc_hdl); 419d8d81063Sfei feng - Sun Microsystems - Beijing China dma_p->acc_hdl = NULL; 420d8d81063Sfei feng - Sun Microsystems - Beijing China } 421d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_dma_free_handle(&dma_p->dma_hdl); 422d8d81063Sfei feng - Sun Microsystems - Beijing China dma_p->ncookies = 0; 423d8d81063Sfei feng - Sun Microsystems - Beijing China dma_p->dma_hdl = NULL; 424d8d81063Sfei feng - Sun Microsystems - Beijing China } 425d8d81063Sfei feng - Sun Microsystems - Beijing China } 426d8d81063Sfei feng - Sun Microsystems - Beijing China 427d8d81063Sfei feng - Sun Microsystems - Beijing China static int 428d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_alloc_cmdbuf(struct mwl_softc *sc) 429d8d81063Sfei feng - Sun Microsystems - Beijing China { 430d8d81063Sfei feng - Sun Microsystems - Beijing China int err; 431d8d81063Sfei feng - Sun Microsystems - Beijing China size_t size; 432d8d81063Sfei feng - Sun Microsystems - Beijing China 433d8d81063Sfei feng - Sun Microsystems - Beijing China size = MWL_CMDBUF_SIZE; 434d8d81063Sfei feng - Sun Microsystems - Beijing China 435d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_alloc_dma_mem(sc->sc_dev, &mwl_dma_attr, size, 436d8d81063Sfei feng - Sun Microsystems - Beijing China &mwl_cmdbuf_accattr, DDI_DMA_CONSISTENT, 437d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 438d8d81063Sfei feng - Sun Microsystems - Beijing China &sc->sc_cmd_dma); 439d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 440d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_cmdbuf(): " 441d8d81063Sfei feng - Sun Microsystems - Beijing China "failed to alloc dma mem\n"); 442d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 443d8d81063Sfei feng - Sun Microsystems - Beijing China } 444d8d81063Sfei feng - Sun Microsystems - Beijing China 445d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_cmd_mem = (uint16_t *)sc->sc_cmd_dma.mem_va; 446d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_cmd_dmaaddr = sc->sc_cmd_dma.cookie.dmac_address; 447d8d81063Sfei feng - Sun Microsystems - Beijing China 448d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS); 449d8d81063Sfei feng - Sun Microsystems - Beijing China } 450d8d81063Sfei feng - Sun Microsystems - Beijing China 451d8d81063Sfei feng - Sun Microsystems - Beijing China static void 452d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_cmdbuf(struct mwl_softc *sc) 453d8d81063Sfei feng - Sun Microsystems - Beijing China { 454d8d81063Sfei feng - Sun Microsystems - Beijing China if (sc->sc_cmd_mem != NULL) 455d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_dma_mem(&sc->sc_cmd_dma); 456d8d81063Sfei feng - Sun Microsystems - Beijing China } 457d8d81063Sfei feng - Sun Microsystems - Beijing China 458d8d81063Sfei feng - Sun Microsystems - Beijing China static int 459d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_alloc_rx_ring(struct mwl_softc *sc, int count) 460d8d81063Sfei feng - Sun Microsystems - Beijing China { 461d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_rx_ring *ring; 462d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_rxdesc *ds; 463d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_rxbuf *bf; 464d8d81063Sfei feng - Sun Microsystems - Beijing China int i, err, datadlen; 465d8d81063Sfei feng - Sun Microsystems - Beijing China 466d8d81063Sfei feng - Sun Microsystems - Beijing China ring = &sc->sc_rxring; 467d8d81063Sfei feng - Sun Microsystems - Beijing China ring->count = count; 468d8d81063Sfei feng - Sun Microsystems - Beijing China ring->cur = ring->next = 0; 469d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_alloc_dma_mem(sc->sc_dev, &mwl_dma_attr, 470d8d81063Sfei feng - Sun Microsystems - Beijing China count * sizeof (struct mwl_rxdesc), 471d8d81063Sfei feng - Sun Microsystems - Beijing China &mwl_desc_accattr, 472d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_CONSISTENT, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 473d8d81063Sfei feng - Sun Microsystems - Beijing China &ring->rxdesc_dma); 474d8d81063Sfei feng - Sun Microsystems - Beijing China if (err) { 475d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_rxring(): " 476d8d81063Sfei feng - Sun Microsystems - Beijing China "alloc tx ring failed, size %d\n", 477d8d81063Sfei feng - Sun Microsystems - Beijing China (uint32_t)(count * sizeof (struct mwl_rxdesc))); 478d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 479d8d81063Sfei feng - Sun Microsystems - Beijing China } 480d8d81063Sfei feng - Sun Microsystems - Beijing China 481d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_rx_ring(): " 482d8d81063Sfei feng - Sun Microsystems - Beijing China "dma len = %d\n", (uint32_t)(ring->rxdesc_dma.alength)); 483d8d81063Sfei feng - Sun Microsystems - Beijing China ring->desc = (struct mwl_rxdesc *)ring->rxdesc_dma.mem_va; 484d8d81063Sfei feng - Sun Microsystems - Beijing China ring->physaddr = ring->rxdesc_dma.cookie.dmac_address; 485d8d81063Sfei feng - Sun Microsystems - Beijing China bzero(ring->desc, count * sizeof (struct mwl_rxdesc)); 486d8d81063Sfei feng - Sun Microsystems - Beijing China 487d8d81063Sfei feng - Sun Microsystems - Beijing China datadlen = count * sizeof (struct mwl_rxbuf); 488d8d81063Sfei feng - Sun Microsystems - Beijing China ring->buf = (struct mwl_rxbuf *)kmem_zalloc(datadlen, KM_SLEEP); 489d8d81063Sfei feng - Sun Microsystems - Beijing China if (ring->buf == NULL) { 490d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_rxring(): " 491d8d81063Sfei feng - Sun Microsystems - Beijing China "could not alloc rx ring data buffer\n"); 492d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 493d8d81063Sfei feng - Sun Microsystems - Beijing China } 494d8d81063Sfei feng - Sun Microsystems - Beijing China bzero(ring->buf, count * sizeof (struct mwl_rxbuf)); 495d8d81063Sfei feng - Sun Microsystems - Beijing China 496d8d81063Sfei feng - Sun Microsystems - Beijing China /* 497d8d81063Sfei feng - Sun Microsystems - Beijing China * Pre-allocate Rx buffers and populate Rx ring. 498d8d81063Sfei feng - Sun Microsystems - Beijing China */ 499d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < count; i++) { 500d8d81063Sfei feng - Sun Microsystems - Beijing China ds = &ring->desc[i]; 501d8d81063Sfei feng - Sun Microsystems - Beijing China bf = &ring->buf[i]; 502d8d81063Sfei feng - Sun Microsystems - Beijing China /* alloc DMA memory */ 503d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_alloc_dma_mem(sc->sc_dev, &mwl_dma_attr, 504d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_dmabuf_size, 505d8d81063Sfei feng - Sun Microsystems - Beijing China &mwl_buf_accattr, 506d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_STREAMING, 507d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_READ | DDI_DMA_STREAMING, 508d8d81063Sfei feng - Sun Microsystems - Beijing China &bf->rxbuf_dma); 509d8d81063Sfei feng - Sun Microsystems - Beijing China bf->bf_mem = (uint8_t *)(bf->rxbuf_dma.mem_va); 510d8d81063Sfei feng - Sun Microsystems - Beijing China bf->bf_baddr = bf->rxbuf_dma.cookie.dmac_address; 511d8d81063Sfei feng - Sun Microsystems - Beijing China bf->bf_desc = ds; 512d8d81063Sfei feng - Sun Microsystems - Beijing China bf->bf_daddr = ring->physaddr + _PTRDIFF(ds, ring->desc); 513d8d81063Sfei feng - Sun Microsystems - Beijing China } 514d8d81063Sfei feng - Sun Microsystems - Beijing China 515d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl, 516d8d81063Sfei feng - Sun Microsystems - Beijing China 0, 517d8d81063Sfei feng - Sun Microsystems - Beijing China ring->rxdesc_dma.alength, 518d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV); 519d8d81063Sfei feng - Sun Microsystems - Beijing China 520d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 521d8d81063Sfei feng - Sun Microsystems - Beijing China } 522d8d81063Sfei feng - Sun Microsystems - Beijing China 523d8d81063Sfei feng - Sun Microsystems - Beijing China static void 524d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_rx_ring(struct mwl_softc *sc) 525d8d81063Sfei feng - Sun Microsystems - Beijing China { 526d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_rx_ring *ring; 527d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_rxbuf *bf; 528d8d81063Sfei feng - Sun Microsystems - Beijing China int i; 529d8d81063Sfei feng - Sun Microsystems - Beijing China 530d8d81063Sfei feng - Sun Microsystems - Beijing China ring = &sc->sc_rxring; 531d8d81063Sfei feng - Sun Microsystems - Beijing China 532d8d81063Sfei feng - Sun Microsystems - Beijing China if (ring->desc != NULL) { 533d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_dma_mem(&ring->rxdesc_dma); 534d8d81063Sfei feng - Sun Microsystems - Beijing China } 535d8d81063Sfei feng - Sun Microsystems - Beijing China 536d8d81063Sfei feng - Sun Microsystems - Beijing China if (ring->buf != NULL) { 537d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < ring->count; i++) { 538d8d81063Sfei feng - Sun Microsystems - Beijing China bf = &ring->buf[i]; 539d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_dma_mem(&bf->rxbuf_dma); 540d8d81063Sfei feng - Sun Microsystems - Beijing China } 541d8d81063Sfei feng - Sun Microsystems - Beijing China kmem_free(ring->buf, 542d8d81063Sfei feng - Sun Microsystems - Beijing China (ring->count * sizeof (struct mwl_rxbuf))); 543d8d81063Sfei feng - Sun Microsystems - Beijing China } 544d8d81063Sfei feng - Sun Microsystems - Beijing China } 545d8d81063Sfei feng - Sun Microsystems - Beijing China 546d8d81063Sfei feng - Sun Microsystems - Beijing China static int 547d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_alloc_tx_ring(struct mwl_softc *sc, struct mwl_tx_ring *ring, 548d8d81063Sfei feng - Sun Microsystems - Beijing China int count) 549d8d81063Sfei feng - Sun Microsystems - Beijing China { 550d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_txdesc *ds; 551d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_txbuf *bf; 552d8d81063Sfei feng - Sun Microsystems - Beijing China int i, err, datadlen; 553d8d81063Sfei feng - Sun Microsystems - Beijing China 554d8d81063Sfei feng - Sun Microsystems - Beijing China ring->count = count; 555d8d81063Sfei feng - Sun Microsystems - Beijing China ring->queued = 0; 556d8d81063Sfei feng - Sun Microsystems - Beijing China ring->cur = ring->next = ring->stat = 0; 557d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_alloc_dma_mem(sc->sc_dev, &mwl_dma_attr, 558d8d81063Sfei feng - Sun Microsystems - Beijing China count * sizeof (struct mwl_txdesc), &mwl_desc_accattr, 559d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_CONSISTENT, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 560d8d81063Sfei feng - Sun Microsystems - Beijing China &ring->txdesc_dma); 561d8d81063Sfei feng - Sun Microsystems - Beijing China if (err) { 562d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_tx_ring(): " 563d8d81063Sfei feng - Sun Microsystems - Beijing China "alloc tx ring failed, size %d\n", 564d8d81063Sfei feng - Sun Microsystems - Beijing China (uint32_t)(count * sizeof (struct mwl_txdesc))); 565d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 566d8d81063Sfei feng - Sun Microsystems - Beijing China } 567d8d81063Sfei feng - Sun Microsystems - Beijing China 568d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_tx_ring(): " 569d8d81063Sfei feng - Sun Microsystems - Beijing China "dma len = %d\n", (uint32_t)(ring->txdesc_dma.alength)); 570d8d81063Sfei feng - Sun Microsystems - Beijing China ring->desc = (struct mwl_txdesc *)ring->txdesc_dma.mem_va; 571d8d81063Sfei feng - Sun Microsystems - Beijing China ring->physaddr = ring->txdesc_dma.cookie.dmac_address; 572d8d81063Sfei feng - Sun Microsystems - Beijing China bzero(ring->desc, count * sizeof (struct mwl_txdesc)); 573d8d81063Sfei feng - Sun Microsystems - Beijing China 574d8d81063Sfei feng - Sun Microsystems - Beijing China datadlen = count * sizeof (struct mwl_txbuf); 575d8d81063Sfei feng - Sun Microsystems - Beijing China ring->buf = kmem_zalloc(datadlen, KM_SLEEP); 576d8d81063Sfei feng - Sun Microsystems - Beijing China if (ring->buf == NULL) { 577d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_tx_ring(): " 578d8d81063Sfei feng - Sun Microsystems - Beijing China "could not alloc tx ring data buffer\n"); 579d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 580d8d81063Sfei feng - Sun Microsystems - Beijing China } 581d8d81063Sfei feng - Sun Microsystems - Beijing China bzero(ring->buf, count * sizeof (struct mwl_txbuf)); 582d8d81063Sfei feng - Sun Microsystems - Beijing China 583d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < count; i++) { 584d8d81063Sfei feng - Sun Microsystems - Beijing China ds = &ring->desc[i]; 585d8d81063Sfei feng - Sun Microsystems - Beijing China bf = &ring->buf[i]; 586d8d81063Sfei feng - Sun Microsystems - Beijing China /* alloc DMA memory */ 587d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_alloc_dma_mem(sc->sc_dev, &mwl_dma_attr, 588d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_dmabuf_size, 589d8d81063Sfei feng - Sun Microsystems - Beijing China &mwl_buf_accattr, 590d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_STREAMING, 591d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_WRITE | DDI_DMA_STREAMING, 592d8d81063Sfei feng - Sun Microsystems - Beijing China &bf->txbuf_dma); 593d8d81063Sfei feng - Sun Microsystems - Beijing China bf->bf_baddr = bf->txbuf_dma.cookie.dmac_address; 594d8d81063Sfei feng - Sun Microsystems - Beijing China bf->bf_mem = (uint8_t *)(bf->txbuf_dma.mem_va); 595d8d81063Sfei feng - Sun Microsystems - Beijing China bf->bf_daddr = ring->physaddr + _PTRDIFF(ds, ring->desc); 596d8d81063Sfei feng - Sun Microsystems - Beijing China bf->bf_desc = ds; 597d8d81063Sfei feng - Sun Microsystems - Beijing China } 598d8d81063Sfei feng - Sun Microsystems - Beijing China 599d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl, 600d8d81063Sfei feng - Sun Microsystems - Beijing China 0, 601d8d81063Sfei feng - Sun Microsystems - Beijing China ring->txdesc_dma.alength, 602d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV); 603d8d81063Sfei feng - Sun Microsystems - Beijing China 604d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 605d8d81063Sfei feng - Sun Microsystems - Beijing China } 606d8d81063Sfei feng - Sun Microsystems - Beijing China 607d8d81063Sfei feng - Sun Microsystems - Beijing China /* ARGSUSED */ 608d8d81063Sfei feng - Sun Microsystems - Beijing China static void 609d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_tx_ring(struct mwl_softc *sc, struct mwl_tx_ring *ring) 610d8d81063Sfei feng - Sun Microsystems - Beijing China { 611d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_txbuf *bf; 612d8d81063Sfei feng - Sun Microsystems - Beijing China int i; 613d8d81063Sfei feng - Sun Microsystems - Beijing China 614d8d81063Sfei feng - Sun Microsystems - Beijing China if (ring->desc != NULL) { 615d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_dma_mem(&ring->txdesc_dma); 616d8d81063Sfei feng - Sun Microsystems - Beijing China } 617d8d81063Sfei feng - Sun Microsystems - Beijing China 618d8d81063Sfei feng - Sun Microsystems - Beijing China if (ring->buf != NULL) { 619d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < ring->count; i++) { 620d8d81063Sfei feng - Sun Microsystems - Beijing China bf = &ring->buf[i]; 621d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_dma_mem(&bf->txbuf_dma); 622d8d81063Sfei feng - Sun Microsystems - Beijing China } 623d8d81063Sfei feng - Sun Microsystems - Beijing China kmem_free(ring->buf, 624d8d81063Sfei feng - Sun Microsystems - Beijing China (ring->count * sizeof (struct mwl_txbuf))); 625d8d81063Sfei feng - Sun Microsystems - Beijing China } 626d8d81063Sfei feng - Sun Microsystems - Beijing China } 627d8d81063Sfei feng - Sun Microsystems - Beijing China 628d8d81063Sfei feng - Sun Microsystems - Beijing China /* 629d8d81063Sfei feng - Sun Microsystems - Beijing China * Inform the f/w about location of the tx/rx dma data structures 630d8d81063Sfei feng - Sun Microsystems - Beijing China * and related state. This cmd must be done immediately after a 631d8d81063Sfei feng - Sun Microsystems - Beijing China * mwl_hal_gethwspecs call or the f/w will lockup. 632d8d81063Sfei feng - Sun Microsystems - Beijing China */ 633d8d81063Sfei feng - Sun Microsystems - Beijing China static int 634d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_sethwdma(struct mwl_softc *sc, const struct mwl_hal_txrxdma *dma) 635d8d81063Sfei feng - Sun Microsystems - Beijing China { 636d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_DS_SET_HW_SPEC *pCmd; 637d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 638d8d81063Sfei feng - Sun Microsystems - Beijing China 639d8d81063Sfei feng - Sun Microsystems - Beijing China _CMD_SETUP(pCmd, HostCmd_DS_SET_HW_SPEC, HostCmd_CMD_SET_HW_SPEC); 640d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->WcbBase[0] = LE_32(dma->wcbBase[0]); 641d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->WcbBase[1] = LE_32(dma->wcbBase[1]); 642d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->WcbBase[2] = LE_32(dma->wcbBase[2]); 643d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->WcbBase[3] = LE_32(dma->wcbBase[3]); 644d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->TxWcbNumPerQueue = LE_32(dma->maxNumTxWcb); 645d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->NumTxQueues = LE_32(dma->maxNumWCB); 646d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->TotalRxWcb = LE_32(1); /* XXX */ 647d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->RxPdWrPtr = LE_32(dma->rxDescRead); 648d8d81063Sfei feng - Sun Microsystems - Beijing China /* 649d8d81063Sfei feng - Sun Microsystems - Beijing China * pCmd->Flags = LE_32(SET_HW_SPEC_HOSTFORM_BEACON 650d8d81063Sfei feng - Sun Microsystems - Beijing China * #ifdef MWL_HOST_PS_SUPPORT 651d8d81063Sfei feng - Sun Microsystems - Beijing China * | SET_HW_SPEC_HOST_POWERSAVE 652d8d81063Sfei feng - Sun Microsystems - Beijing China * #endif 653d8d81063Sfei feng - Sun Microsystems - Beijing China * | SET_HW_SPEC_HOSTFORM_PROBERESP); 654d8d81063Sfei feng - Sun Microsystems - Beijing China */ 655d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Flags = 0; 656d8d81063Sfei feng - Sun Microsystems - Beijing China /* disable multi-bss operation for A1-A4 parts */ 657d8d81063Sfei feng - Sun Microsystems - Beijing China if (sc->sc_revs.mh_macRev < 5) 658d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Flags |= LE_32(SET_HW_SPEC_DISABLEMBSS); 659d8d81063Sfei feng - Sun Microsystems - Beijing China 660d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_SET_HW_SPEC); 661d8d81063Sfei feng - Sun Microsystems - Beijing China if (retval == 0) { 662d8d81063Sfei feng - Sun Microsystems - Beijing China if (pCmd->Flags & LE_32(SET_HW_SPEC_DISABLEMBSS)) 663d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_hw_flags &= ~MHF_MBSS; 664d8d81063Sfei feng - Sun Microsystems - Beijing China else 665d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_hw_flags |= MHF_MBSS; 666d8d81063Sfei feng - Sun Microsystems - Beijing China } 667d8d81063Sfei feng - Sun Microsystems - Beijing China 668d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 669d8d81063Sfei feng - Sun Microsystems - Beijing China } 670d8d81063Sfei feng - Sun Microsystems - Beijing China 671d8d81063Sfei feng - Sun Microsystems - Beijing China /* 672d8d81063Sfei feng - Sun Microsystems - Beijing China * Inform firmware of our tx/rx dma setup. The BAR 0 673d8d81063Sfei feng - Sun Microsystems - Beijing China * writes below are for compatibility with older firmware. 674d8d81063Sfei feng - Sun Microsystems - Beijing China * For current firmware we send this information with a 675d8d81063Sfei feng - Sun Microsystems - Beijing China * cmd block via mwl_hal_sethwdma. 676d8d81063Sfei feng - Sun Microsystems - Beijing China */ 677d8d81063Sfei feng - Sun Microsystems - Beijing China static int 678d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_setupdma(struct mwl_softc *sc) 679d8d81063Sfei feng - Sun Microsystems - Beijing China { 680d8d81063Sfei feng - Sun Microsystems - Beijing China int i, err; 681d8d81063Sfei feng - Sun Microsystems - Beijing China 682d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_hwdma.rxDescRead = sc->sc_rxring.physaddr; 683d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_mem_write4(sc, sc->sc_hwspecs.rxDescRead, sc->sc_hwdma.rxDescRead); 684d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_mem_write4(sc, sc->sc_hwspecs.rxDescWrite, sc->sc_hwdma.rxDescRead); 685d8d81063Sfei feng - Sun Microsystems - Beijing China 686d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < MWL_NUM_TX_QUEUES - MWL_NUM_ACK_QUEUES; i++) { 687d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_tx_ring *txring = &sc->sc_txring[i]; 688d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_hwdma.wcbBase[i] = txring->physaddr; 689d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_mem_write4(sc, sc->sc_hwspecs.wcbBase[i], 690d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_hwdma.wcbBase[i]); 691d8d81063Sfei feng - Sun Microsystems - Beijing China } 692d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_hwdma.maxNumTxWcb = MWL_TX_RING_COUNT; 693d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_hwdma.maxNumWCB = MWL_NUM_TX_QUEUES - MWL_NUM_ACK_QUEUES; 694d8d81063Sfei feng - Sun Microsystems - Beijing China 695d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_hal_sethwdma(sc, &sc->sc_hwdma); 696d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 697d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_DMA, "mwl: mwl_setupdma(): " 698d8d81063Sfei feng - Sun Microsystems - Beijing China "unable to setup tx/rx dma; hal status %u\n", err); 699d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX */ 700d8d81063Sfei feng - Sun Microsystems - Beijing China } 701d8d81063Sfei feng - Sun Microsystems - Beijing China 702d8d81063Sfei feng - Sun Microsystems - Beijing China return (err); 703d8d81063Sfei feng - Sun Microsystems - Beijing China } 704d8d81063Sfei feng - Sun Microsystems - Beijing China 705d8d81063Sfei feng - Sun Microsystems - Beijing China /* ARGSUSED */ 706d8d81063Sfei feng - Sun Microsystems - Beijing China static void 707d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_txq_init(struct mwl_softc *sc, struct mwl_tx_ring *txring, int qnum) 708d8d81063Sfei feng - Sun Microsystems - Beijing China { 709d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_txbuf *bf; 710d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_txdesc *ds; 711d8d81063Sfei feng - Sun Microsystems - Beijing China int i; 712d8d81063Sfei feng - Sun Microsystems - Beijing China 713d8d81063Sfei feng - Sun Microsystems - Beijing China txring->qnum = qnum; 714d8d81063Sfei feng - Sun Microsystems - Beijing China txring->txpri = 0; /* XXX */ 715d8d81063Sfei feng - Sun Microsystems - Beijing China 716d8d81063Sfei feng - Sun Microsystems - Beijing China bf = txring->buf; 717d8d81063Sfei feng - Sun Microsystems - Beijing China ds = txring->desc; 718d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < MWL_TX_RING_COUNT - 1; i++) { 719d8d81063Sfei feng - Sun Microsystems - Beijing China bf++; 720d8d81063Sfei feng - Sun Microsystems - Beijing China ds->pPhysNext = bf->bf_daddr; 721d8d81063Sfei feng - Sun Microsystems - Beijing China ds++; 722d8d81063Sfei feng - Sun Microsystems - Beijing China } 723d8d81063Sfei feng - Sun Microsystems - Beijing China bf = txring->buf; 724d8d81063Sfei feng - Sun Microsystems - Beijing China ds->pPhysNext = LE_32(bf->bf_daddr); 725d8d81063Sfei feng - Sun Microsystems - Beijing China } 726d8d81063Sfei feng - Sun Microsystems - Beijing China 727d8d81063Sfei feng - Sun Microsystems - Beijing China /* 728d8d81063Sfei feng - Sun Microsystems - Beijing China * Setup a hardware data transmit queue for the specified 729d8d81063Sfei feng - Sun Microsystems - Beijing China * access control. We record the mapping from ac's 730d8d81063Sfei feng - Sun Microsystems - Beijing China * to h/w queues for use by mwl_tx_start. 731d8d81063Sfei feng - Sun Microsystems - Beijing China */ 732d8d81063Sfei feng - Sun Microsystems - Beijing China static int 733d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_tx_setup(struct mwl_softc *sc, int ac, int mvtype) 734d8d81063Sfei feng - Sun Microsystems - Beijing China { 735d8d81063Sfei feng - Sun Microsystems - Beijing China #define N(a) (sizeof (a)/sizeof (a[0])) 736d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_tx_ring *txring; 737d8d81063Sfei feng - Sun Microsystems - Beijing China 738d8d81063Sfei feng - Sun Microsystems - Beijing China if (ac >= N(sc->sc_ac2q)) { 739d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_DMA, "mwl: mwl_tx_setup(): " 740d8d81063Sfei feng - Sun Microsystems - Beijing China "AC %u out of range, max %u!\n", 741d8d81063Sfei feng - Sun Microsystems - Beijing China ac, (uint_t)N(sc->sc_ac2q)); 742d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 743d8d81063Sfei feng - Sun Microsystems - Beijing China } 744d8d81063Sfei feng - Sun Microsystems - Beijing China if (mvtype >= MWL_NUM_TX_QUEUES) { 745d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_DMA, "mwl: mwl_tx_setup(): " 746d8d81063Sfei feng - Sun Microsystems - Beijing China "mvtype %u out of range, max %u!\n", 747d8d81063Sfei feng - Sun Microsystems - Beijing China mvtype, MWL_NUM_TX_QUEUES); 748d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 749d8d81063Sfei feng - Sun Microsystems - Beijing China } 750d8d81063Sfei feng - Sun Microsystems - Beijing China txring = &sc->sc_txring[mvtype]; 751d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_txq_init(sc, txring, mvtype); 752d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_ac2q[ac] = txring; 753d8d81063Sfei feng - Sun Microsystems - Beijing China return (1); 754d8d81063Sfei feng - Sun Microsystems - Beijing China #undef N 755d8d81063Sfei feng - Sun Microsystems - Beijing China } 756d8d81063Sfei feng - Sun Microsystems - Beijing China 757d8d81063Sfei feng - Sun Microsystems - Beijing China static int 758d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_setup_txq(struct mwl_softc *sc) 759d8d81063Sfei feng - Sun Microsystems - Beijing China { 760d8d81063Sfei feng - Sun Microsystems - Beijing China int err = 0; 761d8d81063Sfei feng - Sun Microsystems - Beijing China 762d8d81063Sfei feng - Sun Microsystems - Beijing China /* NB: insure BK queue is the lowest priority h/w queue */ 763d8d81063Sfei feng - Sun Microsystems - Beijing China if (!mwl_tx_setup(sc, WME_AC_BK, MWL_WME_AC_BK)) { 764d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_DMA, "mwl: mwl_setup_txq(): " 765d8d81063Sfei feng - Sun Microsystems - Beijing China "unable to setup xmit queue for %s traffic!\n", 766d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_wme_acnames[WME_AC_BK]); 767d8d81063Sfei feng - Sun Microsystems - Beijing China err = EIO; 768d8d81063Sfei feng - Sun Microsystems - Beijing China return (err); 769d8d81063Sfei feng - Sun Microsystems - Beijing China } 770d8d81063Sfei feng - Sun Microsystems - Beijing China if (!mwl_tx_setup(sc, WME_AC_BE, MWL_WME_AC_BE) || 771d8d81063Sfei feng - Sun Microsystems - Beijing China !mwl_tx_setup(sc, WME_AC_VI, MWL_WME_AC_VI) || 772d8d81063Sfei feng - Sun Microsystems - Beijing China !mwl_tx_setup(sc, WME_AC_VO, MWL_WME_AC_VO)) { 773d8d81063Sfei feng - Sun Microsystems - Beijing China /* 774d8d81063Sfei feng - Sun Microsystems - Beijing China * Not enough hardware tx queues to properly do WME; 775d8d81063Sfei feng - Sun Microsystems - Beijing China * just punt and assign them all to the same h/w queue. 776d8d81063Sfei feng - Sun Microsystems - Beijing China * We could do a better job of this if, for example, 777d8d81063Sfei feng - Sun Microsystems - Beijing China * we allocate queues when we switch from station to 778d8d81063Sfei feng - Sun Microsystems - Beijing China * AP mode. 779d8d81063Sfei feng - Sun Microsystems - Beijing China */ 780d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_ac2q[WME_AC_BE] = sc->sc_ac2q[WME_AC_BK]; 781d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_ac2q[WME_AC_VI] = sc->sc_ac2q[WME_AC_BK]; 782d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_ac2q[WME_AC_VO] = sc->sc_ac2q[WME_AC_BK]; 783d8d81063Sfei feng - Sun Microsystems - Beijing China } 784d8d81063Sfei feng - Sun Microsystems - Beijing China 785d8d81063Sfei feng - Sun Microsystems - Beijing China return (err); 786d8d81063Sfei feng - Sun Microsystems - Beijing China } 787d8d81063Sfei feng - Sun Microsystems - Beijing China 788d8d81063Sfei feng - Sun Microsystems - Beijing China /* 789d8d81063Sfei feng - Sun Microsystems - Beijing China * find mwl firmware module's "_start" "_end" symbols 790d8d81063Sfei feng - Sun Microsystems - Beijing China * and get its size. 791d8d81063Sfei feng - Sun Microsystems - Beijing China */ 792d8d81063Sfei feng - Sun Microsystems - Beijing China static int 793d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_loadsym(ddi_modhandle_t modp, char *sym, char **start, size_t *len) 794d8d81063Sfei feng - Sun Microsystems - Beijing China { 795d8d81063Sfei feng - Sun Microsystems - Beijing China char start_sym[64]; 796d8d81063Sfei feng - Sun Microsystems - Beijing China char end_sym[64]; 797d8d81063Sfei feng - Sun Microsystems - Beijing China char *p, *end; 798d8d81063Sfei feng - Sun Microsystems - Beijing China int rv; 799d8d81063Sfei feng - Sun Microsystems - Beijing China size_t n; 800d8d81063Sfei feng - Sun Microsystems - Beijing China 801d8d81063Sfei feng - Sun Microsystems - Beijing China (void) snprintf(start_sym, sizeof (start_sym), "%s_start", sym); 802d8d81063Sfei feng - Sun Microsystems - Beijing China (void) snprintf(end_sym, sizeof (end_sym), "%s_end", sym); 803d8d81063Sfei feng - Sun Microsystems - Beijing China 804d8d81063Sfei feng - Sun Microsystems - Beijing China p = (char *)ddi_modsym(modp, start_sym, &rv); 805d8d81063Sfei feng - Sun Microsystems - Beijing China if (p == NULL || rv != 0) { 806d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_FW, "mwl: mwl_loadsym(): " 807d8d81063Sfei feng - Sun Microsystems - Beijing China "mod %s: symbol %s not found\n", sym, start_sym); 808d8d81063Sfei feng - Sun Microsystems - Beijing China return (-1); 809d8d81063Sfei feng - Sun Microsystems - Beijing China } 810d8d81063Sfei feng - Sun Microsystems - Beijing China 811d8d81063Sfei feng - Sun Microsystems - Beijing China end = (char *)ddi_modsym(modp, end_sym, &rv); 812d8d81063Sfei feng - Sun Microsystems - Beijing China if (end == NULL || rv != 0) { 813d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_FW, "mwl: mwl_loadsym(): " 814d8d81063Sfei feng - Sun Microsystems - Beijing China "mod %s: symbol %s not found\n", sym, end_sym); 815d8d81063Sfei feng - Sun Microsystems - Beijing China return (-1); 816d8d81063Sfei feng - Sun Microsystems - Beijing China } 817d8d81063Sfei feng - Sun Microsystems - Beijing China 818d8d81063Sfei feng - Sun Microsystems - Beijing China n = _PTRDIFF(end, p); 819d8d81063Sfei feng - Sun Microsystems - Beijing China *start = p; 820d8d81063Sfei feng - Sun Microsystems - Beijing China *len = n; 821d8d81063Sfei feng - Sun Microsystems - Beijing China 822d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 823d8d81063Sfei feng - Sun Microsystems - Beijing China } 824d8d81063Sfei feng - Sun Microsystems - Beijing China 825d8d81063Sfei feng - Sun Microsystems - Beijing China static void 826d8d81063Sfei feng - Sun Microsystems - Beijing China mwlFwReset(struct mwl_softc *sc) 827d8d81063Sfei feng - Sun Microsystems - Beijing China { 828d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwl_ctl_read4(sc, MACREG_REG_INT_CODE) == 0xffffffff) { 829d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_FW, "mwl: mwlFWReset(): " 830d8d81063Sfei feng - Sun Microsystems - Beijing China "device not present!\n"); 831d8d81063Sfei feng - Sun Microsystems - Beijing China return; 832d8d81063Sfei feng - Sun Microsystems - Beijing China } 833d8d81063Sfei feng - Sun Microsystems - Beijing China 834d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_H2A_INTERRUPT_EVENTS, ISR_RESET); 835d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_hw_flags &= ~MHF_FWHANG; 836d8d81063Sfei feng - Sun Microsystems - Beijing China } 837d8d81063Sfei feng - Sun Microsystems - Beijing China 838d8d81063Sfei feng - Sun Microsystems - Beijing China static void 839d8d81063Sfei feng - Sun Microsystems - Beijing China mwlPokeSdramController(struct mwl_softc *sc, int SDRAMSIZE_Addr) 840d8d81063Sfei feng - Sun Microsystems - Beijing China { 841d8d81063Sfei feng - Sun Microsystems - Beijing China /* Set up sdram controller for superflyv2 */ 842d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, 0x00006014, 0x33); 843d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, 0x00006018, 0xa3a2632); 844d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, 0x00006010, SDRAMSIZE_Addr); 845d8d81063Sfei feng - Sun Microsystems - Beijing China } 846d8d81063Sfei feng - Sun Microsystems - Beijing China 847d8d81063Sfei feng - Sun Microsystems - Beijing China static void 848d8d81063Sfei feng - Sun Microsystems - Beijing China mwlTriggerPciCmd(struct mwl_softc *sc) 849d8d81063Sfei feng - Sun Microsystems - Beijing China { 850d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(sc->sc_cmd_dma.dma_hdl, 851d8d81063Sfei feng - Sun Microsystems - Beijing China 0, 852d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_cmd_dma.alength, 853d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV); 854d8d81063Sfei feng - Sun Microsystems - Beijing China 855d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_GEN_PTR, sc->sc_cmd_dmaaddr); 856d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_ctl_read4(sc, MACREG_REG_INT_CODE); 857d8d81063Sfei feng - Sun Microsystems - Beijing China 858d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_INT_CODE, 0x00); 859d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_ctl_read4(sc, MACREG_REG_INT_CODE); 860d8d81063Sfei feng - Sun Microsystems - Beijing China 861d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_H2A_INTERRUPT_EVENTS, 862d8d81063Sfei feng - Sun Microsystems - Beijing China MACREG_H2ARIC_BIT_DOOR_BELL); 863d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_ctl_read4(sc, MACREG_REG_INT_CODE); 864d8d81063Sfei feng - Sun Microsystems - Beijing China } 865d8d81063Sfei feng - Sun Microsystems - Beijing China 866d8d81063Sfei feng - Sun Microsystems - Beijing China static int 867d8d81063Sfei feng - Sun Microsystems - Beijing China mwlWaitFor(struct mwl_softc *sc, uint32_t val) 868d8d81063Sfei feng - Sun Microsystems - Beijing China { 869d8d81063Sfei feng - Sun Microsystems - Beijing China int i; 870d8d81063Sfei feng - Sun Microsystems - Beijing China 871d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < FW_MAX_NUM_CHECKS; i++) { 872d8d81063Sfei feng - Sun Microsystems - Beijing China DELAY(FW_CHECK_USECS); 873d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwl_ctl_read4(sc, MACREG_REG_INT_CODE) == val) 874d8d81063Sfei feng - Sun Microsystems - Beijing China return (1); 875d8d81063Sfei feng - Sun Microsystems - Beijing China } 876d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 877d8d81063Sfei feng - Sun Microsystems - Beijing China } 878d8d81063Sfei feng - Sun Microsystems - Beijing China 879d8d81063Sfei feng - Sun Microsystems - Beijing China /* 880d8d81063Sfei feng - Sun Microsystems - Beijing China * Firmware block xmit when talking to the boot-rom. 881d8d81063Sfei feng - Sun Microsystems - Beijing China */ 882d8d81063Sfei feng - Sun Microsystems - Beijing China static int 883d8d81063Sfei feng - Sun Microsystems - Beijing China mwlSendBlock(struct mwl_softc *sc, int bsize, const void *data, size_t dsize) 884d8d81063Sfei feng - Sun Microsystems - Beijing China { 885d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_cmd_mem[0] = LE_16(HostCmd_CMD_CODE_DNLD); 886d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_cmd_mem[1] = LE_16(bsize); 887d8d81063Sfei feng - Sun Microsystems - Beijing China (void) memcpy(&sc->sc_cmd_mem[4], data, dsize); 888d8d81063Sfei feng - Sun Microsystems - Beijing China mwlTriggerPciCmd(sc); 889d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX 2000 vs 200 */ 890d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwlWaitFor(sc, MACREG_INT_CODE_CMD_FINISHED)) { 891d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_INT_CODE, 0); 892d8d81063Sfei feng - Sun Microsystems - Beijing China return (1); 893d8d81063Sfei feng - Sun Microsystems - Beijing China } 894d8d81063Sfei feng - Sun Microsystems - Beijing China 895d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_FW, "mwl: mwlSendBlock(): " 896d8d81063Sfei feng - Sun Microsystems - Beijing China "timeout waiting for CMD_FINISHED, INT_CODE 0x%x\n", 897d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_read4(sc, MACREG_REG_INT_CODE)); 898d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 899d8d81063Sfei feng - Sun Microsystems - Beijing China } 900d8d81063Sfei feng - Sun Microsystems - Beijing China 901d8d81063Sfei feng - Sun Microsystems - Beijing China /* 902d8d81063Sfei feng - Sun Microsystems - Beijing China * Firmware block xmit when talking to the 1st-stage loader. 903d8d81063Sfei feng - Sun Microsystems - Beijing China */ 904d8d81063Sfei feng - Sun Microsystems - Beijing China static int 905d8d81063Sfei feng - Sun Microsystems - Beijing China mwlSendBlock2(struct mwl_softc *sc, const void *data, size_t dsize) 906d8d81063Sfei feng - Sun Microsystems - Beijing China { 907d8d81063Sfei feng - Sun Microsystems - Beijing China (void) memcpy(&sc->sc_cmd_mem[0], data, dsize); 908d8d81063Sfei feng - Sun Microsystems - Beijing China mwlTriggerPciCmd(sc); 909d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwlWaitFor(sc, MACREG_INT_CODE_CMD_FINISHED)) { 910d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_INT_CODE, 0); 911d8d81063Sfei feng - Sun Microsystems - Beijing China return (1); 912d8d81063Sfei feng - Sun Microsystems - Beijing China } 913d8d81063Sfei feng - Sun Microsystems - Beijing China 914d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_FW, "mwl: mwlSendBlock2(): " 915d8d81063Sfei feng - Sun Microsystems - Beijing China "timeout waiting for CMD_FINISHED, INT_CODE 0x%x\n", 916d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_read4(sc, MACREG_REG_INT_CODE)); 917d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 918d8d81063Sfei feng - Sun Microsystems - Beijing China } 919d8d81063Sfei feng - Sun Microsystems - Beijing China 920d8d81063Sfei feng - Sun Microsystems - Beijing China /* ARGSUSED */ 921d8d81063Sfei feng - Sun Microsystems - Beijing China static int 922d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_fwload(struct mwl_softc *sc, void *fwargs) 923d8d81063Sfei feng - Sun Microsystems - Beijing China { 924d8d81063Sfei feng - Sun Microsystems - Beijing China char *fwname = "mwlfw"; 925d8d81063Sfei feng - Sun Microsystems - Beijing China char *fwbootname = "mwlboot"; 926d8d81063Sfei feng - Sun Microsystems - Beijing China char *fwbinname = "mw88W8363fw"; 927d8d81063Sfei feng - Sun Microsystems - Beijing China char *fwboot_index, *fw_index; 928d8d81063Sfei feng - Sun Microsystems - Beijing China uint8_t *fw, *fwboot; 929d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_modhandle_t modfw; 930d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX get from firmware header */ 931d8d81063Sfei feng - Sun Microsystems - Beijing China uint32_t FwReadySignature = HostCmd_SOFTAP_FWRDY_SIGNATURE; 932d8d81063Sfei feng - Sun Microsystems - Beijing China uint32_t OpMode = HostCmd_SOFTAP_MODE; 933d8d81063Sfei feng - Sun Microsystems - Beijing China const uint8_t *fp, *ep; 934d8d81063Sfei feng - Sun Microsystems - Beijing China size_t fw_size, fwboot_size; 935d8d81063Sfei feng - Sun Microsystems - Beijing China uint32_t blocksize, nbytes; 936d8d81063Sfei feng - Sun Microsystems - Beijing China int i, rv, err, ntries; 937d8d81063Sfei feng - Sun Microsystems - Beijing China 938d8d81063Sfei feng - Sun Microsystems - Beijing China rv = err = 0; 939d8d81063Sfei feng - Sun Microsystems - Beijing China fw = fwboot = NULL; 940d8d81063Sfei feng - Sun Microsystems - Beijing China fw_index = fwboot_index = NULL; 941d8d81063Sfei feng - Sun Microsystems - Beijing China 942d8d81063Sfei feng - Sun Microsystems - Beijing China modfw = ddi_modopen(fwname, KRTLD_MODE_FIRST, &rv); 943d8d81063Sfei feng - Sun Microsystems - Beijing China if (modfw == NULL) { 944d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_FW, "mwl: mwl_fwload(): " 945d8d81063Sfei feng - Sun Microsystems - Beijing China "module %s not found\n", fwname); 946d8d81063Sfei feng - Sun Microsystems - Beijing China err = -1; 947d8d81063Sfei feng - Sun Microsystems - Beijing China goto bad2; 948d8d81063Sfei feng - Sun Microsystems - Beijing China } 949d8d81063Sfei feng - Sun Microsystems - Beijing China 950d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_loadsym(modfw, fwbootname, &fwboot_index, &fwboot_size); 951d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 952d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_FW, "mwl: mwl_fwload(): " 953d8d81063Sfei feng - Sun Microsystems - Beijing China "could not get boot firmware\n"); 954d8d81063Sfei feng - Sun Microsystems - Beijing China err = -1; 955d8d81063Sfei feng - Sun Microsystems - Beijing China goto bad2; 956d8d81063Sfei feng - Sun Microsystems - Beijing China } 957d8d81063Sfei feng - Sun Microsystems - Beijing China 958d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_loadsym(modfw, fwbinname, &fw_index, &fw_size); 959d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 960d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_FW, "mwl: mwl_fwload(): " 961d8d81063Sfei feng - Sun Microsystems - Beijing China "could not get firmware\n"); 962d8d81063Sfei feng - Sun Microsystems - Beijing China err = -1; 963d8d81063Sfei feng - Sun Microsystems - Beijing China goto bad2; 964d8d81063Sfei feng - Sun Microsystems - Beijing China } 965d8d81063Sfei feng - Sun Microsystems - Beijing China 966d8d81063Sfei feng - Sun Microsystems - Beijing China fwboot = (uint8_t *)kmem_alloc(fwboot_size, KM_SLEEP); 967d8d81063Sfei feng - Sun Microsystems - Beijing China if (fwboot == NULL) { 968d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_FW, "mwl: mwl_loadfirmware(): " 969d8d81063Sfei feng - Sun Microsystems - Beijing China "failed to alloc boot firmware memory\n"); 970d8d81063Sfei feng - Sun Microsystems - Beijing China err = -1; 971d8d81063Sfei feng - Sun Microsystems - Beijing China goto bad2; 972d8d81063Sfei feng - Sun Microsystems - Beijing China } 973d8d81063Sfei feng - Sun Microsystems - Beijing China (void) memcpy(fwboot, fwboot_index, fwboot_size); 974d8d81063Sfei feng - Sun Microsystems - Beijing China 975d8d81063Sfei feng - Sun Microsystems - Beijing China fw = (uint8_t *)kmem_alloc(fw_size, KM_SLEEP); 976d8d81063Sfei feng - Sun Microsystems - Beijing China if (fw == NULL) { 977d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_FW, "mwl: mwl_loadfirmware(): " 978d8d81063Sfei feng - Sun Microsystems - Beijing China "failed to alloc firmware memory\n"); 979d8d81063Sfei feng - Sun Microsystems - Beijing China err = -1; 980d8d81063Sfei feng - Sun Microsystems - Beijing China goto bad2; 981d8d81063Sfei feng - Sun Microsystems - Beijing China } 982d8d81063Sfei feng - Sun Microsystems - Beijing China (void) memcpy(fw, fw_index, fw_size); 983d8d81063Sfei feng - Sun Microsystems - Beijing China 984d8d81063Sfei feng - Sun Microsystems - Beijing China if (modfw != NULL) 985d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_modclose(modfw); 986d8d81063Sfei feng - Sun Microsystems - Beijing China 987d8d81063Sfei feng - Sun Microsystems - Beijing China if (fw_size < 4) { 988d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_FW, "mwl: mwl_fwload(): " 989d8d81063Sfei feng - Sun Microsystems - Beijing China "could not load firmware image %s\n", 990d8d81063Sfei feng - Sun Microsystems - Beijing China fwname); 991d8d81063Sfei feng - Sun Microsystems - Beijing China err = ENXIO; 992d8d81063Sfei feng - Sun Microsystems - Beijing China goto bad2; 993d8d81063Sfei feng - Sun Microsystems - Beijing China } 994d8d81063Sfei feng - Sun Microsystems - Beijing China 995d8d81063Sfei feng - Sun Microsystems - Beijing China if (fw[0] == 0x01 && fw[1] == 0x00 && 996d8d81063Sfei feng - Sun Microsystems - Beijing China fw[2] == 0x00 && fw[3] == 0x00) { 997d8d81063Sfei feng - Sun Microsystems - Beijing China /* 998d8d81063Sfei feng - Sun Microsystems - Beijing China * 2-stage load, get the boot firmware. 999d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1000d8d81063Sfei feng - Sun Microsystems - Beijing China if (fwboot == NULL) { 1001d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_FW, "mwl: mwl_fwload(): " 1002d8d81063Sfei feng - Sun Microsystems - Beijing China "could not load firmware image %s\n", 1003d8d81063Sfei feng - Sun Microsystems - Beijing China fwbootname); 1004d8d81063Sfei feng - Sun Microsystems - Beijing China err = ENXIO; 1005d8d81063Sfei feng - Sun Microsystems - Beijing China goto bad2; 1006d8d81063Sfei feng - Sun Microsystems - Beijing China } 1007d8d81063Sfei feng - Sun Microsystems - Beijing China } else 1008d8d81063Sfei feng - Sun Microsystems - Beijing China fwboot = NULL; 1009d8d81063Sfei feng - Sun Microsystems - Beijing China 1010d8d81063Sfei feng - Sun Microsystems - Beijing China mwlFwReset(sc); 1011d8d81063Sfei feng - Sun Microsystems - Beijing China 1012d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_A2H_INTERRUPT_CLEAR_SEL, 1013d8d81063Sfei feng - Sun Microsystems - Beijing China MACREG_A2HRIC_BIT_MASK); 1014d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_A2H_INTERRUPT_CAUSE, 0x00); 1015d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_A2H_INTERRUPT_MASK, 0x00); 1016d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_A2H_INTERRUPT_STATUS_MASK, 1017d8d81063Sfei feng - Sun Microsystems - Beijing China MACREG_A2HRIC_BIT_MASK); 1018d8d81063Sfei feng - Sun Microsystems - Beijing China if (sc->sc_SDRAMSIZE_Addr != 0) { 1019d8d81063Sfei feng - Sun Microsystems - Beijing China /* Set up sdram controller for superflyv2 */ 1020d8d81063Sfei feng - Sun Microsystems - Beijing China mwlPokeSdramController(sc, sc->sc_SDRAMSIZE_Addr); 1021d8d81063Sfei feng - Sun Microsystems - Beijing China } 1022d8d81063Sfei feng - Sun Microsystems - Beijing China 1023d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_FW, "mwl: mwl_fwload(): " 1024d8d81063Sfei feng - Sun Microsystems - Beijing China "load %s firmware image (%u bytes)\n", 1025d8d81063Sfei feng - Sun Microsystems - Beijing China fwname, (unsigned int)fw_size); 1026d8d81063Sfei feng - Sun Microsystems - Beijing China 1027d8d81063Sfei feng - Sun Microsystems - Beijing China if (fwboot != NULL) { 1028d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1029d8d81063Sfei feng - Sun Microsystems - Beijing China * Do 2-stage load. The 1st stage loader is setup 1030d8d81063Sfei feng - Sun Microsystems - Beijing China * with the bootrom loader then we load the real 1031d8d81063Sfei feng - Sun Microsystems - Beijing China * image using a different handshake. With this 1032d8d81063Sfei feng - Sun Microsystems - Beijing China * mechanism the firmware is segmented into chunks 1033d8d81063Sfei feng - Sun Microsystems - Beijing China * that have a CRC. If a chunk is incorrect we'll 1034d8d81063Sfei feng - Sun Microsystems - Beijing China * be told to retransmit. 1035d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1036d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX assumes hlpimage fits in a block */ 1037d8d81063Sfei feng - Sun Microsystems - Beijing China /* NB: zero size block indicates download is finished */ 1038d8d81063Sfei feng - Sun Microsystems - Beijing China if (!mwlSendBlock(sc, fwboot_size, fwboot, fwboot_size) || 1039d8d81063Sfei feng - Sun Microsystems - Beijing China !mwlSendBlock(sc, 0, NULL, 0)) { 1040d8d81063Sfei feng - Sun Microsystems - Beijing China err = ETIMEDOUT; 1041d8d81063Sfei feng - Sun Microsystems - Beijing China goto bad; 1042d8d81063Sfei feng - Sun Microsystems - Beijing China } 1043d8d81063Sfei feng - Sun Microsystems - Beijing China DELAY(200 * FW_CHECK_USECS); 1044d8d81063Sfei feng - Sun Microsystems - Beijing China if (sc->sc_SDRAMSIZE_Addr != 0) { 1045d8d81063Sfei feng - Sun Microsystems - Beijing China /* Set up sdram controller for superflyv2 */ 1046d8d81063Sfei feng - Sun Microsystems - Beijing China mwlPokeSdramController(sc, sc->sc_SDRAMSIZE_Addr); 1047d8d81063Sfei feng - Sun Microsystems - Beijing China } 1048d8d81063Sfei feng - Sun Microsystems - Beijing China nbytes = ntries = 0; /* NB: silence compiler */ 1049d8d81063Sfei feng - Sun Microsystems - Beijing China for (fp = fw, ep = fp + fw_size; fp < ep; ) { 1050d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_INT_CODE, 0); 1051d8d81063Sfei feng - Sun Microsystems - Beijing China blocksize = mwl_ctl_read4(sc, MACREG_REG_SCRATCH); 1052d8d81063Sfei feng - Sun Microsystems - Beijing China if (blocksize == 0) /* download complete */ 1053d8d81063Sfei feng - Sun Microsystems - Beijing China break; 1054d8d81063Sfei feng - Sun Microsystems - Beijing China if (blocksize > 0x00000c00) { 1055d8d81063Sfei feng - Sun Microsystems - Beijing China err = EINVAL; 1056d8d81063Sfei feng - Sun Microsystems - Beijing China goto bad; 1057d8d81063Sfei feng - Sun Microsystems - Beijing China } 1058d8d81063Sfei feng - Sun Microsystems - Beijing China if ((blocksize & 0x1) == 0) { 1059d8d81063Sfei feng - Sun Microsystems - Beijing China /* block successfully downloaded, advance */ 1060d8d81063Sfei feng - Sun Microsystems - Beijing China fp += nbytes; 1061d8d81063Sfei feng - Sun Microsystems - Beijing China ntries = 0; 1062d8d81063Sfei feng - Sun Microsystems - Beijing China } else { 1063d8d81063Sfei feng - Sun Microsystems - Beijing China if (++ntries > 2) { 1064d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1065d8d81063Sfei feng - Sun Microsystems - Beijing China * Guard against f/w telling us to 1066d8d81063Sfei feng - Sun Microsystems - Beijing China * retry infinitely. 1067d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1068d8d81063Sfei feng - Sun Microsystems - Beijing China err = ELOOP; 1069d8d81063Sfei feng - Sun Microsystems - Beijing China goto bad; 1070d8d81063Sfei feng - Sun Microsystems - Beijing China } 1071d8d81063Sfei feng - Sun Microsystems - Beijing China /* clear NAK bit/flag */ 1072d8d81063Sfei feng - Sun Microsystems - Beijing China blocksize &= ~0x1; 1073d8d81063Sfei feng - Sun Microsystems - Beijing China } 1074d8d81063Sfei feng - Sun Microsystems - Beijing China if (blocksize > _PTRDIFF(ep, fp)) { 1075d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX this should not happen, what to do? */ 1076d8d81063Sfei feng - Sun Microsystems - Beijing China blocksize = _PTRDIFF(ep, fp); 1077d8d81063Sfei feng - Sun Microsystems - Beijing China } 1078d8d81063Sfei feng - Sun Microsystems - Beijing China nbytes = blocksize; 1079d8d81063Sfei feng - Sun Microsystems - Beijing China if (!mwlSendBlock2(sc, fp, nbytes)) { 1080d8d81063Sfei feng - Sun Microsystems - Beijing China err = ETIMEDOUT; 1081d8d81063Sfei feng - Sun Microsystems - Beijing China goto bad; 1082d8d81063Sfei feng - Sun Microsystems - Beijing China } 1083d8d81063Sfei feng - Sun Microsystems - Beijing China } 1084d8d81063Sfei feng - Sun Microsystems - Beijing China } else { 1085d8d81063Sfei feng - Sun Microsystems - Beijing China for (fp = fw, ep = fp + fw_size; fp < ep; ) { 1086d8d81063Sfei feng - Sun Microsystems - Beijing China nbytes = _PTRDIFF(ep, fp); 1087d8d81063Sfei feng - Sun Microsystems - Beijing China if (nbytes > FW_DOWNLOAD_BLOCK_SIZE) 1088d8d81063Sfei feng - Sun Microsystems - Beijing China nbytes = FW_DOWNLOAD_BLOCK_SIZE; 1089d8d81063Sfei feng - Sun Microsystems - Beijing China if (!mwlSendBlock(sc, FW_DOWNLOAD_BLOCK_SIZE, fp, 1090d8d81063Sfei feng - Sun Microsystems - Beijing China nbytes)) { 1091d8d81063Sfei feng - Sun Microsystems - Beijing China err = EIO; 1092d8d81063Sfei feng - Sun Microsystems - Beijing China goto bad; 1093d8d81063Sfei feng - Sun Microsystems - Beijing China } 1094d8d81063Sfei feng - Sun Microsystems - Beijing China fp += nbytes; 1095d8d81063Sfei feng - Sun Microsystems - Beijing China } 1096d8d81063Sfei feng - Sun Microsystems - Beijing China } 1097d8d81063Sfei feng - Sun Microsystems - Beijing China 1098d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1099d8d81063Sfei feng - Sun Microsystems - Beijing China * Wait for firmware to startup; we monitor the 1100d8d81063Sfei feng - Sun Microsystems - Beijing China * INT_CODE register waiting for a signature to 1101d8d81063Sfei feng - Sun Microsystems - Beijing China * written back indicating it's ready to go. 1102d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1103d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_cmd_mem[1] = 0; 1104d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1105d8d81063Sfei feng - Sun Microsystems - Beijing China * XXX WAR for mfg fw download 1106d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1107d8d81063Sfei feng - Sun Microsystems - Beijing China if (OpMode != HostCmd_STA_MODE) 1108d8d81063Sfei feng - Sun Microsystems - Beijing China mwlTriggerPciCmd(sc); 1109d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < FW_MAX_NUM_CHECKS; i++) { 1110d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_GEN_PTR, OpMode); 1111d8d81063Sfei feng - Sun Microsystems - Beijing China DELAY(FW_CHECK_USECS); 1112d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwl_ctl_read4(sc, MACREG_REG_INT_CODE) == 1113d8d81063Sfei feng - Sun Microsystems - Beijing China FwReadySignature) { 1114d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_INT_CODE, 0x00); 1115d8d81063Sfei feng - Sun Microsystems - Beijing China return (mwlResetHalState(sc)); 1116d8d81063Sfei feng - Sun Microsystems - Beijing China } 1117d8d81063Sfei feng - Sun Microsystems - Beijing China } 1118d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_FW, "mwl: mwl_fwload(): " 1119d8d81063Sfei feng - Sun Microsystems - Beijing China "firmware download timeout\n"); 1120d8d81063Sfei feng - Sun Microsystems - Beijing China return (ETIMEDOUT); 1121d8d81063Sfei feng - Sun Microsystems - Beijing China bad: 1122d8d81063Sfei feng - Sun Microsystems - Beijing China mwlFwReset(sc); 1123d8d81063Sfei feng - Sun Microsystems - Beijing China bad2: 1124d8d81063Sfei feng - Sun Microsystems - Beijing China if (fw != NULL) 1125d8d81063Sfei feng - Sun Microsystems - Beijing China kmem_free(fw, fw_size); 1126d8d81063Sfei feng - Sun Microsystems - Beijing China if (fwboot != NULL) 1127d8d81063Sfei feng - Sun Microsystems - Beijing China kmem_free(fwboot, fwboot_size); 1128d8d81063Sfei feng - Sun Microsystems - Beijing China fwboot = fw = NULL; 1129d8d81063Sfei feng - Sun Microsystems - Beijing China fwboot_index = fw_index = NULL; 1130d8d81063Sfei feng - Sun Microsystems - Beijing China if (modfw != NULL) 1131d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_modclose(modfw); 1132d8d81063Sfei feng - Sun Microsystems - Beijing China return (err); 1133d8d81063Sfei feng - Sun Microsystems - Beijing China } 1134d8d81063Sfei feng - Sun Microsystems - Beijing China 1135d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1136d8d81063Sfei feng - Sun Microsystems - Beijing China * Low level firmware cmd block handshake support. 1137d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1138d8d81063Sfei feng - Sun Microsystems - Beijing China static void 1139d8d81063Sfei feng - Sun Microsystems - Beijing China mwlSendCmd(struct mwl_softc *sc) 1140d8d81063Sfei feng - Sun Microsystems - Beijing China { 1141d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(sc->sc_cmd_dma.dma_hdl, 1142d8d81063Sfei feng - Sun Microsystems - Beijing China 0, 1143d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_cmd_dma.alength, 1144d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV); 1145d8d81063Sfei feng - Sun Microsystems - Beijing China 1146d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_GEN_PTR, sc->sc_cmd_dmaaddr); 1147d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_ctl_read4(sc, MACREG_REG_INT_CODE); 1148d8d81063Sfei feng - Sun Microsystems - Beijing China 1149d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_H2A_INTERRUPT_EVENTS, 1150d8d81063Sfei feng - Sun Microsystems - Beijing China MACREG_H2ARIC_BIT_DOOR_BELL); 1151d8d81063Sfei feng - Sun Microsystems - Beijing China } 1152d8d81063Sfei feng - Sun Microsystems - Beijing China 1153d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1154d8d81063Sfei feng - Sun Microsystems - Beijing China mwlExecuteCmd(struct mwl_softc *sc, unsigned short cmd) 1155d8d81063Sfei feng - Sun Microsystems - Beijing China { 1156d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwl_ctl_read4(sc, MACREG_REG_INT_CODE) == 0xffffffff) { 1157d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_CMD, "mwl: mwlExecuteCmd(): " 1158d8d81063Sfei feng - Sun Microsystems - Beijing China "device not present!\n"); 1159d8d81063Sfei feng - Sun Microsystems - Beijing China return (EIO); 1160d8d81063Sfei feng - Sun Microsystems - Beijing China } 1161d8d81063Sfei feng - Sun Microsystems - Beijing China mwlSendCmd(sc); 1162d8d81063Sfei feng - Sun Microsystems - Beijing China if (!mwlWaitForCmdComplete(sc, 0x8000 | cmd)) { 1163d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_CMD, "mwl: mwlExecuteCmd(): " 1164d8d81063Sfei feng - Sun Microsystems - Beijing China "timeout waiting for f/w cmd %s\n", mwlcmdname(cmd)); 1165d8d81063Sfei feng - Sun Microsystems - Beijing China return (ETIMEDOUT); 1166d8d81063Sfei feng - Sun Microsystems - Beijing China } 1167d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(sc->sc_cmd_dma.dma_hdl, 1168d8d81063Sfei feng - Sun Microsystems - Beijing China 0, 1169d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_cmd_dma.alength, 1170d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV); 1171d8d81063Sfei feng - Sun Microsystems - Beijing China 1172d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_CMD, "mwl: mwlExecuteCmd(): " 1173d8d81063Sfei feng - Sun Microsystems - Beijing China "send cmd %s\n", mwlcmdname(cmd)); 1174d8d81063Sfei feng - Sun Microsystems - Beijing China 1175d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwl_dbg_flags & MWL_DBG_CMD) 1176d8d81063Sfei feng - Sun Microsystems - Beijing China dumpresult(sc, 1); 1177d8d81063Sfei feng - Sun Microsystems - Beijing China 1178d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 1179d8d81063Sfei feng - Sun Microsystems - Beijing China } 1180d8d81063Sfei feng - Sun Microsystems - Beijing China 1181d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1182d8d81063Sfei feng - Sun Microsystems - Beijing China mwlWaitForCmdComplete(struct mwl_softc *sc, uint16_t cmdCode) 1183d8d81063Sfei feng - Sun Microsystems - Beijing China { 1184d8d81063Sfei feng - Sun Microsystems - Beijing China #define MAX_WAIT_FW_COMPLETE_ITERATIONS 10000 1185d8d81063Sfei feng - Sun Microsystems - Beijing China int i; 1186d8d81063Sfei feng - Sun Microsystems - Beijing China 1187d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < MAX_WAIT_FW_COMPLETE_ITERATIONS; i++) { 1188d8d81063Sfei feng - Sun Microsystems - Beijing China if (sc->sc_cmd_mem[0] == LE_16(cmdCode)) 1189d8d81063Sfei feng - Sun Microsystems - Beijing China return (1); 1190d8d81063Sfei feng - Sun Microsystems - Beijing China DELAY(1 * 1000); 1191d8d81063Sfei feng - Sun Microsystems - Beijing China } 1192d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 1193d8d81063Sfei feng - Sun Microsystems - Beijing China #undef MAX_WAIT_FW_COMPLETE_ITERATIONS 1194d8d81063Sfei feng - Sun Microsystems - Beijing China } 1195d8d81063Sfei feng - Sun Microsystems - Beijing China 1196d8d81063Sfei feng - Sun Microsystems - Beijing China static const char * 1197d8d81063Sfei feng - Sun Microsystems - Beijing China mwlcmdname(int cmd) 1198d8d81063Sfei feng - Sun Microsystems - Beijing China { 1199d8d81063Sfei feng - Sun Microsystems - Beijing China static char buf[12]; 1200d8d81063Sfei feng - Sun Microsystems - Beijing China #define CMD(x) case HostCmd_CMD_##x: return #x 1201d8d81063Sfei feng - Sun Microsystems - Beijing China switch (cmd) { 1202d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(CODE_DNLD); 1203d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(GET_HW_SPEC); 1204d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_HW_SPEC); 1205d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(MAC_MULTICAST_ADR); 1206d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(802_11_GET_STAT); 1207d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(MAC_REG_ACCESS); 1208d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(BBP_REG_ACCESS); 1209d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(RF_REG_ACCESS); 1210d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(802_11_RADIO_CONTROL); 1211d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(802_11_RF_TX_POWER); 1212d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(802_11_RF_ANTENNA); 1213d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_BEACON); 1214d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_RF_CHANNEL); 1215d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_AID); 1216d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_INFRA_MODE); 1217d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_G_PROTECT_FLAG); 1218d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(802_11_RTS_THSD); 1219d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(802_11_SET_SLOT); 1220d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_EDCA_PARAMS); 1221d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(802_11H_DETECT_RADAR); 1222d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_WMM_MODE); 1223d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(HT_GUARD_INTERVAL); 1224d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_FIXED_RATE); 1225d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_LINKADAPT_CS_MODE); 1226d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_MAC_ADDR); 1227d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_RATE_ADAPT_MODE); 1228d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(BSS_START); 1229d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_NEW_STN); 1230d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_KEEP_ALIVE); 1231d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_APMODE); 1232d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_SWITCH_CHANNEL); 1233d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(UPDATE_ENCRYPTION); 1234d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(BASTREAM); 1235d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_RIFS); 1236d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_N_PROTECT_FLAG); 1237d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_N_PROTECT_OPMODE); 1238d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_OPTIMIZATION_LEVEL); 1239d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(GET_CALTABLE); 1240d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_MIMOPSHT); 1241d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(GET_BEACON); 1242d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_REGION_CODE); 1243d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_POWERSAVESTATION); 1244d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(SET_TIM); 1245d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(GET_TIM); 1246d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(GET_SEQNO); 1247d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(DWDS_ENABLE); 1248d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(AMPDU_RETRY_RATEDROP_MODE); 1249d8d81063Sfei feng - Sun Microsystems - Beijing China CMD(CFEND_ENABLE); 1250d8d81063Sfei feng - Sun Microsystems - Beijing China } 1251d8d81063Sfei feng - Sun Microsystems - Beijing China (void) snprintf(buf, sizeof (buf), "0x%x", cmd); 1252d8d81063Sfei feng - Sun Microsystems - Beijing China return (buf); 1253d8d81063Sfei feng - Sun Microsystems - Beijing China #undef CMD 1254d8d81063Sfei feng - Sun Microsystems - Beijing China } 1255d8d81063Sfei feng - Sun Microsystems - Beijing China 1256d8d81063Sfei feng - Sun Microsystems - Beijing China static void 1257d8d81063Sfei feng - Sun Microsystems - Beijing China dumpresult(struct mwl_softc *sc, int showresult) 1258d8d81063Sfei feng - Sun Microsystems - Beijing China { 1259d8d81063Sfei feng - Sun Microsystems - Beijing China const FWCmdHdr *h = (const FWCmdHdr *)sc->sc_cmd_mem; 1260d8d81063Sfei feng - Sun Microsystems - Beijing China int len; 1261d8d81063Sfei feng - Sun Microsystems - Beijing China 1262d8d81063Sfei feng - Sun Microsystems - Beijing China len = LE_16(h->Length); 1263d8d81063Sfei feng - Sun Microsystems - Beijing China #ifdef MWL_MBSS_SUPPORT 1264d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_CMD, "mwl: mwl_dumpresult(): " 1265d8d81063Sfei feng - Sun Microsystems - Beijing China "Cmd %s Length %d SeqNum %d MacId %d", 1266d8d81063Sfei feng - Sun Microsystems - Beijing China mwlcmdname(LE_16(h->Cmd) & ~0x8000), len, h->SeqNum, h->MacId); 1267d8d81063Sfei feng - Sun Microsystems - Beijing China #else 1268d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_CMD, "mwl: mwl_dumpresult(): " 1269d8d81063Sfei feng - Sun Microsystems - Beijing China "Cmd %s Length %d SeqNum %d", 1270d8d81063Sfei feng - Sun Microsystems - Beijing China mwlcmdname(LE_16(h->Cmd) & ~0x8000), len, LE_16(h->SeqNum)); 1271d8d81063Sfei feng - Sun Microsystems - Beijing China #endif 1272d8d81063Sfei feng - Sun Microsystems - Beijing China if (showresult) { 1273d8d81063Sfei feng - Sun Microsystems - Beijing China const char *results[] = 1274d8d81063Sfei feng - Sun Microsystems - Beijing China { "OK", "ERROR", "NOT_SUPPORT", "PENDING", "BUSY", 1275d8d81063Sfei feng - Sun Microsystems - Beijing China "PARTIAL_DATA" }; 1276d8d81063Sfei feng - Sun Microsystems - Beijing China int result = LE_16(h->Result); 1277d8d81063Sfei feng - Sun Microsystems - Beijing China 1278d8d81063Sfei feng - Sun Microsystems - Beijing China if (result <= HostCmd_RESULT_PARTIAL_DATA) 1279d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_CMD, "mwl: dumpresult(): " 1280d8d81063Sfei feng - Sun Microsystems - Beijing China "Result %s", results[result]); 1281d8d81063Sfei feng - Sun Microsystems - Beijing China else 1282d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_CMD, "mwl: dumpresult(): " 1283d8d81063Sfei feng - Sun Microsystems - Beijing China "Result %d", result); 1284d8d81063Sfei feng - Sun Microsystems - Beijing China } 1285d8d81063Sfei feng - Sun Microsystems - Beijing China } 1286d8d81063Sfei feng - Sun Microsystems - Beijing China 1287d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1288d8d81063Sfei feng - Sun Microsystems - Beijing China mwlGetCalTable(struct mwl_softc *sc, uint8_t annex, uint8_t index) 1289d8d81063Sfei feng - Sun Microsystems - Beijing China { 1290d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_FW_GET_CALTABLE *pCmd; 1291d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 1292d8d81063Sfei feng - Sun Microsystems - Beijing China 1293d8d81063Sfei feng - Sun Microsystems - Beijing China _CMD_SETUP(pCmd, HostCmd_FW_GET_CALTABLE, HostCmd_CMD_GET_CALTABLE); 1294d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->annex = annex; 1295d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->index = index; 1296cb2cd10cSfei feng - Sun Microsystems - Beijing China (void) memset(pCmd->calTbl, 0, sizeof (pCmd->calTbl)); 1297d8d81063Sfei feng - Sun Microsystems - Beijing China 1298d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_GET_CALTABLE); 1299d8d81063Sfei feng - Sun Microsystems - Beijing China if (retval == 0 && 1300d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->calTbl[0] != annex && annex != 0 && annex != 255) 1301d8d81063Sfei feng - Sun Microsystems - Beijing China retval = EIO; 1302d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 1303d8d81063Sfei feng - Sun Microsystems - Beijing China } 1304d8d81063Sfei feng - Sun Microsystems - Beijing China 1305d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1306d8d81063Sfei feng - Sun Microsystems - Beijing China * Construct channel info for 2.4GHz channels from cal data. 1307d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1308d8d81063Sfei feng - Sun Microsystems - Beijing China static void 1309d8d81063Sfei feng - Sun Microsystems - Beijing China get2Ghz(MWL_HAL_CHANNELINFO *ci, const uint8_t table[], int len) 1310d8d81063Sfei feng - Sun Microsystems - Beijing China { 1311d8d81063Sfei feng - Sun Microsystems - Beijing China int i, j; 1312d8d81063Sfei feng - Sun Microsystems - Beijing China 1313d8d81063Sfei feng - Sun Microsystems - Beijing China j = 0; 1314d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < len; i += 4) { 1315d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_hal_channel *hc = &ci->channels[j]; 1316d8d81063Sfei feng - Sun Microsystems - Beijing China hc->ieee = 1+j; 1317d8d81063Sfei feng - Sun Microsystems - Beijing China hc->freq = ieee2mhz(1+j); 1318d8d81063Sfei feng - Sun Microsystems - Beijing China (void) memcpy(hc->targetPowers, &table[i], 4); 1319d8d81063Sfei feng - Sun Microsystems - Beijing China setmaxtxpow(hc, 0, 4); 1320d8d81063Sfei feng - Sun Microsystems - Beijing China j++; 1321d8d81063Sfei feng - Sun Microsystems - Beijing China } 1322d8d81063Sfei feng - Sun Microsystems - Beijing China ci->nchannels = j; 1323d8d81063Sfei feng - Sun Microsystems - Beijing China ci->freqLow = ieee2mhz(1); 1324d8d81063Sfei feng - Sun Microsystems - Beijing China ci->freqHigh = ieee2mhz(j); 1325d8d81063Sfei feng - Sun Microsystems - Beijing China } 1326d8d81063Sfei feng - Sun Microsystems - Beijing China 1327d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1328d8d81063Sfei feng - Sun Microsystems - Beijing China * Construct channel info for 5GHz channels from cal data. 1329d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1330d8d81063Sfei feng - Sun Microsystems - Beijing China static void 1331d8d81063Sfei feng - Sun Microsystems - Beijing China get5Ghz(MWL_HAL_CHANNELINFO *ci, const uint8_t table[], int len) 1332d8d81063Sfei feng - Sun Microsystems - Beijing China { 1333d8d81063Sfei feng - Sun Microsystems - Beijing China int i, j, f, l, h; 1334d8d81063Sfei feng - Sun Microsystems - Beijing China 1335d8d81063Sfei feng - Sun Microsystems - Beijing China l = 32000; 1336d8d81063Sfei feng - Sun Microsystems - Beijing China h = 0; 1337d8d81063Sfei feng - Sun Microsystems - Beijing China j = 0; 1338d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < len; i += 4) { 1339d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_hal_channel *hc; 1340d8d81063Sfei feng - Sun Microsystems - Beijing China 1341d8d81063Sfei feng - Sun Microsystems - Beijing China if (table[i] == 0) 1342d8d81063Sfei feng - Sun Microsystems - Beijing China continue; 1343d8d81063Sfei feng - Sun Microsystems - Beijing China f = 5000 + 5*table[i]; 1344d8d81063Sfei feng - Sun Microsystems - Beijing China if (f < l) 1345d8d81063Sfei feng - Sun Microsystems - Beijing China l = f; 1346d8d81063Sfei feng - Sun Microsystems - Beijing China if (f > h) 1347d8d81063Sfei feng - Sun Microsystems - Beijing China h = f; 1348d8d81063Sfei feng - Sun Microsystems - Beijing China hc = &ci->channels[j]; 1349d8d81063Sfei feng - Sun Microsystems - Beijing China hc->freq = (uint16_t)f; 1350d8d81063Sfei feng - Sun Microsystems - Beijing China hc->ieee = table[i]; 1351d8d81063Sfei feng - Sun Microsystems - Beijing China (void) memcpy(hc->targetPowers, &table[i], 4); 1352d8d81063Sfei feng - Sun Microsystems - Beijing China setmaxtxpow(hc, 1, 4); /* NB: col 1 is the freq, skip */ 1353d8d81063Sfei feng - Sun Microsystems - Beijing China j++; 1354d8d81063Sfei feng - Sun Microsystems - Beijing China } 1355d8d81063Sfei feng - Sun Microsystems - Beijing China ci->nchannels = j; 1356d8d81063Sfei feng - Sun Microsystems - Beijing China ci->freqLow = (uint16_t)((l == 32000) ? 0 : l); 1357d8d81063Sfei feng - Sun Microsystems - Beijing China ci->freqHigh = (uint16_t)h; 1358d8d81063Sfei feng - Sun Microsystems - Beijing China } 1359d8d81063Sfei feng - Sun Microsystems - Beijing China 1360d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1361d8d81063Sfei feng - Sun Microsystems - Beijing China * Calculate the max tx power from the channel's cal data. 1362d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1363d8d81063Sfei feng - Sun Microsystems - Beijing China static void 1364d8d81063Sfei feng - Sun Microsystems - Beijing China setmaxtxpow(struct mwl_hal_channel *hc, int i, int maxix) 1365d8d81063Sfei feng - Sun Microsystems - Beijing China { 1366d8d81063Sfei feng - Sun Microsystems - Beijing China hc->maxTxPow = hc->targetPowers[i]; 1367d8d81063Sfei feng - Sun Microsystems - Beijing China for (i++; i < maxix; i++) 1368d8d81063Sfei feng - Sun Microsystems - Beijing China if (hc->targetPowers[i] > hc->maxTxPow) 1369d8d81063Sfei feng - Sun Microsystems - Beijing China hc->maxTxPow = hc->targetPowers[i]; 1370d8d81063Sfei feng - Sun Microsystems - Beijing China } 1371d8d81063Sfei feng - Sun Microsystems - Beijing China 1372d8d81063Sfei feng - Sun Microsystems - Beijing China static uint16_t 1373d8d81063Sfei feng - Sun Microsystems - Beijing China ieee2mhz(int chan) 1374d8d81063Sfei feng - Sun Microsystems - Beijing China { 1375d8d81063Sfei feng - Sun Microsystems - Beijing China if (chan == 14) 1376d8d81063Sfei feng - Sun Microsystems - Beijing China return (2484); 1377d8d81063Sfei feng - Sun Microsystems - Beijing China if (chan < 14) 1378d8d81063Sfei feng - Sun Microsystems - Beijing China return (2407 + chan * 5); 1379d8d81063Sfei feng - Sun Microsystems - Beijing China return (2512 + (chan - 15) * 20); 1380d8d81063Sfei feng - Sun Microsystems - Beijing China } 1381d8d81063Sfei feng - Sun Microsystems - Beijing China 1382d8d81063Sfei feng - Sun Microsystems - Beijing China static void 1383d8d81063Sfei feng - Sun Microsystems - Beijing China dumpcaldata(const char *name, const uint8_t *table, int n) 1384d8d81063Sfei feng - Sun Microsystems - Beijing China { 1385d8d81063Sfei feng - Sun Microsystems - Beijing China int i; 1386d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "\n%s:\n", name); 1387d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < n; i += 4) 1388d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "[%2d] %3d %3d %3d %3d\n", 1389d8d81063Sfei feng - Sun Microsystems - Beijing China i/4, table[i+0], table[i+1], table[i+2], table[i+3]); 1390d8d81063Sfei feng - Sun Microsystems - Beijing China } 1391d8d81063Sfei feng - Sun Microsystems - Beijing China 1392d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1393d8d81063Sfei feng - Sun Microsystems - Beijing China mwlGetPwrCalTable(struct mwl_softc *sc) 1394d8d81063Sfei feng - Sun Microsystems - Beijing China { 1395d8d81063Sfei feng - Sun Microsystems - Beijing China const uint8_t *data; 1396d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_HAL_CHANNELINFO *ci; 1397d8d81063Sfei feng - Sun Microsystems - Beijing China int len; 1398d8d81063Sfei feng - Sun Microsystems - Beijing China 1399d8d81063Sfei feng - Sun Microsystems - Beijing China /* NB: we hold the lock so it's ok to use cmdbuf */ 1400d8d81063Sfei feng - Sun Microsystems - Beijing China data = ((const HostCmd_FW_GET_CALTABLE *) sc->sc_cmd_mem)->calTbl; 1401d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwlGetCalTable(sc, 33, 0) == 0) { 1402d8d81063Sfei feng - Sun Microsystems - Beijing China len = (data[2] | (data[3] << 8)) - 12; 1403d8d81063Sfei feng - Sun Microsystems - Beijing China if (len > PWTAGETRATETABLE20M) 1404d8d81063Sfei feng - Sun Microsystems - Beijing China len = PWTAGETRATETABLE20M; 1405d8d81063Sfei feng - Sun Microsystems - Beijing China dumpcaldata("2.4G 20M", &data[12], len); 1406d8d81063Sfei feng - Sun Microsystems - Beijing China get2Ghz(&sc->sc_20M, &data[12], len); 1407d8d81063Sfei feng - Sun Microsystems - Beijing China } 1408d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwlGetCalTable(sc, 34, 0) == 0) { 1409d8d81063Sfei feng - Sun Microsystems - Beijing China len = (data[2] | (data[3] << 8)) - 12; 1410d8d81063Sfei feng - Sun Microsystems - Beijing China if (len > PWTAGETRATETABLE40M) 1411d8d81063Sfei feng - Sun Microsystems - Beijing China len = PWTAGETRATETABLE40M; 1412d8d81063Sfei feng - Sun Microsystems - Beijing China dumpcaldata("2.4G 40M", &data[12], len); 1413d8d81063Sfei feng - Sun Microsystems - Beijing China ci = &sc->sc_40M; 1414d8d81063Sfei feng - Sun Microsystems - Beijing China get2Ghz(ci, &data[12], len); 1415d8d81063Sfei feng - Sun Microsystems - Beijing China } 1416d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwlGetCalTable(sc, 35, 0) == 0) { 1417d8d81063Sfei feng - Sun Microsystems - Beijing China len = (data[2] | (data[3] << 8)) - 20; 1418d8d81063Sfei feng - Sun Microsystems - Beijing China if (len > PWTAGETRATETABLE20M_5G) 1419d8d81063Sfei feng - Sun Microsystems - Beijing China len = PWTAGETRATETABLE20M_5G; 1420d8d81063Sfei feng - Sun Microsystems - Beijing China dumpcaldata("5G 20M", &data[20], len); 1421d8d81063Sfei feng - Sun Microsystems - Beijing China get5Ghz(&sc->sc_20M_5G, &data[20], len); 1422d8d81063Sfei feng - Sun Microsystems - Beijing China } 1423d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwlGetCalTable(sc, 36, 0) == 0) { 1424d8d81063Sfei feng - Sun Microsystems - Beijing China len = (data[2] | (data[3] << 8)) - 20; 1425d8d81063Sfei feng - Sun Microsystems - Beijing China if (len > PWTAGETRATETABLE40M_5G) 1426d8d81063Sfei feng - Sun Microsystems - Beijing China len = PWTAGETRATETABLE40M_5G; 1427d8d81063Sfei feng - Sun Microsystems - Beijing China dumpcaldata("5G 40M", &data[20], len); 1428d8d81063Sfei feng - Sun Microsystems - Beijing China ci = &sc->sc_40M_5G; 1429d8d81063Sfei feng - Sun Microsystems - Beijing China get5Ghz(ci, &data[20], len); 1430d8d81063Sfei feng - Sun Microsystems - Beijing China } 1431d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_hw_flags |= MHF_CALDATA; 1432d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 1433d8d81063Sfei feng - Sun Microsystems - Beijing China } 1434d8d81063Sfei feng - Sun Microsystems - Beijing China 1435d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1436d8d81063Sfei feng - Sun Microsystems - Beijing China * Reset internal state after a firmware download. 1437d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1438d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1439d8d81063Sfei feng - Sun Microsystems - Beijing China mwlResetHalState(struct mwl_softc *sc) 1440d8d81063Sfei feng - Sun Microsystems - Beijing China { 1441d8d81063Sfei feng - Sun Microsystems - Beijing China int err = 0; 1442d8d81063Sfei feng - Sun Microsystems - Beijing China 1443d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1444d8d81063Sfei feng - Sun Microsystems - Beijing China * Fetch cal data for later use. 1445d8d81063Sfei feng - Sun Microsystems - Beijing China * XXX may want to fetch other stuff too. 1446d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1447d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX check return */ 1448d8d81063Sfei feng - Sun Microsystems - Beijing China if ((sc->sc_hw_flags & MHF_CALDATA) == 0) 1449d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwlGetPwrCalTable(sc); 1450d8d81063Sfei feng - Sun Microsystems - Beijing China return (err); 1451d8d81063Sfei feng - Sun Microsystems - Beijing China } 1452d8d81063Sfei feng - Sun Microsystems - Beijing China 1453d8d81063Sfei feng - Sun Microsystems - Beijing China #define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT|IEEE80211_CHAN_G) 1454d8d81063Sfei feng - Sun Microsystems - Beijing China #define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT|IEEE80211_CHAN_A) 1455d8d81063Sfei feng - Sun Microsystems - Beijing China 1456d8d81063Sfei feng - Sun Microsystems - Beijing China static void 1457d8d81063Sfei feng - Sun Microsystems - Beijing China addchan(struct mwl_channel *c, int freq, int flags, int ieee, int txpow) 1458d8d81063Sfei feng - Sun Microsystems - Beijing China { 1459d8d81063Sfei feng - Sun Microsystems - Beijing China c->ic_freq = (uint16_t)freq; 1460d8d81063Sfei feng - Sun Microsystems - Beijing China c->ic_flags = flags; 1461d8d81063Sfei feng - Sun Microsystems - Beijing China c->ic_ieee = (uint8_t)ieee; 1462d8d81063Sfei feng - Sun Microsystems - Beijing China c->ic_minpower = 0; 1463d8d81063Sfei feng - Sun Microsystems - Beijing China c->ic_maxpower = 2*txpow; 1464d8d81063Sfei feng - Sun Microsystems - Beijing China c->ic_maxregpower = (uint8_t)txpow; 1465d8d81063Sfei feng - Sun Microsystems - Beijing China } 1466d8d81063Sfei feng - Sun Microsystems - Beijing China 1467d8d81063Sfei feng - Sun Microsystems - Beijing China static const struct mwl_channel * 1468d8d81063Sfei feng - Sun Microsystems - Beijing China findchannel(const struct mwl_channel chans[], int nchans, 1469d8d81063Sfei feng - Sun Microsystems - Beijing China int freq, int flags) 1470d8d81063Sfei feng - Sun Microsystems - Beijing China { 1471d8d81063Sfei feng - Sun Microsystems - Beijing China const struct mwl_channel *c; 1472d8d81063Sfei feng - Sun Microsystems - Beijing China int i; 1473d8d81063Sfei feng - Sun Microsystems - Beijing China 1474d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < nchans; i++) { 1475d8d81063Sfei feng - Sun Microsystems - Beijing China c = &chans[i]; 1476d8d81063Sfei feng - Sun Microsystems - Beijing China if (c->ic_freq == freq && c->ic_flags == flags) 1477d8d81063Sfei feng - Sun Microsystems - Beijing China return (c); 1478d8d81063Sfei feng - Sun Microsystems - Beijing China } 1479d8d81063Sfei feng - Sun Microsystems - Beijing China return (NULL); 1480d8d81063Sfei feng - Sun Microsystems - Beijing China } 1481d8d81063Sfei feng - Sun Microsystems - Beijing China 1482d8d81063Sfei feng - Sun Microsystems - Beijing China static void 1483d8d81063Sfei feng - Sun Microsystems - Beijing China addht40channels(struct mwl_channel chans[], int maxchans, int *nchans, 1484d8d81063Sfei feng - Sun Microsystems - Beijing China const MWL_HAL_CHANNELINFO *ci, int flags) 1485d8d81063Sfei feng - Sun Microsystems - Beijing China { 1486d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_channel *c; 1487d8d81063Sfei feng - Sun Microsystems - Beijing China const struct mwl_channel *extc; 1488d8d81063Sfei feng - Sun Microsystems - Beijing China const struct mwl_hal_channel *hc; 1489d8d81063Sfei feng - Sun Microsystems - Beijing China int i; 1490d8d81063Sfei feng - Sun Microsystems - Beijing China 1491d8d81063Sfei feng - Sun Microsystems - Beijing China c = &chans[*nchans]; 1492d8d81063Sfei feng - Sun Microsystems - Beijing China 1493d8d81063Sfei feng - Sun Microsystems - Beijing China flags &= ~IEEE80211_CHAN_HT; 1494d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < ci->nchannels; i++) { 1495d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1496d8d81063Sfei feng - Sun Microsystems - Beijing China * Each entry defines an HT40 channel pair; find the 1497d8d81063Sfei feng - Sun Microsystems - Beijing China * extension channel above and the insert the pair. 1498d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1499d8d81063Sfei feng - Sun Microsystems - Beijing China hc = &ci->channels[i]; 1500d8d81063Sfei feng - Sun Microsystems - Beijing China extc = findchannel(chans, *nchans, hc->freq+20, 1501d8d81063Sfei feng - Sun Microsystems - Beijing China flags | IEEE80211_CHAN_HT20); 1502d8d81063Sfei feng - Sun Microsystems - Beijing China if (extc != NULL) { 1503d8d81063Sfei feng - Sun Microsystems - Beijing China if (*nchans >= maxchans) 1504d8d81063Sfei feng - Sun Microsystems - Beijing China break; 1505d8d81063Sfei feng - Sun Microsystems - Beijing China addchan(c, hc->freq, flags | IEEE80211_CHAN_HT40U, 1506d8d81063Sfei feng - Sun Microsystems - Beijing China hc->ieee, hc->maxTxPow); 1507d8d81063Sfei feng - Sun Microsystems - Beijing China c->ic_extieee = extc->ic_ieee; 1508d8d81063Sfei feng - Sun Microsystems - Beijing China c++, (*nchans)++; 1509d8d81063Sfei feng - Sun Microsystems - Beijing China if (*nchans >= maxchans) 1510d8d81063Sfei feng - Sun Microsystems - Beijing China break; 1511d8d81063Sfei feng - Sun Microsystems - Beijing China addchan(c, extc->ic_freq, flags | IEEE80211_CHAN_HT40D, 1512d8d81063Sfei feng - Sun Microsystems - Beijing China extc->ic_ieee, hc->maxTxPow); 1513d8d81063Sfei feng - Sun Microsystems - Beijing China c->ic_extieee = hc->ieee; 1514d8d81063Sfei feng - Sun Microsystems - Beijing China c++, (*nchans)++; 1515d8d81063Sfei feng - Sun Microsystems - Beijing China } 1516d8d81063Sfei feng - Sun Microsystems - Beijing China } 1517d8d81063Sfei feng - Sun Microsystems - Beijing China } 1518d8d81063Sfei feng - Sun Microsystems - Beijing China 1519d8d81063Sfei feng - Sun Microsystems - Beijing China static void 1520d8d81063Sfei feng - Sun Microsystems - Beijing China addchannels(struct mwl_channel chans[], int maxchans, int *nchans, 1521d8d81063Sfei feng - Sun Microsystems - Beijing China const MWL_HAL_CHANNELINFO *ci, int flags) 1522d8d81063Sfei feng - Sun Microsystems - Beijing China { 1523d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_channel *c; 1524d8d81063Sfei feng - Sun Microsystems - Beijing China int i; 1525d8d81063Sfei feng - Sun Microsystems - Beijing China 1526d8d81063Sfei feng - Sun Microsystems - Beijing China c = &chans[*nchans]; 1527d8d81063Sfei feng - Sun Microsystems - Beijing China 1528d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < ci->nchannels; i++) { 1529d8d81063Sfei feng - Sun Microsystems - Beijing China const struct mwl_hal_channel *hc; 1530d8d81063Sfei feng - Sun Microsystems - Beijing China 1531d8d81063Sfei feng - Sun Microsystems - Beijing China hc = &ci->channels[i]; 1532d8d81063Sfei feng - Sun Microsystems - Beijing China if (*nchans >= maxchans) 1533d8d81063Sfei feng - Sun Microsystems - Beijing China break; 1534d8d81063Sfei feng - Sun Microsystems - Beijing China addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 1535d8d81063Sfei feng - Sun Microsystems - Beijing China c++, (*nchans)++; 1536d8d81063Sfei feng - Sun Microsystems - Beijing China 1537d8d81063Sfei feng - Sun Microsystems - Beijing China if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 1538d8d81063Sfei feng - Sun Microsystems - Beijing China /* g channel have a separate b-only entry */ 1539d8d81063Sfei feng - Sun Microsystems - Beijing China if (*nchans >= maxchans) 1540d8d81063Sfei feng - Sun Microsystems - Beijing China break; 1541d8d81063Sfei feng - Sun Microsystems - Beijing China c[0] = c[-1]; 1542d8d81063Sfei feng - Sun Microsystems - Beijing China c[-1].ic_flags = IEEE80211_CHAN_B; 1543d8d81063Sfei feng - Sun Microsystems - Beijing China c++, (*nchans)++; 1544d8d81063Sfei feng - Sun Microsystems - Beijing China } 1545d8d81063Sfei feng - Sun Microsystems - Beijing China if (flags == IEEE80211_CHAN_HTG) { 1546d8d81063Sfei feng - Sun Microsystems - Beijing China /* HT g channel have a separate g-only entry */ 1547d8d81063Sfei feng - Sun Microsystems - Beijing China if (*nchans >= maxchans) 1548d8d81063Sfei feng - Sun Microsystems - Beijing China break; 1549d8d81063Sfei feng - Sun Microsystems - Beijing China c[-1].ic_flags = IEEE80211_CHAN_G; 1550d8d81063Sfei feng - Sun Microsystems - Beijing China c[0] = c[-1]; 1551d8d81063Sfei feng - Sun Microsystems - Beijing China c[0].ic_flags &= ~IEEE80211_CHAN_HT; 1552d8d81063Sfei feng - Sun Microsystems - Beijing China c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 1553d8d81063Sfei feng - Sun Microsystems - Beijing China c++, (*nchans)++; 1554d8d81063Sfei feng - Sun Microsystems - Beijing China } 1555d8d81063Sfei feng - Sun Microsystems - Beijing China if (flags == IEEE80211_CHAN_HTA) { 1556d8d81063Sfei feng - Sun Microsystems - Beijing China /* HT a channel have a separate a-only entry */ 1557d8d81063Sfei feng - Sun Microsystems - Beijing China if (*nchans >= maxchans) 1558d8d81063Sfei feng - Sun Microsystems - Beijing China break; 1559d8d81063Sfei feng - Sun Microsystems - Beijing China c[-1].ic_flags = IEEE80211_CHAN_A; 1560d8d81063Sfei feng - Sun Microsystems - Beijing China c[0] = c[-1]; 1561d8d81063Sfei feng - Sun Microsystems - Beijing China c[0].ic_flags &= ~IEEE80211_CHAN_HT; 1562d8d81063Sfei feng - Sun Microsystems - Beijing China c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 1563d8d81063Sfei feng - Sun Microsystems - Beijing China c++, (*nchans)++; 1564d8d81063Sfei feng - Sun Microsystems - Beijing China } 1565d8d81063Sfei feng - Sun Microsystems - Beijing China } 1566d8d81063Sfei feng - Sun Microsystems - Beijing China } 1567d8d81063Sfei feng - Sun Microsystems - Beijing China 1568d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1569d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_getchannelinfo(struct mwl_softc *sc, int band, int chw, 1570d8d81063Sfei feng - Sun Microsystems - Beijing China const MWL_HAL_CHANNELINFO **ci) 1571d8d81063Sfei feng - Sun Microsystems - Beijing China { 1572d8d81063Sfei feng - Sun Microsystems - Beijing China switch (band) { 1573d8d81063Sfei feng - Sun Microsystems - Beijing China case MWL_FREQ_BAND_2DOT4GHZ: 1574d8d81063Sfei feng - Sun Microsystems - Beijing China *ci = (chw == MWL_CH_20_MHz_WIDTH) ? &sc->sc_20M : &sc->sc_40M; 1575d8d81063Sfei feng - Sun Microsystems - Beijing China break; 1576d8d81063Sfei feng - Sun Microsystems - Beijing China case MWL_FREQ_BAND_5GHZ: 1577d8d81063Sfei feng - Sun Microsystems - Beijing China *ci = (chw == MWL_CH_20_MHz_WIDTH) ? 1578d8d81063Sfei feng - Sun Microsystems - Beijing China &sc->sc_20M_5G : &sc->sc_40M_5G; 1579d8d81063Sfei feng - Sun Microsystems - Beijing China break; 1580d8d81063Sfei feng - Sun Microsystems - Beijing China default: 1581d8d81063Sfei feng - Sun Microsystems - Beijing China return (EINVAL); 1582d8d81063Sfei feng - Sun Microsystems - Beijing China } 1583d8d81063Sfei feng - Sun Microsystems - Beijing China return (((*ci)->freqLow == (*ci)->freqHigh) ? EINVAL : 0); 1584d8d81063Sfei feng - Sun Microsystems - Beijing China } 1585d8d81063Sfei feng - Sun Microsystems - Beijing China 1586d8d81063Sfei feng - Sun Microsystems - Beijing China static void 1587d8d81063Sfei feng - Sun Microsystems - Beijing China getchannels(struct mwl_softc *sc, int maxchans, int *nchans, 1588d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_channel chans[]) 1589d8d81063Sfei feng - Sun Microsystems - Beijing China { 1590d8d81063Sfei feng - Sun Microsystems - Beijing China const MWL_HAL_CHANNELINFO *ci; 1591d8d81063Sfei feng - Sun Microsystems - Beijing China 1592d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1593d8d81063Sfei feng - Sun Microsystems - Beijing China * Use the channel info from the hal to craft the 1594d8d81063Sfei feng - Sun Microsystems - Beijing China * channel list. Note that we pass back an unsorted 1595d8d81063Sfei feng - Sun Microsystems - Beijing China * list; the caller is required to sort it for us 1596d8d81063Sfei feng - Sun Microsystems - Beijing China * (if desired). 1597d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1598d8d81063Sfei feng - Sun Microsystems - Beijing China *nchans = 0; 1599d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwl_hal_getchannelinfo(sc, 1600d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_FREQ_BAND_2DOT4GHZ, MWL_CH_20_MHz_WIDTH, &ci) == 0) 1601d8d81063Sfei feng - Sun Microsystems - Beijing China addchannels(chans, maxchans, nchans, ci, IEEE80211_CHAN_HTG); 1602d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwl_hal_getchannelinfo(sc, 1603d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_FREQ_BAND_5GHZ, MWL_CH_20_MHz_WIDTH, &ci) == 0) 1604d8d81063Sfei feng - Sun Microsystems - Beijing China addchannels(chans, maxchans, nchans, ci, IEEE80211_CHAN_HTA); 1605d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwl_hal_getchannelinfo(sc, 1606d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_FREQ_BAND_2DOT4GHZ, MWL_CH_40_MHz_WIDTH, &ci) == 0) 1607d8d81063Sfei feng - Sun Microsystems - Beijing China addht40channels(chans, maxchans, nchans, ci, 1608d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_CHAN_HTG); 1609d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwl_hal_getchannelinfo(sc, 1610d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_FREQ_BAND_5GHZ, MWL_CH_40_MHz_WIDTH, &ci) == 0) 1611d8d81063Sfei feng - Sun Microsystems - Beijing China addht40channels(chans, maxchans, nchans, ci, 1612d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_CHAN_HTA); 1613d8d81063Sfei feng - Sun Microsystems - Beijing China } 1614d8d81063Sfei feng - Sun Microsystems - Beijing China 1615d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1616d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_getchannels(struct mwl_softc *sc) 1617d8d81063Sfei feng - Sun Microsystems - Beijing China { 1618d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1619d8d81063Sfei feng - Sun Microsystems - Beijing China * Use the channel info from the hal to craft the 1620d8d81063Sfei feng - Sun Microsystems - Beijing China * channel list for net80211. Note that we pass up 1621d8d81063Sfei feng - Sun Microsystems - Beijing China * an unsorted list; net80211 will sort it for us. 1622d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1623cb2cd10cSfei feng - Sun Microsystems - Beijing China (void) memset(sc->sc_channels, 0, sizeof (sc->sc_channels)); 1624d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_nchans = 0; 1625d8d81063Sfei feng - Sun Microsystems - Beijing China getchannels(sc, IEEE80211_CHAN_MAX, &sc->sc_nchans, sc->sc_channels); 1626d8d81063Sfei feng - Sun Microsystems - Beijing China 1627d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_regdomain.regdomain = SKU_DEBUG; 1628d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_regdomain.country = CTRY_DEFAULT; 1629d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_regdomain.location = 'I'; 1630d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_regdomain.isocc[0] = ' '; /* XXX? */ 1631d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_regdomain.isocc[1] = ' '; 1632d8d81063Sfei feng - Sun Microsystems - Beijing China return (sc->sc_nchans == 0 ? EIO : 0); 1633d8d81063Sfei feng - Sun Microsystems - Beijing China } 1634d8d81063Sfei feng - Sun Microsystems - Beijing China 1635d8d81063Sfei feng - Sun Microsystems - Beijing China #undef IEEE80211_CHAN_HTA 1636d8d81063Sfei feng - Sun Microsystems - Beijing China #undef IEEE80211_CHAN_HTG 1637d8d81063Sfei feng - Sun Microsystems - Beijing China 1638d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1639d8d81063Sfei feng - Sun Microsystems - Beijing China * Return "hw specs". Note this must be the first 1640d8d81063Sfei feng - Sun Microsystems - Beijing China * cmd MUST be done after a firmware download or the 1641d8d81063Sfei feng - Sun Microsystems - Beijing China * f/w will lockup. 1642d8d81063Sfei feng - Sun Microsystems - Beijing China * XXX move into the hal so driver doesn't need to be responsible 1643d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1644d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1645d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_gethwspecs(struct mwl_softc *sc) 1646d8d81063Sfei feng - Sun Microsystems - Beijing China { 1647d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_hal_hwspec *hw; 1648d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_DS_GET_HW_SPEC *pCmd; 1649d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 1650d8d81063Sfei feng - Sun Microsystems - Beijing China 1651d8d81063Sfei feng - Sun Microsystems - Beijing China hw = &sc->sc_hwspecs; 1652d8d81063Sfei feng - Sun Microsystems - Beijing China _CMD_SETUP(pCmd, HostCmd_DS_GET_HW_SPEC, HostCmd_CMD_GET_HW_SPEC); 1653cb2cd10cSfei feng - Sun Microsystems - Beijing China (void) memset(&pCmd->PermanentAddr[0], 0xff, IEEE80211_ADDR_LEN); 1654d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->ulFwAwakeCookie = LE_32((unsigned int)sc->sc_cmd_dmaaddr + 2048); 1655d8d81063Sfei feng - Sun Microsystems - Beijing China 1656d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_GET_HW_SPEC); 1657d8d81063Sfei feng - Sun Microsystems - Beijing China if (retval == 0) { 1658d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(hw->macAddr, pCmd->PermanentAddr); 1659d8d81063Sfei feng - Sun Microsystems - Beijing China hw->wcbBase[0] = LE_32(pCmd->WcbBase0) & 0x0000ffff; 1660d8d81063Sfei feng - Sun Microsystems - Beijing China hw->wcbBase[1] = LE_32(pCmd->WcbBase1[0]) & 0x0000ffff; 1661d8d81063Sfei feng - Sun Microsystems - Beijing China hw->wcbBase[2] = LE_32(pCmd->WcbBase1[1]) & 0x0000ffff; 1662d8d81063Sfei feng - Sun Microsystems - Beijing China hw->wcbBase[3] = LE_32(pCmd->WcbBase1[2]) & 0x0000ffff; 1663d8d81063Sfei feng - Sun Microsystems - Beijing China hw->rxDescRead = LE_32(pCmd->RxPdRdPtr)& 0x0000ffff; 1664d8d81063Sfei feng - Sun Microsystems - Beijing China hw->rxDescWrite = LE_32(pCmd->RxPdWrPtr)& 0x0000ffff; 1665d8d81063Sfei feng - Sun Microsystems - Beijing China hw->regionCode = LE_16(pCmd->RegionCode) & 0x00ff; 1666d8d81063Sfei feng - Sun Microsystems - Beijing China hw->fwReleaseNumber = LE_32(pCmd->FWReleaseNumber); 1667d8d81063Sfei feng - Sun Microsystems - Beijing China hw->maxNumWCB = LE_16(pCmd->NumOfWCB); 1668d8d81063Sfei feng - Sun Microsystems - Beijing China hw->maxNumMCAddr = LE_16(pCmd->NumOfMCastAddr); 1669d8d81063Sfei feng - Sun Microsystems - Beijing China hw->numAntennas = LE_16(pCmd->NumberOfAntenna); 1670d8d81063Sfei feng - Sun Microsystems - Beijing China hw->hwVersion = pCmd->Version; 1671d8d81063Sfei feng - Sun Microsystems - Beijing China hw->hostInterface = pCmd->HostIf; 1672d8d81063Sfei feng - Sun Microsystems - Beijing China 1673d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_revs.mh_macRev = hw->hwVersion; /* XXX */ 1674d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_revs.mh_phyRev = hw->hostInterface; /* XXX */ 1675d8d81063Sfei feng - Sun Microsystems - Beijing China } 1676d8d81063Sfei feng - Sun Microsystems - Beijing China 1677d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 1678d8d81063Sfei feng - Sun Microsystems - Beijing China } 1679d8d81063Sfei feng - Sun Microsystems - Beijing China 1680d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1681d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_setmac_locked(struct mwl_softc *sc, 1682d8d81063Sfei feng - Sun Microsystems - Beijing China const uint8_t addr[IEEE80211_ADDR_LEN]) 1683d8d81063Sfei feng - Sun Microsystems - Beijing China { 1684d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_DS_SET_MAC *pCmd; 1685d8d81063Sfei feng - Sun Microsystems - Beijing China 1686d8d81063Sfei feng - Sun Microsystems - Beijing China _VCMD_SETUP(pCmd, HostCmd_DS_SET_MAC, HostCmd_CMD_SET_MAC_ADDR); 1687d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(&pCmd->MacAddr[0], addr); 1688d8d81063Sfei feng - Sun Microsystems - Beijing China #ifdef MWL_MBSS_SUPPORT 1689d8d81063Sfei feng - Sun Microsystems - Beijing China /* NB: already byte swapped */ 1690d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->MacType = WL_MAC_TYPE_PRIMARY_CLIENT; 1691d8d81063Sfei feng - Sun Microsystems - Beijing China #endif 1692d8d81063Sfei feng - Sun Microsystems - Beijing China return (mwlExecuteCmd(sc, HostCmd_CMD_SET_MAC_ADDR)); 1693d8d81063Sfei feng - Sun Microsystems - Beijing China } 1694d8d81063Sfei feng - Sun Microsystems - Beijing China 1695d8d81063Sfei feng - Sun Microsystems - Beijing China static void 1696d8d81063Sfei feng - Sun Microsystems - Beijing China cvtPeerInfo(PeerInfo_t *to, const MWL_HAL_PEERINFO *from) 1697d8d81063Sfei feng - Sun Microsystems - Beijing China { 1698d8d81063Sfei feng - Sun Microsystems - Beijing China to->LegacyRateBitMap = LE_32(from->LegacyRateBitMap); 1699d8d81063Sfei feng - Sun Microsystems - Beijing China to->HTRateBitMap = LE_32(from->HTRateBitMap); 1700d8d81063Sfei feng - Sun Microsystems - Beijing China to->CapInfo = LE_16(from->CapInfo); 1701d8d81063Sfei feng - Sun Microsystems - Beijing China to->HTCapabilitiesInfo = LE_16(from->HTCapabilitiesInfo); 1702d8d81063Sfei feng - Sun Microsystems - Beijing China to->MacHTParamInfo = from->MacHTParamInfo; 1703d8d81063Sfei feng - Sun Microsystems - Beijing China to->AddHtInfo.ControlChan = from->AddHtInfo.ControlChan; 1704d8d81063Sfei feng - Sun Microsystems - Beijing China to->AddHtInfo.AddChan = from->AddHtInfo.AddChan; 1705d8d81063Sfei feng - Sun Microsystems - Beijing China to->AddHtInfo.OpMode = LE_16(from->AddHtInfo.OpMode); 1706d8d81063Sfei feng - Sun Microsystems - Beijing China to->AddHtInfo.stbc = LE_16(from->AddHtInfo.stbc); 1707d8d81063Sfei feng - Sun Microsystems - Beijing China } 1708d8d81063Sfei feng - Sun Microsystems - Beijing China 1709d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX station id must be in [0..63] */ 1710d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1711d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_newstation(struct mwl_softc *sc, 1712d8d81063Sfei feng - Sun Microsystems - Beijing China const uint8_t addr[IEEE80211_ADDR_LEN], uint16_t aid, uint16_t sid, 1713d8d81063Sfei feng - Sun Microsystems - Beijing China const MWL_HAL_PEERINFO *peer, int isQosSta, int wmeInfo) 1714d8d81063Sfei feng - Sun Microsystems - Beijing China { 1715d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_FW_SET_NEW_STN *pCmd; 1716d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 1717d8d81063Sfei feng - Sun Microsystems - Beijing China 1718d8d81063Sfei feng - Sun Microsystems - Beijing China _VCMD_SETUP(pCmd, HostCmd_FW_SET_NEW_STN, HostCmd_CMD_SET_NEW_STN); 1719d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->AID = LE_16(aid); 1720d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->StnId = LE_16(sid); 1721d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Action = LE_16(0); /* SET */ 1722d8d81063Sfei feng - Sun Microsystems - Beijing China if (peer != NULL) { 1723d8d81063Sfei feng - Sun Microsystems - Beijing China /* NB: must fix up byte order */ 1724d8d81063Sfei feng - Sun Microsystems - Beijing China cvtPeerInfo(&pCmd->PeerInfo, peer); 1725d8d81063Sfei feng - Sun Microsystems - Beijing China } 1726d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(&pCmd->MacAddr[0], addr); 1727d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Qosinfo = (uint8_t)wmeInfo; 1728d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->isQosSta = (isQosSta != 0); 1729d8d81063Sfei feng - Sun Microsystems - Beijing China 1730d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: mwl_hal_newstation(): " 1731d8d81063Sfei feng - Sun Microsystems - Beijing China "LegacyRateBitMap %x, CapInfo %x\n", 1732d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->PeerInfo.LegacyRateBitMap, pCmd->PeerInfo.CapInfo); 1733d8d81063Sfei feng - Sun Microsystems - Beijing China 1734d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_SET_NEW_STN); 1735d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 1736d8d81063Sfei feng - Sun Microsystems - Beijing China } 1737d8d81063Sfei feng - Sun Microsystems - Beijing China 1738d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1739d8d81063Sfei feng - Sun Microsystems - Beijing China * Configure antenna use. 1740d8d81063Sfei feng - Sun Microsystems - Beijing China * Takes effect immediately. 1741d8d81063Sfei feng - Sun Microsystems - Beijing China * XXX tx antenna setting ignored 1742d8d81063Sfei feng - Sun Microsystems - Beijing China * XXX rx antenna setting should always be 3 (for now) 1743d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1744d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1745d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_setantenna(struct mwl_softc *sc, MWL_HAL_ANTENNA dirSet, int ant) 1746d8d81063Sfei feng - Sun Microsystems - Beijing China { 1747d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_DS_802_11_RF_ANTENNA *pCmd; 1748d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 1749d8d81063Sfei feng - Sun Microsystems - Beijing China 1750d8d81063Sfei feng - Sun Microsystems - Beijing China if (!(dirSet == WL_ANTENNATYPE_RX || dirSet == WL_ANTENNATYPE_TX)) 1751d8d81063Sfei feng - Sun Microsystems - Beijing China return (EINVAL); 1752d8d81063Sfei feng - Sun Microsystems - Beijing China 1753d8d81063Sfei feng - Sun Microsystems - Beijing China _CMD_SETUP(pCmd, HostCmd_DS_802_11_RF_ANTENNA, 1754d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_CMD_802_11_RF_ANTENNA); 1755d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Action = LE_16(dirSet); 1756d8d81063Sfei feng - Sun Microsystems - Beijing China if (ant == 0) /* default to all/both antennae */ 1757d8d81063Sfei feng - Sun Microsystems - Beijing China ant = 3; 1758d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->AntennaMode = LE_16(ant); 1759d8d81063Sfei feng - Sun Microsystems - Beijing China 1760d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_802_11_RF_ANTENNA); 1761d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 1762d8d81063Sfei feng - Sun Microsystems - Beijing China } 1763d8d81063Sfei feng - Sun Microsystems - Beijing China 1764d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1765d8d81063Sfei feng - Sun Microsystems - Beijing China * Configure radio. 1766d8d81063Sfei feng - Sun Microsystems - Beijing China * Takes effect immediately. 1767d8d81063Sfei feng - Sun Microsystems - Beijing China * XXX preamble installed after set fixed rate cmd 1768d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1769d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1770d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_setradio(struct mwl_softc *sc, int onoff, MWL_HAL_PREAMBLE preamble) 1771d8d81063Sfei feng - Sun Microsystems - Beijing China { 1772d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_DS_802_11_RADIO_CONTROL *pCmd; 1773d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 1774d8d81063Sfei feng - Sun Microsystems - Beijing China 1775d8d81063Sfei feng - Sun Microsystems - Beijing China _CMD_SETUP(pCmd, HostCmd_DS_802_11_RADIO_CONTROL, 1776d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_CMD_802_11_RADIO_CONTROL); 1777d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Action = LE_16(HostCmd_ACT_GEN_SET); 1778d8d81063Sfei feng - Sun Microsystems - Beijing China if (onoff == 0) 1779d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Control = 0; 1780d8d81063Sfei feng - Sun Microsystems - Beijing China else 1781d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Control = LE_16(preamble); 1782d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->RadioOn = LE_16(onoff); 1783d8d81063Sfei feng - Sun Microsystems - Beijing China 1784d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_802_11_RADIO_CONTROL); 1785d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 1786d8d81063Sfei feng - Sun Microsystems - Beijing China } 1787d8d81063Sfei feng - Sun Microsystems - Beijing China 1788d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1789d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_setwmm(struct mwl_softc *sc, int onoff) 1790d8d81063Sfei feng - Sun Microsystems - Beijing China { 1791d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_FW_SetWMMMode *pCmd; 1792d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 1793d8d81063Sfei feng - Sun Microsystems - Beijing China 1794d8d81063Sfei feng - Sun Microsystems - Beijing China _CMD_SETUP(pCmd, HostCmd_FW_SetWMMMode, 1795d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_CMD_SET_WMM_MODE); 1796d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Action = LE_16(onoff); 1797d8d81063Sfei feng - Sun Microsystems - Beijing China 1798d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_SET_WMM_MODE); 1799d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 1800d8d81063Sfei feng - Sun Microsystems - Beijing China } 1801d8d81063Sfei feng - Sun Microsystems - Beijing China 1802d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1803d8d81063Sfei feng - Sun Microsystems - Beijing China * Convert public channel flags definition to a 1804d8d81063Sfei feng - Sun Microsystems - Beijing China * value suitable for feeding to the firmware. 1805d8d81063Sfei feng - Sun Microsystems - Beijing China * Note this includes byte swapping. 1806d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1807d8d81063Sfei feng - Sun Microsystems - Beijing China static uint32_t 1808d8d81063Sfei feng - Sun Microsystems - Beijing China cvtChannelFlags(const MWL_HAL_CHANNEL *chan) 1809d8d81063Sfei feng - Sun Microsystems - Beijing China { 1810d8d81063Sfei feng - Sun Microsystems - Beijing China uint32_t w; 1811d8d81063Sfei feng - Sun Microsystems - Beijing China 1812d8d81063Sfei feng - Sun Microsystems - Beijing China /* 1813d8d81063Sfei feng - Sun Microsystems - Beijing China * NB: f/w only understands FREQ_BAND_5GHZ, supplying the more 1814d8d81063Sfei feng - Sun Microsystems - Beijing China * precise band info causes it to lockup (sometimes). 1815d8d81063Sfei feng - Sun Microsystems - Beijing China */ 1816d8d81063Sfei feng - Sun Microsystems - Beijing China w = (chan->channelFlags.FreqBand == MWL_FREQ_BAND_2DOT4GHZ) ? 1817d8d81063Sfei feng - Sun Microsystems - Beijing China FREQ_BAND_2DOT4GHZ : FREQ_BAND_5GHZ; 1818d8d81063Sfei feng - Sun Microsystems - Beijing China switch (chan->channelFlags.ChnlWidth) { 1819d8d81063Sfei feng - Sun Microsystems - Beijing China case MWL_CH_10_MHz_WIDTH: 1820d8d81063Sfei feng - Sun Microsystems - Beijing China w |= CH_10_MHz_WIDTH; 1821d8d81063Sfei feng - Sun Microsystems - Beijing China break; 1822d8d81063Sfei feng - Sun Microsystems - Beijing China case MWL_CH_20_MHz_WIDTH: 1823d8d81063Sfei feng - Sun Microsystems - Beijing China w |= CH_20_MHz_WIDTH; 1824d8d81063Sfei feng - Sun Microsystems - Beijing China break; 1825d8d81063Sfei feng - Sun Microsystems - Beijing China case MWL_CH_40_MHz_WIDTH: 1826d8d81063Sfei feng - Sun Microsystems - Beijing China default: 1827d8d81063Sfei feng - Sun Microsystems - Beijing China w |= CH_40_MHz_WIDTH; 1828d8d81063Sfei feng - Sun Microsystems - Beijing China break; 1829d8d81063Sfei feng - Sun Microsystems - Beijing China } 1830d8d81063Sfei feng - Sun Microsystems - Beijing China switch (chan->channelFlags.ExtChnlOffset) { 1831d8d81063Sfei feng - Sun Microsystems - Beijing China case MWL_EXT_CH_NONE: 1832d8d81063Sfei feng - Sun Microsystems - Beijing China w |= EXT_CH_NONE; 1833d8d81063Sfei feng - Sun Microsystems - Beijing China break; 1834d8d81063Sfei feng - Sun Microsystems - Beijing China case MWL_EXT_CH_ABOVE_CTRL_CH: 1835d8d81063Sfei feng - Sun Microsystems - Beijing China w |= EXT_CH_ABOVE_CTRL_CH; 1836d8d81063Sfei feng - Sun Microsystems - Beijing China break; 1837d8d81063Sfei feng - Sun Microsystems - Beijing China case MWL_EXT_CH_BELOW_CTRL_CH: 1838d8d81063Sfei feng - Sun Microsystems - Beijing China w |= EXT_CH_BELOW_CTRL_CH; 1839d8d81063Sfei feng - Sun Microsystems - Beijing China break; 1840d8d81063Sfei feng - Sun Microsystems - Beijing China } 1841d8d81063Sfei feng - Sun Microsystems - Beijing China return (LE_32(w)); 1842d8d81063Sfei feng - Sun Microsystems - Beijing China } 1843d8d81063Sfei feng - Sun Microsystems - Beijing China 1844d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1845d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_setchannel(struct mwl_softc *sc, const MWL_HAL_CHANNEL *chan) 1846d8d81063Sfei feng - Sun Microsystems - Beijing China { 1847d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_FW_SET_RF_CHANNEL *pCmd; 1848d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 1849d8d81063Sfei feng - Sun Microsystems - Beijing China 1850d8d81063Sfei feng - Sun Microsystems - Beijing China _CMD_SETUP(pCmd, HostCmd_FW_SET_RF_CHANNEL, HostCmd_CMD_SET_RF_CHANNEL); 1851d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Action = LE_16(HostCmd_ACT_GEN_SET); 1852d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->CurrentChannel = chan->channel; 1853d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->ChannelFlags = cvtChannelFlags(chan); /* NB: byte-swapped */ 1854d8d81063Sfei feng - Sun Microsystems - Beijing China 1855d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_SET_RF_CHANNEL); 1856d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 1857d8d81063Sfei feng - Sun Microsystems - Beijing China } 1858d8d81063Sfei feng - Sun Microsystems - Beijing China 1859d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1860d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_settxpower(struct mwl_softc *sc, 1861d8d81063Sfei feng - Sun Microsystems - Beijing China const MWL_HAL_CHANNEL *c, uint8_t maxtxpow) 1862d8d81063Sfei feng - Sun Microsystems - Beijing China { 1863d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_DS_802_11_RF_TX_POWER *pCmd; 1864d8d81063Sfei feng - Sun Microsystems - Beijing China const struct mwl_hal_channel *hc; 1865d8d81063Sfei feng - Sun Microsystems - Beijing China int i = 0, retval; 1866d8d81063Sfei feng - Sun Microsystems - Beijing China 1867d8d81063Sfei feng - Sun Microsystems - Beijing China hc = findhalchannel(sc, c); 1868d8d81063Sfei feng - Sun Microsystems - Beijing China if (hc == NULL) { 1869d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX temp while testing */ 1870d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: mwl_hal_settxpower(): " 1871d8d81063Sfei feng - Sun Microsystems - Beijing China "no cal data for channel %u band %u width %u ext %u\n", 1872d8d81063Sfei feng - Sun Microsystems - Beijing China c->channel, c->channelFlags.FreqBand, 1873d8d81063Sfei feng - Sun Microsystems - Beijing China c->channelFlags.ChnlWidth, c->channelFlags.ExtChnlOffset); 1874d8d81063Sfei feng - Sun Microsystems - Beijing China return (EINVAL); 1875d8d81063Sfei feng - Sun Microsystems - Beijing China } 1876d8d81063Sfei feng - Sun Microsystems - Beijing China 1877d8d81063Sfei feng - Sun Microsystems - Beijing China _CMD_SETUP(pCmd, HostCmd_DS_802_11_RF_TX_POWER, 1878d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_CMD_802_11_RF_TX_POWER); 1879d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Action = LE_16(HostCmd_ACT_GEN_SET_LIST); 1880d8d81063Sfei feng - Sun Microsystems - Beijing China /* NB: 5Ghz cal data have the channel # in [0]; don't truncate */ 1881d8d81063Sfei feng - Sun Microsystems - Beijing China if (c->channelFlags.FreqBand == MWL_FREQ_BAND_5GHZ) 1882d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->PowerLevelList[i++] = LE_16(hc->targetPowers[0]); 1883d8d81063Sfei feng - Sun Microsystems - Beijing China for (; i < 4; i++) { 1884d8d81063Sfei feng - Sun Microsystems - Beijing China uint16_t pow = hc->targetPowers[i]; 1885d8d81063Sfei feng - Sun Microsystems - Beijing China if (pow > maxtxpow) 1886d8d81063Sfei feng - Sun Microsystems - Beijing China pow = maxtxpow; 1887d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->PowerLevelList[i] = LE_16(pow); 1888d8d81063Sfei feng - Sun Microsystems - Beijing China } 1889d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_802_11_RF_TX_POWER); 1890d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 1891d8d81063Sfei feng - Sun Microsystems - Beijing China } 1892d8d81063Sfei feng - Sun Microsystems - Beijing China 1893d8d81063Sfei feng - Sun Microsystems - Beijing China #define RATEVAL(r) ((r) &~ RATE_MCS) 1894d8d81063Sfei feng - Sun Microsystems - Beijing China #define RATETYPE(r) (((r) & RATE_MCS) ? HT_RATE_TYPE : LEGACY_RATE_TYPE) 1895d8d81063Sfei feng - Sun Microsystems - Beijing China 1896d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1897d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_settxrate(struct mwl_softc *sc, MWL_HAL_TXRATE_HANDLING handling, 1898d8d81063Sfei feng - Sun Microsystems - Beijing China const MWL_HAL_TXRATE *rate) 1899d8d81063Sfei feng - Sun Microsystems - Beijing China { 1900d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_FW_USE_FIXED_RATE *pCmd; 1901d8d81063Sfei feng - Sun Microsystems - Beijing China FIXED_RATE_ENTRY *fp; 1902d8d81063Sfei feng - Sun Microsystems - Beijing China int retval, i, n; 1903d8d81063Sfei feng - Sun Microsystems - Beijing China 1904d8d81063Sfei feng - Sun Microsystems - Beijing China _VCMD_SETUP(pCmd, HostCmd_FW_USE_FIXED_RATE, 1905d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_CMD_SET_FIXED_RATE); 1906d8d81063Sfei feng - Sun Microsystems - Beijing China 1907d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->MulticastRate = RATEVAL(rate->McastRate); 1908d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->MultiRateTxType = RATETYPE(rate->McastRate); 1909d8d81063Sfei feng - Sun Microsystems - Beijing China /* NB: no rate type field */ 1910d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->ManagementRate = RATEVAL(rate->MgtRate); 1911cb2cd10cSfei feng - Sun Microsystems - Beijing China (void) memset(pCmd->FixedRateTable, 0, sizeof (pCmd->FixedRateTable)); 1912d8d81063Sfei feng - Sun Microsystems - Beijing China if (handling == RATE_FIXED) { 1913d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Action = LE_32(HostCmd_ACT_GEN_SET); 1914d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->AllowRateDrop = LE_32(FIXED_RATE_WITHOUT_AUTORATE_DROP); 1915d8d81063Sfei feng - Sun Microsystems - Beijing China fp = pCmd->FixedRateTable; 1916d8d81063Sfei feng - Sun Microsystems - Beijing China fp->FixedRate = 1917d8d81063Sfei feng - Sun Microsystems - Beijing China LE_32(RATEVAL(rate->RateSeries[0].Rate)); 1918d8d81063Sfei feng - Sun Microsystems - Beijing China fp->FixRateTypeFlags.FixRateType = 1919d8d81063Sfei feng - Sun Microsystems - Beijing China LE_32(RATETYPE(rate->RateSeries[0].Rate)); 1920d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->EntryCount = LE_32(1); 1921d8d81063Sfei feng - Sun Microsystems - Beijing China } else if (handling == RATE_FIXED_DROP) { 1922d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Action = LE_32(HostCmd_ACT_GEN_SET); 1923d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->AllowRateDrop = LE_32(FIXED_RATE_WITH_AUTO_RATE_DROP); 1924d8d81063Sfei feng - Sun Microsystems - Beijing China n = 0; 1925d8d81063Sfei feng - Sun Microsystems - Beijing China fp = pCmd->FixedRateTable; 1926d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < 4; i++) { 1927d8d81063Sfei feng - Sun Microsystems - Beijing China if (rate->RateSeries[0].TryCount == 0) 1928d8d81063Sfei feng - Sun Microsystems - Beijing China break; 1929d8d81063Sfei feng - Sun Microsystems - Beijing China fp->FixRateTypeFlags.FixRateType = 1930d8d81063Sfei feng - Sun Microsystems - Beijing China LE_32(RATETYPE(rate->RateSeries[i].Rate)); 1931d8d81063Sfei feng - Sun Microsystems - Beijing China fp->FixedRate = 1932d8d81063Sfei feng - Sun Microsystems - Beijing China LE_32(RATEVAL(rate->RateSeries[i].Rate)); 1933d8d81063Sfei feng - Sun Microsystems - Beijing China fp->FixRateTypeFlags.RetryCountValid = 1934d8d81063Sfei feng - Sun Microsystems - Beijing China LE_32(RETRY_COUNT_VALID); 1935d8d81063Sfei feng - Sun Microsystems - Beijing China fp->RetryCount = 1936d8d81063Sfei feng - Sun Microsystems - Beijing China LE_32(rate->RateSeries[i].TryCount-1); 1937d8d81063Sfei feng - Sun Microsystems - Beijing China n++; 1938d8d81063Sfei feng - Sun Microsystems - Beijing China } 1939d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->EntryCount = LE_32(n); 1940d8d81063Sfei feng - Sun Microsystems - Beijing China } else 1941d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Action = LE_32(HostCmd_ACT_NOT_USE_FIXED_RATE); 1942d8d81063Sfei feng - Sun Microsystems - Beijing China 1943d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_SET_FIXED_RATE); 1944d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 1945d8d81063Sfei feng - Sun Microsystems - Beijing China } 1946d8d81063Sfei feng - Sun Microsystems - Beijing China 1947d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1948d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_settxrate_auto(struct mwl_softc *sc, const MWL_HAL_TXRATE *rate) 1949d8d81063Sfei feng - Sun Microsystems - Beijing China { 1950d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_FW_USE_FIXED_RATE *pCmd; 1951d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 1952d8d81063Sfei feng - Sun Microsystems - Beijing China 1953d8d81063Sfei feng - Sun Microsystems - Beijing China _CMD_SETUP(pCmd, HostCmd_FW_USE_FIXED_RATE, 1954d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_CMD_SET_FIXED_RATE); 1955d8d81063Sfei feng - Sun Microsystems - Beijing China 1956d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->MulticastRate = RATEVAL(rate->McastRate); 1957d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->MultiRateTxType = RATETYPE(rate->McastRate); 1958d8d81063Sfei feng - Sun Microsystems - Beijing China /* NB: no rate type field */ 1959d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->ManagementRate = RATEVAL(rate->MgtRate); 1960cb2cd10cSfei feng - Sun Microsystems - Beijing China (void) memset(pCmd->FixedRateTable, 0, sizeof (pCmd->FixedRateTable)); 1961d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Action = LE_32(HostCmd_ACT_NOT_USE_FIXED_RATE); 1962d8d81063Sfei feng - Sun Microsystems - Beijing China 1963d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_SET_FIXED_RATE); 1964d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 1965d8d81063Sfei feng - Sun Microsystems - Beijing China } 1966d8d81063Sfei feng - Sun Microsystems - Beijing China 1967d8d81063Sfei feng - Sun Microsystems - Beijing China #undef RATEVAL 1968d8d81063Sfei feng - Sun Microsystems - Beijing China #undef RATETYPE 1969d8d81063Sfei feng - Sun Microsystems - Beijing China 1970d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX 0 = indoor, 1 = outdoor */ 1971d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1972d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_setrateadaptmode(struct mwl_softc *sc, uint16_t mode) 1973d8d81063Sfei feng - Sun Microsystems - Beijing China { 1974d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_DS_SET_RATE_ADAPT_MODE *pCmd; 1975d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 1976d8d81063Sfei feng - Sun Microsystems - Beijing China 1977d8d81063Sfei feng - Sun Microsystems - Beijing China _CMD_SETUP(pCmd, HostCmd_DS_SET_RATE_ADAPT_MODE, 1978d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_CMD_SET_RATE_ADAPT_MODE); 1979d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Action = LE_16(HostCmd_ACT_GEN_SET); 1980d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->RateAdaptMode = LE_16(mode); 1981d8d81063Sfei feng - Sun Microsystems - Beijing China 1982d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_SET_RATE_ADAPT_MODE); 1983d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 1984d8d81063Sfei feng - Sun Microsystems - Beijing China } 1985d8d81063Sfei feng - Sun Microsystems - Beijing China 1986d8d81063Sfei feng - Sun Microsystems - Beijing China static int 1987d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_setoptimizationlevel(struct mwl_softc *sc, int level) 1988d8d81063Sfei feng - Sun Microsystems - Beijing China { 1989d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_FW_SET_OPTIMIZATION_LEVEL *pCmd; 1990d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 1991d8d81063Sfei feng - Sun Microsystems - Beijing China 1992d8d81063Sfei feng - Sun Microsystems - Beijing China _CMD_SETUP(pCmd, HostCmd_FW_SET_OPTIMIZATION_LEVEL, 1993d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_CMD_SET_OPTIMIZATION_LEVEL); 1994d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->OptLevel = (uint8_t)level; 1995d8d81063Sfei feng - Sun Microsystems - Beijing China 1996d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_SET_OPTIMIZATION_LEVEL); 1997d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 1998d8d81063Sfei feng - Sun Microsystems - Beijing China } 1999d8d81063Sfei feng - Sun Microsystems - Beijing China 2000d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2001d8d81063Sfei feng - Sun Microsystems - Beijing China * Set the region code that selects the radar bin'ing agorithm. 2002d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2003d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2004d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_setregioncode(struct mwl_softc *sc, int regionCode) 2005d8d81063Sfei feng - Sun Microsystems - Beijing China { 2006d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_SET_REGIONCODE_INFO *pCmd; 2007d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 2008d8d81063Sfei feng - Sun Microsystems - Beijing China 2009d8d81063Sfei feng - Sun Microsystems - Beijing China _CMD_SETUP(pCmd, HostCmd_SET_REGIONCODE_INFO, 2010d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_CMD_SET_REGION_CODE); 2011d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX map pseudo-codes to fw codes */ 2012d8d81063Sfei feng - Sun Microsystems - Beijing China switch (regionCode) { 2013d8d81063Sfei feng - Sun Microsystems - Beijing China case DOMAIN_CODE_ETSI_131: 2014d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->regionCode = LE_16(DOMAIN_CODE_ETSI); 2015d8d81063Sfei feng - Sun Microsystems - Beijing China break; 2016d8d81063Sfei feng - Sun Microsystems - Beijing China default: 2017d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->regionCode = LE_16(regionCode); 2018d8d81063Sfei feng - Sun Microsystems - Beijing China break; 2019d8d81063Sfei feng - Sun Microsystems - Beijing China } 2020d8d81063Sfei feng - Sun Microsystems - Beijing China 2021d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_SET_REGION_CODE); 2022d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 2023d8d81063Sfei feng - Sun Microsystems - Beijing China } 2024d8d81063Sfei feng - Sun Microsystems - Beijing China 2025d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2026d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_setassocid(struct mwl_softc *sc, 2027d8d81063Sfei feng - Sun Microsystems - Beijing China const uint8_t bssId[IEEE80211_ADDR_LEN], uint16_t assocId) 2028d8d81063Sfei feng - Sun Microsystems - Beijing China { 2029d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_FW_SET_AID *pCmd = (HostCmd_FW_SET_AID *) &sc->sc_cmd_mem[0]; 2030d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 2031d8d81063Sfei feng - Sun Microsystems - Beijing China 2032d8d81063Sfei feng - Sun Microsystems - Beijing China _VCMD_SETUP(pCmd, HostCmd_FW_SET_AID, HostCmd_CMD_SET_AID); 2033d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->AssocID = LE_16(assocId); 2034d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(&pCmd->MacAddr[0], bssId); 2035d8d81063Sfei feng - Sun Microsystems - Beijing China 2036d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_SET_AID); 2037d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 2038d8d81063Sfei feng - Sun Microsystems - Beijing China } 2039d8d81063Sfei feng - Sun Microsystems - Beijing China 2040d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2041d8d81063Sfei feng - Sun Microsystems - Beijing China * Inform firmware of tx rate parameters. Called whenever 2042d8d81063Sfei feng - Sun Microsystems - Beijing China * user-settable params change and after a channel change. 2043d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2044d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2045d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_setrates(struct ieee80211com *ic) 2046d8d81063Sfei feng - Sun Microsystems - Beijing China { 2047d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc = (struct mwl_softc *)ic; 2048d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_HAL_TXRATE rates; 2049d8d81063Sfei feng - Sun Microsystems - Beijing China 2050d8d81063Sfei feng - Sun Microsystems - Beijing China const struct ieee80211_rateset *rs; 2051d8d81063Sfei feng - Sun Microsystems - Beijing China rs = &ic->ic_bss->in_rates; 2052d8d81063Sfei feng - Sun Microsystems - Beijing China 2053d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2054d8d81063Sfei feng - Sun Microsystems - Beijing China * Update the h/w rate map. 2055d8d81063Sfei feng - Sun Microsystems - Beijing China * NB: 0x80 for MCS is passed through unchanged 2056d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2057cb2cd10cSfei feng - Sun Microsystems - Beijing China (void) memset(&rates, 0, sizeof (rates)); 2058d8d81063Sfei feng - Sun Microsystems - Beijing China /* rate used to send management frames */ 2059d8d81063Sfei feng - Sun Microsystems - Beijing China rates.MgtRate = rs->ir_rates[0] & IEEE80211_RATE_VAL; 2060d8d81063Sfei feng - Sun Microsystems - Beijing China /* rate used to send multicast frames */ 2061d8d81063Sfei feng - Sun Microsystems - Beijing China rates.McastRate = rates.MgtRate; 2062d8d81063Sfei feng - Sun Microsystems - Beijing China 2063d8d81063Sfei feng - Sun Microsystems - Beijing China return (mwl_hal_settxrate(sc, RATE_AUTO, &rates)); 2064d8d81063Sfei feng - Sun Microsystems - Beijing China } 2065d8d81063Sfei feng - Sun Microsystems - Beijing China 2066d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2067d8d81063Sfei feng - Sun Microsystems - Beijing China * Set packet size threshold for implicit use of RTS. 2068d8d81063Sfei feng - Sun Microsystems - Beijing China * Takes effect immediately. 2069d8d81063Sfei feng - Sun Microsystems - Beijing China * XXX packet length > threshold =>'s RTS 2070d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2071d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2072d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_setrtsthreshold(struct mwl_softc *sc, int threshold) 2073d8d81063Sfei feng - Sun Microsystems - Beijing China { 2074d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_DS_802_11_RTS_THSD *pCmd; 2075d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 2076d8d81063Sfei feng - Sun Microsystems - Beijing China 2077d8d81063Sfei feng - Sun Microsystems - Beijing China _VCMD_SETUP(pCmd, HostCmd_DS_802_11_RTS_THSD, 2078d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_CMD_802_11_RTS_THSD); 2079d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Action = LE_16(HostCmd_ACT_GEN_SET); 2080d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Threshold = LE_16(threshold); 2081d8d81063Sfei feng - Sun Microsystems - Beijing China 2082d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_802_11_RTS_THSD); 2083d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 2084d8d81063Sfei feng - Sun Microsystems - Beijing China } 2085d8d81063Sfei feng - Sun Microsystems - Beijing China 2086d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2087d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_setcsmode(struct mwl_softc *sc, MWL_HAL_CSMODE csmode) 2088d8d81063Sfei feng - Sun Microsystems - Beijing China { 2089d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_DS_SET_LINKADAPT_CS_MODE *pCmd; 2090d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 2091d8d81063Sfei feng - Sun Microsystems - Beijing China 2092d8d81063Sfei feng - Sun Microsystems - Beijing China _CMD_SETUP(pCmd, HostCmd_DS_SET_LINKADAPT_CS_MODE, 2093d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_CMD_SET_LINKADAPT_CS_MODE); 2094d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Action = LE_16(HostCmd_ACT_GEN_SET); 2095d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->CSMode = LE_16(csmode); 2096d8d81063Sfei feng - Sun Microsystems - Beijing China 2097d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_SET_LINKADAPT_CS_MODE); 2098d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 2099d8d81063Sfei feng - Sun Microsystems - Beijing China } 2100d8d81063Sfei feng - Sun Microsystems - Beijing China 2101d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2102d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_setpromisc(struct mwl_softc *sc, int ena) 2103d8d81063Sfei feng - Sun Microsystems - Beijing China { 2104d8d81063Sfei feng - Sun Microsystems - Beijing China uint32_t v; 2105d8d81063Sfei feng - Sun Microsystems - Beijing China 2106d8d81063Sfei feng - Sun Microsystems - Beijing China v = mwl_ctl_read4(sc, MACREG_REG_PROMISCUOUS); 2107d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_PROMISCUOUS, ena ? v | 1 : v & ~1); 2108d8d81063Sfei feng - Sun Microsystems - Beijing China 2109d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 2110d8d81063Sfei feng - Sun Microsystems - Beijing China } 2111d8d81063Sfei feng - Sun Microsystems - Beijing China 2112d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2113d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_start(struct mwl_softc *sc) 2114d8d81063Sfei feng - Sun Microsystems - Beijing China { 2115d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_DS_BSS_START *pCmd; 2116d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 2117d8d81063Sfei feng - Sun Microsystems - Beijing China 2118d8d81063Sfei feng - Sun Microsystems - Beijing China _VCMD_SETUP(pCmd, HostCmd_DS_BSS_START, HostCmd_CMD_BSS_START); 2119d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Enable = LE_32(HostCmd_ACT_GEN_ON); 2120d8d81063Sfei feng - Sun Microsystems - Beijing China 2121d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_BSS_START); 2122d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 2123d8d81063Sfei feng - Sun Microsystems - Beijing China } 2124d8d81063Sfei feng - Sun Microsystems - Beijing China 2125d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2126d8d81063Sfei feng - Sun Microsystems - Beijing China * Enable sta-mode operation (disables beacon frame xmit). 2127d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2128d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2129d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_setinframode(struct mwl_softc *sc) 2130d8d81063Sfei feng - Sun Microsystems - Beijing China { 2131d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_FW_SET_INFRA_MODE *pCmd; 2132d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 2133d8d81063Sfei feng - Sun Microsystems - Beijing China 2134d8d81063Sfei feng - Sun Microsystems - Beijing China _VCMD_SETUP(pCmd, HostCmd_FW_SET_INFRA_MODE, 2135d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_CMD_SET_INFRA_MODE); 2136d8d81063Sfei feng - Sun Microsystems - Beijing China 2137d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_SET_INFRA_MODE); 2138d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 2139d8d81063Sfei feng - Sun Microsystems - Beijing China } 2140d8d81063Sfei feng - Sun Microsystems - Beijing China 2141d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2142d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_stop(struct mwl_softc *sc) 2143d8d81063Sfei feng - Sun Microsystems - Beijing China { 2144d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_DS_BSS_START *pCmd; 2145d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 2146d8d81063Sfei feng - Sun Microsystems - Beijing China 2147d8d81063Sfei feng - Sun Microsystems - Beijing China _VCMD_SETUP(pCmd, HostCmd_DS_BSS_START, 2148d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_CMD_BSS_START); 2149d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->Enable = LE_32(HostCmd_ACT_GEN_OFF); 2150d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_BSS_START); 2151d8d81063Sfei feng - Sun Microsystems - Beijing China 2152d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 2153d8d81063Sfei feng - Sun Microsystems - Beijing China } 2154d8d81063Sfei feng - Sun Microsystems - Beijing China 2155d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2156d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_keyset(struct mwl_softc *sc, const MWL_HAL_KEYVAL *kv, 2157d8d81063Sfei feng - Sun Microsystems - Beijing China const uint8_t mac[IEEE80211_ADDR_LEN]) 2158d8d81063Sfei feng - Sun Microsystems - Beijing China { 2159d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_FW_UPDATE_ENCRYPTION_SET_KEY *pCmd; 2160d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 2161d8d81063Sfei feng - Sun Microsystems - Beijing China 2162d8d81063Sfei feng - Sun Microsystems - Beijing China _VCMD_SETUP(pCmd, HostCmd_FW_UPDATE_ENCRYPTION_SET_KEY, 2163d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_CMD_UPDATE_ENCRYPTION); 2164d8d81063Sfei feng - Sun Microsystems - Beijing China if (kv->keyFlags & (KEY_FLAG_TXGROUPKEY|KEY_FLAG_RXGROUPKEY)) 2165d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->ActionType = LE_32(EncrActionTypeSetGroupKey); 2166d8d81063Sfei feng - Sun Microsystems - Beijing China else 2167d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->ActionType = LE_32(EncrActionTypeSetKey); 2168d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->KeyParam.Length = LE_16(sizeof (pCmd->KeyParam)); 2169d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->KeyParam.KeyTypeId = LE_16(kv->keyTypeId); 2170d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->KeyParam.KeyInfo = LE_32(kv->keyFlags); 2171d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->KeyParam.KeyIndex = LE_32(kv->keyIndex); 2172d8d81063Sfei feng - Sun Microsystems - Beijing China /* NB: includes TKIP MIC keys */ 2173d8d81063Sfei feng - Sun Microsystems - Beijing China (void) memcpy(&pCmd->KeyParam.Key, &kv->key, kv->keyLen); 2174d8d81063Sfei feng - Sun Microsystems - Beijing China switch (kv->keyTypeId) { 2175d8d81063Sfei feng - Sun Microsystems - Beijing China case KEY_TYPE_ID_WEP: 2176d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->KeyParam.KeyLen = LE_16(kv->keyLen); 2177d8d81063Sfei feng - Sun Microsystems - Beijing China break; 2178d8d81063Sfei feng - Sun Microsystems - Beijing China case KEY_TYPE_ID_TKIP: 2179d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->KeyParam.KeyLen = LE_16(sizeof (TKIP_TYPE_KEY)); 2180d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->KeyParam.Key.TkipKey.TkipRsc.low = 2181d8d81063Sfei feng - Sun Microsystems - Beijing China LE_16(kv->key.tkip.rsc.low); 2182d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->KeyParam.Key.TkipKey.TkipRsc.high = 2183d8d81063Sfei feng - Sun Microsystems - Beijing China LE_32(kv->key.tkip.rsc.high); 2184d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->KeyParam.Key.TkipKey.TkipTsc.low = 2185d8d81063Sfei feng - Sun Microsystems - Beijing China LE_16(kv->key.tkip.tsc.low); 2186d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->KeyParam.Key.TkipKey.TkipTsc.high = 2187d8d81063Sfei feng - Sun Microsystems - Beijing China LE_32(kv->key.tkip.tsc.high); 2188d8d81063Sfei feng - Sun Microsystems - Beijing China break; 2189d8d81063Sfei feng - Sun Microsystems - Beijing China case KEY_TYPE_ID_AES: 2190d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->KeyParam.KeyLen = LE_16(sizeof (AES_TYPE_KEY)); 2191d8d81063Sfei feng - Sun Microsystems - Beijing China break; 2192d8d81063Sfei feng - Sun Microsystems - Beijing China } 2193d8d81063Sfei feng - Sun Microsystems - Beijing China #ifdef MWL_MBSS_SUPPORT 2194d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(pCmd->KeyParam.Macaddr, mac); 2195d8d81063Sfei feng - Sun Microsystems - Beijing China #else 2196d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(pCmd->Macaddr, mac); 2197d8d81063Sfei feng - Sun Microsystems - Beijing China #endif 2198d8d81063Sfei feng - Sun Microsystems - Beijing China 2199d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_UPDATE_ENCRYPTION); 2200d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 2201d8d81063Sfei feng - Sun Microsystems - Beijing China } 2202d8d81063Sfei feng - Sun Microsystems - Beijing China 2203d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2204d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_keyreset(struct mwl_softc *sc, const MWL_HAL_KEYVAL *kv, 2205d8d81063Sfei feng - Sun Microsystems - Beijing China const uint8_t mac[IEEE80211_ADDR_LEN]) 2206d8d81063Sfei feng - Sun Microsystems - Beijing China { 2207d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_FW_UPDATE_ENCRYPTION_SET_KEY *pCmd; 2208d8d81063Sfei feng - Sun Microsystems - Beijing China int retval; 2209d8d81063Sfei feng - Sun Microsystems - Beijing China 2210d8d81063Sfei feng - Sun Microsystems - Beijing China _VCMD_SETUP(pCmd, HostCmd_FW_UPDATE_ENCRYPTION_SET_KEY, 2211d8d81063Sfei feng - Sun Microsystems - Beijing China HostCmd_CMD_UPDATE_ENCRYPTION); 2212d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->ActionType = LE_16(EncrActionTypeRemoveKey); 2213d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->KeyParam.Length = LE_16(sizeof (pCmd->KeyParam)); 2214d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->KeyParam.KeyTypeId = LE_16(kv->keyTypeId); 2215d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->KeyParam.KeyInfo = LE_32(kv->keyFlags); 2216d8d81063Sfei feng - Sun Microsystems - Beijing China pCmd->KeyParam.KeyIndex = LE_32(kv->keyIndex); 2217d8d81063Sfei feng - Sun Microsystems - Beijing China #ifdef MWL_MBSS_SUPPORT 2218d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(pCmd->KeyParam.Macaddr, mac); 2219d8d81063Sfei feng - Sun Microsystems - Beijing China #else 2220d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(pCmd->Macaddr, mac); 2221d8d81063Sfei feng - Sun Microsystems - Beijing China #endif 2222d8d81063Sfei feng - Sun Microsystems - Beijing China retval = mwlExecuteCmd(sc, HostCmd_CMD_UPDATE_ENCRYPTION); 2223d8d81063Sfei feng - Sun Microsystems - Beijing China return (retval); 2224d8d81063Sfei feng - Sun Microsystems - Beijing China } 2225d8d81063Sfei feng - Sun Microsystems - Beijing China 2226d8d81063Sfei feng - Sun Microsystems - Beijing China /* ARGSUSED */ 2227d8d81063Sfei feng - Sun Microsystems - Beijing China static struct ieee80211_node * 2228d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_node_alloc(struct ieee80211com *ic) 2229d8d81063Sfei feng - Sun Microsystems - Beijing China { 2230d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_node *mn; 2231d8d81063Sfei feng - Sun Microsystems - Beijing China 2232d8d81063Sfei feng - Sun Microsystems - Beijing China mn = kmem_zalloc(sizeof (struct mwl_node), KM_SLEEP); 2233d8d81063Sfei feng - Sun Microsystems - Beijing China if (mn == NULL) { 2234d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX stat+msg */ 2235d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_MSG, "mwl: mwl_node_alloc(): " 2236d8d81063Sfei feng - Sun Microsystems - Beijing China "alloc node failed\n"); 2237d8d81063Sfei feng - Sun Microsystems - Beijing China return (NULL); 2238d8d81063Sfei feng - Sun Microsystems - Beijing China } 2239d8d81063Sfei feng - Sun Microsystems - Beijing China return (&mn->mn_node); 2240d8d81063Sfei feng - Sun Microsystems - Beijing China } 2241d8d81063Sfei feng - Sun Microsystems - Beijing China 2242d8d81063Sfei feng - Sun Microsystems - Beijing China static void 2243d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_node_free(struct ieee80211_node *ni) 2244d8d81063Sfei feng - Sun Microsystems - Beijing China { 2245d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = ni->in_ic; 2246d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_node *mn = MWL_NODE(ni); 2247d8d81063Sfei feng - Sun Microsystems - Beijing China 2248d8d81063Sfei feng - Sun Microsystems - Beijing China if (mn->mn_staid != 0) { 2249d8d81063Sfei feng - Sun Microsystems - Beijing China // mwl_hal_delstation(mn->mn_hvap, vap->iv_myaddr); 2250d8d81063Sfei feng - Sun Microsystems - Beijing China // delstaid(sc, mn->mn_staid); 2251d8d81063Sfei feng - Sun Microsystems - Beijing China mn->mn_staid = 0; 2252d8d81063Sfei feng - Sun Microsystems - Beijing China } 2253d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_node_cleanup(ni); 2254d8d81063Sfei feng - Sun Microsystems - Beijing China kmem_free(ni, sizeof (struct mwl_node)); 2255d8d81063Sfei feng - Sun Microsystems - Beijing China } 2256d8d81063Sfei feng - Sun Microsystems - Beijing China 2257d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2258d8d81063Sfei feng - Sun Microsystems - Beijing China * Allocate a key cache slot for a unicast key. The 2259d8d81063Sfei feng - Sun Microsystems - Beijing China * firmware handles key allocation and every station is 2260d8d81063Sfei feng - Sun Microsystems - Beijing China * guaranteed key space so we are always successful. 2261d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2262d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2263d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_key_alloc(struct ieee80211com *ic, const struct ieee80211_key *k, 2264d8d81063Sfei feng - Sun Microsystems - Beijing China ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) 2265d8d81063Sfei feng - Sun Microsystems - Beijing China { 2266d8d81063Sfei feng - Sun Microsystems - Beijing China if (k->wk_keyix != IEEE80211_KEYIX_NONE || 2267d8d81063Sfei feng - Sun Microsystems - Beijing China (k->wk_flags & IEEE80211_KEY_GROUP)) { 2268d8d81063Sfei feng - Sun Microsystems - Beijing China if (!(&ic->ic_nw_keys[0] <= k && 2269d8d81063Sfei feng - Sun Microsystems - Beijing China k < &ic->ic_nw_keys[IEEE80211_WEP_NKID])) { 2270d8d81063Sfei feng - Sun Microsystems - Beijing China /* should not happen */ 2271d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_CRYPTO, "mwl: mwl_key_alloc(): " 2272d8d81063Sfei feng - Sun Microsystems - Beijing China "bogus group key\n"); 2273d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 2274d8d81063Sfei feng - Sun Microsystems - Beijing China } 2275d8d81063Sfei feng - Sun Microsystems - Beijing China /* give the caller what they requested */ 2276d8d81063Sfei feng - Sun Microsystems - Beijing China *keyix = *rxkeyix = k - ic->ic_nw_keys; 2277d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_CRYPTO, "mwl: mwl_key_alloc(): " 2278d8d81063Sfei feng - Sun Microsystems - Beijing China "alloc GROUP key keyix %x, rxkeyix %x\n", 2279d8d81063Sfei feng - Sun Microsystems - Beijing China *keyix, *rxkeyix); 2280d8d81063Sfei feng - Sun Microsystems - Beijing China } else { 2281d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2282d8d81063Sfei feng - Sun Microsystems - Beijing China * Firmware handles key allocation. 2283d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2284d8d81063Sfei feng - Sun Microsystems - Beijing China *keyix = *rxkeyix = 0; 2285d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_CRYPTO, "mwl: mwl_key_alloc(): " 2286d8d81063Sfei feng - Sun Microsystems - Beijing China "reset key index in key allocation\n"); 2287d8d81063Sfei feng - Sun Microsystems - Beijing China } 2288d8d81063Sfei feng - Sun Microsystems - Beijing China 2289d8d81063Sfei feng - Sun Microsystems - Beijing China return (1); 2290d8d81063Sfei feng - Sun Microsystems - Beijing China } 2291d8d81063Sfei feng - Sun Microsystems - Beijing China 2292d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2293d8d81063Sfei feng - Sun Microsystems - Beijing China * Delete a key entry allocated by mwl_key_alloc. 2294d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2295d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2296d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_key_delete(struct ieee80211com *ic, const struct ieee80211_key *k) 2297d8d81063Sfei feng - Sun Microsystems - Beijing China { 2298d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc = (struct mwl_softc *)ic; 2299d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_HAL_KEYVAL hk; 2300d8d81063Sfei feng - Sun Microsystems - Beijing China const uint8_t bcastaddr[IEEE80211_ADDR_LEN] = 2301d8d81063Sfei feng - Sun Microsystems - Beijing China { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 2302d8d81063Sfei feng - Sun Microsystems - Beijing China 2303cb2cd10cSfei feng - Sun Microsystems - Beijing China (void) memset(&hk, 0, sizeof (hk)); 2304d8d81063Sfei feng - Sun Microsystems - Beijing China hk.keyIndex = k->wk_keyix; 2305d8d81063Sfei feng - Sun Microsystems - Beijing China switch (k->wk_cipher->ic_cipher) { 2306d8d81063Sfei feng - Sun Microsystems - Beijing China case IEEE80211_CIPHER_WEP: 2307d8d81063Sfei feng - Sun Microsystems - Beijing China hk.keyTypeId = KEY_TYPE_ID_WEP; 2308d8d81063Sfei feng - Sun Microsystems - Beijing China break; 2309d8d81063Sfei feng - Sun Microsystems - Beijing China case IEEE80211_CIPHER_TKIP: 2310d8d81063Sfei feng - Sun Microsystems - Beijing China hk.keyTypeId = KEY_TYPE_ID_TKIP; 2311d8d81063Sfei feng - Sun Microsystems - Beijing China break; 2312d8d81063Sfei feng - Sun Microsystems - Beijing China case IEEE80211_CIPHER_AES_CCM: 2313d8d81063Sfei feng - Sun Microsystems - Beijing China hk.keyTypeId = KEY_TYPE_ID_AES; 2314d8d81063Sfei feng - Sun Microsystems - Beijing China break; 2315d8d81063Sfei feng - Sun Microsystems - Beijing China default: 2316d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX should not happen */ 2317d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_CRYPTO, "mwl: mwl_key_delete(): " 2318d8d81063Sfei feng - Sun Microsystems - Beijing China "unknown cipher %d\n", k->wk_cipher->ic_cipher); 2319d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 2320d8d81063Sfei feng - Sun Microsystems - Beijing China } 2321d8d81063Sfei feng - Sun Microsystems - Beijing China return (mwl_hal_keyreset(sc, &hk, bcastaddr) == 0); 2322d8d81063Sfei feng - Sun Microsystems - Beijing China } 2323d8d81063Sfei feng - Sun Microsystems - Beijing China 2324d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2325d8d81063Sfei feng - Sun Microsystems - Beijing China * Set the key cache contents for the specified key. Key cache 2326d8d81063Sfei feng - Sun Microsystems - Beijing China * slot(s) must already have been allocated by mwl_key_alloc. 2327d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2328d8d81063Sfei feng - Sun Microsystems - Beijing China /* ARGSUSED */ 2329d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2330d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_key_set(struct ieee80211com *ic, const struct ieee80211_key *k, 2331d8d81063Sfei feng - Sun Microsystems - Beijing China const uint8_t mac[IEEE80211_ADDR_LEN]) 2332d8d81063Sfei feng - Sun Microsystems - Beijing China { 2333d8d81063Sfei feng - Sun Microsystems - Beijing China #define GRPXMIT (IEEE80211_KEY_XMIT | IEEE80211_KEY_GROUP) 2334d8d81063Sfei feng - Sun Microsystems - Beijing China /* NB: static wep keys are marked GROUP+tx/rx; GTK will be tx or rx */ 2335d8d81063Sfei feng - Sun Microsystems - Beijing China #define IEEE80211_IS_STATICKEY(k) \ 2336d8d81063Sfei feng - Sun Microsystems - Beijing China (((k)->wk_flags & (GRPXMIT|IEEE80211_KEY_RECV)) == \ 2337d8d81063Sfei feng - Sun Microsystems - Beijing China (GRPXMIT|IEEE80211_KEY_RECV)) 2338d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc = (struct mwl_softc *)ic; 2339d8d81063Sfei feng - Sun Microsystems - Beijing China const struct ieee80211_cipher *cip = k->wk_cipher; 2340d8d81063Sfei feng - Sun Microsystems - Beijing China const uint8_t *macaddr; 2341d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_HAL_KEYVAL hk; 2342d8d81063Sfei feng - Sun Microsystems - Beijing China 2343cb2cd10cSfei feng - Sun Microsystems - Beijing China (void) memset(&hk, 0, sizeof (hk)); 2344d8d81063Sfei feng - Sun Microsystems - Beijing China hk.keyIndex = k->wk_keyix; 2345d8d81063Sfei feng - Sun Microsystems - Beijing China switch (cip->ic_cipher) { 2346d8d81063Sfei feng - Sun Microsystems - Beijing China case IEEE80211_CIPHER_WEP: 2347d8d81063Sfei feng - Sun Microsystems - Beijing China hk.keyTypeId = KEY_TYPE_ID_WEP; 2348d8d81063Sfei feng - Sun Microsystems - Beijing China hk.keyLen = k->wk_keylen; 2349d8d81063Sfei feng - Sun Microsystems - Beijing China if (k->wk_keyix == ic->ic_def_txkey) 2350d8d81063Sfei feng - Sun Microsystems - Beijing China hk.keyFlags = KEY_FLAG_WEP_TXKEY; 2351d8d81063Sfei feng - Sun Microsystems - Beijing China if (!IEEE80211_IS_STATICKEY(k)) { 2352d8d81063Sfei feng - Sun Microsystems - Beijing China /* NB: WEP is never used for the PTK */ 2353d8d81063Sfei feng - Sun Microsystems - Beijing China (void) addgroupflags(&hk, k); 2354d8d81063Sfei feng - Sun Microsystems - Beijing China } 2355d8d81063Sfei feng - Sun Microsystems - Beijing China break; 2356d8d81063Sfei feng - Sun Microsystems - Beijing China case IEEE80211_CIPHER_TKIP: 2357d8d81063Sfei feng - Sun Microsystems - Beijing China hk.keyTypeId = KEY_TYPE_ID_TKIP; 2358d8d81063Sfei feng - Sun Microsystems - Beijing China hk.key.tkip.tsc.high = (uint32_t)(k->wk_keytsc >> 16); 2359d8d81063Sfei feng - Sun Microsystems - Beijing China hk.key.tkip.tsc.low = (uint16_t)k->wk_keytsc; 2360d8d81063Sfei feng - Sun Microsystems - Beijing China hk.keyFlags = KEY_FLAG_TSC_VALID | KEY_FLAG_MICKEY_VALID; 2361d8d81063Sfei feng - Sun Microsystems - Beijing China hk.keyLen = k->wk_keylen + IEEE80211_MICBUF_SIZE; 2362d8d81063Sfei feng - Sun Microsystems - Beijing China if (!addgroupflags(&hk, k)) 2363d8d81063Sfei feng - Sun Microsystems - Beijing China hk.keyFlags |= KEY_FLAG_PAIRWISE; 2364d8d81063Sfei feng - Sun Microsystems - Beijing China break; 2365d8d81063Sfei feng - Sun Microsystems - Beijing China case IEEE80211_CIPHER_AES_CCM: 2366d8d81063Sfei feng - Sun Microsystems - Beijing China hk.keyTypeId = KEY_TYPE_ID_AES; 2367d8d81063Sfei feng - Sun Microsystems - Beijing China hk.keyLen = k->wk_keylen; 2368d8d81063Sfei feng - Sun Microsystems - Beijing China if (!addgroupflags(&hk, k)) 2369d8d81063Sfei feng - Sun Microsystems - Beijing China hk.keyFlags |= KEY_FLAG_PAIRWISE; 2370d8d81063Sfei feng - Sun Microsystems - Beijing China break; 2371d8d81063Sfei feng - Sun Microsystems - Beijing China default: 2372d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX should not happen */ 2373d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_CRYPTO, "mwl: mwl_key_set(): " 2374d8d81063Sfei feng - Sun Microsystems - Beijing China "unknown cipher %d\n", 2375d8d81063Sfei feng - Sun Microsystems - Beijing China k->wk_cipher->ic_cipher); 2376d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 2377d8d81063Sfei feng - Sun Microsystems - Beijing China } 2378d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2379d8d81063Sfei feng - Sun Microsystems - Beijing China * NB: tkip mic keys get copied here too; the layout 2380d8d81063Sfei feng - Sun Microsystems - Beijing China * just happens to match that in ieee80211_key. 2381d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2382d8d81063Sfei feng - Sun Microsystems - Beijing China (void) memcpy(hk.key.aes, k->wk_key, hk.keyLen); 2383d8d81063Sfei feng - Sun Microsystems - Beijing China 2384d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2385d8d81063Sfei feng - Sun Microsystems - Beijing China * Locate address of sta db entry for writing key; 2386d8d81063Sfei feng - Sun Microsystems - Beijing China * the convention unfortunately is somewhat different 2387d8d81063Sfei feng - Sun Microsystems - Beijing China * than how net80211, hostapd, and wpa_supplicant think. 2388d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2389d8d81063Sfei feng - Sun Microsystems - Beijing China 2390d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2391d8d81063Sfei feng - Sun Microsystems - Beijing China * NB: keys plumbed before the sta reaches AUTH state 2392d8d81063Sfei feng - Sun Microsystems - Beijing China * will be discarded or written to the wrong sta db 2393d8d81063Sfei feng - Sun Microsystems - Beijing China * entry because iv_bss is meaningless. This is ok 2394d8d81063Sfei feng - Sun Microsystems - Beijing China * (right now) because we handle deferred plumbing of 2395d8d81063Sfei feng - Sun Microsystems - Beijing China * WEP keys when the sta reaches AUTH state. 2396d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2397d8d81063Sfei feng - Sun Microsystems - Beijing China macaddr = ic->ic_bss->in_bssid; 2398d8d81063Sfei feng - Sun Microsystems - Beijing China if (k->wk_flags & IEEE80211_KEY_XMIT) { 2399d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX plumb to local sta db too for static key wep */ 2400d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_hal_keyset(sc, &hk, ic->ic_macaddr); 2401d8d81063Sfei feng - Sun Microsystems - Beijing China } 2402d8d81063Sfei feng - Sun Microsystems - Beijing China return (mwl_hal_keyset(sc, &hk, macaddr) == 0); 2403d8d81063Sfei feng - Sun Microsystems - Beijing China #undef IEEE80211_IS_STATICKEY 2404d8d81063Sfei feng - Sun Microsystems - Beijing China #undef GRPXMIT 2405d8d81063Sfei feng - Sun Microsystems - Beijing China } 2406d8d81063Sfei feng - Sun Microsystems - Beijing China 2407d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2408d8d81063Sfei feng - Sun Microsystems - Beijing China * Plumb any static WEP key for the station. This is 2409d8d81063Sfei feng - Sun Microsystems - Beijing China * necessary as we must propagate the key from the 2410d8d81063Sfei feng - Sun Microsystems - Beijing China * global key table of the vap to each sta db entry. 2411d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2412d8d81063Sfei feng - Sun Microsystems - Beijing China static void 2413d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_setanywepkey(struct ieee80211com *ic, const uint8_t mac[IEEE80211_ADDR_LEN]) 2414d8d81063Sfei feng - Sun Microsystems - Beijing China { 2415d8d81063Sfei feng - Sun Microsystems - Beijing China if ((ic->ic_flags & (IEEE80211_F_PRIVACY|IEEE80211_F_WPA)) == 2416d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_F_PRIVACY && 2417d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_def_txkey != IEEE80211_KEYIX_NONE && 2418d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_nw_keys[ic->ic_def_txkey].wk_keyix != IEEE80211_KEYIX_NONE) 2419d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_key_set(ic, &ic->ic_nw_keys[ic->ic_def_txkey], mac); 2420d8d81063Sfei feng - Sun Microsystems - Beijing China } 2421d8d81063Sfei feng - Sun Microsystems - Beijing China 2422d8d81063Sfei feng - Sun Microsystems - Beijing China static void 2423d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_setglobalkeys(struct ieee80211com *ic) 2424d8d81063Sfei feng - Sun Microsystems - Beijing China { 2425d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211_key *wk; 2426d8d81063Sfei feng - Sun Microsystems - Beijing China 2427d8d81063Sfei feng - Sun Microsystems - Beijing China wk = &ic->ic_nw_keys[0]; 2428d8d81063Sfei feng - Sun Microsystems - Beijing China for (; wk < &ic->ic_nw_keys[IEEE80211_WEP_NKID]; wk++) 2429d8d81063Sfei feng - Sun Microsystems - Beijing China if (wk->wk_keyix != IEEE80211_KEYIX_NONE) 2430d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_key_set(ic, wk, ic->ic_macaddr); 2431d8d81063Sfei feng - Sun Microsystems - Beijing China } 2432d8d81063Sfei feng - Sun Microsystems - Beijing China 2433d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2434d8d81063Sfei feng - Sun Microsystems - Beijing China addgroupflags(MWL_HAL_KEYVAL *hk, const struct ieee80211_key *k) 2435d8d81063Sfei feng - Sun Microsystems - Beijing China { 2436d8d81063Sfei feng - Sun Microsystems - Beijing China if (k->wk_flags & IEEE80211_KEY_GROUP) { 2437d8d81063Sfei feng - Sun Microsystems - Beijing China if (k->wk_flags & IEEE80211_KEY_XMIT) 2438d8d81063Sfei feng - Sun Microsystems - Beijing China hk->keyFlags |= KEY_FLAG_TXGROUPKEY; 2439d8d81063Sfei feng - Sun Microsystems - Beijing China if (k->wk_flags & IEEE80211_KEY_RECV) 2440d8d81063Sfei feng - Sun Microsystems - Beijing China hk->keyFlags |= KEY_FLAG_RXGROUPKEY; 2441d8d81063Sfei feng - Sun Microsystems - Beijing China return (1); 2442d8d81063Sfei feng - Sun Microsystems - Beijing China } else 2443d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 2444d8d81063Sfei feng - Sun Microsystems - Beijing China } 2445d8d81063Sfei feng - Sun Microsystems - Beijing China 2446d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2447d8d81063Sfei feng - Sun Microsystems - Beijing China * Set/change channels. 2448d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2449d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2450d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_chan_set(struct mwl_softc *sc, struct mwl_channel *chan) 2451d8d81063Sfei feng - Sun Microsystems - Beijing China { 2452d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_HAL_CHANNEL hchan; 2453d8d81063Sfei feng - Sun Microsystems - Beijing China int maxtxpow; 2454d8d81063Sfei feng - Sun Microsystems - Beijing China 2455d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: mwl_chan_set(): " 2456d8d81063Sfei feng - Sun Microsystems - Beijing China "chan %u MHz/flags 0x%x\n", 2457d8d81063Sfei feng - Sun Microsystems - Beijing China chan->ic_freq, chan->ic_flags); 2458d8d81063Sfei feng - Sun Microsystems - Beijing China 2459d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2460d8d81063Sfei feng - Sun Microsystems - Beijing China * Convert to a HAL channel description with 2461d8d81063Sfei feng - Sun Microsystems - Beijing China * the flags constrained to reflect the current 2462d8d81063Sfei feng - Sun Microsystems - Beijing China * operating mode. 2463d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2464d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_mapchan(&hchan, chan); 2465d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_intrset(sc, 0); /* disable interrupts */ 2466d8d81063Sfei feng - Sun Microsystems - Beijing China 2467d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_hal_setchannel(sc, &hchan); 2468d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2469d8d81063Sfei feng - Sun Microsystems - Beijing China * Tx power is cap'd by the regulatory setting and 2470d8d81063Sfei feng - Sun Microsystems - Beijing China * possibly a user-set limit. We pass the min of 2471d8d81063Sfei feng - Sun Microsystems - Beijing China * these to the hal to apply them to the cal data 2472d8d81063Sfei feng - Sun Microsystems - Beijing China * for this channel. 2473d8d81063Sfei feng - Sun Microsystems - Beijing China * XXX min bound? 2474d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2475d8d81063Sfei feng - Sun Microsystems - Beijing China maxtxpow = 2 * chan->ic_maxregpower; 2476d8d81063Sfei feng - Sun Microsystems - Beijing China if (maxtxpow > 100) 2477d8d81063Sfei feng - Sun Microsystems - Beijing China maxtxpow = 100; 2478d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_hal_settxpower(sc, &hchan, maxtxpow / 2); 2479d8d81063Sfei feng - Sun Microsystems - Beijing China /* NB: potentially change mcast/mgt rates */ 2480d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_setcurchanrates(sc); 2481d8d81063Sfei feng - Sun Microsystems - Beijing China 2482d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_curchan = hchan; 2483d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_intrset(sc, sc->sc_imask); 2484d8d81063Sfei feng - Sun Microsystems - Beijing China 2485d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 2486d8d81063Sfei feng - Sun Microsystems - Beijing China } 2487d8d81063Sfei feng - Sun Microsystems - Beijing China 2488d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2489d8d81063Sfei feng - Sun Microsystems - Beijing China * Convert net80211 channel to a HAL channel. 2490d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2491d8d81063Sfei feng - Sun Microsystems - Beijing China static void 2492d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_mapchan(MWL_HAL_CHANNEL *hc, const struct mwl_channel *chan) 2493d8d81063Sfei feng - Sun Microsystems - Beijing China { 2494d8d81063Sfei feng - Sun Microsystems - Beijing China hc->channel = chan->ic_ieee; 2495d8d81063Sfei feng - Sun Microsystems - Beijing China 2496d8d81063Sfei feng - Sun Microsystems - Beijing China *(uint32_t *)&hc->channelFlags = 0; 2497d8d81063Sfei feng - Sun Microsystems - Beijing China if (((chan)->ic_flags & IEEE80211_CHAN_2GHZ) != 0) 2498d8d81063Sfei feng - Sun Microsystems - Beijing China hc->channelFlags.FreqBand = MWL_FREQ_BAND_2DOT4GHZ; 2499d8d81063Sfei feng - Sun Microsystems - Beijing China else if (((chan)->ic_flags & IEEE80211_CHAN_5GHZ) != 0) 2500d8d81063Sfei feng - Sun Microsystems - Beijing China hc->channelFlags.FreqBand = MWL_FREQ_BAND_5GHZ; 2501d8d81063Sfei feng - Sun Microsystems - Beijing China if (((chan)->ic_flags & IEEE80211_CHAN_HT40) != 0) { 2502d8d81063Sfei feng - Sun Microsystems - Beijing China hc->channelFlags.ChnlWidth = MWL_CH_40_MHz_WIDTH; 2503d8d81063Sfei feng - Sun Microsystems - Beijing China if (((chan)->ic_flags & IEEE80211_CHAN_HT40U) != 0) 2504d8d81063Sfei feng - Sun Microsystems - Beijing China hc->channelFlags.ExtChnlOffset = 2505d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_EXT_CH_ABOVE_CTRL_CH; 2506d8d81063Sfei feng - Sun Microsystems - Beijing China else 2507d8d81063Sfei feng - Sun Microsystems - Beijing China hc->channelFlags.ExtChnlOffset = 2508d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_EXT_CH_BELOW_CTRL_CH; 2509d8d81063Sfei feng - Sun Microsystems - Beijing China } else 2510d8d81063Sfei feng - Sun Microsystems - Beijing China hc->channelFlags.ChnlWidth = MWL_CH_20_MHz_WIDTH; 2511d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX 10MHz channels */ 2512d8d81063Sfei feng - Sun Microsystems - Beijing China } 2513d8d81063Sfei feng - Sun Microsystems - Beijing China 2514d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2515d8d81063Sfei feng - Sun Microsystems - Beijing China * Return the phy mode for with the specified channel. 2516d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2517d8d81063Sfei feng - Sun Microsystems - Beijing China enum ieee80211_phymode 2518d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_chan2mode(const struct mwl_channel *chan) 2519d8d81063Sfei feng - Sun Microsystems - Beijing China { 2520d8d81063Sfei feng - Sun Microsystems - Beijing China 2521d8d81063Sfei feng - Sun Microsystems - Beijing China if (IEEE80211_IS_CHAN_HTA(chan)) 2522d8d81063Sfei feng - Sun Microsystems - Beijing China return (IEEE80211_MODE_11NA); 2523d8d81063Sfei feng - Sun Microsystems - Beijing China else if (IEEE80211_IS_CHAN_HTG(chan)) 2524d8d81063Sfei feng - Sun Microsystems - Beijing China return (IEEE80211_MODE_11NG); 2525d8d81063Sfei feng - Sun Microsystems - Beijing China else if (IEEE80211_IS_CHAN_108G(chan)) 2526d8d81063Sfei feng - Sun Microsystems - Beijing China return (IEEE80211_MODE_TURBO_G); 2527d8d81063Sfei feng - Sun Microsystems - Beijing China else if (IEEE80211_IS_CHAN_ST(chan)) 2528d8d81063Sfei feng - Sun Microsystems - Beijing China return (IEEE80211_MODE_STURBO_A); 2529d8d81063Sfei feng - Sun Microsystems - Beijing China else if (IEEE80211_IS_CHAN_TURBO(chan)) 2530d8d81063Sfei feng - Sun Microsystems - Beijing China return (IEEE80211_MODE_TURBO_A); 2531d8d81063Sfei feng - Sun Microsystems - Beijing China else if (IEEE80211_IS_CHAN_HALF(chan)) 2532d8d81063Sfei feng - Sun Microsystems - Beijing China return (IEEE80211_MODE_HALF); 2533d8d81063Sfei feng - Sun Microsystems - Beijing China else if (IEEE80211_IS_CHAN_QUARTER(chan)) 2534d8d81063Sfei feng - Sun Microsystems - Beijing China return (IEEE80211_MODE_QUARTER); 2535d8d81063Sfei feng - Sun Microsystems - Beijing China else if (IEEE80211_IS_CHAN_A(chan)) 2536d8d81063Sfei feng - Sun Microsystems - Beijing China return (IEEE80211_MODE_11A); 2537d8d81063Sfei feng - Sun Microsystems - Beijing China else if (IEEE80211_IS_CHAN_ANYG(chan)) 2538d8d81063Sfei feng - Sun Microsystems - Beijing China return (IEEE80211_MODE_11G); 2539d8d81063Sfei feng - Sun Microsystems - Beijing China else if (IEEE80211_IS_CHAN_B(chan)) 2540d8d81063Sfei feng - Sun Microsystems - Beijing China return (IEEE80211_MODE_11B); 2541d8d81063Sfei feng - Sun Microsystems - Beijing China else if (IEEE80211_IS_CHAN_FHSS(chan)) 2542d8d81063Sfei feng - Sun Microsystems - Beijing China return (IEEE80211_MODE_FH); 2543d8d81063Sfei feng - Sun Microsystems - Beijing China 2544d8d81063Sfei feng - Sun Microsystems - Beijing China /* NB: should not get here */ 2545d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: mwl_chan2mode(): " 2546d8d81063Sfei feng - Sun Microsystems - Beijing China "cannot map channel to mode; freq %u flags 0x%x\n", 2547d8d81063Sfei feng - Sun Microsystems - Beijing China chan->ic_freq, chan->ic_flags); 2548d8d81063Sfei feng - Sun Microsystems - Beijing China return (IEEE80211_MODE_11B); 2549d8d81063Sfei feng - Sun Microsystems - Beijing China } 2550d8d81063Sfei feng - Sun Microsystems - Beijing China 2551d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX inline or eliminate? */ 2552d8d81063Sfei feng - Sun Microsystems - Beijing China const struct ieee80211_rateset * 2553d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_get_suprates(struct ieee80211com *ic, const struct mwl_channel *c) 2554d8d81063Sfei feng - Sun Microsystems - Beijing China { 2555d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX does this work for 11ng basic rates? */ 2556d8d81063Sfei feng - Sun Microsystems - Beijing China return (&ic->ic_sup_rates[mwl_chan2mode(c)]); 2557d8d81063Sfei feng - Sun Microsystems - Beijing China } 2558d8d81063Sfei feng - Sun Microsystems - Beijing China 2559d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2560d8d81063Sfei feng - Sun Microsystems - Beijing China * Inform firmware of tx rate parameters. 2561d8d81063Sfei feng - Sun Microsystems - Beijing China * Called after a channel change. 2562d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2563d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2564d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_setcurchanrates(struct mwl_softc *sc) 2565d8d81063Sfei feng - Sun Microsystems - Beijing China { 2566d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic; 2567d8d81063Sfei feng - Sun Microsystems - Beijing China const struct ieee80211_rateset *rs; 2568d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_HAL_TXRATE rates; 2569d8d81063Sfei feng - Sun Microsystems - Beijing China 2570cb2cd10cSfei feng - Sun Microsystems - Beijing China (void) memset(&rates, 0, sizeof (rates)); 2571d8d81063Sfei feng - Sun Microsystems - Beijing China rs = mwl_get_suprates(ic, sc->sc_cur_chan); 2572d8d81063Sfei feng - Sun Microsystems - Beijing China /* rate used to send management frames */ 2573d8d81063Sfei feng - Sun Microsystems - Beijing China rates.MgtRate = rs->ir_rates[0] & IEEE80211_RATE_VAL; 2574d8d81063Sfei feng - Sun Microsystems - Beijing China /* rate used to send multicast frames */ 2575d8d81063Sfei feng - Sun Microsystems - Beijing China rates.McastRate = rates.MgtRate; 2576d8d81063Sfei feng - Sun Microsystems - Beijing China 2577d8d81063Sfei feng - Sun Microsystems - Beijing China return (mwl_hal_settxrate_auto(sc, &rates)); 2578d8d81063Sfei feng - Sun Microsystems - Beijing China } 2579d8d81063Sfei feng - Sun Microsystems - Beijing China 2580d8d81063Sfei feng - Sun Microsystems - Beijing China static const struct mwl_hal_channel * 2581d8d81063Sfei feng - Sun Microsystems - Beijing China findhalchannel(const struct mwl_softc *sc, const MWL_HAL_CHANNEL *c) 2582d8d81063Sfei feng - Sun Microsystems - Beijing China { 2583d8d81063Sfei feng - Sun Microsystems - Beijing China const struct mwl_hal_channel *hc; 2584d8d81063Sfei feng - Sun Microsystems - Beijing China const MWL_HAL_CHANNELINFO *ci; 2585d8d81063Sfei feng - Sun Microsystems - Beijing China int chan = c->channel, i; 2586d8d81063Sfei feng - Sun Microsystems - Beijing China 2587d8d81063Sfei feng - Sun Microsystems - Beijing China if (c->channelFlags.FreqBand == MWL_FREQ_BAND_2DOT4GHZ) { 2588d8d81063Sfei feng - Sun Microsystems - Beijing China i = chan - 1; 2589d8d81063Sfei feng - Sun Microsystems - Beijing China if (c->channelFlags.ChnlWidth == MWL_CH_40_MHz_WIDTH) { 2590d8d81063Sfei feng - Sun Microsystems - Beijing China ci = &sc->sc_40M; 2591d8d81063Sfei feng - Sun Microsystems - Beijing China if (c->channelFlags.ExtChnlOffset == 2592d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_EXT_CH_BELOW_CTRL_CH) 2593d8d81063Sfei feng - Sun Microsystems - Beijing China i -= 4; 2594d8d81063Sfei feng - Sun Microsystems - Beijing China } else 2595d8d81063Sfei feng - Sun Microsystems - Beijing China ci = &sc->sc_20M; 2596d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2.4G channel table is directly indexed */ 2597d8d81063Sfei feng - Sun Microsystems - Beijing China hc = ((unsigned)i < ci->nchannels) ? &ci->channels[i] : NULL; 2598d8d81063Sfei feng - Sun Microsystems - Beijing China } else if (c->channelFlags.FreqBand == MWL_FREQ_BAND_5GHZ) { 2599d8d81063Sfei feng - Sun Microsystems - Beijing China if (c->channelFlags.ChnlWidth == MWL_CH_40_MHz_WIDTH) { 2600d8d81063Sfei feng - Sun Microsystems - Beijing China ci = &sc->sc_40M_5G; 2601d8d81063Sfei feng - Sun Microsystems - Beijing China if (c->channelFlags.ExtChnlOffset == 2602d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_EXT_CH_BELOW_CTRL_CH) 2603d8d81063Sfei feng - Sun Microsystems - Beijing China chan -= 4; 2604d8d81063Sfei feng - Sun Microsystems - Beijing China } else 2605d8d81063Sfei feng - Sun Microsystems - Beijing China ci = &sc->sc_20M_5G; 2606d8d81063Sfei feng - Sun Microsystems - Beijing China /* 5GHz channel table is sparse and must be searched */ 2607d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < ci->nchannels; i++) 2608d8d81063Sfei feng - Sun Microsystems - Beijing China if (ci->channels[i].ieee == chan) 2609d8d81063Sfei feng - Sun Microsystems - Beijing China break; 2610d8d81063Sfei feng - Sun Microsystems - Beijing China hc = (i < ci->nchannels) ? &ci->channels[i] : NULL; 2611d8d81063Sfei feng - Sun Microsystems - Beijing China } else 2612d8d81063Sfei feng - Sun Microsystems - Beijing China hc = NULL; 2613d8d81063Sfei feng - Sun Microsystems - Beijing China return (hc); 2614d8d81063Sfei feng - Sun Microsystems - Beijing China } 2615d8d81063Sfei feng - Sun Microsystems - Beijing China 2616d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2617d8d81063Sfei feng - Sun Microsystems - Beijing China * Map SKU+country code to region code for radar bin'ing. 2618d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2619d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2620d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_map2regioncode(const struct mwl_regdomain *rd) 2621d8d81063Sfei feng - Sun Microsystems - Beijing China { 2622d8d81063Sfei feng - Sun Microsystems - Beijing China switch (rd->regdomain) { 2623d8d81063Sfei feng - Sun Microsystems - Beijing China case SKU_FCC: 2624d8d81063Sfei feng - Sun Microsystems - Beijing China case SKU_FCC3: 2625d8d81063Sfei feng - Sun Microsystems - Beijing China return (DOMAIN_CODE_FCC); 2626d8d81063Sfei feng - Sun Microsystems - Beijing China case SKU_CA: 2627d8d81063Sfei feng - Sun Microsystems - Beijing China return (DOMAIN_CODE_IC); 2628d8d81063Sfei feng - Sun Microsystems - Beijing China case SKU_ETSI: 2629d8d81063Sfei feng - Sun Microsystems - Beijing China case SKU_ETSI2: 2630d8d81063Sfei feng - Sun Microsystems - Beijing China case SKU_ETSI3: 2631d8d81063Sfei feng - Sun Microsystems - Beijing China if (rd->country == CTRY_SPAIN) 2632d8d81063Sfei feng - Sun Microsystems - Beijing China return (DOMAIN_CODE_SPAIN); 2633d8d81063Sfei feng - Sun Microsystems - Beijing China if (rd->country == CTRY_FRANCE || rd->country == CTRY_FRANCE2) 2634d8d81063Sfei feng - Sun Microsystems - Beijing China return (DOMAIN_CODE_FRANCE); 2635d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX force 1.3.1 radar type */ 2636d8d81063Sfei feng - Sun Microsystems - Beijing China return (DOMAIN_CODE_ETSI_131); 2637d8d81063Sfei feng - Sun Microsystems - Beijing China case SKU_JAPAN: 2638d8d81063Sfei feng - Sun Microsystems - Beijing China return (DOMAIN_CODE_MKK); 2639d8d81063Sfei feng - Sun Microsystems - Beijing China case SKU_ROW: 2640d8d81063Sfei feng - Sun Microsystems - Beijing China return (DOMAIN_CODE_DGT); /* Taiwan */ 2641d8d81063Sfei feng - Sun Microsystems - Beijing China case SKU_APAC: 2642d8d81063Sfei feng - Sun Microsystems - Beijing China case SKU_APAC2: 2643d8d81063Sfei feng - Sun Microsystems - Beijing China case SKU_APAC3: 2644d8d81063Sfei feng - Sun Microsystems - Beijing China return (DOMAIN_CODE_AUS); /* Australia */ 2645d8d81063Sfei feng - Sun Microsystems - Beijing China } 2646d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX KOREA? */ 2647d8d81063Sfei feng - Sun Microsystems - Beijing China return (DOMAIN_CODE_FCC); /* XXX? */ 2648d8d81063Sfei feng - Sun Microsystems - Beijing China } 2649d8d81063Sfei feng - Sun Microsystems - Beijing China 2650d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2651d8d81063Sfei feng - Sun Microsystems - Beijing China * Setup the rx data structures. This should only be 2652d8d81063Sfei feng - Sun Microsystems - Beijing China * done once or we may get out of sync with the firmware. 2653d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2654d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2655d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_startrecv(struct mwl_softc *sc) 2656d8d81063Sfei feng - Sun Microsystems - Beijing China { 2657d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_rx_ring *ring; 2658d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_rxdesc *ds; 2659d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_rxbuf *bf, *prev; 2660d8d81063Sfei feng - Sun Microsystems - Beijing China 2661d8d81063Sfei feng - Sun Microsystems - Beijing China int i; 2662d8d81063Sfei feng - Sun Microsystems - Beijing China 2663d8d81063Sfei feng - Sun Microsystems - Beijing China ring = &sc->sc_rxring; 2664d8d81063Sfei feng - Sun Microsystems - Beijing China bf = ring->buf; 2665d8d81063Sfei feng - Sun Microsystems - Beijing China 2666d8d81063Sfei feng - Sun Microsystems - Beijing China prev = NULL; 2667d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < MWL_RX_RING_COUNT; i++, bf++) { 2668d8d81063Sfei feng - Sun Microsystems - Beijing China ds = bf->bf_desc; 2669d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2670d8d81063Sfei feng - Sun Microsystems - Beijing China * NB: DMA buffer contents is known to be unmodified 2671d8d81063Sfei feng - Sun Microsystems - Beijing China * so there's no need to flush the data cache. 2672d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2673d8d81063Sfei feng - Sun Microsystems - Beijing China 2674d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2675d8d81063Sfei feng - Sun Microsystems - Beijing China * Setup descriptor. 2676d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2677d8d81063Sfei feng - Sun Microsystems - Beijing China ds->QosCtrl = 0; 2678d8d81063Sfei feng - Sun Microsystems - Beijing China ds->RSSI = 0; 2679d8d81063Sfei feng - Sun Microsystems - Beijing China ds->Status = EAGLE_RXD_STATUS_IDLE; 2680d8d81063Sfei feng - Sun Microsystems - Beijing China ds->Channel = 0; 2681d8d81063Sfei feng - Sun Microsystems - Beijing China ds->PktLen = LE_16(MWL_AGGR_SIZE); 2682d8d81063Sfei feng - Sun Microsystems - Beijing China ds->SQ2 = 0; 2683d8d81063Sfei feng - Sun Microsystems - Beijing China ds->pPhysBuffData = LE_32(bf->bf_baddr); 2684d8d81063Sfei feng - Sun Microsystems - Beijing China /* NB: don't touch pPhysNext, set once */ 2685d8d81063Sfei feng - Sun Microsystems - Beijing China ds->RxControl = EAGLE_RXD_CTRL_DRIVER_OWN; 2686d8d81063Sfei feng - Sun Microsystems - Beijing China 2687d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl, 2688d8d81063Sfei feng - Sun Microsystems - Beijing China i * sizeof (struct mwl_rxdesc), 2689d8d81063Sfei feng - Sun Microsystems - Beijing China sizeof (struct mwl_rxdesc), 2690d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV); 2691d8d81063Sfei feng - Sun Microsystems - Beijing China 2692d8d81063Sfei feng - Sun Microsystems - Beijing China if (prev != NULL) { 2693d8d81063Sfei feng - Sun Microsystems - Beijing China ds = prev->bf_desc; 2694d8d81063Sfei feng - Sun Microsystems - Beijing China ds->pPhysNext = LE_32(bf->bf_daddr); 2695d8d81063Sfei feng - Sun Microsystems - Beijing China } 2696d8d81063Sfei feng - Sun Microsystems - Beijing China prev = bf; 2697d8d81063Sfei feng - Sun Microsystems - Beijing China } 2698d8d81063Sfei feng - Sun Microsystems - Beijing China 2699d8d81063Sfei feng - Sun Microsystems - Beijing China if (prev != NULL) { 2700d8d81063Sfei feng - Sun Microsystems - Beijing China ds = prev->bf_desc; 2701d8d81063Sfei feng - Sun Microsystems - Beijing China ds->pPhysNext = ring->physaddr; 2702d8d81063Sfei feng - Sun Microsystems - Beijing China } 2703d8d81063Sfei feng - Sun Microsystems - Beijing China 2704d8d81063Sfei feng - Sun Microsystems - Beijing China /* set filters, etc. */ 2705d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_mode_init(sc); 2706d8d81063Sfei feng - Sun Microsystems - Beijing China 2707d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 2708d8d81063Sfei feng - Sun Microsystems - Beijing China } 2709d8d81063Sfei feng - Sun Microsystems - Beijing China 2710d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2711d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_mode_init(struct mwl_softc *sc) 2712d8d81063Sfei feng - Sun Microsystems - Beijing China { 2713d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2714d8d81063Sfei feng - Sun Microsystems - Beijing China * NB: Ignore promisc in hostap mode; it's set by the 2715d8d81063Sfei feng - Sun Microsystems - Beijing China * bridge. This is wrong but we have no way to 2716d8d81063Sfei feng - Sun Microsystems - Beijing China * identify internal requests (from the bridge) 2717d8d81063Sfei feng - Sun Microsystems - Beijing China * versus external requests such as for tcpdump. 2718d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2719d8d81063Sfei feng - Sun Microsystems - Beijing China /* mwl_setmcastfilter - not support now */ 2720d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_hal_setpromisc(sc, 0); 2721d8d81063Sfei feng - Sun Microsystems - Beijing China 2722d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 2723d8d81063Sfei feng - Sun Microsystems - Beijing China } 2724d8d81063Sfei feng - Sun Microsystems - Beijing China 2725d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2726d8d81063Sfei feng - Sun Microsystems - Beijing China * Kick the firmware to tell it there are new tx descriptors 2727d8d81063Sfei feng - Sun Microsystems - Beijing China * for processing. The driver says what h/w q has work in 2728d8d81063Sfei feng - Sun Microsystems - Beijing China * case the f/w ever gets smarter. 2729d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2730d8d81063Sfei feng - Sun Microsystems - Beijing China /* ARGSUSED */ 2731d8d81063Sfei feng - Sun Microsystems - Beijing China static void 2732d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_txstart(struct mwl_softc *sc, int qnum) 2733d8d81063Sfei feng - Sun Microsystems - Beijing China { 2734d8d81063Sfei feng - Sun Microsystems - Beijing China 2735d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_H2A_INTERRUPT_EVENTS, 2736d8d81063Sfei feng - Sun Microsystems - Beijing China MACREG_H2ARIC_BIT_PPA_READY); 2737d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_ctl_read4(sc, MACREG_REG_INT_CODE); 2738d8d81063Sfei feng - Sun Microsystems - Beijing China } 2739d8d81063Sfei feng - Sun Microsystems - Beijing China 2740d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2741d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type) 2742d8d81063Sfei feng - Sun Microsystems - Beijing China { 2743d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc = (struct mwl_softc *)ic; 2744d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_tx_ring *ring; 2745d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_txdesc *ds; 2746d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_txbuf *bf; 2747d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211_frame *wh, *wh1; 2748d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211_node *ni = NULL; 2749d8d81063Sfei feng - Sun Microsystems - Beijing China 2750d8d81063Sfei feng - Sun Microsystems - Beijing China int err, off; 2751d8d81063Sfei feng - Sun Microsystems - Beijing China int mblen, pktlen, hdrlen; 2752d8d81063Sfei feng - Sun Microsystems - Beijing China mblk_t *m, *m0; 2753d8d81063Sfei feng - Sun Microsystems - Beijing China uint8_t *addr_4, *txbuf; 2754d8d81063Sfei feng - Sun Microsystems - Beijing China uint16_t *pfwlen; 2755d8d81063Sfei feng - Sun Microsystems - Beijing China 2756d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_TXLOCK(sc); 2757d8d81063Sfei feng - Sun Microsystems - Beijing China 2758d8d81063Sfei feng - Sun Microsystems - Beijing China err = DDI_SUCCESS; 2759d8d81063Sfei feng - Sun Microsystems - Beijing China if (!MWL_IS_RUNNING(sc) || MWL_IS_SUSPEND(sc)) { 2760d8d81063Sfei feng - Sun Microsystems - Beijing China err = ENXIO; 2761d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail1; 2762d8d81063Sfei feng - Sun Microsystems - Beijing China } 2763d8d81063Sfei feng - Sun Microsystems - Beijing China 2764d8d81063Sfei feng - Sun Microsystems - Beijing China ring = &sc->sc_txring[1]; 2765d8d81063Sfei feng - Sun Microsystems - Beijing China if (ring->queued > 15) { 2766d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_TX, "mwl: mwl_send(): " 2767d8d81063Sfei feng - Sun Microsystems - Beijing China "no txbuf, %d\n", ring->queued); 2768d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_need_sched = 1; 2769d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_tx_nobuf++; 2770d8d81063Sfei feng - Sun Microsystems - Beijing China err = ENOMEM; 2771d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail1; 2772d8d81063Sfei feng - Sun Microsystems - Beijing China } 2773d8d81063Sfei feng - Sun Microsystems - Beijing China 2774d8d81063Sfei feng - Sun Microsystems - Beijing China m = allocb(msgdsize(mp) + 32, BPRI_MED); 2775d8d81063Sfei feng - Sun Microsystems - Beijing China if (m == NULL) { 2776d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_TX, "mwl: mwl_send():" 2777d8d81063Sfei feng - Sun Microsystems - Beijing China "can't alloc mblk.\n"); 2778d8d81063Sfei feng - Sun Microsystems - Beijing China err = DDI_FAILURE; 2779d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail1; 2780d8d81063Sfei feng - Sun Microsystems - Beijing China } 2781d8d81063Sfei feng - Sun Microsystems - Beijing China 2782d8d81063Sfei feng - Sun Microsystems - Beijing China for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) { 2783d8d81063Sfei feng - Sun Microsystems - Beijing China mblen = MBLKL(m0); 2784d8d81063Sfei feng - Sun Microsystems - Beijing China (void) bcopy(m0->b_rptr, m->b_rptr + off, mblen); 2785d8d81063Sfei feng - Sun Microsystems - Beijing China off += mblen; 2786d8d81063Sfei feng - Sun Microsystems - Beijing China } 2787d8d81063Sfei feng - Sun Microsystems - Beijing China m->b_wptr += off; 2788d8d81063Sfei feng - Sun Microsystems - Beijing China 2789d8d81063Sfei feng - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)m->b_rptr; 2790d8d81063Sfei feng - Sun Microsystems - Beijing China ni = ieee80211_find_txnode(ic, wh->i_addr1); 2791d8d81063Sfei feng - Sun Microsystems - Beijing China if (ni == NULL) { 2792d8d81063Sfei feng - Sun Microsystems - Beijing China err = DDI_FAILURE; 2793d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_tx_err++; 2794d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail2; 2795d8d81063Sfei feng - Sun Microsystems - Beijing China } 2796d8d81063Sfei feng - Sun Microsystems - Beijing China 2797d8d81063Sfei feng - Sun Microsystems - Beijing China hdrlen = sizeof (*wh); 2798d8d81063Sfei feng - Sun Microsystems - Beijing China pktlen = msgdsize(m); 2799d8d81063Sfei feng - Sun Microsystems - Beijing China 2800d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ieee80211_encap(ic, m, ni); 2801d8d81063Sfei feng - Sun Microsystems - Beijing China 2802d8d81063Sfei feng - Sun Microsystems - Beijing China if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 2803d8d81063Sfei feng - Sun Microsystems - Beijing China const struct ieee80211_cipher *cip; 2804d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211_key *k; 2805d8d81063Sfei feng - Sun Microsystems - Beijing China k = ieee80211_crypto_encap(ic, m); 2806d8d81063Sfei feng - Sun Microsystems - Beijing China if (k == NULL) { 2807d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_tx_err++; 2808d8d81063Sfei feng - Sun Microsystems - Beijing China err = DDI_FAILURE; 2809d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail3; 2810d8d81063Sfei feng - Sun Microsystems - Beijing China } 2811d8d81063Sfei feng - Sun Microsystems - Beijing China 2812d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2813d8d81063Sfei feng - Sun Microsystems - Beijing China * Adjust the packet length for the crypto additions 2814d8d81063Sfei feng - Sun Microsystems - Beijing China * done during encap and any other bits that the f/w 2815d8d81063Sfei feng - Sun Microsystems - Beijing China * will add later on. 2816d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2817d8d81063Sfei feng - Sun Microsystems - Beijing China cip = k->wk_cipher; 2818d8d81063Sfei feng - Sun Microsystems - Beijing China pktlen += cip->ic_header + cip->ic_miclen + cip->ic_trailer; 2819d8d81063Sfei feng - Sun Microsystems - Beijing China /* packet header may have moved, reset our local pointer */ 2820d8d81063Sfei feng - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)m->b_rptr; 2821d8d81063Sfei feng - Sun Microsystems - Beijing China } 2822d8d81063Sfei feng - Sun Microsystems - Beijing China 2823d8d81063Sfei feng - Sun Microsystems - Beijing China ds = &ring->desc[ring->cur]; 2824d8d81063Sfei feng - Sun Microsystems - Beijing China bf = &ring->buf[ring->cur]; 2825d8d81063Sfei feng - Sun Microsystems - Beijing China 2826d8d81063Sfei feng - Sun Microsystems - Beijing China bf->bf_node = ieee80211_ref_node(ni); 2827d8d81063Sfei feng - Sun Microsystems - Beijing China txbuf = (uint8_t *)bf->bf_mem; 2828d8d81063Sfei feng - Sun Microsystems - Beijing China 2829d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2830d8d81063Sfei feng - Sun Microsystems - Beijing China * inject FW specific fields into the 802.11 frame 2831d8d81063Sfei feng - Sun Microsystems - Beijing China * 2832d8d81063Sfei feng - Sun Microsystems - Beijing China * 2 bytes FW len (inject) 2833d8d81063Sfei feng - Sun Microsystems - Beijing China * 24 bytes 802.11 frame header 2834d8d81063Sfei feng - Sun Microsystems - Beijing China * 6 bytes addr4 (inject) 2835d8d81063Sfei feng - Sun Microsystems - Beijing China * n bytes 802.11 frame body 2836d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2837d8d81063Sfei feng - Sun Microsystems - Beijing China pfwlen = (uint16_t *)txbuf; 2838d8d81063Sfei feng - Sun Microsystems - Beijing China *pfwlen = pktlen - hdrlen; 2839d8d81063Sfei feng - Sun Microsystems - Beijing China wh1 = (struct ieee80211_frame *)(txbuf + 2); 2840d8d81063Sfei feng - Sun Microsystems - Beijing China bcopy(wh, wh1, sizeof (struct ieee80211_frame)); 2841d8d81063Sfei feng - Sun Microsystems - Beijing China addr_4 = txbuf + (sizeof (struct ieee80211_frame) + sizeof (uint16_t)); 2842d8d81063Sfei feng - Sun Microsystems - Beijing China (void) memset(addr_4, 0, 6); 2843d8d81063Sfei feng - Sun Microsystems - Beijing China bcopy(m->b_rptr + sizeof (struct ieee80211_frame), txbuf + 32, *pfwlen); 2844d8d81063Sfei feng - Sun Microsystems - Beijing China pktlen += 8; 2845d8d81063Sfei feng - Sun Microsystems - Beijing China 2846d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(bf->txbuf_dma.dma_hdl, 2847d8d81063Sfei feng - Sun Microsystems - Beijing China 0, 2848d8d81063Sfei feng - Sun Microsystems - Beijing China pktlen, 2849d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV); 2850d8d81063Sfei feng - Sun Microsystems - Beijing China 2851d8d81063Sfei feng - Sun Microsystems - Beijing China ds->QosCtrl = 0; 2852d8d81063Sfei feng - Sun Microsystems - Beijing China ds->PktLen = (uint16_t)pktlen; 2853d8d81063Sfei feng - Sun Microsystems - Beijing China ds->PktPtr = bf->bf_baddr; 2854d8d81063Sfei feng - Sun Microsystems - Beijing China ds->Status = LE_32(EAGLE_TXD_STATUS_FW_OWNED); 2855d8d81063Sfei feng - Sun Microsystems - Beijing China ds->Format = 0; 2856d8d81063Sfei feng - Sun Microsystems - Beijing China ds->pad = 0; 2857d8d81063Sfei feng - Sun Microsystems - Beijing China ds->ack_wcb_addr = 0; 2858d8d81063Sfei feng - Sun Microsystems - Beijing China ds->TxPriority = 1; 2859d8d81063Sfei feng - Sun Microsystems - Beijing China 2860d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_TX, "mwl: mwl_send(): " 2861d8d81063Sfei feng - Sun Microsystems - Beijing China "tx desc Status %x, DataRate %x, TxPriority %x, QosCtrl %x, " 2862d8d81063Sfei feng - Sun Microsystems - Beijing China "PktLen %x, SapPktInfo %x, Format %x, Pad %x, ack_wcb_addr %x\n", 2863d8d81063Sfei feng - Sun Microsystems - Beijing China ds->Status, ds->DataRate, ds->TxPriority, ds->QosCtrl, ds->PktLen, 2864d8d81063Sfei feng - Sun Microsystems - Beijing China ds->SapPktInfo, ds->Format, ds->pad, ds->ack_wcb_addr); 2865d8d81063Sfei feng - Sun Microsystems - Beijing China 2866d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl, 2867d8d81063Sfei feng - Sun Microsystems - Beijing China ring->cur * sizeof (struct mwl_txdesc), 2868d8d81063Sfei feng - Sun Microsystems - Beijing China sizeof (struct mwl_txdesc), 2869d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV); 2870d8d81063Sfei feng - Sun Microsystems - Beijing China 2871d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_TX, "mwl: mwl_send(): " 2872d8d81063Sfei feng - Sun Microsystems - Beijing China "pktlen = %u, slot = %u, queued = %x\n", 2873d8d81063Sfei feng - Sun Microsystems - Beijing China mblen, ring->cur, ring->queued); 2874d8d81063Sfei feng - Sun Microsystems - Beijing China 2875d8d81063Sfei feng - Sun Microsystems - Beijing China ring->queued++; 2876d8d81063Sfei feng - Sun Microsystems - Beijing China ring->cur = (ring->cur + 1) % MWL_TX_RING_COUNT; 2877d8d81063Sfei feng - Sun Microsystems - Beijing China 2878d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2879d8d81063Sfei feng - Sun Microsystems - Beijing China * NB: We don't need to lock against tx done because 2880d8d81063Sfei feng - Sun Microsystems - Beijing China * this just prods the firmware to check the transmit 2881d8d81063Sfei feng - Sun Microsystems - Beijing China * descriptors. The firmware will also start fetching 2882d8d81063Sfei feng - Sun Microsystems - Beijing China * descriptors by itself if it notices new ones are 2883d8d81063Sfei feng - Sun Microsystems - Beijing China * present when it goes to deliver a tx done interrupt 2884d8d81063Sfei feng - Sun Microsystems - Beijing China * to the host. So if we race with tx done processing 2885d8d81063Sfei feng - Sun Microsystems - Beijing China * it's ok. Delivering the kick here rather than in 2886d8d81063Sfei feng - Sun Microsystems - Beijing China * mwl_tx_start is an optimization to avoid poking the 2887d8d81063Sfei feng - Sun Microsystems - Beijing China * firmware for each packet. 2888d8d81063Sfei feng - Sun Microsystems - Beijing China * 2889d8d81063Sfei feng - Sun Microsystems - Beijing China * NB: the queue id isn't used so 0 is ok. 2890d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2891d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_txstart(sc, 0); 2892d8d81063Sfei feng - Sun Microsystems - Beijing China 2893d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_stats.is_tx_frags++; 2894d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_stats.is_tx_bytes += pktlen; 2895d8d81063Sfei feng - Sun Microsystems - Beijing China 2896d8d81063Sfei feng - Sun Microsystems - Beijing China fail3: 2897d8d81063Sfei feng - Sun Microsystems - Beijing China ieee80211_free_node(ni); 2898d8d81063Sfei feng - Sun Microsystems - Beijing China fail2: 2899d8d81063Sfei feng - Sun Microsystems - Beijing China freemsg(m); 2900d8d81063Sfei feng - Sun Microsystems - Beijing China fail1: 2901d8d81063Sfei feng - Sun Microsystems - Beijing China if ((type & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA || 2902d8d81063Sfei feng - Sun Microsystems - Beijing China err == DDI_SUCCESS) 2903d8d81063Sfei feng - Sun Microsystems - Beijing China freemsg(mp); 2904d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_TXUNLOCK(sc); 2905d8d81063Sfei feng - Sun Microsystems - Beijing China return (err); 2906d8d81063Sfei feng - Sun Microsystems - Beijing China } 2907d8d81063Sfei feng - Sun Microsystems - Beijing China 2908d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2909d8d81063Sfei feng - Sun Microsystems - Beijing China * This function is called periodically (every 200ms) during scanning to 2910d8d81063Sfei feng - Sun Microsystems - Beijing China * switch from one channel to another. 2911d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2912d8d81063Sfei feng - Sun Microsystems - Beijing China static void 2913d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_next_scan(void *arg) 2914d8d81063Sfei feng - Sun Microsystems - Beijing China { 2915d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc = (struct mwl_softc *)arg; 2916d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic; 2917d8d81063Sfei feng - Sun Microsystems - Beijing China 2918d8d81063Sfei feng - Sun Microsystems - Beijing China if (ic->ic_state == IEEE80211_S_SCAN) 2919d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ieee80211_next_scan(ic); 2920d8d81063Sfei feng - Sun Microsystems - Beijing China 2921d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_scan_id = 0; 2922d8d81063Sfei feng - Sun Microsystems - Beijing China } 2923d8d81063Sfei feng - Sun Microsystems - Beijing China 2924d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2925d8d81063Sfei feng - Sun Microsystems - Beijing China * Convert a legacy rate set to a firmware bitmask. 2926d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2927d8d81063Sfei feng - Sun Microsystems - Beijing China static uint32_t 2928d8d81063Sfei feng - Sun Microsystems - Beijing China get_rate_bitmap(const struct ieee80211_rateset *rs) 2929d8d81063Sfei feng - Sun Microsystems - Beijing China { 2930d8d81063Sfei feng - Sun Microsystems - Beijing China uint32_t rates; 2931d8d81063Sfei feng - Sun Microsystems - Beijing China int i; 2932d8d81063Sfei feng - Sun Microsystems - Beijing China 2933d8d81063Sfei feng - Sun Microsystems - Beijing China rates = 0; 2934d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 0; i < rs->ir_nrates; i++) 2935d8d81063Sfei feng - Sun Microsystems - Beijing China switch (rs->ir_rates[i] & IEEE80211_RATE_VAL) { 2936d8d81063Sfei feng - Sun Microsystems - Beijing China case 2: rates |= 0x001; break; 2937d8d81063Sfei feng - Sun Microsystems - Beijing China case 4: rates |= 0x002; break; 2938d8d81063Sfei feng - Sun Microsystems - Beijing China case 11: rates |= 0x004; break; 2939d8d81063Sfei feng - Sun Microsystems - Beijing China case 22: rates |= 0x008; break; 2940d8d81063Sfei feng - Sun Microsystems - Beijing China case 44: rates |= 0x010; break; 2941d8d81063Sfei feng - Sun Microsystems - Beijing China case 12: rates |= 0x020; break; 2942d8d81063Sfei feng - Sun Microsystems - Beijing China case 18: rates |= 0x040; break; 2943d8d81063Sfei feng - Sun Microsystems - Beijing China case 24: rates |= 0x080; break; 2944d8d81063Sfei feng - Sun Microsystems - Beijing China case 36: rates |= 0x100; break; 2945d8d81063Sfei feng - Sun Microsystems - Beijing China case 48: rates |= 0x200; break; 2946d8d81063Sfei feng - Sun Microsystems - Beijing China case 72: rates |= 0x400; break; 2947d8d81063Sfei feng - Sun Microsystems - Beijing China case 96: rates |= 0x800; break; 2948d8d81063Sfei feng - Sun Microsystems - Beijing China case 108: rates |= 0x1000; break; 2949d8d81063Sfei feng - Sun Microsystems - Beijing China } 2950d8d81063Sfei feng - Sun Microsystems - Beijing China return (rates); 2951d8d81063Sfei feng - Sun Microsystems - Beijing China } 2952d8d81063Sfei feng - Sun Microsystems - Beijing China 2953d8d81063Sfei feng - Sun Microsystems - Beijing China /* 2954d8d81063Sfei feng - Sun Microsystems - Beijing China * Craft station database entry for station. 2955d8d81063Sfei feng - Sun Microsystems - Beijing China * NB: use host byte order here, the hal handles byte swapping. 2956d8d81063Sfei feng - Sun Microsystems - Beijing China */ 2957d8d81063Sfei feng - Sun Microsystems - Beijing China static MWL_HAL_PEERINFO * 2958d8d81063Sfei feng - Sun Microsystems - Beijing China mkpeerinfo(MWL_HAL_PEERINFO *pi, const struct ieee80211_node *ni) 2959d8d81063Sfei feng - Sun Microsystems - Beijing China { 2960cb2cd10cSfei feng - Sun Microsystems - Beijing China (void) memset(pi, 0, sizeof (*pi)); 2961d8d81063Sfei feng - Sun Microsystems - Beijing China pi->LegacyRateBitMap = get_rate_bitmap(&ni->in_rates); 2962d8d81063Sfei feng - Sun Microsystems - Beijing China pi->CapInfo = ni->in_capinfo; 2963d8d81063Sfei feng - Sun Microsystems - Beijing China return (pi); 2964d8d81063Sfei feng - Sun Microsystems - Beijing China } 2965d8d81063Sfei feng - Sun Microsystems - Beijing China 2966d8d81063Sfei feng - Sun Microsystems - Beijing China static int 2967d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 2968d8d81063Sfei feng - Sun Microsystems - Beijing China { 2969d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc = (struct mwl_softc *)ic; 2970d8d81063Sfei feng - Sun Microsystems - Beijing China enum ieee80211_state ostate; 2971d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211_channel *ic_chan; 2972d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211_node *ni = NULL; 2973d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_HAL_PEERINFO pi; 2974d8d81063Sfei feng - Sun Microsystems - Beijing China uint32_t chan; 2975d8d81063Sfei feng - Sun Microsystems - Beijing China 2976d8d81063Sfei feng - Sun Microsystems - Beijing China if (sc->sc_scan_id != 0) { 2977d8d81063Sfei feng - Sun Microsystems - Beijing China (void) untimeout(sc->sc_scan_id); 2978d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_scan_id = 0; 2979d8d81063Sfei feng - Sun Microsystems - Beijing China } 2980d8d81063Sfei feng - Sun Microsystems - Beijing China 2981d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GLOCK(sc); 2982d8d81063Sfei feng - Sun Microsystems - Beijing China 2983d8d81063Sfei feng - Sun Microsystems - Beijing China ostate = ic->ic_state; 2984d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_MSG, "mwl: mwl_newstate(): " 2985d8d81063Sfei feng - Sun Microsystems - Beijing China "ostate %x -> nstate %x\n", 2986d8d81063Sfei feng - Sun Microsystems - Beijing China ostate, nstate); 2987d8d81063Sfei feng - Sun Microsystems - Beijing China 2988d8d81063Sfei feng - Sun Microsystems - Beijing China switch (nstate) { 2989d8d81063Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_INIT: 2990d8d81063Sfei feng - Sun Microsystems - Beijing China break; 2991d8d81063Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_SCAN: 2992d8d81063Sfei feng - Sun Microsystems - Beijing China if (ostate != IEEE80211_S_INIT) { 2993d8d81063Sfei feng - Sun Microsystems - Beijing China ic_chan = ic->ic_curchan; 2994d8d81063Sfei feng - Sun Microsystems - Beijing China chan = ieee80211_chan2ieee(ic, ic_chan); 2995d8d81063Sfei feng - Sun Microsystems - Beijing China if (chan != 0 && chan != IEEE80211_CHAN_ANY) { 2996d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_cur_chan = 2997d8d81063Sfei feng - Sun Microsystems - Beijing China &sc->sc_channels[3 * chan - 2]; 2998d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_MSG, "mwl: mwl_newstate(): " 2999d8d81063Sfei feng - Sun Microsystems - Beijing China "chan num is %u, sc chan is %u\n", 3000d8d81063Sfei feng - Sun Microsystems - Beijing China chan, sc->sc_cur_chan->ic_ieee); 3001d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_chan_set(sc, sc->sc_cur_chan); 3002d8d81063Sfei feng - Sun Microsystems - Beijing China } 3003d8d81063Sfei feng - Sun Microsystems - Beijing China } 3004d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_scan_id = timeout(mwl_next_scan, (void *)sc, 3005d8d81063Sfei feng - Sun Microsystems - Beijing China drv_usectohz(250000)); 3006d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3007d8d81063Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_AUTH: 3008d8d81063Sfei feng - Sun Microsystems - Beijing China ic_chan = ic->ic_curchan; 3009d8d81063Sfei feng - Sun Microsystems - Beijing China chan = ieee80211_chan2ieee(ic, ic_chan); 3010d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_cur_chan = &sc->sc_channels[3 * chan - 2]; 3011d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_MSG, "mwl: mwl_newstate(): " 3012d8d81063Sfei feng - Sun Microsystems - Beijing China "chan num is %u, sc chan is %u\n", 3013d8d81063Sfei feng - Sun Microsystems - Beijing China chan, sc->sc_cur_chan->ic_ieee); 3014d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_chan_set(sc, sc->sc_cur_chan); 3015d8d81063Sfei feng - Sun Microsystems - Beijing China ni = ic->ic_bss; 3016d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_hal_newstation(sc, ic->ic_macaddr, 0, 0, NULL, 0, 0); 3017d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_setanywepkey(ic, ni->in_macaddr); 3018d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3019d8d81063Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_ASSOC: 3020d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3021d8d81063Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_RUN: 3022d8d81063Sfei feng - Sun Microsystems - Beijing China ni = ic->ic_bss; 3023d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_hal_newstation(sc, 3024d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr, 0, 0, mkpeerinfo(&pi, ni), 0, 0); 3025d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_setglobalkeys(ic); 3026d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_hal_setassocid(sc, 3027d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_bss->in_bssid, ic->ic_bss->in_associd); 3028d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_setrates(ic); 3029d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_hal_setrtsthreshold(sc, ic->ic_rtsthreshold); 3030d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_hal_setcsmode(sc, CSMODE_AUTO_ENA); 3031d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3032d8d81063Sfei feng - Sun Microsystems - Beijing China default: 3033d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3034d8d81063Sfei feng - Sun Microsystems - Beijing China } 3035d8d81063Sfei feng - Sun Microsystems - Beijing China 3036d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GUNLOCK(sc); 3037d8d81063Sfei feng - Sun Microsystems - Beijing China 3038d8d81063Sfei feng - Sun Microsystems - Beijing China return (sc->sc_newstate(ic, nstate, arg)); 3039d8d81063Sfei feng - Sun Microsystems - Beijing China } 3040d8d81063Sfei feng - Sun Microsystems - Beijing China 3041d8d81063Sfei feng - Sun Microsystems - Beijing China /* 3042d8d81063Sfei feng - Sun Microsystems - Beijing China * Set the interrupt mask. 3043d8d81063Sfei feng - Sun Microsystems - Beijing China */ 3044d8d81063Sfei feng - Sun Microsystems - Beijing China static void 3045d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_intrset(struct mwl_softc *sc, uint32_t mask) 3046d8d81063Sfei feng - Sun Microsystems - Beijing China { 3047d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_A2H_INTERRUPT_MASK, 0); 3048d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_ctl_read4(sc, MACREG_REG_INT_CODE); 3049d8d81063Sfei feng - Sun Microsystems - Beijing China 3050d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_hal_imask = mask; 3051d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_A2H_INTERRUPT_MASK, mask); 3052d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_ctl_read4(sc, MACREG_REG_INT_CODE); 3053d8d81063Sfei feng - Sun Microsystems - Beijing China } 3054d8d81063Sfei feng - Sun Microsystems - Beijing China 3055d8d81063Sfei feng - Sun Microsystems - Beijing China /* 3056d8d81063Sfei feng - Sun Microsystems - Beijing China * Return the current ISR setting and clear the cause. 3057d8d81063Sfei feng - Sun Microsystems - Beijing China */ 3058d8d81063Sfei feng - Sun Microsystems - Beijing China static void 3059d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_getisr(struct mwl_softc *sc, uint32_t *status) 3060d8d81063Sfei feng - Sun Microsystems - Beijing China { 3061d8d81063Sfei feng - Sun Microsystems - Beijing China uint32_t cause; 3062d8d81063Sfei feng - Sun Microsystems - Beijing China 3063d8d81063Sfei feng - Sun Microsystems - Beijing China cause = mwl_ctl_read4(sc, MACREG_REG_A2H_INTERRUPT_CAUSE); 3064d8d81063Sfei feng - Sun Microsystems - Beijing China if (cause == 0xffffffff) { /* card removed */ 3065d8d81063Sfei feng - Sun Microsystems - Beijing China cause = 0; 3066d8d81063Sfei feng - Sun Microsystems - Beijing China } else if (cause != 0) { 3067d8d81063Sfei feng - Sun Microsystems - Beijing China /* clear cause bits */ 3068d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_ctl_write4(sc, MACREG_REG_A2H_INTERRUPT_CAUSE, 3069d8d81063Sfei feng - Sun Microsystems - Beijing China cause & ~sc->sc_hal_imask); 3070d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_ctl_read4(sc, MACREG_REG_INT_CODE); 3071d8d81063Sfei feng - Sun Microsystems - Beijing China cause &= sc->sc_hal_imask; 3072d8d81063Sfei feng - Sun Microsystems - Beijing China } 3073d8d81063Sfei feng - Sun Microsystems - Beijing China *status = cause; 3074d8d81063Sfei feng - Sun Microsystems - Beijing China } 3075d8d81063Sfei feng - Sun Microsystems - Beijing China 3076d8d81063Sfei feng - Sun Microsystems - Beijing China static void 3077d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_tx_intr(struct mwl_softc *sc) 3078d8d81063Sfei feng - Sun Microsystems - Beijing China { 3079d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic; 3080d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_tx_ring *ring; 3081d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_txdesc *ds; 3082d8d81063Sfei feng - Sun Microsystems - Beijing China 3083d8d81063Sfei feng - Sun Microsystems - Beijing China uint32_t status; 3084d8d81063Sfei feng - Sun Microsystems - Beijing China 3085d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_TXLOCK(sc); 3086d8d81063Sfei feng - Sun Microsystems - Beijing China 3087d8d81063Sfei feng - Sun Microsystems - Beijing China ring = &sc->sc_txring[1]; 3088d8d81063Sfei feng - Sun Microsystems - Beijing China 3089d8d81063Sfei feng - Sun Microsystems - Beijing China if (!(ring->queued)) { 3090d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_TXUNLOCK(sc); 3091d8d81063Sfei feng - Sun Microsystems - Beijing China return; 3092d8d81063Sfei feng - Sun Microsystems - Beijing China } 3093d8d81063Sfei feng - Sun Microsystems - Beijing China 3094d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl, 3095d8d81063Sfei feng - Sun Microsystems - Beijing China 0, 3096d8d81063Sfei feng - Sun Microsystems - Beijing China ring->txdesc_dma.alength, 3097d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORCPU); 3098d8d81063Sfei feng - Sun Microsystems - Beijing China 3099d8d81063Sfei feng - Sun Microsystems - Beijing China for (;;) { 3100d8d81063Sfei feng - Sun Microsystems - Beijing China ds = &ring->desc[ring->next]; 3101d8d81063Sfei feng - Sun Microsystems - Beijing China 3102d8d81063Sfei feng - Sun Microsystems - Beijing China status = LE_32(ds->Status); 3103d8d81063Sfei feng - Sun Microsystems - Beijing China 3104d8d81063Sfei feng - Sun Microsystems - Beijing China if (status & LE_32(EAGLE_TXD_STATUS_FW_OWNED)) { 3105d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3106d8d81063Sfei feng - Sun Microsystems - Beijing China } 3107d8d81063Sfei feng - Sun Microsystems - Beijing China 3108d8d81063Sfei feng - Sun Microsystems - Beijing China if (status == LE_32(EAGLE_TXD_STATUS_IDLE)) { 3109d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3110d8d81063Sfei feng - Sun Microsystems - Beijing China } 3111d8d81063Sfei feng - Sun Microsystems - Beijing China 3112d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_TX, "mwl: mwl_tx_intr(): " 3113d8d81063Sfei feng - Sun Microsystems - Beijing China "recv tx desc status %x, datarate %x, txpriority %x, " 3114d8d81063Sfei feng - Sun Microsystems - Beijing China "QosCtrl %x, pktLen %x, SapPktInfo %x, Format %x, " 3115d8d81063Sfei feng - Sun Microsystems - Beijing China "pad %x, ack_wcb_addr %x\n", 3116d8d81063Sfei feng - Sun Microsystems - Beijing China ds->Status, ds->DataRate, ds->TxPriority, 3117d8d81063Sfei feng - Sun Microsystems - Beijing China ds->QosCtrl, ds->PktLen, ds->SapPktInfo, 3118d8d81063Sfei feng - Sun Microsystems - Beijing China ds->Format, ds->pad, ds->ack_wcb_addr); 3119d8d81063Sfei feng - Sun Microsystems - Beijing China 3120d8d81063Sfei feng - Sun Microsystems - Beijing China /* descriptor is no longer valid */ 3121d8d81063Sfei feng - Sun Microsystems - Beijing China ds->Status = LE_32(EAGLE_TXD_STATUS_IDLE); 3122d8d81063Sfei feng - Sun Microsystems - Beijing China 3123d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->txdesc_dma.dma_hdl, 3124d8d81063Sfei feng - Sun Microsystems - Beijing China ring->next * sizeof (struct mwl_txdesc), 3125d8d81063Sfei feng - Sun Microsystems - Beijing China sizeof (struct mwl_txdesc), 3126d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV); 3127d8d81063Sfei feng - Sun Microsystems - Beijing China 3128d8d81063Sfei feng - Sun Microsystems - Beijing China ring->queued--; 3129d8d81063Sfei feng - Sun Microsystems - Beijing China ring->next = (ring->next + 1) % MWL_TX_RING_COUNT; 3130d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_TX, "mwl: mwl_tx_intr(): " 3131d8d81063Sfei feng - Sun Microsystems - Beijing China " tx done idx=%u, queued= %d\n", 3132d8d81063Sfei feng - Sun Microsystems - Beijing China ring->next, ring->queued); 3133d8d81063Sfei feng - Sun Microsystems - Beijing China 3134d8d81063Sfei feng - Sun Microsystems - Beijing China if (sc->sc_need_sched && 3135d8d81063Sfei feng - Sun Microsystems - Beijing China (ring->queued < MWL_TX_RING_COUNT)) { 3136d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_need_sched = 0; 3137d8d81063Sfei feng - Sun Microsystems - Beijing China mac_tx_update(ic->ic_mach); 3138d8d81063Sfei feng - Sun Microsystems - Beijing China } 3139d8d81063Sfei feng - Sun Microsystems - Beijing China 3140d8d81063Sfei feng - Sun Microsystems - Beijing China } 3141d8d81063Sfei feng - Sun Microsystems - Beijing China 3142d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_TXUNLOCK(sc); 3143d8d81063Sfei feng - Sun Microsystems - Beijing China } 3144d8d81063Sfei feng - Sun Microsystems - Beijing China 3145d8d81063Sfei feng - Sun Microsystems - Beijing China /* 3146d8d81063Sfei feng - Sun Microsystems - Beijing China * Convert hardware signal strength to rssi. The value 3147d8d81063Sfei feng - Sun Microsystems - Beijing China * provided by the device has the noise floor added in; 3148d8d81063Sfei feng - Sun Microsystems - Beijing China * we need to compensate for this but we don't have that 3149d8d81063Sfei feng - Sun Microsystems - Beijing China * so we use a fixed value. 3150d8d81063Sfei feng - Sun Microsystems - Beijing China * 3151d8d81063Sfei feng - Sun Microsystems - Beijing China * The offset of 8 is good for both 2.4 and 5GHz. The LNA 3152d8d81063Sfei feng - Sun Microsystems - Beijing China * offset is already set as part of the initial gain. This 3153d8d81063Sfei feng - Sun Microsystems - Beijing China * will give at least +/- 3dB for 2.4GHz and +/- 5dB for 5GHz. 3154d8d81063Sfei feng - Sun Microsystems - Beijing China */ 3155d8d81063Sfei feng - Sun Microsystems - Beijing China static int 3156d8d81063Sfei feng - Sun Microsystems - Beijing China cvtrssi(uint8_t ssi) 3157d8d81063Sfei feng - Sun Microsystems - Beijing China { 3158d8d81063Sfei feng - Sun Microsystems - Beijing China int rssi = (int)ssi + 8; 3159d8d81063Sfei feng - Sun Microsystems - Beijing China /* XXX hack guess until we have a real noise floor */ 3160d8d81063Sfei feng - Sun Microsystems - Beijing China rssi = 2 * (87 - rssi); /* NB: .5 dBm units */ 3161d8d81063Sfei feng - Sun Microsystems - Beijing China return (rssi < 0 ? 0 : rssi > 127 ? 127 : rssi); 3162d8d81063Sfei feng - Sun Microsystems - Beijing China } 3163d8d81063Sfei feng - Sun Microsystems - Beijing China 3164d8d81063Sfei feng - Sun Microsystems - Beijing China static void 3165d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_rx_intr(struct mwl_softc *sc) 3166d8d81063Sfei feng - Sun Microsystems - Beijing China { 3167d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic; 3168d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_rx_ring *ring; 3169d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211_node *ni; 3170d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211_frame *wh; 3171d8d81063Sfei feng - Sun Microsystems - Beijing China 3172d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_rxbuf *bf; 3173d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_rxdesc *ds; 3174d8d81063Sfei feng - Sun Microsystems - Beijing China mblk_t *mp0; 3175d8d81063Sfei feng - Sun Microsystems - Beijing China 3176d8d81063Sfei feng - Sun Microsystems - Beijing China int ntodo, len, rssi; 3177d8d81063Sfei feng - Sun Microsystems - Beijing China uint8_t *data, status; 3178d8d81063Sfei feng - Sun Microsystems - Beijing China 3179d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_RXLOCK(sc); 3180d8d81063Sfei feng - Sun Microsystems - Beijing China 3181d8d81063Sfei feng - Sun Microsystems - Beijing China ring = &sc->sc_rxring; 3182d8d81063Sfei feng - Sun Microsystems - Beijing China for (ntodo = MWL_RX_RING_COUNT; ntodo > 0; ntodo--) { 3183d8d81063Sfei feng - Sun Microsystems - Beijing China bf = &ring->buf[ring->cur]; 3184d8d81063Sfei feng - Sun Microsystems - Beijing China ds = bf->bf_desc; 3185d8d81063Sfei feng - Sun Microsystems - Beijing China data = bf->bf_mem; 3186d8d81063Sfei feng - Sun Microsystems - Beijing China 3187d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl, 3188d8d81063Sfei feng - Sun Microsystems - Beijing China ring->cur * sizeof (struct mwl_rxdesc), 3189d8d81063Sfei feng - Sun Microsystems - Beijing China sizeof (struct mwl_rxdesc), 3190d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORCPU); 3191d8d81063Sfei feng - Sun Microsystems - Beijing China 3192d8d81063Sfei feng - Sun Microsystems - Beijing China if (ds->RxControl != EAGLE_RXD_CTRL_DMA_OWN) 3193d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3194d8d81063Sfei feng - Sun Microsystems - Beijing China 3195d8d81063Sfei feng - Sun Microsystems - Beijing China status = ds->Status; 3196d8d81063Sfei feng - Sun Microsystems - Beijing China if (status & EAGLE_RXD_STATUS_DECRYPT_ERR_MASK) { 3197d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_CRYPTO, "mwl: mwl_rx_intr(): " 3198d8d81063Sfei feng - Sun Microsystems - Beijing China "rx decrypt error\n"); 3199d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_rx_err++; 3200d8d81063Sfei feng - Sun Microsystems - Beijing China } 3201d8d81063Sfei feng - Sun Microsystems - Beijing China 3202d8d81063Sfei feng - Sun Microsystems - Beijing China /* 3203d8d81063Sfei feng - Sun Microsystems - Beijing China * Sync the data buffer. 3204d8d81063Sfei feng - Sun Microsystems - Beijing China */ 3205d8d81063Sfei feng - Sun Microsystems - Beijing China len = LE_16(ds->PktLen); 3206d8d81063Sfei feng - Sun Microsystems - Beijing China 3207d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(bf->rxbuf_dma.dma_hdl, 3208d8d81063Sfei feng - Sun Microsystems - Beijing China 0, 3209d8d81063Sfei feng - Sun Microsystems - Beijing China bf->rxbuf_dma.alength, 3210d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORCPU); 3211d8d81063Sfei feng - Sun Microsystems - Beijing China 3212d8d81063Sfei feng - Sun Microsystems - Beijing China if (len < 32 || len > sc->sc_dmabuf_size) { 3213d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_RX, "mwl: mwl_rx_intr(): " 3214d8d81063Sfei feng - Sun Microsystems - Beijing China "packet len error %d\n", len); 3215d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_rx_err++; 3216d8d81063Sfei feng - Sun Microsystems - Beijing China goto rxnext; 3217d8d81063Sfei feng - Sun Microsystems - Beijing China } 3218d8d81063Sfei feng - Sun Microsystems - Beijing China 3219d8d81063Sfei feng - Sun Microsystems - Beijing China mp0 = allocb(sc->sc_dmabuf_size, BPRI_MED); 3220d8d81063Sfei feng - Sun Microsystems - Beijing China if (mp0 == NULL) { 3221d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_RX, "mwl: mwl_rx_intr(): " 3222d8d81063Sfei feng - Sun Microsystems - Beijing China "alloc mblk error\n"); 3223d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_rx_nobuf++; 3224d8d81063Sfei feng - Sun Microsystems - Beijing China goto rxnext; 3225d8d81063Sfei feng - Sun Microsystems - Beijing China } 3226d8d81063Sfei feng - Sun Microsystems - Beijing China bcopy(data+ 2, mp0->b_wptr, 24); 3227d8d81063Sfei feng - Sun Microsystems - Beijing China mp0->b_wptr += 24; 3228d8d81063Sfei feng - Sun Microsystems - Beijing China bcopy(data + 32, mp0->b_wptr, len - 32); 3229d8d81063Sfei feng - Sun Microsystems - Beijing China mp0->b_wptr += (len - 32); 3230d8d81063Sfei feng - Sun Microsystems - Beijing China 3231d8d81063Sfei feng - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)mp0->b_rptr; 3232d8d81063Sfei feng - Sun Microsystems - Beijing China if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 3233d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_FC0_TYPE_CTL) { 3234d8d81063Sfei feng - Sun Microsystems - Beijing China freemsg(mp0); 3235d8d81063Sfei feng - Sun Microsystems - Beijing China goto rxnext; 3236d8d81063Sfei feng - Sun Microsystems - Beijing China } 3237d8d81063Sfei feng - Sun Microsystems - Beijing China 3238d8d81063Sfei feng - Sun Microsystems - Beijing China /* 3239d8d81063Sfei feng - Sun Microsystems - Beijing China * The f/w strips WEP header but doesn't clear 3240d8d81063Sfei feng - Sun Microsystems - Beijing China * the WEP bit; mark the packet with M_WEP so 3241d8d81063Sfei feng - Sun Microsystems - Beijing China * net80211 will treat the data as decrypted. 3242d8d81063Sfei feng - Sun Microsystems - Beijing China * While here also clear the PWR_MGT bit since 3243d8d81063Sfei feng - Sun Microsystems - Beijing China * power save is handled by the firmware and 3244d8d81063Sfei feng - Sun Microsystems - Beijing China * passing this up will potentially cause the 3245d8d81063Sfei feng - Sun Microsystems - Beijing China * upper layer to put a station in power save 3246d8d81063Sfei feng - Sun Microsystems - Beijing China * (except when configured with MWL_HOST_PS_SUPPORT). 3247d8d81063Sfei feng - Sun Microsystems - Beijing China */ 3248d8d81063Sfei feng - Sun Microsystems - Beijing China #ifdef MWL_HOST_PS_SUPPORT 3249d8d81063Sfei feng - Sun Microsystems - Beijing China wh->i_fc[1] &= ~IEEE80211_FC1_WEP; 3250d8d81063Sfei feng - Sun Microsystems - Beijing China #else 3251d8d81063Sfei feng - Sun Microsystems - Beijing China wh->i_fc[1] &= ~(IEEE80211_FC1_WEP | IEEE80211_FC1_PWR_MGT); 3252d8d81063Sfei feng - Sun Microsystems - Beijing China #endif 3253d8d81063Sfei feng - Sun Microsystems - Beijing China 3254d8d81063Sfei feng - Sun Microsystems - Beijing China /* calculate rssi early so we can re-use for each aggregate */ 3255d8d81063Sfei feng - Sun Microsystems - Beijing China rssi = cvtrssi(ds->RSSI); 3256d8d81063Sfei feng - Sun Microsystems - Beijing China 3257d8d81063Sfei feng - Sun Microsystems - Beijing China ni = ieee80211_find_rxnode(ic, wh); 3258d8d81063Sfei feng - Sun Microsystems - Beijing China 3259d8d81063Sfei feng - Sun Microsystems - Beijing China /* send the frame to the 802.11 layer */ 3260d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ieee80211_input(ic, mp0, ni, rssi, 0); 3261d8d81063Sfei feng - Sun Microsystems - Beijing China ieee80211_free_node(ni); 3262d8d81063Sfei feng - Sun Microsystems - Beijing China rxnext: 3263d8d81063Sfei feng - Sun Microsystems - Beijing China /* 3264d8d81063Sfei feng - Sun Microsystems - Beijing China * Setup descriptor. 3265d8d81063Sfei feng - Sun Microsystems - Beijing China */ 3266d8d81063Sfei feng - Sun Microsystems - Beijing China ds->QosCtrl = 0; 3267d8d81063Sfei feng - Sun Microsystems - Beijing China ds->RSSI = 0; 3268d8d81063Sfei feng - Sun Microsystems - Beijing China ds->Status = EAGLE_RXD_STATUS_IDLE; 3269d8d81063Sfei feng - Sun Microsystems - Beijing China ds->Channel = 0; 3270d8d81063Sfei feng - Sun Microsystems - Beijing China ds->PktLen = LE_16(MWL_AGGR_SIZE); 3271d8d81063Sfei feng - Sun Microsystems - Beijing China ds->SQ2 = 0; 3272d8d81063Sfei feng - Sun Microsystems - Beijing China ds->pPhysBuffData = bf->bf_baddr; 3273d8d81063Sfei feng - Sun Microsystems - Beijing China /* NB: don't touch pPhysNext, set once */ 3274d8d81063Sfei feng - Sun Microsystems - Beijing China ds->RxControl = EAGLE_RXD_CTRL_DRIVER_OWN; 3275d8d81063Sfei feng - Sun Microsystems - Beijing China 3276d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl, 3277d8d81063Sfei feng - Sun Microsystems - Beijing China ring->cur * sizeof (struct mwl_rxdesc), 3278d8d81063Sfei feng - Sun Microsystems - Beijing China sizeof (struct mwl_rxdesc), 3279d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV); 3280d8d81063Sfei feng - Sun Microsystems - Beijing China 3281d8d81063Sfei feng - Sun Microsystems - Beijing China /* NB: ignore ENOMEM so we process more descriptors */ 3282d8d81063Sfei feng - Sun Microsystems - Beijing China ring->cur = (ring->cur + 1) % MWL_RX_RING_COUNT; 3283d8d81063Sfei feng - Sun Microsystems - Beijing China } 3284d8d81063Sfei feng - Sun Microsystems - Beijing China 3285d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_RXUNLOCK(sc); 3286d8d81063Sfei feng - Sun Microsystems - Beijing China } 3287d8d81063Sfei feng - Sun Microsystems - Beijing China 3288d8d81063Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/ 3289d8d81063Sfei feng - Sun Microsystems - Beijing China static uint_t 3290d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_softintr(caddr_t data, caddr_t unused) 3291d8d81063Sfei feng - Sun Microsystems - Beijing China { 3292d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc = (struct mwl_softc *)data; 3293d8d81063Sfei feng - Sun Microsystems - Beijing China 3294d8d81063Sfei feng - Sun Microsystems - Beijing China /* 3295d8d81063Sfei feng - Sun Microsystems - Beijing China * Check if the soft interrupt is triggered by another 3296d8d81063Sfei feng - Sun Microsystems - Beijing China * driver at the same level. 3297d8d81063Sfei feng - Sun Microsystems - Beijing China */ 3298d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GLOCK(sc); 3299d8d81063Sfei feng - Sun Microsystems - Beijing China if (sc->sc_rx_pend) { 3300d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_rx_pend = 0; 3301d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GUNLOCK(sc); 3302d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_rx_intr(sc); 3303d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_INTR_CLAIMED); 3304d8d81063Sfei feng - Sun Microsystems - Beijing China } 3305d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GUNLOCK(sc); 3306d8d81063Sfei feng - Sun Microsystems - Beijing China 3307d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_INTR_UNCLAIMED); 3308d8d81063Sfei feng - Sun Microsystems - Beijing China } 3309d8d81063Sfei feng - Sun Microsystems - Beijing China 3310d8d81063Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/ 3311d8d81063Sfei feng - Sun Microsystems - Beijing China static uint_t 3312d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_intr(caddr_t arg, caddr_t unused) 3313d8d81063Sfei feng - Sun Microsystems - Beijing China { 3314d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc = (struct mwl_softc *)arg; 3315d8d81063Sfei feng - Sun Microsystems - Beijing China uint32_t status; 3316d8d81063Sfei feng - Sun Microsystems - Beijing China 3317d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GLOCK(sc); 3318d8d81063Sfei feng - Sun Microsystems - Beijing China 3319d8d81063Sfei feng - Sun Microsystems - Beijing China if (!MWL_IS_RUNNING(sc) || MWL_IS_SUSPEND(sc)) { 3320d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GUNLOCK(sc); 3321d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_INTR_UNCLAIMED); 3322d8d81063Sfei feng - Sun Microsystems - Beijing China } 3323d8d81063Sfei feng - Sun Microsystems - Beijing China 3324d8d81063Sfei feng - Sun Microsystems - Beijing China /* 3325d8d81063Sfei feng - Sun Microsystems - Beijing China * Figure out the reason(s) for the interrupt. 3326d8d81063Sfei feng - Sun Microsystems - Beijing China */ 3327d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_getisr(sc, &status); /* NB: clears ISR too */ 3328d8d81063Sfei feng - Sun Microsystems - Beijing China if (status == 0) { 3329d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GUNLOCK(sc); 3330d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_INTR_UNCLAIMED); 3331d8d81063Sfei feng - Sun Microsystems - Beijing China } 3332d8d81063Sfei feng - Sun Microsystems - Beijing China 3333d8d81063Sfei feng - Sun Microsystems - Beijing China if (status & MACREG_A2HRIC_BIT_RX_RDY) { 3334d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_rx_pend = 1; 3335d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_trigger_softint(sc->sc_softintr_hdl, NULL); 3336d8d81063Sfei feng - Sun Microsystems - Beijing China } 3337d8d81063Sfei feng - Sun Microsystems - Beijing China if (status & MACREG_A2HRIC_BIT_TX_DONE) { 3338d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_tx_intr(sc); 3339d8d81063Sfei feng - Sun Microsystems - Beijing China } 3340d8d81063Sfei feng - Sun Microsystems - Beijing China if (status & MACREG_A2HRIC_BIT_BA_WATCHDOG) { 3341d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_INTR, "mwl: mwl_intr(): " 3342d8d81063Sfei feng - Sun Microsystems - Beijing China "ba watchdog\n"); 3343d8d81063Sfei feng - Sun Microsystems - Beijing China } 3344d8d81063Sfei feng - Sun Microsystems - Beijing China if (status & MACREG_A2HRIC_BIT_OPC_DONE) { 3345d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_INTR, "mwl: mwl_intr(): " 3346d8d81063Sfei feng - Sun Microsystems - Beijing China "opc done\n"); 3347d8d81063Sfei feng - Sun Microsystems - Beijing China } 3348d8d81063Sfei feng - Sun Microsystems - Beijing China if (status & MACREG_A2HRIC_BIT_MAC_EVENT) { 3349d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_INTR, "mwl: mwl_intr(): " 3350d8d81063Sfei feng - Sun Microsystems - Beijing China "mac event\n"); 3351d8d81063Sfei feng - Sun Microsystems - Beijing China } 3352d8d81063Sfei feng - Sun Microsystems - Beijing China if (status & MACREG_A2HRIC_BIT_ICV_ERROR) { 3353d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_INTR, "mwl: mwl_intr(): " 3354d8d81063Sfei feng - Sun Microsystems - Beijing China "ICV error\n"); 3355d8d81063Sfei feng - Sun Microsystems - Beijing China } 3356d8d81063Sfei feng - Sun Microsystems - Beijing China if (status & MACREG_A2HRIC_BIT_QUEUE_EMPTY) { 3357d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_INTR, "mwl: mwl_intr(): " 3358d8d81063Sfei feng - Sun Microsystems - Beijing China "queue empty\n"); 3359d8d81063Sfei feng - Sun Microsystems - Beijing China } 3360d8d81063Sfei feng - Sun Microsystems - Beijing China if (status & MACREG_A2HRIC_BIT_QUEUE_FULL) { 3361d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_INTR, "mwl: mwl_intr(): " 3362d8d81063Sfei feng - Sun Microsystems - Beijing China "queue full\n"); 3363d8d81063Sfei feng - Sun Microsystems - Beijing China } 3364d8d81063Sfei feng - Sun Microsystems - Beijing China if (status & MACREG_A2HRIC_BIT_RADAR_DETECT) { 3365d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_INTR, "mwl: mwl_intr(): " 3366d8d81063Sfei feng - Sun Microsystems - Beijing China "radar detect\n"); 3367d8d81063Sfei feng - Sun Microsystems - Beijing China } 3368d8d81063Sfei feng - Sun Microsystems - Beijing China if (status & MACREG_A2HRIC_BIT_CHAN_SWITCH) { 3369d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_INTR, "mwl: mwl_intr(): " 3370d8d81063Sfei feng - Sun Microsystems - Beijing China "chan switch\n"); 3371d8d81063Sfei feng - Sun Microsystems - Beijing China } 3372d8d81063Sfei feng - Sun Microsystems - Beijing China 3373d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GUNLOCK(sc); 3374d8d81063Sfei feng - Sun Microsystems - Beijing China 3375d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_INTR_CLAIMED); 3376d8d81063Sfei feng - Sun Microsystems - Beijing China } 3377d8d81063Sfei feng - Sun Microsystems - Beijing China 3378d8d81063Sfei feng - Sun Microsystems - Beijing China static int 3379d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_init(struct mwl_softc *sc) 3380d8d81063Sfei feng - Sun Microsystems - Beijing China { 3381d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic; 3382d8d81063Sfei feng - Sun Microsystems - Beijing China int err = 0; 3383d8d81063Sfei feng - Sun Microsystems - Beijing China 3384d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_intrset(sc, 0); 3385d8d81063Sfei feng - Sun Microsystems - Beijing China 3386d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_txantenna = 0; /* h/w default */ 3387d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_rxantenna = 0; /* h/w default */ 3388d8d81063Sfei feng - Sun Microsystems - Beijing China 3389d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_hal_setantenna(sc, WL_ANTENNATYPE_RX, sc->sc_rxantenna); 3390d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3391d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: mwl_init(): " 3392d8d81063Sfei feng - Sun Microsystems - Beijing China "could not set rx antenna\n"); 3393d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3394d8d81063Sfei feng - Sun Microsystems - Beijing China } 3395d8d81063Sfei feng - Sun Microsystems - Beijing China 3396d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_hal_setantenna(sc, WL_ANTENNATYPE_TX, sc->sc_txantenna); 3397d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3398d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: init(): " 3399d8d81063Sfei feng - Sun Microsystems - Beijing China "could not set tx antenna\n"); 3400d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3401d8d81063Sfei feng - Sun Microsystems - Beijing China } 3402d8d81063Sfei feng - Sun Microsystems - Beijing China 3403d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_hal_setradio(sc, 1, WL_AUTO_PREAMBLE); 3404d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3405d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: init(): " 3406d8d81063Sfei feng - Sun Microsystems - Beijing China "could not set radio\n"); 3407d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3408d8d81063Sfei feng - Sun Microsystems - Beijing China } 3409d8d81063Sfei feng - Sun Microsystems - Beijing China 3410d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_hal_setwmm(sc, (ic->ic_flags & IEEE80211_F_WME) != 0); 3411d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3412d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: init(): " 3413d8d81063Sfei feng - Sun Microsystems - Beijing China "could not set wme\n"); 3414d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3415d8d81063Sfei feng - Sun Microsystems - Beijing China } 3416d8d81063Sfei feng - Sun Microsystems - Beijing China 3417d8d81063Sfei feng - Sun Microsystems - Beijing China /* select default channel */ 3418d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_ibss_chan = &ic->ic_sup_channels[0]; 3419d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_curchan = ic->ic_ibss_chan; 3420d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_cur_chan = &sc->sc_channels[1]; 3421d8d81063Sfei feng - Sun Microsystems - Beijing China 3422d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_chan_set(sc, sc->sc_cur_chan); 3423d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3424d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: init(): " 3425d8d81063Sfei feng - Sun Microsystems - Beijing China "could not set wme\n"); 3426d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3427d8d81063Sfei feng - Sun Microsystems - Beijing China } 3428d8d81063Sfei feng - Sun Microsystems - Beijing China 3429d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_hal_setrateadaptmode(sc, 0); 3430d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3431d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: init(): " 3432d8d81063Sfei feng - Sun Microsystems - Beijing China "could not set rate adapt mode\n"); 3433d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3434d8d81063Sfei feng - Sun Microsystems - Beijing China } 3435d8d81063Sfei feng - Sun Microsystems - Beijing China 3436d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_hal_setoptimizationlevel(sc, 3437d8d81063Sfei feng - Sun Microsystems - Beijing China (ic->ic_flags & IEEE80211_F_BURST) != 0); 3438d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3439d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: init(): " 3440d8d81063Sfei feng - Sun Microsystems - Beijing China "could not set optimization level\n"); 3441d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3442d8d81063Sfei feng - Sun Microsystems - Beijing China } 3443d8d81063Sfei feng - Sun Microsystems - Beijing China 3444d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_hal_setregioncode(sc, mwl_map2regioncode(&sc->sc_regdomain)); 3445d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3446d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: init(): " 3447d8d81063Sfei feng - Sun Microsystems - Beijing China "could not set regioncode\n"); 3448d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3449d8d81063Sfei feng - Sun Microsystems - Beijing China } 3450d8d81063Sfei feng - Sun Microsystems - Beijing China 3451d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_startrecv(sc); 3452d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3453d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: init(): " 3454d8d81063Sfei feng - Sun Microsystems - Beijing China "could not set start recv logic\n"); 3455d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3456d8d81063Sfei feng - Sun Microsystems - Beijing China } 3457d8d81063Sfei feng - Sun Microsystems - Beijing China 3458d8d81063Sfei feng - Sun Microsystems - Beijing China /* 3459d8d81063Sfei feng - Sun Microsystems - Beijing China * Enable interrupts. 3460d8d81063Sfei feng - Sun Microsystems - Beijing China */ 3461d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_imask = MACREG_A2HRIC_BIT_RX_RDY 3462d8d81063Sfei feng - Sun Microsystems - Beijing China | MACREG_A2HRIC_BIT_TX_DONE 3463d8d81063Sfei feng - Sun Microsystems - Beijing China | MACREG_A2HRIC_BIT_OPC_DONE 3464d8d81063Sfei feng - Sun Microsystems - Beijing China | MACREG_A2HRIC_BIT_ICV_ERROR 3465d8d81063Sfei feng - Sun Microsystems - Beijing China | MACREG_A2HRIC_BIT_RADAR_DETECT 3466d8d81063Sfei feng - Sun Microsystems - Beijing China | MACREG_A2HRIC_BIT_CHAN_SWITCH 3467d8d81063Sfei feng - Sun Microsystems - Beijing China | MACREG_A2HRIC_BIT_BA_WATCHDOG 3468d8d81063Sfei feng - Sun Microsystems - Beijing China | MACREQ_A2HRIC_BIT_TX_ACK; 3469d8d81063Sfei feng - Sun Microsystems - Beijing China 3470d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_intrset(sc, sc->sc_imask); 3471d8d81063Sfei feng - Sun Microsystems - Beijing China 3472d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_hal_start(sc); 3473d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3474d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: init(): " 3475d8d81063Sfei feng - Sun Microsystems - Beijing China "could not get hal start\n"); 3476d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3477d8d81063Sfei feng - Sun Microsystems - Beijing China } 3478d8d81063Sfei feng - Sun Microsystems - Beijing China 3479d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_hal_setinframode(sc); 3480d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3481d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: init(): " 3482d8d81063Sfei feng - Sun Microsystems - Beijing China "could not set infra mode\n"); 3483d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3484d8d81063Sfei feng - Sun Microsystems - Beijing China } 3485d8d81063Sfei feng - Sun Microsystems - Beijing China 3486d8d81063Sfei feng - Sun Microsystems - Beijing China fail: 3487d8d81063Sfei feng - Sun Microsystems - Beijing China return (err); 3488d8d81063Sfei feng - Sun Microsystems - Beijing China } 3489d8d81063Sfei feng - Sun Microsystems - Beijing China 3490d8d81063Sfei feng - Sun Microsystems - Beijing China static int 3491d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_resume(struct mwl_softc *sc) 3492d8d81063Sfei feng - Sun Microsystems - Beijing China { 3493d8d81063Sfei feng - Sun Microsystems - Beijing China int qid, err = 0; 3494d8d81063Sfei feng - Sun Microsystems - Beijing China 3495d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_fwload(sc, NULL); 3496d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3497d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_SR, "mwl: mwl_resume(): " 3498d8d81063Sfei feng - Sun Microsystems - Beijing China "failed to load fw\n"); 3499d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3500d8d81063Sfei feng - Sun Microsystems - Beijing China } 3501d8d81063Sfei feng - Sun Microsystems - Beijing China 3502d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_gethwspecs(sc); 3503d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3504d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_SR, "mwl: mwl_resume(): " 3505d8d81063Sfei feng - Sun Microsystems - Beijing China "failed to get hw spec\n"); 3506d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3507d8d81063Sfei feng - Sun Microsystems - Beijing China } 3508d8d81063Sfei feng - Sun Microsystems - Beijing China 3509d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_alloc_rx_ring(sc, MWL_RX_RING_COUNT); 3510d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3511d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_SR, "mwl: mwl_resume(): " 3512d8d81063Sfei feng - Sun Microsystems - Beijing China "could not alloc cmd dma buffer\n"); 3513d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3514d8d81063Sfei feng - Sun Microsystems - Beijing China } 3515d8d81063Sfei feng - Sun Microsystems - Beijing China 3516d8d81063Sfei feng - Sun Microsystems - Beijing China for (qid = 0; qid < MWL_NUM_TX_QUEUES; qid++) { 3517d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_alloc_tx_ring(sc, 3518d8d81063Sfei feng - Sun Microsystems - Beijing China &sc->sc_txring[qid], MWL_TX_RING_COUNT); 3519d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3520d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_SR, "mwl: mwl_resume(): " 3521d8d81063Sfei feng - Sun Microsystems - Beijing China "could not alloc tx ring %d\n", qid); 3522d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3523d8d81063Sfei feng - Sun Microsystems - Beijing China } 3524d8d81063Sfei feng - Sun Microsystems - Beijing China } 3525d8d81063Sfei feng - Sun Microsystems - Beijing China 3526d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_setupdma(sc); 3527d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3528d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_SR, "mwl: mwl_resume(): " 3529d8d81063Sfei feng - Sun Microsystems - Beijing China "could not setup dma\n"); 3530d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3531d8d81063Sfei feng - Sun Microsystems - Beijing China } 3532d8d81063Sfei feng - Sun Microsystems - Beijing China 3533d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_setup_txq(sc); 3534d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3535d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_SR, "mwl: mwl_resume(): " 3536d8d81063Sfei feng - Sun Microsystems - Beijing China "could not setup txq\n"); 3537d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail; 3538d8d81063Sfei feng - Sun Microsystems - Beijing China } 3539d8d81063Sfei feng - Sun Microsystems - Beijing China 3540d8d81063Sfei feng - Sun Microsystems - Beijing China fail: 3541d8d81063Sfei feng - Sun Microsystems - Beijing China return (err); 3542d8d81063Sfei feng - Sun Microsystems - Beijing China } 3543d8d81063Sfei feng - Sun Microsystems - Beijing China 3544d8d81063Sfei feng - Sun Microsystems - Beijing China static void 3545d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_stop(struct mwl_softc *sc) 3546d8d81063Sfei feng - Sun Microsystems - Beijing China { 3547d8d81063Sfei feng - Sun Microsystems - Beijing China int err; 3548d8d81063Sfei feng - Sun Microsystems - Beijing China 3549d8d81063Sfei feng - Sun Microsystems - Beijing China /* by pass if it's quiesced */ 3550d8d81063Sfei feng - Sun Microsystems - Beijing China if (!MWL_IS_QUIESCE(sc)) 3551d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GLOCK(sc); 3552d8d81063Sfei feng - Sun Microsystems - Beijing China 3553d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_hal_stop(sc); 3554d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3555d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: mwl_stop(): " 3556d8d81063Sfei feng - Sun Microsystems - Beijing China "could not stop hw\n"); 3557d8d81063Sfei feng - Sun Microsystems - Beijing China } 3558d8d81063Sfei feng - Sun Microsystems - Beijing China 3559d8d81063Sfei feng - Sun Microsystems - Beijing China /* by pass if it's quiesced */ 3560d8d81063Sfei feng - Sun Microsystems - Beijing China if (!MWL_IS_QUIESCE(sc)) 3561d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GUNLOCK(sc); 3562d8d81063Sfei feng - Sun Microsystems - Beijing China } 3563d8d81063Sfei feng - Sun Microsystems - Beijing China 3564d8d81063Sfei feng - Sun Microsystems - Beijing China static int 3565d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_stat(void *arg, uint_t stat, uint64_t *val) 3566d8d81063Sfei feng - Sun Microsystems - Beijing China { 3567d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc = (struct mwl_softc *)arg; 3568d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic; 3569d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211_node *ni = NULL; 3570d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211_rateset *rs = NULL; 3571d8d81063Sfei feng - Sun Microsystems - Beijing China 3572d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GLOCK(sc); 3573d8d81063Sfei feng - Sun Microsystems - Beijing China switch (stat) { 3574d8d81063Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_IFSPEED: 3575d8d81063Sfei feng - Sun Microsystems - Beijing China ni = ic->ic_bss; 3576d8d81063Sfei feng - Sun Microsystems - Beijing China rs = &ni->in_rates; 3577d8d81063Sfei feng - Sun Microsystems - Beijing China *val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ? 3578d8d81063Sfei feng - Sun Microsystems - Beijing China (rs->ir_rates[ni->in_txrate] & IEEE80211_RATE_VAL) 3579d8d81063Sfei feng - Sun Microsystems - Beijing China : ic->ic_fixed_rate) / 2 * 1000000; 3580d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3581d8d81063Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_NOXMTBUF: 3582d8d81063Sfei feng - Sun Microsystems - Beijing China *val = sc->sc_tx_nobuf; 3583d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3584d8d81063Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_NORCVBUF: 3585d8d81063Sfei feng - Sun Microsystems - Beijing China *val = sc->sc_rx_nobuf; 3586d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3587d8d81063Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_IERRORS: 3588d8d81063Sfei feng - Sun Microsystems - Beijing China *val = sc->sc_rx_err; 3589d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3590d8d81063Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_RBYTES: 3591d8d81063Sfei feng - Sun Microsystems - Beijing China *val = ic->ic_stats.is_rx_bytes; 3592d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3593d8d81063Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_IPACKETS: 3594d8d81063Sfei feng - Sun Microsystems - Beijing China *val = ic->ic_stats.is_rx_frags; 3595d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3596d8d81063Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_OBYTES: 3597d8d81063Sfei feng - Sun Microsystems - Beijing China *val = ic->ic_stats.is_tx_bytes; 3598d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3599d8d81063Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_OPACKETS: 3600d8d81063Sfei feng - Sun Microsystems - Beijing China *val = ic->ic_stats.is_tx_frags; 3601d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3602d8d81063Sfei feng - Sun Microsystems - Beijing China case MAC_STAT_OERRORS: 3603d8d81063Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_TX_FAILED: 3604d8d81063Sfei feng - Sun Microsystems - Beijing China *val = sc->sc_tx_err; 3605d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3606d8d81063Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_TX_RETRANS: 3607d8d81063Sfei feng - Sun Microsystems - Beijing China *val = sc->sc_tx_retries; 3608d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3609d8d81063Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_FCS_ERRORS: 3610d8d81063Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_WEP_ERRORS: 3611d8d81063Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_TX_FRAGS: 3612d8d81063Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_MCAST_TX: 3613d8d81063Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_RTS_SUCCESS: 3614d8d81063Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_RTS_FAILURE: 3615d8d81063Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_ACK_FAILURE: 3616d8d81063Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_RX_FRAGS: 3617d8d81063Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_MCAST_RX: 3618d8d81063Sfei feng - Sun Microsystems - Beijing China case WIFI_STAT_RX_DUPS: 3619d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GUNLOCK(sc); 3620d8d81063Sfei feng - Sun Microsystems - Beijing China return (ieee80211_stat(ic, stat, val)); 3621d8d81063Sfei feng - Sun Microsystems - Beijing China default: 3622d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GUNLOCK(sc); 3623d8d81063Sfei feng - Sun Microsystems - Beijing China return (ENOTSUP); 3624d8d81063Sfei feng - Sun Microsystems - Beijing China } 3625d8d81063Sfei feng - Sun Microsystems - Beijing China 3626d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GUNLOCK(sc); 3627d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 3628d8d81063Sfei feng - Sun Microsystems - Beijing China } 3629d8d81063Sfei feng - Sun Microsystems - Beijing China 3630d8d81063Sfei feng - Sun Microsystems - Beijing China static int 3631d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_start(void *arg) 3632d8d81063Sfei feng - Sun Microsystems - Beijing China { 3633d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc = (struct mwl_softc *)arg; 3634d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic; 3635d8d81063Sfei feng - Sun Microsystems - Beijing China int err; 3636d8d81063Sfei feng - Sun Microsystems - Beijing China 3637d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_init(sc); 3638d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 3639d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_HW, "mwl: mwl_m_start():" 3640d8d81063Sfei feng - Sun Microsystems - Beijing China "Hardware initialization failed\n"); 3641d8d81063Sfei feng - Sun Microsystems - Beijing China goto fail1; 3642d8d81063Sfei feng - Sun Microsystems - Beijing China } 3643d8d81063Sfei feng - Sun Microsystems - Beijing China 3644d8d81063Sfei feng - Sun Microsystems - Beijing China ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 3645d8d81063Sfei feng - Sun Microsystems - Beijing China 3646d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GLOCK(sc); 3647d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_flags |= MWL_F_RUNNING; 3648d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GUNLOCK(sc); 3649d8d81063Sfei feng - Sun Microsystems - Beijing China 3650d8d81063Sfei feng - Sun Microsystems - Beijing China return (0); 3651d8d81063Sfei feng - Sun Microsystems - Beijing China fail1: 3652d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_stop(sc); 3653d8d81063Sfei feng - Sun Microsystems - Beijing China return (err); 3654d8d81063Sfei feng - Sun Microsystems - Beijing China } 3655d8d81063Sfei feng - Sun Microsystems - Beijing China 3656d8d81063Sfei feng - Sun Microsystems - Beijing China static void 3657d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_stop(void *arg) 3658d8d81063Sfei feng - Sun Microsystems - Beijing China { 3659d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc = (struct mwl_softc *)arg; 3660d8d81063Sfei feng - Sun Microsystems - Beijing China 3661d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_stop(sc); 3662d8d81063Sfei feng - Sun Microsystems - Beijing China 3663d8d81063Sfei feng - Sun Microsystems - Beijing China ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1); 3664d8d81063Sfei feng - Sun Microsystems - Beijing China 3665d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GLOCK(sc); 3666d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_flags &= ~MWL_F_RUNNING; 3667d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GUNLOCK(sc); 3668d8d81063Sfei feng - Sun Microsystems - Beijing China } 3669d8d81063Sfei feng - Sun Microsystems - Beijing China 3670d8d81063Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/ 3671d8d81063Sfei feng - Sun Microsystems - Beijing China static int 3672d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_promisc(void *arg, boolean_t on) 3673d8d81063Sfei feng - Sun Microsystems - Beijing China { 3674d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc = (struct mwl_softc *)arg; 3675d8d81063Sfei feng - Sun Microsystems - Beijing China int err; 3676d8d81063Sfei feng - Sun Microsystems - Beijing China 3677d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_hal_setpromisc(sc, on); 3678d8d81063Sfei feng - Sun Microsystems - Beijing China 3679d8d81063Sfei feng - Sun Microsystems - Beijing China return (err); 3680d8d81063Sfei feng - Sun Microsystems - Beijing China } 3681d8d81063Sfei feng - Sun Microsystems - Beijing China 3682d8d81063Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/ 3683d8d81063Sfei feng - Sun Microsystems - Beijing China static int 3684d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_multicst(void *arg, boolean_t add, const uint8_t *mca) 3685d8d81063Sfei feng - Sun Microsystems - Beijing China { 3686d8d81063Sfei feng - Sun Microsystems - Beijing China return (ENOTSUP); 3687d8d81063Sfei feng - Sun Microsystems - Beijing China } 3688d8d81063Sfei feng - Sun Microsystems - Beijing China 3689d8d81063Sfei feng - Sun Microsystems - Beijing China /*ARGSUSED*/ 3690d8d81063Sfei feng - Sun Microsystems - Beijing China static int 3691d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_unicst(void *arg, const uint8_t *macaddr) 3692d8d81063Sfei feng - Sun Microsystems - Beijing China { 3693d8d81063Sfei feng - Sun Microsystems - Beijing China return (ENOTSUP); 3694d8d81063Sfei feng - Sun Microsystems - Beijing China } 3695d8d81063Sfei feng - Sun Microsystems - Beijing China 3696d8d81063Sfei feng - Sun Microsystems - Beijing China static mblk_t * 3697d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_tx(void *arg, mblk_t *mp) 3698d8d81063Sfei feng - Sun Microsystems - Beijing China { 3699d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc = (struct mwl_softc *)arg; 3700d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic; 3701d8d81063Sfei feng - Sun Microsystems - Beijing China mblk_t *next; 3702d8d81063Sfei feng - Sun Microsystems - Beijing China 3703d8d81063Sfei feng - Sun Microsystems - Beijing China if (MWL_IS_SUSPEND(sc)) { 3704d8d81063Sfei feng - Sun Microsystems - Beijing China freemsgchain(mp); 3705d8d81063Sfei feng - Sun Microsystems - Beijing China return (NULL); 3706d8d81063Sfei feng - Sun Microsystems - Beijing China } 3707d8d81063Sfei feng - Sun Microsystems - Beijing China 3708d8d81063Sfei feng - Sun Microsystems - Beijing China /* 3709d8d81063Sfei feng - Sun Microsystems - Beijing China * No data frames go out unless we're associated; this 3710d8d81063Sfei feng - Sun Microsystems - Beijing China * should not happen as the 802.11 layer does not enable 3711d8d81063Sfei feng - Sun Microsystems - Beijing China * the xmit queue until we enter the RUN state. 3712d8d81063Sfei feng - Sun Microsystems - Beijing China */ 3713d8d81063Sfei feng - Sun Microsystems - Beijing China if (ic->ic_state != IEEE80211_S_RUN) { 3714d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_TX, "mwl: mwl_m_tx(): " 3715d8d81063Sfei feng - Sun Microsystems - Beijing China "discard, state %u\n", ic->ic_state); 3716d8d81063Sfei feng - Sun Microsystems - Beijing China freemsgchain(mp); 3717d8d81063Sfei feng - Sun Microsystems - Beijing China return (NULL); 3718d8d81063Sfei feng - Sun Microsystems - Beijing China } 3719d8d81063Sfei feng - Sun Microsystems - Beijing China 3720d8d81063Sfei feng - Sun Microsystems - Beijing China while (mp != NULL) { 3721d8d81063Sfei feng - Sun Microsystems - Beijing China next = mp->b_next; 3722d8d81063Sfei feng - Sun Microsystems - Beijing China mp->b_next = NULL; 3723d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwl_send(ic, mp, IEEE80211_FC0_TYPE_DATA) != 3724d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_SUCCESS) { 3725d8d81063Sfei feng - Sun Microsystems - Beijing China mp->b_next = next; 3726d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3727d8d81063Sfei feng - Sun Microsystems - Beijing China } 3728d8d81063Sfei feng - Sun Microsystems - Beijing China mp = next; 3729d8d81063Sfei feng - Sun Microsystems - Beijing China } 3730d8d81063Sfei feng - Sun Microsystems - Beijing China return (mp); 3731d8d81063Sfei feng - Sun Microsystems - Beijing China } 3732d8d81063Sfei feng - Sun Microsystems - Beijing China 3733d8d81063Sfei feng - Sun Microsystems - Beijing China static void 3734d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_ioctl(void* arg, queue_t *wq, mblk_t *mp) 3735d8d81063Sfei feng - Sun Microsystems - Beijing China { 3736d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc = (struct mwl_softc *)arg; 3737d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic; 3738d8d81063Sfei feng - Sun Microsystems - Beijing China int err; 3739d8d81063Sfei feng - Sun Microsystems - Beijing China 3740d8d81063Sfei feng - Sun Microsystems - Beijing China err = ieee80211_ioctl(ic, wq, mp); 3741d8d81063Sfei feng - Sun Microsystems - Beijing China if (err == ENETRESET) { 3742d8d81063Sfei feng - Sun Microsystems - Beijing China if (ic->ic_des_esslen) { 3743d8d81063Sfei feng - Sun Microsystems - Beijing China if (MWL_IS_RUNNING(sc)) { 3744d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_init(sc); 3745d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ieee80211_new_state(ic, 3746d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_S_SCAN, -1); 3747d8d81063Sfei feng - Sun Microsystems - Beijing China } 3748d8d81063Sfei feng - Sun Microsystems - Beijing China } 3749d8d81063Sfei feng - Sun Microsystems - Beijing China } 3750d8d81063Sfei feng - Sun Microsystems - Beijing China } 3751d8d81063Sfei feng - Sun Microsystems - Beijing China 3752d8d81063Sfei feng - Sun Microsystems - Beijing China /* 3753d8d81063Sfei feng - Sun Microsystems - Beijing China * Call back function for get/set proporty 3754d8d81063Sfei feng - Sun Microsystems - Beijing China */ 3755d8d81063Sfei feng - Sun Microsystems - Beijing China static int 3756d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 37570dc2366fSVenugopal Iyer uint_t wldp_length, void *wldp_buf) 3758d8d81063Sfei feng - Sun Microsystems - Beijing China { 3759d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc = (struct mwl_softc *)arg; 3760d8d81063Sfei feng - Sun Microsystems - Beijing China int err = 0; 3761d8d81063Sfei feng - Sun Microsystems - Beijing China 3762d8d81063Sfei feng - Sun Microsystems - Beijing China err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_num, 37630dc2366fSVenugopal Iyer wldp_length, wldp_buf); 3764d8d81063Sfei feng - Sun Microsystems - Beijing China 3765d8d81063Sfei feng - Sun Microsystems - Beijing China return (err); 3766d8d81063Sfei feng - Sun Microsystems - Beijing China } 3767d8d81063Sfei feng - Sun Microsystems - Beijing China 37680dc2366fSVenugopal Iyer static void 37690dc2366fSVenugopal Iyer mwl_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 37700dc2366fSVenugopal Iyer mac_prop_info_handle_t prh) 37710dc2366fSVenugopal Iyer { 37720dc2366fSVenugopal Iyer struct mwl_softc *sc = (struct mwl_softc *)arg; 37730dc2366fSVenugopal Iyer 37740dc2366fSVenugopal Iyer ieee80211_propinfo(&sc->sc_ic, pr_name, wldp_pr_num, prh); 37750dc2366fSVenugopal Iyer } 37760dc2366fSVenugopal Iyer 3777d8d81063Sfei feng - Sun Microsystems - Beijing China static int 3778d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 3779d8d81063Sfei feng - Sun Microsystems - Beijing China uint_t wldp_length, const void *wldp_buf) 3780d8d81063Sfei feng - Sun Microsystems - Beijing China { 3781d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc = (struct mwl_softc *)arg; 3782d8d81063Sfei feng - Sun Microsystems - Beijing China ieee80211com_t *ic = &sc->sc_ic; 3783d8d81063Sfei feng - Sun Microsystems - Beijing China int err; 3784d8d81063Sfei feng - Sun Microsystems - Beijing China 3785d8d81063Sfei feng - Sun Microsystems - Beijing China err = ieee80211_setprop(ic, pr_name, wldp_pr_num, wldp_length, 3786d8d81063Sfei feng - Sun Microsystems - Beijing China wldp_buf); 3787d8d81063Sfei feng - Sun Microsystems - Beijing China if (err == ENETRESET) { 3788d8d81063Sfei feng - Sun Microsystems - Beijing China if (ic->ic_des_esslen) { 3789d8d81063Sfei feng - Sun Microsystems - Beijing China if (MWL_IS_RUNNING(sc)) { 3790d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_init(sc); 3791d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ieee80211_new_state(ic, 3792d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_S_SCAN, -1); 3793d8d81063Sfei feng - Sun Microsystems - Beijing China } 3794d8d81063Sfei feng - Sun Microsystems - Beijing China } 3795d8d81063Sfei feng - Sun Microsystems - Beijing China err = 0; 3796d8d81063Sfei feng - Sun Microsystems - Beijing China } 3797d8d81063Sfei feng - Sun Microsystems - Beijing China return (err); 3798d8d81063Sfei feng - Sun Microsystems - Beijing China } 3799d8d81063Sfei feng - Sun Microsystems - Beijing China 3800d8d81063Sfei feng - Sun Microsystems - Beijing China static int 3801d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) 3802d8d81063Sfei feng - Sun Microsystems - Beijing China { 3803d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc; 3804d8d81063Sfei feng - Sun Microsystems - Beijing China struct ieee80211com *ic; 3805d8d81063Sfei feng - Sun Microsystems - Beijing China int i, err, qid, instance; 3806d8d81063Sfei feng - Sun Microsystems - Beijing China int intr_type, intr_count, intr_actual; 3807d8d81063Sfei feng - Sun Microsystems - Beijing China char strbuf[32]; 3808d8d81063Sfei feng - Sun Microsystems - Beijing China uint8_t csz; 3809d8d81063Sfei feng - Sun Microsystems - Beijing China uint16_t vendor_id, device_id, command; 3810d8d81063Sfei feng - Sun Microsystems - Beijing China 3811d8d81063Sfei feng - Sun Microsystems - Beijing China wifi_data_t wd = { 0 }; 3812d8d81063Sfei feng - Sun Microsystems - Beijing China mac_register_t *macp; 3813d8d81063Sfei feng - Sun Microsystems - Beijing China 3814d8d81063Sfei feng - Sun Microsystems - Beijing China switch (cmd) { 3815d8d81063Sfei feng - Sun Microsystems - Beijing China case DDI_ATTACH: 3816d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3817d8d81063Sfei feng - Sun Microsystems - Beijing China case DDI_RESUME: 3818d8d81063Sfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(mwl_soft_state_p, 3819d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_get_instance(devinfo)); 3820d8d81063Sfei feng - Sun Microsystems - Beijing China ASSERT(sc != NULL); 3821d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GLOCK(sc); 3822d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_flags &= ~MWL_F_SUSPEND; 3823d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GUNLOCK(sc); 3824d8d81063Sfei feng - Sun Microsystems - Beijing China if (mwl_resume(sc) != 0) { 3825d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_SR, "mwl: mwl_attach(): " 3826d8d81063Sfei feng - Sun Microsystems - Beijing China "failed to resume\n"); 3827d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 3828d8d81063Sfei feng - Sun Microsystems - Beijing China } 3829d8d81063Sfei feng - Sun Microsystems - Beijing China if (MWL_IS_RUNNING(sc)) { 3830d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mwl_init(sc); 3831d8d81063Sfei feng - Sun Microsystems - Beijing China ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1); 3832d8d81063Sfei feng - Sun Microsystems - Beijing China } 3833d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_SR, "mwl: mwl_attach(): " 3834d8d81063Sfei feng - Sun Microsystems - Beijing China "resume now\n"); 3835d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS); 3836d8d81063Sfei feng - Sun Microsystems - Beijing China default: 3837d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 3838d8d81063Sfei feng - Sun Microsystems - Beijing China } 3839d8d81063Sfei feng - Sun Microsystems - Beijing China 3840d8d81063Sfei feng - Sun Microsystems - Beijing China instance = ddi_get_instance(devinfo); 3841d8d81063Sfei feng - Sun Microsystems - Beijing China if (ddi_soft_state_zalloc(mwl_soft_state_p, 3842d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_get_instance(devinfo)) != DDI_SUCCESS) { 3843d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 3844d8d81063Sfei feng - Sun Microsystems - Beijing China "Unable to alloc soft state\n"); 3845d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 3846d8d81063Sfei feng - Sun Microsystems - Beijing China } 3847d8d81063Sfei feng - Sun Microsystems - Beijing China 3848d8d81063Sfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(mwl_soft_state_p, ddi_get_instance(devinfo)); 3849d8d81063Sfei feng - Sun Microsystems - Beijing China ic = &sc->sc_ic; 3850d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_dev = devinfo; 3851d8d81063Sfei feng - Sun Microsystems - Beijing China 3852d8d81063Sfei feng - Sun Microsystems - Beijing China /* PCI configuration space */ 3853d8d81063Sfei feng - Sun Microsystems - Beijing China err = ddi_regs_map_setup(devinfo, 0, (caddr_t *)&sc->sc_cfg_base, 0, 0, 3854d8d81063Sfei feng - Sun Microsystems - Beijing China &mwl_reg_accattr, &sc->sc_cfg_handle); 3855d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 3856d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 3857d8d81063Sfei feng - Sun Microsystems - Beijing China "ddi_regs_map_setup() failed"); 3858d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail0; 3859d8d81063Sfei feng - Sun Microsystems - Beijing China } 3860d8d81063Sfei feng - Sun Microsystems - Beijing China csz = ddi_get8(sc->sc_cfg_handle, 3861d8d81063Sfei feng - Sun Microsystems - Beijing China (uint8_t *)(sc->sc_cfg_base + PCI_CONF_CACHE_LINESZ)); 3862d8d81063Sfei feng - Sun Microsystems - Beijing China if (!csz) 3863d8d81063Sfei feng - Sun Microsystems - Beijing China csz = 16; 3864d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_cachelsz = csz << 2; 3865d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_dmabuf_size = roundup(IEEE80211_MAX_LEN, sc->sc_cachelsz); 3866d8d81063Sfei feng - Sun Microsystems - Beijing China vendor_id = ddi_get16(sc->sc_cfg_handle, 3867d8d81063Sfei feng - Sun Microsystems - Beijing China (uint16_t *)(sc->sc_cfg_base + PCI_CONF_VENID)); 3868d8d81063Sfei feng - Sun Microsystems - Beijing China device_id = ddi_get16(sc->sc_cfg_handle, 3869d8d81063Sfei feng - Sun Microsystems - Beijing China (uint16_t *)(sc->sc_cfg_base + PCI_CONF_DEVID)); 3870d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 3871d8d81063Sfei feng - Sun Microsystems - Beijing China "vendor 0x%x, device id 0x%x, cache size %d\n", 3872d8d81063Sfei feng - Sun Microsystems - Beijing China vendor_id, device_id, csz); 3873d8d81063Sfei feng - Sun Microsystems - Beijing China 3874d8d81063Sfei feng - Sun Microsystems - Beijing China /* 3875d8d81063Sfei feng - Sun Microsystems - Beijing China * Enable response to memory space accesses, 3876d8d81063Sfei feng - Sun Microsystems - Beijing China * and enabe bus master. 3877d8d81063Sfei feng - Sun Microsystems - Beijing China */ 3878d8d81063Sfei feng - Sun Microsystems - Beijing China command = PCI_COMM_MAE | PCI_COMM_ME; 3879d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_put16(sc->sc_cfg_handle, 3880d8d81063Sfei feng - Sun Microsystems - Beijing China (uint16_t *)((uintptr_t)(sc->sc_cfg_base) + PCI_CONF_COMM), 3881d8d81063Sfei feng - Sun Microsystems - Beijing China command); 3882d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_put8(sc->sc_cfg_handle, 3883d8d81063Sfei feng - Sun Microsystems - Beijing China (uint8_t *)(sc->sc_cfg_base + PCI_CONF_LATENCY_TIMER), 0xa8); 3884d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_put8(sc->sc_cfg_handle, 3885d8d81063Sfei feng - Sun Microsystems - Beijing China (uint8_t *)(sc->sc_cfg_base + PCI_CONF_ILINE), 0x10); 3886d8d81063Sfei feng - Sun Microsystems - Beijing China 3887d8d81063Sfei feng - Sun Microsystems - Beijing China /* BAR0 */ 3888d8d81063Sfei feng - Sun Microsystems - Beijing China err = ddi_regs_map_setup(devinfo, 1, 3889d8d81063Sfei feng - Sun Microsystems - Beijing China &sc->sc_mem_base, 0, 0, &mwl_reg_accattr, &sc->sc_mem_handle); 3890d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 3891d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 3892d8d81063Sfei feng - Sun Microsystems - Beijing China "i/o space failed"); 3893d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail1; 3894d8d81063Sfei feng - Sun Microsystems - Beijing China } 3895d8d81063Sfei feng - Sun Microsystems - Beijing China 3896d8d81063Sfei feng - Sun Microsystems - Beijing China /* BAR1 */ 3897d8d81063Sfei feng - Sun Microsystems - Beijing China err = ddi_regs_map_setup(devinfo, 2, 3898d8d81063Sfei feng - Sun Microsystems - Beijing China &sc->sc_io_base, 0, 0, &mwl_reg_accattr, &sc->sc_io_handle); 3899d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 3900d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 3901d8d81063Sfei feng - Sun Microsystems - Beijing China "memory space failed"); 3902d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail2; 3903d8d81063Sfei feng - Sun Microsystems - Beijing China } 3904d8d81063Sfei feng - Sun Microsystems - Beijing China 3905d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 3906d8d81063Sfei feng - Sun Microsystems - Beijing China "PCI configuration is done successfully\n"); 3907d8d81063Sfei feng - Sun Microsystems - Beijing China 3908d8d81063Sfei feng - Sun Microsystems - Beijing China /* 3909d8d81063Sfei feng - Sun Microsystems - Beijing China * Alloc cmd DMA buffer for firmware download 3910d8d81063Sfei feng - Sun Microsystems - Beijing China */ 3911d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_alloc_cmdbuf(sc); 3912d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3913d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 3914d8d81063Sfei feng - Sun Microsystems - Beijing China "could not alloc cmd dma buffer\n"); 3915d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail3; 3916d8d81063Sfei feng - Sun Microsystems - Beijing China } 3917d8d81063Sfei feng - Sun Microsystems - Beijing China 3918d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_imask = 0; 3919d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_hw_flags = 0; 3920d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_flags = 0; 3921d8d81063Sfei feng - Sun Microsystems - Beijing China 3922d8d81063Sfei feng - Sun Microsystems - Beijing China /* 3923d8d81063Sfei feng - Sun Microsystems - Beijing China * Some cards have SDRAM. When loading firmware we need 3924d8d81063Sfei feng - Sun Microsystems - Beijing China * to reset the SDRAM controller prior to doing this. 3925d8d81063Sfei feng - Sun Microsystems - Beijing China * When the SDRAMSIZE is non-zero we do that work in 3926d8d81063Sfei feng - Sun Microsystems - Beijing China * mwl_hal_fwload. 3927d8d81063Sfei feng - Sun Microsystems - Beijing China */ 3928d8d81063Sfei feng - Sun Microsystems - Beijing China switch (device_id) { 3929d8d81063Sfei feng - Sun Microsystems - Beijing China case 0x2a02: /* CB82 */ 3930d8d81063Sfei feng - Sun Microsystems - Beijing China case 0x2a03: /* CB85 */ 3931d8d81063Sfei feng - Sun Microsystems - Beijing China case 0x2a08: /* MC85_B1 */ 3932d8d81063Sfei feng - Sun Microsystems - Beijing China case 0x2a0b: /* CB85AP */ 3933d8d81063Sfei feng - Sun Microsystems - Beijing China case 0x2a24: 3934d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_SDRAMSIZE_Addr = 0x40fe70b7; /* 8M SDRAM */ 3935d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3936d8d81063Sfei feng - Sun Microsystems - Beijing China case 0x2a04: /* MC85 */ 3937d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_SDRAMSIZE_Addr = 0x40fc70b7; /* 16M SDRAM */ 3938d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3939d8d81063Sfei feng - Sun Microsystems - Beijing China default: 3940d8d81063Sfei feng - Sun Microsystems - Beijing China break; 3941d8d81063Sfei feng - Sun Microsystems - Beijing China } 3942d8d81063Sfei feng - Sun Microsystems - Beijing China 3943d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_fwload(sc, NULL); 3944d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3945d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 3946d8d81063Sfei feng - Sun Microsystems - Beijing China "firmware download failed\n"); 3947d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail4; 3948d8d81063Sfei feng - Sun Microsystems - Beijing China } 3949d8d81063Sfei feng - Sun Microsystems - Beijing China 3950d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 3951d8d81063Sfei feng - Sun Microsystems - Beijing China "firmware download successfully\n"); 3952d8d81063Sfei feng - Sun Microsystems - Beijing China 3953d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_gethwspecs(sc); 3954d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3955d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 3956d8d81063Sfei feng - Sun Microsystems - Beijing China "failed to get hw spec\n"); 3957d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail4; 3958d8d81063Sfei feng - Sun Microsystems - Beijing China } 3959d8d81063Sfei feng - Sun Microsystems - Beijing China 3960d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_getchannels(sc); 3961d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3962d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 3963d8d81063Sfei feng - Sun Microsystems - Beijing China "failed to get channels\n"); 3964d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail4; 3965d8d81063Sfei feng - Sun Microsystems - Beijing China } 3966d8d81063Sfei feng - Sun Microsystems - Beijing China 3967d8d81063Sfei feng - Sun Microsystems - Beijing China /* 3968d8d81063Sfei feng - Sun Microsystems - Beijing China * Alloc rx DMA buffer 3969d8d81063Sfei feng - Sun Microsystems - Beijing China */ 3970d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_alloc_rx_ring(sc, MWL_RX_RING_COUNT); 3971d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3972d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 3973d8d81063Sfei feng - Sun Microsystems - Beijing China "could not alloc cmd dma buffer\n"); 3974d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail5; 3975d8d81063Sfei feng - Sun Microsystems - Beijing China } 3976d8d81063Sfei feng - Sun Microsystems - Beijing China 3977d8d81063Sfei feng - Sun Microsystems - Beijing China /* 3978d8d81063Sfei feng - Sun Microsystems - Beijing China * Alloc rx DMA buffer 3979d8d81063Sfei feng - Sun Microsystems - Beijing China */ 3980d8d81063Sfei feng - Sun Microsystems - Beijing China for (qid = 0; qid < MWL_NUM_TX_QUEUES; qid++) { 3981d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_alloc_tx_ring(sc, 3982d8d81063Sfei feng - Sun Microsystems - Beijing China &sc->sc_txring[qid], MWL_TX_RING_COUNT); 3983d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3984d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 3985d8d81063Sfei feng - Sun Microsystems - Beijing China "could not alloc tx ring %d\n", qid); 3986d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail6; 3987d8d81063Sfei feng - Sun Microsystems - Beijing China } 3988d8d81063Sfei feng - Sun Microsystems - Beijing China } 3989d8d81063Sfei feng - Sun Microsystems - Beijing China 3990d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_setupdma(sc); 3991d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3992d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 3993d8d81063Sfei feng - Sun Microsystems - Beijing China "could not setup dma\n"); 3994d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail6; 3995d8d81063Sfei feng - Sun Microsystems - Beijing China } 3996d8d81063Sfei feng - Sun Microsystems - Beijing China 3997d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_setup_txq(sc); 3998d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 3999d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 4000d8d81063Sfei feng - Sun Microsystems - Beijing China "could not setup txq\n"); 4001d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail6; 4002d8d81063Sfei feng - Sun Microsystems - Beijing China } 4003d8d81063Sfei feng - Sun Microsystems - Beijing China 4004d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(ic->ic_macaddr, sc->sc_hwspecs.macAddr); 4005d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 4006d8d81063Sfei feng - Sun Microsystems - Beijing China "mwl MAC:%2x:%2x:%2x:%2x:%2x:%2x\n", 4007d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[0], 4008d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[1], 4009d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[2], 4010d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[3], 4011d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[4], 4012d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[5]); 4013d8d81063Sfei feng - Sun Microsystems - Beijing China 4014d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_hal_setmac_locked(sc, ic->ic_macaddr); 4015d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { /* NB: mwl_setupdma prints msg */ 4016d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: attach(): " 4017d8d81063Sfei feng - Sun Microsystems - Beijing China "could not set mac\n"); 4018d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail6; 4019d8d81063Sfei feng - Sun Microsystems - Beijing China } 4020d8d81063Sfei feng - Sun Microsystems - Beijing China 4021d8d81063Sfei feng - Sun Microsystems - Beijing China mutex_init(&sc->sc_glock, NULL, MUTEX_DRIVER, NULL); 4022d8d81063Sfei feng - Sun Microsystems - Beijing China mutex_init(&sc->sc_rxlock, NULL, MUTEX_DRIVER, NULL); 4023d8d81063Sfei feng - Sun Microsystems - Beijing China mutex_init(&sc->sc_txlock, NULL, MUTEX_DRIVER, NULL); 4024d8d81063Sfei feng - Sun Microsystems - Beijing China 4025d8d81063Sfei feng - Sun Microsystems - Beijing China 4026d8d81063Sfei feng - Sun Microsystems - Beijing China /* set supported rates */ 4027d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_sup_rates[IEEE80211_MODE_11B] = mwl_rateset_11b; 4028d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_sup_rates[IEEE80211_MODE_11G] = mwl_rateset_11g; 4029d8d81063Sfei feng - Sun Microsystems - Beijing China 4030d8d81063Sfei feng - Sun Microsystems - Beijing China /* set supported .11b and .11g channels (1 through 14) */ 4031d8d81063Sfei feng - Sun Microsystems - Beijing China for (i = 1; i <= 14; i++) { 4032d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_sup_channels[i].ich_freq = 4033d8d81063Sfei feng - Sun Microsystems - Beijing China ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); 4034d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_sup_channels[i].ich_flags = 4035d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; 4036d8d81063Sfei feng - Sun Microsystems - Beijing China } 4037d8d81063Sfei feng - Sun Microsystems - Beijing China 4038d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 4039d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ 4040d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_state = IEEE80211_S_INIT; 4041d8d81063Sfei feng - Sun Microsystems - Beijing China 4042d8d81063Sfei feng - Sun Microsystems - Beijing China /* set device capabilities */ 4043d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_caps = 4044d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_C_TXPMGT | /* tx power management */ 4045d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_C_SHPREAMBLE | /* short preamble supported */ 4046d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_C_SHSLOT; /* short slot time supported */ 4047d8d81063Sfei feng - Sun Microsystems - Beijing China 4048d8d81063Sfei feng - Sun Microsystems - Beijing China /* WPA/WPA2 support */ 4049d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_caps |= IEEE80211_C_WPA; /* Support WPA/WPA2 */ 4050d8d81063Sfei feng - Sun Microsystems - Beijing China 4051d8d81063Sfei feng - Sun Microsystems - Beijing China /* Enable hardware encryption */ 4052d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_caps |= IEEE80211_C_WEP | IEEE80211_C_TKIP | IEEE80211_C_AES_CCM; 4053d8d81063Sfei feng - Sun Microsystems - Beijing China 4054d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_xmit = mwl_send; 4055d8d81063Sfei feng - Sun Microsystems - Beijing China 4056d8d81063Sfei feng - Sun Microsystems - Beijing China ieee80211_attach(ic); 4057d8d81063Sfei feng - Sun Microsystems - Beijing China 4058d8d81063Sfei feng - Sun Microsystems - Beijing China /* register WPA door */ 4059d8d81063Sfei feng - Sun Microsystems - Beijing China ieee80211_register_door(ic, ddi_driver_name(devinfo), 4060d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_get_instance(devinfo)); 4061d8d81063Sfei feng - Sun Microsystems - Beijing China 4062d8d81063Sfei feng - Sun Microsystems - Beijing China /* override state transition machine */ 4063d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_newstate = ic->ic_newstate; 4064d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_newstate = mwl_newstate; 4065d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_node_alloc = mwl_node_alloc; 4066d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_node_free = mwl_node_free; 4067d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_crypto.cs_max_keyix = 0; 4068d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_crypto.cs_key_alloc = mwl_key_alloc; 4069d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_crypto.cs_key_delete = mwl_key_delete; 4070d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_crypto.cs_key_set = mwl_key_set; 4071d8d81063Sfei feng - Sun Microsystems - Beijing China 4072d8d81063Sfei feng - Sun Microsystems - Beijing China ieee80211_media_init(ic); 4073d8d81063Sfei feng - Sun Microsystems - Beijing China 4074d8d81063Sfei feng - Sun Microsystems - Beijing China ic->ic_def_txkey = 0; 4075d8d81063Sfei feng - Sun Microsystems - Beijing China 4076d8d81063Sfei feng - Sun Microsystems - Beijing China err = mwl_hal_newstation(sc, ic->ic_macaddr, 0, 0, NULL, 0, 0); 4077d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 4078d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: attach(): " 4079d8d81063Sfei feng - Sun Microsystems - Beijing China "could not create new station\n"); 4080d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail7; 4081d8d81063Sfei feng - Sun Microsystems - Beijing China } 4082d8d81063Sfei feng - Sun Microsystems - Beijing China 4083d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(ic->ic_bss->in_bssid, ic->ic_macaddr); 4084d8d81063Sfei feng - Sun Microsystems - Beijing China // mwl_setglobalkeys(ic); 4085d8d81063Sfei feng - Sun Microsystems - Beijing China 4086d8d81063Sfei feng - Sun Microsystems - Beijing China err = ddi_intr_get_supported_types(devinfo, &intr_type); 4087d8d81063Sfei feng - Sun Microsystems - Beijing China if ((err != DDI_SUCCESS) || (!(intr_type & DDI_INTR_TYPE_FIXED))) { 4088d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 4089d8d81063Sfei feng - Sun Microsystems - Beijing China "fixed type interrupt is not supported\n"); 4090d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail7; 4091d8d81063Sfei feng - Sun Microsystems - Beijing China } 4092d8d81063Sfei feng - Sun Microsystems - Beijing China 4093d8d81063Sfei feng - Sun Microsystems - Beijing China err = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_FIXED, &intr_count); 4094d8d81063Sfei feng - Sun Microsystems - Beijing China if ((err != DDI_SUCCESS) || (intr_count != 1)) { 4095d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 4096d8d81063Sfei feng - Sun Microsystems - Beijing China "no fixed interrupts\n"); 4097d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail7; 4098d8d81063Sfei feng - Sun Microsystems - Beijing China } 4099d8d81063Sfei feng - Sun Microsystems - Beijing China 4100d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_intr_htable = kmem_zalloc(sizeof (ddi_intr_handle_t), KM_SLEEP); 4101d8d81063Sfei feng - Sun Microsystems - Beijing China 4102d8d81063Sfei feng - Sun Microsystems - Beijing China err = ddi_intr_alloc(devinfo, sc->sc_intr_htable, 4103d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_INTR_TYPE_FIXED, 0, intr_count, &intr_actual, 0); 4104d8d81063Sfei feng - Sun Microsystems - Beijing China if ((err != DDI_SUCCESS) || (intr_actual != 1)) { 4105d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 4106d8d81063Sfei feng - Sun Microsystems - Beijing China "ddi_intr_alloc() failed 0x%x\n", err); 4107d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail8; 4108d8d81063Sfei feng - Sun Microsystems - Beijing China } 4109d8d81063Sfei feng - Sun Microsystems - Beijing China 4110d8d81063Sfei feng - Sun Microsystems - Beijing China err = ddi_intr_get_pri(sc->sc_intr_htable[0], &sc->sc_intr_pri); 4111d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 4112d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 4113d8d81063Sfei feng - Sun Microsystems - Beijing China "ddi_intr_get_pri() failed 0x%x\n", err); 4114d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail9; 4115d8d81063Sfei feng - Sun Microsystems - Beijing China } 4116d8d81063Sfei feng - Sun Microsystems - Beijing China 4117d8d81063Sfei feng - Sun Microsystems - Beijing China err = ddi_intr_add_softint(devinfo, &sc->sc_softintr_hdl, 4118d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_INTR_SOFTPRI_MAX, mwl_softintr, (caddr_t)sc); 4119d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 4120d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 4121d8d81063Sfei feng - Sun Microsystems - Beijing China "ddi_add_softintr() failed"); 4122d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail9; 4123d8d81063Sfei feng - Sun Microsystems - Beijing China } 4124d8d81063Sfei feng - Sun Microsystems - Beijing China 4125d8d81063Sfei feng - Sun Microsystems - Beijing China err = ddi_intr_add_handler(sc->sc_intr_htable[0], mwl_intr, 4126d8d81063Sfei feng - Sun Microsystems - Beijing China (caddr_t)sc, NULL); 4127d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 4128d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 4129d8d81063Sfei feng - Sun Microsystems - Beijing China "ddi_intr_addr_handle() failed\n"); 4130d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail10; 4131d8d81063Sfei feng - Sun Microsystems - Beijing China } 4132d8d81063Sfei feng - Sun Microsystems - Beijing China 4133d8d81063Sfei feng - Sun Microsystems - Beijing China err = ddi_intr_enable(sc->sc_intr_htable[0]); 4134d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 4135d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 4136d8d81063Sfei feng - Sun Microsystems - Beijing China "ddi_intr_enable() failed\n"); 4137d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail11; 4138d8d81063Sfei feng - Sun Microsystems - Beijing China } 4139d8d81063Sfei feng - Sun Microsystems - Beijing China 4140d8d81063Sfei feng - Sun Microsystems - Beijing China /* 4141d8d81063Sfei feng - Sun Microsystems - Beijing China * Provide initial settings for the WiFi plugin; whenever this 4142d8d81063Sfei feng - Sun Microsystems - Beijing China * information changes, we need to call mac_plugindata_update() 4143d8d81063Sfei feng - Sun Microsystems - Beijing China */ 4144d8d81063Sfei feng - Sun Microsystems - Beijing China wd.wd_opmode = ic->ic_opmode; 4145d8d81063Sfei feng - Sun Microsystems - Beijing China wd.wd_secalloc = WIFI_SEC_NONE; 4146d8d81063Sfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid); 4147d8d81063Sfei feng - Sun Microsystems - Beijing China 4148d8d81063Sfei feng - Sun Microsystems - Beijing China if ((macp = mac_alloc(MAC_VERSION)) == NULL) { 4149d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 4150d8d81063Sfei feng - Sun Microsystems - Beijing China "MAC version mismatch\n"); 4151d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail12; 4152d8d81063Sfei feng - Sun Microsystems - Beijing China } 4153d8d81063Sfei feng - Sun Microsystems - Beijing China 4154d8d81063Sfei feng - Sun Microsystems - Beijing China macp->m_type_ident = MAC_PLUGIN_IDENT_WIFI; 4155d8d81063Sfei feng - Sun Microsystems - Beijing China macp->m_driver = sc; 4156d8d81063Sfei feng - Sun Microsystems - Beijing China macp->m_dip = devinfo; 4157d8d81063Sfei feng - Sun Microsystems - Beijing China macp->m_src_addr = ic->ic_macaddr; 4158d8d81063Sfei feng - Sun Microsystems - Beijing China macp->m_callbacks = &mwl_m_callbacks; 4159d8d81063Sfei feng - Sun Microsystems - Beijing China macp->m_min_sdu = 0; 4160d8d81063Sfei feng - Sun Microsystems - Beijing China macp->m_max_sdu = IEEE80211_MTU; 4161d8d81063Sfei feng - Sun Microsystems - Beijing China macp->m_pdata = &wd; 4162d8d81063Sfei feng - Sun Microsystems - Beijing China macp->m_pdata_size = sizeof (wd); 4163d8d81063Sfei feng - Sun Microsystems - Beijing China 4164d8d81063Sfei feng - Sun Microsystems - Beijing China err = mac_register(macp, &ic->ic_mach); 4165d8d81063Sfei feng - Sun Microsystems - Beijing China mac_free(macp); 4166d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 4167d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 4168d8d81063Sfei feng - Sun Microsystems - Beijing China "mac_register err %x\n", err); 4169d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail12; 4170d8d81063Sfei feng - Sun Microsystems - Beijing China } 4171d8d81063Sfei feng - Sun Microsystems - Beijing China 4172d8d81063Sfei feng - Sun Microsystems - Beijing China /* 4173d8d81063Sfei feng - Sun Microsystems - Beijing China * Create minor node of type DDI_NT_NET_WIFI 4174d8d81063Sfei feng - Sun Microsystems - Beijing China */ 4175d8d81063Sfei feng - Sun Microsystems - Beijing China (void) snprintf(strbuf, sizeof (strbuf), "%s%d", 4176d8d81063Sfei feng - Sun Microsystems - Beijing China "mwl", instance); 4177d8d81063Sfei feng - Sun Microsystems - Beijing China err = ddi_create_minor_node(devinfo, strbuf, S_IFCHR, 4178d8d81063Sfei feng - Sun Microsystems - Beijing China instance + 1, DDI_NT_NET_WIFI, 0); 4179d8d81063Sfei feng - Sun Microsystems - Beijing China if (err != 0) { 4180d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 4181d8d81063Sfei feng - Sun Microsystems - Beijing China "create minor node error\n"); 4182d8d81063Sfei feng - Sun Microsystems - Beijing China goto attach_fail13; 4183d8d81063Sfei feng - Sun Microsystems - Beijing China } 4184d8d81063Sfei feng - Sun Microsystems - Beijing China 4185d8d81063Sfei feng - Sun Microsystems - Beijing China /* 4186d8d81063Sfei feng - Sun Microsystems - Beijing China * Notify link is down now 4187d8d81063Sfei feng - Sun Microsystems - Beijing China */ 4188d8d81063Sfei feng - Sun Microsystems - Beijing China mac_link_update(ic->ic_mach, LINK_STATE_DOWN); 4189d8d81063Sfei feng - Sun Microsystems - Beijing China 4190d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_attach(): " 4191d8d81063Sfei feng - Sun Microsystems - Beijing China "driver attach successfully\n"); 4192d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS); 4193d8d81063Sfei feng - Sun Microsystems - Beijing China 4194d8d81063Sfei feng - Sun Microsystems - Beijing China attach_fail13: 4195d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mac_disable(ic->ic_mach); 4196d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mac_unregister(ic->ic_mach); 4197d8d81063Sfei feng - Sun Microsystems - Beijing China attach_fail12: 4198d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_disable(sc->sc_intr_htable[0]); 4199d8d81063Sfei feng - Sun Microsystems - Beijing China attach_fail11: 4200d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_remove_handler(sc->sc_intr_htable[0]); 4201d8d81063Sfei feng - Sun Microsystems - Beijing China attach_fail10: 4202d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_remove_softint(sc->sc_softintr_hdl); 4203d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_softintr_hdl = NULL; 4204d8d81063Sfei feng - Sun Microsystems - Beijing China attach_fail9: 4205d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_free(sc->sc_intr_htable[0]); 4206d8d81063Sfei feng - Sun Microsystems - Beijing China attach_fail8: 4207d8d81063Sfei feng - Sun Microsystems - Beijing China kmem_free(sc->sc_intr_htable, sizeof (ddi_intr_handle_t)); 4208d8d81063Sfei feng - Sun Microsystems - Beijing China attach_fail7: 4209d8d81063Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_txlock); 4210d8d81063Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_rxlock); 4211d8d81063Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_glock); 4212d8d81063Sfei feng - Sun Microsystems - Beijing China attach_fail6: 4213d8d81063Sfei feng - Sun Microsystems - Beijing China while (--qid >= 0) 4214d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_tx_ring(sc, &sc->sc_txring[qid]); 4215d8d81063Sfei feng - Sun Microsystems - Beijing China attach_fail5: 4216d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_rx_ring(sc); 4217d8d81063Sfei feng - Sun Microsystems - Beijing China attach_fail4: 4218d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_cmdbuf(sc); 4219d8d81063Sfei feng - Sun Microsystems - Beijing China attach_fail3: 4220d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_regs_map_free(&sc->sc_mem_handle); 4221d8d81063Sfei feng - Sun Microsystems - Beijing China attach_fail2: 4222d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_regs_map_free(&sc->sc_io_handle); 4223d8d81063Sfei feng - Sun Microsystems - Beijing China attach_fail1: 4224d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_regs_map_free(&sc->sc_cfg_handle); 4225d8d81063Sfei feng - Sun Microsystems - Beijing China attach_fail0: 4226d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_soft_state_free(mwl_soft_state_p, ddi_get_instance(devinfo)); 4227d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 4228d8d81063Sfei feng - Sun Microsystems - Beijing China } 4229d8d81063Sfei feng - Sun Microsystems - Beijing China 4230d8d81063Sfei feng - Sun Microsystems - Beijing China static int32_t 4231d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd) 4232d8d81063Sfei feng - Sun Microsystems - Beijing China { 4233d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc; 4234d8d81063Sfei feng - Sun Microsystems - Beijing China int qid; 4235d8d81063Sfei feng - Sun Microsystems - Beijing China 4236d8d81063Sfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(mwl_soft_state_p, ddi_get_instance(devinfo)); 4237d8d81063Sfei feng - Sun Microsystems - Beijing China ASSERT(sc != NULL); 4238d8d81063Sfei feng - Sun Microsystems - Beijing China 4239d8d81063Sfei feng - Sun Microsystems - Beijing China switch (cmd) { 4240d8d81063Sfei feng - Sun Microsystems - Beijing China case DDI_DETACH: 4241d8d81063Sfei feng - Sun Microsystems - Beijing China break; 4242d8d81063Sfei feng - Sun Microsystems - Beijing China case DDI_SUSPEND: 4243d8d81063Sfei feng - Sun Microsystems - Beijing China if (MWL_IS_RUNNING(sc)) 4244d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_stop(sc); 4245d8d81063Sfei feng - Sun Microsystems - Beijing China for (qid = 0; qid < MWL_NUM_TX_QUEUES; qid++) 4246d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_tx_ring(sc, &sc->sc_txring[qid]); 4247d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_rx_ring(sc); 4248d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GLOCK(sc); 4249d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_flags |= MWL_F_SUSPEND; 4250d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_GUNLOCK(sc); 4251d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_SR, "mwl: mwl_detach(): " 4252d8d81063Sfei feng - Sun Microsystems - Beijing China "suspend now\n"); 4253d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS); 4254d8d81063Sfei feng - Sun Microsystems - Beijing China default: 4255d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 4256d8d81063Sfei feng - Sun Microsystems - Beijing China } 4257d8d81063Sfei feng - Sun Microsystems - Beijing China 4258d8d81063Sfei feng - Sun Microsystems - Beijing China if (mac_disable(sc->sc_ic.ic_mach) != 0) 4259d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 4260d8d81063Sfei feng - Sun Microsystems - Beijing China 4261d8d81063Sfei feng - Sun Microsystems - Beijing China /* 4262d8d81063Sfei feng - Sun Microsystems - Beijing China * Unregister from the MAC layer subsystem 4263d8d81063Sfei feng - Sun Microsystems - Beijing China */ 4264d8d81063Sfei feng - Sun Microsystems - Beijing China (void) mac_unregister(sc->sc_ic.ic_mach); 4265d8d81063Sfei feng - Sun Microsystems - Beijing China 4266d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_remove_softint(sc->sc_softintr_hdl); 4267d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_softintr_hdl = NULL; 4268d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_disable(sc->sc_intr_htable[0]); 4269d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_remove_handler(sc->sc_intr_htable[0]); 4270d8d81063Sfei feng - Sun Microsystems - Beijing China (void) ddi_intr_free(sc->sc_intr_htable[0]); 4271d8d81063Sfei feng - Sun Microsystems - Beijing China kmem_free(sc->sc_intr_htable, sizeof (ddi_intr_handle_t)); 4272d8d81063Sfei feng - Sun Microsystems - Beijing China 4273d8d81063Sfei feng - Sun Microsystems - Beijing China /* 4274d8d81063Sfei feng - Sun Microsystems - Beijing China * detach ieee80211 layer 4275d8d81063Sfei feng - Sun Microsystems - Beijing China */ 4276d8d81063Sfei feng - Sun Microsystems - Beijing China ieee80211_detach(&sc->sc_ic); 4277d8d81063Sfei feng - Sun Microsystems - Beijing China 4278d8d81063Sfei feng - Sun Microsystems - Beijing China 4279d8d81063Sfei feng - Sun Microsystems - Beijing China for (qid = 0; qid < MWL_NUM_TX_QUEUES; qid++) 4280d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_tx_ring(sc, &sc->sc_txring[qid]); 4281d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_rx_ring(sc); 4282d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_cmdbuf(sc); 4283d8d81063Sfei feng - Sun Microsystems - Beijing China 4284d8d81063Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_txlock); 4285d8d81063Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_rxlock); 4286d8d81063Sfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_glock); 4287d8d81063Sfei feng - Sun Microsystems - Beijing China 4288d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_regs_map_free(&sc->sc_mem_handle); 4289d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_regs_map_free(&sc->sc_io_handle); 4290d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_regs_map_free(&sc->sc_cfg_handle); 4291d8d81063Sfei feng - Sun Microsystems - Beijing China 4292d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_remove_minor_node(devinfo, NULL); 4293d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_soft_state_free(mwl_soft_state_p, ddi_get_instance(devinfo)); 4294d8d81063Sfei feng - Sun Microsystems - Beijing China 4295d8d81063Sfei feng - Sun Microsystems - Beijing China MWL_DBG(MWL_DBG_ATTACH, "mwl: mwl_detach(): " 4296d8d81063Sfei feng - Sun Microsystems - Beijing China "detach successfully\n"); 4297d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS); 4298d8d81063Sfei feng - Sun Microsystems - Beijing China } 4299d8d81063Sfei feng - Sun Microsystems - Beijing China 4300d8d81063Sfei feng - Sun Microsystems - Beijing China /* 4301d8d81063Sfei feng - Sun Microsystems - Beijing China * quiesce(9E) entry point. 4302d8d81063Sfei feng - Sun Microsystems - Beijing China * 4303d8d81063Sfei feng - Sun Microsystems - Beijing China * This function is called when the system is single-threaded at high 4304d8d81063Sfei feng - Sun Microsystems - Beijing China * PIL with preemption disabled. Therefore, this function must not be 4305d8d81063Sfei feng - Sun Microsystems - Beijing China * blocked. 4306d8d81063Sfei feng - Sun Microsystems - Beijing China * 4307d8d81063Sfei feng - Sun Microsystems - Beijing China * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 4308d8d81063Sfei feng - Sun Microsystems - Beijing China * DDI_FAILURE indicates an error condition and should almost never happen. 4309d8d81063Sfei feng - Sun Microsystems - Beijing China */ 4310d8d81063Sfei feng - Sun Microsystems - Beijing China int 4311d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_quiesce(dev_info_t *dip) 4312d8d81063Sfei feng - Sun Microsystems - Beijing China { 4313d8d81063Sfei feng - Sun Microsystems - Beijing China struct mwl_softc *sc; 4314d8d81063Sfei feng - Sun Microsystems - Beijing China 4315d8d81063Sfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(mwl_soft_state_p, ddi_get_instance(dip)); 4316d8d81063Sfei feng - Sun Microsystems - Beijing China if (sc == NULL) 4317d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 4318d8d81063Sfei feng - Sun Microsystems - Beijing China 4319d8d81063Sfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 4320d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_dbg_flags = 0; 4321d8d81063Sfei feng - Sun Microsystems - Beijing China #endif 4322d8d81063Sfei feng - Sun Microsystems - Beijing China 4323d8d81063Sfei feng - Sun Microsystems - Beijing China /* 4324d8d81063Sfei feng - Sun Microsystems - Beijing China * No more blocking is allowed while we are in quiesce(9E) entry point 4325d8d81063Sfei feng - Sun Microsystems - Beijing China */ 4326d8d81063Sfei feng - Sun Microsystems - Beijing China sc->sc_flags |= MWL_F_QUIESCE; 4327d8d81063Sfei feng - Sun Microsystems - Beijing China 4328d8d81063Sfei feng - Sun Microsystems - Beijing China /* 4329d8d81063Sfei feng - Sun Microsystems - Beijing China * Disable all interrupts 4330d8d81063Sfei feng - Sun Microsystems - Beijing China */ 4331d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_stop(sc); 4332d8d81063Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS); 4333d8d81063Sfei feng - Sun Microsystems - Beijing China } 4334d8d81063Sfei feng - Sun Microsystems - Beijing China 4335d8d81063Sfei feng - Sun Microsystems - Beijing China int 4336d8d81063Sfei feng - Sun Microsystems - Beijing China _init(void) 4337d8d81063Sfei feng - Sun Microsystems - Beijing China { 4338d8d81063Sfei feng - Sun Microsystems - Beijing China int status; 4339d8d81063Sfei feng - Sun Microsystems - Beijing China 4340d8d81063Sfei feng - Sun Microsystems - Beijing China status = ddi_soft_state_init(&mwl_soft_state_p, 4341d8d81063Sfei feng - Sun Microsystems - Beijing China sizeof (struct mwl_softc), 1); 4342d8d81063Sfei feng - Sun Microsystems - Beijing China if (status != 0) 4343d8d81063Sfei feng - Sun Microsystems - Beijing China return (status); 4344d8d81063Sfei feng - Sun Microsystems - Beijing China 4345d8d81063Sfei feng - Sun Microsystems - Beijing China mac_init_ops(&mwl_dev_ops, "mwl"); 4346d8d81063Sfei feng - Sun Microsystems - Beijing China status = mod_install(&modlinkage); 4347d8d81063Sfei feng - Sun Microsystems - Beijing China if (status != 0) { 4348d8d81063Sfei feng - Sun Microsystems - Beijing China mac_fini_ops(&mwl_dev_ops); 4349d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_soft_state_fini(&mwl_soft_state_p); 4350d8d81063Sfei feng - Sun Microsystems - Beijing China } 4351d8d81063Sfei feng - Sun Microsystems - Beijing China return (status); 4352d8d81063Sfei feng - Sun Microsystems - Beijing China } 4353d8d81063Sfei feng - Sun Microsystems - Beijing China 4354d8d81063Sfei feng - Sun Microsystems - Beijing China int 4355d8d81063Sfei feng - Sun Microsystems - Beijing China _info(struct modinfo *modinfop) 4356d8d81063Sfei feng - Sun Microsystems - Beijing China { 4357d8d81063Sfei feng - Sun Microsystems - Beijing China return (mod_info(&modlinkage, modinfop)); 4358d8d81063Sfei feng - Sun Microsystems - Beijing China } 4359d8d81063Sfei feng - Sun Microsystems - Beijing China 4360d8d81063Sfei feng - Sun Microsystems - Beijing China int 4361d8d81063Sfei feng - Sun Microsystems - Beijing China _fini(void) 4362d8d81063Sfei feng - Sun Microsystems - Beijing China { 4363d8d81063Sfei feng - Sun Microsystems - Beijing China int status; 4364d8d81063Sfei feng - Sun Microsystems - Beijing China 4365d8d81063Sfei feng - Sun Microsystems - Beijing China status = mod_remove(&modlinkage); 4366d8d81063Sfei feng - Sun Microsystems - Beijing China if (status == 0) { 4367d8d81063Sfei feng - Sun Microsystems - Beijing China mac_fini_ops(&mwl_dev_ops); 4368d8d81063Sfei feng - Sun Microsystems - Beijing China ddi_soft_state_fini(&mwl_soft_state_p); 4369d8d81063Sfei feng - Sun Microsystems - Beijing China } 4370d8d81063Sfei feng - Sun Microsystems - Beijing China return (status); 4371d8d81063Sfei feng - Sun Microsystems - Beijing China } 4372