xref: /illumos-gate/usr/src/uts/common/io/mwl/mwl.c (revision d3351b34)
1d8d81063Sfei feng - Sun Microsystems - Beijing China /*
20dc2366fSVenugopal Iyer  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
3d8d81063Sfei feng - Sun Microsystems - Beijing China  * Use is subject to license terms.
4d8d81063Sfei feng - Sun Microsystems - Beijing China  */
5d8d81063Sfei feng - Sun Microsystems - Beijing China 
6d8d81063Sfei feng - Sun Microsystems - Beijing China /*
7d8d81063Sfei feng - Sun Microsystems - Beijing China  * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
8d8d81063Sfei feng - Sun Microsystems - Beijing China  * Copyright (c) 2007-2008 Marvell Semiconductor, Inc.
9d8d81063Sfei feng - Sun Microsystems - Beijing China  * All rights reserved.
10d8d81063Sfei feng - Sun Microsystems - Beijing China  *
11d8d81063Sfei feng - Sun Microsystems - Beijing China  * Redistribution and use in source and binary forms, with or without
12d8d81063Sfei feng - Sun Microsystems - Beijing China  * modification, are permitted provided that the following conditions
13d8d81063Sfei feng - Sun Microsystems - Beijing China  * are met:
14d8d81063Sfei feng - Sun Microsystems - Beijing China  * 1. Redistributions of source code must retain the above copyright
15d8d81063Sfei feng - Sun Microsystems - Beijing China  *    notice, this list of conditions and the following disclaimer,
16d8d81063Sfei feng - Sun Microsystems - Beijing China  *    without modification.
17d8d81063Sfei feng - Sun Microsystems - Beijing China  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18d8d81063Sfei feng - Sun Microsystems - Beijing China  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
19d8d81063Sfei feng - Sun Microsystems - Beijing China  *    redistribution must be conditioned upon including a substantially
20d8d81063Sfei feng - Sun Microsystems - Beijing China  *    similar Disclaimer requirement for further binary redistribution.
21d8d81063Sfei feng - Sun Microsystems - Beijing China  *
22d8d81063Sfei feng - Sun Microsystems - Beijing China  * NO WARRANTY
23d8d81063Sfei feng - Sun Microsystems - Beijing China  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24d8d81063Sfei feng - Sun Microsystems - Beijing China  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25d8d81063Sfei feng - Sun Microsystems - Beijing China  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
26d8d81063Sfei feng - Sun Microsystems - Beijing China  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
27d8d81063Sfei feng - Sun Microsystems - Beijing China  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
28d8d81063Sfei feng - Sun Microsystems - Beijing China  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29d8d81063Sfei feng - Sun Microsystems - Beijing China  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30d8d81063Sfei feng - Sun Microsystems - Beijing China  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
31d8d81063Sfei feng - Sun Microsystems - Beijing China  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32d8d81063Sfei feng - Sun Microsystems - Beijing China  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33d8d81063Sfei feng - Sun Microsystems - Beijing China  * THE POSSIBILITY OF SUCH DAMAGES.
34d8d81063Sfei feng - Sun Microsystems - Beijing China  */
35d8d81063Sfei feng - Sun Microsystems - Beijing China 
36*d3351b34SJohn Levon /*
37*d3351b34SJohn Levon  * Copyright 2019 Joyent, Inc.
38*d3351b34SJohn Levon  */
39*d3351b34SJohn Levon 
40d8d81063Sfei feng - Sun Microsystems - Beijing China /*
41d8d81063Sfei feng - Sun Microsystems - Beijing China  * Driver for the Marvell 88W8363 Wireless LAN controller.
42d8d81063Sfei feng - Sun Microsystems - Beijing China  */
43d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/stat.h>
44d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/dlpi.h>
45d8d81063Sfei feng - Sun Microsystems - Beijing China #include <inet/common.h>
46d8d81063Sfei feng - Sun Microsystems - Beijing China #include <inet/mi.h>
47d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/stream.h>
48d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/errno.h>
49d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/stropts.h>
50d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/stat.h>
51d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/sunddi.h>
52d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/strsubr.h>
53d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/strsun.h>
54d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/pci.h>
55d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/mac_provider.h>
56d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/mac_wifi.h>
57d8d81063Sfei feng - Sun Microsystems - Beijing China #include <sys/net80211.h>
58d8d81063Sfei feng - Sun Microsystems - Beijing China #include <inet/wifi_ioctl.h>
59d8d81063Sfei feng - Sun Microsystems - Beijing China 
60d8d81063Sfei feng - Sun Microsystems - Beijing China #include "mwl_var.h"
61d8d81063Sfei feng - Sun Microsystems - Beijing China 
62d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd);
63d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd);
64d8d81063Sfei feng - Sun Microsystems - Beijing China static int mwl_quiesce(dev_info_t *devinfo);
65d8d81063Sfei feng - Sun Microsystems - Beijing China 
66d8d81063Sfei feng - Sun Microsystems - Beijing China DDI_DEFINE_STREAM_OPS(mwl_dev_ops, nulldev, nulldev, mwl_attach, mwl_detach,
67d8d81063Sfei feng - Sun Microsystems - Beijing China     nodev, NULL, D_MP, NULL, mwl_quiesce);
68d8d81063Sfei feng - Sun Microsystems - Beijing China 
69d8d81063Sfei feng - Sun Microsystems - Beijing China static struct modldrv mwl_modldrv = {
70d8d81063Sfei feng - Sun Microsystems - Beijing China 	&mod_driverops,	/* Type of module.  This one is a driver */
71d8d81063Sfei feng - Sun Microsystems - Beijing China 	"Marvell 88W8363 WiFi driver v1.1",	/* short description */
72d8d81063Sfei feng - Sun Microsystems - Beijing China 	&mwl_dev_ops	/* driver specific ops */
73d8d81063Sfei feng - Sun Microsystems - Beijing China };
74d8d81063Sfei feng - Sun Microsystems - Beijing China 
75d8d81063Sfei feng - Sun Microsystems - Beijing China static struct modlinkage modlinkage = {
76d8d81063Sfei feng - Sun Microsystems - Beijing China 	MODREV_1, (void *)&mwl_modldrv, NULL
77d8d81063Sfei feng - Sun Microsystems - Beijing China };
78d8d81063Sfei feng - Sun Microsystems - Beijing China 
79d8d81063Sfei feng - Sun Microsystems - Beijing China static void *mwl_soft_state_p = NULL;
80d8d81063Sfei feng - Sun Microsystems - Beijing China 
81d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_m_stat(void *,  uint_t, uint64_t *);
82d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_m_start(void *);
83d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_m_stop(void *);
84d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_m_promisc(void *, boolean_t);
85d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_m_multicst(void *, boolean_t, const uint8_t *);
86d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_m_unicst(void *, const uint8_t *);
87d8d81063Sfei feng - Sun Microsystems - Beijing China static mblk_t	*mwl_m_tx(void *, mblk_t *);
88d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_m_ioctl(void *, queue_t *, mblk_t *);
89d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_m_setprop(void *arg, const char *pr_name,
90d8d81063Sfei feng - Sun Microsystems - Beijing China 		    mac_prop_id_t wldp_pr_num,
91d8d81063Sfei feng - Sun Microsystems - Beijing China 		    uint_t wldp_length, const void *wldp_buf);
92d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_m_getprop(void *arg, const char *pr_name,
930dc2366fSVenugopal Iyer 		    mac_prop_id_t wldp_pr_num, uint_t wldp_length,
940dc2366fSVenugopal Iyer 		    void *wldp_buf);
950dc2366fSVenugopal Iyer static void	mwl_m_propinfo(void *, const char *, mac_prop_id_t,
960dc2366fSVenugopal Iyer     mac_prop_info_handle_t);
97d8d81063Sfei feng - Sun Microsystems - Beijing China 
98d8d81063Sfei feng - Sun Microsystems - Beijing China static mac_callbacks_t mwl_m_callbacks = {
990dc2366fSVenugopal Iyer 	MC_IOCTL | MC_SETPROP | MC_GETPROP | MC_PROPINFO,
100d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_m_stat,
101d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_m_start,
102d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_m_stop,
103d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_m_promisc,
104d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_m_multicst,
105d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_m_unicst,
106d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_m_tx,
1070dc2366fSVenugopal Iyer 	NULL,
108d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_m_ioctl,
109d8d81063Sfei feng - Sun Microsystems - Beijing China 	NULL,
110d8d81063Sfei feng - Sun Microsystems - Beijing China 	NULL,
111d8d81063Sfei feng - Sun Microsystems - Beijing China 	NULL,
112d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_m_setprop,
1130dc2366fSVenugopal Iyer 	mwl_m_getprop,
1140dc2366fSVenugopal Iyer 	mwl_m_propinfo
115d8d81063Sfei feng - Sun Microsystems - Beijing China };
116d8d81063Sfei feng - Sun Microsystems - Beijing China 
117d8d81063Sfei feng - Sun Microsystems - Beijing China #define	MWL_DBG_ATTACH		(1 << 0)
118d8d81063Sfei feng - Sun Microsystems - Beijing China #define	MWL_DBG_DMA		(1 << 1)
119d8d81063Sfei feng - Sun Microsystems - Beijing China #define	MWL_DBG_FW		(1 << 2)
120d8d81063Sfei feng - Sun Microsystems - Beijing China #define	MWL_DBG_HW		(1 << 3)
121d8d81063Sfei feng - Sun Microsystems - Beijing China #define	MWL_DBG_INTR		(1 << 4)
122d8d81063Sfei feng - Sun Microsystems - Beijing China #define	MWL_DBG_RX		(1 << 5)
123d8d81063Sfei feng - Sun Microsystems - Beijing China #define	MWL_DBG_TX		(1 << 6)
124d8d81063Sfei feng - Sun Microsystems - Beijing China #define	MWL_DBG_CMD		(1 << 7)
125d8d81063Sfei feng - Sun Microsystems - Beijing China #define	MWL_DBG_CRYPTO		(1 << 8)
126d8d81063Sfei feng - Sun Microsystems - Beijing China #define	MWL_DBG_SR		(1 << 9)
127d8d81063Sfei feng - Sun Microsystems - Beijing China #define	MWL_DBG_MSG		(1 << 10)
128d8d81063Sfei feng - Sun Microsystems - Beijing China 
129d8d81063Sfei feng - Sun Microsystems - Beijing China uint32_t mwl_dbg_flags = 0x0;
130d8d81063Sfei feng - Sun Microsystems - Beijing China 
131d8d81063Sfei feng - Sun Microsystems - Beijing China #ifdef DEBUG
132d8d81063Sfei feng - Sun Microsystems - Beijing China #define	MWL_DBG	\
133d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_debug
134d8d81063Sfei feng - Sun Microsystems - Beijing China #else
135*d3351b34SJohn Levon #define	MWL_DBG(...) (void)(0)
136d8d81063Sfei feng - Sun Microsystems - Beijing China #endif
137d8d81063Sfei feng - Sun Microsystems - Beijing China 
138d8d81063Sfei feng - Sun Microsystems - Beijing China /*
139d8d81063Sfei feng - Sun Microsystems - Beijing China  * PIO access attributes for registers
140d8d81063Sfei feng - Sun Microsystems - Beijing China  */
141d8d81063Sfei feng - Sun Microsystems - Beijing China static ddi_device_acc_attr_t mwl_reg_accattr = {
142d8d81063Sfei feng - Sun Microsystems - Beijing China 	DDI_DEVICE_ATTR_V0,
143d8d81063Sfei feng - Sun Microsystems - Beijing China 	DDI_STRUCTURE_LE_ACC,
144d8d81063Sfei feng - Sun Microsystems - Beijing China 	DDI_STRICTORDER_ACC,
145d8d81063Sfei feng - Sun Microsystems - Beijing China 	DDI_DEFAULT_ACC
146d8d81063Sfei feng - Sun Microsystems - Beijing China };
147d8d81063Sfei feng - Sun Microsystems - Beijing China 
148d8d81063Sfei feng - Sun Microsystems - Beijing China static ddi_device_acc_attr_t mwl_cmdbuf_accattr = {
149d8d81063Sfei feng - Sun Microsystems - Beijing China 	DDI_DEVICE_ATTR_V0,
150d8d81063Sfei feng - Sun Microsystems - Beijing China 	DDI_NEVERSWAP_ACC,
151d8d81063Sfei feng - Sun Microsystems - Beijing China 	DDI_STRICTORDER_ACC,
152d8d81063Sfei feng - Sun Microsystems - Beijing China 	DDI_DEFAULT_ACC
153d8d81063Sfei feng - Sun Microsystems - Beijing China };
154d8d81063Sfei feng - Sun Microsystems - Beijing China 
155d8d81063Sfei feng - Sun Microsystems - Beijing China /*
156d8d81063Sfei feng - Sun Microsystems - Beijing China  * DMA access attributes for descriptors and bufs: NOT to be byte swapped.
157d8d81063Sfei feng - Sun Microsystems - Beijing China  */
158d8d81063Sfei feng - Sun Microsystems - Beijing China static ddi_device_acc_attr_t mwl_desc_accattr = {
159d8d81063Sfei feng - Sun Microsystems - Beijing China 	DDI_DEVICE_ATTR_V0,
160d8d81063Sfei feng - Sun Microsystems - Beijing China 	DDI_NEVERSWAP_ACC,
161d8d81063Sfei feng - Sun Microsystems - Beijing China 	DDI_STRICTORDER_ACC,
162d8d81063Sfei feng - Sun Microsystems - Beijing China 	DDI_DEFAULT_ACC
163d8d81063Sfei feng - Sun Microsystems - Beijing China };
164d8d81063Sfei feng - Sun Microsystems - Beijing China 
165d8d81063Sfei feng - Sun Microsystems - Beijing China static ddi_device_acc_attr_t mwl_buf_accattr = {
166d8d81063Sfei feng - Sun Microsystems - Beijing China 	DDI_DEVICE_ATTR_V0,
167d8d81063Sfei feng - Sun Microsystems - Beijing China 	DDI_NEVERSWAP_ACC,
168d8d81063Sfei feng - Sun Microsystems - Beijing China 	DDI_STRICTORDER_ACC,
169d8d81063Sfei feng - Sun Microsystems - Beijing China 	DDI_DEFAULT_ACC
170d8d81063Sfei feng - Sun Microsystems - Beijing China };
171d8d81063Sfei feng - Sun Microsystems - Beijing China 
172d8d81063Sfei feng - Sun Microsystems - Beijing China /*
173d8d81063Sfei feng - Sun Microsystems - Beijing China  * Describes the chip's DMA engine
174d8d81063Sfei feng - Sun Microsystems - Beijing China  */
175d8d81063Sfei feng - Sun Microsystems - Beijing China static ddi_dma_attr_t mwl_dma_attr = {
176d8d81063Sfei feng - Sun Microsystems - Beijing China 	DMA_ATTR_V0,			/* dma_attr version */
177d8d81063Sfei feng - Sun Microsystems - Beijing China 	0x0000000000000000ull,		/* dma_attr_addr_lo */
178d8d81063Sfei feng - Sun Microsystems - Beijing China 	0xFFFFFFFF,			/* dma_attr_addr_hi */
179d8d81063Sfei feng - Sun Microsystems - Beijing China 	0x00000000FFFFFFFFull,		/* dma_attr_count_max */
180d8d81063Sfei feng - Sun Microsystems - Beijing China 	0x0000000000000001ull,		/* dma_attr_align */
181d8d81063Sfei feng - Sun Microsystems - Beijing China 	0x00000FFF,			/* dma_attr_burstsizes */
182d8d81063Sfei feng - Sun Microsystems - Beijing China 	0x00000001,			/* dma_attr_minxfer */
183d8d81063Sfei feng - Sun Microsystems - Beijing China 	0x000000000000FFFFull,		/* dma_attr_maxxfer */
184d8d81063Sfei feng - Sun Microsystems - Beijing China 	0xFFFFFFFFFFFFFFFFull,		/* dma_attr_seg */
185d8d81063Sfei feng - Sun Microsystems - Beijing China 	1,				/* dma_attr_sgllen */
186d8d81063Sfei feng - Sun Microsystems - Beijing China 	0x00000001,			/* dma_attr_granular */
187d8d81063Sfei feng - Sun Microsystems - Beijing China 	0				/* dma_attr_flags */
188d8d81063Sfei feng - Sun Microsystems - Beijing China };
189d8d81063Sfei feng - Sun Microsystems - Beijing China 
190d8d81063Sfei feng - Sun Microsystems - Beijing China /*
191d8d81063Sfei feng - Sun Microsystems - Beijing China  * Supported rates for 802.11a/b/g modes (in 500Kbps unit).
192d8d81063Sfei feng - Sun Microsystems - Beijing China  */
193d8d81063Sfei feng - Sun Microsystems - Beijing China static const struct ieee80211_rateset mwl_rateset_11b =
194d8d81063Sfei feng - Sun Microsystems - Beijing China 	{ 4, { 2, 4, 11, 22 } };
195d8d81063Sfei feng - Sun Microsystems - Beijing China 
196d8d81063Sfei feng - Sun Microsystems - Beijing China static const struct ieee80211_rateset mwl_rateset_11g =
197d8d81063Sfei feng - Sun Microsystems - Beijing China 	{ 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
198d8d81063Sfei feng - Sun Microsystems - Beijing China 
199d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_alloc_dma_mem(dev_info_t *, ddi_dma_attr_t *, size_t,
200d8d81063Sfei feng - Sun Microsystems - Beijing China 		    ddi_device_acc_attr_t *, uint_t, uint_t,
201d8d81063Sfei feng - Sun Microsystems - Beijing China 		    struct dma_area *);
202d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_free_dma_mem(struct dma_area *);
203d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_alloc_cmdbuf(struct mwl_softc *);
204d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_free_cmdbuf(struct mwl_softc *);
205d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_alloc_rx_ring(struct mwl_softc *, int);
206d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_free_rx_ring(struct mwl_softc *);
207d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_alloc_tx_ring(struct mwl_softc *, struct mwl_tx_ring *,
208d8d81063Sfei feng - Sun Microsystems - Beijing China 		    int);
209d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_free_tx_ring(struct mwl_softc *, struct mwl_tx_ring *);
210d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_setupdma(struct mwl_softc *);
211d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_txq_init(struct mwl_softc *, struct mwl_tx_ring *, int);
212d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_tx_setup(struct mwl_softc *, int, int);
213d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_setup_txq(struct mwl_softc *);
214d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_fwload(struct mwl_softc *, void *);
215d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_loadsym(ddi_modhandle_t, char *, char **, size_t *);
216d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwlFwReset(struct mwl_softc *);
217d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwlPokeSdramController(struct mwl_softc *, int);
218d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwlTriggerPciCmd(struct mwl_softc *);
219d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwlWaitFor(struct mwl_softc *, uint32_t);
220d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwlSendBlock(struct mwl_softc *, int, const void *, size_t);
221d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwlSendBlock2(struct mwl_softc *, const void *, size_t);
222d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwlSendCmd(struct mwl_softc *);
223d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwlExecuteCmd(struct mwl_softc *, unsigned short);
224d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwlWaitForCmdComplete(struct mwl_softc *, uint16_t);
225d8d81063Sfei feng - Sun Microsystems - Beijing China static void	dumpresult(struct mwl_softc *, int);
226d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwlResetHalState(struct mwl_softc *);
227d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwlGetPwrCalTable(struct mwl_softc *);
228d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwlGetCalTable(struct mwl_softc *, uint8_t, uint8_t);
229d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwlGetPwrCalTable(struct mwl_softc *);
230d8d81063Sfei feng - Sun Microsystems - Beijing China static void	dumpcaldata(const char *, const uint8_t *, int);
231d8d81063Sfei feng - Sun Microsystems - Beijing China static void	get2Ghz(MWL_HAL_CHANNELINFO *, const uint8_t *, int);
232d8d81063Sfei feng - Sun Microsystems - Beijing China static void	get5Ghz(MWL_HAL_CHANNELINFO *, const uint8_t *, int);
233d8d81063Sfei feng - Sun Microsystems - Beijing China static void	setmaxtxpow(struct mwl_hal_channel *, int, int);
234d8d81063Sfei feng - Sun Microsystems - Beijing China static uint16_t	ieee2mhz(int);
235d8d81063Sfei feng - Sun Microsystems - Beijing China static const char *
236d8d81063Sfei feng - Sun Microsystems - Beijing China 		mwlcmdname(int);
237d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_gethwspecs(struct mwl_softc *);
238d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_getchannels(struct mwl_softc *);
239d8d81063Sfei feng - Sun Microsystems - Beijing China static void	getchannels(struct mwl_softc *, int, int *,
240d8d81063Sfei feng - Sun Microsystems - Beijing China 		    struct mwl_channel *);
241d8d81063Sfei feng - Sun Microsystems - Beijing China static void	addchannels(struct mwl_channel *, int, int *,
242d8d81063Sfei feng - Sun Microsystems - Beijing China 		    const MWL_HAL_CHANNELINFO *, int);
243d8d81063Sfei feng - Sun Microsystems - Beijing China static void	addht40channels(struct mwl_channel *, int, int *,
244d8d81063Sfei feng - Sun Microsystems - Beijing China 		    const MWL_HAL_CHANNELINFO *, int);
245d8d81063Sfei feng - Sun Microsystems - Beijing China static const struct mwl_channel *
246d8d81063Sfei feng - Sun Microsystems - Beijing China 		findchannel(const struct mwl_channel *, int,
247d8d81063Sfei feng - Sun Microsystems - Beijing China 		    int, int);
248d8d81063Sfei feng - Sun Microsystems - Beijing China static void	addchan(struct mwl_channel *, int, int, int, int);
249d8d81063Sfei feng - Sun Microsystems - Beijing China 
250d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_chan_set(struct mwl_softc *, struct mwl_channel *);
251d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_mapchan(MWL_HAL_CHANNEL *, const struct mwl_channel *);
252d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_setcurchanrates(struct mwl_softc *);
253d8d81063Sfei feng - Sun Microsystems - Beijing China const struct ieee80211_rateset *
254d8d81063Sfei feng - Sun Microsystems - Beijing China 		mwl_get_suprates(struct ieee80211com *,
255d8d81063Sfei feng - Sun Microsystems - Beijing China 		    const struct mwl_channel *);
256d8d81063Sfei feng - Sun Microsystems - Beijing China static uint32_t	cvtChannelFlags(const MWL_HAL_CHANNEL *);
257d8d81063Sfei feng - Sun Microsystems - Beijing China static const struct mwl_hal_channel *
258d8d81063Sfei feng - Sun Microsystems - Beijing China 		findhalchannel(const struct mwl_softc *,
259d8d81063Sfei feng - Sun Microsystems - Beijing China 		    const MWL_HAL_CHANNEL *);
260d8d81063Sfei feng - Sun Microsystems - Beijing China enum ieee80211_phymode
261d8d81063Sfei feng - Sun Microsystems - Beijing China 		mwl_chan2mode(const struct mwl_channel *);
262d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_map2regioncode(const struct mwl_regdomain *);
263d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_startrecv(struct mwl_softc *);
264d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_mode_init(struct mwl_softc *);
265d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_hal_intrset(struct mwl_softc *, uint32_t);
266d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_hal_getisr(struct mwl_softc *, uint32_t *);
267d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_sethwdma(struct mwl_softc *,
268d8d81063Sfei feng - Sun Microsystems - Beijing China 		    const struct mwl_hal_txrxdma *);
269d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_getchannelinfo(struct mwl_softc *, int, int,
270d8d81063Sfei feng - Sun Microsystems - Beijing China 		    const MWL_HAL_CHANNELINFO **);
271d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_setmac_locked(struct mwl_softc *, const uint8_t *);
272d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_keyreset(struct mwl_softc *, const MWL_HAL_KEYVAL *,
273d8d81063Sfei feng - Sun Microsystems - Beijing China 		    const uint8_t mac[IEEE80211_ADDR_LEN]);
274d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_keyset(struct mwl_softc *, const MWL_HAL_KEYVAL *,
275d8d81063Sfei feng - Sun Microsystems - Beijing China 		    const uint8_t mac[IEEE80211_ADDR_LEN]);
276d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_newstation(struct mwl_softc *, const uint8_t *,
277d8d81063Sfei feng - Sun Microsystems - Beijing China 		    uint16_t, uint16_t, const MWL_HAL_PEERINFO *, int, int);
278d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_setantenna(struct mwl_softc *, MWL_HAL_ANTENNA, int);
279d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_setradio(struct mwl_softc *, int, MWL_HAL_PREAMBLE);
280d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_setwmm(struct mwl_softc *, int);
281d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_setchannel(struct mwl_softc *, const MWL_HAL_CHANNEL *);
282d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_settxpower(struct mwl_softc *, const MWL_HAL_CHANNEL *,
283d8d81063Sfei feng - Sun Microsystems - Beijing China 		    uint8_t);
284d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_settxrate(struct mwl_softc *, MWL_HAL_TXRATE_HANDLING,
285d8d81063Sfei feng - Sun Microsystems - Beijing China 		    const MWL_HAL_TXRATE *);
286d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_settxrate_auto(struct mwl_softc *,
287d8d81063Sfei feng - Sun Microsystems - Beijing China 		    const MWL_HAL_TXRATE *);
288d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_setrateadaptmode(struct mwl_softc *, uint16_t);
289d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_setoptimizationlevel(struct mwl_softc *, int);
290d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_setregioncode(struct mwl_softc *, int);
291d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_setassocid(struct mwl_softc *, const uint8_t *,
292d8d81063Sfei feng - Sun Microsystems - Beijing China 		    uint16_t);
293d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_setrates(struct ieee80211com *);
294d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_setrtsthreshold(struct mwl_softc *, int);
295d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_setcsmode(struct mwl_softc *, MWL_HAL_CSMODE);
296d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_setpromisc(struct mwl_softc *, int);
297d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_start(struct mwl_softc *);
298d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_setinframode(struct mwl_softc *);
299d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_hal_stop(struct mwl_softc *);
300d8d81063Sfei feng - Sun Microsystems - Beijing China static struct ieee80211_node *
301d8d81063Sfei feng - Sun Microsystems - Beijing China 		mwl_node_alloc(struct ieee80211com *);
302d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_node_free(struct ieee80211_node *);
303d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_key_alloc(struct ieee80211com *,
304d8d81063Sfei feng - Sun Microsystems - Beijing China 		    const struct ieee80211_key *,
305d8d81063Sfei feng - Sun Microsystems - Beijing China 		    ieee80211_keyix *, ieee80211_keyix *);
306d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_key_delete(struct ieee80211com *,
307d8d81063Sfei feng - Sun Microsystems - Beijing China 		    const struct ieee80211_key *);
308d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_key_set(struct ieee80211com *, const struct ieee80211_key *,
309d8d81063Sfei feng - Sun Microsystems - Beijing China 		    const uint8_t mac[IEEE80211_ADDR_LEN]);
310d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_setanywepkey(struct ieee80211com *, const uint8_t *);
311d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_setglobalkeys(struct ieee80211com *c);
312d8d81063Sfei feng - Sun Microsystems - Beijing China static int	addgroupflags(MWL_HAL_KEYVAL *, const struct ieee80211_key *);
313d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_hal_txstart(struct mwl_softc *, int);
314d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_send(ieee80211com_t *, mblk_t *, uint8_t);
315d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_next_scan(void *);
316d8d81063Sfei feng - Sun Microsystems - Beijing China static MWL_HAL_PEERINFO *
317d8d81063Sfei feng - Sun Microsystems - Beijing China 		mkpeerinfo(MWL_HAL_PEERINFO *, const struct ieee80211_node *);
318d8d81063Sfei feng - Sun Microsystems - Beijing China static uint32_t	get_rate_bitmap(const struct ieee80211_rateset *);
319d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_newstate(struct ieee80211com *, enum ieee80211_state, int);
320d8d81063Sfei feng - Sun Microsystems - Beijing China static int	cvtrssi(uint8_t);
321d8d81063Sfei feng - Sun Microsystems - Beijing China static uint_t	mwl_intr(caddr_t, caddr_t);
322d8d81063Sfei feng - Sun Microsystems - Beijing China static uint_t	mwl_softintr(caddr_t, caddr_t);
323d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_tx_intr(struct mwl_softc *);
324d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_rx_intr(struct mwl_softc *);
325d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_init(struct mwl_softc *);
326d8d81063Sfei feng - Sun Microsystems - Beijing China static void	mwl_stop(struct mwl_softc *);
327d8d81063Sfei feng - Sun Microsystems - Beijing China static int	mwl_resume(struct mwl_softc *);
328d8d81063Sfei feng - Sun Microsystems - Beijing China 
329d8d81063Sfei feng - Sun Microsystems - Beijing China 
330d8d81063Sfei feng - Sun Microsystems - Beijing China #ifdef DEBUG
331d8d81063Sfei feng - Sun Microsystems - Beijing China static void
mwl_debug(uint32_t dbg_flags,const int8_t * fmt,...)332d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_debug(uint32_t dbg_flags, const int8_t *fmt, ...)
333d8d81063Sfei feng - Sun Microsystems - Beijing China {
334d8d81063Sfei feng - Sun Microsystems - Beijing China 	va_list args;
335d8d81063Sfei feng - Sun Microsystems - Beijing China 
336d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (dbg_flags & mwl_dbg_flags) {
337d8d81063Sfei feng - Sun Microsystems - Beijing China 		va_start(args, fmt);
338d8d81063Sfei feng - Sun Microsystems - Beijing China 		vcmn_err(CE_CONT, fmt, args);
339d8d81063Sfei feng - Sun Microsystems - Beijing China 		va_end(args);
340d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
341d8d81063Sfei feng - Sun Microsystems - Beijing China }
342d8d81063Sfei feng - Sun Microsystems - Beijing China #endif
343d8d81063Sfei feng - Sun Microsystems - Beijing China 
344d8d81063Sfei feng - Sun Microsystems - Beijing China /*
345d8d81063Sfei feng - Sun Microsystems - Beijing China  * Allocate an DMA memory and a DMA handle for accessing it
346d8d81063Sfei feng - Sun Microsystems - Beijing China  */
347d8d81063Sfei feng - Sun Microsystems - Beijing China static int
mwl_alloc_dma_mem(dev_info_t * devinfo,ddi_dma_attr_t * dma_attr,size_t memsize,ddi_device_acc_attr_t * attr_p,uint_t alloc_flags,uint_t bind_flags,struct dma_area * dma_p)348d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_alloc_dma_mem(dev_info_t *devinfo, ddi_dma_attr_t *dma_attr,
349d8d81063Sfei feng - Sun Microsystems - Beijing China 	size_t memsize, ddi_device_acc_attr_t *attr_p, uint_t alloc_flags,
350d8d81063Sfei feng - Sun Microsystems - Beijing China 	uint_t bind_flags, struct dma_area *dma_p)
351d8d81063Sfei feng - Sun Microsystems - Beijing China {
352d8d81063Sfei feng - Sun Microsystems - Beijing China 	int err;
353d8d81063Sfei feng - Sun Microsystems - Beijing China 
354d8d81063Sfei feng - Sun Microsystems - Beijing China 	/*
355d8d81063Sfei feng - Sun Microsystems - Beijing China 	 * Allocate handle
356d8d81063Sfei feng - Sun Microsystems - Beijing China 	 */
357d8d81063Sfei feng - Sun Microsystems - Beijing China 	err = ddi_dma_alloc_handle(devinfo, dma_attr,
358d8d81063Sfei feng - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl);
359d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (err != DDI_SUCCESS) {
360d8d81063Sfei feng - Sun Microsystems - Beijing China 		MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_dma_mem(): "
361d8d81063Sfei feng - Sun Microsystems - Beijing China 		    "failed to alloc handle\n");
362d8d81063Sfei feng - Sun Microsystems - Beijing China 		goto fail1;
363d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
364d8d81063Sfei feng - Sun Microsystems - Beijing China 
365d8d81063Sfei feng - Sun Microsystems - Beijing China 	/*
366d8d81063Sfei feng - Sun Microsystems - Beijing China 	 * Allocate memory
367d8d81063Sfei feng - Sun Microsystems - Beijing China 	 */
368d8d81063Sfei feng - Sun Microsystems - Beijing China 	err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, attr_p,
369d8d81063Sfei feng - Sun Microsystems - Beijing China 	    alloc_flags, DDI_DMA_SLEEP, NULL, &dma_p->mem_va,
370d8d81063Sfei feng - Sun Microsystems - Beijing China 	    &dma_p->alength, &dma_p->acc_hdl);
371d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (err != DDI_SUCCESS) {
372d8d81063Sfei feng - Sun Microsystems - Beijing China 		MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_dma_mem(): "
373d8d81063Sfei feng - Sun Microsystems - Beijing China 		    "failed to alloc mem\n");
374d8d81063Sfei feng - Sun Microsystems - Beijing China 		goto fail2;
375d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
376d8d81063Sfei feng - Sun Microsystems - Beijing China 
377d8d81063Sfei feng - Sun Microsystems - Beijing China 	/*
378d8d81063Sfei feng - Sun Microsystems - Beijing China 	 * Bind the two together
379d8d81063Sfei feng - Sun Microsystems - Beijing China 	 */
380d8d81063Sfei feng - Sun Microsystems - Beijing China 	err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL,
381d8d81063Sfei feng - Sun Microsystems - Beijing China 	    dma_p->mem_va, dma_p->alength, bind_flags,
382d8d81063Sfei feng - Sun Microsystems - Beijing China 	    DDI_DMA_SLEEP, NULL, &dma_p->cookie, &dma_p->ncookies);
383d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (err != DDI_DMA_MAPPED) {
384d8d81063Sfei feng - Sun Microsystems - Beijing China 		MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_dma_mem(): "
385d8d81063Sfei feng - Sun Microsystems - Beijing China 		    "failed to bind handle\n");
386d8d81063Sfei feng - Sun Microsystems - Beijing China 		goto fail3;
387d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
388d8d81063Sfei feng - Sun Microsystems - Beijing China 
389d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (dma_p->ncookies != 1) {
390d8d81063Sfei feng - Sun Microsystems - Beijing China 		MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_dma_mem(): "
391d8d81063Sfei feng - Sun Microsystems - Beijing China 		    "failed to alloc cookies\n");
392d8d81063Sfei feng - Sun Microsystems - Beijing China 		goto fail4;
393d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
394d8d81063Sfei feng - Sun Microsystems - Beijing China 
395d8d81063Sfei feng - Sun Microsystems - Beijing China 	dma_p->nslots = ~0U;
396d8d81063Sfei feng - Sun Microsystems - Beijing China 	dma_p->size = ~0U;
397d8d81063Sfei feng - Sun Microsystems - Beijing China 	dma_p->token = ~0U;
398d8d81063Sfei feng - Sun Microsystems - Beijing China 	dma_p->offset = 0;
399d8d81063Sfei feng - Sun Microsystems - Beijing China 
400d8d81063Sfei feng - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
401d8d81063Sfei feng - Sun Microsystems - Beijing China 
402d8d81063Sfei feng - Sun Microsystems - Beijing China fail4:
403d8d81063Sfei feng - Sun Microsystems - Beijing China 	(void) ddi_dma_unbind_handle(dma_p->dma_hdl);
404d8d81063Sfei feng - Sun Microsystems - Beijing China fail3:
405d8d81063Sfei feng - Sun Microsystems - Beijing China 	ddi_dma_mem_free(&dma_p->acc_hdl);
406d8d81063Sfei feng - Sun Microsystems - Beijing China fail2:
407d8d81063Sfei feng - Sun Microsystems - Beijing China 	ddi_dma_free_handle(&dma_p->dma_hdl);
408d8d81063Sfei feng - Sun Microsystems - Beijing China fail1:
409d8d81063Sfei feng - Sun Microsystems - Beijing China 	return (err);
410d8d81063Sfei feng - Sun Microsystems - Beijing China }
411d8d81063Sfei feng - Sun Microsystems - Beijing China 
412d8d81063Sfei feng - Sun Microsystems - Beijing China static void
mwl_free_dma_mem(struct dma_area * dma_p)413d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_dma_mem(struct dma_area *dma_p)
414d8d81063Sfei feng - Sun Microsystems - Beijing China {
415d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (dma_p->dma_hdl != NULL) {
416d8d81063Sfei feng - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(dma_p->dma_hdl);
417d8d81063Sfei feng - Sun Microsystems - Beijing China 		if (dma_p->acc_hdl != NULL) {
418d8d81063Sfei feng - Sun Microsystems - Beijing China 			ddi_dma_mem_free(&dma_p->acc_hdl);
419d8d81063Sfei feng - Sun Microsystems - Beijing China 			dma_p->acc_hdl = NULL;
420d8d81063Sfei feng - Sun Microsystems - Beijing China 		}
421d8d81063Sfei feng - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&dma_p->dma_hdl);
422d8d81063Sfei feng - Sun Microsystems - Beijing China 		dma_p->ncookies = 0;
423d8d81063Sfei feng - Sun Microsystems - Beijing China 		dma_p->dma_hdl = NULL;
424d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
425d8d81063Sfei feng - Sun Microsystems - Beijing China }
426d8d81063Sfei feng - Sun Microsystems - Beijing China 
427d8d81063Sfei feng - Sun Microsystems - Beijing China static int
mwl_alloc_cmdbuf(struct mwl_softc * sc)428d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_alloc_cmdbuf(struct mwl_softc *sc)
429d8d81063Sfei feng - Sun Microsystems - Beijing China {
430d8d81063Sfei feng - Sun Microsystems - Beijing China 	int err;
431d8d81063Sfei feng - Sun Microsystems - Beijing China 	size_t size;
432d8d81063Sfei feng - Sun Microsystems - Beijing China 
433d8d81063Sfei feng - Sun Microsystems - Beijing China 	size = MWL_CMDBUF_SIZE;
434d8d81063Sfei feng - Sun Microsystems - Beijing China 
435d8d81063Sfei feng - Sun Microsystems - Beijing China 	err = mwl_alloc_dma_mem(sc->sc_dev, &mwl_dma_attr, size,
436d8d81063Sfei feng - Sun Microsystems - Beijing China 	    &mwl_cmdbuf_accattr, DDI_DMA_CONSISTENT,
437d8d81063Sfei feng - Sun Microsystems - Beijing China 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
438d8d81063Sfei feng - Sun Microsystems - Beijing China 	    &sc->sc_cmd_dma);
439d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (err != DDI_SUCCESS) {
440d8d81063Sfei feng - Sun Microsystems - Beijing China 		MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_cmdbuf(): "
441d8d81063Sfei feng - Sun Microsystems - Beijing China 		    "failed to alloc dma mem\n");
442d8d81063Sfei feng - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
443d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
444d8d81063Sfei feng - Sun Microsystems - Beijing China 
445d8d81063Sfei feng - Sun Microsystems - Beijing China 	sc->sc_cmd_mem = (uint16_t *)sc->sc_cmd_dma.mem_va;
446d8d81063Sfei feng - Sun Microsystems - Beijing China 	sc->sc_cmd_dmaaddr = sc->sc_cmd_dma.cookie.dmac_address;
447d8d81063Sfei feng - Sun Microsystems - Beijing China 
448d8d81063Sfei feng - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
449d8d81063Sfei feng - Sun Microsystems - Beijing China }
450d8d81063Sfei feng - Sun Microsystems - Beijing China 
451d8d81063Sfei feng - Sun Microsystems - Beijing China static void
mwl_free_cmdbuf(struct mwl_softc * sc)452d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_cmdbuf(struct mwl_softc *sc)
453d8d81063Sfei feng - Sun Microsystems - Beijing China {
454d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (sc->sc_cmd_mem != NULL)
455d8d81063Sfei feng - Sun Microsystems - Beijing China 		mwl_free_dma_mem(&sc->sc_cmd_dma);
456d8d81063Sfei feng - Sun Microsystems - Beijing China }
457d8d81063Sfei feng - Sun Microsystems - Beijing China 
458d8d81063Sfei feng - Sun Microsystems - Beijing China static int
mwl_alloc_rx_ring(struct mwl_softc * sc,int count)459d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_alloc_rx_ring(struct mwl_softc *sc, int count)
460d8d81063Sfei feng - Sun Microsystems - Beijing China {
461d8d81063Sfei feng - Sun Microsystems - Beijing China 	struct mwl_rx_ring *ring;
462d8d81063Sfei feng - Sun Microsystems - Beijing China 	struct mwl_rxdesc *ds;
463d8d81063Sfei feng - Sun Microsystems - Beijing China 	struct mwl_rxbuf *bf;
464d8d81063Sfei feng - Sun Microsystems - Beijing China 	int i, err, datadlen;
465d8d81063Sfei feng - Sun Microsystems - Beijing China 
466d8d81063Sfei feng - Sun Microsystems - Beijing China 	ring = &sc->sc_rxring;
467d8d81063Sfei feng - Sun Microsystems - Beijing China 	ring->count = count;
468d8d81063Sfei feng - Sun Microsystems - Beijing China 	ring->cur = ring->next = 0;
469d8d81063Sfei feng - Sun Microsystems - Beijing China 	err = mwl_alloc_dma_mem(sc->sc_dev, &mwl_dma_attr,
470d8d81063Sfei feng - Sun Microsystems - Beijing China 	    count * sizeof (struct mwl_rxdesc),
471d8d81063Sfei feng - Sun Microsystems - Beijing China 	    &mwl_desc_accattr,
472d8d81063Sfei feng - Sun Microsystems - Beijing China 	    DDI_DMA_CONSISTENT, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
473d8d81063Sfei feng - Sun Microsystems - Beijing China 	    &ring->rxdesc_dma);
474d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (err) {
475d8d81063Sfei feng - Sun Microsystems - Beijing China 		MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_rxring(): "
476d8d81063Sfei feng - Sun Microsystems - Beijing China 		    "alloc tx ring failed, size %d\n",
477d8d81063Sfei feng - Sun Microsystems - Beijing China 		    (uint32_t)(count * sizeof (struct mwl_rxdesc)));
478d8d81063Sfei feng - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
479d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
480d8d81063Sfei feng - Sun Microsystems - Beijing China 
481d8d81063Sfei feng - Sun Microsystems - Beijing China 	MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_rx_ring(): "
482d8d81063Sfei feng - Sun Microsystems - Beijing China 	    "dma len = %d\n", (uint32_t)(ring->rxdesc_dma.alength));
483d8d81063Sfei feng - Sun Microsystems - Beijing China 	ring->desc = (struct mwl_rxdesc *)ring->rxdesc_dma.mem_va;
484d8d81063Sfei feng - Sun Microsystems - Beijing China 	ring->physaddr = ring->rxdesc_dma.cookie.dmac_address;
485d8d81063Sfei feng - Sun Microsystems - Beijing China 	bzero(ring->desc, count * sizeof (struct mwl_rxdesc));
486d8d81063Sfei feng - Sun Microsystems - Beijing China 
487d8d81063Sfei feng - Sun Microsystems - Beijing China 	datadlen = count * sizeof (struct mwl_rxbuf);
488d8d81063Sfei feng - Sun Microsystems - Beijing China 	ring->buf = (struct mwl_rxbuf *)kmem_zalloc(datadlen, KM_SLEEP);
489d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (ring->buf == NULL) {
490d8d81063Sfei feng - Sun Microsystems - Beijing China 		MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_rxring(): "
491d8d81063Sfei feng - Sun Microsystems - Beijing China 		    "could not alloc rx ring data buffer\n");
492d8d81063Sfei feng - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
493d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
494d8d81063Sfei feng - Sun Microsystems - Beijing China 	bzero(ring->buf, count * sizeof (struct mwl_rxbuf));
495d8d81063Sfei feng - Sun Microsystems - Beijing China 
496d8d81063Sfei feng - Sun Microsystems - Beijing China 	/*
497d8d81063Sfei feng - Sun Microsystems - Beijing China 	 * Pre-allocate Rx buffers and populate Rx ring.
498d8d81063Sfei feng - Sun Microsystems - Beijing China 	 */
499d8d81063Sfei feng - Sun Microsystems - Beijing China 	for (i = 0; i < count; i++) {
500d8d81063Sfei feng - Sun Microsystems - Beijing China 		ds = &ring->desc[i];
501d8d81063Sfei feng - Sun Microsystems - Beijing China 		bf = &ring->buf[i];
502d8d81063Sfei feng - Sun Microsystems - Beijing China 		/* alloc DMA memory */
503d8d81063Sfei feng - Sun Microsystems - Beijing China 		(void) mwl_alloc_dma_mem(sc->sc_dev, &mwl_dma_attr,
504d8d81063Sfei feng - Sun Microsystems - Beijing China 		    sc->sc_dmabuf_size,
505d8d81063Sfei feng - Sun Microsystems - Beijing China 		    &mwl_buf_accattr,
506d8d81063Sfei feng - Sun Microsystems - Beijing China 		    DDI_DMA_STREAMING,
507d8d81063Sfei feng - Sun Microsystems - Beijing China 		    DDI_DMA_READ | DDI_DMA_STREAMING,
508d8d81063Sfei feng - Sun Microsystems - Beijing China 		    &bf->rxbuf_dma);
509d8d81063Sfei feng - Sun Microsystems - Beijing China 		bf->bf_mem = (uint8_t *)(bf->rxbuf_dma.mem_va);
510d8d81063Sfei feng - Sun Microsystems - Beijing China 		bf->bf_baddr = bf->rxbuf_dma.cookie.dmac_address;
511d8d81063Sfei feng - Sun Microsystems - Beijing China 		bf->bf_desc = ds;
512d8d81063Sfei feng - Sun Microsystems - Beijing China 		bf->bf_daddr = ring->physaddr + _PTRDIFF(ds, ring->desc);
513d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
514d8d81063Sfei feng - Sun Microsystems - Beijing China 
515d8d81063Sfei feng - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(ring->rxdesc_dma.dma_hdl,
516d8d81063Sfei feng - Sun Microsystems - Beijing China 	    0,
517d8d81063Sfei feng - Sun Microsystems - Beijing China 	    ring->rxdesc_dma.alength,
518d8d81063Sfei feng - Sun Microsystems - Beijing China 	    DDI_DMA_SYNC_FORDEV);
519d8d81063Sfei feng - Sun Microsystems - Beijing China 
520d8d81063Sfei feng - Sun Microsystems - Beijing China 	return (0);
521d8d81063Sfei feng - Sun Microsystems - Beijing China }
522d8d81063Sfei feng - Sun Microsystems - Beijing China 
523d8d81063Sfei feng - Sun Microsystems - Beijing China static void
mwl_free_rx_ring(struct mwl_softc * sc)524d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_rx_ring(struct mwl_softc *sc)
525d8d81063Sfei feng - Sun Microsystems - Beijing China {
526d8d81063Sfei feng - Sun Microsystems - Beijing China 	struct mwl_rx_ring *ring;
527d8d81063Sfei feng - Sun Microsystems - Beijing China 	struct mwl_rxbuf *bf;
528d8d81063Sfei feng - Sun Microsystems - Beijing China 	int i;
529d8d81063Sfei feng - Sun Microsystems - Beijing China 
530d8d81063Sfei feng - Sun Microsystems - Beijing China 	ring = &sc->sc_rxring;
531d8d81063Sfei feng - Sun Microsystems - Beijing China 
532d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (ring->desc != NULL) {
533d8d81063Sfei feng - Sun Microsystems - Beijing China 		mwl_free_dma_mem(&ring->rxdesc_dma);
534d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
535d8d81063Sfei feng - Sun Microsystems - Beijing China 
536d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (ring->buf != NULL) {
537d8d81063Sfei feng - Sun Microsystems - Beijing China 		for (i = 0; i < ring->count; i++) {
538d8d81063Sfei feng - Sun Microsystems - Beijing China 			bf = &ring->buf[i];
539d8d81063Sfei feng - Sun Microsystems - Beijing China 			mwl_free_dma_mem(&bf->rxbuf_dma);
540d8d81063Sfei feng - Sun Microsystems - Beijing China 		}
541d8d81063Sfei feng - Sun Microsystems - Beijing China 		kmem_free(ring->buf,
542d8d81063Sfei feng - Sun Microsystems - Beijing China 		    (ring->count * sizeof (struct mwl_rxbuf)));
543d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
544d8d81063Sfei feng - Sun Microsystems - Beijing China }
545d8d81063Sfei feng - Sun Microsystems - Beijing China 
546d8d81063Sfei feng - Sun Microsystems - Beijing China static int
mwl_alloc_tx_ring(struct mwl_softc * sc,struct mwl_tx_ring * ring,int count)547d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_alloc_tx_ring(struct mwl_softc *sc, struct mwl_tx_ring *ring,
548d8d81063Sfei feng - Sun Microsystems - Beijing China     int count)
549d8d81063Sfei feng - Sun Microsystems - Beijing China {
550d8d81063Sfei feng - Sun Microsystems - Beijing China 	struct mwl_txdesc *ds;
551d8d81063Sfei feng - Sun Microsystems - Beijing China 	struct mwl_txbuf *bf;
552d8d81063Sfei feng - Sun Microsystems - Beijing China 	int i, err, datadlen;
553d8d81063Sfei feng - Sun Microsystems - Beijing China 
554d8d81063Sfei feng - Sun Microsystems - Beijing China 	ring->count = count;
555d8d81063Sfei feng - Sun Microsystems - Beijing China 	ring->queued = 0;
556d8d81063Sfei feng - Sun Microsystems - Beijing China 	ring->cur = ring->next = ring->stat = 0;
557d8d81063Sfei feng - Sun Microsystems - Beijing China 	err = mwl_alloc_dma_mem(sc->sc_dev, &mwl_dma_attr,
558d8d81063Sfei feng - Sun Microsystems - Beijing China 	    count * sizeof (struct mwl_txdesc), &mwl_desc_accattr,
559d8d81063Sfei feng - Sun Microsystems - Beijing China 	    DDI_DMA_CONSISTENT, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
560d8d81063Sfei feng - Sun Microsystems - Beijing China 	    &ring->txdesc_dma);
561d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (err) {
562d8d81063Sfei feng - Sun Microsystems - Beijing China 		MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_tx_ring(): "
563d8d81063Sfei feng - Sun Microsystems - Beijing China 		    "alloc tx ring failed, size %d\n",
564d8d81063Sfei feng - Sun Microsystems - Beijing China 		    (uint32_t)(count * sizeof (struct mwl_txdesc)));
565d8d81063Sfei feng - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
566d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
567d8d81063Sfei feng - Sun Microsystems - Beijing China 
568d8d81063Sfei feng - Sun Microsystems - Beijing China 	MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_tx_ring(): "
569d8d81063Sfei feng - Sun Microsystems - Beijing China 	    "dma len = %d\n", (uint32_t)(ring->txdesc_dma.alength));
570d8d81063Sfei feng - Sun Microsystems - Beijing China 	ring->desc = (struct mwl_txdesc *)ring->txdesc_dma.mem_va;
571d8d81063Sfei feng - Sun Microsystems - Beijing China 	ring->physaddr = ring->txdesc_dma.cookie.dmac_address;
572d8d81063Sfei feng - Sun Microsystems - Beijing China 	bzero(ring->desc, count * sizeof (struct mwl_txdesc));
573d8d81063Sfei feng - Sun Microsystems - Beijing China 
574d8d81063Sfei feng - Sun Microsystems - Beijing China 	datadlen = count * sizeof (struct mwl_txbuf);
575d8d81063Sfei feng - Sun Microsystems - Beijing China 	ring->buf = kmem_zalloc(datadlen, KM_SLEEP);
576d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (ring->buf == NULL) {
577d8d81063Sfei feng - Sun Microsystems - Beijing China 		MWL_DBG(MWL_DBG_DMA, "mwl: mwl_alloc_tx_ring(): "
578d8d81063Sfei feng - Sun Microsystems - Beijing China 		    "could not alloc tx ring data buffer\n");
579d8d81063Sfei feng - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
580d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
581d8d81063Sfei feng - Sun Microsystems - Beijing China 	bzero(ring->buf, count * sizeof (struct mwl_txbuf));
582d8d81063Sfei feng - Sun Microsystems - Beijing China 
583d8d81063Sfei feng - Sun Microsystems - Beijing China 	for (i = 0; i < count; i++) {
584d8d81063Sfei feng - Sun Microsystems - Beijing China 		ds = &ring->desc[i];
585d8d81063Sfei feng - Sun Microsystems - Beijing China 		bf = &ring->buf[i];
586d8d81063Sfei feng - Sun Microsystems - Beijing China 		/* alloc DMA memory */
587d8d81063Sfei feng - Sun Microsystems - Beijing China 		(void) mwl_alloc_dma_mem(sc->sc_dev, &mwl_dma_attr,
588d8d81063Sfei feng - Sun Microsystems - Beijing China 		    sc->sc_dmabuf_size,
589d8d81063Sfei feng - Sun Microsystems - Beijing China 		    &mwl_buf_accattr,
590d8d81063Sfei feng - Sun Microsystems - Beijing China 		    DDI_DMA_STREAMING,
591d8d81063Sfei feng - Sun Microsystems - Beijing China 		    DDI_DMA_WRITE | DDI_DMA_STREAMING,
592d8d81063Sfei feng - Sun Microsystems - Beijing China 		    &bf->txbuf_dma);
593d8d81063Sfei feng - Sun Microsystems - Beijing China 		bf->bf_baddr = bf->txbuf_dma.cookie.dmac_address;
594d8d81063Sfei feng - Sun Microsystems - Beijing China 		bf->bf_mem = (uint8_t *)(bf->txbuf_dma.mem_va);
595d8d81063Sfei feng - Sun Microsystems - Beijing China 		bf->bf_daddr = ring->physaddr + _PTRDIFF(ds, ring->desc);
596d8d81063Sfei feng - Sun Microsystems - Beijing China 		bf->bf_desc = ds;
597d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
598d8d81063Sfei feng - Sun Microsystems - Beijing China 
599d8d81063Sfei feng - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(ring->txdesc_dma.dma_hdl,
600d8d81063Sfei feng - Sun Microsystems - Beijing China 	    0,
601d8d81063Sfei feng - Sun Microsystems - Beijing China 	    ring->txdesc_dma.alength,
602d8d81063Sfei feng - Sun Microsystems - Beijing China 	    DDI_DMA_SYNC_FORDEV);
603d8d81063Sfei feng - Sun Microsystems - Beijing China 
604d8d81063Sfei feng - Sun Microsystems - Beijing China 	return (0);
605d8d81063Sfei feng - Sun Microsystems - Beijing China }
606d8d81063Sfei feng - Sun Microsystems - Beijing China 
607d8d81063Sfei feng - Sun Microsystems - Beijing China /* ARGSUSED */
608d8d81063Sfei feng - Sun Microsystems - Beijing China static void
mwl_free_tx_ring(struct mwl_softc * sc,struct mwl_tx_ring * ring)609d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_free_tx_ring(struct mwl_softc *sc, struct mwl_tx_ring *ring)
610d8d81063Sfei feng - Sun Microsystems - Beijing China {
611d8d81063Sfei feng - Sun Microsystems - Beijing China 	struct mwl_txbuf *bf;
612d8d81063Sfei feng - Sun Microsystems - Beijing China 	int i;
613d8d81063Sfei feng - Sun Microsystems - Beijing China 
614d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (ring->desc != NULL) {
615d8d81063Sfei feng - Sun Microsystems - Beijing China 		mwl_free_dma_mem(&ring->txdesc_dma);
616d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
617d8d81063Sfei feng - Sun Microsystems - Beijing China 
618d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (ring->buf != NULL) {
619d8d81063Sfei feng - Sun Microsystems - Beijing China 		for (i = 0; i < ring->count; i++) {
620d8d81063Sfei feng - Sun Microsystems - Beijing China 			bf = &ring->buf[i];
621d8d81063Sfei feng - Sun Microsystems - Beijing China 			mwl_free_dma_mem(&bf->txbuf_dma);
622d8d81063Sfei feng - Sun Microsystems - Beijing China 		}
623d8d81063Sfei feng - Sun Microsystems - Beijing China 		kmem_free(ring->buf,
624d8d81063Sfei feng - Sun Microsystems - Beijing China 		    (ring->count * sizeof (struct mwl_txbuf)));
625d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
626d8d81063Sfei feng - Sun Microsystems - Beijing China }
627d8d81063Sfei feng - Sun Microsystems - Beijing China 
628d8d81063Sfei feng - Sun Microsystems - Beijing China /*
629d8d81063Sfei feng - Sun Microsystems - Beijing China  * Inform the f/w about location of the tx/rx dma data structures
630d8d81063Sfei feng - Sun Microsystems - Beijing China  * and related state.  This cmd must be done immediately after a
631d8d81063Sfei feng - Sun Microsystems - Beijing China  * mwl_hal_gethwspecs call or the f/w will lockup.
632d8d81063Sfei feng - Sun Microsystems - Beijing China  */
633d8d81063Sfei feng - Sun Microsystems - Beijing China static int
mwl_hal_sethwdma(struct mwl_softc * sc,const struct mwl_hal_txrxdma * dma)634d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_hal_sethwdma(struct mwl_softc *sc, const struct mwl_hal_txrxdma *dma)
635d8d81063Sfei feng - Sun Microsystems - Beijing China {
636d8d81063Sfei feng - Sun Microsystems - Beijing China 	HostCmd_DS_SET_HW_SPEC *pCmd;
637d8d81063Sfei feng - Sun Microsystems - Beijing China 	int retval;
638d8d81063Sfei feng - Sun Microsystems - Beijing China 
639d8d81063Sfei feng - Sun Microsystems - Beijing China 	_CMD_SETUP(pCmd, HostCmd_DS_SET_HW_SPEC, HostCmd_CMD_SET_HW_SPEC);
640d8d81063Sfei feng - Sun Microsystems - Beijing China 	pCmd->WcbBase[0] = LE_32(dma->wcbBase[0]);
641d8d81063Sfei feng - Sun Microsystems - Beijing China 	pCmd->WcbBase[1] = LE_32(dma->wcbBase[1]);
642d8d81063Sfei feng - Sun Microsystems - Beijing China 	pCmd->WcbBase[2] = LE_32(dma->wcbBase[2]);
643d8d81063Sfei feng - Sun Microsystems - Beijing China 	pCmd->WcbBase[3] = LE_32(dma->wcbBase[3]);
644d8d81063Sfei feng - Sun Microsystems - Beijing China 	pCmd->TxWcbNumPerQueue = LE_32(dma->maxNumTxWcb);
645d8d81063Sfei feng - Sun Microsystems - Beijing China 	pCmd->NumTxQueues = LE_32(dma->maxNumWCB);
646d8d81063Sfei feng - Sun Microsystems - Beijing China 	pCmd->TotalRxWcb = LE_32(1);		/* XXX */
647d8d81063Sfei feng - Sun Microsystems - Beijing China 	pCmd->RxPdWrPtr = LE_32(dma->rxDescRead);
648d8d81063Sfei feng - Sun Microsystems - Beijing China 	/*
649d8d81063Sfei feng - Sun Microsystems - Beijing China 	 * pCmd->Flags = LE_32(SET_HW_SPEC_HOSTFORM_BEACON
650d8d81063Sfei feng - Sun Microsystems - Beijing China 	 * #ifdef MWL_HOST_PS_SUPPORT
651d8d81063Sfei feng - Sun Microsystems - Beijing China 	 * | SET_HW_SPEC_HOST_POWERSAVE
652d8d81063Sfei feng - Sun Microsystems - Beijing China 	 * #endif
653d8d81063Sfei feng - Sun Microsystems - Beijing China 	 * | SET_HW_SPEC_HOSTFORM_PROBERESP);
654d8d81063Sfei feng - Sun Microsystems - Beijing China 	 */
655d8d81063Sfei feng - Sun Microsystems - Beijing China 	pCmd->Flags = 0;
656d8d81063Sfei feng - Sun Microsystems - Beijing China 	/* disable multi-bss operation for A1-A4 parts */
657d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (sc->sc_revs.mh_macRev < 5)
658d8d81063Sfei feng - Sun Microsystems - Beijing China 		pCmd->Flags |= LE_32(SET_HW_SPEC_DISABLEMBSS);
659d8d81063Sfei feng - Sun Microsystems - Beijing China 
660d8d81063Sfei feng - Sun Microsystems - Beijing China 	retval = mwlExecuteCmd(sc, HostCmd_CMD_SET_HW_SPEC);
661d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (retval == 0) {
662d8d81063Sfei feng - Sun Microsystems - Beijing China 		if (pCmd->Flags & LE_32(SET_HW_SPEC_DISABLEMBSS))
663d8d81063Sfei feng - Sun Microsystems - Beijing China 			sc->sc_hw_flags &= ~MHF_MBSS;
664d8d81063Sfei feng - Sun Microsystems - Beijing China 		else
665d8d81063Sfei feng - Sun Microsystems - Beijing China 			sc->sc_hw_flags |= MHF_MBSS;
666d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
667d8d81063Sfei feng - Sun Microsystems - Beijing China 
668d8d81063Sfei feng - Sun Microsystems - Beijing China 	return (retval);
669d8d81063Sfei feng - Sun Microsystems - Beijing China }
670d8d81063Sfei feng - Sun Microsystems - Beijing China 
671d8d81063Sfei feng - Sun Microsystems - Beijing China /*
672d8d81063Sfei feng - Sun Microsystems - Beijing China  * Inform firmware of our tx/rx dma setup.  The BAR 0
673d8d81063Sfei feng - Sun Microsystems - Beijing China  * writes below are for compatibility with older firmware.
674d8d81063Sfei feng - Sun Microsystems - Beijing China  * For current firmware we send this information with a
675d8d81063Sfei feng - Sun Microsystems - Beijing China  * cmd block via mwl_hal_sethwdma.
676d8d81063Sfei feng - Sun Microsystems - Beijing China  */
677d8d81063Sfei feng - Sun Microsystems - Beijing China static int
mwl_setupdma(struct mwl_softc * sc)678d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_setupdma(struct mwl_softc *sc)
679d8d81063Sfei feng - Sun Microsystems - Beijing China {
680d8d81063Sfei feng - Sun Microsystems - Beijing China 	int i, err;
681d8d81063Sfei feng - Sun Microsystems - Beijing China 
682d8d81063Sfei feng - Sun Microsystems - Beijing China 	sc->sc_hwdma.rxDescRead = sc->sc_rxring.physaddr;
683d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_mem_write4(sc, sc->sc_hwspecs.rxDescRead, sc->sc_hwdma.rxDescRead);
684d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_mem_write4(sc, sc->sc_hwspecs.rxDescWrite, sc->sc_hwdma.rxDescRead);
685d8d81063Sfei feng - Sun Microsystems - Beijing China 
686d8d81063Sfei feng - Sun Microsystems - Beijing China 	for (i = 0; i < MWL_NUM_TX_QUEUES - MWL_NUM_ACK_QUEUES; i++) {
687d8d81063Sfei feng - Sun Microsystems - Beijing China 		struct mwl_tx_ring *txring = &sc->sc_txring[i];
688d8d81063Sfei feng - Sun Microsystems - Beijing China 		sc->sc_hwdma.wcbBase[i] = txring->physaddr;
689d8d81063Sfei feng - Sun Microsystems - Beijing China 		mwl_mem_write4(sc, sc->sc_hwspecs.wcbBase[i],
690d8d81063Sfei feng - Sun Microsystems - Beijing China 		    sc->sc_hwdma.wcbBase[i]);
691d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
692d8d81063Sfei feng - Sun Microsystems - Beijing China 	sc->sc_hwdma.maxNumTxWcb = MWL_TX_RING_COUNT;
693d8d81063Sfei feng - Sun Microsystems - Beijing China 	sc->sc_hwdma.maxNumWCB = MWL_NUM_TX_QUEUES - MWL_NUM_ACK_QUEUES;
694d8d81063Sfei feng - Sun Microsystems - Beijing China 
695d8d81063Sfei feng - Sun Microsystems - Beijing China 	err = mwl_hal_sethwdma(sc, &sc->sc_hwdma);
696d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (err != 0) {
697d8d81063Sfei feng - Sun Microsystems - Beijing China 		MWL_DBG(MWL_DBG_DMA, "mwl: mwl_setupdma(): "
698d8d81063Sfei feng - Sun Microsystems - Beijing China 		    "unable to setup tx/rx dma; hal status %u\n", err);
699d8d81063Sfei feng - Sun Microsystems - Beijing China 		/* XXX */
700d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
701d8d81063Sfei feng - Sun Microsystems - Beijing China 
702d8d81063Sfei feng - Sun Microsystems - Beijing China 	return (err);
703d8d81063Sfei feng - Sun Microsystems - Beijing China }
704d8d81063Sfei feng - Sun Microsystems - Beijing China 
705d8d81063Sfei feng - Sun Microsystems - Beijing China /* ARGSUSED */
706d8d81063Sfei feng - Sun Microsystems - Beijing China static void
mwl_txq_init(struct mwl_softc * sc,struct mwl_tx_ring * txring,int qnum)707d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_txq_init(struct mwl_softc *sc, struct mwl_tx_ring *txring, int qnum)
708d8d81063Sfei feng - Sun Microsystems - Beijing China {
709d8d81063Sfei feng - Sun Microsystems - Beijing China 	struct mwl_txbuf *bf;
710d8d81063Sfei feng - Sun Microsystems - Beijing China 	struct mwl_txdesc *ds;
711d8d81063Sfei feng - Sun Microsystems - Beijing China 	int i;
712d8d81063Sfei feng - Sun Microsystems - Beijing China 
713d8d81063Sfei feng - Sun Microsystems - Beijing China 	txring->qnum = qnum;
714d8d81063Sfei feng - Sun Microsystems - Beijing China 	txring->txpri = 0;	/* XXX */
715d8d81063Sfei feng - Sun Microsystems - Beijing China 
716d8d81063Sfei feng - Sun Microsystems - Beijing China 	bf = txring->buf;
717d8d81063Sfei feng - Sun Microsystems - Beijing China 	ds = txring->desc;
718d8d81063Sfei feng - Sun Microsystems - Beijing China 	for (i = 0; i < MWL_TX_RING_COUNT - 1; i++) {
719d8d81063Sfei feng - Sun Microsystems - Beijing China 		bf++;
720d8d81063Sfei feng - Sun Microsystems - Beijing China 		ds->pPhysNext = bf->bf_daddr;
721d8d81063Sfei feng - Sun Microsystems - Beijing China 		ds++;
722d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
723d8d81063Sfei feng - Sun Microsystems - Beijing China 	bf = txring->buf;
724d8d81063Sfei feng - Sun Microsystems - Beijing China 	ds->pPhysNext = LE_32(bf->bf_daddr);
725d8d81063Sfei feng - Sun Microsystems - Beijing China }
726d8d81063Sfei feng - Sun Microsystems - Beijing China 
727d8d81063Sfei feng - Sun Microsystems - Beijing China /*
728d8d81063Sfei feng - Sun Microsystems - Beijing China  * Setup a hardware data transmit queue for the specified
729d8d81063Sfei feng - Sun Microsystems - Beijing China  * access control.  We record the mapping from ac's
730d8d81063Sfei feng - Sun Microsystems - Beijing China  * to h/w queues for use by mwl_tx_start.
731d8d81063Sfei feng - Sun Microsystems - Beijing China  */
732d8d81063Sfei feng - Sun Microsystems - Beijing China static int
mwl_tx_setup(struct mwl_softc * sc,int ac,int mvtype)733d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_tx_setup(struct mwl_softc *sc, int ac, int mvtype)
734d8d81063Sfei feng - Sun Microsystems - Beijing China {
735d8d81063Sfei feng - Sun Microsystems - Beijing China #define	N(a)	(sizeof (a)/sizeof (a[0]))
736d8d81063Sfei feng - Sun Microsystems - Beijing China 	struct mwl_tx_ring *txring;
737d8d81063Sfei feng - Sun Microsystems - Beijing China 
738d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (ac >= N(sc->sc_ac2q)) {
739d8d81063Sfei feng - Sun Microsystems - Beijing China 		MWL_DBG(MWL_DBG_DMA, "mwl: mwl_tx_setup(): "
740d8d81063Sfei feng - Sun Microsystems - Beijing China 		    "AC %u out of range, max %u!\n",
741d8d81063Sfei feng - Sun Microsystems - Beijing China 		    ac, (uint_t)N(sc->sc_ac2q));
742d8d81063Sfei feng - Sun Microsystems - Beijing China 		return (0);
743d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
744d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (mvtype >= MWL_NUM_TX_QUEUES) {
745d8d81063Sfei feng - Sun Microsystems - Beijing China 		MWL_DBG(MWL_DBG_DMA, "mwl: mwl_tx_setup(): "
746d8d81063Sfei feng - Sun Microsystems - Beijing China 		    "mvtype %u out of range, max %u!\n",
747d8d81063Sfei feng - Sun Microsystems - Beijing China 		    mvtype, MWL_NUM_TX_QUEUES);
748d8d81063Sfei feng - Sun Microsystems - Beijing China 		return (0);
749d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
750d8d81063Sfei feng - Sun Microsystems - Beijing China 	txring = &sc->sc_txring[mvtype];
751d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_txq_init(sc, txring, mvtype);
752d8d81063Sfei feng - Sun Microsystems - Beijing China 	sc->sc_ac2q[ac] = txring;
753d8d81063Sfei feng - Sun Microsystems - Beijing China 	return (1);
754d8d81063Sfei feng - Sun Microsystems - Beijing China #undef N
755d8d81063Sfei feng - Sun Microsystems - Beijing China }
756d8d81063Sfei feng - Sun Microsystems - Beijing China 
757d8d81063Sfei feng - Sun Microsystems - Beijing China static int
mwl_setup_txq(struct mwl_softc * sc)758d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_setup_txq(struct mwl_softc *sc)
759d8d81063Sfei feng - Sun Microsystems - Beijing China {
760d8d81063Sfei feng - Sun Microsystems - Beijing China 	int err = 0;
761d8d81063Sfei feng - Sun Microsystems - Beijing China 
762d8d81063Sfei feng - Sun Microsystems - Beijing China 	/* NB: insure BK queue is the lowest priority h/w queue */
763d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (!mwl_tx_setup(sc, WME_AC_BK, MWL_WME_AC_BK)) {
764d8d81063Sfei feng - Sun Microsystems - Beijing China 		MWL_DBG(MWL_DBG_DMA, "mwl: mwl_setup_txq(): "
765d8d81063Sfei feng - Sun Microsystems - Beijing China 		    "unable to setup xmit queue for %s traffic!\n",
766d8d81063Sfei feng - Sun Microsystems - Beijing China 		    mwl_wme_acnames[WME_AC_BK]);
767d8d81063Sfei feng - Sun Microsystems - Beijing China 		err = EIO;
768d8d81063Sfei feng - Sun Microsystems - Beijing China 		return (err);
769d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
770d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (!mwl_tx_setup(sc, WME_AC_BE, MWL_WME_AC_BE) ||
771d8d81063Sfei feng - Sun Microsystems - Beijing China 	    !mwl_tx_setup(sc, WME_AC_VI, MWL_WME_AC_VI) ||
772d8d81063Sfei feng - Sun Microsystems - Beijing China 	    !mwl_tx_setup(sc, WME_AC_VO, MWL_WME_AC_VO)) {
773d8d81063Sfei feng - Sun Microsystems - Beijing China 		/*
774d8d81063Sfei feng - Sun Microsystems - Beijing China 		 * Not enough hardware tx queues to properly do WME;
775d8d81063Sfei feng - Sun Microsystems - Beijing China 		 * just punt and assign them all to the same h/w queue.
776d8d81063Sfei feng - Sun Microsystems - Beijing China 		 * We could do a better job of this if, for example,
777d8d81063Sfei feng - Sun Microsystems - Beijing China 		 * we allocate queues when we switch from station to
778d8d81063Sfei feng - Sun Microsystems - Beijing China 		 * AP mode.
779d8d81063Sfei feng - Sun Microsystems - Beijing China 		 */
780d8d81063Sfei feng - Sun Microsystems - Beijing China 		sc->sc_ac2q[WME_AC_BE] = sc->sc_ac2q[WME_AC_BK];
781d8d81063Sfei feng - Sun Microsystems - Beijing China 		sc->sc_ac2q[WME_AC_VI] = sc->sc_ac2q[WME_AC_BK];
782d8d81063Sfei feng - Sun Microsystems - Beijing China 		sc->sc_ac2q[WME_AC_VO] = sc->sc_ac2q[WME_AC_BK];
783d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
784d8d81063Sfei feng - Sun Microsystems - Beijing China 
785d8d81063Sfei feng - Sun Microsystems - Beijing China 	return (err);
786d8d81063Sfei feng - Sun Microsystems - Beijing China }
787d8d81063Sfei feng - Sun Microsystems - Beijing China 
788d8d81063Sfei feng - Sun Microsystems - Beijing China /*
789d8d81063Sfei feng - Sun Microsystems - Beijing China  * find mwl firmware module's "_start" "_end" symbols
790d8d81063Sfei feng - Sun Microsystems - Beijing China  * and get its size.
791d8d81063Sfei feng - Sun Microsystems - Beijing China  */
792d8d81063Sfei feng - Sun Microsystems - Beijing China static int
mwl_loadsym(ddi_modhandle_t modp,char * sym,char ** start,size_t * len)793d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_loadsym(ddi_modhandle_t modp, char *sym, char **start, size_t *len)
794d8d81063Sfei feng - Sun Microsystems - Beijing China {
795d8d81063Sfei feng - Sun Microsystems - Beijing China 	char start_sym[64];
796d8d81063Sfei feng - Sun Microsystems - Beijing China 	char end_sym[64];
797d8d81063Sfei feng - Sun Microsystems - Beijing China 	char *p, *end;
798d8d81063Sfei feng - Sun Microsystems - Beijing China 	int rv;
799d8d81063Sfei feng - Sun Microsystems - Beijing China 	size_t n;
800d8d81063Sfei feng - Sun Microsystems - Beijing China 
801d8d81063Sfei feng - Sun Microsystems - Beijing China 	(void) snprintf(start_sym, sizeof (start_sym), "%s_start", sym);
802d8d81063Sfei feng - Sun Microsystems - Beijing China 	(void) snprintf(end_sym, sizeof (end_sym), "%s_end", sym);
803d8d81063Sfei feng - Sun Microsystems - Beijing China 
804d8d81063Sfei feng - Sun Microsystems - Beijing China 	p = (char *)ddi_modsym(modp, start_sym, &rv);
805d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (p == NULL || rv != 0) {
806d8d81063Sfei feng - Sun Microsystems - Beijing China 		MWL_DBG(MWL_DBG_FW, "mwl: mwl_loadsym(): "
807d8d81063Sfei feng - Sun Microsystems - Beijing China 		    "mod %s: symbol %s not found\n", sym, start_sym);
808d8d81063Sfei feng - Sun Microsystems - Beijing China 		return (-1);
809d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
810d8d81063Sfei feng - Sun Microsystems - Beijing China 
811d8d81063Sfei feng - Sun Microsystems - Beijing China 	end = (char *)ddi_modsym(modp, end_sym, &rv);
812d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (end == NULL || rv != 0) {
813d8d81063Sfei feng - Sun Microsystems - Beijing China 		MWL_DBG(MWL_DBG_FW, "mwl: mwl_loadsym(): "
814d8d81063Sfei feng - Sun Microsystems - Beijing China 		    "mod %s: symbol %s not found\n", sym, end_sym);
815d8d81063Sfei feng - Sun Microsystems - Beijing China 		return (-1);
816d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
817d8d81063Sfei feng - Sun Microsystems - Beijing China 
818d8d81063Sfei feng - Sun Microsystems - Beijing China 	n = _PTRDIFF(end, p);
819d8d81063Sfei feng - Sun Microsystems - Beijing China 	*start = p;
820d8d81063Sfei feng - Sun Microsystems - Beijing China 	*len = n;
821d8d81063Sfei feng - Sun Microsystems - Beijing China 
822d8d81063Sfei feng - Sun Microsystems - Beijing China 	return (0);
823d8d81063Sfei feng - Sun Microsystems - Beijing China }
824d8d81063Sfei feng - Sun Microsystems - Beijing China 
825d8d81063Sfei feng - Sun Microsystems - Beijing China static void
mwlFwReset(struct mwl_softc * sc)826d8d81063Sfei feng - Sun Microsystems - Beijing China mwlFwReset(struct mwl_softc *sc)
827d8d81063Sfei feng - Sun Microsystems - Beijing China {
828d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (mwl_ctl_read4(sc,  MACREG_REG_INT_CODE) == 0xffffffff) {
829d8d81063Sfei feng - Sun Microsystems - Beijing China 		MWL_DBG(MWL_DBG_FW, "mwl: mwlFWReset(): "
830d8d81063Sfei feng - Sun Microsystems - Beijing China 		    "device not present!\n");
831d8d81063Sfei feng - Sun Microsystems - Beijing China 		return;
832d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
833d8d81063Sfei feng - Sun Microsystems - Beijing China 
834d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_ctl_write4(sc, MACREG_REG_H2A_INTERRUPT_EVENTS, ISR_RESET);
835d8d81063Sfei feng - Sun Microsystems - Beijing China 	sc->sc_hw_flags &= ~MHF_FWHANG;
836d8d81063Sfei feng - Sun Microsystems - Beijing China }
837d8d81063Sfei feng - Sun Microsystems - Beijing China 
838d8d81063Sfei feng - Sun Microsystems - Beijing China static void
mwlPokeSdramController(struct mwl_softc * sc,int SDRAMSIZE_Addr)839d8d81063Sfei feng - Sun Microsystems - Beijing China mwlPokeSdramController(struct mwl_softc *sc, int SDRAMSIZE_Addr)
840d8d81063Sfei feng - Sun Microsystems - Beijing China {
841d8d81063Sfei feng - Sun Microsystems - Beijing China 	/* Set up sdram controller for superflyv2 */
842d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_ctl_write4(sc, 0x00006014, 0x33);
843d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_ctl_write4(sc, 0x00006018, 0xa3a2632);
844d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_ctl_write4(sc, 0x00006010, SDRAMSIZE_Addr);
845d8d81063Sfei feng - Sun Microsystems - Beijing China }
846d8d81063Sfei feng - Sun Microsystems - Beijing China 
847d8d81063Sfei feng - Sun Microsystems - Beijing China static void
mwlTriggerPciCmd(struct mwl_softc * sc)848d8d81063Sfei feng - Sun Microsystems - Beijing China mwlTriggerPciCmd(struct mwl_softc *sc)
849d8d81063Sfei feng - Sun Microsystems - Beijing China {
850d8d81063Sfei feng - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(sc->sc_cmd_dma.dma_hdl,
851d8d81063Sfei feng - Sun Microsystems - Beijing China 	    0,
852d8d81063Sfei feng - Sun Microsystems - Beijing China 	    sc->sc_cmd_dma.alength,
853d8d81063Sfei feng - Sun Microsystems - Beijing China 	    DDI_DMA_SYNC_FORDEV);
854d8d81063Sfei feng - Sun Microsystems - Beijing China 
855d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_ctl_write4(sc, MACREG_REG_GEN_PTR, sc->sc_cmd_dmaaddr);
856d8d81063Sfei feng - Sun Microsystems - Beijing China 	(void) mwl_ctl_read4(sc, MACREG_REG_INT_CODE);
857d8d81063Sfei feng - Sun Microsystems - Beijing China 
858d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_ctl_write4(sc, MACREG_REG_INT_CODE, 0x00);
859d8d81063Sfei feng - Sun Microsystems - Beijing China 	(void) mwl_ctl_read4(sc, MACREG_REG_INT_CODE);
860d8d81063Sfei feng - Sun Microsystems - Beijing China 
861d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwl_ctl_write4(sc, MACREG_REG_H2A_INTERRUPT_EVENTS,
862d8d81063Sfei feng - Sun Microsystems - Beijing China 	    MACREG_H2ARIC_BIT_DOOR_BELL);
863d8d81063Sfei feng - Sun Microsystems - Beijing China 	(void) mwl_ctl_read4(sc, MACREG_REG_INT_CODE);
864d8d81063Sfei feng - Sun Microsystems - Beijing China }
865d8d81063Sfei feng - Sun Microsystems - Beijing China 
866d8d81063Sfei feng - Sun Microsystems - Beijing China static int
mwlWaitFor(struct mwl_softc * sc,uint32_t val)867d8d81063Sfei feng - Sun Microsystems - Beijing China mwlWaitFor(struct mwl_softc *sc, uint32_t val)
868d8d81063Sfei feng - Sun Microsystems - Beijing China {
869d8d81063Sfei feng - Sun Microsystems - Beijing China 	int i;
870d8d81063Sfei feng - Sun Microsystems - Beijing China 
871d8d81063Sfei feng - Sun Microsystems - Beijing China 	for (i = 0; i < FW_MAX_NUM_CHECKS; i++) {
872d8d81063Sfei feng - Sun Microsystems - Beijing China 		DELAY(FW_CHECK_USECS);
873d8d81063Sfei feng - Sun Microsystems - Beijing China 		if (mwl_ctl_read4(sc, MACREG_REG_INT_CODE) == val)
874d8d81063Sfei feng - Sun Microsystems - Beijing China 			return (1);
875d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
876d8d81063Sfei feng - Sun Microsystems - Beijing China 	return (0);
877d8d81063Sfei feng - Sun Microsystems - Beijing China }
878d8d81063Sfei feng - Sun Microsystems - Beijing China 
879d8d81063Sfei feng - Sun Microsystems - Beijing China /*
880d8d81063Sfei feng - Sun Microsystems - Beijing China  * Firmware block xmit when talking to the boot-rom.
881d8d81063Sfei feng - Sun Microsystems - Beijing China  */
882d8d81063Sfei feng - Sun Microsystems - Beijing China static int
mwlSendBlock(struct mwl_softc * sc,int bsize,const void * data,size_t dsize)883d8d81063Sfei feng - Sun Microsystems - Beijing China mwlSendBlock(struct mwl_softc *sc, int bsize, const void *data, size_t dsize)
884d8d81063Sfei feng - Sun Microsystems - Beijing China {
885d8d81063Sfei feng - Sun Microsystems - Beijing China 	sc->sc_cmd_mem[0] = LE_16(HostCmd_CMD_CODE_DNLD);
886d8d81063Sfei feng - Sun Microsystems - Beijing China 	sc->sc_cmd_mem[1] = LE_16(bsize);
887d8d81063Sfei feng - Sun Microsystems - Beijing China 	(void) memcpy(&sc->sc_cmd_mem[4], data, dsize);
888d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwlTriggerPciCmd(sc);
889d8d81063Sfei feng - Sun Microsystems - Beijing China 	/* XXX 2000 vs 200 */
890d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (mwlWaitFor(sc, MACREG_INT_CODE_CMD_FINISHED)) {
891d8d81063Sfei feng - Sun Microsystems - Beijing China 		mwl_ctl_write4(sc, MACREG_REG_INT_CODE, 0);
892d8d81063Sfei feng - Sun Microsystems - Beijing China 		return (1);
893d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
894d8d81063Sfei feng - Sun Microsystems - Beijing China 
895d8d81063Sfei feng - Sun Microsystems - Beijing China 	MWL_DBG(MWL_DBG_FW, "mwl: mwlSendBlock(): "
896d8d81063Sfei feng - Sun Microsystems - Beijing China 	    "timeout waiting for CMD_FINISHED, INT_CODE 0x%x\n",
897d8d81063Sfei feng - Sun Microsystems - Beijing China 	    mwl_ctl_read4(sc, MACREG_REG_INT_CODE));
898d8d81063Sfei feng - Sun Microsystems - Beijing China 	return (0);
899d8d81063Sfei feng - Sun Microsystems - Beijing China }
900d8d81063Sfei feng - Sun Microsystems - Beijing China 
901d8d81063Sfei feng - Sun Microsystems - Beijing China /*
902d8d81063Sfei feng - Sun Microsystems - Beijing China  * Firmware block xmit when talking to the 1st-stage loader.
903d8d81063Sfei feng - Sun Microsystems - Beijing China  */
904d8d81063Sfei feng - Sun Microsystems - Beijing China static int
mwlSendBlock2(struct mwl_softc * sc,const void * data,size_t dsize)905d8d81063Sfei feng - Sun Microsystems - Beijing China mwlSendBlock2(struct mwl_softc *sc, const void *data, size_t dsize)
906d8d81063Sfei feng - Sun Microsystems - Beijing China {
907d8d81063Sfei feng - Sun Microsystems - Beijing China 	(void) memcpy(&sc->sc_cmd_mem[0], data, dsize);
908d8d81063Sfei feng - Sun Microsystems - Beijing China 	mwlTriggerPciCmd(sc);
909d8d81063Sfei feng - Sun Microsystems - Beijing China 	if (mwlWaitFor(sc, MACREG_INT_CODE_CMD_FINISHED)) {
910d8d81063Sfei feng - Sun Microsystems - Beijing China 		mwl_ctl_write4(sc, MACREG_REG_INT_CODE, 0);
911d8d81063Sfei feng - Sun Microsystems - Beijing China 		return (1);
912d8d81063Sfei feng - Sun Microsystems - Beijing China 	}
913d8d81063Sfei feng - Sun Microsystems - Beijing China 
914d8d81063Sfei feng - Sun Microsystems - Beijing China 	MWL_DBG(MWL_DBG_FW, "mwl: mwlSendBlock2(): "
915d8d81063Sfei feng - Sun Microsystems - Beijing China 	    "timeout waiting for CMD_FINISHED, INT_CODE 0x%x\n",
916d8d81063Sfei feng - Sun Microsystems - Beijing China 	    mwl_ctl_read4(sc, MACREG_REG_INT_CODE));
917d8d81063Sfei feng - Sun Microsystems - Beijing China 	return (0);
918d8d81063Sfei feng - Sun Microsystems - Beijing China }
919d8d81063Sfei feng - Sun Microsystems - Beijing China 
920d8d81063Sfei feng - Sun Microsystems - Beijing China /* ARGSUSED */
921d8d81063Sfei feng - Sun Microsystems - Beijing China static int
mwl_fwload(struct mwl_softc * sc,void * fwargs)922d8d81063Sfei feng - Sun Microsystems - Beijing China mwl_fwload(struct mwl_softc *sc, void *fwargs)
923d8d81063Sfei feng - Sun Microsystems - Beijing China {
924d8d81063Sfei feng - Sun Microsystems - Beijing China 	char *fwname = "mwlfw";
925d8d81063Sfei feng - Sun Microsystems - Beijing China 	char *fwbootname = "mwlboot";
926d8d81063Sfei feng - Sun Microsystems - Beijing China 	char *fwbinname = "mw88W8363fw";
927d8d81063Sfei feng - Sun Microsystems - Beijing China 	char *fwboot_index, *fw_index;
928d8d81063Sfei feng - Sun Microsystems - Beijing China 	uint8_t *fw, *fwboot;
929d8d81063Sfei feng - Sun Microsystems - Beijing China 	ddi_modhandle_t modfw;
930d8d81063Sfei feng - Sun Microsystems - Beijing China 	/* XXX get from firmware header */
931d8d81063Sfei feng - Sun Microsystems - Beijing China 	uint32_t FwReadySignature = HostCmd_SOFTAP_FWRDY_SIGNATURE;
932d8d81063Sfei feng - Sun Microsystems - Beijing China 	uint32_t OpMode = HostCmd_SOFTAP_MODE;
933d8d81063Sfei feng - Sun Microsystems - Beijing China 	const uint8_t *fp, *ep;
934d8d81063Sfei feng - Sun Microsystems - Beijing China 	size_t fw_size, fwboot_size;
935d8d81063Sfei feng - Sun Microsystems - Beijing China 	uint32_t blocksize, nbytes;
936d8d81063Sfei feng - Sun Microsystems - Beijing China 	int i, rv, err, ntries;
937d8d81063Sfei feng - Sun Microsystems - Beijing China 
938d8d81063Sfei feng - Sun Microsystems - Beijing China 	rv = err = 0;
939d8d81063Sfei feng - Sun Microsystems - Beijing China 	fw = fwboot = NULL;
940d8d81063Sfei feng - Sun Microsystems - Beijing China 	fw_index = fwboot_index = NULL;
941d8d81063Sfei feng - Sun Microsystems - Beijing China 
942d8d81063Sfei feng - Sun Microsystems - Beijing China 	modfw = ddi_modopen(fwname, KRTLD_MODE_FIRST, &rv);