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