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
_init(void)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
_fini(void)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
_info(struct modinfo * mip)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
iwh_dbg(uint32_t flags,const char * fmt,...)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
iwh_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)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
iwh_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)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
iwh_destroy_locks(iwh_sc_t * sc)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
iwh_alloc_dma_mem(iwh_sc_t * sc,size_t memsize,ddi_dma_attr_t * dma_attr_p,ddi_device_acc_attr_t * acc_attr_p,uint_t dma_flags,iwh_dma_t * dma_p)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
iwh_free_dma_mem(iwh_dma_t * dma_p)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
iwh_alloc_fw_dma(iwh_sc_t * sc)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
iwh_free_fw_dma(iwh_sc_t * sc)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
iwh_alloc_shared(iwh_sc_t * sc)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
iwh_free_shared(iwh_sc_t * sc)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
iwh_alloc_kw(iwh_sc_t * sc)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
iwh_free_kw(iwh_sc_t * sc)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
iwh_alloc_rx_ring(iwh_sc_t * sc)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
iwh_reset_rx_ring(iwh_sc_t * sc)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
iwh_free_rx_ring(iwh_sc_t * sc)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
iwh_alloc_tx_ring(iwh_sc_t * sc,iwh_tx_ring_t * ring,int slots,int qid)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
iwh_reset_tx_ring(iwh_sc_t * sc,iwh_tx_ring_t * ring)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
iwh_free_tx_ring(iwh_tx_ring_t * ring)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
iwh_ring_init(iwh_sc_t * sc)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
iwh_ring_free(iwh_sc_t * sc)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 *
iwh_node_alloc(ieee80211com_t * ic)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
iwh_node_free(ieee80211_node_t * in)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
iwh_newstate(ieee80211com_t * ic,enum ieee80211_state nstate,int arg)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
iwh_mac_access_enter(iwh_sc_t * sc)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
iwh_mac_access_exit(iwh_sc_t * sc)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
iwh_mem_write(iwh_sc_t * sc,uint32_t addr,uint32_t data)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
iwh_reg_read(iwh_sc_t * sc,uint32_t addr)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
iwh_reg_write(iwh_sc_t * sc,uint32_t addr,uint32_t data)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
iwh_load_init_firmware(iwh_sc_t * sc)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
iwh_load_run_firmware(iwh_sc_t * sc)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
iwh_rx_phy_intr(iwh_sc_t * sc,iwh_rx_desc_t * desc)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
iwh_rx_mpdu_intr(iwh_sc_t * sc,iwh_rx_desc_t * desc)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
iwh_tx_intr(iwh_sc_t * sc,iwh_rx_desc_t * desc)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
iwh_cmd_intr(iwh_sc_t * sc,iwh_rx_desc_t * desc)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
iwh_ucode_alive(iwh_sc_t * sc,iwh_rx_desc_t * desc)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
iwh_rx_softintr(caddr_t arg,caddr_t unused)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
iwh_intr(caddr_t arg,caddr_t unused)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
iwh_rate_to_plcp(int rate)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 *
iwh_m_tx(void * arg,mblk_t * mp)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
iwh_send(ieee80211com_t * ic,mblk_t * mp,uint8_t type)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
iwh_m_ioctl(void * arg,queue_t * wq,mblk_t * mp)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
iwh_m_getprop(void * arg,const char * pr_name,mac_prop_id_t wldp_pr_num,uint_t wldp_length,void * wldp_buf)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
iwh_m_propinfo(void * arg,const char * pr_name,mac_prop_id_t wldp_pr_num,mac_prop_info_handle_t mph)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
iwh_m_setprop(void * arg,const char * pr_name,mac_prop_id_t wldp_pr_num,uint_t wldp_length,const void * wldp_buf)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
iwh_m_stat(void * arg,uint_t stat,uint64_t * val)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
iwh_m_start(void * arg)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
iwh_m_stop(void * arg)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
iwh_m_unicst(void * arg,const uint8_t * macaddr)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
iwh_m_multicst(void * arg,boolean_t add,const uint8_t * m)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
iwh_m_promisc(void * arg,boolean_t on)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
iwh_thread(iwh_sc_t * sc)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
iwh_cmd(iwh_sc_t * sc,int code,const void * buf,int size,int async)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
iwh_set_led(iwh_sc_t * sc,uint8_t id,uint8_t off,uint8_t on)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
iwh_hw_set_before_auth(iwh_sc_t * sc)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
iwh_scan(iwh_sc_t * sc)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
iwh_config(iwh_sc_t * sc)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
iwh_quiesce(dev_info_t * dip)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
iwh_stop_master(iwh_sc_t * sc)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
iwh_power_up(iwh_sc_t * sc)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
iwh_preinit(iwh_sc_t * sc)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
iwh_eep_sem_down(iwh_sc_t * sc)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
iwh_eep_sem_up(iwh_sc_t * sc)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
iwh_eep_load(iwh_sc_t * sc)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
iwh_get_mac_from_eep(iwh_sc_t * sc)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
iwh_init(iwh_sc_t * sc)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
iwh_stop(iwh_sc_t * sc)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
iwh_amrr_init(iwh_amrr_t * amrr)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
iwh_amrr_timeout(iwh_sc_t * sc)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
iwh_is_max_rate(ieee80211_node_t * in)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
iwh_is_min_rate(ieee80211_node_t * in)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
iwh_increase_rate(ieee80211_node_t * in)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
iwh_decrease_rate(ieee80211_node_t * in)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
iwh_amrr_ratectl(void * arg,ieee80211_node_t * in)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 *
iwh_eep_addr_trans(iwh_sc_t * sc,uint32_t indi_addr)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
iwh_put_seg_fw(iwh_sc_t * sc,uint32_t addr_s,uint32_t addr_d,uint32_t len)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
iwh_alive_common(iwh_sc_t * sc)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
iwh_save_calib_result(iwh_sc_t * sc,iwh_rx_desc_t * desc)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
iwh_tx_power_table(iwh_sc_t * sc,int async)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
iwh_release_calib_buffer(iwh_sc_t * sc)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
iwh_init_common(iwh_sc_t * sc)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
iwh_fast_recover(iwh_sc_t * sc)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
iwh_run_state_config(iwh_sc_t * sc)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
iwh_wme_update(ieee80211com_t * ic)5848e2cf88acSQuaker Fang iwh_wme_update(ieee80211com_t *ic)
5849e2cf88acSQuaker Fang {
5850e2cf88acSQuaker Fang return (0);
5851e2cf88acSQuaker Fang }
5852e2cf88acSQuaker Fang
5853e2cf88acSQuaker Fang static int
iwh_wme_to_qos_ac(int wme_ac)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
iwh_cw_e_to_cw(uint8_t cw_e)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
iwh_wmeparam_check(struct wmeParams * wmeparam)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
iwh_qosparam_to_hw(iwh_sc_t * sc,int async)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
iwh_wme_tid_qos_ac(int tid)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
iwh_qos_ac_to_txq(int qos_ac)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
iwh_wme_tid_to_txq(int tid)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
iwh_init_ht_conf(iwh_sc_t * sc)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
iwh_overwrite_11n_rateset(iwh_sc_t * sc)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
iwh_overwrite_ic_default(iwh_sc_t * sc)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
iwh_config_rxon_chain(iwh_sc_t * sc)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
iwh_add_ap_sta(iwh_sc_t * sc)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
iwh_ap_lq(iwh_sc_t * sc)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
iwh_recv_action(struct ieee80211_node * in,const uint8_t * frm,const uint8_t * efrm)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
iwh_send_action(struct ieee80211_node * in,int category,int action,uint16_t args[4])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
iwh_reset_hw(iwh_sc_t * sc)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