1c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 27d483bc1Sfei feng - Sun Microsystems - Beijing China * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 3c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Use is subject to license terms. 4c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5c7ee0b5cSfei feng - Sun Microsystems - Beijing China 6c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 7e2cf88acSQuaker Fang * Copyright (c) 2009, Intel Corporation 8c7ee0b5cSfei feng - Sun Microsystems - Beijing China * All rights reserved. 9c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 10c7ee0b5cSfei feng - Sun Microsystems - Beijing China 11c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 12c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Copyright (c) 2006 13c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Copyright (c) 2007 14c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Damien Bergamini <damien.bergamini@free.fr> 15c7ee0b5cSfei feng - Sun Microsystems - Beijing China * 16c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Permission to use, copy, modify, and distribute this software for any 17c7ee0b5cSfei feng - Sun Microsystems - Beijing China * purpose with or without fee is hereby granted, provided that the above 18c7ee0b5cSfei feng - Sun Microsystems - Beijing China * copyright notice and this permission notice appear in all copies. 19c7ee0b5cSfei feng - Sun Microsystems - Beijing China * 20c7ee0b5cSfei feng - Sun Microsystems - Beijing China * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 21c7ee0b5cSfei feng - Sun Microsystems - Beijing China * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 22c7ee0b5cSfei feng - Sun Microsystems - Beijing China * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 23c7ee0b5cSfei feng - Sun Microsystems - Beijing China * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 24c7ee0b5cSfei feng - Sun Microsystems - Beijing China * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 25c7ee0b5cSfei feng - Sun Microsystems - Beijing China * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 26c7ee0b5cSfei feng - Sun Microsystems - Beijing China * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 27c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 28c7ee0b5cSfei feng - Sun Microsystems - Beijing China 29c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 30c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Intel(R) WiFi Link 5100/5300 Driver 31c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 32c7ee0b5cSfei feng - Sun Microsystems - Beijing China 33c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/types.h> 34c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/byteorder.h> 35c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/conf.h> 36c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/cmn_err.h> 37c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/stat.h> 38c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/ddi.h> 39c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/sunddi.h> 40c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/strsubr.h> 41c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/ethernet.h> 42c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <inet/common.h> 43c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <inet/nd.h> 44c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <inet/mi.h> 45c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/note.h> 46c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/stream.h> 47c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/strsun.h> 48c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/modctl.h> 49c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/devops.h> 50c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/dlpi.h> 51da14cebeSEric Cheng #include <sys/mac_provider.h> 52c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/mac_wifi.h> 53c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/net80211.h> 54c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/net80211_proto.h> 55e2cf88acSQuaker Fang #include <sys/net80211_ht.h> 56c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/varargs.h> 57c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/policy.h> 58c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <sys/pci.h> 59c7ee0b5cSfei feng - Sun Microsystems - Beijing China 60c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include "iwh_calibration.h" 61c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include "iwh_hw.h" 62c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include "iwh_eeprom.h" 63c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include "iwh_var.h" 64c7ee0b5cSfei feng - Sun Microsystems - Beijing China #include <inet/wifi_ioctl.h> 65c7ee0b5cSfei feng - Sun Microsystems - Beijing China 66c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 67c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DEBUG_80211 (1 << 0) 68c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DEBUG_CMD (1 << 1) 69c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DEBUG_DMA (1 << 2) 70c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DEBUG_EEPROM (1 << 3) 71c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DEBUG_FW (1 << 4) 72c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DEBUG_HW (1 << 5) 73c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DEBUG_INTR (1 << 6) 74c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DEBUG_MRR (1 << 7) 75c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DEBUG_PIO (1 << 8) 76c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DEBUG_RX (1 << 9) 77c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DEBUG_SCAN (1 << 10) 78c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DEBUG_TX (1 << 11) 79c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DEBUG_RATECTL (1 << 12) 80c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DEBUG_RADIO (1 << 13) 81c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DEBUG_RESUME (1 << 14) 82c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DEBUG_CALIBRATION (1 << 15) 83e2cf88acSQuaker Fang #define IWH_DEBUG_BA (1 << 16) 84e2cf88acSQuaker Fang #define IWH_DEBUG_RXON (1 << 17) 85e2cf88acSQuaker Fang #define IWH_DEBUG_HWRATE (1 << 18) 86e2cf88acSQuaker Fang #define IWH_DEBUG_HTRATE (1 << 19) 87e2cf88acSQuaker Fang #define IWH_DEBUG_QOS (1 << 20) 88c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 89c7ee0b5cSfei feng - Sun Microsystems - Beijing China * if want to see debug message of a given section, 90c7ee0b5cSfei feng - Sun Microsystems - Beijing China * please set this flag to one of above values 91c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 92c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t iwh_dbg_flags = 0; 93c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DBG(x) \ 94c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_dbg x 95c7ee0b5cSfei feng - Sun Microsystems - Beijing China #else 96c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_DBG(x) 97c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 98c7ee0b5cSfei feng - Sun Microsystems - Beijing China 99e2cf88acSQuaker Fang #define MS(v, f) (((v) & f) >> f##_S) 100e2cf88acSQuaker Fang 101c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void *iwh_soft_state_p = NULL; 102c7ee0b5cSfei feng - Sun Microsystems - Beijing China 103c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 104c7ee0b5cSfei feng - Sun Microsystems - Beijing China * ucode will be compiled into driver image 105c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 10689b2a9fbSfei feng - Sun Microsystems - Beijing China static uint8_t iwh_fw_5000_bin[] = { 10789b2a9fbSfei feng - Sun Microsystems - Beijing China #include "fw-iw/fw_5000/iwh_5000.ucode" 10889b2a9fbSfei feng - Sun Microsystems - Beijing China }; 10989b2a9fbSfei feng - Sun Microsystems - Beijing China 11089b2a9fbSfei feng - Sun Microsystems - Beijing China static uint8_t iwh_fw_5150_bin[] = { 11189b2a9fbSfei feng - Sun Microsystems - Beijing China #include "fw-iw/fw_5150/iwh_5150.ucode" 112c7ee0b5cSfei feng - Sun Microsystems - Beijing China }; 113c7ee0b5cSfei feng - Sun Microsystems - Beijing China 114c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 115c7ee0b5cSfei feng - Sun Microsystems - Beijing China * DMA attributes for a shared page 116c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 117c7ee0b5cSfei feng - Sun Microsystems - Beijing China static ddi_dma_attr_t sh_dma_attr = { 118c7ee0b5cSfei feng - Sun Microsystems - Beijing China DMA_ATTR_V0, /* version of this structure */ 119c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0, /* lowest usable address */ 120c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* highest usable address */ 121c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum DMAable byte count */ 122c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0x1000, /* alignment in bytes */ 123c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0x1000, /* burst sizes (any?) */ 124c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* minimum transfer */ 125c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum transfer */ 126c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum segment length */ 127c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* maximum number of segments */ 128c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* granularity */ 129c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0, /* flags (reserved) */ 130c7ee0b5cSfei feng - Sun Microsystems - Beijing China }; 131c7ee0b5cSfei feng - Sun Microsystems - Beijing China 132c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 133c7ee0b5cSfei feng - Sun Microsystems - Beijing China * DMA attributes for a keep warm DRAM descriptor 134c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 135c7ee0b5cSfei feng - Sun Microsystems - Beijing China static ddi_dma_attr_t kw_dma_attr = { 136c7ee0b5cSfei feng - Sun Microsystems - Beijing China DMA_ATTR_V0, /* version of this structure */ 137c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0, /* lowest usable address */ 138c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* highest usable address */ 139c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum DMAable byte count */ 140c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0x1000, /* alignment in bytes */ 141c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0x1000, /* burst sizes (any?) */ 142c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* minimum transfer */ 143c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum transfer */ 144c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum segment length */ 145c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* maximum number of segments */ 146c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* granularity */ 147c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0, /* flags (reserved) */ 148c7ee0b5cSfei feng - Sun Microsystems - Beijing China }; 149c7ee0b5cSfei feng - Sun Microsystems - Beijing China 150c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 151c7ee0b5cSfei feng - Sun Microsystems - Beijing China * DMA attributes for a ring descriptor 152c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 153c7ee0b5cSfei feng - Sun Microsystems - Beijing China static ddi_dma_attr_t ring_desc_dma_attr = { 154c7ee0b5cSfei feng - Sun Microsystems - Beijing China DMA_ATTR_V0, /* version of this structure */ 155c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0, /* lowest usable address */ 156c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* highest usable address */ 157c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum DMAable byte count */ 158c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0x100, /* alignment in bytes */ 159c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0x100, /* burst sizes (any?) */ 160c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* minimum transfer */ 161c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum transfer */ 162c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum segment length */ 163c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* maximum number of segments */ 164c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* granularity */ 165c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0, /* flags (reserved) */ 166c7ee0b5cSfei feng - Sun Microsystems - Beijing China }; 167c7ee0b5cSfei feng - Sun Microsystems - Beijing China 168c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 169c7ee0b5cSfei feng - Sun Microsystems - Beijing China * DMA attributes for a cmd 170c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 171c7ee0b5cSfei feng - Sun Microsystems - Beijing China static ddi_dma_attr_t cmd_dma_attr = { 172c7ee0b5cSfei feng - Sun Microsystems - Beijing China DMA_ATTR_V0, /* version of this structure */ 173c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0, /* lowest usable address */ 174c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* highest usable address */ 175c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum DMAable byte count */ 176c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4, /* alignment in bytes */ 177c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0x100, /* burst sizes (any?) */ 178c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* minimum transfer */ 179c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum transfer */ 180c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum segment length */ 181c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* maximum number of segments */ 182c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* granularity */ 183c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0, /* flags (reserved) */ 184c7ee0b5cSfei feng - Sun Microsystems - Beijing China }; 185c7ee0b5cSfei feng - Sun Microsystems - Beijing China 186c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 187c7ee0b5cSfei feng - Sun Microsystems - Beijing China * DMA attributes for a rx buffer 188c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 189c7ee0b5cSfei feng - Sun Microsystems - Beijing China static ddi_dma_attr_t rx_buffer_dma_attr = { 190c7ee0b5cSfei feng - Sun Microsystems - Beijing China DMA_ATTR_V0, /* version of this structure */ 191c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0, /* lowest usable address */ 192c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* highest usable address */ 193c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum DMAable byte count */ 194c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0x100, /* alignment in bytes */ 195c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0x100, /* burst sizes (any?) */ 196c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* minimum transfer */ 197c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum transfer */ 198c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum segment length */ 199c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* maximum number of segments */ 200c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* granularity */ 201c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0, /* flags (reserved) */ 202c7ee0b5cSfei feng - Sun Microsystems - Beijing China }; 203c7ee0b5cSfei feng - Sun Microsystems - Beijing China 204c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 205c7ee0b5cSfei feng - Sun Microsystems - Beijing China * DMA attributes for a tx buffer. 206c7ee0b5cSfei feng - Sun Microsystems - Beijing China * the maximum number of segments is 4 for the hardware. 207c7ee0b5cSfei feng - Sun Microsystems - Beijing China * now all the wifi drivers put the whole frame in a single 208c7ee0b5cSfei feng - Sun Microsystems - Beijing China * descriptor, so we define the maximum number of segments 1, 209c7ee0b5cSfei feng - Sun Microsystems - Beijing China * just the same as the rx_buffer. we consider leverage the HW 210c7ee0b5cSfei feng - Sun Microsystems - Beijing China * ability in the future, that is why we don't define rx and tx 211c7ee0b5cSfei feng - Sun Microsystems - Beijing China * buffer_dma_attr as the same. 212c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 213c7ee0b5cSfei feng - Sun Microsystems - Beijing China static ddi_dma_attr_t tx_buffer_dma_attr = { 214c7ee0b5cSfei feng - Sun Microsystems - Beijing China DMA_ATTR_V0, /* version of this structure */ 215c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0, /* lowest usable address */ 216c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* highest usable address */ 217c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum DMAable byte count */ 218c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4, /* alignment in bytes */ 219c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0x100, /* burst sizes (any?) */ 220c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* minimum transfer */ 221c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum transfer */ 222c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum segment length */ 223c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* maximum number of segments */ 224c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* granularity */ 225c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0, /* flags (reserved) */ 226c7ee0b5cSfei feng - Sun Microsystems - Beijing China }; 227c7ee0b5cSfei feng - Sun Microsystems - Beijing China 228c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 229c7ee0b5cSfei feng - Sun Microsystems - Beijing China * DMA attributes for text and data part in the firmware 230c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 231c7ee0b5cSfei feng - Sun Microsystems - Beijing China static ddi_dma_attr_t fw_dma_attr = { 232c7ee0b5cSfei feng - Sun Microsystems - Beijing China DMA_ATTR_V0, /* version of this structure */ 233c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0, /* lowest usable address */ 234c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* highest usable address */ 235c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0x7fffffff, /* maximum DMAable byte count */ 236c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0x10, /* alignment in bytes */ 237c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0x100, /* burst sizes (any?) */ 238c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* minimum transfer */ 239c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum transfer */ 240c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0xffffffffU, /* maximum segment length */ 241c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* maximum number of segments */ 242c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1, /* granularity */ 243c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0, /* flags (reserved) */ 244c7ee0b5cSfei feng - Sun Microsystems - Beijing China }; 245c7ee0b5cSfei feng - Sun Microsystems - Beijing China 246c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 247c7ee0b5cSfei feng - Sun Microsystems - Beijing China * regs access attributes 248c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 249c7ee0b5cSfei feng - Sun Microsystems - Beijing China static ddi_device_acc_attr_t iwh_reg_accattr = { 250c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DEVICE_ATTR_V0, 251c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_STRUCTURE_LE_ACC, 252c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_STRICTORDER_ACC, 253c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DEFAULT_ACC 254c7ee0b5cSfei feng - Sun Microsystems - Beijing China }; 255c7ee0b5cSfei feng - Sun Microsystems - Beijing China 256c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 257b510adaeSfei feng - Sun Microsystems - Beijing China * DMA access attributes for descriptor 258b510adaeSfei feng - Sun Microsystems - Beijing China */ 259b510adaeSfei feng - Sun Microsystems - Beijing China static ddi_device_acc_attr_t iwh_dma_descattr = { 260b510adaeSfei feng - Sun Microsystems - Beijing China DDI_DEVICE_ATTR_V0, 261b510adaeSfei feng - Sun Microsystems - Beijing China DDI_STRUCTURE_LE_ACC, 262b510adaeSfei feng - Sun Microsystems - Beijing China DDI_STRICTORDER_ACC, 263b510adaeSfei feng - Sun Microsystems - Beijing China DDI_DEFAULT_ACC 264b510adaeSfei feng - Sun Microsystems - Beijing China }; 265b510adaeSfei feng - Sun Microsystems - Beijing China 266b510adaeSfei feng - Sun Microsystems - Beijing China /* 267c7ee0b5cSfei feng - Sun Microsystems - Beijing China * DMA access attributes 268c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 269c7ee0b5cSfei feng - Sun Microsystems - Beijing China static ddi_device_acc_attr_t iwh_dma_accattr = { 270c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DEVICE_ATTR_V0, 271c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_NEVERSWAP_ACC, 272c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_STRICTORDER_ACC, 273c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DEFAULT_ACC 274c7ee0b5cSfei feng - Sun Microsystems - Beijing China }; 275c7ee0b5cSfei feng - Sun Microsystems - Beijing China 276c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_ring_init(iwh_sc_t *); 277c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_ring_free(iwh_sc_t *); 278c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_alloc_shared(iwh_sc_t *); 279c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_free_shared(iwh_sc_t *); 280c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_alloc_kw(iwh_sc_t *); 281c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_free_kw(iwh_sc_t *); 282c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_alloc_fw_dma(iwh_sc_t *); 283c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_free_fw_dma(iwh_sc_t *); 284c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_alloc_rx_ring(iwh_sc_t *); 285c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_reset_rx_ring(iwh_sc_t *); 286c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_free_rx_ring(iwh_sc_t *); 287c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_alloc_tx_ring(iwh_sc_t *, iwh_tx_ring_t *, 288c7ee0b5cSfei feng - Sun Microsystems - Beijing China int, int); 289c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_reset_tx_ring(iwh_sc_t *, iwh_tx_ring_t *); 290c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_free_tx_ring(iwh_tx_ring_t *); 291c7ee0b5cSfei feng - Sun Microsystems - Beijing China static ieee80211_node_t *iwh_node_alloc(ieee80211com_t *); 292c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_node_free(ieee80211_node_t *); 293c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_newstate(ieee80211com_t *, enum ieee80211_state, int); 294c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_mac_access_enter(iwh_sc_t *); 295c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_mac_access_exit(iwh_sc_t *); 296c7ee0b5cSfei feng - Sun Microsystems - Beijing China static uint32_t iwh_reg_read(iwh_sc_t *, uint32_t); 297c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_reg_write(iwh_sc_t *, uint32_t, uint32_t); 298c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_load_init_firmware(iwh_sc_t *); 299c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_load_run_firmware(iwh_sc_t *); 300c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_tx_intr(iwh_sc_t *, iwh_rx_desc_t *); 301c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_cmd_intr(iwh_sc_t *, iwh_rx_desc_t *); 302c7ee0b5cSfei feng - Sun Microsystems - Beijing China static uint_t iwh_intr(caddr_t, caddr_t); 303c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_eep_load(iwh_sc_t *); 304c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_get_mac_from_eep(iwh_sc_t *); 305c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_eep_sem_down(iwh_sc_t *); 306c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_eep_sem_up(iwh_sc_t *); 307c7ee0b5cSfei feng - Sun Microsystems - Beijing China static uint_t iwh_rx_softintr(caddr_t, caddr_t); 308c7ee0b5cSfei feng - Sun Microsystems - Beijing China static uint8_t iwh_rate_to_plcp(int); 309c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_cmd(iwh_sc_t *, int, const void *, int, int); 310c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_set_led(iwh_sc_t *, uint8_t, uint8_t, uint8_t); 311c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_hw_set_before_auth(iwh_sc_t *); 312c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_scan(iwh_sc_t *); 313c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_config(iwh_sc_t *); 314c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_stop_master(iwh_sc_t *); 315c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_power_up(iwh_sc_t *); 316c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_preinit(iwh_sc_t *); 317c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_init(iwh_sc_t *); 318c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_stop(iwh_sc_t *); 319faceed93Sfei feng - Sun Microsystems - Beijing China static int iwh_quiesce(dev_info_t *t); 320c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_amrr_init(iwh_amrr_t *); 321c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_amrr_timeout(iwh_sc_t *); 322c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_amrr_ratectl(void *, ieee80211_node_t *); 323c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_ucode_alive(iwh_sc_t *, iwh_rx_desc_t *); 324c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_rx_phy_intr(iwh_sc_t *, iwh_rx_desc_t *); 325c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_rx_mpdu_intr(iwh_sc_t *, iwh_rx_desc_t *); 326c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_release_calib_buffer(iwh_sc_t *); 327c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_init_common(iwh_sc_t *); 328c7ee0b5cSfei feng - Sun Microsystems - Beijing China static uint8_t *iwh_eep_addr_trans(iwh_sc_t *, uint32_t); 329c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_put_seg_fw(iwh_sc_t *, uint32_t, uint32_t, uint32_t); 330c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_alive_common(iwh_sc_t *); 331c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_save_calib_result(iwh_sc_t *, iwh_rx_desc_t *); 332c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_tx_power_table(iwh_sc_t *, int); 333c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_attach(dev_info_t *, ddi_attach_cmd_t); 334c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_detach(dev_info_t *, ddi_detach_cmd_t); 335c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_destroy_locks(iwh_sc_t *); 336c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_send(ieee80211com_t *, mblk_t *, uint8_t); 337c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_thread(iwh_sc_t *); 338e2cf88acSQuaker Fang static int iwh_run_state_config(iwh_sc_t *); 339e2cf88acSQuaker Fang static int iwh_fast_recover(iwh_sc_t *); 340e2cf88acSQuaker Fang static int iwh_wme_update(ieee80211com_t *); 341e2cf88acSQuaker Fang static int iwh_qosparam_to_hw(iwh_sc_t *, int); 342e2cf88acSQuaker Fang static int iwh_wme_to_qos_ac(int); 343e2cf88acSQuaker Fang static uint16_t iwh_cw_e_to_cw(uint8_t); 344e2cf88acSQuaker Fang static int iwh_wmeparam_check(struct wmeParams *); 345e2cf88acSQuaker Fang static inline int iwh_wme_tid_qos_ac(int); 346e2cf88acSQuaker Fang static inline int iwh_qos_ac_to_txq(int); 347e2cf88acSQuaker Fang static int iwh_wme_tid_to_txq(int); 348e2cf88acSQuaker Fang static void iwh_init_ht_conf(iwh_sc_t *); 349e2cf88acSQuaker Fang static void iwh_overwrite_11n_rateset(iwh_sc_t *); 350e2cf88acSQuaker Fang static void iwh_overwrite_ic_default(iwh_sc_t *); 351e2cf88acSQuaker Fang static void iwh_config_rxon_chain(iwh_sc_t *); 352e2cf88acSQuaker Fang static int iwh_add_ap_sta(iwh_sc_t *); 353e2cf88acSQuaker Fang static int iwh_ap_lq(iwh_sc_t *); 354e2cf88acSQuaker Fang static void iwh_recv_action(struct ieee80211_node *, 355e2cf88acSQuaker Fang const uint8_t *, const uint8_t *); 356e2cf88acSQuaker Fang static int iwh_send_action(struct ieee80211_node *, 357e2cf88acSQuaker Fang int, int, uint16_t[4]); 358e2cf88acSQuaker Fang static int iwh_is_max_rate(ieee80211_node_t *); 359e2cf88acSQuaker Fang static int iwh_is_min_rate(ieee80211_node_t *); 360e2cf88acSQuaker Fang static void iwh_increase_rate(ieee80211_node_t *); 361e2cf88acSQuaker Fang static void iwh_decrease_rate(ieee80211_node_t *); 362e2cf88acSQuaker Fang static int iwh_alloc_dma_mem(iwh_sc_t *, size_t, 363e2cf88acSQuaker Fang ddi_dma_attr_t *, ddi_device_acc_attr_t *, 364e2cf88acSQuaker Fang uint_t, iwh_dma_t *); 365e2cf88acSQuaker Fang static void iwh_free_dma_mem(iwh_dma_t *); 3667d483bc1Sfei feng - Sun Microsystems - Beijing China static int iwh_reset_hw(iwh_sc_t *); 3676f12def4Spengcheng chen - Sun Microsystems - Beijing China 368c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 369c7ee0b5cSfei feng - Sun Microsystems - Beijing China * GLD specific operations 370c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 371c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_m_stat(void *, uint_t, uint64_t *); 372c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_m_start(void *); 373c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_m_stop(void *); 374c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_m_unicst(void *, const uint8_t *); 375c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_m_multicst(void *, boolean_t, const uint8_t *); 376c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int iwh_m_promisc(void *, boolean_t); 377c7ee0b5cSfei feng - Sun Microsystems - Beijing China static mblk_t *iwh_m_tx(void *, mblk_t *); 378c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void iwh_m_ioctl(void *, queue_t *, mblk_t *); 3797efa17f5Sfei feng - Sun Microsystems - Beijing China static int iwh_m_setprop(void *arg, const char *pr_name, 3807efa17f5Sfei feng - Sun Microsystems - Beijing China mac_prop_id_t wldp_pr_num, uint_t wldp_length, const void *wldp_buf); 3817efa17f5Sfei feng - Sun Microsystems - Beijing China static int iwh_m_getprop(void *arg, const char *pr_name, 382*0dc2366fSVenugopal Iyer mac_prop_id_t wldp_pr_num, uint_t wldp_length, 383*0dc2366fSVenugopal Iyer void *wldp_buf); 384*0dc2366fSVenugopal Iyer static void iwh_m_propinfo(void *arg, const char *pr_name, 385*0dc2366fSVenugopal Iyer mac_prop_id_t wldp_pr_num, mac_prop_info_handle_t mph); 386c7ee0b5cSfei feng - Sun Microsystems - Beijing China 387c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 388c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Supported rates for 802.11b/g modes (in 500Kbps unit). 389c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 390c7ee0b5cSfei feng - Sun Microsystems - Beijing China static const struct ieee80211_rateset iwh_rateset_11b = 391c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 4, { 2, 4, 11, 22 } }; 392c7ee0b5cSfei feng - Sun Microsystems - Beijing China 393c7ee0b5cSfei feng - Sun Microsystems - Beijing China static const struct ieee80211_rateset iwh_rateset_11g = 394c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } }; 395c7ee0b5cSfei feng - Sun Microsystems - Beijing China 396c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 397e2cf88acSQuaker Fang * Default 11n reates supported by this station. 398e2cf88acSQuaker Fang */ 399e2cf88acSQuaker Fang extern struct ieee80211_htrateset ieee80211_rateset_11n; 400e2cf88acSQuaker Fang 401e2cf88acSQuaker Fang /* 402c7ee0b5cSfei feng - Sun Microsystems - Beijing China * For mfthread only 403c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 404c7ee0b5cSfei feng - Sun Microsystems - Beijing China extern pri_t minclsyspri; 405c7ee0b5cSfei feng - Sun Microsystems - Beijing China 406c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define DRV_NAME_SP "iwh" 407c7ee0b5cSfei feng - Sun Microsystems - Beijing China 408c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 409c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Module Loading Data & Entry Points 410c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 411c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DEFINE_STREAM_OPS(iwh_devops, nulldev, nulldev, iwh_attach, 412faceed93Sfei feng - Sun Microsystems - Beijing China iwh_detach, nodev, NULL, D_MP, NULL, iwh_quiesce); 413c7ee0b5cSfei feng - Sun Microsystems - Beijing China 414c7ee0b5cSfei feng - Sun Microsystems - Beijing China static struct modldrv iwh_modldrv = { 415c7ee0b5cSfei feng - Sun Microsystems - Beijing China &mod_driverops, 41689b2a9fbSfei feng - Sun Microsystems - Beijing China "Intel(R) ShirleyPeak/EchoPeak driver(N)", 417c7ee0b5cSfei feng - Sun Microsystems - Beijing China &iwh_devops 418c7ee0b5cSfei feng - Sun Microsystems - Beijing China }; 419c7ee0b5cSfei feng - Sun Microsystems - Beijing China 420c7ee0b5cSfei feng - Sun Microsystems - Beijing China static struct modlinkage iwh_modlinkage = { 421c7ee0b5cSfei feng - Sun Microsystems - Beijing China MODREV_1, 422c7ee0b5cSfei feng - Sun Microsystems - Beijing China &iwh_modldrv, 423c7ee0b5cSfei feng - Sun Microsystems - Beijing China NULL 424c7ee0b5cSfei feng - Sun Microsystems - Beijing China }; 425c7ee0b5cSfei feng - Sun Microsystems - Beijing China 426c7ee0b5cSfei feng - Sun Microsystems - Beijing China int 427c7ee0b5cSfei feng - Sun Microsystems - Beijing China _init(void) 428c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 429c7ee0b5cSfei feng - Sun Microsystems - Beijing China int status; 430c7ee0b5cSfei feng - Sun Microsystems - Beijing China 431c7ee0b5cSfei feng - Sun Microsystems - Beijing China status = ddi_soft_state_init(&iwh_soft_state_p, 432c7ee0b5cSfei feng - Sun Microsystems - Beijing China sizeof (iwh_sc_t), 1); 433c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (status != DDI_SUCCESS) { 434c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (status); 435c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 436c7ee0b5cSfei feng - Sun Microsystems - Beijing China 437c7ee0b5cSfei feng - Sun Microsystems - Beijing China mac_init_ops(&iwh_devops, DRV_NAME_SP); 438c7ee0b5cSfei feng - Sun Microsystems - Beijing China status = mod_install(&iwh_modlinkage); 439c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (status != DDI_SUCCESS) { 440c7ee0b5cSfei feng - Sun Microsystems - Beijing China mac_fini_ops(&iwh_devops); 441c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_soft_state_fini(&iwh_soft_state_p); 442c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 443c7ee0b5cSfei feng - Sun Microsystems - Beijing China 444c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (status); 445c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 446c7ee0b5cSfei feng - Sun Microsystems - Beijing China 447c7ee0b5cSfei feng - Sun Microsystems - Beijing China int 448c7ee0b5cSfei feng - Sun Microsystems - Beijing China _fini(void) 449c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 450c7ee0b5cSfei feng - Sun Microsystems - Beijing China int status; 451c7ee0b5cSfei feng - Sun Microsystems - Beijing China 452c7ee0b5cSfei feng - Sun Microsystems - Beijing China status = mod_remove(&iwh_modlinkage); 453c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (DDI_SUCCESS == status) { 454c7ee0b5cSfei feng - Sun Microsystems - Beijing China mac_fini_ops(&iwh_devops); 455c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_soft_state_fini(&iwh_soft_state_p); 456c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 457c7ee0b5cSfei feng - Sun Microsystems - Beijing China 458c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (status); 459c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 460c7ee0b5cSfei feng - Sun Microsystems - Beijing China 461c7ee0b5cSfei feng - Sun Microsystems - Beijing China int 462c7ee0b5cSfei feng - Sun Microsystems - Beijing China _info(struct modinfo *mip) 463c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 464c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (mod_info(&iwh_modlinkage, mip)); 465c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 466c7ee0b5cSfei feng - Sun Microsystems - Beijing China 467c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 468c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Mac Call Back entries 469c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 470c7ee0b5cSfei feng - Sun Microsystems - Beijing China mac_callbacks_t iwh_m_callbacks = { 471*0dc2366fSVenugopal Iyer MC_IOCTL | MC_SETPROP | MC_GETPROP | MC_PROPINFO, 472c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_m_stat, 473c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_m_start, 474c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_m_stop, 475c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_m_promisc, 476c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_m_multicst, 477c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_m_unicst, 478c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_m_tx, 479*0dc2366fSVenugopal Iyer NULL, 4807efa17f5Sfei feng - Sun Microsystems - Beijing China iwh_m_ioctl, 4817efa17f5Sfei feng - Sun Microsystems - Beijing China NULL, 4827efa17f5Sfei feng - Sun Microsystems - Beijing China NULL, 4837efa17f5Sfei feng - Sun Microsystems - Beijing China NULL, 4847efa17f5Sfei feng - Sun Microsystems - Beijing China iwh_m_setprop, 485*0dc2366fSVenugopal Iyer iwh_m_getprop, 486*0dc2366fSVenugopal Iyer iwh_m_propinfo 487c7ee0b5cSfei feng - Sun Microsystems - Beijing China }; 488c7ee0b5cSfei feng - Sun Microsystems - Beijing China 489c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 490c7ee0b5cSfei feng - Sun Microsystems - Beijing China void 491c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_dbg(uint32_t flags, const char *fmt, ...) 492c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 493c7ee0b5cSfei feng - Sun Microsystems - Beijing China va_list ap; 494c7ee0b5cSfei feng - Sun Microsystems - Beijing China 495c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (flags & iwh_dbg_flags) { 496c7ee0b5cSfei feng - Sun Microsystems - Beijing China va_start(ap, fmt); 497d40f4da4Spengcheng chen - Sun Microsystems - Beijing China vcmn_err(CE_NOTE, fmt, ap); 498c7ee0b5cSfei feng - Sun Microsystems - Beijing China va_end(ap); 499c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 500c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 501e2cf88acSQuaker Fang #endif /* DEBUG */ 502c7ee0b5cSfei feng - Sun Microsystems - Beijing China 503c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 504c7ee0b5cSfei feng - Sun Microsystems - Beijing China * device operations 505c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 506c7ee0b5cSfei feng - Sun Microsystems - Beijing China int 507c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 508c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 509c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_sc_t *sc; 510c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211com_t *ic; 511e2cf88acSQuaker Fang int instance, i; 512c7ee0b5cSfei feng - Sun Microsystems - Beijing China char strbuf[32]; 513c7ee0b5cSfei feng - Sun Microsystems - Beijing China wifi_data_t wd = { 0 }; 514c7ee0b5cSfei feng - Sun Microsystems - Beijing China mac_register_t *macp; 515c7ee0b5cSfei feng - Sun Microsystems - Beijing China int intr_type; 516c7ee0b5cSfei feng - Sun Microsystems - Beijing China int intr_count; 517c7ee0b5cSfei feng - Sun Microsystems - Beijing China int intr_actual; 518e2cf88acSQuaker Fang int err = DDI_FAILURE; 519c7ee0b5cSfei feng - Sun Microsystems - Beijing China 520c7ee0b5cSfei feng - Sun Microsystems - Beijing China switch (cmd) { 521c7ee0b5cSfei feng - Sun Microsystems - Beijing China case DDI_ATTACH: 522c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 523e2cf88acSQuaker Fang 524c7ee0b5cSfei feng - Sun Microsystems - Beijing China case DDI_RESUME: 525e2cf88acSQuaker Fang instance = ddi_get_instance(dip); 526c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(iwh_soft_state_p, 527e2cf88acSQuaker Fang instance); 528c7ee0b5cSfei feng - Sun Microsystems - Beijing China ASSERT(sc != NULL); 52909539a3cSpengcheng chen - Sun Microsystems - Beijing China 530e2cf88acSQuaker Fang if (sc->sc_flags & IWH_F_RUNNING) { 531d40f4da4Spengcheng chen - Sun Microsystems - Beijing China (void) iwh_init(sc); 532e2cf88acSQuaker Fang } 533d40f4da4Spengcheng chen - Sun Microsystems - Beijing China 53489b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_SUSPEND); 53589b2a9fbSfei feng - Sun Microsystems - Beijing China 536e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_RESUME, "iwh_attach(): " 537e2cf88acSQuaker Fang "resume\n")); 538c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS); 539e2cf88acSQuaker Fang 540c7ee0b5cSfei feng - Sun Microsystems - Beijing China default: 541c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail1; 542c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 543c7ee0b5cSfei feng - Sun Microsystems - Beijing China 544c7ee0b5cSfei feng - Sun Microsystems - Beijing China instance = ddi_get_instance(dip); 545c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = ddi_soft_state_zalloc(iwh_soft_state_p, instance); 546c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 547c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 548c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to allocate soft state\n"); 549c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail1; 550c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 551e2cf88acSQuaker Fang 552c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(iwh_soft_state_p, instance); 553e2cf88acSQuaker Fang ASSERT(sc != NULL); 554e2cf88acSQuaker Fang 555c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_dip = dip; 556c7ee0b5cSfei feng - Sun Microsystems - Beijing China 557c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 558c7ee0b5cSfei feng - Sun Microsystems - Beijing China * map configure space 559c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 560c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = ddi_regs_map_setup(dip, 0, &sc->sc_cfg_base, 0, 0, 561c7ee0b5cSfei feng - Sun Microsystems - Beijing China &iwh_reg_accattr, &sc->sc_cfg_handle); 562c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 563c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 564c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to map config spaces regs\n"); 565c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail2; 566c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 567c7ee0b5cSfei feng - Sun Microsystems - Beijing China 568e2cf88acSQuaker Fang sc->sc_dev_id = ddi_get16(sc->sc_cfg_handle, 569e2cf88acSQuaker Fang (uint16_t *)(sc->sc_cfg_base + PCI_CONF_DEVID)); 570e2cf88acSQuaker Fang if ((sc->sc_dev_id != 0x4232) && 571e2cf88acSQuaker Fang (sc->sc_dev_id != 0x4235) && 572e2cf88acSQuaker Fang (sc->sc_dev_id != 0x4236) && 573e2cf88acSQuaker Fang (sc->sc_dev_id != 0x4237) && 57489b2a9fbSfei feng - Sun Microsystems - Beijing China (sc->sc_dev_id != 0x423a) && 57589b2a9fbSfei feng - Sun Microsystems - Beijing China (sc->sc_dev_id != 0x423b) && 57689b2a9fbSfei feng - Sun Microsystems - Beijing China (sc->sc_dev_id != 0x423c) && 57789b2a9fbSfei feng - Sun Microsystems - Beijing China (sc->sc_dev_id != 0x423d)) { 578e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_attach(): " 579e2cf88acSQuaker Fang "Do not support this device\n"); 580e2cf88acSQuaker Fang goto attach_fail3; 581e2cf88acSQuaker Fang } 582e2cf88acSQuaker Fang 583e2cf88acSQuaker Fang iwh_init_ht_conf(sc); 584e2cf88acSQuaker Fang iwh_overwrite_11n_rateset(sc); 585c7ee0b5cSfei feng - Sun Microsystems - Beijing China 586c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_rev = ddi_get8(sc->sc_cfg_handle, 587c7ee0b5cSfei feng - Sun Microsystems - Beijing China (uint8_t *)(sc->sc_cfg_base + PCI_CONF_REVID)); 588c7ee0b5cSfei feng - Sun Microsystems - Beijing China 589c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 590c7ee0b5cSfei feng - Sun Microsystems - Beijing China * keep from disturbing C3 state of CPU 591c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 59289b2a9fbSfei feng - Sun Microsystems - Beijing China ddi_put8(sc->sc_cfg_handle, (uint8_t *)(sc->sc_cfg_base + 59389b2a9fbSfei feng - Sun Microsystems - Beijing China PCI_CFG_RETRY_TIMEOUT), 0); 594e2cf88acSQuaker Fang 595e2cf88acSQuaker Fang /* 596e2cf88acSQuaker Fang * determine the size of buffer for frame and command to ucode 597e2cf88acSQuaker Fang */ 598c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_clsz = ddi_get16(sc->sc_cfg_handle, 599c7ee0b5cSfei feng - Sun Microsystems - Beijing China (uint16_t *)(sc->sc_cfg_base + PCI_CONF_CACHE_LINESZ)); 600c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (!sc->sc_clsz) { 601c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_clsz = 16; 602c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 603c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_clsz = (sc->sc_clsz << 2); 604e2cf88acSQuaker Fang 605e2cf88acSQuaker Fang sc->sc_dmabuf_sz = roundup(0x2000 + sizeof (struct ieee80211_frame) + 606c7ee0b5cSfei feng - Sun Microsystems - Beijing China IEEE80211_MTU + IEEE80211_CRC_LEN + 607c7ee0b5cSfei feng - Sun Microsystems - Beijing China (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + 608c7ee0b5cSfei feng - Sun Microsystems - Beijing China IEEE80211_WEP_CRCLEN), sc->sc_clsz); 609c7ee0b5cSfei feng - Sun Microsystems - Beijing China 610c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 611c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Map operating registers 612c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 613c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = ddi_regs_map_setup(dip, 1, &sc->sc_base, 614c7ee0b5cSfei feng - Sun Microsystems - Beijing China 0, 0, &iwh_reg_accattr, &sc->sc_handle); 615c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 616c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 617c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to map device regs\n"); 618c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail3; 619c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 620c7ee0b5cSfei feng - Sun Microsystems - Beijing China 621c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 622c7ee0b5cSfei feng - Sun Microsystems - Beijing China * this is used to differentiate type of hardware 623c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 624c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_hw_rev = IWH_READ(sc, CSR_HW_REV); 625c7ee0b5cSfei feng - Sun Microsystems - Beijing China 626c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = ddi_intr_get_supported_types(dip, &intr_type); 627c7ee0b5cSfei feng - Sun Microsystems - Beijing China if ((err != DDI_SUCCESS) || (!(intr_type & DDI_INTR_TYPE_FIXED))) { 628c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 629c7ee0b5cSfei feng - Sun Microsystems - Beijing China "fixed type interrupt is not supported\n"); 630c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail4; 631c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 632c7ee0b5cSfei feng - Sun Microsystems - Beijing China 633c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = ddi_intr_get_nintrs(dip, DDI_INTR_TYPE_FIXED, &intr_count); 634c7ee0b5cSfei feng - Sun Microsystems - Beijing China if ((err != DDI_SUCCESS) || (intr_count != 1)) { 635c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 636c7ee0b5cSfei feng - Sun Microsystems - Beijing China "no fixed interrupts\n"); 637c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail4; 638c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 639c7ee0b5cSfei feng - Sun Microsystems - Beijing China 640c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_intr_htable = kmem_zalloc(sizeof (ddi_intr_handle_t), KM_SLEEP); 641c7ee0b5cSfei feng - Sun Microsystems - Beijing China 642c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = ddi_intr_alloc(dip, sc->sc_intr_htable, DDI_INTR_TYPE_FIXED, 0, 643c7ee0b5cSfei feng - Sun Microsystems - Beijing China intr_count, &intr_actual, 0); 644c7ee0b5cSfei feng - Sun Microsystems - Beijing China if ((err != DDI_SUCCESS) || (intr_actual != 1)) { 645c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 646c7ee0b5cSfei feng - Sun Microsystems - Beijing China "ddi_intr_alloc() failed 0x%x\n", err); 647c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail5; 648c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 649c7ee0b5cSfei feng - Sun Microsystems - Beijing China 650c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = ddi_intr_get_pri(sc->sc_intr_htable[0], &sc->sc_intr_pri); 651c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 652c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 653c7ee0b5cSfei feng - Sun Microsystems - Beijing China "ddi_intr_get_pri() failed 0x%x\n", err); 654c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail6; 655c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 656c7ee0b5cSfei feng - Sun Microsystems - Beijing China 657c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_init(&sc->sc_glock, NULL, MUTEX_DRIVER, 658c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_INTR_PRI(sc->sc_intr_pri)); 659c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_init(&sc->sc_tx_lock, NULL, MUTEX_DRIVER, 660c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_INTR_PRI(sc->sc_intr_pri)); 661c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_init(&sc->sc_mt_lock, NULL, MUTEX_DRIVER, 662c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_INTR_PRI(sc->sc_intr_pri)); 663c7ee0b5cSfei feng - Sun Microsystems - Beijing China 664c7ee0b5cSfei feng - Sun Microsystems - Beijing China cv_init(&sc->sc_cmd_cv, NULL, CV_DRIVER, NULL); 665c7ee0b5cSfei feng - Sun Microsystems - Beijing China cv_init(&sc->sc_put_seg_cv, NULL, CV_DRIVER, NULL); 666c7ee0b5cSfei feng - Sun Microsystems - Beijing China cv_init(&sc->sc_ucode_cv, NULL, CV_DRIVER, NULL); 667c7ee0b5cSfei feng - Sun Microsystems - Beijing China 668c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 669c7ee0b5cSfei feng - Sun Microsystems - Beijing China * initialize the mfthread 670c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 671c7ee0b5cSfei feng - Sun Microsystems - Beijing China cv_init(&sc->sc_mt_cv, NULL, CV_DRIVER, NULL); 672c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_mf_thread = NULL; 673c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_mf_thread_switch = 0; 674c7ee0b5cSfei feng - Sun Microsystems - Beijing China 675c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 676c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Allocate shared buffer for communication between driver and ucode. 677c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 678c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_shared(sc); 679c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 680c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 681c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to allocate shared page\n"); 682c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail7; 683c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 684c7ee0b5cSfei feng - Sun Microsystems - Beijing China 685c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(sc->sc_shared, 0, sizeof (iwh_shared_t)); 686c7ee0b5cSfei feng - Sun Microsystems - Beijing China 687c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 688c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Allocate keep warm page. 689c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 690c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_kw(sc); 691c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 692c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 693c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to allocate keep warm page\n"); 694c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail8; 695c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 696c7ee0b5cSfei feng - Sun Microsystems - Beijing China 6977d483bc1Sfei feng - Sun Microsystems - Beijing China err = iwh_reset_hw(sc); 6987d483bc1Sfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 6997d483bc1Sfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 7007d483bc1Sfei feng - Sun Microsystems - Beijing China "failed to reset hardware\n"); 7017d483bc1Sfei feng - Sun Microsystems - Beijing China goto attach_fail9; 7027d483bc1Sfei feng - Sun Microsystems - Beijing China } 7037d483bc1Sfei feng - Sun Microsystems - Beijing China 704c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 705c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Do some necessary hardware initializations. 706c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 707c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_preinit(sc); 708c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 709c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 710c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to initialize hardware\n"); 711c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail9; 712c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 713c7ee0b5cSfei feng - Sun Microsystems - Beijing China 714c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 715c7ee0b5cSfei feng - Sun Microsystems - Beijing China * get hardware configurations from eeprom 716c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 717c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_eep_load(sc); 718e2cf88acSQuaker Fang if (err != IWH_SUCCESS) { 719c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 720c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to load eeprom\n"); 721c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail9; 722c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 723c7ee0b5cSfei feng - Sun Microsystems - Beijing China 724c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (IWH_READ_EEP_SHORT(sc, EEP_VERSION) < 0x011a) { 725e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_EEPROM, "iwh_attach(): " 726e2cf88acSQuaker Fang "unsupported eeprom detected\n")); 727c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail9; 728c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 729c7ee0b5cSfei feng - Sun Microsystems - Beijing China 730c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 731c7ee0b5cSfei feng - Sun Microsystems - Beijing China * get MAC address of this chipset 732c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 733c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_get_mac_from_eep(sc); 734c7ee0b5cSfei feng - Sun Microsystems - Beijing China 735c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 736c7ee0b5cSfei feng - Sun Microsystems - Beijing China * calibration information from EEPROM 737c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 738c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_eep_calib = (struct iwh_eep_calibration *) 739c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_eep_addr_trans(sc, EEP_CALIBRATION); 740c7ee0b5cSfei feng - Sun Microsystems - Beijing China 741c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 742c7ee0b5cSfei feng - Sun Microsystems - Beijing China * initialize TX and RX ring buffers 743c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 744c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_ring_init(sc); 745c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 746c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 747c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to allocate and initialize ring\n"); 748c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail9; 749c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 750c7ee0b5cSfei feng - Sun Microsystems - Beijing China 75189b2a9fbSfei feng - Sun Microsystems - Beijing China if ((0x423c == sc->sc_dev_id) || (0x423d == sc->sc_dev_id)) { 75289b2a9fbSfei feng - Sun Microsystems - Beijing China sc->sc_hdr = (iwh_firmware_hdr_t *)iwh_fw_5150_bin; 75389b2a9fbSfei feng - Sun Microsystems - Beijing China } else { 75489b2a9fbSfei feng - Sun Microsystems - Beijing China sc->sc_hdr = (iwh_firmware_hdr_t *)iwh_fw_5000_bin; 75589b2a9fbSfei feng - Sun Microsystems - Beijing China } 756c7ee0b5cSfei feng - Sun Microsystems - Beijing China 757c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 758c7ee0b5cSfei feng - Sun Microsystems - Beijing China * copy ucode to dma buffer 759c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 760c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_fw_dma(sc); 761c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 762c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 763c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to allocate firmware dma\n"); 764c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail10; 765c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 766c7ee0b5cSfei feng - Sun Microsystems - Beijing China 767c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 768c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Initialize the wifi part, which will be used by 769c7ee0b5cSfei feng - Sun Microsystems - Beijing China * 802.11 module 770c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 771c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic = &sc->sc_ic; 772e2cf88acSQuaker Fang ic->ic_phytype = IEEE80211_T_HT; 773c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ 774c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_state = IEEE80211_S_INIT; 775c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_maxrssi = 100; /* experimental number */ 776c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_caps = IEEE80211_C_SHPREAMBLE | IEEE80211_C_TXPMGT | 777c7ee0b5cSfei feng - Sun Microsystems - Beijing China IEEE80211_C_PMGT | IEEE80211_C_SHSLOT; 778c7ee0b5cSfei feng - Sun Microsystems - Beijing China 779c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 780c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Support WPA/WPA2 781c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 782c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_caps |= IEEE80211_C_WPA; 783c7ee0b5cSfei feng - Sun Microsystems - Beijing China 784c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 785e2cf88acSQuaker Fang * Support QoS/WME 786e2cf88acSQuaker Fang */ 787e2cf88acSQuaker Fang ic->ic_caps |= IEEE80211_C_WME; 788e2cf88acSQuaker Fang ic->ic_wme.wme_update = iwh_wme_update; 789e2cf88acSQuaker Fang 790e2cf88acSQuaker Fang /* 791e2cf88acSQuaker Fang * Support 802.11n/HT 792e2cf88acSQuaker Fang */ 793e2cf88acSQuaker Fang if (sc->sc_ht_conf.ht_support) { 794e2cf88acSQuaker Fang ic->ic_htcaps = IEEE80211_HTC_HT | 795e2cf88acSQuaker Fang IEEE80211_HTC_AMSDU; 796e2cf88acSQuaker Fang ic->ic_htcaps |= IEEE80211_HTCAP_MAXAMSDU_7935; 797e2cf88acSQuaker Fang } 798e2cf88acSQuaker Fang 799e2cf88acSQuaker Fang /* 800c7ee0b5cSfei feng - Sun Microsystems - Beijing China * set supported .11b and .11g rates 801c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 802c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_sup_rates[IEEE80211_MODE_11B] = iwh_rateset_11b; 803c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_sup_rates[IEEE80211_MODE_11G] = iwh_rateset_11g; 804c7ee0b5cSfei feng - Sun Microsystems - Beijing China 805c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 806d5bd65e4Sfei feng - Sun Microsystems - Beijing China * set supported .11b and .11g channels (1 through 11) 807c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 808d5bd65e4Sfei feng - Sun Microsystems - Beijing China for (i = 1; i <= 11; i++) { 809c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_sup_channels[i].ich_freq = 810c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); 811c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_sup_channels[i].ich_flags = 812c7ee0b5cSfei feng - Sun Microsystems - Beijing China IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | 813d5bd65e4Sfei feng - Sun Microsystems - Beijing China IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ | 814d5bd65e4Sfei feng - Sun Microsystems - Beijing China IEEE80211_CHAN_PASSIVE; 815e2cf88acSQuaker Fang 816e2cf88acSQuaker Fang if (sc->sc_ht_conf.cap & HT_CAP_SUP_WIDTH) { 817e2cf88acSQuaker Fang ic->ic_sup_channels[i].ich_flags |= 818e2cf88acSQuaker Fang IEEE80211_CHAN_HT40; 819e2cf88acSQuaker Fang } else { 820e2cf88acSQuaker Fang ic->ic_sup_channels[i].ich_flags |= 821e2cf88acSQuaker Fang IEEE80211_CHAN_HT20; 822e2cf88acSQuaker Fang } 823c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 824c7ee0b5cSfei feng - Sun Microsystems - Beijing China 825c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_ibss_chan = &ic->ic_sup_channels[0]; 826c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_xmit = iwh_send; 827c7ee0b5cSfei feng - Sun Microsystems - Beijing China 828c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 829c7ee0b5cSfei feng - Sun Microsystems - Beijing China * attach to 802.11 module 830c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 831c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_attach(ic); 832c7ee0b5cSfei feng - Sun Microsystems - Beijing China 833c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 834c7ee0b5cSfei feng - Sun Microsystems - Beijing China * different instance has different WPA door 835c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 836c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) snprintf(ic->ic_wpadoor, MAX_IEEE80211STR, "%s_%s%d", WPA_DOOR, 837c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_driver_name(dip), 838c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_get_instance(dip)); 839c7ee0b5cSfei feng - Sun Microsystems - Beijing China 840c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 841e2cf88acSQuaker Fang * Overwrite 80211 default configurations. 842c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 843e2cf88acSQuaker Fang iwh_overwrite_ic_default(sc); 844c7ee0b5cSfei feng - Sun Microsystems - Beijing China 845c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 846c7ee0b5cSfei feng - Sun Microsystems - Beijing China * initialize 802.11 module 847c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 848c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_media_init(ic); 849c7ee0b5cSfei feng - Sun Microsystems - Beijing China 850c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 851c7ee0b5cSfei feng - Sun Microsystems - Beijing China * initialize default tx key 852c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 853c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_def_txkey = 0; 854c7ee0b5cSfei feng - Sun Microsystems - Beijing China 855c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = ddi_intr_add_softint(dip, &sc->sc_soft_hdl, DDI_INTR_SOFTPRI_MAX, 856c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_rx_softintr, (caddr_t)sc); 857c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 858c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 859c7ee0b5cSfei feng - Sun Microsystems - Beijing China "add soft interrupt failed\n"); 860c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail12; 861c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 862c7ee0b5cSfei feng - Sun Microsystems - Beijing China 863c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = ddi_intr_add_handler(sc->sc_intr_htable[0], iwh_intr, 864c7ee0b5cSfei feng - Sun Microsystems - Beijing China (caddr_t)sc, NULL); 865c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 866c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 867c7ee0b5cSfei feng - Sun Microsystems - Beijing China "ddi_intr_add_handle() failed\n"); 868c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail13; 869c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 870c7ee0b5cSfei feng - Sun Microsystems - Beijing China 871c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = ddi_intr_enable(sc->sc_intr_htable[0]); 872c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 873c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 874c7ee0b5cSfei feng - Sun Microsystems - Beijing China "ddi_intr_enable() failed\n"); 875c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail14; 876c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 877c7ee0b5cSfei feng - Sun Microsystems - Beijing China 878c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 879c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Initialize pointer to device specific functions 880c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 881c7ee0b5cSfei feng - Sun Microsystems - Beijing China wd.wd_secalloc = WIFI_SEC_NONE; 882c7ee0b5cSfei feng - Sun Microsystems - Beijing China wd.wd_opmode = ic->ic_opmode; 883c7ee0b5cSfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_macaddr); 884c7ee0b5cSfei feng - Sun Microsystems - Beijing China 885c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 886c7ee0b5cSfei feng - Sun Microsystems - Beijing China * create relation to GLD 887c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 888c7ee0b5cSfei feng - Sun Microsystems - Beijing China macp = mac_alloc(MAC_VERSION); 889e2cf88acSQuaker Fang if (NULL == macp) { 890c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 891c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to do mac_alloc()\n"); 892c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail15; 893c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 894c7ee0b5cSfei feng - Sun Microsystems - Beijing China 895c7ee0b5cSfei feng - Sun Microsystems - Beijing China macp->m_type_ident = MAC_PLUGIN_IDENT_WIFI; 896c7ee0b5cSfei feng - Sun Microsystems - Beijing China macp->m_driver = sc; 897c7ee0b5cSfei feng - Sun Microsystems - Beijing China macp->m_dip = dip; 898c7ee0b5cSfei feng - Sun Microsystems - Beijing China macp->m_src_addr = ic->ic_macaddr; 899c7ee0b5cSfei feng - Sun Microsystems - Beijing China macp->m_callbacks = &iwh_m_callbacks; 900c7ee0b5cSfei feng - Sun Microsystems - Beijing China macp->m_min_sdu = 0; 901c7ee0b5cSfei feng - Sun Microsystems - Beijing China macp->m_max_sdu = IEEE80211_MTU; 902c7ee0b5cSfei feng - Sun Microsystems - Beijing China macp->m_pdata = &wd; 903c7ee0b5cSfei feng - Sun Microsystems - Beijing China macp->m_pdata_size = sizeof (wd); 904c7ee0b5cSfei feng - Sun Microsystems - Beijing China 905c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 906c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Register the macp to mac 907c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 908c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = mac_register(macp, &ic->ic_mach); 909c7ee0b5cSfei feng - Sun Microsystems - Beijing China mac_free(macp); 910c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 911c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 912c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to do mac_register()\n"); 913c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto attach_fail15; 914c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 915c7ee0b5cSfei feng - Sun Microsystems - Beijing China 916c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 917c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Create minor node of type DDI_NT_NET_WIFI 918c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 919c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) snprintf(strbuf, sizeof (strbuf), DRV_NAME_SP"%d", instance); 920c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = ddi_create_minor_node(dip, strbuf, S_IFCHR, 921c7ee0b5cSfei feng - Sun Microsystems - Beijing China instance + 1, DDI_NT_NET_WIFI, 0); 922e2cf88acSQuaker Fang if (err != DDI_SUCCESS) { 923c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_attach(): " 924c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to do ddi_create_minor_node()\n"); 925e2cf88acSQuaker Fang } 926c7ee0b5cSfei feng - Sun Microsystems - Beijing China 927c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 928c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Notify link is down now 929c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 930c7ee0b5cSfei feng - Sun Microsystems - Beijing China mac_link_update(ic->ic_mach, LINK_STATE_DOWN); 931c7ee0b5cSfei feng - Sun Microsystems - Beijing China 932c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 933c7ee0b5cSfei feng - Sun Microsystems - Beijing China * create the mf thread to handle the link status, 934c7ee0b5cSfei feng - Sun Microsystems - Beijing China * recovery fatal error, etc. 935c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 936c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_mf_thread_switch = 1; 937c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (NULL == sc->sc_mf_thread) { 938c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_mf_thread = thread_create((caddr_t)NULL, 0, 939c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_thread, sc, 0, &p0, TS_RUN, minclsyspri); 940c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 941c7ee0b5cSfei feng - Sun Microsystems - Beijing China 94289b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_or_32(&sc->sc_flags, IWH_F_ATTACHED); 943c7ee0b5cSfei feng - Sun Microsystems - Beijing China 944c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS); 945c7ee0b5cSfei feng - Sun Microsystems - Beijing China 946c7ee0b5cSfei feng - Sun Microsystems - Beijing China attach_fail15: 947c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) ddi_intr_disable(sc->sc_intr_htable[0]); 948c7ee0b5cSfei feng - Sun Microsystems - Beijing China 949c7ee0b5cSfei feng - Sun Microsystems - Beijing China attach_fail14: 950c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) ddi_intr_remove_handler(sc->sc_intr_htable[0]); 951c7ee0b5cSfei feng - Sun Microsystems - Beijing China 952c7ee0b5cSfei feng - Sun Microsystems - Beijing China attach_fail13: 953c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) ddi_intr_remove_softint(sc->sc_soft_hdl); 954c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_soft_hdl = NULL; 955c7ee0b5cSfei feng - Sun Microsystems - Beijing China 956c7ee0b5cSfei feng - Sun Microsystems - Beijing China attach_fail12: 957c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_detach(ic); 958c7ee0b5cSfei feng - Sun Microsystems - Beijing China 959c7ee0b5cSfei feng - Sun Microsystems - Beijing China attach_fail11: 960c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_fw_dma(sc); 961c7ee0b5cSfei feng - Sun Microsystems - Beijing China 962c7ee0b5cSfei feng - Sun Microsystems - Beijing China attach_fail10: 963c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_ring_free(sc); 964c7ee0b5cSfei feng - Sun Microsystems - Beijing China 965c7ee0b5cSfei feng - Sun Microsystems - Beijing China attach_fail9: 966c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_kw(sc); 967c7ee0b5cSfei feng - Sun Microsystems - Beijing China 968c7ee0b5cSfei feng - Sun Microsystems - Beijing China attach_fail8: 969c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_shared(sc); 970c7ee0b5cSfei feng - Sun Microsystems - Beijing China 971c7ee0b5cSfei feng - Sun Microsystems - Beijing China attach_fail7: 972c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_destroy_locks(sc); 973c7ee0b5cSfei feng - Sun Microsystems - Beijing China 974c7ee0b5cSfei feng - Sun Microsystems - Beijing China attach_fail6: 975c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) ddi_intr_free(sc->sc_intr_htable[0]); 976c7ee0b5cSfei feng - Sun Microsystems - Beijing China 977c7ee0b5cSfei feng - Sun Microsystems - Beijing China attach_fail5: 978c7ee0b5cSfei feng - Sun Microsystems - Beijing China kmem_free(sc->sc_intr_htable, sizeof (ddi_intr_handle_t)); 979c7ee0b5cSfei feng - Sun Microsystems - Beijing China 980c7ee0b5cSfei feng - Sun Microsystems - Beijing China attach_fail4: 981c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_regs_map_free(&sc->sc_handle); 982c7ee0b5cSfei feng - Sun Microsystems - Beijing China 983c7ee0b5cSfei feng - Sun Microsystems - Beijing China attach_fail3: 984c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_regs_map_free(&sc->sc_cfg_handle); 985c7ee0b5cSfei feng - Sun Microsystems - Beijing China 986c7ee0b5cSfei feng - Sun Microsystems - Beijing China attach_fail2: 987c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_soft_state_free(iwh_soft_state_p, instance); 988c7ee0b5cSfei feng - Sun Microsystems - Beijing China 989c7ee0b5cSfei feng - Sun Microsystems - Beijing China attach_fail1: 990e2cf88acSQuaker Fang return (DDI_FAILURE); 991c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 992c7ee0b5cSfei feng - Sun Microsystems - Beijing China 993c7ee0b5cSfei feng - Sun Microsystems - Beijing China int 994c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 995c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 996c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_sc_t *sc; 997e2cf88acSQuaker Fang ieee80211com_t *ic; 998c7ee0b5cSfei feng - Sun Microsystems - Beijing China int err; 999c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1000c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(iwh_soft_state_p, ddi_get_instance(dip)); 1001c7ee0b5cSfei feng - Sun Microsystems - Beijing China ASSERT(sc != NULL); 1002e2cf88acSQuaker Fang ic = &sc->sc_ic; 1003c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1004c7ee0b5cSfei feng - Sun Microsystems - Beijing China switch (cmd) { 1005c7ee0b5cSfei feng - Sun Microsystems - Beijing China case DDI_DETACH: 1006c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 1007e2cf88acSQuaker Fang 1008c7ee0b5cSfei feng - Sun Microsystems - Beijing China case DDI_SUSPEND: 100989b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_HW_ERR_RECOVER); 101089b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_RATE_AUTO_CTL); 101189b2a9fbSfei feng - Sun Microsystems - Beijing China 101289b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_or_32(&sc->sc_flags, IWH_F_SUSPEND); 101389b2a9fbSfei feng - Sun Microsystems - Beijing China 1014d40f4da4Spengcheng chen - Sun Microsystems - Beijing China if (sc->sc_flags & IWH_F_RUNNING) { 1015e2cf88acSQuaker Fang ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 1016c25d4638SQuaker Fang iwh_stop(sc); 1017e2cf88acSQuaker Fang } 1018e2cf88acSQuaker Fang 1019e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_RESUME, "iwh_detach(): " 1020e2cf88acSQuaker Fang "suspend\n")); 1021c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS); 1022e2cf88acSQuaker Fang 1023c7ee0b5cSfei feng - Sun Microsystems - Beijing China default: 1024c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 1025c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1026c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1027c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (!(sc->sc_flags & IWH_F_ATTACHED)) { 1028c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 1029c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1030c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1031c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1032c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Destroy the mf_thread 1033c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1034c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_mf_thread_switch = 0; 1035e2cf88acSQuaker Fang 1036e2cf88acSQuaker Fang mutex_enter(&sc->sc_mt_lock); 1037c7ee0b5cSfei feng - Sun Microsystems - Beijing China while (sc->sc_mf_thread != NULL) { 1038c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (cv_wait_sig(&sc->sc_mt_cv, &sc->sc_mt_lock) == 0) { 1039c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 1040c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1041c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1042c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_mt_lock); 1043c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1044e2cf88acSQuaker Fang err = mac_disable(sc->sc_ic.ic_mach); 1045e2cf88acSQuaker Fang if (err != DDI_SUCCESS) { 1046e2cf88acSQuaker Fang return (err); 1047e2cf88acSQuaker Fang } 1048e2cf88acSQuaker Fang 1049c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1050c7ee0b5cSfei feng - Sun Microsystems - Beijing China * stop chipset 1051c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1052c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_stop(sc); 1053c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1054c7ee0b5cSfei feng - Sun Microsystems - Beijing China DELAY(500000); 1055c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1056c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1057c7ee0b5cSfei feng - Sun Microsystems - Beijing China * release buffer for calibration 1058c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1059c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_release_calib_buffer(sc); 1060c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1061c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1062c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Unregiste from GLD 1063c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1064c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) mac_unregister(sc->sc_ic.ic_mach); 1065c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1066c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_glock); 1067c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_fw_dma(sc); 1068c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_ring_free(sc); 1069c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_kw(sc); 1070c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_shared(sc); 1071c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 1072c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1073c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) ddi_intr_disable(sc->sc_intr_htable[0]); 1074c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) ddi_intr_remove_handler(sc->sc_intr_htable[0]); 1075c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) ddi_intr_free(sc->sc_intr_htable[0]); 1076c7ee0b5cSfei feng - Sun Microsystems - Beijing China kmem_free(sc->sc_intr_htable, sizeof (ddi_intr_handle_t)); 1077c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1078c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) ddi_intr_remove_softint(sc->sc_soft_hdl); 1079c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_soft_hdl = NULL; 1080c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1081c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1082c7ee0b5cSfei feng - Sun Microsystems - Beijing China * detach from 80211 module 1083c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1084c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_detach(&sc->sc_ic); 1085c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1086c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_destroy_locks(sc); 1087c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1088c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_regs_map_free(&sc->sc_handle); 1089c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_regs_map_free(&sc->sc_cfg_handle); 1090c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_remove_minor_node(dip, NULL); 1091c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_soft_state_free(iwh_soft_state_p, ddi_get_instance(dip)); 1092c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1093c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS); 1094c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1095c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1096c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1097c7ee0b5cSfei feng - Sun Microsystems - Beijing China * destroy all locks 1098c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1099c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 1100c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_destroy_locks(iwh_sc_t *sc) 1101c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1102c7ee0b5cSfei feng - Sun Microsystems - Beijing China cv_destroy(&sc->sc_mt_cv); 1103c7ee0b5cSfei feng - Sun Microsystems - Beijing China cv_destroy(&sc->sc_cmd_cv); 1104c7ee0b5cSfei feng - Sun Microsystems - Beijing China cv_destroy(&sc->sc_put_seg_cv); 1105c7ee0b5cSfei feng - Sun Microsystems - Beijing China cv_destroy(&sc->sc_ucode_cv); 1106c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_mt_lock); 1107c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_tx_lock); 1108c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_destroy(&sc->sc_glock); 1109c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1110c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1111c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1112c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Allocate an area of memory and a DMA handle for accessing it 1113c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1114c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 1115c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_alloc_dma_mem(iwh_sc_t *sc, size_t memsize, 1116c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_dma_attr_t *dma_attr_p, ddi_device_acc_attr_t *acc_attr_p, 1117c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint_t dma_flags, iwh_dma_t *dma_p) 1118c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1119c7ee0b5cSfei feng - Sun Microsystems - Beijing China caddr_t vaddr; 1120e2cf88acSQuaker Fang int err = DDI_FAILURE; 1121c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1122c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1123c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Allocate handle 1124c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1125c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = ddi_dma_alloc_handle(sc->sc_dip, dma_attr_p, 1126c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl); 1127c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1128c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->dma_hdl = NULL; 1129c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 1130c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1131c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1132c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1133c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Allocate memory 1134c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1135c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, acc_attr_p, 1136c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_flags & (DDI_DMA_CONSISTENT | DDI_DMA_STREAMING), 1137c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DMA_SLEEP, NULL, &vaddr, &dma_p->alength, &dma_p->acc_hdl); 1138c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1139c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_dma_free_handle(&dma_p->dma_hdl); 1140c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->dma_hdl = NULL; 1141c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->acc_hdl = NULL; 1142c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 1143c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1144c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1145c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1146c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Bind the two together 1147c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1148c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->mem_va = vaddr; 1149c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL, 1150c7ee0b5cSfei feng - Sun Microsystems - Beijing China vaddr, dma_p->alength, dma_flags, DDI_DMA_SLEEP, NULL, 1151c7ee0b5cSfei feng - Sun Microsystems - Beijing China &dma_p->cookie, &dma_p->ncookies); 1152c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_DMA_MAPPED) { 1153c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_dma_mem_free(&dma_p->acc_hdl); 1154c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_dma_free_handle(&dma_p->dma_hdl); 1155c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->acc_hdl = NULL; 1156c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->dma_hdl = NULL; 1157c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 1158c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1159c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1160c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->nslots = ~0U; 1161c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->size = ~0U; 1162c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->token = ~0U; 1163c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->offset = 0; 1164c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS); 1165c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1166c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1167c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1168c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Free one allocated area of DMAable memory 1169c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1170c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 1171c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_dma_mem(iwh_dma_t *dma_p) 1172c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1173c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (dma_p->dma_hdl != NULL) { 1174c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (dma_p->ncookies) { 1175c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) ddi_dma_unbind_handle(dma_p->dma_hdl); 1176c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->ncookies = 0; 1177c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1178c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_dma_free_handle(&dma_p->dma_hdl); 1179c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->dma_hdl = NULL; 1180c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1181c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1182c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (dma_p->acc_hdl != NULL) { 1183c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_dma_mem_free(&dma_p->acc_hdl); 1184c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->acc_hdl = NULL; 1185c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1186c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1187c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1188c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1189c7ee0b5cSfei feng - Sun Microsystems - Beijing China * copy ucode into dma buffers 1190c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1191c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 1192c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_alloc_fw_dma(iwh_sc_t *sc) 1193c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1194e2cf88acSQuaker Fang int err = DDI_FAILURE; 1195c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_dma_t *dma_p; 1196c7ee0b5cSfei feng - Sun Microsystems - Beijing China char *t; 1197c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1198c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1199c7ee0b5cSfei feng - Sun Microsystems - Beijing China * firmware image layout: 1200c7ee0b5cSfei feng - Sun Microsystems - Beijing China * |HDR|<-TEXT->|<-DATA->|<-INIT_TEXT->|<-INIT_DATA->|<-BOOT->| 1201c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1202c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1203c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1204c7ee0b5cSfei feng - Sun Microsystems - Beijing China * copy text of runtime ucode 1205c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1206c7ee0b5cSfei feng - Sun Microsystems - Beijing China t = (char *)(sc->sc_hdr + 1); 1207c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_dma_mem(sc, LE_32(sc->sc_hdr->textsz), 1208c7ee0b5cSfei feng - Sun Microsystems - Beijing China &fw_dma_attr, &iwh_dma_accattr, 1209c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1210c7ee0b5cSfei feng - Sun Microsystems - Beijing China &sc->sc_dma_fw_text); 1211c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1212c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_alloc_fw_dma(): " 1213c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to allocate text dma memory.\n"); 1214c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 1215c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1216c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1217e2cf88acSQuaker Fang dma_p = &sc->sc_dma_fw_text; 1218e2cf88acSQuaker Fang 1219e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_fw_dma(): " 1220e2cf88acSQuaker Fang "text[ncookies:%d addr:%lx size:%lx]\n", 1221e2cf88acSQuaker Fang dma_p->ncookies, dma_p->cookie.dmac_address, 1222e2cf88acSQuaker Fang dma_p->cookie.dmac_size)); 1223e2cf88acSQuaker Fang 122489b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(t, dma_p->mem_va, LE_32(sc->sc_hdr->textsz)); 1225c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1226c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1227c7ee0b5cSfei feng - Sun Microsystems - Beijing China * copy data and bak-data of runtime ucode 1228c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1229c7ee0b5cSfei feng - Sun Microsystems - Beijing China t += LE_32(sc->sc_hdr->textsz); 1230c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_dma_mem(sc, LE_32(sc->sc_hdr->datasz), 1231c7ee0b5cSfei feng - Sun Microsystems - Beijing China &fw_dma_attr, &iwh_dma_accattr, 1232c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1233c7ee0b5cSfei feng - Sun Microsystems - Beijing China &sc->sc_dma_fw_data); 1234c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1235c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_alloc_fw_dma(): " 1236c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to allocate data dma memory\n"); 1237c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 1238c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1239c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1240e2cf88acSQuaker Fang dma_p = &sc->sc_dma_fw_data; 1241e2cf88acSQuaker Fang 1242e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_fw_dma(): " 1243e2cf88acSQuaker Fang "data[ncookies:%d addr:%lx size:%lx]\n", 1244e2cf88acSQuaker Fang dma_p->ncookies, dma_p->cookie.dmac_address, 1245e2cf88acSQuaker Fang dma_p->cookie.dmac_size)); 1246e2cf88acSQuaker Fang 124789b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(t, dma_p->mem_va, LE_32(sc->sc_hdr->datasz)); 1248c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1249c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_dma_mem(sc, LE_32(sc->sc_hdr->datasz), 1250c7ee0b5cSfei feng - Sun Microsystems - Beijing China &fw_dma_attr, &iwh_dma_accattr, 1251c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1252c7ee0b5cSfei feng - Sun Microsystems - Beijing China &sc->sc_dma_fw_data_bak); 1253c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1254c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_alloc_fw_dma(): " 1255c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to allocate data bakup dma memory\n"); 1256c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 1257c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1258c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1259e2cf88acSQuaker Fang dma_p = &sc->sc_dma_fw_data_bak; 1260e2cf88acSQuaker Fang 1261e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_fw_dma(): " 1262e2cf88acSQuaker Fang "data_bak[ncookies:%d addr:%lx " 1263e2cf88acSQuaker Fang "size:%lx]\n", 1264e2cf88acSQuaker Fang dma_p->ncookies, dma_p->cookie.dmac_address, 1265e2cf88acSQuaker Fang dma_p->cookie.dmac_size)); 1266e2cf88acSQuaker Fang 126789b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(t, dma_p->mem_va, LE_32(sc->sc_hdr->datasz)); 1268c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1269c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1270c7ee0b5cSfei feng - Sun Microsystems - Beijing China * copy text of init ucode 1271c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1272c7ee0b5cSfei feng - Sun Microsystems - Beijing China t += LE_32(sc->sc_hdr->datasz); 1273c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_dma_mem(sc, LE_32(sc->sc_hdr->init_textsz), 1274c7ee0b5cSfei feng - Sun Microsystems - Beijing China &fw_dma_attr, &iwh_dma_accattr, 1275c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1276c7ee0b5cSfei feng - Sun Microsystems - Beijing China &sc->sc_dma_fw_init_text); 1277c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1278c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_alloc_fw_dma(): " 1279c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to allocate init text dma memory\n"); 1280c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 1281c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1282c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1283e2cf88acSQuaker Fang dma_p = &sc->sc_dma_fw_init_text; 1284e2cf88acSQuaker Fang 1285e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_fw_dma(): " 1286e2cf88acSQuaker Fang "init_text[ncookies:%d addr:%lx " 1287e2cf88acSQuaker Fang "size:%lx]\n", 1288e2cf88acSQuaker Fang dma_p->ncookies, dma_p->cookie.dmac_address, 1289e2cf88acSQuaker Fang dma_p->cookie.dmac_size)); 1290e2cf88acSQuaker Fang 129189b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(t, dma_p->mem_va, LE_32(sc->sc_hdr->init_textsz)); 1292c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1293c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1294c7ee0b5cSfei feng - Sun Microsystems - Beijing China * copy data of init ucode 1295c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1296c7ee0b5cSfei feng - Sun Microsystems - Beijing China t += LE_32(sc->sc_hdr->init_textsz); 1297c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_dma_mem(sc, LE_32(sc->sc_hdr->init_datasz), 1298c7ee0b5cSfei feng - Sun Microsystems - Beijing China &fw_dma_attr, &iwh_dma_accattr, 1299c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1300c7ee0b5cSfei feng - Sun Microsystems - Beijing China &sc->sc_dma_fw_init_data); 1301c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1302c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_alloc_fw_dma(): " 1303c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to allocate init data dma memory\n"); 1304c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 1305c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1306c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1307e2cf88acSQuaker Fang dma_p = &sc->sc_dma_fw_init_data; 1308e2cf88acSQuaker Fang 1309e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_fw_dma(): " 1310e2cf88acSQuaker Fang "init_data[ncookies:%d addr:%lx " 1311e2cf88acSQuaker Fang "size:%lx]\n", 1312e2cf88acSQuaker Fang dma_p->ncookies, dma_p->cookie.dmac_address, 1313e2cf88acSQuaker Fang dma_p->cookie.dmac_size)); 1314e2cf88acSQuaker Fang 131589b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(t, dma_p->mem_va, LE_32(sc->sc_hdr->init_datasz)); 1316c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1317c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_boot = t + LE_32(sc->sc_hdr->init_datasz); 131889b2a9fbSfei feng - Sun Microsystems - Beijing China 1319c7ee0b5cSfei feng - Sun Microsystems - Beijing China fail: 1320c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 1321c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1322c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1323c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 1324c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_fw_dma(iwh_sc_t *sc) 1325c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1326c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_dma_mem(&sc->sc_dma_fw_text); 1327c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_dma_mem(&sc->sc_dma_fw_data); 1328c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_dma_mem(&sc->sc_dma_fw_data_bak); 1329c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_dma_mem(&sc->sc_dma_fw_init_text); 1330c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_dma_mem(&sc->sc_dma_fw_init_data); 1331c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1332c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1333c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1334c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Allocate a shared buffer between host and NIC. 1335c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1336c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 1337c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_alloc_shared(iwh_sc_t *sc) 1338c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1339c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 1340c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_dma_t *dma_p; 1341c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 1342e2cf88acSQuaker Fang int err = DDI_FAILURE; 1343c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1344c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1345c7ee0b5cSfei feng - Sun Microsystems - Beijing China * must be aligned on a 4K-page boundary 1346c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1347c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_dma_mem(sc, sizeof (iwh_shared_t), 1348b510adaeSfei feng - Sun Microsystems - Beijing China &sh_dma_attr, &iwh_dma_descattr, 1349c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1350c7ee0b5cSfei feng - Sun Microsystems - Beijing China &sc->sc_dma_sh); 1351c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1352c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 1353c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1354c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1355c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_shared = (iwh_shared_t *)sc->sc_dma_sh.mem_va; 1356c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1357c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 1358c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p = &sc->sc_dma_sh; 1359c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 1360e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_shared(): " 1361e2cf88acSQuaker Fang "sh[ncookies:%d addr:%lx size:%lx]\n", 1362c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->ncookies, dma_p->cookie.dmac_address, 1363c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->cookie.dmac_size)); 1364c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1365c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 136689b2a9fbSfei feng - Sun Microsystems - Beijing China 1367c7ee0b5cSfei feng - Sun Microsystems - Beijing China fail: 1368c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_shared(sc); 1369c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 1370c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1371c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1372c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 1373c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_shared(iwh_sc_t *sc) 1374c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1375c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_dma_mem(&sc->sc_dma_sh); 1376c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1377c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1378c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1379c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Allocate a keep warm page. 1380c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1381c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 1382c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_alloc_kw(iwh_sc_t *sc) 1383c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1384c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 1385c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_dma_t *dma_p; 1386c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 1387e2cf88acSQuaker Fang int err = DDI_FAILURE; 1388c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1389c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1390c7ee0b5cSfei feng - Sun Microsystems - Beijing China * must be aligned on a 4K-page boundary 1391c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1392c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_dma_mem(sc, IWH_KW_SIZE, 1393b510adaeSfei feng - Sun Microsystems - Beijing China &kw_dma_attr, &iwh_dma_descattr, 1394c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1395c7ee0b5cSfei feng - Sun Microsystems - Beijing China &sc->sc_dma_kw); 1396c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1397c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 1398c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1399c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1400c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 1401c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p = &sc->sc_dma_kw; 1402c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 1403e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_kw(): " 1404e2cf88acSQuaker Fang "kw[ncookies:%d addr:%lx size:%lx]\n", 1405c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->ncookies, dma_p->cookie.dmac_address, 1406c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->cookie.dmac_size)); 1407c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1408c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 140989b2a9fbSfei feng - Sun Microsystems - Beijing China 1410c7ee0b5cSfei feng - Sun Microsystems - Beijing China fail: 1411c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_kw(sc); 1412c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 1413c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1414c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1415c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 1416c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_kw(iwh_sc_t *sc) 1417c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1418c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_dma_mem(&sc->sc_dma_kw); 1419c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1420c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1421c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1422c7ee0b5cSfei feng - Sun Microsystems - Beijing China * initialize RX ring buffers 1423c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1424c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 1425c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_alloc_rx_ring(iwh_sc_t *sc) 1426c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1427c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_rx_ring_t *ring; 1428c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_rx_data_t *data; 1429c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 1430c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_dma_t *dma_p; 1431c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 1432e2cf88acSQuaker Fang int i, err = DDI_FAILURE; 1433c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1434c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring = &sc->sc_rxq; 1435c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring->cur = 0; 1436c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1437c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1438c7ee0b5cSfei feng - Sun Microsystems - Beijing China * allocate RX description ring buffer 1439c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1440c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_dma_mem(sc, RX_QUEUE_SIZE * sizeof (uint32_t), 1441b510adaeSfei feng - Sun Microsystems - Beijing China &ring_desc_dma_attr, &iwh_dma_descattr, 1442c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1443c7ee0b5cSfei feng - Sun Microsystems - Beijing China &ring->dma_desc); 1444c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1445e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_rx_ring(): " 1446e2cf88acSQuaker Fang "dma alloc rx ring desc " 1447c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed\n")); 1448c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 1449c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1450c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1451c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring->desc = (uint32_t *)ring->dma_desc.mem_va; 1452c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 1453c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p = &ring->dma_desc; 1454c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 1455e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_rx_ring(): " 1456e2cf88acSQuaker Fang "rx bd[ncookies:%d addr:%lx size:%lx]\n", 1457c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->ncookies, dma_p->cookie.dmac_address, 1458c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->cookie.dmac_size)); 1459c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1460c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1461c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Allocate Rx frame buffers. 1462c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1463c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (i = 0; i < RX_QUEUE_SIZE; i++) { 1464c7ee0b5cSfei feng - Sun Microsystems - Beijing China data = &ring->data[i]; 1465c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_dma_mem(sc, sc->sc_dmabuf_sz, 1466c7ee0b5cSfei feng - Sun Microsystems - Beijing China &rx_buffer_dma_attr, &iwh_dma_accattr, 1467c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DMA_READ | DDI_DMA_STREAMING, 1468c7ee0b5cSfei feng - Sun Microsystems - Beijing China &data->dma_data); 1469c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1470e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_rx_ring(): " 1471e2cf88acSQuaker Fang "dma alloc rx ring " 1472c7ee0b5cSfei feng - Sun Microsystems - Beijing China "buf[%d] failed\n", i)); 1473c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 1474c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1475c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1476c7ee0b5cSfei feng - Sun Microsystems - Beijing China * the physical address bit [8-36] are used, 1477c7ee0b5cSfei feng - Sun Microsystems - Beijing China * instead of bit [0-31] in 3945. 1478c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1479b510adaeSfei feng - Sun Microsystems - Beijing China ring->desc[i] = (uint32_t) 1480b510adaeSfei feng - Sun Microsystems - Beijing China (data->dma_data.cookie.dmac_address >> 8); 1481c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1482c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1483c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 1484c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p = &ring->data[0].dma_data; 1485c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 1486e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_rx_ring(): " 1487e2cf88acSQuaker Fang "rx buffer[0][ncookies:%d addr:%lx " 1488c7ee0b5cSfei feng - Sun Microsystems - Beijing China "size:%lx]\n", 1489c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->ncookies, dma_p->cookie.dmac_address, 1490c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->cookie.dmac_size)); 1491c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1492c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV); 1493c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1494c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 1495c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1496c7ee0b5cSfei feng - Sun Microsystems - Beijing China fail: 1497c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_rx_ring(sc); 1498c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 1499c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1500c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1501c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1502c7ee0b5cSfei feng - Sun Microsystems - Beijing China * disable RX ring 1503c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1504c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 1505c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reset_rx_ring(iwh_sc_t *sc) 1506c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1507c7ee0b5cSfei feng - Sun Microsystems - Beijing China int n; 1508c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1509c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_enter(sc); 1510c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); 1511c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (n = 0; n < 2000; n++) { 1512c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (IWH_READ(sc, FH_MEM_RSSR_RX_STATUS_REG) & (1 << 24)) { 1513c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 1514c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1515c7ee0b5cSfei feng - Sun Microsystems - Beijing China DELAY(1000); 1516c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1517c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 1518c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (2000 == n) { 1519e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_reset_rx_ring(): " 1520e2cf88acSQuaker Fang "timeout resetting Rx ring\n")); 1521c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1522c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 1523c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_exit(sc); 1524c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1525c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_rxq.cur = 0; 1526c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1527c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1528c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 1529c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_rx_ring(iwh_sc_t *sc) 1530c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1531c7ee0b5cSfei feng - Sun Microsystems - Beijing China int i; 1532c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1533c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (i = 0; i < RX_QUEUE_SIZE; i++) { 1534c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (sc->sc_rxq.data[i].dma_data.dma_hdl) { 1535c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_DMA_SYNC(sc->sc_rxq.data[i].dma_data, 1536c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORCPU); 1537c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1538c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1539c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_dma_mem(&sc->sc_rxq.data[i].dma_data); 1540c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1541c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1542c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (sc->sc_rxq.dma_desc.dma_hdl) { 1543c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_DMA_SYNC(sc->sc_rxq.dma_desc, DDI_DMA_SYNC_FORDEV); 1544c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1545c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1546c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_dma_mem(&sc->sc_rxq.dma_desc); 1547c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1548c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1549c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1550c7ee0b5cSfei feng - Sun Microsystems - Beijing China * initialize TX ring buffers 1551c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1552c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 1553c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_alloc_tx_ring(iwh_sc_t *sc, iwh_tx_ring_t *ring, 1554c7ee0b5cSfei feng - Sun Microsystems - Beijing China int slots, int qid) 1555c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1556c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_data_t *data; 1557c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_desc_t *desc_h; 1558c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t paddr_desc_h; 1559c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_cmd_t *cmd_h; 1560c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t paddr_cmd_h; 1561c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 1562c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_dma_t *dma_p; 1563c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 1564e2cf88acSQuaker Fang int i, err = DDI_FAILURE; 156589b2a9fbSfei feng - Sun Microsystems - Beijing China 1566c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring->qid = qid; 1567c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring->count = TFD_QUEUE_SIZE_MAX; 1568c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring->window = slots; 1569c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring->queued = 0; 1570c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring->cur = 0; 157189b2a9fbSfei feng - Sun Microsystems - Beijing China ring->desc_cur = 0; 1572c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1573c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1574c7ee0b5cSfei feng - Sun Microsystems - Beijing China * allocate buffer for TX descriptor ring 1575c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1576c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_dma_mem(sc, 1577c7ee0b5cSfei feng - Sun Microsystems - Beijing China TFD_QUEUE_SIZE_MAX * sizeof (iwh_tx_desc_t), 1578b510adaeSfei feng - Sun Microsystems - Beijing China &ring_desc_dma_attr, &iwh_dma_descattr, 1579c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1580c7ee0b5cSfei feng - Sun Microsystems - Beijing China &ring->dma_desc); 1581c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1582e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_tx_ring(): " 1583e2cf88acSQuaker Fang "dma alloc tx ring desc[%d] " 1584c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed\n", qid)); 1585c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 1586c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1587c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1588c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 1589c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p = &ring->dma_desc; 1590c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 1591e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_tx_ring(): " 1592e2cf88acSQuaker Fang "tx bd[ncookies:%d addr:%lx size:%lx]\n", 1593c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->ncookies, dma_p->cookie.dmac_address, 1594c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->cookie.dmac_size)); 1595c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1596c7ee0b5cSfei feng - Sun Microsystems - Beijing China desc_h = (iwh_tx_desc_t *)ring->dma_desc.mem_va; 1597c7ee0b5cSfei feng - Sun Microsystems - Beijing China paddr_desc_h = ring->dma_desc.cookie.dmac_address; 1598c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1599c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1600c7ee0b5cSfei feng - Sun Microsystems - Beijing China * allocate buffer for ucode command 1601c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1602c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_dma_mem(sc, 1603c7ee0b5cSfei feng - Sun Microsystems - Beijing China TFD_QUEUE_SIZE_MAX * sizeof (iwh_cmd_t), 1604c7ee0b5cSfei feng - Sun Microsystems - Beijing China &cmd_dma_attr, &iwh_dma_accattr, 1605c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1606c7ee0b5cSfei feng - Sun Microsystems - Beijing China &ring->dma_cmd); 1607c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1608e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_tx_ring(): " 1609e2cf88acSQuaker Fang "dma alloc tx ring cmd[%d]" 1610c7ee0b5cSfei feng - Sun Microsystems - Beijing China " failed\n", qid)); 1611c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 1612c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1613c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1614c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 1615c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p = &ring->dma_cmd; 1616c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 1617e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_tx_ring(): " 1618e2cf88acSQuaker Fang "tx cmd[ncookies:%d addr:%lx size:%lx]\n", 1619c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->ncookies, dma_p->cookie.dmac_address, 1620c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->cookie.dmac_size)); 1621c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1622c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd_h = (iwh_cmd_t *)ring->dma_cmd.mem_va; 1623c7ee0b5cSfei feng - Sun Microsystems - Beijing China paddr_cmd_h = ring->dma_cmd.cookie.dmac_address; 1624c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1625c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1626c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Allocate Tx frame buffers. 1627c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1628c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring->data = kmem_zalloc(sizeof (iwh_tx_data_t) * TFD_QUEUE_SIZE_MAX, 1629c7ee0b5cSfei feng - Sun Microsystems - Beijing China KM_NOSLEEP); 1630c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (NULL == ring->data) { 1631e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_tx_ring(): " 1632e2cf88acSQuaker Fang "could not allocate " 1633c7ee0b5cSfei feng - Sun Microsystems - Beijing China "tx data slots\n")); 1634c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 1635c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1636c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1637c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (i = 0; i < TFD_QUEUE_SIZE_MAX; i++) { 1638c7ee0b5cSfei feng - Sun Microsystems - Beijing China data = &ring->data[i]; 1639c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_dma_mem(sc, sc->sc_dmabuf_sz, 1640c7ee0b5cSfei feng - Sun Microsystems - Beijing China &tx_buffer_dma_attr, &iwh_dma_accattr, 1641c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DMA_WRITE | DDI_DMA_STREAMING, 1642c7ee0b5cSfei feng - Sun Microsystems - Beijing China &data->dma_data); 1643c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1644e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_tx_ring(): " 1645e2cf88acSQuaker Fang "dma alloc tx " 1646c7ee0b5cSfei feng - Sun Microsystems - Beijing China "ring buf[%d] failed\n", i)); 1647c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 1648c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1649c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1650c7ee0b5cSfei feng - Sun Microsystems - Beijing China data->desc = desc_h + i; 1651c7ee0b5cSfei feng - Sun Microsystems - Beijing China data->paddr_desc = paddr_desc_h + 1652c7ee0b5cSfei feng - Sun Microsystems - Beijing China _PTRDIFF(data->desc, desc_h); 1653e2cf88acSQuaker Fang data->cmd = cmd_h + i; 1654c7ee0b5cSfei feng - Sun Microsystems - Beijing China data->paddr_cmd = paddr_cmd_h + 1655c7ee0b5cSfei feng - Sun Microsystems - Beijing China _PTRDIFF(data->cmd, cmd_h); 1656c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1657c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 1658c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p = &ring->data[0].dma_data; 1659c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 1660e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_alloc_tx_ring(): " 1661e2cf88acSQuaker Fang "tx buffer[0][ncookies:%d addr:%lx " 1662c7ee0b5cSfei feng - Sun Microsystems - Beijing China "size:%lx]\n", 1663c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->ncookies, dma_p->cookie.dmac_address, 1664c7ee0b5cSfei feng - Sun Microsystems - Beijing China dma_p->cookie.dmac_size)); 1665c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1666c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 1667c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1668c7ee0b5cSfei feng - Sun Microsystems - Beijing China fail: 1669c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_tx_ring(ring); 1670c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1671c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 1672c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1673c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1674c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1675c7ee0b5cSfei feng - Sun Microsystems - Beijing China * disable TX ring 1676c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1677c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 1678c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reset_tx_ring(iwh_sc_t *sc, iwh_tx_ring_t *ring) 1679c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1680c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_data_t *data; 1681c7ee0b5cSfei feng - Sun Microsystems - Beijing China int i, n; 1682c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1683c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_enter(sc); 1684c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1685c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, IWH_FH_TCSR_CHNL_TX_CONFIG_REG(ring->qid), 0); 1686c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (n = 0; n < 200; n++) { 1687c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (IWH_READ(sc, IWH_FH_TSSR_TX_STATUS_REG) & 1688c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ring->qid)) { 1689c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 1690c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1691c7ee0b5cSfei feng - Sun Microsystems - Beijing China DELAY(10); 1692c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1693e2cf88acSQuaker Fang 1694e2cf88acSQuaker Fang #ifdef DEBUG 1695d5bd65e4Sfei feng - Sun Microsystems - Beijing China if (200 == n) { 1696e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_DMA, "iwh_reset_tx_ring(): " 1697e2cf88acSQuaker Fang "timeout reset tx ring %d\n", 1698c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring->qid)); 1699c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1700e2cf88acSQuaker Fang #endif 1701e2cf88acSQuaker Fang 1702c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_exit(sc); 1703c7ee0b5cSfei feng - Sun Microsystems - Beijing China 170489b2a9fbSfei feng - Sun Microsystems - Beijing China /* 170589b2a9fbSfei feng - Sun Microsystems - Beijing China * by pass, if it's quiesce 170689b2a9fbSfei feng - Sun Microsystems - Beijing China */ 1707faceed93Sfei feng - Sun Microsystems - Beijing China if (!(sc->sc_flags & IWH_F_QUIESCED)) { 1708c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (i = 0; i < ring->count; i++) { 1709c7ee0b5cSfei feng - Sun Microsystems - Beijing China data = &ring->data[i]; 1710c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_DMA_SYNC(data->dma_data, DDI_DMA_SYNC_FORDEV); 1711c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1712faceed93Sfei feng - Sun Microsystems - Beijing China } 1713c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1714c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring->queued = 0; 1715c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring->cur = 0; 171689b2a9fbSfei feng - Sun Microsystems - Beijing China ring->desc_cur = 0; 1717c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1718c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1719c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 1720c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_tx_ring(iwh_tx_ring_t *ring) 1721c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1722c7ee0b5cSfei feng - Sun Microsystems - Beijing China int i; 1723c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1724c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ring->dma_desc.dma_hdl != NULL) { 1725c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV); 1726c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1727c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_dma_mem(&ring->dma_desc); 1728c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1729c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ring->dma_cmd.dma_hdl != NULL) { 1730c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_DMA_SYNC(ring->dma_cmd, DDI_DMA_SYNC_FORDEV); 1731c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1732c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_dma_mem(&ring->dma_cmd); 1733c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1734c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ring->data != NULL) { 1735c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (i = 0; i < ring->count; i++) { 1736c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ring->data[i].dma_data.dma_hdl) { 1737c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_DMA_SYNC(ring->data[i].dma_data, 1738c7ee0b5cSfei feng - Sun Microsystems - Beijing China DDI_DMA_SYNC_FORDEV); 1739c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1740c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_dma_mem(&ring->data[i].dma_data); 1741c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1742c7ee0b5cSfei feng - Sun Microsystems - Beijing China kmem_free(ring->data, ring->count * sizeof (iwh_tx_data_t)); 1743c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1744c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1745c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1746c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1747c7ee0b5cSfei feng - Sun Microsystems - Beijing China * initialize TX and RX ring 1748c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1749c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 1750c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_ring_init(iwh_sc_t *sc) 1751c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1752e2cf88acSQuaker Fang int i, err = DDI_FAILURE; 1753c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1754c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (i = 0; i < IWH_NUM_QUEUES; i++) { 1755c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (IWH_CMD_QUEUE_NUM == i) { 1756c7ee0b5cSfei feng - Sun Microsystems - Beijing China continue; 1757c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1758c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1759c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_tx_ring(sc, &sc->sc_txq[i], TFD_TX_CMD_SLOTS, 1760c7ee0b5cSfei feng - Sun Microsystems - Beijing China i); 1761c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1762c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 1763c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1764c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1765c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1766c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1767c7ee0b5cSfei feng - Sun Microsystems - Beijing China * initialize command queue 1768c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1769c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_tx_ring(sc, &sc->sc_txq[IWH_CMD_QUEUE_NUM], 1770c7ee0b5cSfei feng - Sun Microsystems - Beijing China TFD_CMD_SLOTS, IWH_CMD_QUEUE_NUM); 1771c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1772c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 1773c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1774c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1775c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_alloc_rx_ring(sc); 1776c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != DDI_SUCCESS) { 1777c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 1778c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1779c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1780c7ee0b5cSfei feng - Sun Microsystems - Beijing China fail: 1781c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 1782c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1783c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1784c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 1785c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_ring_free(iwh_sc_t *sc) 1786c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1787c7ee0b5cSfei feng - Sun Microsystems - Beijing China int i = IWH_NUM_QUEUES; 1788c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1789c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_rx_ring(sc); 1790c7ee0b5cSfei feng - Sun Microsystems - Beijing China while (--i >= 0) { 1791c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_free_tx_ring(&sc->sc_txq[i]); 1792c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1793c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1794c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1795c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* ARGSUSED */ 1796c7ee0b5cSfei feng - Sun Microsystems - Beijing China static ieee80211_node_t * 1797c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_node_alloc(ieee80211com_t *ic) 1798c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1799c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_amrr_t *amrr; 1800c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1801c7ee0b5cSfei feng - Sun Microsystems - Beijing China amrr = kmem_zalloc(sizeof (iwh_amrr_t), KM_SLEEP); 1802e2cf88acSQuaker Fang if (NULL == amrr) { 1803e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_node_alloc(): " 1804e2cf88acSQuaker Fang "failed to allocate memory for amrr structure\n"); 1805e2cf88acSQuaker Fang return (NULL); 1806c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1807c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1808e2cf88acSQuaker Fang iwh_amrr_init(amrr); 1809e2cf88acSQuaker Fang 1810c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (&amrr->in); 1811c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1812c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1813c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 1814c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_node_free(ieee80211_node_t *in) 1815c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1816e2cf88acSQuaker Fang ieee80211com_t *ic; 1817c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1818e2cf88acSQuaker Fang if ((NULL == in) || 1819e2cf88acSQuaker Fang (NULL == in->in_ic)) { 1820e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_node_free() " 1821e2cf88acSQuaker Fang "Got a NULL point from Net80211 module\n"); 1822e2cf88acSQuaker Fang return; 1823e2cf88acSQuaker Fang } 1824e2cf88acSQuaker Fang ic = in->in_ic; 1825e2cf88acSQuaker Fang 1826e2cf88acSQuaker Fang if (ic->ic_node_cleanup != NULL) { 1827c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_node_cleanup(in); 1828e2cf88acSQuaker Fang } 1829e2cf88acSQuaker Fang 1830c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (in->in_wpa_ie != NULL) { 1831c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_free(in->in_wpa_ie); 1832c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1833c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1834e2cf88acSQuaker Fang if (in->in_wme_ie != NULL) { 1835e2cf88acSQuaker Fang ieee80211_free(in->in_wme_ie); 1836e2cf88acSQuaker Fang } 1837e2cf88acSQuaker Fang 1838e2cf88acSQuaker Fang if (in->in_htcap_ie != NULL) { 1839e2cf88acSQuaker Fang ieee80211_free(in->in_htcap_ie); 1840e2cf88acSQuaker Fang } 1841e2cf88acSQuaker Fang 1842c7ee0b5cSfei feng - Sun Microsystems - Beijing China kmem_free(in, sizeof (iwh_amrr_t)); 1843c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1844c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1845c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1846c7ee0b5cSfei feng - Sun Microsystems - Beijing China * change station's state. this function will be invoked by 80211 module 1847c7ee0b5cSfei feng - Sun Microsystems - Beijing China * when need to change staton's state. 1848c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1849c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 1850c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_newstate(ieee80211com_t *ic, enum ieee80211_state nstate, int arg) 1851c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 1852e2cf88acSQuaker Fang iwh_sc_t *sc; 1853e2cf88acSQuaker Fang ieee80211_node_t *in; 1854e2cf88acSQuaker Fang enum ieee80211_state ostate; 1855e2cf88acSQuaker Fang iwh_add_sta_t node; 1856e2cf88acSQuaker Fang iwh_amrr_t *amrr; 1857e2cf88acSQuaker Fang uint8_t r; 1858e2cf88acSQuaker Fang int i, err = IWH_FAIL; 1859e2cf88acSQuaker Fang 1860e2cf88acSQuaker Fang if (NULL == ic) { 1861e2cf88acSQuaker Fang return (err); 1862e2cf88acSQuaker Fang } 1863e2cf88acSQuaker Fang sc = (iwh_sc_t *)ic; 1864e2cf88acSQuaker Fang in = ic->ic_bss; 1865e2cf88acSQuaker Fang ostate = ic->ic_state; 1866c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1867c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_glock); 1868c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1869c7ee0b5cSfei feng - Sun Microsystems - Beijing China switch (nstate) { 1870c7ee0b5cSfei feng - Sun Microsystems - Beijing China case IEEE80211_S_SCAN: 1871d5bd65e4Sfei feng - Sun Microsystems - Beijing China switch (ostate) { 1872d5bd65e4Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_INIT: 187389b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_or_32(&sc->sc_flags, IWH_F_SCANNING); 1874c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_set_led(sc, 2, 10, 2); 1875c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1876d5bd65e4Sfei feng - Sun Microsystems - Beijing China /* 1877d5bd65e4Sfei feng - Sun Microsystems - Beijing China * clear association to receive beacons from 1878d5bd65e4Sfei feng - Sun Microsystems - Beijing China * all BSS'es 1879d5bd65e4Sfei feng - Sun Microsystems - Beijing China */ 1880d5bd65e4Sfei feng - Sun Microsystems - Beijing China sc->sc_config.assoc_id = 0; 1881d5bd65e4Sfei feng - Sun Microsystems - Beijing China sc->sc_config.filter_flags &= 1882d5bd65e4Sfei feng - Sun Microsystems - Beijing China ~LE_32(RXON_FILTER_ASSOC_MSK); 1883d5bd65e4Sfei feng - Sun Microsystems - Beijing China 1884e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_80211, "iwh_newstate(): " 1885e2cf88acSQuaker Fang "config chan %d " 1886b510adaeSfei feng - Sun Microsystems - Beijing China "flags %x filter_flags %x\n", 1887b510adaeSfei feng - Sun Microsystems - Beijing China LE_16(sc->sc_config.chan), 1888b510adaeSfei feng - Sun Microsystems - Beijing China LE_32(sc->sc_config.flags), 1889b510adaeSfei feng - Sun Microsystems - Beijing China LE_32(sc->sc_config.filter_flags))); 1890d5bd65e4Sfei feng - Sun Microsystems - Beijing China 1891d5bd65e4Sfei feng - Sun Microsystems - Beijing China err = iwh_cmd(sc, REPLY_RXON, &sc->sc_config, 1892d5bd65e4Sfei feng - Sun Microsystems - Beijing China sizeof (iwh_rxon_cmd_t), 1); 1893d5bd65e4Sfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 1894e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_newstate(): " 1895d5bd65e4Sfei feng - Sun Microsystems - Beijing China "could not clear association\n"); 189689b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_SCANNING); 1897c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 1898c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 1899c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1900d5bd65e4Sfei feng - Sun Microsystems - Beijing China 190189b2a9fbSfei feng - Sun Microsystems - Beijing China /* 190289b2a9fbSfei feng - Sun Microsystems - Beijing China * add broadcast node to send probe request 190389b2a9fbSfei feng - Sun Microsystems - Beijing China */ 1904d5bd65e4Sfei feng - Sun Microsystems - Beijing China (void) memset(&node, 0, sizeof (node)); 1905d5bd65e4Sfei feng - Sun Microsystems - Beijing China (void) memset(&node.sta.addr, 0xff, IEEE80211_ADDR_LEN); 1906d5bd65e4Sfei feng - Sun Microsystems - Beijing China node.sta.sta_id = IWH_BROADCAST_ID; 1907d5bd65e4Sfei feng - Sun Microsystems - Beijing China err = iwh_cmd(sc, REPLY_ADD_STA, &node, 1908d5bd65e4Sfei feng - Sun Microsystems - Beijing China sizeof (node), 1); 1909d5bd65e4Sfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 1910e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_newstate(): " 1911e2cf88acSQuaker Fang "could not add broadcast node\n"); 191289b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_SCANNING); 1913d5bd65e4Sfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 1914d5bd65e4Sfei feng - Sun Microsystems - Beijing China return (err); 1915d5bd65e4Sfei feng - Sun Microsystems - Beijing China } 1916d5bd65e4Sfei feng - Sun Microsystems - Beijing China break; 1917d5bd65e4Sfei feng - Sun Microsystems - Beijing China case IEEE80211_S_SCAN: 1918d5bd65e4Sfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 1919d5bd65e4Sfei feng - Sun Microsystems - Beijing China /* step to next channel before actual FW scan */ 1920d5bd65e4Sfei feng - Sun Microsystems - Beijing China err = sc->sc_newstate(ic, nstate, arg); 1921d5bd65e4Sfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_glock); 1922d5bd65e4Sfei feng - Sun Microsystems - Beijing China if ((err != 0) || ((err = iwh_scan(sc)) != 0)) { 1923e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_newstate(): " 1924d5bd65e4Sfei feng - Sun Microsystems - Beijing China "could not initiate scan\n"); 192589b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_SCANNING); 1926d5bd65e4Sfei feng - Sun Microsystems - Beijing China ieee80211_cancel_scan(ic); 1927d5bd65e4Sfei feng - Sun Microsystems - Beijing China } 1928d5bd65e4Sfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 1929d5bd65e4Sfei feng - Sun Microsystems - Beijing China return (err); 1930d5bd65e4Sfei feng - Sun Microsystems - Beijing China default: 1931d5bd65e4Sfei feng - Sun Microsystems - Beijing China break; 1932c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1933c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_clk = 0; 1934d5bd65e4Sfei feng - Sun Microsystems - Beijing China break; 1935c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1936c7ee0b5cSfei feng - Sun Microsystems - Beijing China case IEEE80211_S_AUTH: 1937d5bd65e4Sfei feng - Sun Microsystems - Beijing China if (ostate == IEEE80211_S_SCAN) { 193889b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_SCANNING); 1939d5bd65e4Sfei feng - Sun Microsystems - Beijing China } 1940d5bd65e4Sfei feng - Sun Microsystems - Beijing China 1941c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1942c7ee0b5cSfei feng - Sun Microsystems - Beijing China * reset state to handle reassociations correctly 1943c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1944c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.assoc_id = 0; 1945c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.filter_flags &= ~LE_32(RXON_FILTER_ASSOC_MSK); 1946c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1947c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1948c7ee0b5cSfei feng - Sun Microsystems - Beijing China * before sending authentication and association request frame, 1949c7ee0b5cSfei feng - Sun Microsystems - Beijing China * we need do something in the hardware, such as setting the 1950c7ee0b5cSfei feng - Sun Microsystems - Beijing China * channel same to the target AP... 1951c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1952c7ee0b5cSfei feng - Sun Microsystems - Beijing China if ((err = iwh_hw_set_before_auth(sc)) != 0) { 1953e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_80211, "iwh_newstate(): " 1954c7ee0b5cSfei feng - Sun Microsystems - Beijing China "could not send authentication request\n")); 1955c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 1956c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 1957c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1958c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 1959c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1960c7ee0b5cSfei feng - Sun Microsystems - Beijing China case IEEE80211_S_RUN: 1961d5bd65e4Sfei feng - Sun Microsystems - Beijing China if (ostate == IEEE80211_S_SCAN) { 196289b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_SCANNING); 1963d5bd65e4Sfei feng - Sun Microsystems - Beijing China } 1964d5bd65e4Sfei feng - Sun Microsystems - Beijing China 1965c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (IEEE80211_M_MONITOR == ic->ic_opmode) { 196689b2a9fbSfei feng - Sun Microsystems - Beijing China /* 196789b2a9fbSfei feng - Sun Microsystems - Beijing China * let LED blink when monitoring 196889b2a9fbSfei feng - Sun Microsystems - Beijing China */ 1969c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_set_led(sc, 2, 10, 10); 1970c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 1971c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1972c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1973e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_80211, "iwh_newstate(): " 1974e2cf88acSQuaker Fang "associated.\n")); 1975c7ee0b5cSfei feng - Sun Microsystems - Beijing China 19766f12def4Spengcheng chen - Sun Microsystems - Beijing China err = iwh_run_state_config(sc); 1977c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 19786f12def4Spengcheng chen - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_newstate(): " 19796f12def4Spengcheng chen - Sun Microsystems - Beijing China "failed to set up association\n"); 1980c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 1981c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 1982c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 1983c7ee0b5cSfei feng - Sun Microsystems - Beijing China 1984c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 1985c7ee0b5cSfei feng - Sun Microsystems - Beijing China * start automatic rate control 1986c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 1987e2cf88acSQuaker Fang if ((in->in_flags & IEEE80211_NODE_HT) && 1988e2cf88acSQuaker Fang (sc->sc_ht_conf.ht_support) && 1989e2cf88acSQuaker Fang (in->in_htrates.rs_nrates > 0) && 1990e2cf88acSQuaker Fang (in->in_htrates.rs_nrates <= IEEE80211_HTRATE_MAXSIZE)) { 1991e2cf88acSQuaker Fang amrr = (iwh_amrr_t *)in; 1992e2cf88acSQuaker Fang 1993e2cf88acSQuaker Fang for (i = in->in_htrates.rs_nrates - 1; i > 0; i--) { 1994e2cf88acSQuaker Fang 1995e2cf88acSQuaker Fang r = in->in_htrates.rs_rates[i] & 1996e2cf88acSQuaker Fang IEEE80211_RATE_VAL; 1997e2cf88acSQuaker Fang if ((r != 0) && (r <= 0xd) && 1998e2cf88acSQuaker Fang (sc->sc_ht_conf.tx_support_mcs[r/8] & 1999e2cf88acSQuaker Fang (1 << (r%8)))) { 2000e2cf88acSQuaker Fang amrr->ht_mcs_idx = r; 200189b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_or_32(&sc->sc_flags, 200289b2a9fbSfei feng - Sun Microsystems - Beijing China IWH_F_RATE_AUTO_CTL); 2003e2cf88acSQuaker Fang break; 2004e2cf88acSQuaker Fang } 2005e2cf88acSQuaker Fang } 2006e2cf88acSQuaker Fang } else { 2007c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (IEEE80211_FIXED_RATE_NONE == ic->ic_fixed_rate) { 200889b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_or_32(&sc->sc_flags, 200989b2a9fbSfei feng - Sun Microsystems - Beijing China IWH_F_RATE_AUTO_CTL); 2010e2cf88acSQuaker Fang 2011c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2012c7ee0b5cSfei feng - Sun Microsystems - Beijing China * set rate to some reasonable initial value 2013c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2014c7ee0b5cSfei feng - Sun Microsystems - Beijing China i = in->in_rates.ir_nrates - 1; 2015c7ee0b5cSfei feng - Sun Microsystems - Beijing China while (i > 0 && IEEE80211_RATE(i) > 72) { 2016c7ee0b5cSfei feng - Sun Microsystems - Beijing China i--; 2017c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2018c7ee0b5cSfei feng - Sun Microsystems - Beijing China in->in_txrate = i; 2019e2cf88acSQuaker Fang 2020c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { 202189b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, 202289b2a9fbSfei feng - Sun Microsystems - Beijing China ~IWH_F_RATE_AUTO_CTL); 2023c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2024e2cf88acSQuaker Fang } 2025c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2026c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2027c7ee0b5cSfei feng - Sun Microsystems - Beijing China * set LED on after associated 2028c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2029c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_set_led(sc, 2, 0, 1); 2030c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2031c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2032c7ee0b5cSfei feng - Sun Microsystems - Beijing China case IEEE80211_S_INIT: 2033d5bd65e4Sfei feng - Sun Microsystems - Beijing China if (ostate == IEEE80211_S_SCAN) { 203489b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_SCANNING); 2035d5bd65e4Sfei feng - Sun Microsystems - Beijing China } 2036c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2037c7ee0b5cSfei feng - Sun Microsystems - Beijing China * set LED off after init 2038c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2039c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_set_led(sc, 2, 1, 0); 2040c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2041c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2042c7ee0b5cSfei feng - Sun Microsystems - Beijing China case IEEE80211_S_ASSOC: 2043d5bd65e4Sfei feng - Sun Microsystems - Beijing China if (ostate == IEEE80211_S_SCAN) { 204489b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_SCANNING); 2045d5bd65e4Sfei feng - Sun Microsystems - Beijing China } 2046c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2047c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2048c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2049c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 2050c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2051c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (sc->sc_newstate(ic, nstate, arg)); 2052c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2053c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2054c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2055c7ee0b5cSfei feng - Sun Microsystems - Beijing China * exclusive access to mac begin. 2056c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2057c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 2058c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_enter(iwh_sc_t *sc) 2059c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2060c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t tmp; 2061c7ee0b5cSfei feng - Sun Microsystems - Beijing China int n; 2062c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2063c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_GP_CNTRL); 2064c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_GP_CNTRL, 2065c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 2066c7ee0b5cSfei feng - Sun Microsystems - Beijing China 206789b2a9fbSfei feng - Sun Microsystems - Beijing China /* 206889b2a9fbSfei feng - Sun Microsystems - Beijing China * wait until we succeed 206989b2a9fbSfei feng - Sun Microsystems - Beijing China */ 2070c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (n = 0; n < 1000; n++) { 2071c7ee0b5cSfei feng - Sun Microsystems - Beijing China if ((IWH_READ(sc, CSR_GP_CNTRL) & 2072c7ee0b5cSfei feng - Sun Microsystems - Beijing China (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | 2073c7ee0b5cSfei feng - Sun Microsystems - Beijing China CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP)) == 2074c7ee0b5cSfei feng - Sun Microsystems - Beijing China CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN) { 2075c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2076c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2077c7ee0b5cSfei feng - Sun Microsystems - Beijing China DELAY(10); 2078c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2079c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2080c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 2081c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (1000 == n) { 2082e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_PIO, "iwh_mac_access_enter(): " 2083e2cf88acSQuaker Fang "could not lock memory\n")); 2084c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2085c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 2086c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2087c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2088c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2089c7ee0b5cSfei feng - Sun Microsystems - Beijing China * exclusive access to mac end. 2090c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2091c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 2092c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_exit(iwh_sc_t *sc) 2093c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2094c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t tmp = IWH_READ(sc, CSR_GP_CNTRL); 2095c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_GP_CNTRL, 2096c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp & ~CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 2097c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2098c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2099c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2100c7ee0b5cSfei feng - Sun Microsystems - Beijing China * this function defined here for future use. 2101c7ee0b5cSfei feng - Sun Microsystems - Beijing China * static uint32_t 2102c7ee0b5cSfei feng - Sun Microsystems - Beijing China * iwh_mem_read(iwh_sc_t *sc, uint32_t addr) 2103c7ee0b5cSfei feng - Sun Microsystems - Beijing China * { 2104c7ee0b5cSfei feng - Sun Microsystems - Beijing China * IWH_WRITE(sc, HBUS_TARG_MEM_RADDR, addr); 2105c7ee0b5cSfei feng - Sun Microsystems - Beijing China * return (IWH_READ(sc, HBUS_TARG_MEM_RDAT)); 2106c7ee0b5cSfei feng - Sun Microsystems - Beijing China * } 2107c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2108c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2109c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2110c7ee0b5cSfei feng - Sun Microsystems - Beijing China * write mac memory 2111c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2112c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 2113c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mem_write(iwh_sc_t *sc, uint32_t addr, uint32_t data) 2114c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2115c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, HBUS_TARG_MEM_WADDR, addr); 2116c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, HBUS_TARG_MEM_WDAT, data); 2117c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2118c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2119c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2120c7ee0b5cSfei feng - Sun Microsystems - Beijing China * read mac register 2121c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2122c7ee0b5cSfei feng - Sun Microsystems - Beijing China static uint32_t 2123c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_read(iwh_sc_t *sc, uint32_t addr) 2124c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2125c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, HBUS_TARG_PRPH_RADDR, addr | (3 << 24)); 2126c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_READ(sc, HBUS_TARG_PRPH_RDAT)); 2127c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2128c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2129c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2130c7ee0b5cSfei feng - Sun Microsystems - Beijing China * write mac register 2131c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2132c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 2133c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(iwh_sc_t *sc, uint32_t addr, uint32_t data) 2134c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2135c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, HBUS_TARG_PRPH_WADDR, addr | (3 << 24)); 2136c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, HBUS_TARG_PRPH_WDAT, data); 2137c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2138c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2139c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2140c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2141c7ee0b5cSfei feng - Sun Microsystems - Beijing China * steps of loading ucode: 2142c7ee0b5cSfei feng - Sun Microsystems - Beijing China * load init ucode=>init alive=>calibrate=> 2143c7ee0b5cSfei feng - Sun Microsystems - Beijing China * receive calibration result=>reinitialize NIC=> 2144c7ee0b5cSfei feng - Sun Microsystems - Beijing China * load runtime ucode=>runtime alive=> 2145c7ee0b5cSfei feng - Sun Microsystems - Beijing China * send calibration result=>running. 2146c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2147c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 2148c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_load_init_firmware(iwh_sc_t *sc) 2149c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2150e2cf88acSQuaker Fang int err = IWH_FAIL; 2151c7ee0b5cSfei feng - Sun Microsystems - Beijing China clock_t clk; 2152c7ee0b5cSfei feng - Sun Microsystems - Beijing China 215389b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_PUT_SEG); 2154c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2155c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2156c7ee0b5cSfei feng - Sun Microsystems - Beijing China * load init_text section of uCode to hardware 2157c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2158c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_put_seg_fw(sc, sc->sc_dma_fw_init_text.cookie.dmac_address, 2159c7ee0b5cSfei feng - Sun Microsystems - Beijing China RTC_INST_LOWER_BOUND, sc->sc_dma_fw_init_text.cookie.dmac_size); 2160c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 2161c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_load_init_firmware(): " 2162c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to write init uCode.\n"); 2163c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 2164c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2165c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2166c7ee0b5cSfei feng - Sun Microsystems - Beijing China clk = ddi_get_lbolt() + drv_usectohz(1000000); 2167c7ee0b5cSfei feng - Sun Microsystems - Beijing China 216889b2a9fbSfei feng - Sun Microsystems - Beijing China /* 216989b2a9fbSfei feng - Sun Microsystems - Beijing China * wait loading init_text until completed or timeout 217089b2a9fbSfei feng - Sun Microsystems - Beijing China */ 2171c7ee0b5cSfei feng - Sun Microsystems - Beijing China while (!(sc->sc_flags & IWH_F_PUT_SEG)) { 2172c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (cv_timedwait(&sc->sc_put_seg_cv, &sc->sc_glock, clk) < 0) { 2173c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2174c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2175c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2176c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2177c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (!(sc->sc_flags & IWH_F_PUT_SEG)) { 2178c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_load_init_firmware(): " 2179c7ee0b5cSfei feng - Sun Microsystems - Beijing China "timeout waiting for init uCode load.\n"); 2180c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 2181c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2182c7ee0b5cSfei feng - Sun Microsystems - Beijing China 218389b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_PUT_SEG); 2184c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2185c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2186c7ee0b5cSfei feng - Sun Microsystems - Beijing China * load init_data section of uCode to hardware 2187c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2188c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_put_seg_fw(sc, sc->sc_dma_fw_init_data.cookie.dmac_address, 2189c7ee0b5cSfei feng - Sun Microsystems - Beijing China RTC_DATA_LOWER_BOUND, sc->sc_dma_fw_init_data.cookie.dmac_size); 2190c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 2191c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_load_init_firmware(): " 2192c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to write init_data uCode.\n"); 2193c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 2194c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2195c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2196c7ee0b5cSfei feng - Sun Microsystems - Beijing China clk = ddi_get_lbolt() + drv_usectohz(1000000); 2197c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2198c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2199c7ee0b5cSfei feng - Sun Microsystems - Beijing China * wait loading init_data until completed or timeout 2200c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2201c7ee0b5cSfei feng - Sun Microsystems - Beijing China while (!(sc->sc_flags & IWH_F_PUT_SEG)) { 2202c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (cv_timedwait(&sc->sc_put_seg_cv, &sc->sc_glock, clk) < 0) { 2203c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2204c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2205c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2206c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2207c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (!(sc->sc_flags & IWH_F_PUT_SEG)) { 2208c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_load_init_firmware(): " 2209c7ee0b5cSfei feng - Sun Microsystems - Beijing China "timeout waiting for init_data uCode load.\n"); 2210c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 2211c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2212c7ee0b5cSfei feng - Sun Microsystems - Beijing China 221389b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_PUT_SEG); 2214c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2215c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 2216c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2217c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2218c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 2219c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_load_run_firmware(iwh_sc_t *sc) 2220c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2221e2cf88acSQuaker Fang int err = IWH_FAIL; 2222c7ee0b5cSfei feng - Sun Microsystems - Beijing China clock_t clk; 2223c7ee0b5cSfei feng - Sun Microsystems - Beijing China 222489b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_PUT_SEG); 2225c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2226c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2227c7ee0b5cSfei feng - Sun Microsystems - Beijing China * load init_text section of uCode to hardware 2228c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2229c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_put_seg_fw(sc, sc->sc_dma_fw_text.cookie.dmac_address, 2230c7ee0b5cSfei feng - Sun Microsystems - Beijing China RTC_INST_LOWER_BOUND, sc->sc_dma_fw_text.cookie.dmac_size); 2231c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 2232c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_load_run_firmware(): " 2233c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to write run uCode.\n"); 2234c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 2235c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2236c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2237c7ee0b5cSfei feng - Sun Microsystems - Beijing China clk = ddi_get_lbolt() + drv_usectohz(1000000); 2238c7ee0b5cSfei feng - Sun Microsystems - Beijing China 223989b2a9fbSfei feng - Sun Microsystems - Beijing China /* 224089b2a9fbSfei feng - Sun Microsystems - Beijing China * wait loading run_text until completed or timeout 224189b2a9fbSfei feng - Sun Microsystems - Beijing China */ 2242c7ee0b5cSfei feng - Sun Microsystems - Beijing China while (!(sc->sc_flags & IWH_F_PUT_SEG)) { 2243c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (cv_timedwait(&sc->sc_put_seg_cv, &sc->sc_glock, clk) < 0) { 2244c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2245c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2246c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2247c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2248c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (!(sc->sc_flags & IWH_F_PUT_SEG)) { 2249c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_load_run_firmware(): " 2250c7ee0b5cSfei feng - Sun Microsystems - Beijing China "timeout waiting for run uCode load.\n"); 2251c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 2252c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2253c7ee0b5cSfei feng - Sun Microsystems - Beijing China 225489b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_PUT_SEG); 2255c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2256c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2257c7ee0b5cSfei feng - Sun Microsystems - Beijing China * load run_data section of uCode to hardware 2258c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2259c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_put_seg_fw(sc, sc->sc_dma_fw_data_bak.cookie.dmac_address, 2260c7ee0b5cSfei feng - Sun Microsystems - Beijing China RTC_DATA_LOWER_BOUND, sc->sc_dma_fw_data.cookie.dmac_size); 2261c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 2262c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_load_run_firmware(): " 2263c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to write run_data uCode.\n"); 2264c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 2265c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2266c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2267c7ee0b5cSfei feng - Sun Microsystems - Beijing China clk = ddi_get_lbolt() + drv_usectohz(1000000); 2268c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2269c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2270c7ee0b5cSfei feng - Sun Microsystems - Beijing China * wait loading run_data until completed or timeout 2271c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2272c7ee0b5cSfei feng - Sun Microsystems - Beijing China while (!(sc->sc_flags & IWH_F_PUT_SEG)) { 2273c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (cv_timedwait(&sc->sc_put_seg_cv, &sc->sc_glock, clk) < 0) { 2274c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2275c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2276c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2277c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2278c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (!(sc->sc_flags & IWH_F_PUT_SEG)) { 2279c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_load_run_firmware(): " 2280c7ee0b5cSfei feng - Sun Microsystems - Beijing China "timeout waiting for run_data uCode load.\n"); 2281c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 2282c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2283c7ee0b5cSfei feng - Sun Microsystems - Beijing China 228489b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_PUT_SEG); 2285c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2286c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 2287c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2288c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2289c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2290c7ee0b5cSfei feng - Sun Microsystems - Beijing China * this function will be invoked to receive phy information 2291c7ee0b5cSfei feng - Sun Microsystems - Beijing China * when a frame is received. 2292c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2293c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 2294c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_rx_phy_intr(iwh_sc_t *sc, iwh_rx_desc_t *desc) 2295c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2296c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2297c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_rx_phy_res.flag = 1; 2298c7ee0b5cSfei feng - Sun Microsystems - Beijing China 229989b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy((uint8_t *)(desc + 1), sc->sc_rx_phy_res.buf, 2300c7ee0b5cSfei feng - Sun Microsystems - Beijing China sizeof (iwh_rx_phy_res_t)); 2301c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2302c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2303c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2304c7ee0b5cSfei feng - Sun Microsystems - Beijing China * this function will be invoked to receive body of frame when 2305c7ee0b5cSfei feng - Sun Microsystems - Beijing China * a frame is received. 2306c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2307c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 2308c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_rx_mpdu_intr(iwh_sc_t *sc, iwh_rx_desc_t *desc) 2309c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2310c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211com_t *ic = &sc->sc_ic; 2311c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 2312c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_rx_ring_t *ring = &sc->sc_rxq; 2313c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 2314b510adaeSfei feng - Sun Microsystems - Beijing China struct ieee80211_frame *wh; 2315b510adaeSfei feng - Sun Microsystems - Beijing China struct iwh_rx_non_cfg_phy *phyinfo; 2316b510adaeSfei feng - Sun Microsystems - Beijing China struct iwh_rx_mpdu_body_size *mpdu_size; 2317b510adaeSfei feng - Sun Microsystems - Beijing China mblk_t *mp; 2318b510adaeSfei feng - Sun Microsystems - Beijing China int16_t t; 2319b510adaeSfei feng - Sun Microsystems - Beijing China uint16_t len, rssi, agc; 2320b510adaeSfei feng - Sun Microsystems - Beijing China uint32_t temp, crc, *tail; 2321b510adaeSfei feng - Sun Microsystems - Beijing China uint32_t arssi, brssi, crssi, mrssi; 2322c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_rx_phy_res_t *stat; 2323c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_node_t *in; 2324c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2325c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2326c7ee0b5cSfei feng - Sun Microsystems - Beijing China * assuming not 11n here. cope with 11n in phase-II 2327c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2328c7ee0b5cSfei feng - Sun Microsystems - Beijing China mpdu_size = (struct iwh_rx_mpdu_body_size *)(desc + 1); 2329c7ee0b5cSfei feng - Sun Microsystems - Beijing China stat = (iwh_rx_phy_res_t *)sc->sc_rx_phy_res.buf; 2330c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (stat->cfg_phy_cnt > 20) { 2331c7ee0b5cSfei feng - Sun Microsystems - Beijing China return; 2332c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2333c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2334c7ee0b5cSfei feng - Sun Microsystems - Beijing China phyinfo = (struct iwh_rx_non_cfg_phy *)stat->non_cfg_phy; 2335b510adaeSfei feng - Sun Microsystems - Beijing China temp = LE_32(phyinfo->non_cfg_phy[IWH_RX_RES_AGC_IDX]); 2336c7ee0b5cSfei feng - Sun Microsystems - Beijing China agc = (temp & IWH_OFDM_AGC_MSK) >> IWH_OFDM_AGC_BIT_POS; 2337c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2338b510adaeSfei feng - Sun Microsystems - Beijing China temp = LE_32(phyinfo->non_cfg_phy[IWH_RX_RES_RSSI_AB_IDX]); 2339c7ee0b5cSfei feng - Sun Microsystems - Beijing China arssi = (temp & IWH_OFDM_RSSI_A_MSK) >> IWH_OFDM_RSSI_A_BIT_POS; 2340c7ee0b5cSfei feng - Sun Microsystems - Beijing China brssi = (temp & IWH_OFDM_RSSI_B_MSK) >> IWH_OFDM_RSSI_B_BIT_POS; 2341c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2342b510adaeSfei feng - Sun Microsystems - Beijing China temp = LE_32(phyinfo->non_cfg_phy[IWH_RX_RES_RSSI_C_IDX]); 2343c7ee0b5cSfei feng - Sun Microsystems - Beijing China crssi = (temp & IWH_OFDM_RSSI_C_MSK) >> IWH_OFDM_RSSI_C_BIT_POS; 2344c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2345c7ee0b5cSfei feng - Sun Microsystems - Beijing China mrssi = MAX(arssi, brssi); 2346c7ee0b5cSfei feng - Sun Microsystems - Beijing China mrssi = MAX(mrssi, crssi); 2347c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2348c7ee0b5cSfei feng - Sun Microsystems - Beijing China t = mrssi - agc - IWH_RSSI_OFFSET; 2349c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2350c7ee0b5cSfei feng - Sun Microsystems - Beijing China * convert dBm to percentage 2351c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2352c7ee0b5cSfei feng - Sun Microsystems - Beijing China rssi = (100 * 75 * 75 - (-20 - t) * (15 * 75 + 62 * (-20 - t))) 2353c7ee0b5cSfei feng - Sun Microsystems - Beijing China / (75 * 75); 2354c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (rssi > 100) { 2355c7ee0b5cSfei feng - Sun Microsystems - Beijing China rssi = 100; 2356c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2357c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (rssi < 1) { 2358c7ee0b5cSfei feng - Sun Microsystems - Beijing China rssi = 1; 2359c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2360c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2361c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2362c7ee0b5cSfei feng - Sun Microsystems - Beijing China * size of frame, not include FCS 2363c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2364b510adaeSfei feng - Sun Microsystems - Beijing China len = LE_16(mpdu_size->byte_count); 2365c7ee0b5cSfei feng - Sun Microsystems - Beijing China tail = (uint32_t *)((uint8_t *)(desc + 1) + 2366c7ee0b5cSfei feng - Sun Microsystems - Beijing China sizeof (struct iwh_rx_mpdu_body_size) + len); 2367b510adaeSfei feng - Sun Microsystems - Beijing China bcopy(tail, &crc, 4); 2368c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2369e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_RX, "iwh_rx_mpdu_intr(): " 2370e2cf88acSQuaker Fang "rx intr: idx=%d phy_len=%x len=%d " 2371c7ee0b5cSfei feng - Sun Microsystems - Beijing China "rate=%x chan=%d tstamp=%x non_cfg_phy_count=%x " 2372c7ee0b5cSfei feng - Sun Microsystems - Beijing China "cfg_phy_count=%x tail=%x", ring->cur, sizeof (*stat), 2373c7ee0b5cSfei feng - Sun Microsystems - Beijing China len, stat->rate.r.s.rate, stat->channel, 2374c7ee0b5cSfei feng - Sun Microsystems - Beijing China LE_32(stat->timestampl), stat->non_cfg_phy_cnt, 2375b510adaeSfei feng - Sun Microsystems - Beijing China stat->cfg_phy_cnt, LE_32(crc))); 2376c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2377c7ee0b5cSfei feng - Sun Microsystems - Beijing China if ((len < 16) || (len > sc->sc_dmabuf_sz)) { 2378e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_RX, "iwh_rx_mpdu_intr(): " 2379e2cf88acSQuaker Fang "rx frame oversize\n")); 2380c7ee0b5cSfei feng - Sun Microsystems - Beijing China return; 2381c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2382c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2383c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2384c7ee0b5cSfei feng - Sun Microsystems - Beijing China * discard Rx frames with bad CRC 2385c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2386b510adaeSfei feng - Sun Microsystems - Beijing China if ((LE_32(crc) & 2387c7ee0b5cSfei feng - Sun Microsystems - Beijing China (RX_RES_STATUS_NO_CRC32_ERROR | RX_RES_STATUS_NO_RXE_OVERFLOW)) != 2388c7ee0b5cSfei feng - Sun Microsystems - Beijing China (RX_RES_STATUS_NO_CRC32_ERROR | RX_RES_STATUS_NO_RXE_OVERFLOW)) { 2389e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_RX, "iwh_rx_mpdu_intr(): " 2390e2cf88acSQuaker Fang "rx crc error tail: %x\n", 2391b510adaeSfei feng - Sun Microsystems - Beijing China LE_32(crc))); 2392c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_rx_err++; 2393c7ee0b5cSfei feng - Sun Microsystems - Beijing China return; 2394c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2395c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2396c7ee0b5cSfei feng - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *) 2397c7ee0b5cSfei feng - Sun Microsystems - Beijing China ((uint8_t *)(desc + 1)+ sizeof (struct iwh_rx_mpdu_body_size)); 2398c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2399c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (IEEE80211_FC0_SUBTYPE_ASSOC_RESP == *(uint8_t *)wh) { 2400c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_assoc_id = *((uint16_t *)(wh + 1) + 2); 2401e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_RX, "iwh_rx_mpdu_intr(): " 2402e2cf88acSQuaker Fang "rx : association id = %x\n", 2403c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_assoc_id)); 2404c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2405c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2406c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 2407c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (iwh_dbg_flags & IWH_DEBUG_RX) { 2408c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_dump_pkt((uint8_t *)wh, len, 0, 0); 2409c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2410c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 2411c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2412c7ee0b5cSfei feng - Sun Microsystems - Beijing China in = ieee80211_find_rxnode(ic, wh); 2413c7ee0b5cSfei feng - Sun Microsystems - Beijing China mp = allocb(len, BPRI_MED); 2414c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (mp) { 241589b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(wh, mp->b_wptr, len); 2416c7ee0b5cSfei feng - Sun Microsystems - Beijing China mp->b_wptr += len; 2417c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2418c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2419c7ee0b5cSfei feng - Sun Microsystems - Beijing China * send the frame to the 802.11 layer 2420c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2421c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) ieee80211_input(ic, mp, in, rssi, 0); 2422c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { 2423c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_rx_nobuf++; 2424e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_RX, "iwh_rx_mpdu_intr(): " 2425e2cf88acSQuaker Fang "alloc rx buf failed\n")); 2426c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2427c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2428c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2429c7ee0b5cSfei feng - Sun Microsystems - Beijing China * release node reference 2430c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2431c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_free_node(in); 2432c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2433c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2434c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2435c7ee0b5cSfei feng - Sun Microsystems - Beijing China * process correlative affairs after a frame is sent. 2436c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2437c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 2438c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_intr(iwh_sc_t *sc, iwh_rx_desc_t *desc) 2439c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2440c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211com_t *ic = &sc->sc_ic; 2441c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_ring_t *ring = &sc->sc_txq[desc->hdr.qid & 0x3]; 2442c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_stat_t *stat = (iwh_tx_stat_t *)(desc + 1); 2443e2cf88acSQuaker Fang iwh_amrr_t *amrr; 2444e2cf88acSQuaker Fang 2445e2cf88acSQuaker Fang if (NULL == ic->ic_bss) { 2446e2cf88acSQuaker Fang return; 2447e2cf88acSQuaker Fang } 2448e2cf88acSQuaker Fang 2449e2cf88acSQuaker Fang amrr = (iwh_amrr_t *)ic->ic_bss; 2450c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2451c7ee0b5cSfei feng - Sun Microsystems - Beijing China amrr->txcnt++; 2452e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_RATECTL, "iwh_tx_intr(): " 2453e2cf88acSQuaker Fang "tx: %d cnt\n", amrr->txcnt)); 2454c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2455c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (stat->ntries > 0) { 2456c7ee0b5cSfei feng - Sun Microsystems - Beijing China amrr->retrycnt++; 2457c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_tx_retries++; 2458e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_TX, "iwh_tx_intr(): " 2459e2cf88acSQuaker Fang "tx: %d retries\n", 2460c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_tx_retries)); 2461c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2462c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2463e2cf88acSQuaker Fang mutex_enter(&sc->sc_mt_lock); 2464c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_tx_timer = 0; 2465e2cf88acSQuaker Fang mutex_exit(&sc->sc_mt_lock); 2466c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2467c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_tx_lock); 2468c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2469c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring->queued--; 2470c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ring->queued < 0) { 2471c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring->queued = 0; 2472c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2473c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2474e2cf88acSQuaker Fang if ((sc->sc_need_reschedule) && (ring->queued <= (ring->count >> 3))) { 2475c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_need_reschedule = 0; 2476c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_tx_lock); 2477c7ee0b5cSfei feng - Sun Microsystems - Beijing China mac_tx_update(ic->ic_mach); 2478c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_tx_lock); 2479c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2480c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2481c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_tx_lock); 2482c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2483c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2484c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2485c7ee0b5cSfei feng - Sun Microsystems - Beijing China * inform a given command has been executed 2486c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2487c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 2488c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_cmd_intr(iwh_sc_t *sc, iwh_rx_desc_t *desc) 2489c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2490c7ee0b5cSfei feng - Sun Microsystems - Beijing China if ((desc->hdr.qid & 7) != 4) { 2491c7ee0b5cSfei feng - Sun Microsystems - Beijing China return; 2492c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2493c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2494e2cf88acSQuaker Fang if (sc->sc_cmd_accum > 0) { 2495e2cf88acSQuaker Fang sc->sc_cmd_accum--; 2496e2cf88acSQuaker Fang return; 2497e2cf88acSQuaker Fang } 2498e2cf88acSQuaker Fang 2499c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_glock); 2500c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2501e2cf88acSQuaker Fang sc->sc_cmd_flag = SC_CMD_FLG_DONE; 2502e2cf88acSQuaker Fang 2503c7ee0b5cSfei feng - Sun Microsystems - Beijing China cv_signal(&sc->sc_cmd_cv); 2504c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2505c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 2506c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2507e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_CMD, "iwh_cmd_intr(): " 2508c7ee0b5cSfei feng - Sun Microsystems - Beijing China "qid=%x idx=%d flags=%x type=0x%x\n", 2509c7ee0b5cSfei feng - Sun Microsystems - Beijing China desc->hdr.qid, desc->hdr.idx, desc->hdr.flags, 2510c7ee0b5cSfei feng - Sun Microsystems - Beijing China desc->hdr.type)); 2511c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2512c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2513c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2514c7ee0b5cSfei feng - Sun Microsystems - Beijing China * this function will be invoked when alive notification occur. 2515c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2516c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 2517c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_ucode_alive(iwh_sc_t *sc, iwh_rx_desc_t *desc) 2518c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2519c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t rv; 2520c7ee0b5cSfei feng - Sun Microsystems - Beijing China struct iwh_calib_cfg_cmd cmd; 2521c7ee0b5cSfei feng - Sun Microsystems - Beijing China struct iwh_alive_resp *ar = 2522c7ee0b5cSfei feng - Sun Microsystems - Beijing China (struct iwh_alive_resp *)(desc + 1); 2523c7ee0b5cSfei feng - Sun Microsystems - Beijing China struct iwh_calib_results *res_p = &sc->sc_calib_results; 2524c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2525c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2526c7ee0b5cSfei feng - Sun Microsystems - Beijing China * the microcontroller is ready 2527c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2528e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_FW, "iwh_ucode_alive(): " 2529c7ee0b5cSfei feng - Sun Microsystems - Beijing China "microcode alive notification minor: %x major: %x type: " 2530c7ee0b5cSfei feng - Sun Microsystems - Beijing China "%x subtype: %x\n", 2531c7ee0b5cSfei feng - Sun Microsystems - Beijing China ar->ucode_minor, ar->ucode_minor, ar->ver_type, ar->ver_subtype)); 2532c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2533c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 2534c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (LE_32(ar->is_valid) != UCODE_VALID_OK) { 2535e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_FW, "iwh_ucode_alive(): " 2536c7ee0b5cSfei feng - Sun Microsystems - Beijing China "microcontroller initialization failed\n")); 2537c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2538c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 2539c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2540c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2541c7ee0b5cSfei feng - Sun Microsystems - Beijing China * determine if init alive or runtime alive. 2542c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2543c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (INITIALIZE_SUBTYPE == ar->ver_subtype) { 2544e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_FW, "iwh_ucode_alive(): " 2545c7ee0b5cSfei feng - Sun Microsystems - Beijing China "initialization alive received.\n")); 2546c7ee0b5cSfei feng - Sun Microsystems - Beijing China 254789b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(ar, &sc->sc_card_alive_init, 2548c7ee0b5cSfei feng - Sun Microsystems - Beijing China sizeof (struct iwh_init_alive_resp)); 2549c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2550c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2551c7ee0b5cSfei feng - Sun Microsystems - Beijing China * necessary configuration to NIC 2552c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2553c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_glock); 2554c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2555c7ee0b5cSfei feng - Sun Microsystems - Beijing China rv = iwh_alive_common(sc); 2556c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (rv != IWH_SUCCESS) { 2557c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_ucode_alive(): " 2558c7ee0b5cSfei feng - Sun Microsystems - Beijing China "common alive process failed in init alive.\n"); 2559c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 2560c7ee0b5cSfei feng - Sun Microsystems - Beijing China return; 2561c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2562c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2563c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(&cmd, 0, sizeof (cmd)); 2564c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2565c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd.ucd_calib_cfg.once.is_enable = IWH_CALIB_INIT_CFG_ALL; 2566c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd.ucd_calib_cfg.once.start = IWH_CALIB_INIT_CFG_ALL; 2567c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd.ucd_calib_cfg.once.send_res = IWH_CALIB_INIT_CFG_ALL; 2568c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd.ucd_calib_cfg.flags = IWH_CALIB_INIT_CFG_ALL; 2569c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2570c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2571c7ee0b5cSfei feng - Sun Microsystems - Beijing China * require ucode execute calibration 2572c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2573c7ee0b5cSfei feng - Sun Microsystems - Beijing China rv = iwh_cmd(sc, CALIBRATION_CFG_CMD, &cmd, sizeof (cmd), 1); 2574c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (rv != IWH_SUCCESS) { 2575c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_ucode_alive(): " 2576c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to send calibration configure command.\n"); 2577c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 2578c7ee0b5cSfei feng - Sun Microsystems - Beijing China return; 2579c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2580c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2581c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 2582c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2583c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { /* runtime alive */ 2584c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2585e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_FW, "iwh_ucode_alive(): " 2586e2cf88acSQuaker Fang "runtime alive received.\n")); 2587c7ee0b5cSfei feng - Sun Microsystems - Beijing China 258889b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(ar, &sc->sc_card_alive_run, 2589c7ee0b5cSfei feng - Sun Microsystems - Beijing China sizeof (struct iwh_alive_resp)); 2590c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2591c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_glock); 2592c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2593c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2594c7ee0b5cSfei feng - Sun Microsystems - Beijing China * necessary configuration to NIC 2595c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2596c7ee0b5cSfei feng - Sun Microsystems - Beijing China rv = iwh_alive_common(sc); 2597c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (rv != IWH_SUCCESS) { 2598c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_ucode_alive(): " 2599c7ee0b5cSfei feng - Sun Microsystems - Beijing China "common alive process failed in run alive.\n"); 2600c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 2601c7ee0b5cSfei feng - Sun Microsystems - Beijing China return; 2602c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2603c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2604c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2605c7ee0b5cSfei feng - Sun Microsystems - Beijing China * send the result of local oscilator calibration to uCode. 2606c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2607c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (res_p->lo_res != NULL) { 2608c7ee0b5cSfei feng - Sun Microsystems - Beijing China rv = iwh_cmd(sc, REPLY_PHY_CALIBRATION_CMD, 2609c7ee0b5cSfei feng - Sun Microsystems - Beijing China res_p->lo_res, res_p->lo_res_len, 1); 2610c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (rv != IWH_SUCCESS) { 2611c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_ucode_alive(): " 2612c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to send local" 2613c7ee0b5cSfei feng - Sun Microsystems - Beijing China "oscilator calibration command.\n"); 2614c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 2615c7ee0b5cSfei feng - Sun Microsystems - Beijing China return; 2616c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2617c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2618c7ee0b5cSfei feng - Sun Microsystems - Beijing China DELAY(1000); 2619c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2620c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2621c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2622c7ee0b5cSfei feng - Sun Microsystems - Beijing China * send the result of TX IQ calibration to uCode. 2623c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2624c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (res_p->tx_iq_res != NULL) { 2625c7ee0b5cSfei feng - Sun Microsystems - Beijing China rv = iwh_cmd(sc, REPLY_PHY_CALIBRATION_CMD, 2626c7ee0b5cSfei feng - Sun Microsystems - Beijing China res_p->tx_iq_res, res_p->tx_iq_res_len, 1); 2627c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (rv != IWH_SUCCESS) { 2628c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_ucode_alive(): " 2629c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to send TX IQ" 2630c7ee0b5cSfei feng - Sun Microsystems - Beijing China "calibration command.\n"); 2631c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 2632c7ee0b5cSfei feng - Sun Microsystems - Beijing China return; 2633c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2634c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2635c7ee0b5cSfei feng - Sun Microsystems - Beijing China DELAY(1000); 2636c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2637c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2638c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2639c7ee0b5cSfei feng - Sun Microsystems - Beijing China * sned the result of TX IQ perd calibration to uCode. 2640c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2641c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (res_p->tx_iq_perd_res != NULL) { 2642c7ee0b5cSfei feng - Sun Microsystems - Beijing China rv = iwh_cmd(sc, REPLY_PHY_CALIBRATION_CMD, 2643c7ee0b5cSfei feng - Sun Microsystems - Beijing China res_p->tx_iq_perd_res, 2644c7ee0b5cSfei feng - Sun Microsystems - Beijing China res_p->tx_iq_perd_res_len, 1); 2645c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (rv != IWH_SUCCESS) { 2646c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_ucode_alive(): " 2647c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to send TX IQ perd" 2648c7ee0b5cSfei feng - Sun Microsystems - Beijing China "calibration command.\n"); 2649c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 2650c7ee0b5cSfei feng - Sun Microsystems - Beijing China return; 2651c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2652c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2653c7ee0b5cSfei feng - Sun Microsystems - Beijing China DELAY(1000); 2654c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2655c7ee0b5cSfei feng - Sun Microsystems - Beijing China 265689b2a9fbSfei feng - Sun Microsystems - Beijing China /* 265789b2a9fbSfei feng - Sun Microsystems - Beijing China * send the result of DC calibration to uCode. 265889b2a9fbSfei feng - Sun Microsystems - Beijing China */ 265989b2a9fbSfei feng - Sun Microsystems - Beijing China if (res_p->dc_res != NULL) { 266089b2a9fbSfei feng - Sun Microsystems - Beijing China rv = iwh_cmd(sc, REPLY_PHY_CALIBRATION_CMD, 266189b2a9fbSfei feng - Sun Microsystems - Beijing China res_p->dc_res, 266289b2a9fbSfei feng - Sun Microsystems - Beijing China res_p->dc_res_len, 1); 266389b2a9fbSfei feng - Sun Microsystems - Beijing China if (rv != IWH_SUCCESS) { 266489b2a9fbSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_ucode_alive(): " 266589b2a9fbSfei feng - Sun Microsystems - Beijing China "failed to send DC" 266689b2a9fbSfei feng - Sun Microsystems - Beijing China "calibration command.\n"); 266789b2a9fbSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 266889b2a9fbSfei feng - Sun Microsystems - Beijing China return; 266989b2a9fbSfei feng - Sun Microsystems - Beijing China } 267089b2a9fbSfei feng - Sun Microsystems - Beijing China 267189b2a9fbSfei feng - Sun Microsystems - Beijing China DELAY(1000); 267289b2a9fbSfei feng - Sun Microsystems - Beijing China } 267389b2a9fbSfei feng - Sun Microsystems - Beijing China 267489b2a9fbSfei feng - Sun Microsystems - Beijing China /* 267589b2a9fbSfei feng - Sun Microsystems - Beijing China * send the result of BASE BAND calibration to uCode. 267689b2a9fbSfei feng - Sun Microsystems - Beijing China */ 267789b2a9fbSfei feng - Sun Microsystems - Beijing China if (res_p->base_band_res != NULL) { 267889b2a9fbSfei feng - Sun Microsystems - Beijing China rv = iwh_cmd(sc, REPLY_PHY_CALIBRATION_CMD, 267989b2a9fbSfei feng - Sun Microsystems - Beijing China res_p->base_band_res, 268089b2a9fbSfei feng - Sun Microsystems - Beijing China res_p->base_band_res_len, 1); 268189b2a9fbSfei feng - Sun Microsystems - Beijing China if (rv != IWH_SUCCESS) { 268289b2a9fbSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_ucode_alive(): " 268389b2a9fbSfei feng - Sun Microsystems - Beijing China "failed to send BASE BAND" 268489b2a9fbSfei feng - Sun Microsystems - Beijing China "calibration command.\n"); 268589b2a9fbSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 268689b2a9fbSfei feng - Sun Microsystems - Beijing China return; 268789b2a9fbSfei feng - Sun Microsystems - Beijing China } 268889b2a9fbSfei feng - Sun Microsystems - Beijing China 268989b2a9fbSfei feng - Sun Microsystems - Beijing China DELAY(1000); 269089b2a9fbSfei feng - Sun Microsystems - Beijing China } 269189b2a9fbSfei feng - Sun Microsystems - Beijing China 269289b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_or_32(&sc->sc_flags, IWH_F_FW_INIT); 2693c7ee0b5cSfei feng - Sun Microsystems - Beijing China cv_signal(&sc->sc_ucode_cv); 2694e2cf88acSQuaker Fang 2695e2cf88acSQuaker Fang mutex_exit(&sc->sc_glock); 2696c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2697c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2698c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2699c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2700c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2701c7ee0b5cSfei feng - Sun Microsystems - Beijing China * deal with receiving frames, command response 2702c7ee0b5cSfei feng - Sun Microsystems - Beijing China * and all notifications from ucode. 2703c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2704e2cf88acSQuaker Fang /* ARGSUSED */ 2705c7ee0b5cSfei feng - Sun Microsystems - Beijing China static uint_t 2706c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_rx_softintr(caddr_t arg, caddr_t unused) 2707c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2708e2cf88acSQuaker Fang iwh_sc_t *sc; 2709e2cf88acSQuaker Fang ieee80211com_t *ic; 2710c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_rx_desc_t *desc; 2711c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_rx_data_t *data; 2712c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t index; 2713c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2714e2cf88acSQuaker Fang if (NULL == arg) { 2715c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (DDI_INTR_UNCLAIMED); 2716c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2717e2cf88acSQuaker Fang sc = (iwh_sc_t *)arg; 2718e2cf88acSQuaker Fang ic = &sc->sc_ic; 2719c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2720c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2721c7ee0b5cSfei feng - Sun Microsystems - Beijing China * firmware has moved the index of the rx queue, driver get it, 2722c7ee0b5cSfei feng - Sun Microsystems - Beijing China * and deal with it. 2723c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2724b510adaeSfei feng - Sun Microsystems - Beijing China index = (sc->sc_shared->val0) & 0xfff; 2725c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2726c7ee0b5cSfei feng - Sun Microsystems - Beijing China while (sc->sc_rxq.cur != index) { 2727c7ee0b5cSfei feng - Sun Microsystems - Beijing China data = &sc->sc_rxq.data[sc->sc_rxq.cur]; 2728c7ee0b5cSfei feng - Sun Microsystems - Beijing China desc = (iwh_rx_desc_t *)data->dma_data.mem_va; 2729c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2730e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_INTR, "iwh_rx_softintr(): " 2731e2cf88acSQuaker Fang "rx notification index = %d" 2732c7ee0b5cSfei feng - Sun Microsystems - Beijing China " cur = %d qid=%x idx=%d flags=%x type=%x len=%d\n", 2733c7ee0b5cSfei feng - Sun Microsystems - Beijing China index, sc->sc_rxq.cur, desc->hdr.qid, desc->hdr.idx, 2734c7ee0b5cSfei feng - Sun Microsystems - Beijing China desc->hdr.flags, desc->hdr.type, LE_32(desc->len))); 2735c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2736c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2737c7ee0b5cSfei feng - Sun Microsystems - Beijing China * a command other than a tx need to be replied 2738c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2739c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (!(desc->hdr.qid & 0x80) && 2740e2cf88acSQuaker Fang (desc->hdr.type != REPLY_SCAN_CMD) && 2741e2cf88acSQuaker Fang (desc->hdr.type != REPLY_TX)) { 2742c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_cmd_intr(sc, desc); 2743c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2744c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2745c7ee0b5cSfei feng - Sun Microsystems - Beijing China switch (desc->hdr.type) { 2746c7ee0b5cSfei feng - Sun Microsystems - Beijing China case REPLY_RX_PHY_CMD: 2747c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_rx_phy_intr(sc, desc); 2748c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2749c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2750c7ee0b5cSfei feng - Sun Microsystems - Beijing China case REPLY_RX_MPDU_CMD: 2751c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_rx_mpdu_intr(sc, desc); 2752c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2753c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2754c7ee0b5cSfei feng - Sun Microsystems - Beijing China case REPLY_TX: 2755c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_intr(sc, desc); 2756c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2757c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2758c7ee0b5cSfei feng - Sun Microsystems - Beijing China case REPLY_ALIVE: 2759c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_ucode_alive(sc, desc); 2760c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2761c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2762c7ee0b5cSfei feng - Sun Microsystems - Beijing China case CARD_STATE_NOTIFICATION: 2763c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2764c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t *status = (uint32_t *)(desc + 1); 2765c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2766e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_RADIO, "iwh_rx_softintr(): " 2767e2cf88acSQuaker Fang "state changed to %x\n", 2768c7ee0b5cSfei feng - Sun Microsystems - Beijing China LE_32(*status))); 2769c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2770c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (LE_32(*status) & 1) { 2771c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2772c7ee0b5cSfei feng - Sun Microsystems - Beijing China * the radio button has to be pushed(OFF). It 2773c7ee0b5cSfei feng - Sun Microsystems - Beijing China * is considered as a hw error, the 2774c7ee0b5cSfei feng - Sun Microsystems - Beijing China * iwh_thread() tries to recover it after the 2775c7ee0b5cSfei feng - Sun Microsystems - Beijing China * button is pushed again(ON) 2776c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2777b510adaeSfei feng - Sun Microsystems - Beijing China cmn_err(CE_NOTE, "iwh_rx_softintr(): " 2778c7ee0b5cSfei feng - Sun Microsystems - Beijing China "radio transmitter is off\n"); 2779c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_ostate = sc->sc_ic.ic_state; 2780c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_new_state(&sc->sc_ic, 2781c7ee0b5cSfei feng - Sun Microsystems - Beijing China IEEE80211_S_INIT, -1); 278289b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_or_32(&sc->sc_flags, 278389b2a9fbSfei feng - Sun Microsystems - Beijing China (IWH_F_HW_ERR_RECOVER | IWH_F_RADIO_OFF)); 2784c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2785e2cf88acSQuaker Fang 2786c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2787c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2788c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2789c7ee0b5cSfei feng - Sun Microsystems - Beijing China case SCAN_START_NOTIFICATION: 2790c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2791c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_start_scan_t *scan = 2792c7ee0b5cSfei feng - Sun Microsystems - Beijing China (iwh_start_scan_t *)(desc + 1); 2793c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2794e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_SCAN, "iwh_rx_softintr(): " 2795c7ee0b5cSfei feng - Sun Microsystems - Beijing China "scanning channel %d status %x\n", 2796c7ee0b5cSfei feng - Sun Microsystems - Beijing China scan->chan, LE_32(scan->status))); 2797c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2798c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_curchan = &ic->ic_sup_channels[scan->chan]; 2799c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2800c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2801c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2802c7ee0b5cSfei feng - Sun Microsystems - Beijing China case SCAN_COMPLETE_NOTIFICATION: 2803d5bd65e4Sfei feng - Sun Microsystems - Beijing China { 2804e2cf88acSQuaker Fang #ifdef DEBUG 2805d5bd65e4Sfei feng - Sun Microsystems - Beijing China iwh_stop_scan_t *scan = 2806d5bd65e4Sfei feng - Sun Microsystems - Beijing China (iwh_stop_scan_t *)(desc + 1); 2807d5bd65e4Sfei feng - Sun Microsystems - Beijing China 2808e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_SCAN, "iwh_rx_softintr(): " 2809d5bd65e4Sfei feng - Sun Microsystems - Beijing China "completed channel %d (burst of %d) status %02x\n", 2810d5bd65e4Sfei feng - Sun Microsystems - Beijing China scan->chan, scan->nchan, scan->status)); 2811e2cf88acSQuaker Fang #endif 2812d5bd65e4Sfei feng - Sun Microsystems - Beijing China 2813d5bd65e4Sfei feng - Sun Microsystems - Beijing China sc->sc_scan_pending++; 2814c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2815d5bd65e4Sfei feng - Sun Microsystems - Beijing China } 2816c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2817c7ee0b5cSfei feng - Sun Microsystems - Beijing China case STATISTICS_NOTIFICATION: 2818c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2819c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2820c7ee0b5cSfei feng - Sun Microsystems - Beijing China * handle statistics notification 2821c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2822c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2823c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2824c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2825c7ee0b5cSfei feng - Sun Microsystems - Beijing China case CALIBRATION_RES_NOTIFICATION: 2826c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_save_calib_result(sc, desc); 2827c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2828c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2829c7ee0b5cSfei feng - Sun Microsystems - Beijing China case CALIBRATION_COMPLETE_NOTIFICATION: 2830e2cf88acSQuaker Fang mutex_enter(&sc->sc_glock); 283189b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_or_32(&sc->sc_flags, IWH_F_FW_INIT); 2832c7ee0b5cSfei feng - Sun Microsystems - Beijing China cv_signal(&sc->sc_ucode_cv); 2833e2cf88acSQuaker Fang mutex_exit(&sc->sc_glock); 2834c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2835d00ac735Sfei feng - Sun Microsystems - Beijing China 2836d00ac735Sfei feng - Sun Microsystems - Beijing China case MISSED_BEACONS_NOTIFICATION: 2837216e0daaSQuaker Fang /* handle beacon miss by software mechanism */ 2838d00ac735Sfei feng - Sun Microsystems - Beijing China break; 2839d00ac735Sfei feng - Sun Microsystems - Beijing China } 2840c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2841c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_rxq.cur = (sc->sc_rxq.cur + 1) % RX_QUEUE_SIZE; 2842c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2843c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2844c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2845c7ee0b5cSfei feng - Sun Microsystems - Beijing China * driver dealt with what received in rx queue and tell the information 2846c7ee0b5cSfei feng - Sun Microsystems - Beijing China * to the firmware. 2847c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2848c7ee0b5cSfei feng - Sun Microsystems - Beijing China index = (0 == index) ? RX_QUEUE_SIZE - 1 : index - 1; 2849c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, index & (~7)); 2850c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2851c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2852c7ee0b5cSfei feng - Sun Microsystems - Beijing China * re-enable interrupts 2853c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2854c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_INT_MASK, CSR_INI_SET_MASK); 2855c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2856c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (DDI_INTR_CLAIMED); 2857c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2858c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2859c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2860c7ee0b5cSfei feng - Sun Microsystems - Beijing China * the handle of interrupt 2861c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2862e2cf88acSQuaker Fang /* ARGSUSED */ 2863c7ee0b5cSfei feng - Sun Microsystems - Beijing China static uint_t 2864c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_intr(caddr_t arg, caddr_t unused) 2865c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2866e2cf88acSQuaker Fang iwh_sc_t *sc; 2867c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t r, rfh; 2868c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2869e2cf88acSQuaker Fang if (NULL == arg) { 2870e2cf88acSQuaker Fang return (DDI_INTR_UNCLAIMED); 2871e2cf88acSQuaker Fang } 2872e2cf88acSQuaker Fang sc = (iwh_sc_t *)arg; 2873e2cf88acSQuaker Fang 2874e2cf88acSQuaker Fang r = IWH_READ(sc, CSR_INT); 2875e2cf88acSQuaker Fang if (0 == r || 0xffffffff == r) { 2876e2cf88acSQuaker Fang return (DDI_INTR_UNCLAIMED); 2877e2cf88acSQuaker Fang } 2878e2cf88acSQuaker Fang 2879e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_INTR, "iwh_intr(): " 2880e2cf88acSQuaker Fang "interrupt reg %x\n", r)); 2881c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2882c7ee0b5cSfei feng - Sun Microsystems - Beijing China rfh = IWH_READ(sc, CSR_FH_INT_STATUS); 2883c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2884e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_INTR, "iwh_intr(): " 2885e2cf88acSQuaker Fang "FH interrupt reg %x\n", rfh)); 2886c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2887c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2888c7ee0b5cSfei feng - Sun Microsystems - Beijing China * disable interrupts 2889c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2890c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_INT_MASK, 0); 2891c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2892c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2893c7ee0b5cSfei feng - Sun Microsystems - Beijing China * ack interrupts 2894c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2895c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_INT, r); 2896c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_FH_INT_STATUS, rfh); 2897c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2898c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (r & (BIT_INT_SWERROR | BIT_INT_ERR)) { 2899e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_FW, "iwh_intr(): " 2900e2cf88acSQuaker Fang "fatal firmware error\n")); 2901c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_stop(sc); 2902c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_ostate = sc->sc_ic.ic_state; 29036f12def4Spengcheng chen - Sun Microsystems - Beijing China 290489b2a9fbSfei feng - Sun Microsystems - Beijing China /* 290589b2a9fbSfei feng - Sun Microsystems - Beijing China * notify upper layer 290689b2a9fbSfei feng - Sun Microsystems - Beijing China */ 2907e2cf88acSQuaker Fang if (!IWH_CHK_FAST_RECOVER(sc)) { 2908c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1); 2909e2cf88acSQuaker Fang } 29106f12def4Spengcheng chen - Sun Microsystems - Beijing China 291189b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_or_32(&sc->sc_flags, IWH_F_HW_ERR_RECOVER); 2912c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (DDI_INTR_CLAIMED); 2913c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2914c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2915c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (r & BIT_INT_RF_KILL) { 2916b510adaeSfei feng - Sun Microsystems - Beijing China uint32_t tmp = IWH_READ(sc, CSR_GP_CNTRL); 2917e2cf88acSQuaker Fang if (tmp & (1 << 27)) { 2918b510adaeSfei feng - Sun Microsystems - Beijing China cmn_err(CE_NOTE, "RF switch: radio on\n"); 2919c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2920e2cf88acSQuaker Fang } 2921c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2922c7ee0b5cSfei feng - Sun Microsystems - Beijing China if ((r & (BIT_INT_FH_RX | BIT_INT_SW_RX)) || 2923c7ee0b5cSfei feng - Sun Microsystems - Beijing China (rfh & FH_INT_RX_MASK)) { 2924c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) ddi_intr_trigger_softint(sc->sc_soft_hdl, NULL); 2925e2cf88acSQuaker Fang return (DDI_INTR_CLAIMED); 2926c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2927c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2928c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (r & BIT_INT_FH_TX) { 2929e2cf88acSQuaker Fang mutex_enter(&sc->sc_glock); 293089b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_or_32(&sc->sc_flags, IWH_F_PUT_SEG); 2931c7ee0b5cSfei feng - Sun Microsystems - Beijing China cv_signal(&sc->sc_put_seg_cv); 2932e2cf88acSQuaker Fang mutex_exit(&sc->sc_glock); 2933c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2934c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2935c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 2936c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (r & BIT_INT_ALIVE) { 2937e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_FW, "iwh_intr(): " 2938e2cf88acSQuaker Fang "firmware initialized.\n")); 2939c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2940c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 2941c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2942c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2943c7ee0b5cSfei feng - Sun Microsystems - Beijing China * re-enable interrupts 2944c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2945c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_INT_MASK, CSR_INI_SET_MASK); 2946c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2947c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (DDI_INTR_CLAIMED); 2948c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 2949c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2950c7ee0b5cSfei feng - Sun Microsystems - Beijing China static uint8_t 2951c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_rate_to_plcp(int rate) 2952c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 2953c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint8_t ret; 2954c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2955c7ee0b5cSfei feng - Sun Microsystems - Beijing China switch (rate) { 2956c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2957c7ee0b5cSfei feng - Sun Microsystems - Beijing China * CCK rates 2958c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2959c7ee0b5cSfei feng - Sun Microsystems - Beijing China case 2: 2960c7ee0b5cSfei feng - Sun Microsystems - Beijing China ret = 0xa; 2961c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2962c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2963c7ee0b5cSfei feng - Sun Microsystems - Beijing China case 4: 2964c7ee0b5cSfei feng - Sun Microsystems - Beijing China ret = 0x14; 2965c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2966c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2967c7ee0b5cSfei feng - Sun Microsystems - Beijing China case 11: 2968c7ee0b5cSfei feng - Sun Microsystems - Beijing China ret = 0x37; 2969c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2970c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2971c7ee0b5cSfei feng - Sun Microsystems - Beijing China case 22: 2972c7ee0b5cSfei feng - Sun Microsystems - Beijing China ret = 0x6e; 2973c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2974c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2975c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 2976c7ee0b5cSfei feng - Sun Microsystems - Beijing China * OFDM rates 2977c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 2978c7ee0b5cSfei feng - Sun Microsystems - Beijing China case 12: 2979c7ee0b5cSfei feng - Sun Microsystems - Beijing China ret = 0xd; 2980c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2981c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2982c7ee0b5cSfei feng - Sun Microsystems - Beijing China case 18: 2983c7ee0b5cSfei feng - Sun Microsystems - Beijing China ret = 0xf; 2984c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2985c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2986c7ee0b5cSfei feng - Sun Microsystems - Beijing China case 24: 2987c7ee0b5cSfei feng - Sun Microsystems - Beijing China ret = 0x5; 2988c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2989c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2990c7ee0b5cSfei feng - Sun Microsystems - Beijing China case 36: 2991c7ee0b5cSfei feng - Sun Microsystems - Beijing China ret = 0x7; 2992c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2993c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2994c7ee0b5cSfei feng - Sun Microsystems - Beijing China case 48: 2995c7ee0b5cSfei feng - Sun Microsystems - Beijing China ret = 0x9; 2996c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 2997c7ee0b5cSfei feng - Sun Microsystems - Beijing China 2998c7ee0b5cSfei feng - Sun Microsystems - Beijing China case 72: 2999c7ee0b5cSfei feng - Sun Microsystems - Beijing China ret = 0xb; 3000c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 3001c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3002c7ee0b5cSfei feng - Sun Microsystems - Beijing China case 96: 3003c7ee0b5cSfei feng - Sun Microsystems - Beijing China ret = 0x1; 3004c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 3005c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3006c7ee0b5cSfei feng - Sun Microsystems - Beijing China case 108: 3007c7ee0b5cSfei feng - Sun Microsystems - Beijing China ret = 0x3; 3008c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 3009c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3010c7ee0b5cSfei feng - Sun Microsystems - Beijing China default: 3011c7ee0b5cSfei feng - Sun Microsystems - Beijing China ret = 0; 3012c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 3013c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3014c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3015c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (ret); 3016c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3017c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3018c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3019c7ee0b5cSfei feng - Sun Microsystems - Beijing China * invoked by GLD send frames 3020c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3021c7ee0b5cSfei feng - Sun Microsystems - Beijing China static mblk_t * 3022c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_m_tx(void *arg, mblk_t *mp) 3023c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 3024e2cf88acSQuaker Fang iwh_sc_t *sc; 3025e2cf88acSQuaker Fang ieee80211com_t *ic; 3026c7ee0b5cSfei feng - Sun Microsystems - Beijing China mblk_t *next; 3027c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3028e2cf88acSQuaker Fang if (NULL == arg) { 3029c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (NULL); 3030c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3031e2cf88acSQuaker Fang sc = (iwh_sc_t *)arg; 3032e2cf88acSQuaker Fang ic = &sc->sc_ic; 3033c7ee0b5cSfei feng - Sun Microsystems - Beijing China 303489b2a9fbSfei feng - Sun Microsystems - Beijing China if (sc->sc_flags & IWH_F_SUSPEND) { 303589b2a9fbSfei feng - Sun Microsystems - Beijing China freemsgchain(mp); 303689b2a9fbSfei feng - Sun Microsystems - Beijing China return (NULL); 303789b2a9fbSfei feng - Sun Microsystems - Beijing China } 303889b2a9fbSfei feng - Sun Microsystems - Beijing China 3039c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ic->ic_state != IEEE80211_S_RUN) { 3040c7ee0b5cSfei feng - Sun Microsystems - Beijing China freemsgchain(mp); 3041c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (NULL); 3042c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3043c7ee0b5cSfei feng - Sun Microsystems - Beijing China 30446f12def4Spengcheng chen - Sun Microsystems - Beijing China if ((sc->sc_flags & IWH_F_HW_ERR_RECOVER) && 30456f12def4Spengcheng chen - Sun Microsystems - Beijing China IWH_CHK_FAST_RECOVER(sc)) { 3046e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_FW, "iwh_m_tx(): " 3047e2cf88acSQuaker Fang "hold queue\n")); 30486f12def4Spengcheng chen - Sun Microsystems - Beijing China return (mp); 30496f12def4Spengcheng chen - Sun Microsystems - Beijing China } 30506f12def4Spengcheng chen - Sun Microsystems - Beijing China 3051c7ee0b5cSfei feng - Sun Microsystems - Beijing China while (mp != NULL) { 3052c7ee0b5cSfei feng - Sun Microsystems - Beijing China next = mp->b_next; 3053c7ee0b5cSfei feng - Sun Microsystems - Beijing China mp->b_next = NULL; 3054c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (iwh_send(ic, mp, IEEE80211_FC0_TYPE_DATA) != 0) { 3055c7ee0b5cSfei feng - Sun Microsystems - Beijing China mp->b_next = next; 3056c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 3057c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3058c7ee0b5cSfei feng - Sun Microsystems - Beijing China mp = next; 3059c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3060c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3061c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (mp); 3062c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3063c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3064c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3065c7ee0b5cSfei feng - Sun Microsystems - Beijing China * send frames 3066c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3067c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 3068c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type) 3069c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 3070e2cf88acSQuaker Fang iwh_sc_t *sc; 3071c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_ring_t *ring; 3072c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_desc_t *desc; 3073c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_data_t *data; 307489b2a9fbSfei feng - Sun Microsystems - Beijing China iwh_tx_data_t *desc_data; 3075c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_cmd_t *cmd; 3076c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_cmd_t *tx; 3077c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_node_t *in; 307889b2a9fbSfei feng - Sun Microsystems - Beijing China struct ieee80211_frame *wh, *mp_wh; 3079c7ee0b5cSfei feng - Sun Microsystems - Beijing China struct ieee80211_key *k = NULL; 3080c7ee0b5cSfei feng - Sun Microsystems - Beijing China mblk_t *m, *m0; 3081e2cf88acSQuaker Fang int hdrlen, len, len0, mblen, off, err = IWH_SUCCESS; 3082c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint16_t masks = 0; 3083e2cf88acSQuaker Fang uint32_t rate, s_id = 0; 3084e2cf88acSQuaker Fang int txq_id = NON_QOS_TXQ; 3085e2cf88acSQuaker Fang struct ieee80211_qosframe *qwh = NULL; 3086e2cf88acSQuaker Fang int tid = WME_TID_INVALID; 3087c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3088e2cf88acSQuaker Fang if (NULL == ic) { 3089e2cf88acSQuaker Fang return (IWH_FAIL); 3090e2cf88acSQuaker Fang } 3091e2cf88acSQuaker Fang sc = (iwh_sc_t *)ic; 3092c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3093c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (sc->sc_flags & IWH_F_SUSPEND) { 3094c7ee0b5cSfei feng - Sun Microsystems - Beijing China if ((type & IEEE80211_FC0_TYPE_MASK) != 3095c7ee0b5cSfei feng - Sun Microsystems - Beijing China IEEE80211_FC0_TYPE_DATA) { 3096c7ee0b5cSfei feng - Sun Microsystems - Beijing China freemsg(mp); 3097c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3098c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = IWH_FAIL; 3099c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto exit; 3100c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3101c7ee0b5cSfei feng - Sun Microsystems - Beijing China 310289b2a9fbSfei feng - Sun Microsystems - Beijing China if ((NULL == mp) || (MBLKL(mp) <= 0)) { 310389b2a9fbSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 3104c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3105c7ee0b5cSfei feng - Sun Microsystems - Beijing China 310689b2a9fbSfei feng - Sun Microsystems - Beijing China mp_wh = (struct ieee80211_frame *)mp->b_rptr; 3107c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3108c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 310989b2a9fbSfei feng - Sun Microsystems - Beijing China * Determine send which AP or station in IBSS 3110c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 311189b2a9fbSfei feng - Sun Microsystems - Beijing China in = ieee80211_find_txnode(ic, mp_wh->i_addr1); 3112c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (NULL == in) { 3113c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_send(): " 3114c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to find tx node\n"); 3115e2cf88acSQuaker Fang freemsg(mp); 3116c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_tx_err++; 3117c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = IWH_SUCCESS; 3118c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto exit; 3119c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3120c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3121e2cf88acSQuaker Fang /* 3122e2cf88acSQuaker Fang * Determine TX queue according to traffic ID in frame 3123e2cf88acSQuaker Fang * if working in QoS mode. 3124e2cf88acSQuaker Fang */ 3125e2cf88acSQuaker Fang if (in->in_flags & IEEE80211_NODE_QOS) { 3126e2cf88acSQuaker Fang 3127e2cf88acSQuaker Fang if ((type & IEEE80211_FC0_TYPE_MASK) == 3128e2cf88acSQuaker Fang IEEE80211_FC0_TYPE_DATA) { 3129e2cf88acSQuaker Fang 313089b2a9fbSfei feng - Sun Microsystems - Beijing China if (mp_wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) { 313189b2a9fbSfei feng - Sun Microsystems - Beijing China qwh = (struct ieee80211_qosframe *)mp_wh; 3132e2cf88acSQuaker Fang 3133e2cf88acSQuaker Fang tid = qwh->i_qos[0] & IEEE80211_QOS_TID; 3134e2cf88acSQuaker Fang txq_id = iwh_wme_tid_to_txq(tid); 3135e2cf88acSQuaker Fang 3136e2cf88acSQuaker Fang if (txq_id < TXQ_FOR_AC_MIN || 3137e2cf88acSQuaker Fang (txq_id > TXQ_FOR_AC_MAX)) { 3138e2cf88acSQuaker Fang freemsg(mp); 3139e2cf88acSQuaker Fang sc->sc_tx_err++; 3140e2cf88acSQuaker Fang err = IWH_SUCCESS; 3141e2cf88acSQuaker Fang goto exit; 3142e2cf88acSQuaker Fang } 3143e2cf88acSQuaker Fang 3144e2cf88acSQuaker Fang } else { 3145e2cf88acSQuaker Fang txq_id = NON_QOS_TXQ; 3146e2cf88acSQuaker Fang } 3147e2cf88acSQuaker Fang 3148e2cf88acSQuaker Fang } else if ((type & IEEE80211_FC0_TYPE_MASK) == 3149e2cf88acSQuaker Fang IEEE80211_FC0_TYPE_MGT) { 3150e2cf88acSQuaker Fang txq_id = QOS_TXQ_FOR_MGT; 3151e2cf88acSQuaker Fang } else { 3152e2cf88acSQuaker Fang txq_id = NON_QOS_TXQ; 3153e2cf88acSQuaker Fang } 3154e2cf88acSQuaker Fang 3155e2cf88acSQuaker Fang } else { 3156e2cf88acSQuaker Fang txq_id = NON_QOS_TXQ; 3157e2cf88acSQuaker Fang } 3158e2cf88acSQuaker Fang 315989b2a9fbSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_tx_lock); 3160e2cf88acSQuaker Fang ring = &sc->sc_txq[txq_id]; 3161e2cf88acSQuaker Fang data = &ring->data[ring->cur]; 3162e2cf88acSQuaker Fang cmd = data->cmd; 3163e2cf88acSQuaker Fang bzero(cmd, sizeof (*cmd)); 3164e2cf88acSQuaker Fang 316589b2a9fbSfei feng - Sun Microsystems - Beijing China ring->cur = (ring->cur + 1) % ring->count; 3166e2cf88acSQuaker Fang 3167e2cf88acSQuaker Fang /* 3168e2cf88acSQuaker Fang * Need reschedule TX if TX buffer is full. 3169e2cf88acSQuaker Fang */ 3170e2cf88acSQuaker Fang if (ring->queued > ring->count - IWH_MAX_WIN_SIZE) { 3171e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_TX, "iwh_send(): " 3172e2cf88acSQuaker Fang "no txbuf\n")); 3173e2cf88acSQuaker Fang 3174e2cf88acSQuaker Fang sc->sc_need_reschedule = 1; 3175e2cf88acSQuaker Fang mutex_exit(&sc->sc_tx_lock); 3176e2cf88acSQuaker Fang 3177e2cf88acSQuaker Fang if ((type & IEEE80211_FC0_TYPE_MASK) != 3178e2cf88acSQuaker Fang IEEE80211_FC0_TYPE_DATA) { 3179e2cf88acSQuaker Fang freemsg(mp); 3180e2cf88acSQuaker Fang } 3181e2cf88acSQuaker Fang sc->sc_tx_nobuf++; 3182e2cf88acSQuaker Fang err = IWH_FAIL; 3183e2cf88acSQuaker Fang goto exit; 3184e2cf88acSQuaker Fang } 318589b2a9fbSfei feng - Sun Microsystems - Beijing China 318689b2a9fbSfei feng - Sun Microsystems - Beijing China ring->queued++; 318789b2a9fbSfei feng - Sun Microsystems - Beijing China 3188e2cf88acSQuaker Fang mutex_exit(&sc->sc_tx_lock); 3189e2cf88acSQuaker Fang 319089b2a9fbSfei feng - Sun Microsystems - Beijing China hdrlen = ieee80211_hdrspace(ic, mp->b_rptr); 319189b2a9fbSfei feng - Sun Microsystems - Beijing China 319289b2a9fbSfei feng - Sun Microsystems - Beijing China m = allocb(msgdsize(mp) + 32, BPRI_MED); 319389b2a9fbSfei feng - Sun Microsystems - Beijing China if (NULL == m) { /* can not alloc buf, drop this package */ 319489b2a9fbSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_send(): " 319589b2a9fbSfei feng - Sun Microsystems - Beijing China "failed to allocate msgbuf\n"); 319689b2a9fbSfei feng - Sun Microsystems - Beijing China freemsg(mp); 319789b2a9fbSfei feng - Sun Microsystems - Beijing China 319889b2a9fbSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_tx_lock); 319989b2a9fbSfei feng - Sun Microsystems - Beijing China ring->queued--; 320089b2a9fbSfei feng - Sun Microsystems - Beijing China if ((sc->sc_need_reschedule) && (ring->queued <= 0)) { 320189b2a9fbSfei feng - Sun Microsystems - Beijing China sc->sc_need_reschedule = 0; 320289b2a9fbSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_tx_lock); 320389b2a9fbSfei feng - Sun Microsystems - Beijing China mac_tx_update(ic->ic_mach); 320489b2a9fbSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_tx_lock); 320589b2a9fbSfei feng - Sun Microsystems - Beijing China } 320689b2a9fbSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_tx_lock); 320789b2a9fbSfei feng - Sun Microsystems - Beijing China 320889b2a9fbSfei feng - Sun Microsystems - Beijing China err = IWH_SUCCESS; 320989b2a9fbSfei feng - Sun Microsystems - Beijing China goto exit; 321089b2a9fbSfei feng - Sun Microsystems - Beijing China } 321189b2a9fbSfei feng - Sun Microsystems - Beijing China 321289b2a9fbSfei feng - Sun Microsystems - Beijing China for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) { 321389b2a9fbSfei feng - Sun Microsystems - Beijing China mblen = MBLKL(m0); 321489b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(m0->b_rptr, m->b_rptr + off, mblen); 321589b2a9fbSfei feng - Sun Microsystems - Beijing China off += mblen; 321689b2a9fbSfei feng - Sun Microsystems - Beijing China } 321789b2a9fbSfei feng - Sun Microsystems - Beijing China 321889b2a9fbSfei feng - Sun Microsystems - Beijing China m->b_wptr += off; 321989b2a9fbSfei feng - Sun Microsystems - Beijing China 322089b2a9fbSfei feng - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)m->b_rptr; 322189b2a9fbSfei feng - Sun Microsystems - Beijing China 322289b2a9fbSfei feng - Sun Microsystems - Beijing China /* 322389b2a9fbSfei feng - Sun Microsystems - Beijing China * Net80211 module encapsulate outbound data frames. 322489b2a9fbSfei feng - Sun Microsystems - Beijing China * Add some feilds of 80211 frame. 322589b2a9fbSfei feng - Sun Microsystems - Beijing China */ 322689b2a9fbSfei feng - Sun Microsystems - Beijing China if ((type & IEEE80211_FC0_TYPE_MASK) == 322789b2a9fbSfei feng - Sun Microsystems - Beijing China IEEE80211_FC0_TYPE_DATA) { 322889b2a9fbSfei feng - Sun Microsystems - Beijing China (void) ieee80211_encap(ic, m, in); 322989b2a9fbSfei feng - Sun Microsystems - Beijing China } 323089b2a9fbSfei feng - Sun Microsystems - Beijing China 3231e2cf88acSQuaker Fang freemsg(mp); 3232c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3233c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd->hdr.type = REPLY_TX; 3234c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd->hdr.flags = 0; 3235c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd->hdr.qid = ring->qid; 3236c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3237c7ee0b5cSfei feng - Sun Microsystems - Beijing China tx = (iwh_tx_cmd_t *)cmd->data; 3238c7ee0b5cSfei feng - Sun Microsystems - Beijing China tx->tx_flags = 0; 3239c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3240c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { 3241c7ee0b5cSfei feng - Sun Microsystems - Beijing China tx->tx_flags &= ~(LE_32(TX_CMD_FLG_ACK_MSK)); 3242c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { 3243c7ee0b5cSfei feng - Sun Microsystems - Beijing China tx->tx_flags |= LE_32(TX_CMD_FLG_ACK_MSK); 3244c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3245c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3246c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 3247c7ee0b5cSfei feng - Sun Microsystems - Beijing China k = ieee80211_crypto_encap(ic, m); 3248c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (NULL == k) { 3249c7ee0b5cSfei feng - Sun Microsystems - Beijing China freemsg(m); 3250c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_tx_err++; 325189b2a9fbSfei feng - Sun Microsystems - Beijing China 325289b2a9fbSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_tx_lock); 325389b2a9fbSfei feng - Sun Microsystems - Beijing China ring->queued--; 325489b2a9fbSfei feng - Sun Microsystems - Beijing China if ((sc->sc_need_reschedule) && (ring->queued <= 0)) { 325589b2a9fbSfei feng - Sun Microsystems - Beijing China sc->sc_need_reschedule = 0; 325689b2a9fbSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_tx_lock); 325789b2a9fbSfei feng - Sun Microsystems - Beijing China mac_tx_update(ic->ic_mach); 325889b2a9fbSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_tx_lock); 325989b2a9fbSfei feng - Sun Microsystems - Beijing China } 326089b2a9fbSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_tx_lock); 326189b2a9fbSfei feng - Sun Microsystems - Beijing China 3262c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = IWH_SUCCESS; 3263c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto exit; 3264c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3265c7ee0b5cSfei feng - Sun Microsystems - Beijing China 326689b2a9fbSfei feng - Sun Microsystems - Beijing China /* 326789b2a9fbSfei feng - Sun Microsystems - Beijing China * packet header may have moved, reset our local pointer 326889b2a9fbSfei feng - Sun Microsystems - Beijing China */ 3269c7ee0b5cSfei feng - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)m->b_rptr; 3270c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3271c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3272c7ee0b5cSfei feng - Sun Microsystems - Beijing China len = msgdsize(m); 3273c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3274c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 3275c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (iwh_dbg_flags & IWH_DEBUG_TX) { 3276c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_dump_pkt((uint8_t *)wh, hdrlen, 0, 0); 3277c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3278c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 3279c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3280e2cf88acSQuaker Fang tx->rts_retry_limit = IWH_TX_RTS_RETRY_LIMIT; 3281e2cf88acSQuaker Fang tx->data_retry_limit = IWH_TX_DATA_RETRY_LIMIT; 3282e2cf88acSQuaker Fang 3283c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3284e2cf88acSQuaker Fang * specific TX parameters for management frames 3285c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3286c7ee0b5cSfei feng - Sun Microsystems - Beijing China if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 3287c7ee0b5cSfei feng - Sun Microsystems - Beijing China IEEE80211_FC0_TYPE_MGT) { 3288c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3289c7ee0b5cSfei feng - Sun Microsystems - Beijing China * mgmt frames are sent at 1M 3290c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3291e2cf88acSQuaker Fang if ((in->in_rates.ir_rates[0] & 3292e2cf88acSQuaker Fang IEEE80211_RATE_VAL) != 0) { 3293e2cf88acSQuaker Fang rate = in->in_rates.ir_rates[0] & IEEE80211_RATE_VAL; 3294e2cf88acSQuaker Fang } else { 3295e2cf88acSQuaker Fang rate = 2; 3296e2cf88acSQuaker Fang } 3297e2cf88acSQuaker Fang 3298e2cf88acSQuaker Fang tx->tx_flags |= LE_32(TX_CMD_FLG_SEQ_CTL_MSK); 3299e2cf88acSQuaker Fang 3300e2cf88acSQuaker Fang /* 3301e2cf88acSQuaker Fang * tell h/w to set timestamp in probe responses 3302e2cf88acSQuaker Fang */ 3303e2cf88acSQuaker Fang if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == 3304e2cf88acSQuaker Fang IEEE80211_FC0_SUBTYPE_PROBE_RESP) { 3305e2cf88acSQuaker Fang tx->tx_flags |= LE_32(TX_CMD_FLG_TSF_MSK); 3306e2cf88acSQuaker Fang 3307e2cf88acSQuaker Fang tx->data_retry_limit = 3; 3308e2cf88acSQuaker Fang if (tx->data_retry_limit < tx->rts_retry_limit) { 3309e2cf88acSQuaker Fang tx->rts_retry_limit = tx->data_retry_limit; 3310e2cf88acSQuaker Fang } 3311e2cf88acSQuaker Fang } 3312e2cf88acSQuaker Fang 3313e2cf88acSQuaker Fang if (((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == 3314e2cf88acSQuaker Fang IEEE80211_FC0_SUBTYPE_ASSOC_REQ) || 3315e2cf88acSQuaker Fang ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == 3316e2cf88acSQuaker Fang IEEE80211_FC0_SUBTYPE_REASSOC_REQ)) { 3317e2cf88acSQuaker Fang tx->timeout.pm_frame_timeout = LE_16(3); 3318e2cf88acSQuaker Fang } else { 3319e2cf88acSQuaker Fang tx->timeout.pm_frame_timeout = LE_16(2); 3320e2cf88acSQuaker Fang } 3321e2cf88acSQuaker Fang 3322c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { 3323c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3324e2cf88acSQuaker Fang * do it here for the software way rate scaling. 3325c7ee0b5cSfei feng - Sun Microsystems - Beijing China * later for rate scaling in hardware. 3326c7ee0b5cSfei feng - Sun Microsystems - Beijing China * 3327c7ee0b5cSfei feng - Sun Microsystems - Beijing China * now the txrate is determined in tx cmd flags, set to the 3328e2cf88acSQuaker Fang * max value 54M for 11g and 11M for 11b and 96M for 11n 3329e2cf88acSQuaker Fang * originally. 3330c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3331c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) { 3332c7ee0b5cSfei feng - Sun Microsystems - Beijing China rate = ic->ic_fixed_rate; 3333c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { 3334e2cf88acSQuaker Fang if ((in->in_flags & IEEE80211_NODE_HT) && 3335e2cf88acSQuaker Fang (sc->sc_ht_conf.ht_support)) { 3336e2cf88acSQuaker Fang iwh_amrr_t *amrr = (iwh_amrr_t *)in; 3337e2cf88acSQuaker Fang rate = amrr->ht_mcs_idx; 3338e2cf88acSQuaker Fang } else { 3339e2cf88acSQuaker Fang if ((in->in_rates.ir_rates[in->in_txrate] & 3340e2cf88acSQuaker Fang IEEE80211_RATE_VAL) != 0) { 3341e2cf88acSQuaker Fang rate = in->in_rates. 3342e2cf88acSQuaker Fang ir_rates[in->in_txrate] & 3343e2cf88acSQuaker Fang IEEE80211_RATE_VAL; 3344e2cf88acSQuaker Fang } 3345c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3346c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3347c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3348e2cf88acSQuaker Fang if (tid != WME_TID_INVALID) { 3349e2cf88acSQuaker Fang tx->tid_tspec = (uint8_t)tid; 3350e2cf88acSQuaker Fang tx->tx_flags &= LE_32(~TX_CMD_FLG_SEQ_CTL_MSK); 3351e2cf88acSQuaker Fang } else { 3352e2cf88acSQuaker Fang tx->tx_flags |= LE_32(TX_CMD_FLG_SEQ_CTL_MSK); 3353e2cf88acSQuaker Fang } 3354c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3355e2cf88acSQuaker Fang tx->timeout.pm_frame_timeout = 0; 3356e2cf88acSQuaker Fang } 3357e2cf88acSQuaker Fang 3358e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_TX, "iwh_send(): " 3359e2cf88acSQuaker Fang "tx rate[%d of %d] = %x", 3360c7ee0b5cSfei feng - Sun Microsystems - Beijing China in->in_txrate, in->in_rates.ir_nrates, rate)); 3361c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3362c7ee0b5cSfei feng - Sun Microsystems - Beijing China len0 = roundup(4 + sizeof (iwh_tx_cmd_t) + hdrlen, 4); 3363c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (len0 != (4 + sizeof (iwh_tx_cmd_t) + hdrlen)) { 3364b510adaeSfei feng - Sun Microsystems - Beijing China tx->tx_flags |= LE_32(TX_CMD_FLG_MH_PAD_MSK); 3365c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3366c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3367c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3368c7ee0b5cSfei feng - Sun Microsystems - Beijing China * retrieve destination node's id 3369c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3370c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { 3371c7ee0b5cSfei feng - Sun Microsystems - Beijing China tx->sta_id = IWH_BROADCAST_ID; 3372c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { 3373c7ee0b5cSfei feng - Sun Microsystems - Beijing China tx->sta_id = IWH_AP_ID; 3374c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3375c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3376e2cf88acSQuaker Fang if ((in->in_flags & IEEE80211_NODE_HT) && 3377e2cf88acSQuaker Fang (sc->sc_ht_conf.ht_support) && 3378e2cf88acSQuaker Fang ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 3379e2cf88acSQuaker Fang IEEE80211_FC0_TYPE_DATA)) { 3380e2cf88acSQuaker Fang if (rate >= HT_2CHAIN_RATE_MIN_IDX) { 3381e2cf88acSQuaker Fang rate |= LE_32(RATE_MCS_ANT_AB_MSK); 3382e2cf88acSQuaker Fang } else { 3383e2cf88acSQuaker Fang rate |= LE_32(RATE_MCS_ANT_B_MSK); 3384c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3385c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3386e2cf88acSQuaker Fang rate |= LE_32((1 << RATE_MCS_HT_POS)); 3387c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3388e2cf88acSQuaker Fang tx->rate.r.rate_n_flags = rate; 3389e2cf88acSQuaker Fang 3390e2cf88acSQuaker Fang } else { 3391c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (2 == rate || 4 == rate || 11 == rate || 22 == rate) { 3392c7ee0b5cSfei feng - Sun Microsystems - Beijing China masks |= RATE_MCS_CCK_MSK; 3393c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3394c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3395c7ee0b5cSfei feng - Sun Microsystems - Beijing China masks |= RATE_MCS_ANT_B_MSK; 3396b510adaeSfei feng - Sun Microsystems - Beijing China tx->rate.r.rate_n_flags = LE_32(iwh_rate_to_plcp(rate) | masks); 3397e2cf88acSQuaker Fang } 3398c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3399e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_TX, "iwh_send(): " 3400e2cf88acSQuaker Fang "tx flag = %x", 3401c7ee0b5cSfei feng - Sun Microsystems - Beijing China tx->tx_flags)); 3402c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3403c7ee0b5cSfei feng - Sun Microsystems - Beijing China tx->stop_time.life_time = LE_32(0xffffffff); 3404c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3405c7ee0b5cSfei feng - Sun Microsystems - Beijing China tx->len = LE_16(len); 3406c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3407c7ee0b5cSfei feng - Sun Microsystems - Beijing China tx->dram_lsb_ptr = 3408b510adaeSfei feng - Sun Microsystems - Beijing China LE_32(data->paddr_cmd + 4 + offsetof(iwh_tx_cmd_t, scratch)); 3409c7ee0b5cSfei feng - Sun Microsystems - Beijing China tx->dram_msb_ptr = 0; 3410c7ee0b5cSfei feng - Sun Microsystems - Beijing China tx->driver_txop = 0; 3411c7ee0b5cSfei feng - Sun Microsystems - Beijing China tx->next_frame_len = 0; 3412c7ee0b5cSfei feng - Sun Microsystems - Beijing China 341389b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(m->b_rptr, tx + 1, hdrlen); 3414c7ee0b5cSfei feng - Sun Microsystems - Beijing China m->b_rptr += hdrlen; 341589b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(m->b_rptr, data->dma_data.mem_va, (len - hdrlen)); 3416c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3417e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_TX, "iwh_send(): " 3418e2cf88acSQuaker Fang "sending data: qid=%d idx=%d len=%d", 3419c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring->qid, ring->cur, len)); 3420c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3421c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3422c7ee0b5cSfei feng - Sun Microsystems - Beijing China * first segment includes the tx cmd plus the 802.11 header, 3423c7ee0b5cSfei feng - Sun Microsystems - Beijing China * the second includes the remaining of the 802.11 frame. 3424c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 342589b2a9fbSfei feng - Sun Microsystems - Beijing China 342689b2a9fbSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_tx_lock); 342789b2a9fbSfei feng - Sun Microsystems - Beijing China cmd->hdr.idx = ring->desc_cur; 342889b2a9fbSfei feng - Sun Microsystems - Beijing China desc_data = &ring->data[ring->desc_cur]; 342989b2a9fbSfei feng - Sun Microsystems - Beijing China desc = desc_data->desc; 343089b2a9fbSfei feng - Sun Microsystems - Beijing China bzero(desc, sizeof (*desc)); 3431b510adaeSfei feng - Sun Microsystems - Beijing China desc->val0 = 2 << 24; 3432b510adaeSfei feng - Sun Microsystems - Beijing China desc->pa[0].tb1_addr = data->paddr_cmd; 3433c7ee0b5cSfei feng - Sun Microsystems - Beijing China desc->pa[0].val1 = ((len0 << 4) & 0xfff0) | 3434c7ee0b5cSfei feng - Sun Microsystems - Beijing China ((data->dma_data.cookie.dmac_address & 0xffff) << 16); 3435c7ee0b5cSfei feng - Sun Microsystems - Beijing China desc->pa[0].val2 = 3436c7ee0b5cSfei feng - Sun Microsystems - Beijing China ((data->dma_data.cookie.dmac_address & 0xffff0000) >> 16) | 3437c7ee0b5cSfei feng - Sun Microsystems - Beijing China ((len - hdrlen) << 20); 3438e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_TX, "iwh_send(): " 3439e2cf88acSQuaker Fang "phy addr1 = 0x%x phy addr2 = 0x%x " 3440c7ee0b5cSfei feng - Sun Microsystems - Beijing China "len1 = 0x%x, len2 = 0x%x val1 = 0x%x val2 = 0x%x", 3441c7ee0b5cSfei feng - Sun Microsystems - Beijing China data->paddr_cmd, data->dma_data.cookie.dmac_address, 3442c7ee0b5cSfei feng - Sun Microsystems - Beijing China len0, len - hdrlen, desc->pa[0].val1, desc->pa[0].val2)); 3443c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3444c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3445c7ee0b5cSfei feng - Sun Microsystems - Beijing China * kick ring 3446c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3447c7ee0b5cSfei feng - Sun Microsystems - Beijing China s_id = tx->sta_id; 3448c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3449c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_shared->queues_byte_cnt_tbls[ring->qid]. 345089b2a9fbSfei feng - Sun Microsystems - Beijing China tfd_offset[ring->desc_cur].val = 3451c7ee0b5cSfei feng - Sun Microsystems - Beijing China (8 + len) | (s_id << 12); 345289b2a9fbSfei feng - Sun Microsystems - Beijing China if (ring->desc_cur < IWH_MAX_WIN_SIZE) { 3453c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_shared->queues_byte_cnt_tbls[ring->qid]. 345489b2a9fbSfei feng - Sun Microsystems - Beijing China tfd_offset[IWH_QUEUE_SIZE + ring->desc_cur].val = 3455c7ee0b5cSfei feng - Sun Microsystems - Beijing China (8 + len) | (s_id << 12); 3456c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3457c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3458c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_DMA_SYNC(data->dma_data, DDI_DMA_SYNC_FORDEV); 3459c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV); 3460c7ee0b5cSfei feng - Sun Microsystems - Beijing China 346189b2a9fbSfei feng - Sun Microsystems - Beijing China ring->desc_cur = (ring->desc_cur + 1) % ring->count; 346289b2a9fbSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, HBUS_TARG_WRPTR, ring->qid << 8 | ring->desc_cur); 346389b2a9fbSfei feng - Sun Microsystems - Beijing China 346489b2a9fbSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_tx_lock); 3465c7ee0b5cSfei feng - Sun Microsystems - Beijing China freemsg(m); 3466c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3467c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3468c7ee0b5cSfei feng - Sun Microsystems - Beijing China * release node reference 3469c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3470c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_free_node(in); 3471c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3472c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_stats.is_tx_bytes += len; 3473c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_stats.is_tx_frags++; 3474c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3475e2cf88acSQuaker Fang mutex_enter(&sc->sc_mt_lock); 3476c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (0 == sc->sc_tx_timer) { 34776f12def4Spengcheng chen - Sun Microsystems - Beijing China sc->sc_tx_timer = 4; 3478c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3479e2cf88acSQuaker Fang mutex_exit(&sc->sc_mt_lock); 3480c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3481c7ee0b5cSfei feng - Sun Microsystems - Beijing China exit: 3482c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 3483c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3484c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3485c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3486c7ee0b5cSfei feng - Sun Microsystems - Beijing China * invoked by GLD to deal with IOCTL affaires 3487c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3488c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 3489c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_m_ioctl(void* arg, queue_t *wq, mblk_t *mp) 3490c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 3491e2cf88acSQuaker Fang iwh_sc_t *sc; 3492e2cf88acSQuaker Fang ieee80211com_t *ic; 3493e2cf88acSQuaker Fang int err = EINVAL; 3494e2cf88acSQuaker Fang 3495e2cf88acSQuaker Fang if (NULL == arg) { 3496e2cf88acSQuaker Fang return; 3497e2cf88acSQuaker Fang } 3498e2cf88acSQuaker Fang sc = (iwh_sc_t *)arg; 3499e2cf88acSQuaker Fang ic = &sc->sc_ic; 3500c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3501c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = ieee80211_ioctl(ic, wq, mp); 3502c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ENETRESET == err) { 3503c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3504c7ee0b5cSfei feng - Sun Microsystems - Beijing China * This is special for the hidden AP connection. 3505c7ee0b5cSfei feng - Sun Microsystems - Beijing China * In any case, we should make sure only one 'scan' 3506c7ee0b5cSfei feng - Sun Microsystems - Beijing China * in the driver for a 'connect' CLI command. So 3507c7ee0b5cSfei feng - Sun Microsystems - Beijing China * when connecting to a hidden AP, the scan is just 3508c7ee0b5cSfei feng - Sun Microsystems - Beijing China * sent out to the air when we know the desired 3509c7ee0b5cSfei feng - Sun Microsystems - Beijing China * essid of the AP we want to connect. 3510c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3511c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ic->ic_des_esslen) { 3512d5bd65e4Sfei feng - Sun Microsystems - Beijing China if (sc->sc_flags & IWH_F_RUNNING) { 3513d5bd65e4Sfei feng - Sun Microsystems - Beijing China iwh_m_stop(sc); 3514d5bd65e4Sfei feng - Sun Microsystems - Beijing China (void) iwh_m_start(sc); 3515c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) ieee80211_new_state(ic, 3516c7ee0b5cSfei feng - Sun Microsystems - Beijing China IEEE80211_S_SCAN, -1); 3517c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3518c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3519c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3520d5bd65e4Sfei feng - Sun Microsystems - Beijing China } 3521c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3522c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 35237efa17f5Sfei feng - Sun Microsystems - Beijing China * Call back functions for get/set proporty 35247efa17f5Sfei feng - Sun Microsystems - Beijing China */ 35257efa17f5Sfei feng - Sun Microsystems - Beijing China static int 35267efa17f5Sfei feng - Sun Microsystems - Beijing China iwh_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 3527*0dc2366fSVenugopal Iyer uint_t wldp_length, void *wldp_buf) 35287efa17f5Sfei feng - Sun Microsystems - Beijing China { 3529e2cf88acSQuaker Fang iwh_sc_t *sc; 3530e2cf88acSQuaker Fang int err = EINVAL; 3531e2cf88acSQuaker Fang 3532e2cf88acSQuaker Fang if (NULL == arg) { 3533e2cf88acSQuaker Fang return (EINVAL); 3534e2cf88acSQuaker Fang } 3535e2cf88acSQuaker Fang sc = (iwh_sc_t *)arg; 35367efa17f5Sfei feng - Sun Microsystems - Beijing China 35377efa17f5Sfei feng - Sun Microsystems - Beijing China err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_num, 3538*0dc2366fSVenugopal Iyer wldp_length, wldp_buf); 35397efa17f5Sfei feng - Sun Microsystems - Beijing China 35407efa17f5Sfei feng - Sun Microsystems - Beijing China return (err); 35417efa17f5Sfei feng - Sun Microsystems - Beijing China } 35427efa17f5Sfei feng - Sun Microsystems - Beijing China 3543*0dc2366fSVenugopal Iyer static void 3544*0dc2366fSVenugopal Iyer iwh_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 3545*0dc2366fSVenugopal Iyer mac_prop_info_handle_t mph) 3546*0dc2366fSVenugopal Iyer { 3547*0dc2366fSVenugopal Iyer iwh_sc_t *sc = (iwh_sc_t *)arg; 3548*0dc2366fSVenugopal Iyer 3549*0dc2366fSVenugopal Iyer ieee80211_propinfo(&sc->sc_ic, pr_name, wldp_pr_num, mph); 3550*0dc2366fSVenugopal Iyer } 3551*0dc2366fSVenugopal Iyer 35527efa17f5Sfei feng - Sun Microsystems - Beijing China static int 35537efa17f5Sfei feng - Sun Microsystems - Beijing China iwh_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 35547efa17f5Sfei feng - Sun Microsystems - Beijing China uint_t wldp_length, const void *wldp_buf) 35557efa17f5Sfei feng - Sun Microsystems - Beijing China { 3556e2cf88acSQuaker Fang iwh_sc_t *sc; 3557e2cf88acSQuaker Fang ieee80211com_t *ic; 3558e2cf88acSQuaker Fang int err = EINVAL; 3559e2cf88acSQuaker Fang 3560e2cf88acSQuaker Fang if (NULL == arg) { 3561e2cf88acSQuaker Fang return (EINVAL); 3562e2cf88acSQuaker Fang } 3563e2cf88acSQuaker Fang sc = (iwh_sc_t *)arg; 3564e2cf88acSQuaker Fang ic = &sc->sc_ic; 35657efa17f5Sfei feng - Sun Microsystems - Beijing China 35667efa17f5Sfei feng - Sun Microsystems - Beijing China err = ieee80211_setprop(ic, pr_name, wldp_pr_num, wldp_length, 35677efa17f5Sfei feng - Sun Microsystems - Beijing China wldp_buf); 35687efa17f5Sfei feng - Sun Microsystems - Beijing China 35697efa17f5Sfei feng - Sun Microsystems - Beijing China if (err == ENETRESET) { 35707efa17f5Sfei feng - Sun Microsystems - Beijing China if (ic->ic_des_esslen) { 35717efa17f5Sfei feng - Sun Microsystems - Beijing China if (sc->sc_flags & IWH_F_RUNNING) { 35727efa17f5Sfei feng - Sun Microsystems - Beijing China iwh_m_stop(sc); 35737efa17f5Sfei feng - Sun Microsystems - Beijing China (void) iwh_m_start(sc); 35747efa17f5Sfei feng - Sun Microsystems - Beijing China (void) ieee80211_new_state(ic, 35757efa17f5Sfei feng - Sun Microsystems - Beijing China IEEE80211_S_SCAN, -1); 35767efa17f5Sfei feng - Sun Microsystems - Beijing China } 35777efa17f5Sfei feng - Sun Microsystems - Beijing China } 35787efa17f5Sfei feng - Sun Microsystems - Beijing China err = 0; 35797efa17f5Sfei feng - Sun Microsystems - Beijing China } 35807efa17f5Sfei feng - Sun Microsystems - Beijing China return (err); 35817efa17f5Sfei feng - Sun Microsystems - Beijing China } 35827efa17f5Sfei feng - Sun Microsystems - Beijing China 35837efa17f5Sfei feng - Sun Microsystems - Beijing China /* 3584c7ee0b5cSfei feng - Sun Microsystems - Beijing China * invoked by GLD supply statistics NIC and driver 3585c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3586c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 3587c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_m_stat(void *arg, uint_t stat, uint64_t *val) 3588c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 3589e2cf88acSQuaker Fang iwh_sc_t *sc; 3590e2cf88acSQuaker Fang ieee80211com_t *ic; 35916cf34271Spengcheng chen - Sun Microsystems - Beijing China ieee80211_node_t *in; 3592c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3593e2cf88acSQuaker Fang if (NULL == arg) { 3594e2cf88acSQuaker Fang return (EINVAL); 3595e2cf88acSQuaker Fang } 3596e2cf88acSQuaker Fang sc = (iwh_sc_t *)arg; 3597e2cf88acSQuaker Fang ic = &sc->sc_ic; 3598e2cf88acSQuaker Fang 3599c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_glock); 3600c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3601c7ee0b5cSfei feng - Sun Microsystems - Beijing China switch (stat) { 3602c7ee0b5cSfei feng - Sun Microsystems - Beijing China case MAC_STAT_IFSPEED: 36036cf34271Spengcheng chen - Sun Microsystems - Beijing China in = ic->ic_bss; 3604c7ee0b5cSfei feng - Sun Microsystems - Beijing China *val = ((IEEE80211_FIXED_RATE_NONE == ic->ic_fixed_rate) ? 36056cf34271Spengcheng chen - Sun Microsystems - Beijing China IEEE80211_RATE(in->in_txrate) : 3606c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_fixed_rate) / 2 * 1000000; 3607c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 3608c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3609c7ee0b5cSfei feng - Sun Microsystems - Beijing China case MAC_STAT_NOXMTBUF: 3610c7ee0b5cSfei feng - Sun Microsystems - Beijing China *val = sc->sc_tx_nobuf; 3611c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 3612c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3613c7ee0b5cSfei feng - Sun Microsystems - Beijing China case MAC_STAT_NORCVBUF: 3614c7ee0b5cSfei feng - Sun Microsystems - Beijing China *val = sc->sc_rx_nobuf; 3615c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 3616c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3617c7ee0b5cSfei feng - Sun Microsystems - Beijing China case MAC_STAT_IERRORS: 3618c7ee0b5cSfei feng - Sun Microsystems - Beijing China *val = sc->sc_rx_err; 3619c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 3620c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3621c7ee0b5cSfei feng - Sun Microsystems - Beijing China case MAC_STAT_RBYTES: 3622c7ee0b5cSfei feng - Sun Microsystems - Beijing China *val = ic->ic_stats.is_rx_bytes; 3623c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 3624c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3625c7ee0b5cSfei feng - Sun Microsystems - Beijing China case MAC_STAT_IPACKETS: 3626c7ee0b5cSfei feng - Sun Microsystems - Beijing China *val = ic->ic_stats.is_rx_frags; 3627c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 3628c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3629c7ee0b5cSfei feng - Sun Microsystems - Beijing China case MAC_STAT_OBYTES: 3630c7ee0b5cSfei feng - Sun Microsystems - Beijing China *val = ic->ic_stats.is_tx_bytes; 3631c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 3632c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3633c7ee0b5cSfei feng - Sun Microsystems - Beijing China case MAC_STAT_OPACKETS: 3634c7ee0b5cSfei feng - Sun Microsystems - Beijing China *val = ic->ic_stats.is_tx_frags; 3635c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 3636c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3637c7ee0b5cSfei feng - Sun Microsystems - Beijing China case MAC_STAT_OERRORS: 3638c7ee0b5cSfei feng - Sun Microsystems - Beijing China case WIFI_STAT_TX_FAILED: 3639c7ee0b5cSfei feng - Sun Microsystems - Beijing China *val = sc->sc_tx_err; 3640c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 3641c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3642c7ee0b5cSfei feng - Sun Microsystems - Beijing China case WIFI_STAT_TX_RETRANS: 3643c7ee0b5cSfei feng - Sun Microsystems - Beijing China *val = sc->sc_tx_retries; 3644c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 3645c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3646c7ee0b5cSfei feng - Sun Microsystems - Beijing China case WIFI_STAT_FCS_ERRORS: 3647c7ee0b5cSfei feng - Sun Microsystems - Beijing China case WIFI_STAT_WEP_ERRORS: 3648c7ee0b5cSfei feng - Sun Microsystems - Beijing China case WIFI_STAT_TX_FRAGS: 3649c7ee0b5cSfei feng - Sun Microsystems - Beijing China case WIFI_STAT_MCAST_TX: 3650c7ee0b5cSfei feng - Sun Microsystems - Beijing China case WIFI_STAT_RTS_SUCCESS: 3651c7ee0b5cSfei feng - Sun Microsystems - Beijing China case WIFI_STAT_RTS_FAILURE: 3652c7ee0b5cSfei feng - Sun Microsystems - Beijing China case WIFI_STAT_ACK_FAILURE: 3653c7ee0b5cSfei feng - Sun Microsystems - Beijing China case WIFI_STAT_RX_FRAGS: 3654c7ee0b5cSfei feng - Sun Microsystems - Beijing China case WIFI_STAT_MCAST_RX: 3655c7ee0b5cSfei feng - Sun Microsystems - Beijing China case WIFI_STAT_RX_DUPS: 3656c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 3657c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (ieee80211_stat(ic, stat, val)); 3658c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3659c7ee0b5cSfei feng - Sun Microsystems - Beijing China default: 3660c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 3661c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (ENOTSUP); 3662c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3663c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3664c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 3665c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3666c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 3667c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3668c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3669c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3670c7ee0b5cSfei feng - Sun Microsystems - Beijing China * invoked by GLD to start or open NIC 3671c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3672c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 3673c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_m_start(void *arg) 3674c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 3675e2cf88acSQuaker Fang iwh_sc_t *sc; 3676e2cf88acSQuaker Fang ieee80211com_t *ic; 3677e2cf88acSQuaker Fang int err = IWH_FAIL; 3678e2cf88acSQuaker Fang 3679e2cf88acSQuaker Fang if (NULL == arg) { 3680e2cf88acSQuaker Fang return (EINVAL); 3681e2cf88acSQuaker Fang } 3682e2cf88acSQuaker Fang sc = (iwh_sc_t *)arg; 3683e2cf88acSQuaker Fang ic = &sc->sc_ic; 3684c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3685c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_init(sc); 3686c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 3687c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3688c7ee0b5cSfei feng - Sun Microsystems - Beijing China * The hw init err(eg. RF is OFF). Return Success to make 3689c7ee0b5cSfei feng - Sun Microsystems - Beijing China * the 'plumb' succeed. The iwh_thread() tries to re-init 3690c7ee0b5cSfei feng - Sun Microsystems - Beijing China * background. 3691c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 369289b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_or_32(&sc->sc_flags, IWH_F_HW_ERR_RECOVER); 3693c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 3694c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3695c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3696c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 3697c7ee0b5cSfei feng - Sun Microsystems - Beijing China 369889b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_or_32(&sc->sc_flags, IWH_F_RUNNING); 3699c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3700c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 3701c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3702c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3703c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3704c7ee0b5cSfei feng - Sun Microsystems - Beijing China * invoked by GLD to stop or down NIC 3705c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3706c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 3707c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_m_stop(void *arg) 3708c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 3709e2cf88acSQuaker Fang iwh_sc_t *sc; 3710e2cf88acSQuaker Fang ieee80211com_t *ic; 3711e2cf88acSQuaker Fang 3712e2cf88acSQuaker Fang if (NULL == arg) { 3713e2cf88acSQuaker Fang return; 3714e2cf88acSQuaker Fang } 3715e2cf88acSQuaker Fang sc = (iwh_sc_t *)arg; 3716e2cf88acSQuaker Fang ic = &sc->sc_ic; 3717c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3718c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_stop(sc); 3719c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3720c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3721c7ee0b5cSfei feng - Sun Microsystems - Beijing China * release buffer for calibration 3722c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3723c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_release_calib_buffer(sc); 3724c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3725c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 3726c7ee0b5cSfei feng - Sun Microsystems - Beijing China 372789b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_HW_ERR_RECOVER); 372889b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_RATE_AUTO_CTL); 3729e2cf88acSQuaker Fang 373089b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_RUNNING); 373189b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_SCANNING); 3732c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3733c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3734c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3735c7ee0b5cSfei feng - Sun Microsystems - Beijing China * invoked by GLD to configure NIC 3736c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3737c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 3738c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_m_unicst(void *arg, const uint8_t *macaddr) 3739c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 3740e2cf88acSQuaker Fang iwh_sc_t *sc; 3741e2cf88acSQuaker Fang ieee80211com_t *ic; 3742e2cf88acSQuaker Fang int err = IWH_SUCCESS; 3743e2cf88acSQuaker Fang 3744e2cf88acSQuaker Fang if (NULL == arg) { 3745e2cf88acSQuaker Fang return (EINVAL); 3746e2cf88acSQuaker Fang } 3747e2cf88acSQuaker Fang sc = (iwh_sc_t *)arg; 3748e2cf88acSQuaker Fang ic = &sc->sc_ic; 3749c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3750c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (!IEEE80211_ADDR_EQ(ic->ic_macaddr, macaddr)) { 3751c7ee0b5cSfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(ic->ic_macaddr, macaddr); 3752c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_glock); 3753c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_config(sc); 3754c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 3755c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 3756c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_m_unicst(): " 3757c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to configure device\n"); 3758c7ee0b5cSfei feng - Sun Microsystems - Beijing China goto fail; 3759c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3760c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3761c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3762c7ee0b5cSfei feng - Sun Microsystems - Beijing China fail: 3763c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 3764c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3765c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3766e2cf88acSQuaker Fang /* ARGSUSED */ 3767c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 3768c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_m_multicst(void *arg, boolean_t add, const uint8_t *m) 3769c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 3770c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 3771c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3772c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3773e2cf88acSQuaker Fang /* ARGSUSED */ 3774c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 3775c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_m_promisc(void *arg, boolean_t on) 3776c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 3777c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 3778c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3779c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3780c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3781c7ee0b5cSfei feng - Sun Microsystems - Beijing China * kernel thread to deal with exceptional situation 3782c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3783c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 3784c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_thread(iwh_sc_t *sc) 3785c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 3786c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211com_t *ic = &sc->sc_ic; 3787c7ee0b5cSfei feng - Sun Microsystems - Beijing China clock_t clk; 3788c7ee0b5cSfei feng - Sun Microsystems - Beijing China int err, n = 0, timeout = 0; 3789c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t tmp; 3790c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 3791c7ee0b5cSfei feng - Sun Microsystems - Beijing China int times = 0; 3792c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 3793c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3794c7ee0b5cSfei feng - Sun Microsystems - Beijing China while (sc->sc_mf_thread_switch) { 3795c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_GP_CNTRL); 3796c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (tmp & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) { 379789b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_RADIO_OFF); 3798c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { 379989b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_or_32(&sc->sc_flags, IWH_F_RADIO_OFF); 3800c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3801c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3802c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3803c7ee0b5cSfei feng - Sun Microsystems - Beijing China * If in SUSPEND or the RF is OFF, do nothing. 3804c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3805e2cf88acSQuaker Fang if (sc->sc_flags & IWH_F_RADIO_OFF) { 3806c7ee0b5cSfei feng - Sun Microsystems - Beijing China delay(drv_usectohz(100000)); 3807c7ee0b5cSfei feng - Sun Microsystems - Beijing China continue; 3808c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3809c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3810c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3811c7ee0b5cSfei feng - Sun Microsystems - Beijing China * recovery fatal error 3812c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3813c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ic->ic_mach && 3814c7ee0b5cSfei feng - Sun Microsystems - Beijing China (sc->sc_flags & IWH_F_HW_ERR_RECOVER)) { 3815c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3816e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_FW, "iwh_thread(): " 3817c7ee0b5cSfei feng - Sun Microsystems - Beijing China "try to recover fatal hw error: %d\n", times++)); 3818c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3819c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_stop(sc); 3820c7ee0b5cSfei feng - Sun Microsystems - Beijing China 38216f12def4Spengcheng chen - Sun Microsystems - Beijing China if (IWH_CHK_FAST_RECOVER(sc)) { 382289b2a9fbSfei feng - Sun Microsystems - Beijing China /* 382389b2a9fbSfei feng - Sun Microsystems - Beijing China * save runtime configuration 382489b2a9fbSfei feng - Sun Microsystems - Beijing China */ 38256f12def4Spengcheng chen - Sun Microsystems - Beijing China bcopy(&sc->sc_config, &sc->sc_config_save, 38266f12def4Spengcheng chen - Sun Microsystems - Beijing China sizeof (sc->sc_config)); 38276f12def4Spengcheng chen - Sun Microsystems - Beijing China } else { 3828d5bd65e4Sfei feng - Sun Microsystems - Beijing China ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 3829c7ee0b5cSfei feng - Sun Microsystems - Beijing China delay(drv_usectohz(2000000 + n*500000)); 38306f12def4Spengcheng chen - Sun Microsystems - Beijing China } 3831c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3832c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_init(sc); 3833c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 3834c7ee0b5cSfei feng - Sun Microsystems - Beijing China n++; 3835c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (n < 20) { 3836c7ee0b5cSfei feng - Sun Microsystems - Beijing China continue; 3837c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3838c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3839c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3840c7ee0b5cSfei feng - Sun Microsystems - Beijing China n = 0; 3841c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (!err) { 384289b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_or_32(&sc->sc_flags, IWH_F_RUNNING); 3843c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3844c7ee0b5cSfei feng - Sun Microsystems - Beijing China 38456f12def4Spengcheng chen - Sun Microsystems - Beijing China 38466f12def4Spengcheng chen - Sun Microsystems - Beijing China if (!IWH_CHK_FAST_RECOVER(sc) || 38476f12def4Spengcheng chen - Sun Microsystems - Beijing China iwh_fast_recover(sc) != IWH_SUCCESS) { 384889b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, 384989b2a9fbSfei feng - Sun Microsystems - Beijing China ~IWH_F_HW_ERR_RECOVER); 3850c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3851c7ee0b5cSfei feng - Sun Microsystems - Beijing China delay(drv_usectohz(2000000)); 3852e2cf88acSQuaker Fang if (sc->sc_ostate != IEEE80211_S_INIT) { 38536f12def4Spengcheng chen - Sun Microsystems - Beijing China ieee80211_new_state(ic, 38546f12def4Spengcheng chen - Sun Microsystems - Beijing China IEEE80211_S_SCAN, 0); 3855c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 38566f12def4Spengcheng chen - Sun Microsystems - Beijing China } 3857d40f4da4Spengcheng chen - Sun Microsystems - Beijing China } 3858d40f4da4Spengcheng chen - Sun Microsystems - Beijing China 3859d5bd65e4Sfei feng - Sun Microsystems - Beijing China if (ic->ic_mach && 3860d5bd65e4Sfei feng - Sun Microsystems - Beijing China (sc->sc_flags & IWH_F_SCANNING) && sc->sc_scan_pending) { 3861e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_SCAN, "iwh_thread(): " 3862d5bd65e4Sfei feng - Sun Microsystems - Beijing China "wait for probe response\n")); 3863d5bd65e4Sfei feng - Sun Microsystems - Beijing China 3864d5bd65e4Sfei feng - Sun Microsystems - Beijing China sc->sc_scan_pending--; 3865d5bd65e4Sfei feng - Sun Microsystems - Beijing China delay(drv_usectohz(200000)); 3866d5bd65e4Sfei feng - Sun Microsystems - Beijing China ieee80211_next_scan(ic); 3867d5bd65e4Sfei feng - Sun Microsystems - Beijing China } 3868d5bd65e4Sfei feng - Sun Microsystems - Beijing China 3869c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3870c7ee0b5cSfei feng - Sun Microsystems - Beijing China * rate ctl 3871c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3872c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ic->ic_mach && 3873c7ee0b5cSfei feng - Sun Microsystems - Beijing China (sc->sc_flags & IWH_F_RATE_AUTO_CTL)) { 3874c7ee0b5cSfei feng - Sun Microsystems - Beijing China clk = ddi_get_lbolt(); 3875e2cf88acSQuaker Fang if (clk > sc->sc_clk + drv_usectohz(1000000)) { 3876c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_amrr_timeout(sc); 3877c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3878c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3879c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3880216e0daaSQuaker Fang if ((ic->ic_state == IEEE80211_S_RUN) && 3881216e0daaSQuaker Fang (ic->ic_beaconmiss++ > 100)) { /* 10 seconds */ 3882216e0daaSQuaker Fang cmn_err(CE_WARN, "iwh: beacon missed for 10 seconds\n"); 3883216e0daaSQuaker Fang (void) ieee80211_new_state(ic, 3884216e0daaSQuaker Fang IEEE80211_S_INIT, -1); 3885216e0daaSQuaker Fang } 3886216e0daaSQuaker Fang 3887c7ee0b5cSfei feng - Sun Microsystems - Beijing China delay(drv_usectohz(100000)); 3888c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3889e2cf88acSQuaker Fang mutex_enter(&sc->sc_mt_lock); 3890c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (sc->sc_tx_timer) { 3891c7ee0b5cSfei feng - Sun Microsystems - Beijing China timeout++; 3892c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (10 == timeout) { 3893c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_tx_timer--; 3894c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (0 == sc->sc_tx_timer) { 389589b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_or_32(&sc->sc_flags, 389689b2a9fbSfei feng - Sun Microsystems - Beijing China IWH_F_HW_ERR_RECOVER); 3897c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_ostate = IEEE80211_S_RUN; 3898e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_FW, "iwh_thread(): " 3899e2cf88acSQuaker Fang "try to recover from " 3900e2cf88acSQuaker Fang "send fail\n")); 3901c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3902c7ee0b5cSfei feng - Sun Microsystems - Beijing China timeout = 0; 3903c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3904c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3905e2cf88acSQuaker Fang mutex_exit(&sc->sc_mt_lock); 3906c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3907c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3908e2cf88acSQuaker Fang mutex_enter(&sc->sc_mt_lock); 3909c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_mf_thread = NULL; 3910c7ee0b5cSfei feng - Sun Microsystems - Beijing China cv_signal(&sc->sc_mt_cv); 3911c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_mt_lock); 3912c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3913c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3914c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3915c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Send a command to the ucode. 3916c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3917c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 3918c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_cmd(iwh_sc_t *sc, int code, const void *buf, int size, int async) 3919c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 3920c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_ring_t *ring = &sc->sc_txq[IWH_CMD_QUEUE_NUM]; 3921c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_desc_t *desc; 3922c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_cmd_t *cmd; 3923c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3924c7ee0b5cSfei feng - Sun Microsystems - Beijing China ASSERT(size <= sizeof (cmd->data)); 3925c7ee0b5cSfei feng - Sun Microsystems - Beijing China ASSERT(mutex_owned(&sc->sc_glock)); 3926c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3927e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_CMD, "iwh_cmd() " 3928e2cf88acSQuaker Fang "code[%d]", code)); 3929c7ee0b5cSfei feng - Sun Microsystems - Beijing China desc = ring->data[ring->cur].desc; 3930c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd = ring->data[ring->cur].cmd; 3931c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3932c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd->hdr.type = (uint8_t)code; 3933c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd->hdr.flags = 0; 3934c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd->hdr.qid = ring->qid; 3935c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd->hdr.idx = ring->cur; 393689b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(buf, cmd->data, size); 3937c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(desc, 0, sizeof (*desc)); 3938c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3939b510adaeSfei feng - Sun Microsystems - Beijing China desc->val0 = 1 << 24; 3940c7ee0b5cSfei feng - Sun Microsystems - Beijing China desc->pa[0].tb1_addr = 3941c7ee0b5cSfei feng - Sun Microsystems - Beijing China (uint32_t)(ring->data[ring->cur].paddr_cmd & 0xffffffff); 3942c7ee0b5cSfei feng - Sun Microsystems - Beijing China desc->pa[0].val1 = ((4 + size) << 4) & 0xfff0; 3943c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3944e2cf88acSQuaker Fang if (async) { 3945e2cf88acSQuaker Fang sc->sc_cmd_accum++; 3946e2cf88acSQuaker Fang } 3947e2cf88acSQuaker Fang 3948c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3949c7ee0b5cSfei feng - Sun Microsystems - Beijing China * kick cmd ring XXX 3950c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3951c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_shared->queues_byte_cnt_tbls[ring->qid]. 3952c7ee0b5cSfei feng - Sun Microsystems - Beijing China tfd_offset[ring->cur].val = 8; 3953c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ring->cur < IWH_MAX_WIN_SIZE) { 3954c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_shared->queues_byte_cnt_tbls[ring->qid]. 3955c7ee0b5cSfei feng - Sun Microsystems - Beijing China tfd_offset[IWH_QUEUE_SIZE + ring->cur].val = 8; 3956c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3957c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring->cur = (ring->cur + 1) % ring->count; 3958c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur); 3959c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3960c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (async) { 3961c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 3962c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { 3963c7ee0b5cSfei feng - Sun Microsystems - Beijing China clock_t clk; 3964e2cf88acSQuaker Fang 3965c7ee0b5cSfei feng - Sun Microsystems - Beijing China clk = ddi_get_lbolt() + drv_usectohz(2000000); 3966e2cf88acSQuaker Fang while (sc->sc_cmd_flag != SC_CMD_FLG_DONE) { 3967c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (cv_timedwait(&sc->sc_cmd_cv, 3968c7ee0b5cSfei feng - Sun Microsystems - Beijing China &sc->sc_glock, clk) < 0) { 3969c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 3970c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3971c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3972c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3973e2cf88acSQuaker Fang if (SC_CMD_FLG_DONE == sc->sc_cmd_flag) { 3974e2cf88acSQuaker Fang sc->sc_cmd_flag = SC_CMD_FLG_NONE; 3975c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 3976c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { 3977e2cf88acSQuaker Fang sc->sc_cmd_flag = SC_CMD_FLG_NONE; 3978c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 3979c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3980c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3981c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3982c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3983c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 3984c7ee0b5cSfei feng - Sun Microsystems - Beijing China * require ucode seting led of NIC 3985c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 3986c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 3987c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_set_led(iwh_sc_t *sc, uint8_t id, uint8_t off, uint8_t on) 3988c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 3989c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_led_cmd_t led; 3990c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3991c7ee0b5cSfei feng - Sun Microsystems - Beijing China led.interval = LE_32(100000); /* unit: 100ms */ 3992c7ee0b5cSfei feng - Sun Microsystems - Beijing China led.id = id; 3993c7ee0b5cSfei feng - Sun Microsystems - Beijing China led.off = off; 3994c7ee0b5cSfei feng - Sun Microsystems - Beijing China led.on = on; 3995c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3996c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) iwh_cmd(sc, REPLY_LEDS_CMD, &led, sizeof (led), 1); 3997c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 3998c7ee0b5cSfei feng - Sun Microsystems - Beijing China 3999c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4000c7ee0b5cSfei feng - Sun Microsystems - Beijing China * necessary setting to NIC before authentication 4001c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4002c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 4003c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_hw_set_before_auth(iwh_sc_t *sc) 4004c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 4005c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211com_t *ic = &sc->sc_ic; 4006c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_node_t *in = ic->ic_bss; 4007e2cf88acSQuaker Fang int err = IWH_FAIL; 4008c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4009c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4010c7ee0b5cSfei feng - Sun Microsystems - Beijing China * update adapter's configuration according 4011c7ee0b5cSfei feng - Sun Microsystems - Beijing China * the info of target AP 4012c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4013c7ee0b5cSfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(sc->sc_config.bssid, in->in_bssid); 4014b510adaeSfei feng - Sun Microsystems - Beijing China sc->sc_config.chan = LE_16(ieee80211_chan2ieee(ic, in->in_chan)); 4015e2cf88acSQuaker Fang 4016e2cf88acSQuaker Fang if (ic->ic_curmode != IEEE80211_MODE_11NG) { 4017e2cf88acSQuaker Fang 4018e2cf88acSQuaker Fang sc->sc_config.ofdm_ht_triple_stream_basic_rates = 0; 4019e2cf88acSQuaker Fang sc->sc_config.ofdm_ht_dual_stream_basic_rates = 0; 4020e2cf88acSQuaker Fang sc->sc_config.ofdm_ht_single_stream_basic_rates = 0; 4021e2cf88acSQuaker Fang 4022c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (IEEE80211_MODE_11B == ic->ic_curmode) { 4023c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.cck_basic_rates = 0x03; 4024c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.ofdm_basic_rates = 0; 4025c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else if ((in->in_chan != IEEE80211_CHAN_ANYC) && 4026c7ee0b5cSfei feng - Sun Microsystems - Beijing China (IEEE80211_IS_CHAN_5GHZ(in->in_chan))) { 4027c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.cck_basic_rates = 0; 4028c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.ofdm_basic_rates = 0x15; 4029c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { /* assume 802.11b/g */ 4030c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.cck_basic_rates = 0x0f; 4031c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.ofdm_basic_rates = 0xff; 4032c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4033e2cf88acSQuaker Fang } 4034c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4035c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.flags &= ~LE_32(RXON_FLG_SHORT_PREAMBLE_MSK | 4036c7ee0b5cSfei feng - Sun Microsystems - Beijing China RXON_FLG_SHORT_SLOT_MSK); 4037c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4038c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ic->ic_flags & IEEE80211_F_SHSLOT) { 4039c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.flags |= LE_32(RXON_FLG_SHORT_SLOT_MSK); 4040c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { 4041c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.flags &= LE_32(~RXON_FLG_SHORT_SLOT_MSK); 4042c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4043c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4044c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) { 4045c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.flags |= LE_32(RXON_FLG_SHORT_PREAMBLE_MSK); 4046c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { 4047c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.flags &= LE_32(~RXON_FLG_SHORT_PREAMBLE_MSK); 4048c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4049c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4050e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_80211, "iwh_hw_set_before_auth(): " 4051e2cf88acSQuaker Fang "config chan %d flags %x " 4052c7ee0b5cSfei feng - Sun Microsystems - Beijing China "filter_flags %x cck %x ofdm %x" 4053c7ee0b5cSfei feng - Sun Microsystems - Beijing China " bssid:%02x:%02x:%02x:%02x:%02x:%2x\n", 4054b510adaeSfei feng - Sun Microsystems - Beijing China LE_16(sc->sc_config.chan), LE_32(sc->sc_config.flags), 4055b510adaeSfei feng - Sun Microsystems - Beijing China LE_32(sc->sc_config.filter_flags), 4056c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.cck_basic_rates, sc->sc_config.ofdm_basic_rates, 4057c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.bssid[0], sc->sc_config.bssid[1], 4058c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.bssid[2], sc->sc_config.bssid[3], 4059c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.bssid[4], sc->sc_config.bssid[5])); 4060c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4061c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_cmd(sc, REPLY_RXON, &sc->sc_config, 4062c7ee0b5cSfei feng - Sun Microsystems - Beijing China sizeof (iwh_rxon_cmd_t), 1); 4063c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 4064c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_hw_set_before_auth(): " 4065c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to config chan%d\n", sc->sc_config.chan); 4066c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 4067c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4068c7ee0b5cSfei feng - Sun Microsystems - Beijing China 406989b2a9fbSfei feng - Sun Microsystems - Beijing China if ((sc->sc_dev_id != 0x423c) && 407089b2a9fbSfei feng - Sun Microsystems - Beijing China (sc->sc_dev_id != 0x423d)) { 4071c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_tx_power_table(sc, 1); 4072c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 4073c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 4074c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 407589b2a9fbSfei feng - Sun Microsystems - Beijing China } 4076c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4077c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4078c7ee0b5cSfei feng - Sun Microsystems - Beijing China * add default AP node 4079c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4080e2cf88acSQuaker Fang err = iwh_add_ap_sta(sc); 4081c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 4082c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 4083c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4084c7ee0b5cSfei feng - Sun Microsystems - Beijing China 408589b2a9fbSfei feng - Sun Microsystems - Beijing China if ((sc->sc_dev_id != 0x423c) && 408689b2a9fbSfei feng - Sun Microsystems - Beijing China (sc->sc_dev_id != 0x423d)) { 4087c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4088e2cf88acSQuaker Fang * set up retry rate table for AP node 4089c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4090e2cf88acSQuaker Fang err = iwh_ap_lq(sc); 4091c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 4092c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 4093c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 409489b2a9fbSfei feng - Sun Microsystems - Beijing China } 4095c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4096e2cf88acSQuaker Fang return (err); 4097c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4098c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4099c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4100c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Send a scan request(assembly scan cmd) to the firmware. 4101c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4102c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 4103c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_scan(iwh_sc_t *sc) 4104c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 4105c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211com_t *ic = &sc->sc_ic; 4106c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_ring_t *ring = &sc->sc_txq[IWH_CMD_QUEUE_NUM]; 4107c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_desc_t *desc; 4108c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_data_t *data; 4109c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_cmd_t *cmd; 4110c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_scan_hdr_t *hdr; 4111b510adaeSfei feng - Sun Microsystems - Beijing China iwh_scan_chan_t chan; 4112c7ee0b5cSfei feng - Sun Microsystems - Beijing China struct ieee80211_frame *wh; 4113c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_node_t *in = ic->ic_bss; 4114d5bd65e4Sfei feng - Sun Microsystems - Beijing China uint8_t essid[IEEE80211_NWID_LEN+1]; 4115c7ee0b5cSfei feng - Sun Microsystems - Beijing China struct ieee80211_rateset *rs; 4116c7ee0b5cSfei feng - Sun Microsystems - Beijing China enum ieee80211_phymode mode; 4117c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint8_t *frm; 4118c7ee0b5cSfei feng - Sun Microsystems - Beijing China int i, pktlen, nrates; 4119c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4120c7ee0b5cSfei feng - Sun Microsystems - Beijing China data = &ring->data[ring->cur]; 4121c7ee0b5cSfei feng - Sun Microsystems - Beijing China desc = data->desc; 4122c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd = (iwh_cmd_t *)data->dma_data.mem_va; 4123c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4124c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd->hdr.type = REPLY_SCAN_CMD; 4125c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd->hdr.flags = 0; 4126c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd->hdr.qid = ring->qid; 4127c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmd->hdr.idx = ring->cur | 0x40; 4128c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4129c7ee0b5cSfei feng - Sun Microsystems - Beijing China hdr = (iwh_scan_hdr_t *)cmd->data; 4130c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(hdr, 0, sizeof (iwh_scan_hdr_t)); 4131d5bd65e4Sfei feng - Sun Microsystems - Beijing China hdr->nchan = 1; 4132d5bd65e4Sfei feng - Sun Microsystems - Beijing China hdr->quiet_time = LE_16(50); 4133c7ee0b5cSfei feng - Sun Microsystems - Beijing China hdr->quiet_plcp_th = LE_16(1); 4134c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4135b510adaeSfei feng - Sun Microsystems - Beijing China hdr->flags = LE_32(RXON_FLG_BAND_24G_MSK); 4136b510adaeSfei feng - Sun Microsystems - Beijing China hdr->rx_chain = LE_16(RXON_RX_CHAIN_DRIVER_FORCE_MSK | 4137b510adaeSfei feng - Sun Microsystems - Beijing China (0x7 << RXON_RX_CHAIN_VALID_POS) | 4138c7ee0b5cSfei feng - Sun Microsystems - Beijing China (0x2 << RXON_RX_CHAIN_FORCE_SEL_POS) | 4139c7ee0b5cSfei feng - Sun Microsystems - Beijing China (0x2 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS)); 4140c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4141c7ee0b5cSfei feng - Sun Microsystems - Beijing China hdr->tx_cmd.tx_flags = LE_32(TX_CMD_FLG_SEQ_CTL_MSK); 4142c7ee0b5cSfei feng - Sun Microsystems - Beijing China hdr->tx_cmd.sta_id = IWH_BROADCAST_ID; 4143b510adaeSfei feng - Sun Microsystems - Beijing China hdr->tx_cmd.stop_time.life_time = LE_32(0xffffffff); 4144b510adaeSfei feng - Sun Microsystems - Beijing China hdr->tx_cmd.rate.r.rate_n_flags = LE_32(iwh_rate_to_plcp(2)); 4145c7ee0b5cSfei feng - Sun Microsystems - Beijing China hdr->tx_cmd.rate.r.rate_n_flags |= 4146b510adaeSfei feng - Sun Microsystems - Beijing China LE_32(RATE_MCS_ANT_B_MSK |RATE_MCS_CCK_MSK); 4147c7ee0b5cSfei feng - Sun Microsystems - Beijing China hdr->direct_scan[0].len = ic->ic_des_esslen; 4148c7ee0b5cSfei feng - Sun Microsystems - Beijing China hdr->direct_scan[0].id = IEEE80211_ELEMID_SSID; 4149c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4150b510adaeSfei feng - Sun Microsystems - Beijing China hdr->filter_flags = LE_32(RXON_FILTER_ACCEPT_GRP_MSK | 4151b510adaeSfei feng - Sun Microsystems - Beijing China RXON_FILTER_BCON_AWARE_MSK); 4152c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4153c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ic->ic_des_esslen) { 4154d5bd65e4Sfei feng - Sun Microsystems - Beijing China bcopy(ic->ic_des_essid, essid, ic->ic_des_esslen); 4155d5bd65e4Sfei feng - Sun Microsystems - Beijing China essid[ic->ic_des_esslen] = '\0'; 4156e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_SCAN, "iwh_scan(): " 4157e2cf88acSQuaker Fang "directed scan %s\n", essid)); 4158d5bd65e4Sfei feng - Sun Microsystems - Beijing China 4159c7ee0b5cSfei feng - Sun Microsystems - Beijing China bcopy(ic->ic_des_essid, hdr->direct_scan[0].ssid, 4160c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_des_esslen); 4161c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { 4162c7ee0b5cSfei feng - Sun Microsystems - Beijing China bzero(hdr->direct_scan[0].ssid, 4163c7ee0b5cSfei feng - Sun Microsystems - Beijing China sizeof (hdr->direct_scan[0].ssid)); 4164c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4165c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4166c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4167c7ee0b5cSfei feng - Sun Microsystems - Beijing China * a probe request frame is required after the REPLY_SCAN_CMD 4168c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4169c7ee0b5cSfei feng - Sun Microsystems - Beijing China wh = (struct ieee80211_frame *)(hdr + 1); 4170c7ee0b5cSfei feng - Sun Microsystems - Beijing China wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | 4171c7ee0b5cSfei feng - Sun Microsystems - Beijing China IEEE80211_FC0_SUBTYPE_PROBE_REQ; 4172c7ee0b5cSfei feng - Sun Microsystems - Beijing China wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; 4173c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(wh->i_addr1, 0xff, 6); 4174c7ee0b5cSfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_macaddr); 4175c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(wh->i_addr3, 0xff, 6); 4176c7ee0b5cSfei feng - Sun Microsystems - Beijing China *(uint16_t *)&wh->i_dur[0] = 0; 4177c7ee0b5cSfei feng - Sun Microsystems - Beijing China *(uint16_t *)&wh->i_seq[0] = 0; 4178c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4179c7ee0b5cSfei feng - Sun Microsystems - Beijing China frm = (uint8_t *)(wh + 1); 4180c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4181c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4182c7ee0b5cSfei feng - Sun Microsystems - Beijing China * essid IE 4183c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4184d5bd65e4Sfei feng - Sun Microsystems - Beijing China if (in->in_esslen) { 4185d5bd65e4Sfei feng - Sun Microsystems - Beijing China bcopy(in->in_essid, essid, in->in_esslen); 4186d5bd65e4Sfei feng - Sun Microsystems - Beijing China essid[in->in_esslen] = '\0'; 4187e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_SCAN, "iwh_scan(): " 4188e2cf88acSQuaker Fang "probe with ESSID %s\n", 4189d5bd65e4Sfei feng - Sun Microsystems - Beijing China essid)); 4190d5bd65e4Sfei feng - Sun Microsystems - Beijing China } 4191c7ee0b5cSfei feng - Sun Microsystems - Beijing China *frm++ = IEEE80211_ELEMID_SSID; 4192c7ee0b5cSfei feng - Sun Microsystems - Beijing China *frm++ = in->in_esslen; 419389b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(in->in_essid, frm, in->in_esslen); 4194c7ee0b5cSfei feng - Sun Microsystems - Beijing China frm += in->in_esslen; 4195c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4196c7ee0b5cSfei feng - Sun Microsystems - Beijing China mode = ieee80211_chan2mode(ic, ic->ic_curchan); 4197c7ee0b5cSfei feng - Sun Microsystems - Beijing China rs = &ic->ic_sup_rates[mode]; 4198c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4199c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4200c7ee0b5cSfei feng - Sun Microsystems - Beijing China * supported rates IE 4201c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4202c7ee0b5cSfei feng - Sun Microsystems - Beijing China *frm++ = IEEE80211_ELEMID_RATES; 4203c7ee0b5cSfei feng - Sun Microsystems - Beijing China nrates = rs->ir_nrates; 4204c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (nrates > IEEE80211_RATE_SIZE) { 4205c7ee0b5cSfei feng - Sun Microsystems - Beijing China nrates = IEEE80211_RATE_SIZE; 4206c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4207c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4208c7ee0b5cSfei feng - Sun Microsystems - Beijing China *frm++ = (uint8_t)nrates; 420989b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(rs->ir_rates, frm, nrates); 4210c7ee0b5cSfei feng - Sun Microsystems - Beijing China frm += nrates; 4211c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4212c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4213c7ee0b5cSfei feng - Sun Microsystems - Beijing China * supported xrates IE 4214c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4215c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (rs->ir_nrates > IEEE80211_RATE_SIZE) { 4216c7ee0b5cSfei feng - Sun Microsystems - Beijing China nrates = rs->ir_nrates - IEEE80211_RATE_SIZE; 4217c7ee0b5cSfei feng - Sun Microsystems - Beijing China *frm++ = IEEE80211_ELEMID_XRATES; 4218c7ee0b5cSfei feng - Sun Microsystems - Beijing China *frm++ = (uint8_t)nrates; 421989b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(rs->ir_rates + IEEE80211_RATE_SIZE, frm, nrates); 4220c7ee0b5cSfei feng - Sun Microsystems - Beijing China frm += nrates; 4221c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4222c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4223c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4224c7ee0b5cSfei feng - Sun Microsystems - Beijing China * optionnal IE (usually for wpa) 4225c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4226c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ic->ic_opt_ie != NULL) { 422789b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(ic->ic_opt_ie, frm, ic->ic_opt_ie_len); 4228c7ee0b5cSfei feng - Sun Microsystems - Beijing China frm += ic->ic_opt_ie_len; 4229c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4230c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4231c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* setup length of probe request */ 4232b510adaeSfei feng - Sun Microsystems - Beijing China hdr->tx_cmd.len = LE_16(_PTRDIFF(frm, wh)); 4233b510adaeSfei feng - Sun Microsystems - Beijing China hdr->len = LE_16(hdr->nchan * sizeof (iwh_scan_chan_t) + 4234b510adaeSfei feng - Sun Microsystems - Beijing China LE_16(hdr->tx_cmd.len) + sizeof (iwh_scan_hdr_t)); 4235c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4236c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4237c7ee0b5cSfei feng - Sun Microsystems - Beijing China * the attribute of the scan channels are required after the probe 4238c7ee0b5cSfei feng - Sun Microsystems - Beijing China * request frame. 4239c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4240b510adaeSfei feng - Sun Microsystems - Beijing China for (i = 1; i <= hdr->nchan; i++) { 4241d5bd65e4Sfei feng - Sun Microsystems - Beijing China if (ic->ic_des_esslen) { 4242b510adaeSfei feng - Sun Microsystems - Beijing China chan.type = LE_32(3); 4243d5bd65e4Sfei feng - Sun Microsystems - Beijing China } else { 4244b510adaeSfei feng - Sun Microsystems - Beijing China chan.type = LE_32(1); 4245d5bd65e4Sfei feng - Sun Microsystems - Beijing China } 4246d5bd65e4Sfei feng - Sun Microsystems - Beijing China 4247b510adaeSfei feng - Sun Microsystems - Beijing China chan.chan = LE_16(ieee80211_chan2ieee(ic, ic->ic_curchan)); 4248b510adaeSfei feng - Sun Microsystems - Beijing China chan.tpc.tx_gain = 0x28; 4249b510adaeSfei feng - Sun Microsystems - Beijing China chan.tpc.dsp_atten = 110; 4250b510adaeSfei feng - Sun Microsystems - Beijing China chan.active_dwell = LE_16(50); 4251b510adaeSfei feng - Sun Microsystems - Beijing China chan.passive_dwell = LE_16(120); 4252c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4253b510adaeSfei feng - Sun Microsystems - Beijing China bcopy(&chan, frm, sizeof (iwh_scan_chan_t)); 4254c7ee0b5cSfei feng - Sun Microsystems - Beijing China frm += sizeof (iwh_scan_chan_t); 4255c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4256c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4257c7ee0b5cSfei feng - Sun Microsystems - Beijing China pktlen = _PTRDIFF(frm, cmd); 4258c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4259c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(desc, 0, sizeof (*desc)); 4260b510adaeSfei feng - Sun Microsystems - Beijing China desc->val0 = 1 << 24; 4261c7ee0b5cSfei feng - Sun Microsystems - Beijing China desc->pa[0].tb1_addr = 4262c7ee0b5cSfei feng - Sun Microsystems - Beijing China (uint32_t)(data->dma_data.cookie.dmac_address & 0xffffffff); 4263c7ee0b5cSfei feng - Sun Microsystems - Beijing China desc->pa[0].val1 = (pktlen << 4) & 0xfff0; 4264c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4265c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4266c7ee0b5cSfei feng - Sun Microsystems - Beijing China * maybe for cmd, filling the byte cnt table is not necessary. 4267c7ee0b5cSfei feng - Sun Microsystems - Beijing China * anyway, we fill it here. 4268c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4269c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_shared->queues_byte_cnt_tbls[ring->qid] 4270c7ee0b5cSfei feng - Sun Microsystems - Beijing China .tfd_offset[ring->cur].val = 8; 4271c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (ring->cur < IWH_MAX_WIN_SIZE) { 4272c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_shared->queues_byte_cnt_tbls[ring->qid]. 4273c7ee0b5cSfei feng - Sun Microsystems - Beijing China tfd_offset[IWH_QUEUE_SIZE + ring->cur].val = 8; 4274c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4275c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4276c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4277c7ee0b5cSfei feng - Sun Microsystems - Beijing China * kick cmd ring 4278c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4279c7ee0b5cSfei feng - Sun Microsystems - Beijing China ring->cur = (ring->cur + 1) % ring->count; 4280c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur); 4281c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4282c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 4283c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4284c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4285c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4286c7ee0b5cSfei feng - Sun Microsystems - Beijing China * configure NIC by using ucode commands after loading ucode. 4287c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4288c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 4289c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_config(iwh_sc_t *sc) 4290c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 4291c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211com_t *ic = &sc->sc_ic; 4292c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_powertable_cmd_t powertable; 4293c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_bt_cmd_t bt; 4294c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_add_sta_t node; 4295c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_rem_sta_t rm_sta; 4296c7ee0b5cSfei feng - Sun Microsystems - Beijing China const uint8_t bcast[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 4297c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_link_quality_cmd_t link_quality; 4298e2cf88acSQuaker Fang int i, err = IWH_FAIL; 4299c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint16_t masks = 0; 4300c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4301c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4302c7ee0b5cSfei feng - Sun Microsystems - Beijing China * set power mode. Disable power management at present, do it later 4303c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4304c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(&powertable, 0, sizeof (powertable)); 4305c7ee0b5cSfei feng - Sun Microsystems - Beijing China powertable.flags = LE_16(0x8); 4306c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_cmd(sc, POWER_TABLE_CMD, &powertable, 4307c7ee0b5cSfei feng - Sun Microsystems - Beijing China sizeof (powertable), 0); 4308c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 4309c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_config(): " 4310c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to set power mode\n"); 4311c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 4312c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4313c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4314c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4315c7ee0b5cSfei feng - Sun Microsystems - Beijing China * configure bt coexistence 4316c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4317c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(&bt, 0, sizeof (bt)); 4318c7ee0b5cSfei feng - Sun Microsystems - Beijing China bt.flags = 3; 4319c7ee0b5cSfei feng - Sun Microsystems - Beijing China bt.lead_time = 0xaa; 4320c7ee0b5cSfei feng - Sun Microsystems - Beijing China bt.max_kill = 1; 4321c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_cmd(sc, REPLY_BT_CONFIG, &bt, 4322c7ee0b5cSfei feng - Sun Microsystems - Beijing China sizeof (bt), 0); 4323c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 4324c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_config(): " 4325c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to configurate bt coexistence\n"); 4326c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 4327c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4328c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4329c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4330c7ee0b5cSfei feng - Sun Microsystems - Beijing China * configure rxon 4331c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4332c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(&sc->sc_config, 0, sizeof (iwh_rxon_cmd_t)); 4333c7ee0b5cSfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(sc->sc_config.node_addr, ic->ic_macaddr); 4334c7ee0b5cSfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(sc->sc_config.wlap_bssid, ic->ic_macaddr); 4335b510adaeSfei feng - Sun Microsystems - Beijing China sc->sc_config.chan = LE_16(ieee80211_chan2ieee(ic, ic->ic_curchan)); 4336b510adaeSfei feng - Sun Microsystems - Beijing China sc->sc_config.flags = LE_32(RXON_FLG_BAND_24G_MSK); 4337e2cf88acSQuaker Fang sc->sc_config.flags &= LE_32(~(RXON_FLG_CHANNEL_MODE_MIXED_MSK | 4338e2cf88acSQuaker Fang RXON_FLG_CHANNEL_MODE_PURE_40_MSK)); 4339c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4340c7ee0b5cSfei feng - Sun Microsystems - Beijing China switch (ic->ic_opmode) { 4341c7ee0b5cSfei feng - Sun Microsystems - Beijing China case IEEE80211_M_STA: 4342c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.dev_type = RXON_DEV_TYPE_ESS; 4343e2cf88acSQuaker Fang sc->sc_config.filter_flags |= LE_32(RXON_FILTER_ACCEPT_GRP_MSK | 4344e2cf88acSQuaker Fang RXON_FILTER_DIS_DECRYPT_MSK | 4345c7ee0b5cSfei feng - Sun Microsystems - Beijing China RXON_FILTER_DIS_GRP_DECRYPT_MSK); 4346c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 4347c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4348c7ee0b5cSfei feng - Sun Microsystems - Beijing China case IEEE80211_M_IBSS: 4349c7ee0b5cSfei feng - Sun Microsystems - Beijing China case IEEE80211_M_AHDEMO: 4350c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.dev_type = RXON_DEV_TYPE_IBSS; 4351c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4352b510adaeSfei feng - Sun Microsystems - Beijing China sc->sc_config.flags |= LE_32(RXON_FLG_SHORT_PREAMBLE_MSK); 4353c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.filter_flags = LE_32(RXON_FILTER_ACCEPT_GRP_MSK | 4354c7ee0b5cSfei feng - Sun Microsystems - Beijing China RXON_FILTER_DIS_DECRYPT_MSK | 4355c7ee0b5cSfei feng - Sun Microsystems - Beijing China RXON_FILTER_DIS_GRP_DECRYPT_MSK); 4356c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 4357c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4358c7ee0b5cSfei feng - Sun Microsystems - Beijing China case IEEE80211_M_HOSTAP: 4359c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.dev_type = RXON_DEV_TYPE_AP; 4360c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 4361c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4362c7ee0b5cSfei feng - Sun Microsystems - Beijing China case IEEE80211_M_MONITOR: 4363c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.dev_type = RXON_DEV_TYPE_SNIFFER; 4364c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.filter_flags |= LE_32(RXON_FILTER_ACCEPT_GRP_MSK | 4365c7ee0b5cSfei feng - Sun Microsystems - Beijing China RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK); 4366c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 4367c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4368c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4369e2cf88acSQuaker Fang /* 4370e2cf88acSQuaker Fang * Support all CCK rates. 4371e2cf88acSQuaker Fang */ 4372c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.cck_basic_rates = 0x0f; 4373e2cf88acSQuaker Fang 4374e2cf88acSQuaker Fang /* 4375e2cf88acSQuaker Fang * Support all OFDM rates. 4376e2cf88acSQuaker Fang */ 4377c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_config.ofdm_basic_rates = 0xff; 4378c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4379c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4380e2cf88acSQuaker Fang * Determine HT supported rates. 4381c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4382e2cf88acSQuaker Fang switch (sc->sc_ht_conf.rx_stream_count) { 4383e2cf88acSQuaker Fang case 3: 4384e2cf88acSQuaker Fang sc->sc_config.ofdm_ht_triple_stream_basic_rates = 0xff; 4385e2cf88acSQuaker Fang sc->sc_config.ofdm_ht_dual_stream_basic_rates = 0xff; 4386e2cf88acSQuaker Fang sc->sc_config.ofdm_ht_single_stream_basic_rates = 0xff; 4387e2cf88acSQuaker Fang break; 4388e2cf88acSQuaker Fang case 2: 4389e2cf88acSQuaker Fang sc->sc_config.ofdm_ht_dual_stream_basic_rates = 0xff; 4390e2cf88acSQuaker Fang sc->sc_config.ofdm_ht_single_stream_basic_rates = 0xff; 4391e2cf88acSQuaker Fang break; 4392e2cf88acSQuaker Fang case 1: 4393e2cf88acSQuaker Fang sc->sc_config.ofdm_ht_single_stream_basic_rates = 0xff; 4394e2cf88acSQuaker Fang break; 4395e2cf88acSQuaker Fang default: 4396e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_config(): " 4397e2cf88acSQuaker Fang "RX stream count %d is not in suitable range\n", 4398e2cf88acSQuaker Fang sc->sc_ht_conf.rx_stream_count); 4399e2cf88acSQuaker Fang return (IWH_FAIL); 4400e2cf88acSQuaker Fang } 4401e2cf88acSQuaker Fang 4402e2cf88acSQuaker Fang /* 4403e2cf88acSQuaker Fang * set RX chains/antennas. 4404e2cf88acSQuaker Fang */ 4405e2cf88acSQuaker Fang iwh_config_rxon_chain(sc); 4406c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4407c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_cmd(sc, REPLY_RXON, &sc->sc_config, 4408c7ee0b5cSfei feng - Sun Microsystems - Beijing China sizeof (iwh_rxon_cmd_t), 0); 4409c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 4410c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_config(): " 4411c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to set configure command\n"); 4412c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 4413c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4414c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4415c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4416c7ee0b5cSfei feng - Sun Microsystems - Beijing China * remove all nodes in NIC 4417c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4418c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(&rm_sta, 0, sizeof (rm_sta)); 4419c7ee0b5cSfei feng - Sun Microsystems - Beijing China rm_sta.num_sta = 1; 442089b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(bcast, rm_sta.addr, 6); 4421c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4422c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_cmd(sc, REPLY_REMOVE_STA, &rm_sta, sizeof (iwh_rem_sta_t), 0); 4423c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 4424c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_config(): " 4425c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to remove broadcast node in hardware.\n"); 4426c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 4427c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4428c7ee0b5cSfei feng - Sun Microsystems - Beijing China 442989b2a9fbSfei feng - Sun Microsystems - Beijing China if ((sc->sc_dev_id != 0x423c) && 443089b2a9fbSfei feng - Sun Microsystems - Beijing China (sc->sc_dev_id != 0x423d)) { 4431c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4432e2cf88acSQuaker Fang * configure TX power table 4433c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4434c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_tx_power_table(sc, 0); 4435c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 4436c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 4437c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 443889b2a9fbSfei feng - Sun Microsystems - Beijing China } 4439c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4440c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4441c7ee0b5cSfei feng - Sun Microsystems - Beijing China * add broadcast node so that we can send broadcast frame 4442c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4443c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(&node, 0, sizeof (node)); 4444c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(node.sta.addr, 0xff, 6); 4445c7ee0b5cSfei feng - Sun Microsystems - Beijing China node.mode = 0; 4446c7ee0b5cSfei feng - Sun Microsystems - Beijing China node.sta.sta_id = IWH_BROADCAST_ID; 4447c7ee0b5cSfei feng - Sun Microsystems - Beijing China node.station_flags = 0; 4448c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4449c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_cmd(sc, REPLY_ADD_STA, &node, sizeof (node), 0); 4450c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 4451c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_config(): " 4452c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to add broadcast node\n"); 4453c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 4454c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4455c7ee0b5cSfei feng - Sun Microsystems - Beijing China 445689b2a9fbSfei feng - Sun Microsystems - Beijing China if ((sc->sc_dev_id != 0x423c) && 445789b2a9fbSfei feng - Sun Microsystems - Beijing China (sc->sc_dev_id != 0x423d)) { 4458c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4459c7ee0b5cSfei feng - Sun Microsystems - Beijing China * TX_LINK_QUALITY cmd 4460c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4461c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(&link_quality, 0, sizeof (link_quality)); 4462c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { 4463c7ee0b5cSfei feng - Sun Microsystems - Beijing China masks |= RATE_MCS_CCK_MSK; 4464c7ee0b5cSfei feng - Sun Microsystems - Beijing China masks |= RATE_MCS_ANT_B_MSK; 4465c7ee0b5cSfei feng - Sun Microsystems - Beijing China masks &= ~RATE_MCS_ANT_A_MSK; 4466b510adaeSfei feng - Sun Microsystems - Beijing China link_quality.rate_n_flags[i] = 4467b510adaeSfei feng - Sun Microsystems - Beijing China LE_32(iwh_rate_to_plcp(2) | masks); 4468c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4469c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4470c7ee0b5cSfei feng - Sun Microsystems - Beijing China link_quality.general_params.single_stream_ant_msk = 2; 4471c7ee0b5cSfei feng - Sun Microsystems - Beijing China link_quality.general_params.dual_stream_ant_msk = 3; 4472c7ee0b5cSfei feng - Sun Microsystems - Beijing China link_quality.agg_params.agg_dis_start_th = 3; 4473c7ee0b5cSfei feng - Sun Microsystems - Beijing China link_quality.agg_params.agg_time_limit = LE_16(4000); 4474c7ee0b5cSfei feng - Sun Microsystems - Beijing China link_quality.sta_id = IWH_BROADCAST_ID; 4475c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_cmd(sc, REPLY_TX_LINK_QUALITY_CMD, &link_quality, 4476c7ee0b5cSfei feng - Sun Microsystems - Beijing China sizeof (link_quality), 0); 4477c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 4478c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_config(): " 4479c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to config link quality table\n"); 4480c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 4481c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 448289b2a9fbSfei feng - Sun Microsystems - Beijing China } 4483c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4484e2cf88acSQuaker Fang return (err); 4485c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4486c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4487faceed93Sfei feng - Sun Microsystems - Beijing China /* 4488faceed93Sfei feng - Sun Microsystems - Beijing China * quiesce(9E) entry point. 4489faceed93Sfei feng - Sun Microsystems - Beijing China * This function is called when the system is single-threaded at high 4490faceed93Sfei feng - Sun Microsystems - Beijing China * PIL with preemption disabled. Therefore, this function must not be 4491faceed93Sfei feng - Sun Microsystems - Beijing China * blocked. 4492faceed93Sfei feng - Sun Microsystems - Beijing China * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 4493faceed93Sfei feng - Sun Microsystems - Beijing China * DDI_FAILURE indicates an error condition and should almost never happen. 4494faceed93Sfei feng - Sun Microsystems - Beijing China */ 4495faceed93Sfei feng - Sun Microsystems - Beijing China static int 4496faceed93Sfei feng - Sun Microsystems - Beijing China iwh_quiesce(dev_info_t *dip) 4497faceed93Sfei feng - Sun Microsystems - Beijing China { 4498faceed93Sfei feng - Sun Microsystems - Beijing China iwh_sc_t *sc; 4499faceed93Sfei feng - Sun Microsystems - Beijing China 4500faceed93Sfei feng - Sun Microsystems - Beijing China sc = ddi_get_soft_state(iwh_soft_state_p, ddi_get_instance(dip)); 4501e2cf88acSQuaker Fang if (sc == NULL) { 4502faceed93Sfei feng - Sun Microsystems - Beijing China return (DDI_FAILURE); 4503e2cf88acSQuaker Fang } 4504faceed93Sfei feng - Sun Microsystems - Beijing China 4505faceed93Sfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 450689b2a9fbSfei feng - Sun Microsystems - Beijing China /* 450789b2a9fbSfei feng - Sun Microsystems - Beijing China * by pass any messages, if it's quiesce 450889b2a9fbSfei feng - Sun Microsystems - Beijing China */ 4509faceed93Sfei feng - Sun Microsystems - Beijing China iwh_dbg_flags = 0; 4510faceed93Sfei feng - Sun Microsystems - Beijing China #endif 4511faceed93Sfei feng - Sun Microsystems - Beijing China 4512faceed93Sfei feng - Sun Microsystems - Beijing China /* 4513faceed93Sfei feng - Sun Microsystems - Beijing China * No more blocking is allowed while we are in the 4514faceed93Sfei feng - Sun Microsystems - Beijing China * quiesce(9E) entry point. 4515faceed93Sfei feng - Sun Microsystems - Beijing China */ 451689b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_or_32(&sc->sc_flags, IWH_F_QUIESCED); 4517faceed93Sfei feng - Sun Microsystems - Beijing China 4518faceed93Sfei feng - Sun Microsystems - Beijing China /* 4519faceed93Sfei feng - Sun Microsystems - Beijing China * Disable and mask all interrupts. 4520faceed93Sfei feng - Sun Microsystems - Beijing China */ 4521faceed93Sfei feng - Sun Microsystems - Beijing China iwh_stop(sc); 4522faceed93Sfei feng - Sun Microsystems - Beijing China 4523faceed93Sfei feng - Sun Microsystems - Beijing China return (DDI_SUCCESS); 4524faceed93Sfei feng - Sun Microsystems - Beijing China } 4525faceed93Sfei feng - Sun Microsystems - Beijing China 4526c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 4527c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_stop_master(iwh_sc_t *sc) 4528c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 4529c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t tmp; 4530c7ee0b5cSfei feng - Sun Microsystems - Beijing China int n; 4531c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4532c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_RESET); 4533c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_RESET, tmp | CSR_RESET_REG_FLAG_STOP_MASTER); 4534c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4535c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_GP_CNTRL); 4536c7ee0b5cSfei feng - Sun Microsystems - Beijing China if ((tmp & CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE) == 4537c7ee0b5cSfei feng - Sun Microsystems - Beijing China CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE) { 4538c7ee0b5cSfei feng - Sun Microsystems - Beijing China return; 4539c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4540c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4541c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (n = 0; n < 2000; n++) { 4542c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (IWH_READ(sc, CSR_RESET) & 4543c7ee0b5cSfei feng - Sun Microsystems - Beijing China CSR_RESET_REG_FLAG_MASTER_DISABLED) { 4544c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 4545c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4546c7ee0b5cSfei feng - Sun Microsystems - Beijing China DELAY(1000); 4547c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4548c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4549c7ee0b5cSfei feng - Sun Microsystems - Beijing China #ifdef DEBUG 4550c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (2000 == n) { 4551e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_HW, "iwh_stop_master(): " 4552c7ee0b5cSfei feng - Sun Microsystems - Beijing China "timeout waiting for master stop\n")); 4553c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4554c7ee0b5cSfei feng - Sun Microsystems - Beijing China #endif 4555c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4556c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4557c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 4558c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_power_up(iwh_sc_t *sc) 4559c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 4560c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t tmp; 4561c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4562c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_enter(sc); 4563c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = iwh_reg_read(sc, ALM_APMG_PS_CTL); 4564c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp &= ~APMG_PS_CTRL_REG_MSK_POWER_SRC; 4565c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp |= APMG_PS_CTRL_REG_VAL_POWER_SRC_VMAIN; 4566c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, ALM_APMG_PS_CTL, tmp); 4567c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_exit(sc); 4568c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4569c7ee0b5cSfei feng - Sun Microsystems - Beijing China DELAY(5000); 4570c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 4571c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4572c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4573c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4574c7ee0b5cSfei feng - Sun Microsystems - Beijing China * hardware initialization 4575c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4576c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 4577c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_preinit(iwh_sc_t *sc) 4578c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 4579c7ee0b5cSfei feng - Sun Microsystems - Beijing China int n; 4580c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint8_t vlink; 4581c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint16_t radio_cfg; 4582b510adaeSfei feng - Sun Microsystems - Beijing China uint32_t tmp; 4583c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4584c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4585c7ee0b5cSfei feng - Sun Microsystems - Beijing China * clear any pending interrupts 4586c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4587c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_INT, 0xffffffff); 4588c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4589c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_GIO_CHICKEN_BITS); 4590c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_GIO_CHICKEN_BITS, 4591c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); 4592c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4593c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_ANA_PLL_CFG); 4594c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_ANA_PLL_CFG, tmp | IWH_CSR_ANA_PLL_CFG); 4595c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4596c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_GP_CNTRL); 4597c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_GP_CNTRL, tmp | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 4598c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4599c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4600c7ee0b5cSfei feng - Sun Microsystems - Beijing China * wait for clock ready 4601c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4602c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (n = 0; n < 1000; n++) { 4603c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (IWH_READ(sc, CSR_GP_CNTRL) & 4604c7ee0b5cSfei feng - Sun Microsystems - Beijing China CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY) { 4605c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 4606c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4607c7ee0b5cSfei feng - Sun Microsystems - Beijing China DELAY(10); 4608c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4609c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4610c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (1000 == n) { 4611c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (ETIMEDOUT); 4612c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4613c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4614c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_enter(sc); 4615c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4616c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, ALM_APMG_CLK_EN, APMG_CLK_REG_VAL_DMA_CLK_RQT); 4617c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4618c7ee0b5cSfei feng - Sun Microsystems - Beijing China DELAY(20); 4619c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = iwh_reg_read(sc, ALM_APMG_PCIDEV_STT); 4620c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, ALM_APMG_PCIDEV_STT, tmp | 4621c7ee0b5cSfei feng - Sun Microsystems - Beijing China APMG_DEV_STATE_REG_VAL_L1_ACTIVE_DISABLE); 4622c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_exit(sc); 4623c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4624c7ee0b5cSfei feng - Sun Microsystems - Beijing China radio_cfg = IWH_READ_EEP_SHORT(sc, EEP_SP_RADIO_CONFIGURATION); 4625c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (SP_RADIO_TYPE_MSK(radio_cfg) < SP_RADIO_TYPE_MAX) { 4626c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_HW_IF_CONFIG_REG); 4627c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_HW_IF_CONFIG_REG, 4628c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp | SP_RADIO_TYPE_MSK(radio_cfg) | 4629c7ee0b5cSfei feng - Sun Microsystems - Beijing China SP_RADIO_STEP_MSK(radio_cfg) | 4630c7ee0b5cSfei feng - Sun Microsystems - Beijing China SP_RADIO_DASH_MSK(radio_cfg)); 4631c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { 4632c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_preinit(): " 4633c7ee0b5cSfei feng - Sun Microsystems - Beijing China "radio configuration information in eeprom is wrong\n"); 4634c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 4635c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4636c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4637c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4638c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_INT_COALESCING, 512 / 32); 4639c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4640c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) iwh_power_up(sc); 4641c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4642c7ee0b5cSfei feng - Sun Microsystems - Beijing China if ((sc->sc_rev & 0x80) == 0x80 && (sc->sc_rev & 0x7f) < 8) { 4643c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = ddi_get32(sc->sc_cfg_handle, 4644c7ee0b5cSfei feng - Sun Microsystems - Beijing China (uint32_t *)(sc->sc_cfg_base + 0xe8)); 4645c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_put32(sc->sc_cfg_handle, 4646c7ee0b5cSfei feng - Sun Microsystems - Beijing China (uint32_t *)(sc->sc_cfg_base + 0xe8), 4647c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp & ~(1 << 11)); 4648c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4649c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4650c7ee0b5cSfei feng - Sun Microsystems - Beijing China vlink = ddi_get8(sc->sc_cfg_handle, 4651c7ee0b5cSfei feng - Sun Microsystems - Beijing China (uint8_t *)(sc->sc_cfg_base + 0xf0)); 4652c7ee0b5cSfei feng - Sun Microsystems - Beijing China ddi_put8(sc->sc_cfg_handle, (uint8_t *)(sc->sc_cfg_base + 0xf0), 4653c7ee0b5cSfei feng - Sun Microsystems - Beijing China vlink & ~2); 4654c7ee0b5cSfei feng - Sun Microsystems - Beijing China 465589b2a9fbSfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_HW_IF_CONFIG_REG); 4656c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | 4657c7ee0b5cSfei feng - Sun Microsystems - Beijing China CSR_HW_IF_CONFIG_REG_BIT_MAC_SI; 4658c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_SW_VER, tmp); 4659c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4660c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4661c7ee0b5cSfei feng - Sun Microsystems - Beijing China * make sure power supply on each part of the hardware 4662c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4663c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_enter(sc); 4664c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = iwh_reg_read(sc, ALM_APMG_PS_CTL); 4665c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp |= APMG_PS_CTRL_REG_VAL_ALM_R_RESET_REQ; 4666c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, ALM_APMG_PS_CTL, tmp); 4667c7ee0b5cSfei feng - Sun Microsystems - Beijing China DELAY(5); 4668c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4669c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = iwh_reg_read(sc, ALM_APMG_PS_CTL); 4670c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp &= ~APMG_PS_CTRL_REG_VAL_ALM_R_RESET_REQ; 4671c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, ALM_APMG_PS_CTL, tmp); 4672c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_exit(sc); 4673c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4674c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 4675c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4676c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4677c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4678c7ee0b5cSfei feng - Sun Microsystems - Beijing China * set up semphore flag to own EEPROM 4679c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4680c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 4681c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_eep_sem_down(iwh_sc_t *sc) 4682c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 4683c7ee0b5cSfei feng - Sun Microsystems - Beijing China int count1, count2; 4684c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t tmp; 4685c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4686c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (count1 = 0; count1 < 1000; count1++) { 4687c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_HW_IF_CONFIG_REG); 4688c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_HW_IF_CONFIG_REG, 4689c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp | CSR_HW_IF_CONFIG_REG_EEP_SEM); 4690c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4691c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (count2 = 0; count2 < 2; count2++) { 4692c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (IWH_READ(sc, CSR_HW_IF_CONFIG_REG) & 4693c7ee0b5cSfei feng - Sun Microsystems - Beijing China CSR_HW_IF_CONFIG_REG_EEP_SEM) { 4694c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 4695c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4696c7ee0b5cSfei feng - Sun Microsystems - Beijing China DELAY(10000); 4697c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4698c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 469989b2a9fbSfei feng - Sun Microsystems - Beijing China 4700c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 4701c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4702c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4703c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4704c7ee0b5cSfei feng - Sun Microsystems - Beijing China * reset semphore flag to release EEPROM 4705c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4706c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 4707c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_eep_sem_up(iwh_sc_t *sc) 4708c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 4709c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t tmp; 4710c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4711c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_HW_IF_CONFIG_REG); 4712c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_HW_IF_CONFIG_REG, 4713c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp & (~CSR_HW_IF_CONFIG_REG_EEP_SEM)); 4714c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4715c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4716c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4717c7ee0b5cSfei feng - Sun Microsystems - Beijing China * This function read all infomation from eeprom 4718c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4719c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 4720c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_eep_load(iwh_sc_t *sc) 4721c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 4722c7ee0b5cSfei feng - Sun Microsystems - Beijing China int i, rr; 4723c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t rv, tmp, eep_gp; 4724c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint16_t addr, eep_sz = sizeof (sc->sc_eep_map); 4725c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint16_t *eep_p = (uint16_t *)&sc->sc_eep_map; 4726c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4727c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4728c7ee0b5cSfei feng - Sun Microsystems - Beijing China * read eeprom gp register in CSR 4729c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4730c7ee0b5cSfei feng - Sun Microsystems - Beijing China eep_gp = IWH_READ(sc, CSR_EEPROM_GP); 4731c7ee0b5cSfei feng - Sun Microsystems - Beijing China if ((eep_gp & CSR_EEPROM_GP_VALID_MSK) == 4732c7ee0b5cSfei feng - Sun Microsystems - Beijing China CSR_EEPROM_GP_BAD_SIGNATURE) { 4733e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_EEPROM, "iwh_eep_load(): " 4734e2cf88acSQuaker Fang "not find eeprom\n")); 4735c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 4736c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4737c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4738c7ee0b5cSfei feng - Sun Microsystems - Beijing China rr = iwh_eep_sem_down(sc); 4739c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (rr != 0) { 4740e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_EEPROM, "iwh_eep_load(): " 4741e2cf88acSQuaker Fang "driver failed to own EEPROM\n")); 4742c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 4743c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4744c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4745c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (addr = 0; addr < eep_sz; addr += 2) { 4746c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_EEPROM_REG, addr<<1); 4747c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_EEPROM_REG); 4748c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_EEPROM_REG, tmp & ~(0x2)); 4749c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4750c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (i = 0; i < 10; i++) { 4751c7ee0b5cSfei feng - Sun Microsystems - Beijing China rv = IWH_READ(sc, CSR_EEPROM_REG); 4752c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (rv & 1) { 4753c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 4754c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4755c7ee0b5cSfei feng - Sun Microsystems - Beijing China DELAY(10); 4756c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4757c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4758c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (!(rv & 1)) { 4759e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_EEPROM, "iwh_eep_load(): " 4760c7ee0b5cSfei feng - Sun Microsystems - Beijing China "time out when read eeprome\n")); 4761c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_eep_sem_up(sc); 4762c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 4763c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4764c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4765b510adaeSfei feng - Sun Microsystems - Beijing China eep_p[addr/2] = LE_16(rv >> 16); 4766c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4767c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4768c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_eep_sem_up(sc); 4769c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 4770c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4771c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4772c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4773c7ee0b5cSfei feng - Sun Microsystems - Beijing China * initialize mac address in ieee80211com_t struct 4774c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4775c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 4776c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_get_mac_from_eep(iwh_sc_t *sc) 4777c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 4778c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211com_t *ic = &sc->sc_ic; 4779c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4780c7ee0b5cSfei feng - Sun Microsystems - Beijing China IEEE80211_ADDR_COPY(ic->ic_macaddr, &sc->sc_eep_map[EEP_MAC_ADDRESS]); 4781c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4782e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_EEPROM, "iwh_get_mac_from_eep(): " 4783e2cf88acSQuaker Fang "mac:%2x:%2x:%2x:%2x:%2x:%2x\n", 4784c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[0], ic->ic_macaddr[1], ic->ic_macaddr[2], 4785c7ee0b5cSfei feng - Sun Microsystems - Beijing China ic->ic_macaddr[3], ic->ic_macaddr[4], ic->ic_macaddr[5])); 4786c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4787c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4788c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4789c7ee0b5cSfei feng - Sun Microsystems - Beijing China * main initialization function 4790c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4791c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 4792c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_init(iwh_sc_t *sc) 4793c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 4794e2cf88acSQuaker Fang int err = IWH_FAIL; 4795c7ee0b5cSfei feng - Sun Microsystems - Beijing China clock_t clk; 4796c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4797c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4798c7ee0b5cSfei feng - Sun Microsystems - Beijing China * release buffer for calibration 4799c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4800c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_release_calib_buffer(sc); 4801c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4802c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_glock); 480389b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_FW_INIT); 4804c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4805c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_init_common(sc); 4806c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 4807c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 4808c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 4809c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4810c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4811c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4812c7ee0b5cSfei feng - Sun Microsystems - Beijing China * backup ucode data part for future use. 4813c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 481489b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(sc->sc_dma_fw_data.mem_va, 481589b2a9fbSfei feng - Sun Microsystems - Beijing China sc->sc_dma_fw_data_bak.mem_va, 4816c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_dma_fw_data.alength); 4817c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4818c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* load firmware init segment into NIC */ 4819c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_load_init_firmware(sc); 4820c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 4821c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_init(): " 4822c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to setup init firmware\n"); 4823e2cf88acSQuaker Fang mutex_exit(&sc->sc_glock); 4824e2cf88acSQuaker Fang return (IWH_FAIL); 4825c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4826c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4827c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4828c7ee0b5cSfei feng - Sun Microsystems - Beijing China * now press "execute" start running 4829c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4830c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_RESET, 0); 4831c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4832c7ee0b5cSfei feng - Sun Microsystems - Beijing China clk = ddi_get_lbolt() + drv_usectohz(1000000); 4833c7ee0b5cSfei feng - Sun Microsystems - Beijing China while (!(sc->sc_flags & IWH_F_FW_INIT)) { 4834c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (cv_timedwait(&sc->sc_ucode_cv, 4835e2cf88acSQuaker Fang &sc->sc_glock, clk) < 0) { 4836c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 4837c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4838c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4839c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4840c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (!(sc->sc_flags & IWH_F_FW_INIT)) { 4841c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_init(): " 4842c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to process init alive.\n"); 4843e2cf88acSQuaker Fang mutex_exit(&sc->sc_glock); 4844c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 4845c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4846c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4847e2cf88acSQuaker Fang mutex_exit(&sc->sc_glock); 4848c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4849c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4850c7ee0b5cSfei feng - Sun Microsystems - Beijing China * stop chipset for initializing chipset again 4851c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4852c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_stop(sc); 4853c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4854c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_glock); 485589b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_FW_INIT); 4856c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4857c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_init_common(sc); 4858c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 4859c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 4860c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 4861c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4862c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4863c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4864c7ee0b5cSfei feng - Sun Microsystems - Beijing China * load firmware run segment into NIC 4865c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4866c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_load_run_firmware(sc); 4867c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 4868c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_init(): " 4869c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to setup run firmware\n"); 4870e2cf88acSQuaker Fang mutex_exit(&sc->sc_glock); 4871e2cf88acSQuaker Fang return (IWH_FAIL); 4872c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4873c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4874c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4875c7ee0b5cSfei feng - Sun Microsystems - Beijing China * now press "execute" start running 4876c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4877c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_RESET, 0); 4878c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4879c7ee0b5cSfei feng - Sun Microsystems - Beijing China clk = ddi_get_lbolt() + drv_usectohz(1000000); 4880c7ee0b5cSfei feng - Sun Microsystems - Beijing China while (!(sc->sc_flags & IWH_F_FW_INIT)) { 4881c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (cv_timedwait(&sc->sc_ucode_cv, 4882e2cf88acSQuaker Fang &sc->sc_glock, clk) < 0) { 4883c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 4884c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4885c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4886c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4887c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (!(sc->sc_flags & IWH_F_FW_INIT)) { 4888c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_init(): " 4889c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to process runtime alive.\n"); 4890e2cf88acSQuaker Fang mutex_exit(&sc->sc_glock); 4891c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 4892c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4893c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4894e2cf88acSQuaker Fang mutex_exit(&sc->sc_glock); 4895e2cf88acSQuaker Fang 4896e2cf88acSQuaker Fang DELAY(1000); 4897c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4898c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_glock); 489989b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_FW_INIT); 4900c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4901c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4902c7ee0b5cSfei feng - Sun Microsystems - Beijing China * at this point, the firmware is loaded OK, then config the hardware 4903c7ee0b5cSfei feng - Sun Microsystems - Beijing China * with the ucode API, including rxon, txpower, etc. 4904c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4905c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_config(sc); 4906c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err) { 4907c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_init(): " 4908c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to configure device\n"); 4909c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 4910c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 4911c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4912c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4913c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4914c7ee0b5cSfei feng - Sun Microsystems - Beijing China * at this point, hardware may receive beacons :) 4915c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4916c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 4917c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 4918c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4919c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4920c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4921c7ee0b5cSfei feng - Sun Microsystems - Beijing China * stop or disable NIC 4922c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4923c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 4924c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_stop(iwh_sc_t *sc) 4925c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 4926c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t tmp; 4927c7ee0b5cSfei feng - Sun Microsystems - Beijing China int i; 4928c7ee0b5cSfei feng - Sun Microsystems - Beijing China 492989b2a9fbSfei feng - Sun Microsystems - Beijing China /* 493089b2a9fbSfei feng - Sun Microsystems - Beijing China * by pass if it's quiesced 493189b2a9fbSfei feng - Sun Microsystems - Beijing China */ 4932e2cf88acSQuaker Fang if (!(sc->sc_flags & IWH_F_QUIESCED)) { 4933c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_enter(&sc->sc_glock); 4934e2cf88acSQuaker Fang } 4935c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4936c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); 4937c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4938c7ee0b5cSfei feng - Sun Microsystems - Beijing China * disable interrupts 4939c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4940c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_INT_MASK, 0); 4941c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_INT, CSR_INI_SET_MASK); 4942c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_FH_INT_STATUS, 0xffffffff); 4943c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4944c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4945c7ee0b5cSfei feng - Sun Microsystems - Beijing China * reset all Tx rings 4946c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4947c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (i = 0; i < IWH_NUM_QUEUES; i++) { 4948c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reset_tx_ring(sc, &sc->sc_txq[i]); 4949c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4950c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4951c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4952c7ee0b5cSfei feng - Sun Microsystems - Beijing China * reset Rx ring 4953c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4954c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reset_rx_ring(sc); 4955c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4956c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_enter(sc); 4957c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, ALM_APMG_CLK_DIS, APMG_CLK_REG_VAL_DMA_CLK_RQT); 4958c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_exit(sc); 4959c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4960c7ee0b5cSfei feng - Sun Microsystems - Beijing China DELAY(5); 4961c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4962c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_stop_master(sc); 4963c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4964e2cf88acSQuaker Fang mutex_enter(&sc->sc_mt_lock); 4965c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_tx_timer = 0; 4966e2cf88acSQuaker Fang mutex_exit(&sc->sc_mt_lock); 4967e2cf88acSQuaker Fang 4968c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_RESET); 4969c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_RESET, tmp | CSR_RESET_REG_FLAG_SW_RESET); 4970c7ee0b5cSfei feng - Sun Microsystems - Beijing China 497189b2a9fbSfei feng - Sun Microsystems - Beijing China /* 497289b2a9fbSfei feng - Sun Microsystems - Beijing China * by pass if it's quiesced 497389b2a9fbSfei feng - Sun Microsystems - Beijing China */ 4974e2cf88acSQuaker Fang if (!(sc->sc_flags & IWH_F_QUIESCED)) { 4975c7ee0b5cSfei feng - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 4976c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 4977e2cf88acSQuaker Fang } 4978c7ee0b5cSfei feng - Sun Microsystems - Beijing China 4979c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 4980c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Naive implementation of the Adaptive Multi Rate Retry algorithm: 4981c7ee0b5cSfei feng - Sun Microsystems - Beijing China * "IEEE 802.11 Rate Adaptation: A Practical Approach" 4982c7ee0b5cSfei feng - Sun Microsystems - Beijing China * Mathieu Lacage, Hossein Manshaei, Thierry Turletti 4983c7ee0b5cSfei feng - Sun Microsystems - Beijing China * INRIA Sophia - Projet Planete 4984c7ee0b5cSfei feng - Sun Microsystems - Beijing China * http://www-sop.inria.fr/rapports/sophia/RR-5208.html 4985c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 4986c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define is_success(amrr) \ 4987c7ee0b5cSfei feng - Sun Microsystems - Beijing China ((amrr)->retrycnt < (amrr)->txcnt / 10) 4988c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define is_failure(amrr) \ 4989c7ee0b5cSfei feng - Sun Microsystems - Beijing China ((amrr)->retrycnt > (amrr)->txcnt / 3) 4990c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define is_enough(amrr) \ 4991e2cf88acSQuaker Fang ((amrr)->txcnt > 200) 4992e2cf88acSQuaker Fang #define not_very_few(amrr) \ 4993e2cf88acSQuaker Fang ((amrr)->txcnt > 40) 4994c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define is_min_rate(in) \ 4995c7ee0b5cSfei feng - Sun Microsystems - Beijing China (0 == (in)->in_txrate) 4996c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define is_max_rate(in) \ 4997c7ee0b5cSfei feng - Sun Microsystems - Beijing China ((in)->in_rates.ir_nrates - 1 == (in)->in_txrate) 4998c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define increase_rate(in) \ 4999c7ee0b5cSfei feng - Sun Microsystems - Beijing China ((in)->in_txrate++) 5000c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define decrease_rate(in) \ 5001c7ee0b5cSfei feng - Sun Microsystems - Beijing China ((in)->in_txrate--) 5002c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define reset_cnt(amrr) \ 5003c7ee0b5cSfei feng - Sun Microsystems - Beijing China { (amrr)->txcnt = (amrr)->retrycnt = 0; } 5004c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5005c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_AMRR_MIN_SUCCESS_THRESHOLD 1 5006c7ee0b5cSfei feng - Sun Microsystems - Beijing China #define IWH_AMRR_MAX_SUCCESS_THRESHOLD 15 5007c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5008c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 5009c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_amrr_init(iwh_amrr_t *amrr) 5010c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 5011c7ee0b5cSfei feng - Sun Microsystems - Beijing China amrr->success = 0; 5012c7ee0b5cSfei feng - Sun Microsystems - Beijing China amrr->recovery = 0; 5013c7ee0b5cSfei feng - Sun Microsystems - Beijing China amrr->txcnt = amrr->retrycnt = 0; 5014c7ee0b5cSfei feng - Sun Microsystems - Beijing China amrr->success_threshold = IWH_AMRR_MIN_SUCCESS_THRESHOLD; 5015e2cf88acSQuaker Fang amrr->ht_mcs_idx = 0; /* 6Mbps */ 5016c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5017c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5018c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 5019c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_amrr_timeout(iwh_sc_t *sc) 5020c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 5021c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211com_t *ic = &sc->sc_ic; 5022c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5023e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_RATECTL, "iwh_amrr_timeout(): " 5024e2cf88acSQuaker Fang "enter\n")); 5025c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5026c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (IEEE80211_M_STA == ic->ic_opmode) { 5027c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_amrr_ratectl(NULL, ic->ic_bss); 5028c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { 5029c7ee0b5cSfei feng - Sun Microsystems - Beijing China ieee80211_iterate_nodes(&ic->ic_sta, iwh_amrr_ratectl, NULL); 5030c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5031c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5032c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_clk = ddi_get_lbolt(); 5033c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5034c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5035e2cf88acSQuaker Fang static int 5036e2cf88acSQuaker Fang iwh_is_max_rate(ieee80211_node_t *in) 5037e2cf88acSQuaker Fang { 5038e2cf88acSQuaker Fang int i; 5039e2cf88acSQuaker Fang iwh_amrr_t *amrr = (iwh_amrr_t *)in; 5040e2cf88acSQuaker Fang uint8_t r = (uint8_t)amrr->ht_mcs_idx; 5041e2cf88acSQuaker Fang ieee80211com_t *ic = in->in_ic; 5042e2cf88acSQuaker Fang iwh_sc_t *sc = (iwh_sc_t *)ic; 5043e2cf88acSQuaker Fang 5044e2cf88acSQuaker Fang if (in->in_flags & IEEE80211_NODE_HT) { 5045e2cf88acSQuaker Fang for (i = in->in_htrates.rs_nrates - 1; i >= 0; i--) { 5046e2cf88acSQuaker Fang r = in->in_htrates.rs_rates[i] & 5047e2cf88acSQuaker Fang IEEE80211_RATE_VAL; 5048e2cf88acSQuaker Fang if (sc->sc_ht_conf.tx_support_mcs[r/8] & 5049e2cf88acSQuaker Fang (1 << (r%8))) { 5050e2cf88acSQuaker Fang break; 5051e2cf88acSQuaker Fang } 5052e2cf88acSQuaker Fang } 5053e2cf88acSQuaker Fang 5054e2cf88acSQuaker Fang return (r == (uint8_t)amrr->ht_mcs_idx); 5055e2cf88acSQuaker Fang } else { 5056e2cf88acSQuaker Fang return (is_max_rate(in)); 5057e2cf88acSQuaker Fang } 5058e2cf88acSQuaker Fang } 5059e2cf88acSQuaker Fang 5060e2cf88acSQuaker Fang static int 5061e2cf88acSQuaker Fang iwh_is_min_rate(ieee80211_node_t *in) 5062e2cf88acSQuaker Fang { 5063e2cf88acSQuaker Fang int i; 5064e2cf88acSQuaker Fang uint8_t r = 0; 5065e2cf88acSQuaker Fang iwh_amrr_t *amrr = (iwh_amrr_t *)in; 5066e2cf88acSQuaker Fang ieee80211com_t *ic = in->in_ic; 5067e2cf88acSQuaker Fang iwh_sc_t *sc = (iwh_sc_t *)ic; 5068e2cf88acSQuaker Fang 5069e2cf88acSQuaker Fang if (in->in_flags & IEEE80211_NODE_HT) { 5070e2cf88acSQuaker Fang for (i = 0; i < in->in_htrates.rs_nrates; i++) { 5071e2cf88acSQuaker Fang r = in->in_htrates.rs_rates[i] & 5072e2cf88acSQuaker Fang IEEE80211_RATE_VAL; 5073e2cf88acSQuaker Fang if (sc->sc_ht_conf.tx_support_mcs[r/8] & 5074e2cf88acSQuaker Fang (1 << (r%8))) { 5075e2cf88acSQuaker Fang break; 5076e2cf88acSQuaker Fang } 5077e2cf88acSQuaker Fang } 5078e2cf88acSQuaker Fang 5079e2cf88acSQuaker Fang return (r == (uint8_t)amrr->ht_mcs_idx); 5080e2cf88acSQuaker Fang } else { 5081e2cf88acSQuaker Fang return (is_min_rate(in)); 5082e2cf88acSQuaker Fang } 5083e2cf88acSQuaker Fang } 5084e2cf88acSQuaker Fang 5085c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 5086e2cf88acSQuaker Fang iwh_increase_rate(ieee80211_node_t *in) 5087e2cf88acSQuaker Fang { 5088e2cf88acSQuaker Fang int i; 5089e2cf88acSQuaker Fang uint8_t r; 5090e2cf88acSQuaker Fang iwh_amrr_t *amrr = (iwh_amrr_t *)in; 5091e2cf88acSQuaker Fang ieee80211com_t *ic = in->in_ic; 5092e2cf88acSQuaker Fang iwh_sc_t *sc = (iwh_sc_t *)ic; 5093e2cf88acSQuaker Fang 5094e2cf88acSQuaker Fang if (in->in_flags & IEEE80211_NODE_HT) { 5095e2cf88acSQuaker Fang again: 5096e2cf88acSQuaker Fang amrr->ht_mcs_idx++; 5097e2cf88acSQuaker Fang 5098e2cf88acSQuaker Fang for (i = 0; i < in->in_htrates.rs_nrates; i++) { 5099e2cf88acSQuaker Fang r = in->in_htrates.rs_rates[i] & 5100e2cf88acSQuaker Fang IEEE80211_RATE_VAL; 5101e2cf88acSQuaker Fang if ((r == (uint8_t)amrr->ht_mcs_idx) && 5102e2cf88acSQuaker Fang (sc->sc_ht_conf.tx_support_mcs[r/8] & 5103e2cf88acSQuaker Fang (1 << (r%8)))) { 5104e2cf88acSQuaker Fang break; 5105e2cf88acSQuaker Fang } 5106e2cf88acSQuaker Fang } 5107e2cf88acSQuaker Fang 5108e2cf88acSQuaker Fang if (i >= in->in_htrates.rs_nrates) { 5109e2cf88acSQuaker Fang goto again; 5110e2cf88acSQuaker Fang } 5111e2cf88acSQuaker Fang } else { 5112e2cf88acSQuaker Fang increase_rate(in); 5113e2cf88acSQuaker Fang } 5114e2cf88acSQuaker Fang } 5115e2cf88acSQuaker Fang 5116e2cf88acSQuaker Fang static void 5117e2cf88acSQuaker Fang iwh_decrease_rate(ieee80211_node_t *in) 5118e2cf88acSQuaker Fang { 5119e2cf88acSQuaker Fang int i; 5120e2cf88acSQuaker Fang uint8_t r; 5121e2cf88acSQuaker Fang iwh_amrr_t *amrr = (iwh_amrr_t *)in; 5122e2cf88acSQuaker Fang ieee80211com_t *ic = in->in_ic; 5123e2cf88acSQuaker Fang iwh_sc_t *sc = (iwh_sc_t *)ic; 5124e2cf88acSQuaker Fang 5125e2cf88acSQuaker Fang if (in->in_flags & IEEE80211_NODE_HT) { 5126e2cf88acSQuaker Fang again: 5127e2cf88acSQuaker Fang amrr->ht_mcs_idx--; 5128e2cf88acSQuaker Fang 5129e2cf88acSQuaker Fang for (i = 0; i < in->in_htrates.rs_nrates; i++) { 5130e2cf88acSQuaker Fang r = in->in_htrates.rs_rates[i] & 5131e2cf88acSQuaker Fang IEEE80211_RATE_VAL; 5132e2cf88acSQuaker Fang if ((r == (uint8_t)amrr->ht_mcs_idx) && 5133e2cf88acSQuaker Fang (sc->sc_ht_conf.tx_support_mcs[r/8] & 5134e2cf88acSQuaker Fang (1 << (r%8)))) { 5135e2cf88acSQuaker Fang break; 5136e2cf88acSQuaker Fang } 5137e2cf88acSQuaker Fang } 5138e2cf88acSQuaker Fang 5139e2cf88acSQuaker Fang if (i >= in->in_htrates.rs_nrates) { 5140e2cf88acSQuaker Fang goto again; 5141e2cf88acSQuaker Fang } 5142e2cf88acSQuaker Fang } else { 5143e2cf88acSQuaker Fang decrease_rate(in); 5144e2cf88acSQuaker Fang } 5145e2cf88acSQuaker Fang } 5146e2cf88acSQuaker Fang 5147e2cf88acSQuaker Fang /* ARGSUSED */ 5148e2cf88acSQuaker Fang static void 5149c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_amrr_ratectl(void *arg, ieee80211_node_t *in) 5150c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 5151c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_amrr_t *amrr = (iwh_amrr_t *)in; 5152c7ee0b5cSfei feng - Sun Microsystems - Beijing China int need_change = 0; 5153c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5154c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (is_success(amrr) && is_enough(amrr)) { 5155c7ee0b5cSfei feng - Sun Microsystems - Beijing China amrr->success++; 5156c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (amrr->success >= amrr->success_threshold && 5157e2cf88acSQuaker Fang !iwh_is_max_rate(in)) { 5158c7ee0b5cSfei feng - Sun Microsystems - Beijing China amrr->recovery = 1; 5159c7ee0b5cSfei feng - Sun Microsystems - Beijing China amrr->success = 0; 5160e2cf88acSQuaker Fang iwh_increase_rate(in); 5161e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_RATECTL, "iwh_amrr_ratectl(): " 5162e2cf88acSQuaker Fang "AMRR increasing rate %d " 5163e2cf88acSQuaker Fang "(txcnt=%d retrycnt=%d), mcs_idx=%d\n", 5164e2cf88acSQuaker Fang in->in_txrate, amrr->txcnt, 5165e2cf88acSQuaker Fang amrr->retrycnt, amrr->ht_mcs_idx)); 5166c7ee0b5cSfei feng - Sun Microsystems - Beijing China need_change = 1; 5167c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { 5168c7ee0b5cSfei feng - Sun Microsystems - Beijing China amrr->recovery = 0; 5169c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5170e2cf88acSQuaker Fang } else if (not_very_few(amrr) && is_failure(amrr)) { 5171c7ee0b5cSfei feng - Sun Microsystems - Beijing China amrr->success = 0; 5172e2cf88acSQuaker Fang if (!iwh_is_min_rate(in)) { 5173c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (amrr->recovery) { 5174c7ee0b5cSfei feng - Sun Microsystems - Beijing China amrr->success_threshold++; 5175c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (amrr->success_threshold > 5176c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_AMRR_MAX_SUCCESS_THRESHOLD) { 5177c7ee0b5cSfei feng - Sun Microsystems - Beijing China amrr->success_threshold = 5178c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_AMRR_MAX_SUCCESS_THRESHOLD; 5179c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5180c7ee0b5cSfei feng - Sun Microsystems - Beijing China } else { 5181c7ee0b5cSfei feng - Sun Microsystems - Beijing China amrr->success_threshold = 5182c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_AMRR_MIN_SUCCESS_THRESHOLD; 5183c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5184e2cf88acSQuaker Fang iwh_decrease_rate(in); 5185e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_RATECTL, "iwh_amrr_ratectl(): " 5186e2cf88acSQuaker Fang "AMRR decreasing rate %d " 5187e2cf88acSQuaker Fang "(txcnt=%d retrycnt=%d), mcs_idx=%d\n", 5188e2cf88acSQuaker Fang in->in_txrate, amrr->txcnt, 5189e2cf88acSQuaker Fang amrr->retrycnt, amrr->ht_mcs_idx)); 5190c7ee0b5cSfei feng - Sun Microsystems - Beijing China need_change = 1; 5191c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5192c7ee0b5cSfei feng - Sun Microsystems - Beijing China amrr->recovery = 0; /* paper is incorrect */ 5193c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5194c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5195c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (is_enough(amrr) || need_change) { 5196c7ee0b5cSfei feng - Sun Microsystems - Beijing China reset_cnt(amrr); 5197c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5198c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5199c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5200c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5201c7ee0b5cSfei feng - Sun Microsystems - Beijing China * translate indirect address in eeprom to direct address 5202c7ee0b5cSfei feng - Sun Microsystems - Beijing China * in eeprom and return address of entry whos indirect address 5203c7ee0b5cSfei feng - Sun Microsystems - Beijing China * is indi_addr 5204c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5205c7ee0b5cSfei feng - Sun Microsystems - Beijing China static uint8_t * 5206c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_eep_addr_trans(iwh_sc_t *sc, uint32_t indi_addr) 5207c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 5208c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t di_addr; 5209c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint16_t temp; 5210c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5211c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (!(indi_addr & INDIRECT_ADDRESS)) { 5212c7ee0b5cSfei feng - Sun Microsystems - Beijing China di_addr = indi_addr; 5213c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (&sc->sc_eep_map[di_addr]); 5214c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5215c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5216c7ee0b5cSfei feng - Sun Microsystems - Beijing China switch (indi_addr & INDIRECT_TYPE_MSK) { 5217c7ee0b5cSfei feng - Sun Microsystems - Beijing China case INDIRECT_GENERAL: 5218c7ee0b5cSfei feng - Sun Microsystems - Beijing China temp = IWH_READ_EEP_SHORT(sc, EEP_LINK_GENERAL); 5219c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 5220c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5221c7ee0b5cSfei feng - Sun Microsystems - Beijing China case INDIRECT_HOST: 5222c7ee0b5cSfei feng - Sun Microsystems - Beijing China temp = IWH_READ_EEP_SHORT(sc, EEP_LINK_HOST); 5223c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 5224c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5225c7ee0b5cSfei feng - Sun Microsystems - Beijing China case INDIRECT_REGULATORY: 5226c7ee0b5cSfei feng - Sun Microsystems - Beijing China temp = IWH_READ_EEP_SHORT(sc, EEP_LINK_REGULATORY); 5227c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 5228c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5229c7ee0b5cSfei feng - Sun Microsystems - Beijing China case INDIRECT_CALIBRATION: 5230c7ee0b5cSfei feng - Sun Microsystems - Beijing China temp = IWH_READ_EEP_SHORT(sc, EEP_LINK_CALIBRATION); 5231c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 5232c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5233c7ee0b5cSfei feng - Sun Microsystems - Beijing China case INDIRECT_PROCESS_ADJST: 5234c7ee0b5cSfei feng - Sun Microsystems - Beijing China temp = IWH_READ_EEP_SHORT(sc, EEP_LINK_PROCESS_ADJST); 5235c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 5236c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5237c7ee0b5cSfei feng - Sun Microsystems - Beijing China case INDIRECT_OTHERS: 5238c7ee0b5cSfei feng - Sun Microsystems - Beijing China temp = IWH_READ_EEP_SHORT(sc, EEP_LINK_OTHERS); 5239c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 5240c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5241c7ee0b5cSfei feng - Sun Microsystems - Beijing China default: 5242c7ee0b5cSfei feng - Sun Microsystems - Beijing China temp = 0; 5243c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_eep_addr_trans(): " 5244c7ee0b5cSfei feng - Sun Microsystems - Beijing China "incorrect indirect eeprom address.\n"); 5245c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 5246c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5247c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5248c7ee0b5cSfei feng - Sun Microsystems - Beijing China di_addr = (indi_addr & ADDRESS_MSK) + (temp << 1); 5249c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5250c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (&sc->sc_eep_map[di_addr]); 5251c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5252c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5253c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5254c7ee0b5cSfei feng - Sun Microsystems - Beijing China * loade a section of ucode into NIC 5255c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5256c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 5257c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_put_seg_fw(iwh_sc_t *sc, uint32_t addr_s, uint32_t addr_d, uint32_t len) 5258c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 5259c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5260c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_enter(sc); 5261c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5262c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, IWH_FH_TCSR_CHNL_TX_CONFIG_REG(IWH_FH_SRVC_CHNL), 5263c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); 5264c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5265c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, IWH_FH_SRVC_CHNL_SRAM_ADDR_REG(IWH_FH_SRVC_CHNL), addr_d); 5266c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5267c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, IWH_FH_TFDIB_CTRL0_REG(IWH_FH_SRVC_CHNL), 5268c7ee0b5cSfei feng - Sun Microsystems - Beijing China (addr_s & FH_MEM_TFDIB_DRAM_ADDR_LSB_MASK)); 5269c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5270c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, IWH_FH_TFDIB_CTRL1_REG(IWH_FH_SRVC_CHNL), len); 5271c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5272c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, IWH_FH_TCSR_CHNL_TX_BUF_STS_REG(IWH_FH_SRVC_CHNL), 5273c7ee0b5cSfei feng - Sun Microsystems - Beijing China (1 << IWH_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM) | 5274c7ee0b5cSfei feng - Sun Microsystems - Beijing China (1 << IWH_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX) | 5275c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); 5276c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5277c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, IWH_FH_TCSR_CHNL_TX_CONFIG_REG(IWH_FH_SRVC_CHNL), 5278c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | 5279c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL | 5280c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); 5281c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5282c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_exit(sc); 5283c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5284c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 5285c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5286c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5287c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5288c7ee0b5cSfei feng - Sun Microsystems - Beijing China * necessary setting during alive notification 5289c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5290c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 5291c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_alive_common(iwh_sc_t *sc) 5292c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 5293c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t base; 5294c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t i; 5295c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_wimax_coex_cmd_t w_cmd; 5296c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_calibration_crystal_cmd_t c_cmd; 5297e2cf88acSQuaker Fang uint32_t rv = IWH_FAIL; 5298c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5299c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5300c7ee0b5cSfei feng - Sun Microsystems - Beijing China * initialize SCD related registers to make TX work. 5301c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5302c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_enter(sc); 5303c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5304c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5305c7ee0b5cSfei feng - Sun Microsystems - Beijing China * read sram address of data base. 5306c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5307c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_scd_base = iwh_reg_read(sc, IWH_SCD_SRAM_BASE_ADDR); 5308c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5309c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (base = sc->sc_scd_base + IWH_SCD_CONTEXT_DATA_OFFSET; 5310c7ee0b5cSfei feng - Sun Microsystems - Beijing China base < sc->sc_scd_base + IWH_SCD_TX_STTS_BITMAP_OFFSET; 5311c7ee0b5cSfei feng - Sun Microsystems - Beijing China base += 4) { 5312c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mem_write(sc, base, 0); 5313c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5314c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5315c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (; base < sc->sc_scd_base + IWH_SCD_TRANSLATE_TBL_OFFSET; 5316c7ee0b5cSfei feng - Sun Microsystems - Beijing China base += 4) { 5317c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mem_write(sc, base, 0); 5318c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5319c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5320c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (i = 0; i < sizeof (uint16_t) * IWH_NUM_QUEUES; i += 4) { 5321c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mem_write(sc, base + i, 0); 5322c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5323c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5324c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, IWH_SCD_DRAM_BASE_ADDR, 5325c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_dma_sh.cookie.dmac_address >> 10); 5326c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5327c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, IWH_SCD_QUEUECHAIN_SEL, 5328c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_SCD_QUEUECHAIN_SEL_ALL(IWH_NUM_QUEUES)); 5329c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5330c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, IWH_SCD_AGGR_SEL, 0); 5331c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5332c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (i = 0; i < IWH_NUM_QUEUES; i++) { 5333c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, IWH_SCD_QUEUE_RDPTR(i), 0); 5334c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, HBUS_TARG_WRPTR, 0 | (i << 8)); 5335c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mem_write(sc, sc->sc_scd_base + 5336c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_SCD_CONTEXT_QUEUE_OFFSET(i), 0); 5337c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mem_write(sc, sc->sc_scd_base + 5338c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_SCD_CONTEXT_QUEUE_OFFSET(i) + 5339c7ee0b5cSfei feng - Sun Microsystems - Beijing China sizeof (uint32_t), 5340c7ee0b5cSfei feng - Sun Microsystems - Beijing China ((SCD_WIN_SIZE << IWH_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & 5341c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | 5342c7ee0b5cSfei feng - Sun Microsystems - Beijing China ((SCD_FRAME_LIMIT << 5343c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & 5344c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); 5345c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5346c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5347c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, IWH_SCD_INTERRUPT_MASK, (1 << IWH_NUM_QUEUES) - 1); 5348c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5349c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, (IWH_SCD_BASE + 0x10), 5350c7ee0b5cSfei feng - Sun Microsystems - Beijing China SCD_TXFACT_REG_TXFIFO_MASK(0, 7)); 5351c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5352c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, HBUS_TARG_WRPTR, (IWH_CMD_QUEUE_NUM << 8)); 5353c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, IWH_SCD_QUEUE_RDPTR(IWH_CMD_QUEUE_NUM), 0); 5354c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5355c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5356c7ee0b5cSfei feng - Sun Microsystems - Beijing China * queue 0-7 map to FIFO 0-7 and 5357c7ee0b5cSfei feng - Sun Microsystems - Beijing China * all queues work under FIFO mode(none-scheduler_ack) 5358c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5359c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (i = 0; i < 4; i++) { 5360c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, IWH_SCD_QUEUE_STATUS_BITS(i), 5361c7ee0b5cSfei feng - Sun Microsystems - Beijing China (1 << IWH_SCD_QUEUE_STTS_REG_POS_ACTIVE) | 5362c7ee0b5cSfei feng - Sun Microsystems - Beijing China ((3-i) << IWH_SCD_QUEUE_STTS_REG_POS_TXF) | 5363c7ee0b5cSfei feng - Sun Microsystems - Beijing China (1 << IWH_SCD_QUEUE_STTS_REG_POS_WSL) | 5364c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_SCD_QUEUE_STTS_REG_MSK); 5365c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5366c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5367c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, IWH_SCD_QUEUE_STATUS_BITS(IWH_CMD_QUEUE_NUM), 5368c7ee0b5cSfei feng - Sun Microsystems - Beijing China (1 << IWH_SCD_QUEUE_STTS_REG_POS_ACTIVE) | 5369c7ee0b5cSfei feng - Sun Microsystems - Beijing China (IWH_CMD_FIFO_NUM << IWH_SCD_QUEUE_STTS_REG_POS_TXF) | 5370c7ee0b5cSfei feng - Sun Microsystems - Beijing China (1 << IWH_SCD_QUEUE_STTS_REG_POS_WSL) | 5371c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_SCD_QUEUE_STTS_REG_MSK); 5372c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5373c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (i = 5; i < 7; i++) { 5374c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, IWH_SCD_QUEUE_STATUS_BITS(i), 5375c7ee0b5cSfei feng - Sun Microsystems - Beijing China (1 << IWH_SCD_QUEUE_STTS_REG_POS_ACTIVE) | 5376c7ee0b5cSfei feng - Sun Microsystems - Beijing China (i << IWH_SCD_QUEUE_STTS_REG_POS_TXF) | 5377c7ee0b5cSfei feng - Sun Microsystems - Beijing China (1 << IWH_SCD_QUEUE_STTS_REG_POS_WSL) | 5378c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_SCD_QUEUE_STTS_REG_MSK); 5379c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5380c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5381c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_exit(sc); 5382c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5383c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(&w_cmd, 0, sizeof (w_cmd)); 5384c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5385c7ee0b5cSfei feng - Sun Microsystems - Beijing China rv = iwh_cmd(sc, COEX_PRIORITY_TABLE_CMD, &w_cmd, sizeof (w_cmd), 1); 5386c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (rv != IWH_SUCCESS) { 5387c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_alive_common(): " 5388c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to send wimax coexist command.\n"); 5389c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (rv); 5390c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5391c7ee0b5cSfei feng - Sun Microsystems - Beijing China 539289b2a9fbSfei feng - Sun Microsystems - Beijing China if ((sc->sc_dev_id != 0x423c) && 539389b2a9fbSfei feng - Sun Microsystems - Beijing China (sc->sc_dev_id != 0x423d)) { 5394c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(&c_cmd, 0, sizeof (c_cmd)); 5395c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5396c7ee0b5cSfei feng - Sun Microsystems - Beijing China c_cmd.opCode = PHY_CALIBRATE_CRYSTAL_FRQ_CMD; 5397b510adaeSfei feng - Sun Microsystems - Beijing China c_cmd.data.cap_pin1 = LE_16(sc->sc_eep_calib->xtal_calib[0]); 5398b510adaeSfei feng - Sun Microsystems - Beijing China c_cmd.data.cap_pin2 = LE_16(sc->sc_eep_calib->xtal_calib[1]); 5399c7ee0b5cSfei feng - Sun Microsystems - Beijing China 540089b2a9fbSfei feng - Sun Microsystems - Beijing China rv = iwh_cmd(sc, REPLY_PHY_CALIBRATION_CMD, 540189b2a9fbSfei feng - Sun Microsystems - Beijing China &c_cmd, sizeof (c_cmd), 1); 5402c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (rv != IWH_SUCCESS) { 5403c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_alive_common(): " 540489b2a9fbSfei feng - Sun Microsystems - Beijing China "failed to send crystal" 540589b2a9fbSfei feng - Sun Microsystems - Beijing China "frq calibration command.\n"); 5406c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (rv); 5407c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5408c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5409c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5410c7ee0b5cSfei feng - Sun Microsystems - Beijing China * make sure crystal frequency calibration ready 5411c7ee0b5cSfei feng - Sun Microsystems - Beijing China * before next operations. 5412c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5413c7ee0b5cSfei feng - Sun Microsystems - Beijing China DELAY(1000); 541489b2a9fbSfei feng - Sun Microsystems - Beijing China } 5415c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5416c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 5417c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5418c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5419c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5420c7ee0b5cSfei feng - Sun Microsystems - Beijing China * save results of calibration from ucode 5421c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5422c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 5423c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_save_calib_result(iwh_sc_t *sc, iwh_rx_desc_t *desc) 5424c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 5425c7ee0b5cSfei feng - Sun Microsystems - Beijing China struct iwh_calib_results *res_p = &sc->sc_calib_results; 5426c7ee0b5cSfei feng - Sun Microsystems - Beijing China struct iwh_calib_hdr *calib_hdr = (struct iwh_calib_hdr *)(desc + 1); 5427b510adaeSfei feng - Sun Microsystems - Beijing China int len = LE_32(desc->len); 5428c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5429c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5430c7ee0b5cSfei feng - Sun Microsystems - Beijing China * ensure the size of buffer is not too big 5431c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5432c7ee0b5cSfei feng - Sun Microsystems - Beijing China len = (len & FH_RSCSR_FRAME_SIZE_MASK) - 4; 5433c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5434c7ee0b5cSfei feng - Sun Microsystems - Beijing China switch (calib_hdr->op_code) { 5435c7ee0b5cSfei feng - Sun Microsystems - Beijing China case PHY_CALIBRATE_LO_CMD: 5436c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (NULL == res_p->lo_res) { 5437c7ee0b5cSfei feng - Sun Microsystems - Beijing China res_p->lo_res = kmem_alloc(len, KM_NOSLEEP); 5438c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5439c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5440c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (NULL == res_p->lo_res) { 5441c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_save_calib_result(): " 5442c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to allocate memory.\n"); 5443c7ee0b5cSfei feng - Sun Microsystems - Beijing China return; 5444c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5445c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5446c7ee0b5cSfei feng - Sun Microsystems - Beijing China res_p->lo_res_len = len; 544789b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(calib_hdr, res_p->lo_res, len); 5448c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 5449c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5450c7ee0b5cSfei feng - Sun Microsystems - Beijing China case PHY_CALIBRATE_TX_IQ_CMD: 5451c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (NULL == res_p->tx_iq_res) { 5452c7ee0b5cSfei feng - Sun Microsystems - Beijing China res_p->tx_iq_res = kmem_alloc(len, KM_NOSLEEP); 5453c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5454c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5455c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (NULL == res_p->tx_iq_res) { 5456c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_save_calib_result(): " 5457c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to allocate memory.\n"); 5458c7ee0b5cSfei feng - Sun Microsystems - Beijing China return; 5459c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5460c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5461c7ee0b5cSfei feng - Sun Microsystems - Beijing China res_p->tx_iq_res_len = len; 546289b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(calib_hdr, res_p->tx_iq_res, len); 5463c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 5464c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5465c7ee0b5cSfei feng - Sun Microsystems - Beijing China case PHY_CALIBRATE_TX_IQ_PERD_CMD: 5466c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (NULL == res_p->tx_iq_perd_res) { 5467c7ee0b5cSfei feng - Sun Microsystems - Beijing China res_p->tx_iq_perd_res = kmem_alloc(len, KM_NOSLEEP); 5468c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5469c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5470c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (NULL == res_p->tx_iq_perd_res) { 5471c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_save_calib_result(): " 5472c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to allocate memory.\n"); 54737d483bc1Sfei feng - Sun Microsystems - Beijing China return; 5474c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5475c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5476c7ee0b5cSfei feng - Sun Microsystems - Beijing China res_p->tx_iq_perd_res_len = len; 547789b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(calib_hdr, res_p->tx_iq_perd_res, len); 547889b2a9fbSfei feng - Sun Microsystems - Beijing China break; 547989b2a9fbSfei feng - Sun Microsystems - Beijing China 548089b2a9fbSfei feng - Sun Microsystems - Beijing China case PHY_CALIBRATE_DC_CMD: 548189b2a9fbSfei feng - Sun Microsystems - Beijing China if (NULL == res_p->dc_res) { 548289b2a9fbSfei feng - Sun Microsystems - Beijing China res_p->dc_res = kmem_alloc(len, KM_NOSLEEP); 548389b2a9fbSfei feng - Sun Microsystems - Beijing China } 548489b2a9fbSfei feng - Sun Microsystems - Beijing China 548589b2a9fbSfei feng - Sun Microsystems - Beijing China if (NULL == res_p->dc_res) { 548689b2a9fbSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_save_calib_result(): " 548789b2a9fbSfei feng - Sun Microsystems - Beijing China "failed to allocate memory.\n"); 54887d483bc1Sfei feng - Sun Microsystems - Beijing China return; 548989b2a9fbSfei feng - Sun Microsystems - Beijing China } 549089b2a9fbSfei feng - Sun Microsystems - Beijing China 549189b2a9fbSfei feng - Sun Microsystems - Beijing China res_p->dc_res_len = len; 549289b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(calib_hdr, res_p->dc_res, len); 549389b2a9fbSfei feng - Sun Microsystems - Beijing China break; 549489b2a9fbSfei feng - Sun Microsystems - Beijing China 549589b2a9fbSfei feng - Sun Microsystems - Beijing China case PHY_CALIBRATE_BASE_BAND_CMD: 549689b2a9fbSfei feng - Sun Microsystems - Beijing China if (NULL == res_p->base_band_res) { 549789b2a9fbSfei feng - Sun Microsystems - Beijing China res_p->base_band_res = kmem_alloc(len, KM_NOSLEEP); 549889b2a9fbSfei feng - Sun Microsystems - Beijing China } 549989b2a9fbSfei feng - Sun Microsystems - Beijing China 550089b2a9fbSfei feng - Sun Microsystems - Beijing China if (NULL == res_p->base_band_res) { 550189b2a9fbSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_save_calib_result(): " 550289b2a9fbSfei feng - Sun Microsystems - Beijing China "failed to allocate memory.\n"); 55037d483bc1Sfei feng - Sun Microsystems - Beijing China return; 550489b2a9fbSfei feng - Sun Microsystems - Beijing China } 550589b2a9fbSfei feng - Sun Microsystems - Beijing China 550689b2a9fbSfei feng - Sun Microsystems - Beijing China res_p->base_band_res_len = len; 550789b2a9fbSfei feng - Sun Microsystems - Beijing China bcopy(calib_hdr, res_p->base_band_res, len); 5508c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 5509c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5510c7ee0b5cSfei feng - Sun Microsystems - Beijing China default: 5511c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_save_calib_result(): " 551289b2a9fbSfei feng - Sun Microsystems - Beijing China "incorrect calibration type(%d).\n", calib_hdr->op_code); 5513c7ee0b5cSfei feng - Sun Microsystems - Beijing China break; 5514c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5515c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5516c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5517c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5518c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5519c7ee0b5cSfei feng - Sun Microsystems - Beijing China * configure TX pwoer table 5520c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5521c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 5522c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_power_table(iwh_sc_t *sc, int async) 5523c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 5524c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_tx_power_table_cmd_t txpower; 5525e2cf88acSQuaker Fang int i, err = IWH_FAIL; 5526c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5527c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) memset(&txpower, 0, sizeof (txpower)); 5528c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5529c7ee0b5cSfei feng - Sun Microsystems - Beijing China txpower.band = 1; /* for 2.4G */ 5530b510adaeSfei feng - Sun Microsystems - Beijing China txpower.channel = (uint8_t)LE_16(sc->sc_config.chan); 5531c7ee0b5cSfei feng - Sun Microsystems - Beijing China txpower.pa_measurements = 1; 5532c7ee0b5cSfei feng - Sun Microsystems - Beijing China txpower.max_mcs = 23; 5533c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5534c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (i = 0; i < 24; i++) { 5535c7ee0b5cSfei feng - Sun Microsystems - Beijing China txpower.db.ht_ofdm_power[i].s.radio_tx_gain[0] = 0x16; 5536c7ee0b5cSfei feng - Sun Microsystems - Beijing China txpower.db.ht_ofdm_power[i].s.radio_tx_gain[1] = 0x16; 5537c7ee0b5cSfei feng - Sun Microsystems - Beijing China txpower.db.ht_ofdm_power[i].s.radio_tx_gain[2] = 0x16; 5538c7ee0b5cSfei feng - Sun Microsystems - Beijing China txpower.db.ht_ofdm_power[i].s.dsp_predis_atten[0] = 0x6E; 5539c7ee0b5cSfei feng - Sun Microsystems - Beijing China txpower.db.ht_ofdm_power[i].s.dsp_predis_atten[1] = 0x6E; 5540c7ee0b5cSfei feng - Sun Microsystems - Beijing China txpower.db.ht_ofdm_power[i].s.dsp_predis_atten[2] = 0x6E; 5541c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5542c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5543c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (i = 0; i < 2; i++) { 5544c7ee0b5cSfei feng - Sun Microsystems - Beijing China txpower.db.cck_power[i].s.radio_tx_gain[0] = 0x16; 5545c7ee0b5cSfei feng - Sun Microsystems - Beijing China txpower.db.cck_power[i].s.radio_tx_gain[1] = 0x16; 5546c7ee0b5cSfei feng - Sun Microsystems - Beijing China txpower.db.cck_power[i].s.radio_tx_gain[2] = 0x16; 5547c7ee0b5cSfei feng - Sun Microsystems - Beijing China txpower.db.cck_power[i].s.dsp_predis_atten[0] = 0x6E; 5548c7ee0b5cSfei feng - Sun Microsystems - Beijing China txpower.db.cck_power[i].s.dsp_predis_atten[1] = 0x6E; 5549c7ee0b5cSfei feng - Sun Microsystems - Beijing China txpower.db.cck_power[i].s.dsp_predis_atten[2] = 0x6E; 5550c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5551c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5552c7ee0b5cSfei feng - Sun Microsystems - Beijing China err = iwh_cmd(sc, REPLY_TX_PWR_TABLE_CMD, &txpower, 5553c7ee0b5cSfei feng - Sun Microsystems - Beijing China sizeof (txpower), async); 5554c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 5555c7ee0b5cSfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_tx_power_table(): " 5556c7ee0b5cSfei feng - Sun Microsystems - Beijing China "failed to set tx power table.\n"); 5557c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (err); 5558c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5559c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5560e2cf88acSQuaker Fang return (err); 5561c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5562c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5563c7ee0b5cSfei feng - Sun Microsystems - Beijing China static void 5564c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_release_calib_buffer(iwh_sc_t *sc) 5565c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 5566c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (sc->sc_calib_results.lo_res != NULL) { 5567c7ee0b5cSfei feng - Sun Microsystems - Beijing China kmem_free(sc->sc_calib_results.lo_res, 5568c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_calib_results.lo_res_len); 5569c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_calib_results.lo_res = NULL; 5570c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5571c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5572c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (sc->sc_calib_results.tx_iq_res != NULL) { 5573c7ee0b5cSfei feng - Sun Microsystems - Beijing China kmem_free(sc->sc_calib_results.tx_iq_res, 5574c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_calib_results.tx_iq_res_len); 5575c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_calib_results.tx_iq_res = NULL; 5576c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5577c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5578c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (sc->sc_calib_results.tx_iq_perd_res != NULL) { 5579c7ee0b5cSfei feng - Sun Microsystems - Beijing China kmem_free(sc->sc_calib_results.tx_iq_perd_res, 5580c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_calib_results.tx_iq_perd_res_len); 5581c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_calib_results.tx_iq_perd_res = NULL; 5582c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5583c7ee0b5cSfei feng - Sun Microsystems - Beijing China 558489b2a9fbSfei feng - Sun Microsystems - Beijing China if (sc->sc_calib_results.dc_res != NULL) { 558589b2a9fbSfei feng - Sun Microsystems - Beijing China kmem_free(sc->sc_calib_results.dc_res, 558689b2a9fbSfei feng - Sun Microsystems - Beijing China sc->sc_calib_results.dc_res_len); 558789b2a9fbSfei feng - Sun Microsystems - Beijing China sc->sc_calib_results.dc_res = NULL; 558889b2a9fbSfei feng - Sun Microsystems - Beijing China } 558989b2a9fbSfei feng - Sun Microsystems - Beijing China 559089b2a9fbSfei feng - Sun Microsystems - Beijing China if (sc->sc_calib_results.base_band_res != NULL) { 559189b2a9fbSfei feng - Sun Microsystems - Beijing China kmem_free(sc->sc_calib_results.base_band_res, 559289b2a9fbSfei feng - Sun Microsystems - Beijing China sc->sc_calib_results.base_band_res_len); 559389b2a9fbSfei feng - Sun Microsystems - Beijing China sc->sc_calib_results.base_band_res = NULL; 559489b2a9fbSfei feng - Sun Microsystems - Beijing China } 5595c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5596c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5597c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5598e2cf88acSQuaker Fang * common section of intialization 5599c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5600c7ee0b5cSfei feng - Sun Microsystems - Beijing China static int 5601c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_init_common(iwh_sc_t *sc) 5602c7ee0b5cSfei feng - Sun Microsystems - Beijing China { 5603c7ee0b5cSfei feng - Sun Microsystems - Beijing China int32_t qid; 5604c7ee0b5cSfei feng - Sun Microsystems - Beijing China uint32_t tmp; 5605c7ee0b5cSfei feng - Sun Microsystems - Beijing China 56067d483bc1Sfei feng - Sun Microsystems - Beijing China if (iwh_reset_hw(sc) != IWH_SUCCESS) { 56077d483bc1Sfei feng - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_init_common(): " 56087d483bc1Sfei feng - Sun Microsystems - Beijing China "failed to reset hardware\n"); 56097d483bc1Sfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 56107d483bc1Sfei feng - Sun Microsystems - Beijing China } 56117d483bc1Sfei feng - Sun Microsystems - Beijing China 5612c7ee0b5cSfei feng - Sun Microsystems - Beijing China (void) iwh_preinit(sc); 5613c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5614c7ee0b5cSfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_GP_CNTRL); 5615c7ee0b5cSfei feng - Sun Microsystems - Beijing China if (!(tmp & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) { 5616b510adaeSfei feng - Sun Microsystems - Beijing China cmn_err(CE_NOTE, "iwh_init_common(): " 5617c7ee0b5cSfei feng - Sun Microsystems - Beijing China "radio transmitter is off\n"); 5618c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_FAIL); 5619c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5620c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5621c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5622c7ee0b5cSfei feng - Sun Microsystems - Beijing China * init Rx ring 5623c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5624c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_enter(sc); 5625c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); 5626c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5627c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); 5628c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, FH_RSCSR_CHNL0_RBDCB_BASE_REG, 5629c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_rxq.dma_desc.cookie.dmac_address >> 8); 5630c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5631c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, FH_RSCSR_CHNL0_STTS_WPTR_REG, 5632c7ee0b5cSfei feng - Sun Microsystems - Beijing China ((uint32_t)(sc->sc_dma_sh.cookie.dmac_address + 5633c7ee0b5cSfei feng - Sun Microsystems - Beijing China offsetof(struct iwh_shared, val0)) >> 4)); 5634c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5635c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, FH_MEM_RCSR_CHNL0_CONFIG_REG, 5636c7ee0b5cSfei feng - Sun Microsystems - Beijing China FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | 5637c7ee0b5cSfei feng - Sun Microsystems - Beijing China FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | 5638e2cf88acSQuaker Fang IWH_FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K | 5639c7ee0b5cSfei feng - Sun Microsystems - Beijing China (RX_QUEUE_SIZE_LOG << 5640c7ee0b5cSfei feng - Sun Microsystems - Beijing China FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT)); 5641c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_exit(sc); 5642c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 5643c7ee0b5cSfei feng - Sun Microsystems - Beijing China (RX_QUEUE_SIZE - 1) & ~0x7); 5644c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5645c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5646c7ee0b5cSfei feng - Sun Microsystems - Beijing China * init Tx rings 5647c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5648c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_enter(sc); 5649c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_reg_write(sc, IWH_SCD_TXFACT, 0); 5650c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5651c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5652c7ee0b5cSfei feng - Sun Microsystems - Beijing China * keep warm page 5653c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5654c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, IWH_FH_KW_MEM_ADDR_REG, 5655c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_dma_kw.cookie.dmac_address >> 4); 5656c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5657c7ee0b5cSfei feng - Sun Microsystems - Beijing China for (qid = 0; qid < IWH_NUM_QUEUES; qid++) { 5658c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, FH_MEM_CBBC_QUEUE(qid), 5659c7ee0b5cSfei feng - Sun Microsystems - Beijing China sc->sc_txq[qid].dma_desc.cookie.dmac_address >> 8); 5660c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, IWH_FH_TCSR_CHNL_TX_CONFIG_REG(qid), 5661c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | 5662c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL); 5663c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 5664c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5665c7ee0b5cSfei feng - Sun Microsystems - Beijing China iwh_mac_access_exit(sc); 5666c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5667c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5668c7ee0b5cSfei feng - Sun Microsystems - Beijing China * clear "radio off" and "disable command" bits 5669c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5670c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); 5671c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_UCODE_DRV_GP1_CLR, 5672c7ee0b5cSfei feng - Sun Microsystems - Beijing China CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); 5673c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5674c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5675c7ee0b5cSfei feng - Sun Microsystems - Beijing China * clear any pending interrupts 5676c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5677c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_INT, 0xffffffff); 5678c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5679c7ee0b5cSfei feng - Sun Microsystems - Beijing China /* 5680c7ee0b5cSfei feng - Sun Microsystems - Beijing China * enable interrupts 5681c7ee0b5cSfei feng - Sun Microsystems - Beijing China */ 5682c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_INT_MASK, CSR_INI_SET_MASK); 5683c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5684c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); 5685c7ee0b5cSfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); 5686c7ee0b5cSfei feng - Sun Microsystems - Beijing China 5687c7ee0b5cSfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 5688c7ee0b5cSfei feng - Sun Microsystems - Beijing China } 56896f12def4Spengcheng chen - Sun Microsystems - Beijing China 56906f12def4Spengcheng chen - Sun Microsystems - Beijing China static int 56916f12def4Spengcheng chen - Sun Microsystems - Beijing China iwh_fast_recover(iwh_sc_t *sc) 56926f12def4Spengcheng chen - Sun Microsystems - Beijing China { 56936f12def4Spengcheng chen - Sun Microsystems - Beijing China ieee80211com_t *ic = &sc->sc_ic; 5694e2cf88acSQuaker Fang int err = IWH_FAIL; 56956f12def4Spengcheng chen - Sun Microsystems - Beijing China 56966f12def4Spengcheng chen - Sun Microsystems - Beijing China mutex_enter(&sc->sc_glock); 56976f12def4Spengcheng chen - Sun Microsystems - Beijing China 569889b2a9fbSfei feng - Sun Microsystems - Beijing China /* 569989b2a9fbSfei feng - Sun Microsystems - Beijing China * restore runtime configuration 570089b2a9fbSfei feng - Sun Microsystems - Beijing China */ 57016f12def4Spengcheng chen - Sun Microsystems - Beijing China bcopy(&sc->sc_config_save, &sc->sc_config, 57026f12def4Spengcheng chen - Sun Microsystems - Beijing China sizeof (sc->sc_config)); 57036f12def4Spengcheng chen - Sun Microsystems - Beijing China 57046f12def4Spengcheng chen - Sun Microsystems - Beijing China sc->sc_config.assoc_id = 0; 57056f12def4Spengcheng chen - Sun Microsystems - Beijing China sc->sc_config.filter_flags &= ~LE_32(RXON_FILTER_ASSOC_MSK); 57066f12def4Spengcheng chen - Sun Microsystems - Beijing China 5707e2cf88acSQuaker Fang if ((err = iwh_hw_set_before_auth(sc)) != IWH_SUCCESS) { 57086f12def4Spengcheng chen - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_fast_recover(): " 57096f12def4Spengcheng chen - Sun Microsystems - Beijing China "could not setup authentication\n"); 57106f12def4Spengcheng chen - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 57116f12def4Spengcheng chen - Sun Microsystems - Beijing China return (err); 57126f12def4Spengcheng chen - Sun Microsystems - Beijing China } 57136f12def4Spengcheng chen - Sun Microsystems - Beijing China 57146f12def4Spengcheng chen - Sun Microsystems - Beijing China bcopy(&sc->sc_config_save, &sc->sc_config, 57156f12def4Spengcheng chen - Sun Microsystems - Beijing China sizeof (sc->sc_config)); 57166f12def4Spengcheng chen - Sun Microsystems - Beijing China 571789b2a9fbSfei feng - Sun Microsystems - Beijing China /* 571889b2a9fbSfei feng - Sun Microsystems - Beijing China * update adapter's configuration 571989b2a9fbSfei feng - Sun Microsystems - Beijing China */ 57206f12def4Spengcheng chen - Sun Microsystems - Beijing China err = iwh_run_state_config(sc); 57216f12def4Spengcheng chen - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 57226f12def4Spengcheng chen - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_fast_recover(): " 57236f12def4Spengcheng chen - Sun Microsystems - Beijing China "failed to setup association\n"); 57246f12def4Spengcheng chen - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 57256f12def4Spengcheng chen - Sun Microsystems - Beijing China return (err); 57266f12def4Spengcheng chen - Sun Microsystems - Beijing China } 572789b2a9fbSfei feng - Sun Microsystems - Beijing China 572889b2a9fbSfei feng - Sun Microsystems - Beijing China /* 572989b2a9fbSfei feng - Sun Microsystems - Beijing China * set LED on 573089b2a9fbSfei feng - Sun Microsystems - Beijing China */ 57316f12def4Spengcheng chen - Sun Microsystems - Beijing China iwh_set_led(sc, 2, 0, 1); 57326f12def4Spengcheng chen - Sun Microsystems - Beijing China 57336f12def4Spengcheng chen - Sun Microsystems - Beijing China mutex_exit(&sc->sc_glock); 57346f12def4Spengcheng chen - Sun Microsystems - Beijing China 573589b2a9fbSfei feng - Sun Microsystems - Beijing China atomic_and_32(&sc->sc_flags, ~IWH_F_HW_ERR_RECOVER); 57366f12def4Spengcheng chen - Sun Microsystems - Beijing China 573789b2a9fbSfei feng - Sun Microsystems - Beijing China /* 573889b2a9fbSfei feng - Sun Microsystems - Beijing China * start queue 573989b2a9fbSfei feng - Sun Microsystems - Beijing China */ 5740e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_FW, "iwh_fast_recover(): " 5741e2cf88acSQuaker Fang "resume xmit\n")); 57426f12def4Spengcheng chen - Sun Microsystems - Beijing China mac_tx_update(ic->ic_mach); 57436f12def4Spengcheng chen - Sun Microsystems - Beijing China 57446f12def4Spengcheng chen - Sun Microsystems - Beijing China return (IWH_SUCCESS); 57456f12def4Spengcheng chen - Sun Microsystems - Beijing China } 57466f12def4Spengcheng chen - Sun Microsystems - Beijing China 57476f12def4Spengcheng chen - Sun Microsystems - Beijing China static int 57486f12def4Spengcheng chen - Sun Microsystems - Beijing China iwh_run_state_config(iwh_sc_t *sc) 57496f12def4Spengcheng chen - Sun Microsystems - Beijing China { 57506f12def4Spengcheng chen - Sun Microsystems - Beijing China struct ieee80211com *ic = &sc->sc_ic; 57516f12def4Spengcheng chen - Sun Microsystems - Beijing China ieee80211_node_t *in = ic->ic_bss; 5752e2cf88acSQuaker Fang uint32_t ht_protec = (uint32_t)(-1); 5753e2cf88acSQuaker Fang int err = IWH_FAIL; 57546f12def4Spengcheng chen - Sun Microsystems - Beijing China 57556f12def4Spengcheng chen - Sun Microsystems - Beijing China /* 57566f12def4Spengcheng chen - Sun Microsystems - Beijing China * update adapter's configuration 57576f12def4Spengcheng chen - Sun Microsystems - Beijing China */ 57586f12def4Spengcheng chen - Sun Microsystems - Beijing China sc->sc_config.assoc_id = in->in_associd & 0x3fff; 57596f12def4Spengcheng chen - Sun Microsystems - Beijing China 57606f12def4Spengcheng chen - Sun Microsystems - Beijing China /* 57616f12def4Spengcheng chen - Sun Microsystems - Beijing China * short preamble/slot time are 57626f12def4Spengcheng chen - Sun Microsystems - Beijing China * negotiated when associating 57636f12def4Spengcheng chen - Sun Microsystems - Beijing China */ 57646f12def4Spengcheng chen - Sun Microsystems - Beijing China sc->sc_config.flags &= 57656f12def4Spengcheng chen - Sun Microsystems - Beijing China ~LE_32(RXON_FLG_SHORT_PREAMBLE_MSK | 57666f12def4Spengcheng chen - Sun Microsystems - Beijing China RXON_FLG_SHORT_SLOT_MSK); 57676f12def4Spengcheng chen - Sun Microsystems - Beijing China 57686f12def4Spengcheng chen - Sun Microsystems - Beijing China if (ic->ic_flags & IEEE80211_F_SHSLOT) { 57696f12def4Spengcheng chen - Sun Microsystems - Beijing China sc->sc_config.flags |= 57706f12def4Spengcheng chen - Sun Microsystems - Beijing China LE_32(RXON_FLG_SHORT_SLOT_MSK); 57716f12def4Spengcheng chen - Sun Microsystems - Beijing China } 57726f12def4Spengcheng chen - Sun Microsystems - Beijing China 57736f12def4Spengcheng chen - Sun Microsystems - Beijing China if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) { 57746f12def4Spengcheng chen - Sun Microsystems - Beijing China sc->sc_config.flags |= 57756f12def4Spengcheng chen - Sun Microsystems - Beijing China LE_32(RXON_FLG_SHORT_PREAMBLE_MSK); 57766f12def4Spengcheng chen - Sun Microsystems - Beijing China } 57776f12def4Spengcheng chen - Sun Microsystems - Beijing China 5778e2cf88acSQuaker Fang if (in->in_flags & IEEE80211_NODE_HT) { 5779e2cf88acSQuaker Fang ht_protec = in->in_htopmode; 5780e2cf88acSQuaker Fang if (ht_protec > 3) { 5781e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_run_state_config(): " 5782e2cf88acSQuaker Fang "HT protection mode is not correct.\n"); 5783e2cf88acSQuaker Fang return (IWH_FAIL); 5784e2cf88acSQuaker Fang } else if (NO_HT_PROT == ht_protec) { 5785e2cf88acSQuaker Fang ht_protec = sc->sc_ht_conf.ht_protection; 5786e2cf88acSQuaker Fang } 5787e2cf88acSQuaker Fang 5788e2cf88acSQuaker Fang sc->sc_config.flags |= 5789e2cf88acSQuaker Fang LE_32(ht_protec << RXON_FLG_HT_OPERATING_MODE_POS); 5790e2cf88acSQuaker Fang } 5791e2cf88acSQuaker Fang 5792e2cf88acSQuaker Fang /* 5793e2cf88acSQuaker Fang * set RX chains/antennas. 5794e2cf88acSQuaker Fang */ 5795e2cf88acSQuaker Fang iwh_config_rxon_chain(sc); 5796e2cf88acSQuaker Fang 57976f12def4Spengcheng chen - Sun Microsystems - Beijing China sc->sc_config.filter_flags |= 57986f12def4Spengcheng chen - Sun Microsystems - Beijing China LE_32(RXON_FILTER_ASSOC_MSK); 57996f12def4Spengcheng chen - Sun Microsystems - Beijing China 58006f12def4Spengcheng chen - Sun Microsystems - Beijing China if (ic->ic_opmode != IEEE80211_M_STA) { 58016f12def4Spengcheng chen - Sun Microsystems - Beijing China sc->sc_config.filter_flags |= 58026f12def4Spengcheng chen - Sun Microsystems - Beijing China LE_32(RXON_FILTER_BCON_AWARE_MSK); 58036f12def4Spengcheng chen - Sun Microsystems - Beijing China } 58046f12def4Spengcheng chen - Sun Microsystems - Beijing China 5805e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_80211, "iwh_run_state_config(): " 5806e2cf88acSQuaker Fang "config chan %d flags %x" 58076f12def4Spengcheng chen - Sun Microsystems - Beijing China " filter_flags %x\n", 58086f12def4Spengcheng chen - Sun Microsystems - Beijing China sc->sc_config.chan, sc->sc_config.flags, 58096f12def4Spengcheng chen - Sun Microsystems - Beijing China sc->sc_config.filter_flags)); 58106f12def4Spengcheng chen - Sun Microsystems - Beijing China 58116f12def4Spengcheng chen - Sun Microsystems - Beijing China err = iwh_cmd(sc, REPLY_RXON, &sc->sc_config, 58126f12def4Spengcheng chen - Sun Microsystems - Beijing China sizeof (iwh_rxon_cmd_t), 1); 58136f12def4Spengcheng chen - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 58146f12def4Spengcheng chen - Sun Microsystems - Beijing China cmn_err(CE_WARN, "iwh_run_state_config(): " 58156f12def4Spengcheng chen - Sun Microsystems - Beijing China "could not update configuration\n"); 58166f12def4Spengcheng chen - Sun Microsystems - Beijing China return (err); 58176f12def4Spengcheng chen - Sun Microsystems - Beijing China } 58186f12def4Spengcheng chen - Sun Microsystems - Beijing China 581989b2a9fbSfei feng - Sun Microsystems - Beijing China if ((sc->sc_dev_id != 0x423c) && 582089b2a9fbSfei feng - Sun Microsystems - Beijing China (sc->sc_dev_id != 0x423d)) { 58216f12def4Spengcheng chen - Sun Microsystems - Beijing China /* 58226f12def4Spengcheng chen - Sun Microsystems - Beijing China * send tx power table command 58236f12def4Spengcheng chen - Sun Microsystems - Beijing China */ 58246f12def4Spengcheng chen - Sun Microsystems - Beijing China err = iwh_tx_power_table(sc, 1); 58256f12def4Spengcheng chen - Sun Microsystems - Beijing China if (err != IWH_SUCCESS) { 58266f12def4Spengcheng chen - Sun Microsystems - Beijing China return (err); 58276f12def4Spengcheng chen - Sun Microsystems - Beijing China } 582889b2a9fbSfei feng - Sun Microsystems - Beijing China } 58296f12def4Spengcheng chen - Sun Microsystems - Beijing China 5830e2cf88acSQuaker Fang /* 5831e2cf88acSQuaker Fang * Not need to update retry rate table for AP node 5832e2cf88acSQuaker Fang */ 5833e2cf88acSQuaker Fang err = iwh_qosparam_to_hw(sc, 1); 5834e2cf88acSQuaker Fang if (err != IWH_SUCCESS) { 5835e2cf88acSQuaker Fang return (err); 5836e2cf88acSQuaker Fang } 5837e2cf88acSQuaker Fang 5838e2cf88acSQuaker Fang return (err); 5839e2cf88acSQuaker Fang } 5840e2cf88acSQuaker Fang 5841e2cf88acSQuaker Fang /* 5842e2cf88acSQuaker Fang * This function is only for compatibility with Net80211 module. 5843e2cf88acSQuaker Fang * iwh_qosparam_to_hw() is the actual function updating EDCA 5844e2cf88acSQuaker Fang * parameters to hardware. 5845e2cf88acSQuaker Fang */ 5846e2cf88acSQuaker Fang /* ARGSUSED */ 5847e2cf88acSQuaker Fang static int 5848e2cf88acSQuaker Fang iwh_wme_update(ieee80211com_t *ic) 5849e2cf88acSQuaker Fang { 5850e2cf88acSQuaker Fang return (0); 5851e2cf88acSQuaker Fang } 5852e2cf88acSQuaker Fang 5853e2cf88acSQuaker Fang static int 5854e2cf88acSQuaker Fang iwh_wme_to_qos_ac(int wme_ac) 5855e2cf88acSQuaker Fang { 5856e2cf88acSQuaker Fang int qos_ac = QOS_AC_INVALID; 5857e2cf88acSQuaker Fang 5858e2cf88acSQuaker Fang if (wme_ac < WME_AC_BE || wme_ac > WME_AC_VO) { 5859e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_wme_to_qos_ac(): " 5860e2cf88acSQuaker Fang "WME AC index is not in suitable range.\n"); 5861e2cf88acSQuaker Fang return (qos_ac); 5862e2cf88acSQuaker Fang } 5863e2cf88acSQuaker Fang 5864e2cf88acSQuaker Fang switch (wme_ac) { 5865e2cf88acSQuaker Fang case WME_AC_BE: 5866e2cf88acSQuaker Fang qos_ac = QOS_AC_BK; 5867e2cf88acSQuaker Fang break; 5868e2cf88acSQuaker Fang case WME_AC_BK: 5869e2cf88acSQuaker Fang qos_ac = QOS_AC_BE; 5870e2cf88acSQuaker Fang break; 5871e2cf88acSQuaker Fang case WME_AC_VI: 5872e2cf88acSQuaker Fang qos_ac = QOS_AC_VI; 5873e2cf88acSQuaker Fang break; 5874e2cf88acSQuaker Fang case WME_AC_VO: 5875e2cf88acSQuaker Fang qos_ac = QOS_AC_VO; 5876e2cf88acSQuaker Fang break; 5877e2cf88acSQuaker Fang } 5878e2cf88acSQuaker Fang 5879e2cf88acSQuaker Fang return (qos_ac); 5880e2cf88acSQuaker Fang } 5881e2cf88acSQuaker Fang 5882e2cf88acSQuaker Fang static uint16_t 5883e2cf88acSQuaker Fang iwh_cw_e_to_cw(uint8_t cw_e) 5884e2cf88acSQuaker Fang { 5885e2cf88acSQuaker Fang uint16_t cw = 1; 5886e2cf88acSQuaker Fang 5887e2cf88acSQuaker Fang while (cw_e > 0) { 5888e2cf88acSQuaker Fang cw <<= 1; 5889e2cf88acSQuaker Fang cw_e--; 5890e2cf88acSQuaker Fang } 5891e2cf88acSQuaker Fang 5892e2cf88acSQuaker Fang cw -= 1; 5893e2cf88acSQuaker Fang return (cw); 5894e2cf88acSQuaker Fang } 5895e2cf88acSQuaker Fang 5896e2cf88acSQuaker Fang static int 5897e2cf88acSQuaker Fang iwh_wmeparam_check(struct wmeParams *wmeparam) 5898e2cf88acSQuaker Fang { 5899e2cf88acSQuaker Fang int i; 5900e2cf88acSQuaker Fang 5901e2cf88acSQuaker Fang for (i = 0; i < WME_NUM_AC; i++) { 5902e2cf88acSQuaker Fang 5903e2cf88acSQuaker Fang if ((wmeparam[i].wmep_logcwmax > QOS_CW_RANGE_MAX) || 5904e2cf88acSQuaker Fang (wmeparam[i].wmep_logcwmin >= wmeparam[i].wmep_logcwmax)) { 5905e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_wmeparam_check(): " 5906e2cf88acSQuaker Fang "Contention window is not in suitable range.\n"); 5907e2cf88acSQuaker Fang return (IWH_FAIL); 5908e2cf88acSQuaker Fang } 5909e2cf88acSQuaker Fang 5910e2cf88acSQuaker Fang if ((wmeparam[i].wmep_aifsn < QOS_AIFSN_MIN) || 5911e2cf88acSQuaker Fang (wmeparam[i].wmep_aifsn > QOS_AIFSN_MAX)) { 5912e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_wmeparam_check(): " 5913e2cf88acSQuaker Fang "Arbitration interframe space number" 5914e2cf88acSQuaker Fang "is not in suitable range.\n"); 5915e2cf88acSQuaker Fang return (IWH_FAIL); 5916e2cf88acSQuaker Fang } 5917e2cf88acSQuaker Fang } 5918e2cf88acSQuaker Fang 59196f12def4Spengcheng chen - Sun Microsystems - Beijing China return (IWH_SUCCESS); 59206f12def4Spengcheng chen - Sun Microsystems - Beijing China } 5921e2cf88acSQuaker Fang 5922e2cf88acSQuaker Fang /* 5923e2cf88acSQuaker Fang * This function updates EDCA parameters into hardware. 5924e2cf88acSQuaker Fang * FIFO0-background, FIFO1-best effort, FIFO2-viedo, FIFO3-voice. 5925e2cf88acSQuaker Fang */ 5926e2cf88acSQuaker Fang static int 5927e2cf88acSQuaker Fang iwh_qosparam_to_hw(iwh_sc_t *sc, int async) 5928e2cf88acSQuaker Fang { 5929e2cf88acSQuaker Fang ieee80211com_t *ic = &sc->sc_ic; 5930e2cf88acSQuaker Fang ieee80211_node_t *in = ic->ic_bss; 5931e2cf88acSQuaker Fang struct wmeParams *wmeparam; 5932e2cf88acSQuaker Fang iwh_qos_param_cmd_t qosparam_cmd; 5933e2cf88acSQuaker Fang int i, j; 5934e2cf88acSQuaker Fang int err = IWH_FAIL; 5935e2cf88acSQuaker Fang 5936e2cf88acSQuaker Fang if ((in->in_flags & IEEE80211_NODE_QOS) && 5937e2cf88acSQuaker Fang (IEEE80211_M_STA == ic->ic_opmode)) { 5938e2cf88acSQuaker Fang wmeparam = ic->ic_wme.wme_chanParams.cap_wmeParams; 5939e2cf88acSQuaker Fang } else { 5940e2cf88acSQuaker Fang return (IWH_SUCCESS); 5941e2cf88acSQuaker Fang } 5942e2cf88acSQuaker Fang 5943e2cf88acSQuaker Fang (void) memset(&qosparam_cmd, 0, sizeof (qosparam_cmd)); 5944e2cf88acSQuaker Fang 5945e2cf88acSQuaker Fang err = iwh_wmeparam_check(wmeparam); 5946e2cf88acSQuaker Fang if (err != IWH_SUCCESS) { 5947e2cf88acSQuaker Fang return (err); 5948e2cf88acSQuaker Fang } 5949e2cf88acSQuaker Fang 5950e2cf88acSQuaker Fang if (in->in_flags & IEEE80211_NODE_QOS) { 5951e2cf88acSQuaker Fang qosparam_cmd.flags |= QOS_PARAM_FLG_UPDATE_EDCA; 5952e2cf88acSQuaker Fang } 5953e2cf88acSQuaker Fang 5954e2cf88acSQuaker Fang if (in->in_flags & (IEEE80211_NODE_QOS | IEEE80211_NODE_HT)) { 5955e2cf88acSQuaker Fang qosparam_cmd.flags |= QOS_PARAM_FLG_TGN; 5956e2cf88acSQuaker Fang } 5957e2cf88acSQuaker Fang 5958e2cf88acSQuaker Fang for (i = 0; i < WME_NUM_AC; i++) { 5959e2cf88acSQuaker Fang 5960e2cf88acSQuaker Fang j = iwh_wme_to_qos_ac(i); 5961e2cf88acSQuaker Fang if (j < QOS_AC_BK || j > QOS_AC_VO) { 5962e2cf88acSQuaker Fang return (IWH_FAIL); 5963e2cf88acSQuaker Fang } 5964e2cf88acSQuaker Fang 5965e2cf88acSQuaker Fang qosparam_cmd.ac[j].cw_min = 5966e2cf88acSQuaker Fang iwh_cw_e_to_cw(wmeparam[i].wmep_logcwmin); 5967e2cf88acSQuaker Fang qosparam_cmd.ac[j].cw_max = 5968e2cf88acSQuaker Fang iwh_cw_e_to_cw(wmeparam[i].wmep_logcwmax); 5969e2cf88acSQuaker Fang qosparam_cmd.ac[j].aifsn = 5970e2cf88acSQuaker Fang wmeparam[i].wmep_aifsn; 5971e2cf88acSQuaker Fang qosparam_cmd.ac[j].txop = 5972e2cf88acSQuaker Fang (uint16_t)(wmeparam[i].wmep_txopLimit * 32); 5973e2cf88acSQuaker Fang } 5974e2cf88acSQuaker Fang 5975e2cf88acSQuaker Fang err = iwh_cmd(sc, REPLY_QOS_PARAM, &qosparam_cmd, 5976e2cf88acSQuaker Fang sizeof (qosparam_cmd), async); 5977e2cf88acSQuaker Fang if (err != IWH_SUCCESS) { 5978e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_qosparam_to_hw(): " 5979e2cf88acSQuaker Fang "failed to update QoS parameters into hardware.\n"); 5980e2cf88acSQuaker Fang return (err); 5981e2cf88acSQuaker Fang } 5982e2cf88acSQuaker Fang 5983e2cf88acSQuaker Fang #ifdef DEBUG 5984e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_QOS, "iwh_qosparam_to_hw(): " 5985e2cf88acSQuaker Fang "EDCA parameters are as follows:\n")); 5986e2cf88acSQuaker Fang 5987e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_QOS, "BK parameters are: " 5988e2cf88acSQuaker Fang "cw_min = %d, cw_max = %d, aifsn = %d, txop = %d\n", 5989e2cf88acSQuaker Fang qosparam_cmd.ac[0].cw_min, qosparam_cmd.ac[0].cw_max, 5990e2cf88acSQuaker Fang qosparam_cmd.ac[0].aifsn, qosparam_cmd.ac[0].txop)); 5991e2cf88acSQuaker Fang 5992e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_QOS, "BE parameters are: " 5993e2cf88acSQuaker Fang "cw_min = %d, cw_max = %d, aifsn = %d, txop = %d\n", 5994e2cf88acSQuaker Fang qosparam_cmd.ac[1].cw_min, qosparam_cmd.ac[1].cw_max, 5995e2cf88acSQuaker Fang qosparam_cmd.ac[1].aifsn, qosparam_cmd.ac[1].txop)); 5996e2cf88acSQuaker Fang 5997e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_QOS, "VI parameters are: " 5998e2cf88acSQuaker Fang "cw_min = %d, cw_max = %d, aifsn = %d, txop = %d\n", 5999e2cf88acSQuaker Fang qosparam_cmd.ac[2].cw_min, qosparam_cmd.ac[2].cw_max, 6000e2cf88acSQuaker Fang qosparam_cmd.ac[2].aifsn, qosparam_cmd.ac[2].txop)); 6001e2cf88acSQuaker Fang 6002e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_QOS, "VO parameters are: " 6003e2cf88acSQuaker Fang "cw_min = %d, cw_max = %d, aifsn = %d, txop = %d\n", 6004e2cf88acSQuaker Fang qosparam_cmd.ac[3].cw_min, qosparam_cmd.ac[3].cw_max, 6005e2cf88acSQuaker Fang qosparam_cmd.ac[3].aifsn, qosparam_cmd.ac[3].txop)); 6006e2cf88acSQuaker Fang #endif 6007e2cf88acSQuaker Fang return (err); 6008e2cf88acSQuaker Fang } 6009e2cf88acSQuaker Fang 6010e2cf88acSQuaker Fang static inline int 6011e2cf88acSQuaker Fang iwh_wme_tid_qos_ac(int tid) 6012e2cf88acSQuaker Fang { 6013e2cf88acSQuaker Fang switch (tid) { 6014e2cf88acSQuaker Fang case 1: 6015e2cf88acSQuaker Fang case 2: 6016e2cf88acSQuaker Fang return (QOS_AC_BK); 6017e2cf88acSQuaker Fang case 0: 6018e2cf88acSQuaker Fang case 3: 6019e2cf88acSQuaker Fang return (QOS_AC_BE); 6020e2cf88acSQuaker Fang case 4: 6021e2cf88acSQuaker Fang case 5: 6022e2cf88acSQuaker Fang return (QOS_AC_VI); 6023e2cf88acSQuaker Fang case 6: 6024e2cf88acSQuaker Fang case 7: 6025e2cf88acSQuaker Fang return (QOS_AC_VO); 6026e2cf88acSQuaker Fang } 6027e2cf88acSQuaker Fang 6028e2cf88acSQuaker Fang return (QOS_AC_BE); 6029e2cf88acSQuaker Fang } 6030e2cf88acSQuaker Fang 6031e2cf88acSQuaker Fang static inline int 6032e2cf88acSQuaker Fang iwh_qos_ac_to_txq(int qos_ac) 6033e2cf88acSQuaker Fang { 6034e2cf88acSQuaker Fang switch (qos_ac) { 6035e2cf88acSQuaker Fang case QOS_AC_BK: 6036e2cf88acSQuaker Fang return (QOS_AC_BK_TO_TXQ); 6037e2cf88acSQuaker Fang case QOS_AC_BE: 6038e2cf88acSQuaker Fang return (QOS_AC_BE_TO_TXQ); 6039e2cf88acSQuaker Fang case QOS_AC_VI: 6040e2cf88acSQuaker Fang return (QOS_AC_VI_TO_TXQ); 6041e2cf88acSQuaker Fang case QOS_AC_VO: 6042e2cf88acSQuaker Fang return (QOS_AC_VO_TO_TXQ); 6043e2cf88acSQuaker Fang } 6044e2cf88acSQuaker Fang 6045e2cf88acSQuaker Fang return (QOS_AC_BE_TO_TXQ); 6046e2cf88acSQuaker Fang } 6047e2cf88acSQuaker Fang 6048e2cf88acSQuaker Fang static int 6049e2cf88acSQuaker Fang iwh_wme_tid_to_txq(int tid) 6050e2cf88acSQuaker Fang { 6051e2cf88acSQuaker Fang int queue_n = TXQ_FOR_AC_INVALID; 6052e2cf88acSQuaker Fang int qos_ac; 6053e2cf88acSQuaker Fang 6054e2cf88acSQuaker Fang if (tid < WME_TID_MIN || 6055e2cf88acSQuaker Fang tid > WME_TID_MAX) { 6056e2cf88acSQuaker Fang cmn_err(CE_WARN, "wme_tid_to_txq(): " 6057e2cf88acSQuaker Fang "TID is not in suitable range.\n"); 6058e2cf88acSQuaker Fang return (queue_n); 6059e2cf88acSQuaker Fang } 6060e2cf88acSQuaker Fang 6061e2cf88acSQuaker Fang qos_ac = iwh_wme_tid_qos_ac(tid); 6062e2cf88acSQuaker Fang queue_n = iwh_qos_ac_to_txq(qos_ac); 6063e2cf88acSQuaker Fang 6064e2cf88acSQuaker Fang return (queue_n); 6065e2cf88acSQuaker Fang } 6066e2cf88acSQuaker Fang 6067e2cf88acSQuaker Fang /* 6068e2cf88acSQuaker Fang * This function is used for intializing HT relevant configurations. 6069e2cf88acSQuaker Fang */ 6070e2cf88acSQuaker Fang static void 6071e2cf88acSQuaker Fang iwh_init_ht_conf(iwh_sc_t *sc) 6072e2cf88acSQuaker Fang { 6073e2cf88acSQuaker Fang (void) memset(&sc->sc_ht_conf, 0, sizeof (iwh_ht_conf_t)); 6074e2cf88acSQuaker Fang 6075e2cf88acSQuaker Fang if ((0x4235 == sc->sc_dev_id) || 6076e2cf88acSQuaker Fang (0x4236 == sc->sc_dev_id) || 6077e2cf88acSQuaker Fang (0x423a == sc->sc_dev_id)) { 6078e2cf88acSQuaker Fang sc->sc_ht_conf.ht_support = 1; 6079e2cf88acSQuaker Fang 6080e2cf88acSQuaker Fang sc->sc_ht_conf.valid_chains = 3; 6081e2cf88acSQuaker Fang sc->sc_ht_conf.tx_stream_count = 2; 6082e2cf88acSQuaker Fang sc->sc_ht_conf.rx_stream_count = 2; 6083e2cf88acSQuaker Fang 6084e2cf88acSQuaker Fang sc->sc_ht_conf.tx_support_mcs[0] = 0xff; 6085e2cf88acSQuaker Fang sc->sc_ht_conf.tx_support_mcs[1] = 0xff; 6086e2cf88acSQuaker Fang sc->sc_ht_conf.rx_support_mcs[0] = 0xff; 6087e2cf88acSQuaker Fang sc->sc_ht_conf.rx_support_mcs[1] = 0xff; 6088e2cf88acSQuaker Fang } else { 6089e2cf88acSQuaker Fang sc->sc_ht_conf.ht_support = 1; 6090e2cf88acSQuaker Fang 6091e2cf88acSQuaker Fang sc->sc_ht_conf.valid_chains = 2; 6092e2cf88acSQuaker Fang sc->sc_ht_conf.tx_stream_count = 1; 6093e2cf88acSQuaker Fang sc->sc_ht_conf.rx_stream_count = 2; 6094e2cf88acSQuaker Fang 6095e2cf88acSQuaker Fang sc->sc_ht_conf.tx_support_mcs[0] = 0xff; 6096e2cf88acSQuaker Fang sc->sc_ht_conf.rx_support_mcs[0] = 0xff; 6097e2cf88acSQuaker Fang sc->sc_ht_conf.rx_support_mcs[1] = 0xff; 6098e2cf88acSQuaker Fang } 6099e2cf88acSQuaker Fang 6100e2cf88acSQuaker Fang if (sc->sc_ht_conf.ht_support) { 6101e2cf88acSQuaker Fang sc->sc_ht_conf.cap |= HT_CAP_GRN_FLD; 6102e2cf88acSQuaker Fang sc->sc_ht_conf.cap |= HT_CAP_SGI_20; 6103e2cf88acSQuaker Fang sc->sc_ht_conf.cap |= HT_CAP_MAX_AMSDU; 6104e2cf88acSQuaker Fang /* should disable MIMO */ 6105e2cf88acSQuaker Fang sc->sc_ht_conf.cap |= HT_CAP_MIMO_PS; 6106e2cf88acSQuaker Fang 6107e2cf88acSQuaker Fang sc->sc_ht_conf.ampdu_p.factor = HT_RX_AMPDU_FACTOR; 6108e2cf88acSQuaker Fang sc->sc_ht_conf.ampdu_p.density = HT_MPDU_DENSITY; 6109e2cf88acSQuaker Fang 6110e2cf88acSQuaker Fang sc->sc_ht_conf.ht_protection = HT_PROT_CHAN_NON_HT; 6111e2cf88acSQuaker Fang } 6112e2cf88acSQuaker Fang } 6113e2cf88acSQuaker Fang 6114e2cf88acSQuaker Fang /* 6115e2cf88acSQuaker Fang * This function overwrites default ieee80211_rateset_11n struc. 6116e2cf88acSQuaker Fang */ 6117e2cf88acSQuaker Fang static void 6118e2cf88acSQuaker Fang iwh_overwrite_11n_rateset(iwh_sc_t *sc) 6119e2cf88acSQuaker Fang { 6120e2cf88acSQuaker Fang uint8_t *ht_rs = sc->sc_ht_conf.rx_support_mcs; 6121e2cf88acSQuaker Fang int mcs_idx, mcs_count = 0; 6122e2cf88acSQuaker Fang int i, j; 6123e2cf88acSQuaker Fang 6124e2cf88acSQuaker Fang for (i = 0; i < HT_RATESET_NUM; i++) { 6125e2cf88acSQuaker Fang for (j = 0; j < 8; j++) { 6126e2cf88acSQuaker Fang if (ht_rs[i] & (1 << j)) { 6127e2cf88acSQuaker Fang mcs_idx = i * 8 + j; 6128e2cf88acSQuaker Fang if (mcs_idx >= IEEE80211_HTRATE_MAXSIZE) { 6129e2cf88acSQuaker Fang break; 6130e2cf88acSQuaker Fang } 6131e2cf88acSQuaker Fang 6132e2cf88acSQuaker Fang ieee80211_rateset_11n.rs_rates[mcs_idx] = 6133e2cf88acSQuaker Fang (uint8_t)mcs_idx; 6134e2cf88acSQuaker Fang mcs_count++; 6135e2cf88acSQuaker Fang } 6136e2cf88acSQuaker Fang } 6137e2cf88acSQuaker Fang } 6138e2cf88acSQuaker Fang 6139e2cf88acSQuaker Fang ieee80211_rateset_11n.rs_nrates = (uint8_t)mcs_count; 6140e2cf88acSQuaker Fang 6141e2cf88acSQuaker Fang #ifdef DEBUG 6142e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_HTRATE, "iwh_overwrite_11n_rateset(): " 6143e2cf88acSQuaker Fang "HT rates supported by this station is as follows:\n")); 6144e2cf88acSQuaker Fang 6145e2cf88acSQuaker Fang for (i = 0; i < ieee80211_rateset_11n.rs_nrates; i++) { 6146e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_HTRATE, "Rate %d is %d\n", 6147e2cf88acSQuaker Fang i, ieee80211_rateset_11n.rs_rates[i])); 6148e2cf88acSQuaker Fang } 6149e2cf88acSQuaker Fang #endif 6150e2cf88acSQuaker Fang } 6151e2cf88acSQuaker Fang 6152e2cf88acSQuaker Fang /* 6153e2cf88acSQuaker Fang * This function overwrites default configurations of 6154e2cf88acSQuaker Fang * ieee80211com structure in Net80211 module. 6155e2cf88acSQuaker Fang */ 6156e2cf88acSQuaker Fang static void 6157e2cf88acSQuaker Fang iwh_overwrite_ic_default(iwh_sc_t *sc) 6158e2cf88acSQuaker Fang { 6159e2cf88acSQuaker Fang ieee80211com_t *ic = &sc->sc_ic; 6160e2cf88acSQuaker Fang 6161e2cf88acSQuaker Fang sc->sc_newstate = ic->ic_newstate; 6162e2cf88acSQuaker Fang ic->ic_newstate = iwh_newstate; 6163e2cf88acSQuaker Fang ic->ic_node_alloc = iwh_node_alloc; 6164e2cf88acSQuaker Fang ic->ic_node_free = iwh_node_free; 6165e2cf88acSQuaker Fang 6166e2cf88acSQuaker Fang if (sc->sc_ht_conf.ht_support) { 6167e2cf88acSQuaker Fang sc->sc_recv_action = ic->ic_recv_action; 6168e2cf88acSQuaker Fang ic->ic_recv_action = iwh_recv_action; 6169e2cf88acSQuaker Fang sc->sc_send_action = ic->ic_send_action; 6170e2cf88acSQuaker Fang ic->ic_send_action = iwh_send_action; 6171e2cf88acSQuaker Fang 6172e2cf88acSQuaker Fang ic->ic_ampdu_rxmax = sc->sc_ht_conf.ampdu_p.factor; 6173e2cf88acSQuaker Fang ic->ic_ampdu_density = sc->sc_ht_conf.ampdu_p.density; 6174e2cf88acSQuaker Fang ic->ic_ampdu_limit = ic->ic_ampdu_rxmax; 6175e2cf88acSQuaker Fang } 6176e2cf88acSQuaker Fang } 6177e2cf88acSQuaker Fang 6178e2cf88acSQuaker Fang /* 6179e2cf88acSQuaker Fang * This function sets "RX chain selection" feild 6180e2cf88acSQuaker Fang * in RXON command during plumb driver. 6181e2cf88acSQuaker Fang */ 6182e2cf88acSQuaker Fang static void 6183e2cf88acSQuaker Fang iwh_config_rxon_chain(iwh_sc_t *sc) 6184e2cf88acSQuaker Fang { 6185e2cf88acSQuaker Fang ieee80211com_t *ic = &sc->sc_ic; 6186e2cf88acSQuaker Fang ieee80211_node_t *in = ic->ic_bss; 6187e2cf88acSQuaker Fang 6188e2cf88acSQuaker Fang if (3 == sc->sc_ht_conf.valid_chains) { 6189e2cf88acSQuaker Fang sc->sc_config.rx_chain = LE_16((RXON_RX_CHAIN_A_MSK | 6190e2cf88acSQuaker Fang RXON_RX_CHAIN_B_MSK | RXON_RX_CHAIN_C_MSK) << 6191e2cf88acSQuaker Fang RXON_RX_CHAIN_VALID_POS); 6192e2cf88acSQuaker Fang 6193e2cf88acSQuaker Fang sc->sc_config.rx_chain |= LE_16((RXON_RX_CHAIN_A_MSK | 6194e2cf88acSQuaker Fang RXON_RX_CHAIN_B_MSK | RXON_RX_CHAIN_C_MSK) << 6195e2cf88acSQuaker Fang RXON_RX_CHAIN_FORCE_SEL_POS); 6196e2cf88acSQuaker Fang 6197e2cf88acSQuaker Fang sc->sc_config.rx_chain |= LE_16((RXON_RX_CHAIN_A_MSK | 6198e2cf88acSQuaker Fang RXON_RX_CHAIN_B_MSK | RXON_RX_CHAIN_C_MSK) << 6199e2cf88acSQuaker Fang RXON_RX_CHAIN_FORCE_MIMO_SEL_POS); 6200e2cf88acSQuaker Fang } else { 6201e2cf88acSQuaker Fang sc->sc_config.rx_chain = LE_16((RXON_RX_CHAIN_A_MSK | 6202e2cf88acSQuaker Fang RXON_RX_CHAIN_B_MSK) << RXON_RX_CHAIN_VALID_POS); 6203e2cf88acSQuaker Fang 6204e2cf88acSQuaker Fang sc->sc_config.rx_chain |= LE_16((RXON_RX_CHAIN_A_MSK | 6205e2cf88acSQuaker Fang RXON_RX_CHAIN_B_MSK) << RXON_RX_CHAIN_FORCE_SEL_POS); 6206e2cf88acSQuaker Fang 6207e2cf88acSQuaker Fang sc->sc_config.rx_chain |= LE_16((RXON_RX_CHAIN_A_MSK | 6208e2cf88acSQuaker Fang RXON_RX_CHAIN_B_MSK) << 6209e2cf88acSQuaker Fang RXON_RX_CHAIN_FORCE_MIMO_SEL_POS); 6210e2cf88acSQuaker Fang } 6211e2cf88acSQuaker Fang 6212e2cf88acSQuaker Fang sc->sc_config.rx_chain |= LE_16(RXON_RX_CHAIN_DRIVER_FORCE_MSK); 6213e2cf88acSQuaker Fang 6214e2cf88acSQuaker Fang if ((in != NULL) && 6215e2cf88acSQuaker Fang (in->in_flags & IEEE80211_NODE_HT) && 6216e2cf88acSQuaker Fang sc->sc_ht_conf.ht_support) { 6217e2cf88acSQuaker Fang if (3 == sc->sc_ht_conf.valid_chains) { 6218e2cf88acSQuaker Fang sc->sc_config.rx_chain |= LE_16(3 << 6219e2cf88acSQuaker Fang RXON_RX_CHAIN_CNT_POS); 6220e2cf88acSQuaker Fang sc->sc_config.rx_chain |= LE_16(3 << 6221e2cf88acSQuaker Fang RXON_RX_CHAIN_MIMO_CNT_POS); 6222e2cf88acSQuaker Fang } else { 6223e2cf88acSQuaker Fang sc->sc_config.rx_chain |= LE_16(2 << 6224e2cf88acSQuaker Fang RXON_RX_CHAIN_CNT_POS); 6225e2cf88acSQuaker Fang sc->sc_config.rx_chain |= LE_16(2 << 6226e2cf88acSQuaker Fang RXON_RX_CHAIN_MIMO_CNT_POS); 6227e2cf88acSQuaker Fang } 6228e2cf88acSQuaker Fang 6229e2cf88acSQuaker Fang sc->sc_config.rx_chain |= LE_16(1 << 6230e2cf88acSQuaker Fang RXON_RX_CHAIN_MIMO_FORCE_POS); 6231e2cf88acSQuaker Fang } 6232e2cf88acSQuaker Fang 6233e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_RXON, "iwh_config_rxon_chain(): " 6234e2cf88acSQuaker Fang "rxon->rx_chain = %x\n", sc->sc_config.rx_chain)); 6235e2cf88acSQuaker Fang } 6236e2cf88acSQuaker Fang 6237e2cf88acSQuaker Fang /* 6238e2cf88acSQuaker Fang * This function adds AP station into hardware. 6239e2cf88acSQuaker Fang */ 6240e2cf88acSQuaker Fang static int 6241e2cf88acSQuaker Fang iwh_add_ap_sta(iwh_sc_t *sc) 6242e2cf88acSQuaker Fang { 6243e2cf88acSQuaker Fang ieee80211com_t *ic = &sc->sc_ic; 6244e2cf88acSQuaker Fang ieee80211_node_t *in = ic->ic_bss; 6245e2cf88acSQuaker Fang iwh_add_sta_t node; 6246e2cf88acSQuaker Fang uint32_t ampdu_factor, ampdu_density; 6247e2cf88acSQuaker Fang int err = IWH_FAIL; 6248e2cf88acSQuaker Fang 6249e2cf88acSQuaker Fang /* 6250e2cf88acSQuaker Fang * Add AP node into hardware. 6251e2cf88acSQuaker Fang */ 6252e2cf88acSQuaker Fang (void) memset(&node, 0, sizeof (node)); 6253e2cf88acSQuaker Fang IEEE80211_ADDR_COPY(node.sta.addr, in->in_bssid); 6254e2cf88acSQuaker Fang node.mode = STA_MODE_ADD_MSK; 6255e2cf88acSQuaker Fang node.sta.sta_id = IWH_AP_ID; 6256e2cf88acSQuaker Fang 6257e2cf88acSQuaker Fang if (sc->sc_ht_conf.ht_support && 6258e2cf88acSQuaker Fang (in->in_htcap_ie != NULL) && 6259e2cf88acSQuaker Fang (in->in_htcap != 0) && 6260e2cf88acSQuaker Fang (in->in_htparam != 0)) { 6261e2cf88acSQuaker Fang 6262e2cf88acSQuaker Fang if (((in->in_htcap & HT_CAP_MIMO_PS) >> 2) 6263e2cf88acSQuaker Fang == HT_CAP_MIMO_PS_DYNAMIC) { 6264e2cf88acSQuaker Fang node.station_flags |= LE_32(STA_FLG_RTS_MIMO_PROT); 6265e2cf88acSQuaker Fang } 6266e2cf88acSQuaker Fang 6267e2cf88acSQuaker Fang ampdu_factor = in->in_htparam & HT_RX_AMPDU_FACTOR_MSK; 6268e2cf88acSQuaker Fang node.station_flags |= 6269e2cf88acSQuaker Fang LE_32(ampdu_factor << STA_FLG_MAX_AMPDU_POS); 6270e2cf88acSQuaker Fang 6271e2cf88acSQuaker Fang ampdu_density = (in->in_htparam & HT_MPDU_DENSITY_MSK) >> 6272e2cf88acSQuaker Fang HT_MPDU_DENSITY_POS; 6273e2cf88acSQuaker Fang node.station_flags |= 6274e2cf88acSQuaker Fang LE_32(ampdu_density << STA_FLG_AMPDU_DENSITY_POS); 6275e2cf88acSQuaker Fang 6276e2cf88acSQuaker Fang if (in->in_htcap & LE_16(HT_CAP_SUP_WIDTH)) { 6277e2cf88acSQuaker Fang node.station_flags |= 6278e2cf88acSQuaker Fang LE_32(STA_FLG_FAT_EN); 6279e2cf88acSQuaker Fang } 6280e2cf88acSQuaker Fang } 6281e2cf88acSQuaker Fang 6282e2cf88acSQuaker Fang err = iwh_cmd(sc, REPLY_ADD_STA, &node, sizeof (node), 1); 6283e2cf88acSQuaker Fang if (err != IWH_SUCCESS) { 6284e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_add_ap_lq(): " 6285e2cf88acSQuaker Fang "failed to add AP node\n"); 6286e2cf88acSQuaker Fang return (err); 6287e2cf88acSQuaker Fang } 6288e2cf88acSQuaker Fang 6289e2cf88acSQuaker Fang return (err); 6290e2cf88acSQuaker Fang } 6291e2cf88acSQuaker Fang 6292e2cf88acSQuaker Fang /* 6293e2cf88acSQuaker Fang * Each station in the Shirley Peak's internal station table has 6294e2cf88acSQuaker Fang * its own table of 16 TX rates and modulation modes for retrying 6295e2cf88acSQuaker Fang * TX when an ACK is not received. This function replaces the entire 6296e2cf88acSQuaker Fang * table for one station.Station must already be in Shirley Peak's 6297e2cf88acSQuaker Fang * station talbe. 6298e2cf88acSQuaker Fang */ 6299e2cf88acSQuaker Fang static int 6300e2cf88acSQuaker Fang iwh_ap_lq(iwh_sc_t *sc) 6301e2cf88acSQuaker Fang { 6302e2cf88acSQuaker Fang ieee80211com_t *ic = &sc->sc_ic; 6303e2cf88acSQuaker Fang ieee80211_node_t *in = ic->ic_bss; 6304e2cf88acSQuaker Fang iwh_link_quality_cmd_t link_quality; 6305e2cf88acSQuaker Fang const struct ieee80211_rateset *rs_sup = NULL; 6306e2cf88acSQuaker Fang uint32_t masks = 0, rate; 6307e2cf88acSQuaker Fang int i, err = IWH_FAIL; 6308e2cf88acSQuaker Fang 6309e2cf88acSQuaker Fang /* 6310e2cf88acSQuaker Fang * TX_LINK_QUALITY cmd 6311e2cf88acSQuaker Fang */ 6312e2cf88acSQuaker Fang (void) memset(&link_quality, 0, sizeof (link_quality)); 6313e2cf88acSQuaker Fang if (in->in_chan == IEEE80211_CHAN_ANYC) /* skip null node */ 6314e2cf88acSQuaker Fang return (err); 6315e2cf88acSQuaker Fang rs_sup = ieee80211_get_suprates(ic, in->in_chan); 6316e2cf88acSQuaker Fang 6317e2cf88acSQuaker Fang for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { 6318e2cf88acSQuaker Fang if (i < rs_sup->ir_nrates) { 6319e2cf88acSQuaker Fang rate = rs_sup->ir_rates[rs_sup->ir_nrates - i] & 6320e2cf88acSQuaker Fang IEEE80211_RATE_VAL; 6321e2cf88acSQuaker Fang } else { 6322e2cf88acSQuaker Fang rate = 2; 6323e2cf88acSQuaker Fang } 6324e2cf88acSQuaker Fang 6325e2cf88acSQuaker Fang if (2 == rate || 4 == rate || 6326e2cf88acSQuaker Fang 11 == rate || 22 == rate) { 6327e2cf88acSQuaker Fang masks |= LE_32(RATE_MCS_CCK_MSK); 6328e2cf88acSQuaker Fang } 6329e2cf88acSQuaker Fang 6330e2cf88acSQuaker Fang masks |= LE_32(RATE_MCS_ANT_B_MSK); 6331e2cf88acSQuaker Fang 6332e2cf88acSQuaker Fang link_quality.rate_n_flags[i] = 6333e2cf88acSQuaker Fang LE_32(iwh_rate_to_plcp(rate) | masks); 6334e2cf88acSQuaker Fang } 6335e2cf88acSQuaker Fang 6336e2cf88acSQuaker Fang link_quality.general_params.single_stream_ant_msk = LINK_QUAL_ANT_B_MSK; 6337e2cf88acSQuaker Fang link_quality.general_params.dual_stream_ant_msk = LINK_QUAL_ANT_MSK; 6338e2cf88acSQuaker Fang link_quality.agg_params.agg_dis_start_th = 3; 6339e2cf88acSQuaker Fang link_quality.agg_params.agg_time_limit = LE_16(4000); 6340e2cf88acSQuaker Fang link_quality.sta_id = IWH_AP_ID; 6341e2cf88acSQuaker Fang err = iwh_cmd(sc, REPLY_TX_LINK_QUALITY_CMD, &link_quality, 6342e2cf88acSQuaker Fang sizeof (link_quality), 1); 6343e2cf88acSQuaker Fang if (err != IWH_SUCCESS) { 6344e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_ap_lq(): " 6345e2cf88acSQuaker Fang "failed to config link quality table\n"); 6346e2cf88acSQuaker Fang return (err); 6347e2cf88acSQuaker Fang } 6348e2cf88acSQuaker Fang 6349e2cf88acSQuaker Fang #ifdef DEBUG 6350e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_HWRATE, "iwh_ap_lq(): " 6351e2cf88acSQuaker Fang "Rates in HW are as follows:\n")); 6352e2cf88acSQuaker Fang 6353e2cf88acSQuaker Fang for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { 6354e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_HWRATE, 6355e2cf88acSQuaker Fang "Rate %d in HW is %x\n", i, link_quality.rate_n_flags[i])); 6356e2cf88acSQuaker Fang } 6357e2cf88acSQuaker Fang #endif 6358e2cf88acSQuaker Fang 6359e2cf88acSQuaker Fang return (err); 6360e2cf88acSQuaker Fang } 6361e2cf88acSQuaker Fang 6362e2cf88acSQuaker Fang /* 6363e2cf88acSQuaker Fang * When block ACK agreement has been set up between station and AP, 6364e2cf88acSQuaker Fang * Net80211 module will call this function to inform hardware about 6365e2cf88acSQuaker Fang * informations of this BA agreement. 6366e2cf88acSQuaker Fang * When AP wants to delete BA agreement that was originated by it, 6367e2cf88acSQuaker Fang * Net80211 modele will call this function to clean up relevant 6368e2cf88acSQuaker Fang * information in hardware. 6369e2cf88acSQuaker Fang */ 6370e2cf88acSQuaker Fang static void 6371e2cf88acSQuaker Fang iwh_recv_action(struct ieee80211_node *in, 6372e2cf88acSQuaker Fang const uint8_t *frm, const uint8_t *efrm) 6373e2cf88acSQuaker Fang { 6374e2cf88acSQuaker Fang struct ieee80211com *ic; 6375e2cf88acSQuaker Fang iwh_sc_t *sc; 6376e2cf88acSQuaker Fang const struct ieee80211_action *ia; 6377e2cf88acSQuaker Fang uint16_t baparamset, baseqctl; 6378e2cf88acSQuaker Fang uint32_t tid, ssn; 6379e2cf88acSQuaker Fang iwh_add_sta_t node; 6380e2cf88acSQuaker Fang int err = IWH_FAIL; 6381e2cf88acSQuaker Fang 6382e2cf88acSQuaker Fang if ((NULL == in) || (NULL == frm)) { 6383e2cf88acSQuaker Fang return; 6384e2cf88acSQuaker Fang } 6385e2cf88acSQuaker Fang 6386e2cf88acSQuaker Fang ic = in->in_ic; 6387e2cf88acSQuaker Fang if (NULL == ic) { 6388e2cf88acSQuaker Fang return; 6389e2cf88acSQuaker Fang } 6390e2cf88acSQuaker Fang 6391e2cf88acSQuaker Fang sc = (iwh_sc_t *)ic; 6392e2cf88acSQuaker Fang 6393e2cf88acSQuaker Fang sc->sc_recv_action(in, frm, efrm); 6394e2cf88acSQuaker Fang 6395e2cf88acSQuaker Fang ia = (const struct ieee80211_action *)frm; 6396e2cf88acSQuaker Fang if (ia->ia_category != IEEE80211_ACTION_CAT_BA) { 6397e2cf88acSQuaker Fang return; 6398e2cf88acSQuaker Fang } 6399e2cf88acSQuaker Fang 6400e2cf88acSQuaker Fang switch (ia->ia_action) { 6401e2cf88acSQuaker Fang case IEEE80211_ACTION_BA_ADDBA_REQUEST: 6402e2cf88acSQuaker Fang baparamset = *(uint16_t *)(frm + 3); 6403e2cf88acSQuaker Fang baseqctl = *(uint16_t *)(frm + 7); 6404e2cf88acSQuaker Fang 6405e2cf88acSQuaker Fang tid = MS(baparamset, IEEE80211_BAPS_TID); 6406e2cf88acSQuaker Fang ssn = MS(baseqctl, IEEE80211_BASEQ_START); 6407e2cf88acSQuaker Fang 6408e2cf88acSQuaker Fang (void) memset(&node, 0, sizeof (node)); 6409e2cf88acSQuaker Fang IEEE80211_ADDR_COPY(node.sta.addr, in->in_bssid); 6410e2cf88acSQuaker Fang node.mode = STA_MODE_MODIFY_MSK; 6411e2cf88acSQuaker Fang node.sta.sta_id = IWH_AP_ID; 6412e2cf88acSQuaker Fang 6413e2cf88acSQuaker Fang node.station_flags_msk = 0; 6414e2cf88acSQuaker Fang node.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK; 6415e2cf88acSQuaker Fang node.add_immediate_ba_tid = (uint8_t)tid; 6416e2cf88acSQuaker Fang node.add_immediate_ba_ssn = LE_16(ssn); 6417e2cf88acSQuaker Fang 6418e2cf88acSQuaker Fang mutex_enter(&sc->sc_glock); 6419e2cf88acSQuaker Fang err = iwh_cmd(sc, REPLY_ADD_STA, &node, sizeof (node), 1); 6420e2cf88acSQuaker Fang if (err != IWH_SUCCESS) { 6421e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_recv_action(): " 6422e2cf88acSQuaker Fang "failed to setup RX block ACK\n"); 6423e2cf88acSQuaker Fang mutex_exit(&sc->sc_glock); 6424e2cf88acSQuaker Fang return; 6425e2cf88acSQuaker Fang } 6426e2cf88acSQuaker Fang mutex_exit(&sc->sc_glock); 6427e2cf88acSQuaker Fang 6428e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_BA, "iwh_recv_action(): " 6429e2cf88acSQuaker Fang "RX block ACK " 6430e2cf88acSQuaker Fang "was setup on TID %d and SSN is %d.\n", tid, ssn)); 6431e2cf88acSQuaker Fang 6432e2cf88acSQuaker Fang return; 6433e2cf88acSQuaker Fang 6434e2cf88acSQuaker Fang case IEEE80211_ACTION_BA_DELBA: 6435e2cf88acSQuaker Fang baparamset = *(uint16_t *)(frm + 2); 6436e2cf88acSQuaker Fang 6437e2cf88acSQuaker Fang if ((baparamset & IEEE80211_DELBAPS_INIT) == 0) { 6438e2cf88acSQuaker Fang return; 6439e2cf88acSQuaker Fang } 6440e2cf88acSQuaker Fang 6441e2cf88acSQuaker Fang tid = MS(baparamset, IEEE80211_DELBAPS_TID); 6442e2cf88acSQuaker Fang 6443e2cf88acSQuaker Fang (void) memset(&node, 0, sizeof (node)); 6444e2cf88acSQuaker Fang IEEE80211_ADDR_COPY(node.sta.addr, in->in_bssid); 6445e2cf88acSQuaker Fang node.mode = STA_MODE_MODIFY_MSK; 6446e2cf88acSQuaker Fang node.sta.sta_id = IWH_AP_ID; 6447e2cf88acSQuaker Fang 6448e2cf88acSQuaker Fang node.station_flags_msk = 0; 6449e2cf88acSQuaker Fang node.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; 6450e2cf88acSQuaker Fang node.add_immediate_ba_tid = (uint8_t)tid; 6451e2cf88acSQuaker Fang 6452e2cf88acSQuaker Fang mutex_enter(&sc->sc_glock); 6453e2cf88acSQuaker Fang err = iwh_cmd(sc, REPLY_ADD_STA, &node, sizeof (node), 1); 6454e2cf88acSQuaker Fang if (err != IWH_SUCCESS) { 6455e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_recv_action(): " 6456e2cf88acSQuaker Fang "failed to delete RX block ACK\n"); 6457e2cf88acSQuaker Fang mutex_exit(&sc->sc_glock); 6458e2cf88acSQuaker Fang return; 6459e2cf88acSQuaker Fang } 6460e2cf88acSQuaker Fang mutex_exit(&sc->sc_glock); 6461e2cf88acSQuaker Fang 6462e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_BA, "iwh_recv_action(): " 6463e2cf88acSQuaker Fang "RX block ACK " 6464e2cf88acSQuaker Fang "was deleted on TID %d.\n", tid)); 6465e2cf88acSQuaker Fang 6466e2cf88acSQuaker Fang return; 6467e2cf88acSQuaker Fang } 6468e2cf88acSQuaker Fang } 6469e2cf88acSQuaker Fang 6470e2cf88acSQuaker Fang /* 6471e2cf88acSQuaker Fang * When local station wants to delete BA agreement that was originated by AP, 6472e2cf88acSQuaker Fang * Net80211 module will call this function to clean up relevant information 6473e2cf88acSQuaker Fang * in hardware. 6474e2cf88acSQuaker Fang */ 6475e2cf88acSQuaker Fang static int 6476e2cf88acSQuaker Fang iwh_send_action(struct ieee80211_node *in, 6477e2cf88acSQuaker Fang int category, int action, uint16_t args[4]) 6478e2cf88acSQuaker Fang { 6479e2cf88acSQuaker Fang struct ieee80211com *ic; 6480e2cf88acSQuaker Fang iwh_sc_t *sc; 6481e2cf88acSQuaker Fang uint32_t tid; 6482e2cf88acSQuaker Fang iwh_add_sta_t node; 6483e2cf88acSQuaker Fang int ret = EIO; 6484e2cf88acSQuaker Fang int err = IWH_FAIL; 6485e2cf88acSQuaker Fang 6486e2cf88acSQuaker Fang 6487e2cf88acSQuaker Fang if (NULL == in) { 6488e2cf88acSQuaker Fang return (ret); 6489e2cf88acSQuaker Fang } 6490e2cf88acSQuaker Fang 6491e2cf88acSQuaker Fang ic = in->in_ic; 6492e2cf88acSQuaker Fang if (NULL == ic) { 6493e2cf88acSQuaker Fang return (ret); 6494e2cf88acSQuaker Fang } 6495e2cf88acSQuaker Fang 6496e2cf88acSQuaker Fang sc = (iwh_sc_t *)ic; 6497e2cf88acSQuaker Fang 6498e2cf88acSQuaker Fang ret = sc->sc_send_action(in, category, action, args); 6499e2cf88acSQuaker Fang 6500e2cf88acSQuaker Fang if (category != IEEE80211_ACTION_CAT_BA) { 6501e2cf88acSQuaker Fang return (ret); 6502e2cf88acSQuaker Fang } 6503e2cf88acSQuaker Fang 6504e2cf88acSQuaker Fang switch (action) { 6505e2cf88acSQuaker Fang case IEEE80211_ACTION_BA_DELBA: 6506e2cf88acSQuaker Fang if (IEEE80211_DELBAPS_INIT == args[1]) { 6507e2cf88acSQuaker Fang return (ret); 6508e2cf88acSQuaker Fang } 6509e2cf88acSQuaker Fang 6510e2cf88acSQuaker Fang tid = args[0]; 6511e2cf88acSQuaker Fang 6512e2cf88acSQuaker Fang (void) memset(&node, 0, sizeof (node)); 6513e2cf88acSQuaker Fang IEEE80211_ADDR_COPY(node.sta.addr, in->in_bssid); 6514e2cf88acSQuaker Fang node.mode = STA_MODE_MODIFY_MSK; 6515e2cf88acSQuaker Fang node.sta.sta_id = IWH_AP_ID; 6516e2cf88acSQuaker Fang 6517e2cf88acSQuaker Fang node.station_flags_msk = 0; 6518e2cf88acSQuaker Fang node.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; 6519e2cf88acSQuaker Fang node.add_immediate_ba_tid = (uint8_t)tid; 6520e2cf88acSQuaker Fang 6521e2cf88acSQuaker Fang mutex_enter(&sc->sc_glock); 6522e2cf88acSQuaker Fang err = iwh_cmd(sc, REPLY_ADD_STA, &node, sizeof (node), 1); 6523e2cf88acSQuaker Fang if (err != IWH_SUCCESS) { 6524e2cf88acSQuaker Fang cmn_err(CE_WARN, "iwh_send_action(): " 6525e2cf88acSQuaker Fang "failed to delete RX balock ACK\n"); 6526e2cf88acSQuaker Fang mutex_exit(&sc->sc_glock); 6527e2cf88acSQuaker Fang return (EIO); 6528e2cf88acSQuaker Fang } 6529e2cf88acSQuaker Fang mutex_exit(&sc->sc_glock); 6530e2cf88acSQuaker Fang 6531e2cf88acSQuaker Fang IWH_DBG((IWH_DEBUG_BA, "iwh_send_action(): " 6532e2cf88acSQuaker Fang "RX block ACK " 6533e2cf88acSQuaker Fang "was deleted on TID %d.\n", tid)); 6534e2cf88acSQuaker Fang 6535e2cf88acSQuaker Fang break; 6536e2cf88acSQuaker Fang } 6537e2cf88acSQuaker Fang 6538e2cf88acSQuaker Fang return (ret); 6539e2cf88acSQuaker Fang } 65407d483bc1Sfei feng - Sun Microsystems - Beijing China 65417d483bc1Sfei feng - Sun Microsystems - Beijing China static int 65427d483bc1Sfei feng - Sun Microsystems - Beijing China iwh_reset_hw(iwh_sc_t *sc) 65437d483bc1Sfei feng - Sun Microsystems - Beijing China { 65447d483bc1Sfei feng - Sun Microsystems - Beijing China uint32_t tmp; 65457d483bc1Sfei feng - Sun Microsystems - Beijing China int n; 65467d483bc1Sfei feng - Sun Microsystems - Beijing China 65477d483bc1Sfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_HW_IF_CONFIG_REG); 65487d483bc1Sfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_HW_IF_CONFIG_REG, 65497d483bc1Sfei feng - Sun Microsystems - Beijing China tmp | CSR_HW_IF_CONFIG_REG_BITS_NIC_READY); 65507d483bc1Sfei feng - Sun Microsystems - Beijing China 65517d483bc1Sfei feng - Sun Microsystems - Beijing China /* 65527d483bc1Sfei feng - Sun Microsystems - Beijing China * wait for HW ready 65537d483bc1Sfei feng - Sun Microsystems - Beijing China */ 65547d483bc1Sfei feng - Sun Microsystems - Beijing China for (n = 0; n < 5; n++) { 65557d483bc1Sfei feng - Sun Microsystems - Beijing China if (IWH_READ(sc, CSR_HW_IF_CONFIG_REG) & 65567d483bc1Sfei feng - Sun Microsystems - Beijing China CSR_HW_IF_CONFIG_REG_BITS_NIC_READY) { 65577d483bc1Sfei feng - Sun Microsystems - Beijing China break; 65587d483bc1Sfei feng - Sun Microsystems - Beijing China } 65597d483bc1Sfei feng - Sun Microsystems - Beijing China DELAY(10); 65607d483bc1Sfei feng - Sun Microsystems - Beijing China } 65617d483bc1Sfei feng - Sun Microsystems - Beijing China 65627d483bc1Sfei feng - Sun Microsystems - Beijing China if (n != 5) { 65637d483bc1Sfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 65647d483bc1Sfei feng - Sun Microsystems - Beijing China } 65657d483bc1Sfei feng - Sun Microsystems - Beijing China 65667d483bc1Sfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_HW_IF_CONFIG_REG); 65677d483bc1Sfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_HW_IF_CONFIG_REG, 65687d483bc1Sfei feng - Sun Microsystems - Beijing China tmp | CSR_HW_IF_CONFIG_REG_BITS_PREPARE); 65697d483bc1Sfei feng - Sun Microsystems - Beijing China 65707d483bc1Sfei feng - Sun Microsystems - Beijing China for (n = 0; n < 15000; n++) { 65717d483bc1Sfei feng - Sun Microsystems - Beijing China if (0 == (IWH_READ(sc, CSR_HW_IF_CONFIG_REG) & 65727d483bc1Sfei feng - Sun Microsystems - Beijing China CSR_HW_IF_CONFIG_REG_BITS_NIC_PREPARE_DONE)) { 65737d483bc1Sfei feng - Sun Microsystems - Beijing China break; 65747d483bc1Sfei feng - Sun Microsystems - Beijing China } 65757d483bc1Sfei feng - Sun Microsystems - Beijing China DELAY(10); 65767d483bc1Sfei feng - Sun Microsystems - Beijing China } 65777d483bc1Sfei feng - Sun Microsystems - Beijing China 65787d483bc1Sfei feng - Sun Microsystems - Beijing China if (15000 == n) { 65797d483bc1Sfei feng - Sun Microsystems - Beijing China return (ETIMEDOUT); 65807d483bc1Sfei feng - Sun Microsystems - Beijing China } 65817d483bc1Sfei feng - Sun Microsystems - Beijing China 65827d483bc1Sfei feng - Sun Microsystems - Beijing China tmp = IWH_READ(sc, CSR_HW_IF_CONFIG_REG); 65837d483bc1Sfei feng - Sun Microsystems - Beijing China IWH_WRITE(sc, CSR_HW_IF_CONFIG_REG, 65847d483bc1Sfei feng - Sun Microsystems - Beijing China tmp | CSR_HW_IF_CONFIG_REG_BITS_NIC_READY); 65857d483bc1Sfei feng - Sun Microsystems - Beijing China 65867d483bc1Sfei feng - Sun Microsystems - Beijing China /* 65877d483bc1Sfei feng - Sun Microsystems - Beijing China * wait for HW ready 65887d483bc1Sfei feng - Sun Microsystems - Beijing China */ 65897d483bc1Sfei feng - Sun Microsystems - Beijing China for (n = 0; n < 5; n++) { 65907d483bc1Sfei feng - Sun Microsystems - Beijing China if (IWH_READ(sc, CSR_HW_IF_CONFIG_REG) & 65917d483bc1Sfei feng - Sun Microsystems - Beijing China CSR_HW_IF_CONFIG_REG_BITS_NIC_READY) { 65927d483bc1Sfei feng - Sun Microsystems - Beijing China break; 65937d483bc1Sfei feng - Sun Microsystems - Beijing China } 65947d483bc1Sfei feng - Sun Microsystems - Beijing China DELAY(10); 65957d483bc1Sfei feng - Sun Microsystems - Beijing China } 65967d483bc1Sfei feng - Sun Microsystems - Beijing China 65977d483bc1Sfei feng - Sun Microsystems - Beijing China if (n != 5) { 65987d483bc1Sfei feng - Sun Microsystems - Beijing China return (IWH_SUCCESS); 65997d483bc1Sfei feng - Sun Microsystems - Beijing China } else { 66007d483bc1Sfei feng - Sun Microsystems - Beijing China return (ETIMEDOUT); 66017d483bc1Sfei feng - Sun Microsystems - Beijing China } 66027d483bc1Sfei feng - Sun Microsystems - Beijing China } 6603