1149871Sscottl
2149871Sscottl/*-
3136849Sscottl * Copyright (c) 2005, 2006
4136849Sscottl *	Damien Bergamini <damien.bergamini@free.fr>
5136849Sscottl *
6136849Sscottl * Copyright (c) 2006, 2008
7136849Sscottl *	Hans Petter Selasky <hselasky@FreeBSD.org>
8136849Sscottl *
9136849Sscottl * Permission to use, copy, modify, and distribute this software for any
10136849Sscottl * purpose with or without fee is hereby granted, provided that the above
11136849Sscottl * copyright notice and this permission notice appear in all copies.
12136849Sscottl *
13136849Sscottl * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14136849Sscottl * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15136849Sscottl * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16136849Sscottl * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17136849Sscottl * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18136849Sscottl * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19136849Sscottl * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20136849Sscottl */
21136849Sscottl
22136849Sscottl#include <sys/cdefs.h>
23136849Sscottl/*-
24136849Sscottl * Ralink Technology RT2500USB chipset driver
25136849Sscottl * http://www.ralinktech.com/
26227912Smarius */
27227912Smarius
28227912Smarius#include "opt_wlan.h"
29149871Sscottl
30136849Sscottl#include <sys/param.h>
31136849Sscottl#include <sys/sockio.h>
32136849Sscottl#include <sys/sysctl.h>
33136849Sscottl#include <sys/lock.h>
34136849Sscottl#include <sys/mutex.h>
35136849Sscottl#include <sys/mbuf.h>
36136849Sscottl#include <sys/kernel.h>
37136849Sscottl#include <sys/socket.h>
38136849Sscottl#include <sys/systm.h>
39136849Sscottl#include <sys/malloc.h>
40136849Sscottl#include <sys/module.h>
41136849Sscottl#include <sys/bus.h>
42136849Sscottl#include <sys/endian.h>
43149871Sscottl#include <sys/kdb.h>
44149871Sscottl
45269617Sjhb#include <net/bpf.h>
46149871Sscottl#include <net/if.h>
47136849Sscottl#include <net/if_var.h>
48136849Sscottl#include <net/if_arp.h>
49136849Sscottl#include <net/ethernet.h>
50149871Sscottl#include <net/if_dl.h>
51149871Sscottl#include <net/if_media.h>
52149871Sscottl#include <net/if_types.h>
53149871Sscottl
54136849Sscottl#ifdef INET
55136849Sscottl#include <netinet/in.h>
56136849Sscottl#include <netinet/in_systm.h>
57143039Sscottl#include <netinet/in_var.h>
58136849Sscottl#include <netinet/if_ether.h>
59149871Sscottl#include <netinet/ip.h>
60136849Sscottl#endif
61136849Sscottl
62136849Sscottl#include <net80211/ieee80211_var.h>
63149871Sscottl#include <net80211/ieee80211_regdomain.h>
64136849Sscottl#include <net80211/ieee80211_radiotap.h>
65136849Sscottl#include <net80211/ieee80211_ratectl.h>
66136849Sscottl
67136849Sscottl#include <dev/usb/usb.h>
68136849Sscottl#include <dev/usb/usbdi.h>
69149871Sscottl#include "usbdevs.h"
70136849Sscottl
71136849Sscottl#define	USB_DEBUG_VAR ural_debug
72136849Sscottl#include <dev/usb/usb_debug.h>
73149871Sscottl
74149871Sscottl#include <dev/usb/wlan/if_uralreg.h>
75149871Sscottl#include <dev/usb/wlan/if_uralvar.h>
76149871Sscottl
77149871Sscottl#ifdef USB_DEBUG
78149871Sscottlstatic int ural_debug = 0;
79149871Sscottl
80149871Sscottlstatic SYSCTL_NODE(_hw_usb, OID_AUTO, ural, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
81149871Sscottl    "USB ural");
82149871SscottlSYSCTL_INT(_hw_usb_ural, OID_AUTO, debug, CTLFLAG_RWTUN, &ural_debug, 0,
83149871Sscottl    "Debug level");
84149871Sscottl#endif
85149871Sscottl
86149871Sscottl#define URAL_RSSI(rssi)					\
87149871Sscottl	((rssi) > (RAL_NOISE_FLOOR + RAL_RSSI_CORR) ?	\
88149871Sscottl	 ((rssi) - (RAL_NOISE_FLOOR + RAL_RSSI_CORR)) : 0)
89190863Sdelphij
90227912Smarius/* various supported device vendors/products */
91149871Sscottlstatic const STRUCT_USB_HOST_ID ural_devs[] = {
92149871Sscottl#define	URAL_DEV(v,p)  { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
93149871Sscottl	URAL_DEV(ASUS, WL167G),
94149871Sscottl	URAL_DEV(ASUS, RT2570),
95149871Sscottl	URAL_DEV(BELKIN, F5D7050),
96149871Sscottl	URAL_DEV(BELKIN, F5D7051),
97149871Sscottl	URAL_DEV(CISCOLINKSYS, HU200TS),
98149871Sscottl	URAL_DEV(CISCOLINKSYS, WUSB54G),
99149871Sscottl	URAL_DEV(CISCOLINKSYS, WUSB54GP),
100149871Sscottl	URAL_DEV(CONCEPTRONIC2, C54RU),
101149871Sscottl	URAL_DEV(DLINK, DWLG122),
102149871Sscottl	URAL_DEV(GIGABYTE, GN54G),
103236379Seadler	URAL_DEV(GIGABYTE, GNWBKG),
104149871Sscottl	URAL_DEV(GUILLEMOT, HWGUSB254),
105149871Sscottl	URAL_DEV(MELCO, KG54),
106149871Sscottl	URAL_DEV(MELCO, KG54AI),
107149871Sscottl	URAL_DEV(MELCO, KG54YB),
108149871Sscottl	URAL_DEV(MELCO, NINWIFI),
109149871Sscottl	URAL_DEV(MSI, RT2570),
110149871Sscottl	URAL_DEV(MSI, RT2570_2),
111149871Sscottl	URAL_DEV(MSI, RT2570_3),
112149871Sscottl	URAL_DEV(NOVATECH, NV902),
113149871Sscottl	URAL_DEV(RALINK, RT2570),
114269617Sjhb	URAL_DEV(RALINK, RT2570_2),
115136849Sscottl	URAL_DEV(RALINK, RT2570_3),
116136849Sscottl	URAL_DEV(SIEMENS2, WL54G),
117136849Sscottl	URAL_DEV(SMC, 2862WG),
118136849Sscottl	URAL_DEV(SPHAIRON, UB801R),
119136849Sscottl	URAL_DEV(SURECOM, RT2570),
120136849Sscottl	URAL_DEV(VTECH, RT2570),
121136849Sscottl	URAL_DEV(ZINWELL, RT2570),
122136849Sscottl#undef URAL_DEV
123136849Sscottl};
124136849Sscottl
125136849Sscottlstatic usb_callback_t ural_bulk_read_callback;
126136849Sscottlstatic usb_callback_t ural_bulk_write_callback;
127136849Sscottl
128136849Sscottlstatic usb_error_t	ural_do_request(struct ural_softc *sc,
129136849Sscottl			    struct usb_device_request *req, void *data);
130136849Sscottlstatic struct ieee80211vap *ural_vap_create(struct ieee80211com *,
131136849Sscottl			    const char [IFNAMSIZ], int, enum ieee80211_opmode,
132136849Sscottl			    int, const uint8_t [IEEE80211_ADDR_LEN],
133136849Sscottl			    const uint8_t [IEEE80211_ADDR_LEN]);
134136849Sscottlstatic void		ural_vap_delete(struct ieee80211vap *);
135136849Sscottlstatic void		ural_tx_free(struct ural_tx_data *, int);
136136849Sscottlstatic void		ural_setup_tx_list(struct ural_softc *);
137136849Sscottlstatic void		ural_unsetup_tx_list(struct ural_softc *);
138136849Sscottlstatic int		ural_newstate(struct ieee80211vap *,
139269617Sjhb			    enum ieee80211_state, int);
140269617Sjhbstatic void		ural_setup_tx_desc(struct ural_softc *,
141136849Sscottl			    struct ural_tx_desc *, uint32_t, int, int);
142136849Sscottlstatic int		ural_tx_bcn(struct ural_softc *, struct mbuf *,
143149871Sscottl			    struct ieee80211_node *);
144136849Sscottlstatic int		ural_tx_mgt(struct ural_softc *, struct mbuf *,
145136849Sscottl			    struct ieee80211_node *);
146136849Sscottlstatic int		ural_tx_data(struct ural_softc *, struct mbuf *,
147136849Sscottl			    struct ieee80211_node *);
148136849Sscottlstatic int		ural_transmit(struct ieee80211com *, struct mbuf *);
149136849Sscottlstatic void		ural_start(struct ural_softc *);
150136849Sscottlstatic void		ural_parent(struct ieee80211com *);
151136849Sscottlstatic void		ural_set_testmode(struct ural_softc *);
152136849Sscottlstatic void		ural_eeprom_read(struct ural_softc *, uint16_t, void *,
153136849Sscottl			    int);
154136849Sscottlstatic uint16_t		ural_read(struct ural_softc *, uint16_t);
155136849Sscottlstatic void		ural_read_multi(struct ural_softc *, uint16_t, void *,
156136849Sscottl			    int);
157269617Sjhbstatic void		ural_write(struct ural_softc *, uint16_t, uint16_t);
158269617Sjhbstatic void		ural_write_multi(struct ural_softc *, uint16_t, void *,
159136849Sscottl			    int) __unused;
160190809Sdelphijstatic void		ural_bbp_write(struct ural_softc *, uint8_t, uint8_t);
161136849Sscottlstatic uint8_t		ural_bbp_read(struct ural_softc *, uint8_t);
162136849Sscottlstatic void		ural_rf_write(struct ural_softc *, uint8_t, uint32_t);
163136849Sscottlstatic void		ural_scan_start(struct ieee80211com *);
164136849Sscottlstatic void		ural_scan_end(struct ieee80211com *);
165136849Sscottlstatic void		ural_getradiocaps(struct ieee80211com *, int, int *,
166136849Sscottl			    struct ieee80211_channel[]);
167298955Spfgstatic void		ural_set_channel(struct ieee80211com *);
168136849Sscottlstatic void		ural_set_chan(struct ural_softc *,
169136849Sscottl			    struct ieee80211_channel *);
170136849Sscottlstatic void		ural_disable_rf_tune(struct ural_softc *);
171136849Sscottlstatic void		ural_enable_tsf_sync(struct ural_softc *);
172136849Sscottlstatic void 		ural_enable_tsf(struct ural_softc *);
173136849Sscottlstatic void		ural_update_slot(struct ural_softc *);
174136849Sscottlstatic void		ural_set_txpreamble(struct ural_softc *);
175136849Sscottlstatic void		ural_set_basicrates(struct ural_softc *,
176136849Sscottl			    const struct ieee80211_channel *);
177149871Sscottlstatic void		ural_set_bssid(struct ural_softc *, const uint8_t *);
178136849Sscottlstatic void		ural_set_macaddr(struct ural_softc *, const uint8_t *);
179149871Sscottlstatic void		ural_update_promisc(struct ieee80211com *);
180149871Sscottlstatic void		ural_setpromisc(struct ural_softc *);
181149871Sscottlstatic const char	*ural_get_rf(int);
182149871Sscottlstatic void		ural_read_eeprom(struct ural_softc *);
183149871Sscottlstatic int		ural_bbp_init(struct ural_softc *);
184149871Sscottlstatic void		ural_set_txantenna(struct ural_softc *, int);
185149871Sscottlstatic void		ural_set_rxantenna(struct ural_softc *, int);
186149871Sscottlstatic void		ural_init(struct ural_softc *);
187149871Sscottlstatic void		ural_stop(struct ural_softc *);
188149871Sscottlstatic int		ural_raw_xmit(struct ieee80211_node *, struct mbuf *,
189149871Sscottl			    const struct ieee80211_bpf_params *);
190149871Sscottlstatic void		ural_ratectl_start(struct ural_softc *,
191149871Sscottl			    struct ieee80211_node *);
192149871Sscottlstatic void		ural_ratectl_timeout(void *);
193149871Sscottlstatic void		ural_ratectl_task(void *, int);
194149871Sscottlstatic int		ural_pause(struct ural_softc *sc, int timeout);
195149871Sscottl
196136849Sscottl/*
197149871Sscottl * Default values for MAC registers; values taken from the reference driver.
198136849Sscottl */
199136849Sscottlstatic const struct {
200136849Sscottl	uint16_t	reg;
201136849Sscottl	uint16_t	val;
202136849Sscottl} ural_def_mac[] = {
203136849Sscottl	{ RAL_TXRX_CSR5,  0x8c8d },
204136849Sscottl	{ RAL_TXRX_CSR6,  0x8b8a },
205136849Sscottl	{ RAL_TXRX_CSR7,  0x8687 },
206136849Sscottl	{ RAL_TXRX_CSR8,  0x0085 },
207136849Sscottl	{ RAL_MAC_CSR13,  0x1111 },
208136849Sscottl	{ RAL_MAC_CSR14,  0x1e11 },
209136849Sscottl	{ RAL_TXRX_CSR21, 0xe78f },
210136849Sscottl	{ RAL_MAC_CSR9,   0xff1d },
211136849Sscottl	{ RAL_MAC_CSR11,  0x0002 },
212136849Sscottl	{ RAL_MAC_CSR22,  0x0053 },
213136849Sscottl	{ RAL_MAC_CSR15,  0x0000 },
214136849Sscottl	{ RAL_MAC_CSR8,   RAL_FRAME_SIZE },
215136849Sscottl	{ RAL_TXRX_CSR19, 0x0000 },
216149871Sscottl	{ RAL_TXRX_CSR18, 0x005a },
217149871Sscottl	{ RAL_PHY_CSR2,   0x0000 },
218149871Sscottl	{ RAL_TXRX_CSR0,  0x1ec0 },
219136849Sscottl	{ RAL_PHY_CSR4,   0x000f }
220136849Sscottl};
221136849Sscottl
222136849Sscottl/*
223149871Sscottl * Default values for BBP registers; values taken from the reference driver.
224149871Sscottl */
225149871Sscottlstatic const struct {
226149871Sscottl	uint8_t	reg;
227149871Sscottl	uint8_t	val;
228149871Sscottl} ural_def_bbp[] = {
229149871Sscottl	{  3, 0x02 },
230149871Sscottl	{  4, 0x19 },
231136849Sscottl	{ 14, 0x1c },
232136849Sscottl	{ 15, 0x30 },
233136849Sscottl	{ 16, 0xac },
234136849Sscottl	{ 17, 0x48 },
235136849Sscottl	{ 18, 0x18 },
236136849Sscottl	{ 19, 0xff },
237149871Sscottl	{ 20, 0x1e },
238149871Sscottl	{ 21, 0x08 },
239149871Sscottl	{ 22, 0x08 },
240136849Sscottl	{ 23, 0x08 },
241136849Sscottl	{ 24, 0x80 },
242136849Sscottl	{ 25, 0x50 },
243136849Sscottl	{ 26, 0x08 },
244136849Sscottl	{ 27, 0x23 },
245136849Sscottl	{ 30, 0x10 },
246136849Sscottl	{ 31, 0x2b },
247136849Sscottl	{ 32, 0xb9 },
248136849Sscottl	{ 34, 0x12 },
249136849Sscottl	{ 35, 0x50 },
250136849Sscottl	{ 39, 0xc4 },
251136849Sscottl	{ 40, 0x02 },
252136849Sscottl	{ 41, 0x60 },
253136849Sscottl	{ 53, 0x10 },
254190809Sdelphij	{ 54, 0x18 },
255136849Sscottl	{ 56, 0x08 },
256136849Sscottl	{ 57, 0x10 },
257136849Sscottl	{ 58, 0x08 },
258136849Sscottl	{ 61, 0x60 },
259149871Sscottl	{ 62, 0x10 },
260136849Sscottl	{ 75, 0xff }
261136849Sscottl};
262136849Sscottl
263136849Sscottl/*
264136849Sscottl * Default values for RF register R2 indexed by channel numbers.
265149871Sscottl */
266149871Sscottlstatic const uint32_t ural_rf2522_r2[] = {
267149871Sscottl	0x307f6, 0x307fb, 0x30800, 0x30805, 0x3080a, 0x3080f, 0x30814,
268136849Sscottl	0x30819, 0x3081e, 0x30823, 0x30828, 0x3082d, 0x30832, 0x3083e
269136849Sscottl};
270149871Sscottl
271136849Sscottlstatic const uint32_t ural_rf2523_r2[] = {
272136849Sscottl	0x00327, 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d,
273136849Sscottl	0x0032e, 0x0032f, 0x00340, 0x00341, 0x00342, 0x00343, 0x00346
274136849Sscottl};
275190809Sdelphij
276149871Sscottlstatic const uint32_t ural_rf2524_r2[] = {
277149871Sscottl	0x00327, 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d,
278136849Sscottl	0x0032e, 0x0032f, 0x00340, 0x00341, 0x00342, 0x00343, 0x00346
279136849Sscottl};
280136849Sscottl
281136849Sscottlstatic const uint32_t ural_rf2525_r2[] = {
282190809Sdelphij	0x20327, 0x20328, 0x20329, 0x2032a, 0x2032b, 0x2032c, 0x2032d,
283149871Sscottl	0x2032e, 0x2032f, 0x20340, 0x20341, 0x20342, 0x20343, 0x20346
284149871Sscottl};
285149871Sscottl
286149871Sscottlstatic const uint32_t ural_rf2525_hi_r2[] = {
287149871Sscottl	0x2032f, 0x20340, 0x20341, 0x20342, 0x20343, 0x20344, 0x20345,
288136849Sscottl	0x20346, 0x20347, 0x20348, 0x20349, 0x2034a, 0x2034b, 0x2034e
289136849Sscottl};
290136849Sscottl
291136849Sscottlstatic const uint32_t ural_rf2525e_r2[] = {
292190809Sdelphij	0x2044d, 0x2044e, 0x2044f, 0x20460, 0x20461, 0x20462, 0x20463,
293149871Sscottl	0x20464, 0x20465, 0x20466, 0x20467, 0x20468, 0x20469, 0x2046b
294149871Sscottl};
295136849Sscottl
296136849Sscottlstatic const uint32_t ural_rf2526_hi_r2[] = {
297136849Sscottl	0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d, 0x0022d,
298136849Sscottl	0x0022e, 0x0022e, 0x0022f, 0x0022d, 0x00240, 0x00240, 0x00241
299190809Sdelphij};
300149871Sscottl
301149871Sscottlstatic const uint32_t ural_rf2526_r2[] = {
302136849Sscottl	0x00226, 0x00227, 0x00227, 0x00228, 0x00228, 0x00229, 0x00229,
303136849Sscottl	0x0022a, 0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d
304136849Sscottl};
305136849Sscottl
306136849Sscottl/*
307136849Sscottl * For dual-band RF, RF registers R1 and R4 also depend on channel number;
308136849Sscottl * values taken from the reference driver.
309136849Sscottl */
310149871Sscottlstatic const struct {
311190809Sdelphij	uint8_t		chan;
312298955Spfg	uint32_t	r1;
313149871Sscottl	uint32_t	r2;
314136849Sscottl	uint32_t	r4;
315136849Sscottl} ural_rf5222[] = {
316136849Sscottl	{   1, 0x08808, 0x0044d, 0x00282 },
317136849Sscottl	{   2, 0x08808, 0x0044e, 0x00282 },
318136849Sscottl	{   3, 0x08808, 0x0044f, 0x00282 },
319136849Sscottl	{   4, 0x08808, 0x00460, 0x00282 },
320136849Sscottl	{   5, 0x08808, 0x00461, 0x00282 },
321136849Sscottl	{   6, 0x08808, 0x00462, 0x00282 },
322136849Sscottl	{   7, 0x08808, 0x00463, 0x00282 },
323136849Sscottl	{   8, 0x08808, 0x00464, 0x00282 },
324136849Sscottl	{   9, 0x08808, 0x00465, 0x00282 },
325149871Sscottl	{  10, 0x08808, 0x00466, 0x00282 },
326149871Sscottl	{  11, 0x08808, 0x00467, 0x00282 },
327136849Sscottl	{  12, 0x08808, 0x00468, 0x00282 },
328136849Sscottl	{  13, 0x08808, 0x00469, 0x00282 },
329149871Sscottl	{  14, 0x08808, 0x0046b, 0x00286 },
330149871Sscottl
331149871Sscottl	{  36, 0x08804, 0x06225, 0x00287 },
332136849Sscottl	{  40, 0x08804, 0x06226, 0x00287 },
333136849Sscottl	{  44, 0x08804, 0x06227, 0x00287 },
334136849Sscottl	{  48, 0x08804, 0x06228, 0x00287 },
335149871Sscottl	{  52, 0x08804, 0x06229, 0x00287 },
336149871Sscottl	{  56, 0x08804, 0x0622a, 0x00287 },
337136849Sscottl	{  60, 0x08804, 0x0622b, 0x00287 },
338136849Sscottl	{  64, 0x08804, 0x0622c, 0x00287 },
339149871Sscottl
340149871Sscottl	{ 100, 0x08804, 0x02200, 0x00283 },
341149871Sscottl	{ 104, 0x08804, 0x02201, 0x00283 },
342136849Sscottl	{ 108, 0x08804, 0x02202, 0x00283 },
343136849Sscottl	{ 112, 0x08804, 0x02203, 0x00283 },
344136849Sscottl	{ 116, 0x08804, 0x02204, 0x00283 },
345149871Sscottl	{ 120, 0x08804, 0x02205, 0x00283 },
346149871Sscottl	{ 124, 0x08804, 0x02206, 0x00283 },
347149871Sscottl	{ 128, 0x08804, 0x02207, 0x00283 },
348136849Sscottl	{ 132, 0x08804, 0x02208, 0x00283 },
349136849Sscottl	{ 136, 0x08804, 0x02209, 0x00283 },
350136849Sscottl	{ 140, 0x08804, 0x0220a, 0x00283 },
351136849Sscottl
352136849Sscottl	{ 149, 0x08808, 0x02429, 0x00281 },
353136849Sscottl	{ 153, 0x08808, 0x0242b, 0x00281 },
354149871Sscottl	{ 157, 0x08808, 0x0242d, 0x00281 },
355149871Sscottl	{ 161, 0x08808, 0x0242f, 0x00281 }
356149871Sscottl};
357136849Sscottl
358136849Sscottlstatic const uint8_t ural_chan_5ghz[] =
359136849Sscottl	{ 36, 40, 44, 48, 52, 56, 60, 64,
360136849Sscottl	  100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140,
361149871Sscottl	  149, 153, 157, 161 };
362149871Sscottl
363136849Sscottlstatic const struct usb_config ural_config[URAL_N_TRANSFER] = {
364136849Sscottl	[URAL_BULK_WR] = {
365149871Sscottl		.type = UE_BULK,
366149871Sscottl		.endpoint = UE_ADDR_ANY,
367149871Sscottl		.direction = UE_DIR_OUT,
368136849Sscottl		.bufsize = (RAL_FRAME_SIZE + RAL_TX_DESC_SIZE + 4),
369136849Sscottl		.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
370136849Sscottl		.callback = ural_bulk_write_callback,
371136849Sscottl		.timeout = 5000,	/* ms */
372136849Sscottl	},
373136849Sscottl	[URAL_BULK_RD] = {
374136849Sscottl		.type = UE_BULK,
375136849Sscottl		.endpoint = UE_ADDR_ANY,
376136849Sscottl		.direction = UE_DIR_IN,
377149871Sscottl		.bufsize = (RAL_FRAME_SIZE + RAL_RX_DESC_SIZE),
378149871Sscottl		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
379149871Sscottl		.callback = ural_bulk_read_callback,
380136849Sscottl	},
381136849Sscottl};
382136849Sscottl
383136849Sscottlstatic device_probe_t ural_match;
384136849Sscottlstatic device_attach_t ural_attach;
385136849Sscottlstatic device_detach_t ural_detach;
386136849Sscottl
387136849Sscottlstatic device_method_t ural_methods[] = {
388136849Sscottl	/* Device interface */
389136849Sscottl	DEVMETHOD(device_probe,		ural_match),
390149871Sscottl	DEVMETHOD(device_attach,	ural_attach),
391136849Sscottl	DEVMETHOD(device_detach,	ural_detach),
392136849Sscottl	DEVMETHOD_END
393136849Sscottl};
394149871Sscottl
395149871Sscottlstatic driver_t ural_driver = {
396149871Sscottl	.name = "ural",
397149871Sscottl	.methods = ural_methods,
398136849Sscottl	.size = sizeof(struct ural_softc),
399136849Sscottl};
400149871Sscottl
401136849SscottlDRIVER_MODULE(ural, uhub, ural_driver, NULL, NULL);
402136849SscottlMODULE_DEPEND(ural, usb, 1, 1, 1);
403149871SscottlMODULE_DEPEND(ural, wlan, 1, 1, 1);
404136849SscottlMODULE_VERSION(ural, 1);
405136849SscottlUSB_PNP_HOST_INFO(ural_devs);
406136849Sscottl
407149871Sscottlstatic int
408136849Sscottlural_match(device_t self)
409136849Sscottl{
410136849Sscottl	struct usb_attach_arg *uaa = device_get_ivars(self);
411149871Sscottl
412136849Sscottl	if (uaa->usb_mode != USB_MODE_HOST)
413136849Sscottl		return (ENXIO);
414149871Sscottl	if (uaa->info.bConfigIndex != 0)
415149871Sscottl		return (ENXIO);
416149871Sscottl	if (uaa->info.bIfaceIndex != RAL_IFACE_INDEX)
417149871Sscottl		return (ENXIO);
418136849Sscottl
419149871Sscottl	return (usbd_lookup_id_by_uaa(ural_devs, sizeof(ural_devs), uaa));
420149871Sscottl}
421136849Sscottl
422136849Sscottlstatic int
423136849Sscottlural_attach(device_t self)
424149871Sscottl{
425149871Sscottl	struct usb_attach_arg *uaa = device_get_ivars(self);
426136849Sscottl	struct ural_softc *sc = device_get_softc(self);
427149871Sscottl	struct ieee80211com *ic = &sc->sc_ic;
428136849Sscottl	uint8_t iface_index;
429136849Sscottl	int error;
430136849Sscottl
431136849Sscottl	device_set_usb_desc(self);
432136849Sscottl	sc->sc_udev = uaa->device;
433149871Sscottl	sc->sc_dev = self;
434149871Sscottl
435136849Sscottl	mtx_init(&sc->sc_mtx, device_get_nameunit(self),
436149871Sscottl	    MTX_NETWORK_LOCK, MTX_DEF);
437149871Sscottl	mbufq_init(&sc->sc_snd, ifqmaxlen);
438136849Sscottl
439136849Sscottl	iface_index = RAL_IFACE_INDEX;
440136849Sscottl	error = usbd_transfer_setup(uaa->device,
441136849Sscottl	    &iface_index, sc->sc_xfer, ural_config,
442136849Sscottl	    URAL_N_TRANSFER, sc, &sc->sc_mtx);
443136849Sscottl	if (error) {
444136849Sscottl		device_printf(self, "could not allocate USB transfers, "
445136849Sscottl		    "err=%s\n", usbd_errstr(error));
446136849Sscottl		goto detach;
447136849Sscottl	}
448136849Sscottl
449136849Sscottl	RAL_LOCK(sc);
450136849Sscottl	/* retrieve RT2570 rev. no */
451136849Sscottl	sc->asic_rev = ural_read(sc, RAL_MAC_CSR0);
452136849Sscottl
453149871Sscottl	/* retrieve MAC address and various other things from EEPROM */
454149871Sscottl	ural_read_eeprom(sc);
455149871Sscottl	RAL_UNLOCK(sc);
456136849Sscottl
457149871Sscottl	device_printf(self, "MAC/BBP RT2570 (rev 0x%02x), RF %s\n",
458136849Sscottl	    sc->asic_rev, ural_get_rf(sc->rf_rev));
459136849Sscottl
460136849Sscottl	ic->ic_softc = sc;
461136849Sscottl	ic->ic_name = device_get_nameunit(self);
462136849Sscottl	ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
463136849Sscottl
464149871Sscottl	/* set device capabilities */
465149871Sscottl	ic->ic_caps =
466149871Sscottl	      IEEE80211_C_STA		/* station mode supported */
467149871Sscottl	    | IEEE80211_C_IBSS		/* IBSS mode supported */
468136849Sscottl	    | IEEE80211_C_MONITOR	/* monitor mode supported */
469190809Sdelphij	    | IEEE80211_C_HOSTAP	/* HostAp mode supported */
470149871Sscottl	    | IEEE80211_C_TXPMGT	/* tx power management */
471136849Sscottl	    | IEEE80211_C_SHPREAMBLE	/* short preamble supported */
472136849Sscottl	    | IEEE80211_C_SHSLOT	/* short slot time supported */
473136849Sscottl	    | IEEE80211_C_BGSCAN	/* bg scanning supported */
474149871Sscottl	    | IEEE80211_C_WPA		/* 802.11i */
475149871Sscottl	    ;
476190809Sdelphij
477149871Sscottl	ural_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans,
478136849Sscottl	    ic->ic_channels);
479136849Sscottl
480136849Sscottl	ieee80211_ifattach(ic);
481136849Sscottl	ic->ic_update_promisc = ural_update_promisc;
482149871Sscottl	ic->ic_raw_xmit = ural_raw_xmit;
483149871Sscottl	ic->ic_scan_start = ural_scan_start;
484149871Sscottl	ic->ic_scan_end = ural_scan_end;
485149871Sscottl	ic->ic_getradiocaps = ural_getradiocaps;
486136849Sscottl	ic->ic_set_channel = ural_set_channel;
487149871Sscottl	ic->ic_parent = ural_parent;
488149871Sscottl	ic->ic_transmit = ural_transmit;
489190809Sdelphij	ic->ic_vap_create = ural_vap_create;
490149871Sscottl	ic->ic_vap_delete = ural_vap_delete;
491136849Sscottl
492136849Sscottl	ieee80211_radiotap_attach(ic,
493136849Sscottl	    &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
494136849Sscottl		RAL_TX_RADIOTAP_PRESENT,
495136849Sscottl	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
496149871Sscottl		RAL_RX_RADIOTAP_PRESENT);
497149871Sscottl
498190809Sdelphij	if (bootverbose)
499149871Sscottl		ieee80211_announce(ic);
500136849Sscottl
501136849Sscottl	return (0);
502149871Sscottl
503149871Sscottldetach:
504190809Sdelphij	ural_detach(self);
505149871Sscottl	return (ENXIO);			/* failure */
506136849Sscottl}
507136849Sscottl
508136849Sscottlstatic int
509136849Sscottlural_detach(device_t self)
510136849Sscottl{
511149871Sscottl	struct ural_softc *sc = device_get_softc(self);
512149871Sscottl	struct ieee80211com *ic = &sc->sc_ic;
513190809Sdelphij
514149871Sscottl	/* prevent further ioctls */
515136849Sscottl	RAL_LOCK(sc);
516149871Sscottl	sc->sc_detached = 1;
517149871Sscottl	RAL_UNLOCK(sc);
518149871Sscottl
519190809Sdelphij	/* stop all USB transfers */
520149871Sscottl	usbd_transfer_unsetup(sc->sc_xfer, URAL_N_TRANSFER);
521136849Sscottl
522136849Sscottl	/* free TX list, if any */
523136849Sscottl	RAL_LOCK(sc);
524149871Sscottl	ural_unsetup_tx_list(sc);
525136849Sscottl	RAL_UNLOCK(sc);
526149871Sscottl
527149871Sscottl	if (ic->ic_softc == sc)
528149871Sscottl		ieee80211_ifdetach(ic);
529149871Sscottl	mbufq_drain(&sc->sc_snd);
530149871Sscottl	mtx_destroy(&sc->sc_mtx);
531149871Sscottl
532149871Sscottl	return (0);
533149871Sscottl}
534190809Sdelphij
535149871Sscottlstatic usb_error_t
536136849Sscottlural_do_request(struct ural_softc *sc,
537136849Sscottl    struct usb_device_request *req, void *data)
538136849Sscottl{
539190809Sdelphij	usb_error_t err;
540149871Sscottl	int ntries = 10;
541149871Sscottl
542149871Sscottl	while (ntries--) {
543149871Sscottl		err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
544190809Sdelphij		    req, data, 0, NULL, 250 /* ms */);
545149871Sscottl		if (err == 0)
546136849Sscottl			break;
547149871Sscottl
548149871Sscottl		DPRINTFN(1, "Control request failed, %s (retrying)\n",
549149871Sscottl		    usbd_errstr(err));
550149871Sscottl		if (ural_pause(sc, hz / 100))
551190809Sdelphij			break;
552149871Sscottl	}
553149871Sscottl	return (err);
554149871Sscottl}
555149871Sscottl
556149871Sscottlstatic struct ieee80211vap *
557190809Sdelphijural_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
558149871Sscottl    enum ieee80211_opmode opmode, int flags,
559149871Sscottl    const uint8_t bssid[IEEE80211_ADDR_LEN],
560149871Sscottl    const uint8_t mac[IEEE80211_ADDR_LEN])
561136849Sscottl{
562190809Sdelphij	struct ural_softc *sc = ic->ic_softc;
563149871Sscottl	struct ural_vap *uvp;
564136849Sscottl	struct ieee80211vap *vap;
565136849Sscottl
566136849Sscottl	if (!TAILQ_EMPTY(&ic->ic_vaps))		/* only one at a time */
567136849Sscottl		return NULL;
568190809Sdelphij	uvp = malloc(sizeof(struct ural_vap), M_80211_VAP, M_WAITOK | M_ZERO);
569149871Sscottl	vap = &uvp->vap;
570136849Sscottl	/* enable s/w bmiss handling for sta mode */
571149871Sscottl
572149871Sscottl	if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
573149871Sscottl	    flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
574149871Sscottl		/* out of memory */
575190809Sdelphij		free(uvp, M_80211_VAP);
576149871Sscottl		return (NULL);
577136849Sscottl	}
578136849Sscottl
579136849Sscottl	/* override state transition machine */
580149871Sscottl	uvp->newstate = vap->iv_newstate;
581149871Sscottl	vap->iv_newstate = ural_newstate;
582136849Sscottl
583149871Sscottl	usb_callout_init_mtx(&uvp->ratectl_ch, &sc->sc_mtx, 0);
584149871Sscottl	TASK_INIT(&uvp->ratectl_task, 0, ural_ratectl_task, uvp);
585149871Sscottl	ieee80211_ratectl_init(vap);
586136849Sscottl	ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
587149871Sscottl
588149871Sscottl	/* complete setup */
589149871Sscottl	ieee80211_vap_attach(vap, ieee80211_media_change,
590149871Sscottl	    ieee80211_media_status, mac);
591136849Sscottl	ic->ic_opmode = opmode;
592136849Sscottl	return vap;
593136849Sscottl}
594190809Sdelphij
595149871Sscottlstatic void
596136849Sscottlural_vap_delete(struct ieee80211vap *vap)
597136849Sscottl{
598149871Sscottl	struct ural_vap *uvp = URAL_VAP(vap);
599149871Sscottl	struct ieee80211com *ic = vap->iv_ic;
600149871Sscottl
601190809Sdelphij	usb_callout_drain(&uvp->ratectl_ch);
602149871Sscottl	ieee80211_draintask(ic, &uvp->ratectl_task);
603136849Sscottl	ieee80211_ratectl_deinit(vap);
604136849Sscottl	ieee80211_vap_detach(vap);
605136849Sscottl	free(uvp, M_80211_VAP);
606136849Sscottl}
607149871Sscottl
608149871Sscottlstatic void
609136849Sscottlural_tx_free(struct ural_tx_data *data, int txerr)
610149871Sscottl{
611149871Sscottl	struct ural_softc *sc = data->sc;
612149871Sscottl
613136849Sscottl	if (data->m != NULL) {
614149871Sscottl		ieee80211_tx_complete(data->ni, data->m, txerr);
615149871Sscottl		data->m = NULL;
616149871Sscottl		data->ni = NULL;
617136849Sscottl	}
618149871Sscottl	STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
619149871Sscottl	sc->tx_nfree++;
620149871Sscottl}
621136849Sscottl
622149871Sscottlstatic void
623149871Sscottlural_setup_tx_list(struct ural_softc *sc)
624149871Sscottl{
625136849Sscottl	struct ural_tx_data *data;
626136849Sscottl	int i;
627136849Sscottl
628190809Sdelphij	sc->tx_nfree = 0;
629149871Sscottl	STAILQ_INIT(&sc->tx_q);
630136849Sscottl	STAILQ_INIT(&sc->tx_free);
631136849Sscottl
632149871Sscottl	for (i = 0; i < RAL_TX_LIST_COUNT; i++) {
633149871Sscottl		data = &sc->tx_data[i];
634149871Sscottl
635149871Sscottl		data->sc = sc;
636190809Sdelphij		STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
637149871Sscottl		sc->tx_nfree++;
638136849Sscottl	}
639149871Sscottl}
640136849Sscottl
641136849Sscottlstatic void
642149871Sscottlural_unsetup_tx_list(struct ural_softc *sc)
643149871Sscottl{
644149871Sscottl	struct ural_tx_data *data;
645149871Sscottl	int i;
646149871Sscottl
647149871Sscottl	/* make sure any subsequent use of the queues will fail */
648149871Sscottl	sc->tx_nfree = 0;
649149871Sscottl	STAILQ_INIT(&sc->tx_q);
650149871Sscottl	STAILQ_INIT(&sc->tx_free);
651149871Sscottl
652149871Sscottl	/* free up all node references and mbufs */
653149871Sscottl	for (i = 0; i < RAL_TX_LIST_COUNT; i++) {
654149871Sscottl		data = &sc->tx_data[i];
655149871Sscottl
656149871Sscottl		if (data->m != NULL) {
657149871Sscottl			m_freem(data->m);
658149871Sscottl			data->m = NULL;
659149871Sscottl		}
660149871Sscottl		if (data->ni != NULL) {
661149871Sscottl			ieee80211_free_node(data->ni);
662149871Sscottl			data->ni = NULL;
663149871Sscottl		}
664149871Sscottl	}
665149871Sscottl}
666149871Sscottl
667149871Sscottlstatic int
668149871Sscottlural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
669149871Sscottl{
670136849Sscottl	struct ural_vap *uvp = URAL_VAP(vap);
671149871Sscottl	struct ieee80211com *ic = vap->iv_ic;
672136849Sscottl	struct ural_softc *sc = ic->ic_softc;
673149871Sscottl	const struct ieee80211_txparam *tp;
674136849Sscottl	struct ieee80211_node *ni;
675149871Sscottl	struct mbuf *m;
676149871Sscottl
677149871Sscottl	DPRINTF("%s -> %s\n",
678149871Sscottl		ieee80211_state_name[vap->iv_state],
679149871Sscottl		ieee80211_state_name[nstate]);
680149871Sscottl
681149871Sscottl	IEEE80211_UNLOCK(ic);
682149871Sscottl	RAL_LOCK(sc);
683190809Sdelphij	usb_callout_stop(&uvp->ratectl_ch);
684149871Sscottl
685136849Sscottl	switch (nstate) {
686136849Sscottl	case IEEE80211_S_INIT:
687136849Sscottl		if (vap->iv_state == IEEE80211_S_RUN) {
688190809Sdelphij			/* abort TSF synchronization */
689149871Sscottl			ural_write(sc, RAL_TXRX_CSR19, 0);
690136849Sscottl
691149871Sscottl			/* force tx led to stop blinking */
692149871Sscottl			ural_write(sc, RAL_MAC_CSR20, 0);
693190809Sdelphij		}
694149871Sscottl		break;
695149871Sscottl
696149871Sscottl	case IEEE80211_S_RUN:
697149871Sscottl		ni = ieee80211_ref_node(vap->iv_bss);
698149871Sscottl
699149871Sscottl		if (vap->iv_opmode != IEEE80211_M_MONITOR) {
700190809Sdelphij			if (ic->ic_bsschan == IEEE80211_CHAN_ANYC)
701149871Sscottl				goto fail;
702149871Sscottl
703149871Sscottl			ural_update_slot(sc);
704149871Sscottl			ural_set_txpreamble(sc);
705149871Sscottl			ural_set_basicrates(sc, ic->ic_bsschan);
706190809Sdelphij			IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
707149871Sscottl			ural_set_bssid(sc, sc->sc_bssid);
708149871Sscottl		}
709149871Sscottl
710136849Sscottl		if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
711190809Sdelphij		    vap->iv_opmode == IEEE80211_M_IBSS) {
712149871Sscottl			m = ieee80211_beacon_alloc(ni);
713149871Sscottl			if (m == NULL) {
714136849Sscottl				device_printf(sc->sc_dev,
715136849Sscottl				    "could not allocate beacon\n");
716136849Sscottl				goto fail;
717149871Sscottl			}
718190809Sdelphij			ieee80211_ref_node(ni);
719149871Sscottl			if (ural_tx_bcn(sc, m, ni) != 0) {
720149871Sscottl				device_printf(sc->sc_dev,
721149871Sscottl				    "could not send beacon\n");
722149871Sscottl				goto fail;
723149871Sscottl			}
724190809Sdelphij		}
725149871Sscottl
726136849Sscottl		/* make tx led blink on tx (controlled by ASIC) */
727136849Sscottl		ural_write(sc, RAL_MAC_CSR20, 1);
728136849Sscottl
729136849Sscottl		if (vap->iv_opmode != IEEE80211_M_MONITOR)
730149871Sscottl			ural_enable_tsf_sync(sc);
731149871Sscottl		else
732190809Sdelphij			ural_enable_tsf(sc);
733149871Sscottl
734136849Sscottl		/* enable automatic rate adaptation */
735136849Sscottl		/* XXX should use ic_bsschan but not valid until after newstate call below */
736190809Sdelphij		tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
737149871Sscottl		if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
738136849Sscottl			ural_ratectl_start(sc, ni);
739136849Sscottl		ieee80211_free_node(ni);
740136849Sscottl		break;
741136849Sscottl
742136849Sscottl	default:
743136849Sscottl		break;
744136849Sscottl	}
745136849Sscottl	RAL_UNLOCK(sc);
746136849Sscottl	IEEE80211_LOCK(ic);
747136849Sscottl	return (uvp->newstate(vap, nstate, arg));
748149871Sscottl
749149871Sscottlfail:
750149871Sscottl	RAL_UNLOCK(sc);
751269617Sjhb	IEEE80211_LOCK(ic);
752269617Sjhb	ieee80211_free_node(ni);
753149871Sscottl	return (-1);
754149871Sscottl}
755149871Sscottl
756149871Sscottlstatic void
757149871Sscottlural_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
758149871Sscottl{
759149871Sscottl	struct ural_softc *sc = usbd_xfer_softc(xfer);
760149871Sscottl	struct ieee80211vap *vap;
761149871Sscottl	struct ural_tx_data *data;
762190809Sdelphij	struct mbuf *m;
763149871Sscottl	struct usb_page_cache *pc;
764149871Sscottl	int len;
765149871Sscottl
766149871Sscottl	usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
767190809Sdelphij
768149871Sscottl	switch (USB_GET_STATE(xfer)) {
769149871Sscottl	case USB_ST_TRANSFERRED:
770149871Sscottl		DPRINTFN(11, "transfer complete, %d bytes\n", len);
771149871Sscottl
772149871Sscottl		/* free resources */
773149871Sscottl		data = usbd_xfer_get_priv(xfer);
774149871Sscottl		ural_tx_free(data, 0);
775149871Sscottl		usbd_xfer_set_priv(xfer, NULL);
776190809Sdelphij
777149871Sscottl		/* FALLTHROUGH */
778149871Sscottl	case USB_ST_SETUP:
779149871Sscottltr_setup:
780149871Sscottl		data = STAILQ_FIRST(&sc->tx_q);
781149871Sscottl		if (data) {
782149871Sscottl			STAILQ_REMOVE_HEAD(&sc->tx_q, next);
783149871Sscottl			m = data->m;
784149871Sscottl
785149871Sscottl			if (m->m_pkthdr.len > (int)(RAL_FRAME_SIZE + RAL_TX_DESC_SIZE)) {
786149871Sscottl				DPRINTFN(0, "data overflow, %u bytes\n",
787136849Sscottl				    m->m_pkthdr.len);
788149871Sscottl				m->m_pkthdr.len = (RAL_FRAME_SIZE + RAL_TX_DESC_SIZE);
789149871Sscottl			}
790149871Sscottl			pc = usbd_xfer_get_frame(xfer, 0);
791149871Sscottl			usbd_copy_in(pc, 0, &data->desc, RAL_TX_DESC_SIZE);
792190809Sdelphij			usbd_m_copy_in(pc, RAL_TX_DESC_SIZE, m, 0,
793149871Sscottl			    m->m_pkthdr.len);
794149871Sscottl
795149871Sscottl			vap = data->ni->ni_vap;
796149871Sscottl			if (ieee80211_radiotap_active_vap(vap)) {
797149871Sscottl				struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
798149871Sscottl
799149871Sscottl				tap->wt_flags = 0;
800149871Sscottl				tap->wt_rate = data->rate;
801149871Sscottl				tap->wt_antenna = sc->tx_ant;
802149871Sscottl
803149871Sscottl				ieee80211_radiotap_tx(vap, m);
804190809Sdelphij			}
805149871Sscottl
806149871Sscottl			/* xfer length needs to be a multiple of two! */
807149871Sscottl			len = (RAL_TX_DESC_SIZE + m->m_pkthdr.len + 1) & ~1;
808136849Sscottl			if ((len % 64) == 0)
809149871Sscottl				len += 2;
810149871Sscottl
811190809Sdelphij			DPRINTFN(11, "sending frame len=%u xferlen=%u\n",
812149871Sscottl			    m->m_pkthdr.len, len);
813149871Sscottl
814149871Sscottl			usbd_xfer_set_frame_len(xfer, 0, len);
815136849Sscottl			usbd_xfer_set_priv(xfer, data);
816136849Sscottl
817149871Sscottl			usbd_transfer_submit(xfer);
818149871Sscottl		}
819136849Sscottl		ural_start(sc);
820149871Sscottl		break;
821149871Sscottl
822136849Sscottl	default:			/* Error */
823136849Sscottl		DPRINTFN(11, "transfer error, %s\n",
824149871Sscottl		    usbd_errstr(error));
825136849Sscottl
826136849Sscottl		data = usbd_xfer_get_priv(xfer);
827136849Sscottl		if (data != NULL) {
828136849Sscottl			ural_tx_free(data, error);
829136849Sscottl			usbd_xfer_set_priv(xfer, NULL);
830136849Sscottl		}
831136849Sscottl
832136849Sscottl		if (error == USB_ERR_STALLED) {
833149871Sscottl			/* try to clear stall first */
834136849Sscottl			usbd_xfer_set_stall(xfer);
835136849Sscottl			goto tr_setup;
836136849Sscottl		}
837136849Sscottl		if (error == USB_ERR_TIMEOUT)
838136849Sscottl			device_printf(sc->sc_dev, "device timeout\n");
839149871Sscottl		break;
840136849Sscottl	}
841136849Sscottl}
842136849Sscottl
843136849Sscottlstatic void
844149871Sscottlural_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
845136849Sscottl{
846149871Sscottl	struct ural_softc *sc = usbd_xfer_softc(xfer);
847136849Sscottl	struct ieee80211com *ic = &sc->sc_ic;
848149871Sscottl	struct ieee80211_node *ni;
849136849Sscottl	struct mbuf *m = NULL;
850149871Sscottl	struct usb_page_cache *pc;
851149871Sscottl	uint32_t flags;
852149871Sscottl	int8_t rssi = 0, nf = 0;
853136849Sscottl	int len;
854149871Sscottl
855149871Sscottl	usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
856149871Sscottl
857190809Sdelphij	switch (USB_GET_STATE(xfer)) {
858149871Sscottl	case USB_ST_TRANSFERRED:
859149871Sscottl
860269617Sjhb		DPRINTFN(15, "rx done, actlen=%d\n", len);
861149871Sscottl
862149871Sscottl		if (len < (int)(RAL_RX_DESC_SIZE + IEEE80211_MIN_LEN)) {
863149871Sscottl			DPRINTF("%s: xfer too short %d\n",
864149871Sscottl			    device_get_nameunit(sc->sc_dev), len);
865190809Sdelphij			counter_u64_add(ic->ic_ierrors, 1);
866149871Sscottl			goto tr_setup;
867149871Sscottl		}
868149871Sscottl
869269617Sjhb		len -= RAL_RX_DESC_SIZE;
870149871Sscottl		/* rx descriptor is located at the end */
871149871Sscottl		pc = usbd_xfer_get_frame(xfer, 0);
872149871Sscottl		usbd_copy_out(pc, len, &sc->sc_rx_desc, RAL_RX_DESC_SIZE);
873149871Sscottl
874149871Sscottl		rssi = URAL_RSSI(sc->sc_rx_desc.rssi);
875136849Sscottl		nf = RAL_NOISE_FLOOR;
876250460Seadler		flags = le32toh(sc->sc_rx_desc.flags);
877250460Seadler		if (flags & (RAL_RX_PHY_ERROR | RAL_RX_CRC_ERROR)) {
878149871Sscottl			/*
879149871Sscottl		         * This should not happen since we did not
880149871Sscottl		         * request to receive those frames when we
881149871Sscottl		         * filled RAL_TXRX_CSR2:
882149871Sscottl		         */
883149871Sscottl			DPRINTFN(5, "PHY or CRC error\n");
884190809Sdelphij			counter_u64_add(ic->ic_ierrors, 1);
885149871Sscottl			goto tr_setup;
886149871Sscottl		}
887149871Sscottl
888190809Sdelphij		m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
889149871Sscottl		if (m == NULL) {
890149871Sscottl			DPRINTF("could not allocate mbuf\n");
891136849Sscottl			counter_u64_add(ic->ic_ierrors, 1);
892136849Sscottl			goto tr_setup;
893136849Sscottl		}
894136849Sscottl		usbd_copy_out(pc, 0, mtod(m, uint8_t *), len);
895149871Sscottl
896136849Sscottl		/* finalize mbuf */
897136849Sscottl		m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
898149871Sscottl
899149871Sscottl		if (ieee80211_radiotap_active(ic)) {
900149871Sscottl			struct ural_rx_radiotap_header *tap = &sc->sc_rxtap;
901149871Sscottl
902190809Sdelphij			/* XXX set once */
903149871Sscottl			tap->wr_flags = 0;
904136849Sscottl			tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate,
905136849Sscottl			    (flags & RAL_RX_OFDM) ?
906149871Sscottl			    IEEE80211_T_OFDM : IEEE80211_T_CCK);
907149871Sscottl			tap->wr_antenna = sc->rx_ant;
908136849Sscottl			tap->wr_antsignal = nf + rssi;
909149871Sscottl			tap->wr_antnoise = nf;
910149871Sscottl		}
911149871Sscottl		/* Strip trailing 802.11 MAC FCS. */
912136849Sscottl		m_adj(m, -IEEE80211_CRC_LEN);
913149871Sscottl
914136849Sscottl		/* FALLTHROUGH */
915149871Sscottl	case USB_ST_SETUP:
916149871Sscottltr_setup:
917149871Sscottl		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
918190809Sdelphij		usbd_transfer_submit(xfer);
919149871Sscottl
920149871Sscottl		/*
921136849Sscottl		 * At the end of a USB callback it is always safe to unlock
922136849Sscottl		 * the private mutex of a device! That is why we do the
923136849Sscottl		 * "ieee80211_input" here, and not some lines up!
924149871Sscottl		 */
925149871Sscottl		RAL_UNLOCK(sc);
926149871Sscottl		if (m) {
927149871Sscottl			ni = ieee80211_find_rxnode(ic,
928190809Sdelphij			    mtod(m, struct ieee80211_frame_min *));
929149871Sscottl			if (ni != NULL) {
930149871Sscottl				(void) ieee80211_input(ni, m, rssi, nf);
931136849Sscottl				ieee80211_free_node(ni);
932136849Sscottl			} else
933149871Sscottl				(void) ieee80211_input_all(ic, m, rssi, nf);
934149871Sscottl		}
935136849Sscottl		RAL_LOCK(sc);
936149871Sscottl		ural_start(sc);
937149871Sscottl		return;
938149871Sscottl
939149871Sscottl	default:			/* Error */
940149871Sscottl		if (error != USB_ERR_CANCELLED) {
941136849Sscottl			/* try to clear stall first */
942149871Sscottl			usbd_xfer_set_stall(xfer);
943149871Sscottl			goto tr_setup;
944149871Sscottl		}
945250460Seadler		return;
946149871Sscottl	}
947149871Sscottl}
948149871Sscottl
949136849Sscottlstatic uint8_t
950136849Sscottlural_plcp_signal(int rate)
951136849Sscottl{
952136849Sscottl	switch (rate) {
953136849Sscottl	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
954136849Sscottl	case 12:	return 0xb;
955136849Sscottl	case 18:	return 0xf;
956136849Sscottl	case 24:	return 0xa;
957149871Sscottl	case 36:	return 0xe;
958149871Sscottl	case 48:	return 0x9;
959136849Sscottl	case 72:	return 0xd;
960136849Sscottl	case 96:	return 0x8;
961136849Sscottl	case 108:	return 0xc;
962136849Sscottl
963136849Sscottl	/* CCK rates (NB: not IEEE std, device-specific) */
964136849Sscottl	case 2:		return 0x0;
965136849Sscottl	case 4:		return 0x1;
966149871Sscottl	case 11:	return 0x2;
967136849Sscottl	case 22:	return 0x3;
968136849Sscottl	}
969136849Sscottl	return 0xff;		/* XXX unsupported/unknown rate */
970136849Sscottl}
971136849Sscottl
972136849Sscottlstatic void
973136849Sscottlural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc,
974136849Sscottl    uint32_t flags, int len, int rate)
975136849Sscottl{
976136849Sscottl	struct ieee80211com *ic = &sc->sc_ic;
977136849Sscottl	uint16_t plcp_length;
978136849Sscottl	int remainder;
979136849Sscottl
980136849Sscottl	desc->flags = htole32(flags);
981136849Sscottl	desc->flags |= htole32(RAL_TX_NEWSEQ);
982136849Sscottl	desc->flags |= htole32(len << 16);
983136849Sscottl
984136849Sscottl	desc->wme = htole16(RAL_AIFSN(2) | RAL_LOGCWMIN(3) | RAL_LOGCWMAX(5));
985136849Sscottl	desc->wme |= htole16(RAL_IVOFFSET(sizeof (struct ieee80211_frame)));
986136849Sscottl
987136849Sscottl	/* setup PLCP fields */
988136849Sscottl	desc->plcp_signal  = ural_plcp_signal(rate);
989136849Sscottl	desc->plcp_service = 4;
990149871Sscottl
991136849Sscottl	len += IEEE80211_CRC_LEN;
992136849Sscottl	if (ieee80211_rate2phytype(ic->ic_rt, rate) == IEEE80211_T_OFDM) {
993136849Sscottl		desc->flags |= htole32(RAL_TX_OFDM);
994136849Sscottl
995136849Sscottl		plcp_length = len & 0xfff;
996136849Sscottl		desc->plcp_length_hi = plcp_length >> 6;
997136849Sscottl		desc->plcp_length_lo = plcp_length & 0x3f;
998149871Sscottl	} else {
999136849Sscottl		if (rate == 0)
1000136849Sscottl			rate = 2;	/* avoid division by zero */
1001136849Sscottl		plcp_length = howmany(16 * len, rate);
1002149871Sscottl		if (rate == 22) {
1003149871Sscottl			remainder = (16 * len) % 22;
1004136849Sscottl			if (remainder != 0 && remainder < 7)
1005149871Sscottl				desc->plcp_service |= RAL_PLCP_LENGEXT;
1006149871Sscottl		}
1007136849Sscottl		desc->plcp_length_hi = plcp_length >> 8;
1008136849Sscottl		desc->plcp_length_lo = plcp_length & 0xff;
1009136849Sscottl
1010136849Sscottl		if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
1011136849Sscottl			desc->plcp_signal |= 0x08;
1012136849Sscottl	}
1013149871Sscottl
1014149871Sscottl	desc->iv = 0;
1015149871Sscottl	desc->eiv = 0;
1016136849Sscottl}
1017136849Sscottl
1018136849Sscottl#define RAL_TX_TIMEOUT	5000
1019136849Sscottl
1020136849Sscottlstatic int
1021136849Sscottlural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
1022136849Sscottl{
1023136849Sscottl	struct ieee80211vap *vap = ni->ni_vap;
1024136849Sscottl	struct ieee80211com *ic = ni->ni_ic;
1025136849Sscottl	const struct ieee80211_txparam *tp;
1026136849Sscottl	struct ural_tx_data *data;
1027149871Sscottl
1028190809Sdelphij	if (sc->tx_nfree == 0) {
1029190809Sdelphij		m_freem(m0);
1030136849Sscottl		ieee80211_free_node(ni);
1031136849Sscottl		return (EIO);
1032136849Sscottl	}
1033149871Sscottl	if (ic->ic_bsschan == IEEE80211_CHAN_ANYC) {
1034149871Sscottl		m_freem(m0);
1035136849Sscottl		ieee80211_free_node(ni);
1036136849Sscottl		return (ENXIO);
1037136849Sscottl	}
1038149871Sscottl	data = STAILQ_FIRST(&sc->tx_free);
1039136849Sscottl	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
1040136849Sscottl	sc->tx_nfree--;
1041149871Sscottl	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
1042149871Sscottl
1043149871Sscottl	data->m = m0;
1044149871Sscottl	data->ni = ni;
1045149871Sscottl	data->rate = tp->mgmtrate;
1046149871Sscottl
1047136849Sscottl	ural_setup_tx_desc(sc, &data->desc,
1048136849Sscottl	    RAL_TX_IFS_NEWBACKOFF | RAL_TX_TIMESTAMP, m0->m_pkthdr.len,
1049136849Sscottl	    tp->mgmtrate);
1050136849Sscottl
1051136849Sscottl	DPRINTFN(10, "sending beacon frame len=%u rate=%u\n",
1052136849Sscottl	    m0->m_pkthdr.len, tp->mgmtrate);
1053136849Sscottl
1054136849Sscottl	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
1055136849Sscottl	usbd_transfer_start(sc->sc_xfer[URAL_BULK_WR]);
1056136849Sscottl
1057136849Sscottl	return (0);
1058136849Sscottl}
1059136849Sscottl
1060136849Sscottlstatic int
1061136849Sscottlural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
1062136849Sscottl{
1063149871Sscottl	const struct ieee80211_txparam *tp = ni->ni_txparms;
1064149871Sscottl	struct ieee80211com *ic = ni->ni_ic;
1065149871Sscottl	struct ural_tx_data *data;
1066136849Sscottl	struct ieee80211_frame *wh;
1067136849Sscottl	struct ieee80211_key *k;
1068136849Sscottl	uint32_t flags;
1069136849Sscottl	uint16_t dur;
1070136849Sscottl
1071136849Sscottl	RAL_LOCK_ASSERT(sc, MA_OWNED);
1072136849Sscottl
1073136849Sscottl	data = STAILQ_FIRST(&sc->tx_free);
1074136849Sscottl	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
1075136849Sscottl	sc->tx_nfree--;
1076136849Sscottl
1077136849Sscottl	wh = mtod(m0, struct ieee80211_frame *);
1078136849Sscottl	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1079136849Sscottl		k = ieee80211_crypto_encap(ni, m0);
1080136849Sscottl		if (k == NULL) {
1081136849Sscottl			m_freem(m0);
1082136849Sscottl			return ENOBUFS;
1083136849Sscottl		}
1084149871Sscottl		wh = mtod(m0, struct ieee80211_frame *);
1085149871Sscottl	}
1086149871Sscottl
1087136849Sscottl	data->m = m0;
1088136849Sscottl	data->ni = ni;
1089136849Sscottl	data->rate = tp->mgmtrate;
1090136849Sscottl
1091136849Sscottl	flags = 0;
1092136849Sscottl	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1093136849Sscottl		flags |= RAL_TX_ACK;
1094190809Sdelphij
1095190809Sdelphij		dur = ieee80211_ack_duration(ic->ic_rt, tp->mgmtrate,
1096190809Sdelphij		    ic->ic_flags & IEEE80211_F_SHPREAMBLE);
1097190809Sdelphij		USETW(wh->i_dur, dur);
1098190809Sdelphij
1099190809Sdelphij		/* tell hardware to add timestamp for probe responses */
1100190809Sdelphij		if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
1101190809Sdelphij		    IEEE80211_FC0_TYPE_MGT &&
1102190809Sdelphij		    (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
1103190809Sdelphij		    IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1104190809Sdelphij			flags |= RAL_TX_TIMESTAMP;
1105190809Sdelphij	}
1106190809Sdelphij
1107190809Sdelphij	ural_setup_tx_desc(sc, &data->desc, flags, m0->m_pkthdr.len, tp->mgmtrate);
1108190809Sdelphij
1109190809Sdelphij	DPRINTFN(10, "sending mgt frame len=%u rate=%u\n",
1110190809Sdelphij	    m0->m_pkthdr.len, tp->mgmtrate);
1111190809Sdelphij
1112190809Sdelphij	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
1113190809Sdelphij	usbd_transfer_start(sc->sc_xfer[URAL_BULK_WR]);
1114190809Sdelphij
1115190809Sdelphij	return 0;
1116190809Sdelphij}
1117190809Sdelphij
1118190809Sdelphijstatic int
1119190809Sdelphijural_sendprot(struct ural_softc *sc,
1120190809Sdelphij    const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate)
1121190809Sdelphij{
1122190809Sdelphij	struct ieee80211com *ic = ni->ni_ic;
1123190809Sdelphij	struct ural_tx_data *data;
1124190809Sdelphij	struct mbuf *mprot;
1125190809Sdelphij	int protrate, flags;
1126190809Sdelphij
1127190809Sdelphij	mprot = ieee80211_alloc_prot(ni, m, rate, prot);
1128190809Sdelphij	if (mprot == NULL) {
1129190809Sdelphij		if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
1130190809Sdelphij		device_printf(sc->sc_dev,
1131190809Sdelphij		    "could not allocate mbuf for protection mode %d\n", prot);
1132190809Sdelphij		return ENOBUFS;
1133190809Sdelphij	}
1134190809Sdelphij
1135190809Sdelphij	protrate = ieee80211_ctl_rate(ic->ic_rt, rate);
1136190809Sdelphij	flags = RAL_TX_RETRY(7);
1137190809Sdelphij	if (prot == IEEE80211_PROT_RTSCTS)
1138190809Sdelphij		flags |= RAL_TX_ACK;
1139190809Sdelphij
1140190809Sdelphij	data = STAILQ_FIRST(&sc->tx_free);
1141190809Sdelphij	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
1142190809Sdelphij	sc->tx_nfree--;
1143190809Sdelphij
1144190809Sdelphij	data->m = mprot;
1145190809Sdelphij	data->ni = ieee80211_ref_node(ni);
1146190809Sdelphij	data->rate = protrate;
1147190809Sdelphij	ural_setup_tx_desc(sc, &data->desc, flags, mprot->m_pkthdr.len, protrate);
1148190809Sdelphij
1149190809Sdelphij	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
1150190809Sdelphij	usbd_transfer_start(sc->sc_xfer[URAL_BULK_WR]);
1151190809Sdelphij
1152190809Sdelphij	return 0;
1153190809Sdelphij}
1154190809Sdelphij
1155190809Sdelphijstatic int
1156190809Sdelphijural_tx_raw(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
1157190809Sdelphij    const struct ieee80211_bpf_params *params)
1158190809Sdelphij{
1159190809Sdelphij	struct ieee80211com *ic = ni->ni_ic;
1160190809Sdelphij	struct ural_tx_data *data;
1161190809Sdelphij	uint32_t flags;
1162190809Sdelphij	int error;
1163190809Sdelphij	int rate;
1164190809Sdelphij
1165190809Sdelphij	RAL_LOCK_ASSERT(sc, MA_OWNED);
1166190809Sdelphij	KASSERT(params != NULL, ("no raw xmit params"));
1167190809Sdelphij
1168190809Sdelphij	rate = params->ibp_rate0;
1169190809Sdelphij	if (!ieee80211_isratevalid(ic->ic_rt, rate)) {
1170190809Sdelphij		m_freem(m0);
1171190809Sdelphij		return EINVAL;
1172190809Sdelphij	}
1173190809Sdelphij	flags = 0;
1174190809Sdelphij	if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
1175190809Sdelphij		flags |= RAL_TX_ACK;
1176190809Sdelphij	if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) {
1177190809Sdelphij		error = ural_sendprot(sc, m0, ni,
1178190809Sdelphij		    params->ibp_flags & IEEE80211_BPF_RTS ?
1179190809Sdelphij			 IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY,
1180190809Sdelphij		    rate);
1181190809Sdelphij		if (error || sc->tx_nfree == 0) {
1182190809Sdelphij			m_freem(m0);
1183190809Sdelphij			return ENOBUFS;
1184190809Sdelphij		}
1185190809Sdelphij		flags |= RAL_TX_IFS_SIFS;
1186190809Sdelphij	}
1187190809Sdelphij
1188190809Sdelphij	data = STAILQ_FIRST(&sc->tx_free);
1189190809Sdelphij	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
1190190809Sdelphij	sc->tx_nfree--;
1191190809Sdelphij
1192190809Sdelphij	data->m = m0;
1193190809Sdelphij	data->ni = ni;
1194190809Sdelphij	data->rate = rate;
1195190809Sdelphij
1196190809Sdelphij	/* XXX need to setup descriptor ourself */
1197190809Sdelphij	ural_setup_tx_desc(sc, &data->desc, flags, m0->m_pkthdr.len, rate);
1198190809Sdelphij
1199190809Sdelphij	DPRINTFN(10, "sending raw frame len=%u rate=%u\n",
1200190809Sdelphij	    m0->m_pkthdr.len, rate);
1201190809Sdelphij
1202190809Sdelphij	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
1203190809Sdelphij	usbd_transfer_start(sc->sc_xfer[URAL_BULK_WR]);
1204190809Sdelphij
1205190809Sdelphij	return 0;
1206190809Sdelphij}
1207190809Sdelphij
1208190809Sdelphijstatic int
1209190809Sdelphijural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
1210190809Sdelphij{
1211190809Sdelphij	struct ieee80211vap *vap = ni->ni_vap;
1212190809Sdelphij	struct ieee80211com *ic = ni->ni_ic;
1213190809Sdelphij	struct ural_tx_data *data;
1214190809Sdelphij	struct ieee80211_frame *wh;
1215136849Sscottl	const struct ieee80211_txparam *tp = ni->ni_txparms;
1216136849Sscottl	struct ieee80211_key *k;
1217149871Sscottl	uint32_t flags = 0;
1218136849Sscottl	uint16_t dur;
1219136849Sscottl	int error, rate;
1220136849Sscottl
1221136849Sscottl	RAL_LOCK_ASSERT(sc, MA_OWNED);
1222136849Sscottl
1223136849Sscottl	wh = mtod(m0, struct ieee80211_frame *);
1224149871Sscottl
1225136849Sscottl	if (m0->m_flags & M_EAPOL)
1226136849Sscottl		rate = tp->mgmtrate;
1227136849Sscottl	else if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1228136849Sscottl		rate = tp->mcastrate;
1229136849Sscottl	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
1230136849Sscottl		rate = tp->ucastrate;
1231136849Sscottl	else {
1232149871Sscottl		(void) ieee80211_ratectl_rate(ni, NULL, 0);
1233149871Sscottl		rate = ni->ni_txrate;
1234149871Sscottl	}
1235149871Sscottl
1236149871Sscottl	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1237149871Sscottl		k = ieee80211_crypto_encap(ni, m0);
1238149871Sscottl		if (k == NULL) {
1239149871Sscottl			m_freem(m0);
1240149871Sscottl			return ENOBUFS;
1241149871Sscottl		}
1242149871Sscottl		/* packet header may have moved, reset our local pointer */
1243149871Sscottl		wh = mtod(m0, struct ieee80211_frame *);
1244149871Sscottl	}
1245149871Sscottl
1246149871Sscottl	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1247149871Sscottl		int prot = IEEE80211_PROT_NONE;
1248136849Sscottl		if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
1249136849Sscottl			prot = IEEE80211_PROT_RTSCTS;
1250136849Sscottl		else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
1251136849Sscottl		    ieee80211_rate2phytype(ic->ic_rt, rate) == IEEE80211_T_OFDM)
1252136849Sscottl			prot = ic->ic_protmode;
1253136849Sscottl		if (prot != IEEE80211_PROT_NONE) {
1254149871Sscottl			error = ural_sendprot(sc, m0, ni, prot, rate);
1255136849Sscottl			if (error || sc->tx_nfree == 0) {
1256136849Sscottl				m_freem(m0);
1257136849Sscottl				return ENOBUFS;
1258269617Sjhb			}
1259269617Sjhb			flags |= RAL_TX_IFS_SIFS;
1260269617Sjhb		}
1261190809Sdelphij	}
1262269617Sjhb
1263136849Sscottl	data = STAILQ_FIRST(&sc->tx_free);
1264136849Sscottl	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
1265149871Sscottl	sc->tx_nfree--;
1266136849Sscottl
1267136849Sscottl	data->m = m0;
1268149871Sscottl	data->ni = ni;
1269149871Sscottl	data->rate = rate;
1270136849Sscottl
1271136849Sscottl	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1272136849Sscottl		flags |= RAL_TX_ACK;
1273269617Sjhb		flags |= RAL_TX_RETRY(7);
1274136849Sscottl
1275136849Sscottl		dur = ieee80211_ack_duration(ic->ic_rt, rate,
1276136849Sscottl		    ic->ic_flags & IEEE80211_F_SHPREAMBLE);
1277136849Sscottl		USETW(wh->i_dur, dur);
1278136849Sscottl	}
1279136849Sscottl
1280136849Sscottl	ural_setup_tx_desc(sc, &data->desc, flags, m0->m_pkthdr.len, rate);
1281232854Sscottl
1282149871Sscottl	DPRINTFN(10, "sending data frame len=%u rate=%u\n",
1283149871Sscottl	    m0->m_pkthdr.len, rate);
1284149871Sscottl
1285149871Sscottl	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
1286149871Sscottl	usbd_transfer_start(sc->sc_xfer[URAL_BULK_WR]);
1287149871Sscottl
1288149871Sscottl	return 0;
1289149871Sscottl}
1290149871Sscottl
1291149871Sscottlstatic int
1292269617Sjhbural_transmit(struct ieee80211com *ic, struct mbuf *m)
1293149871Sscottl{
1294149871Sscottl	struct ural_softc *sc = ic->ic_softc;
1295201758Smbr	int error;
1296136849Sscottl
1297136849Sscottl	RAL_LOCK(sc);
1298136849Sscottl	if (!sc->sc_running) {
1299149871Sscottl		RAL_UNLOCK(sc);
1300149871Sscottl		return (ENXIO);
1301190809Sdelphij	}
1302149871Sscottl	error = mbufq_enqueue(&sc->sc_snd, m);
1303136849Sscottl	if (error) {
1304136849Sscottl		RAL_UNLOCK(sc);
1305136849Sscottl		return (error);
1306136849Sscottl	}
1307296135Sjhibbits	ural_start(sc);
1308296135Sjhibbits	RAL_UNLOCK(sc);
1309149871Sscottl
1310149871Sscottl	return (0);
1311149871Sscottl}
1312190809Sdelphij
1313149871Sscottlstatic void
1314149871Sscottlural_start(struct ural_softc *sc)
1315136849Sscottl{
1316149871Sscottl	struct ieee80211_node *ni;
1317149871Sscottl	struct mbuf *m;
1318190809Sdelphij
1319149871Sscottl	RAL_LOCK_ASSERT(sc, MA_OWNED);
1320136849Sscottl
1321136849Sscottl	if (sc->sc_running == 0)
1322136849Sscottl		return;
1323149871Sscottl
1324136849Sscottl	while (sc->tx_nfree >= RAL_TX_MINFREE &&
1325149871Sscottl	    (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
1326190809Sdelphij		ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1327136849Sscottl		if (ural_tx_data(sc, m, ni) != 0) {
1328136849Sscottl			if_inc_counter(ni->ni_vap->iv_ifp,
1329136849Sscottl			     IFCOUNTER_OERRORS, 1);
1330136849Sscottl			ieee80211_free_node(ni);
1331136849Sscottl			break;
1332136849Sscottl		}
1333136849Sscottl	}
1334136849Sscottl}
1335136849Sscottl
1336149871Sscottlstatic void
1337149871Sscottlural_parent(struct ieee80211com *ic)
1338190809Sdelphij{
1339149871Sscottl	struct ural_softc *sc = ic->ic_softc;
1340149871Sscottl	int startall = 0;
1341149871Sscottl
1342149871Sscottl	RAL_LOCK(sc);
1343149871Sscottl	if (sc->sc_detached) {
1344136849Sscottl		RAL_UNLOCK(sc);
1345136849Sscottl		return;
1346136849Sscottl	}
1347136849Sscottl	if (ic->ic_nrunning > 0) {
1348136849Sscottl		if (sc->sc_running == 0) {
1349136849Sscottl			ural_init(sc);
1350136849Sscottl			startall = 1;
1351136849Sscottl		} else
1352136849Sscottl			ural_setpromisc(sc);
1353136849Sscottl	} else if (sc->sc_running)
1354149871Sscottl		ural_stop(sc);
1355149871Sscottl	RAL_UNLOCK(sc);
1356149871Sscottl	if (startall)
1357149871Sscottl		ieee80211_start_all(ic);
1358149871Sscottl}
1359149871Sscottl
1360149871Sscottlstatic void
1361136849Sscottlural_set_testmode(struct ural_softc *sc)
1362149871Sscottl{
1363149871Sscottl	struct usb_device_request req;
1364149871Sscottl	usb_error_t error;
1365136849Sscottl
1366149871Sscottl	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1367149871Sscottl	req.bRequest = RAL_VENDOR_REQUEST;
1368149871Sscottl	USETW(req.wValue, 4);
1369149871Sscottl	USETW(req.wIndex, 1);
1370149871Sscottl	USETW(req.wLength, 0);
1371149871Sscottl
1372136849Sscottl	error = ural_do_request(sc, &req, NULL);
1373136849Sscottl	if (error != 0) {
1374149871Sscottl		device_printf(sc->sc_dev, "could not set test mode: %s\n",
1375149871Sscottl		    usbd_errstr(error));
1376149871Sscottl	}
1377149871Sscottl}
1378149871Sscottl
1379149871Sscottlstatic void
1380149871Sscottlural_eeprom_read(struct ural_softc *sc, uint16_t addr, void *buf, int len)
1381149871Sscottl{
1382149871Sscottl	struct usb_device_request req;
1383149871Sscottl	usb_error_t error;
1384149871Sscottl
1385149871Sscottl	req.bmRequestType = UT_READ_VENDOR_DEVICE;
1386149871Sscottl	req.bRequest = RAL_READ_EEPROM;
1387269617Sjhb	USETW(req.wValue, 0);
1388149871Sscottl	USETW(req.wIndex, addr);
1389136849Sscottl	USETW(req.wLength, len);
1390136849Sscottl
1391136849Sscottl	error = ural_do_request(sc, &req, buf);
1392149871Sscottl	if (error != 0) {
1393149871Sscottl		device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
1394149871Sscottl		    usbd_errstr(error));
1395149871Sscottl	}
1396136862Sscottl}
1397136849Sscottl
1398136849Sscottlstatic uint16_t
1399136849Sscottlural_read(struct ural_softc *sc, uint16_t reg)
1400136849Sscottl{
1401149871Sscottl	struct usb_device_request req;
1402149871Sscottl	usb_error_t error;
1403149871Sscottl	uint16_t val;
1404149871Sscottl
1405149871Sscottl	req.bmRequestType = UT_READ_VENDOR_DEVICE;
1406149871Sscottl	req.bRequest = RAL_READ_MAC;
1407149871Sscottl	USETW(req.wValue, 0);
1408149871Sscottl	USETW(req.wIndex, reg);
1409149871Sscottl	USETW(req.wLength, sizeof (uint16_t));
1410136849Sscottl
1411136849Sscottl	error = ural_do_request(sc, &req, &val);
1412136849Sscottl	if (error != 0) {
1413136849Sscottl		device_printf(sc->sc_dev, "could not read MAC register: %s\n",
1414136849Sscottl		    usbd_errstr(error));
1415149871Sscottl		return 0;
1416149871Sscottl	}
1417136849Sscottl
1418136849Sscottl	return le16toh(val);
1419149871Sscottl}
1420149871Sscottl
1421190809Sdelphijstatic void
1422149871Sscottlural_read_multi(struct ural_softc *sc, uint16_t reg, void *buf, int len)
1423136849Sscottl{
1424149871Sscottl	struct usb_device_request req;
1425149871Sscottl	usb_error_t error;
1426149871Sscottl
1427149871Sscottl	req.bmRequestType = UT_READ_VENDOR_DEVICE;
1428190809Sdelphij	req.bRequest = RAL_READ_MULTI_MAC;
1429149871Sscottl	USETW(req.wValue, 0);
1430149871Sscottl	USETW(req.wIndex, reg);
1431149871Sscottl	USETW(req.wLength, len);
1432149871Sscottl
1433149871Sscottl	error = ural_do_request(sc, &req, buf);
1434149871Sscottl	if (error != 0) {
1435149871Sscottl		device_printf(sc->sc_dev, "could not read MAC register: %s\n",
1436190809Sdelphij		    usbd_errstr(error));
1437149871Sscottl	}
1438149871Sscottl}
1439149871Sscottl
1440149871Sscottlstatic void
1441149871Sscottlural_write(struct ural_softc *sc, uint16_t reg, uint16_t val)
1442149871Sscottl{
1443149871Sscottl	struct usb_device_request req;
1444149871Sscottl	usb_error_t error;
1445149871Sscottl
1446136849Sscottl	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1447136849Sscottl	req.bRequest = RAL_WRITE_MAC;
1448136849Sscottl	USETW(req.wValue, val);
1449136849Sscottl	USETW(req.wIndex, reg);
1450136849Sscottl	USETW(req.wLength, 0);
1451136849Sscottl
1452136849Sscottl	error = ural_do_request(sc, &req, NULL);
1453136849Sscottl	if (error != 0) {
1454136849Sscottl		device_printf(sc->sc_dev, "could not write MAC register: %s\n",
1455136849Sscottl		    usbd_errstr(error));
1456136849Sscottl	}
1457136849Sscottl}
1458136849Sscottl
1459136849Sscottlstatic void
1460136849Sscottlural_write_multi(struct ural_softc *sc, uint16_t reg, void *buf, int len)
1461149871Sscottl{
1462136849Sscottl	struct usb_device_request req;
1463136849Sscottl	usb_error_t error;
1464136849Sscottl
1465136849Sscottl	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1466136849Sscottl	req.bRequest = RAL_WRITE_MULTI_MAC;
1467136849Sscottl	USETW(req.wValue, 0);
1468136849Sscottl	USETW(req.wIndex, reg);
1469136849Sscottl	USETW(req.wLength, len);
1470136849Sscottl
1471136849Sscottl	error = ural_do_request(sc, &req, buf);
1472136849Sscottl	if (error != 0) {
1473136849Sscottl		device_printf(sc->sc_dev, "could not write MAC register: %s\n",
1474136849Sscottl		    usbd_errstr(error));
1475136849Sscottl	}
1476136849Sscottl}
1477136849Sscottl
1478136849Sscottlstatic void
1479136849Sscottlural_bbp_write(struct ural_softc *sc, uint8_t reg, uint8_t val)
1480136849Sscottl{
1481136849Sscottl	uint16_t tmp;
1482190809Sdelphij	int ntries;
1483136849Sscottl
1484136849Sscottl	for (ntries = 0; ntries < 100; ntries++) {
1485136849Sscottl		if (!(ural_read(sc, RAL_PHY_CSR8) & RAL_BBP_BUSY))
1486136849Sscottl			break;
1487136849Sscottl		if (ural_pause(sc, hz / 100))
1488136849Sscottl			break;
1489136849Sscottl	}
1490136849Sscottl	if (ntries == 100) {
1491136849Sscottl		device_printf(sc->sc_dev, "could not write to BBP\n");
1492149871Sscottl		return;
1493136849Sscottl	}
1494136849Sscottl
1495136849Sscottl	tmp = reg << 8 | val;
1496136849Sscottl	ural_write(sc, RAL_PHY_CSR7, tmp);
1497136849Sscottl}
1498136849Sscottl
1499149871Sscottlstatic uint8_t
1500149871Sscottlural_bbp_read(struct ural_softc *sc, uint8_t reg)
1501190809Sdelphij{
1502149871Sscottl	uint16_t val;
1503149871Sscottl	int ntries;
1504136849Sscottl
1505136849Sscottl	val = RAL_BBP_WRITE | reg << 8;
1506136849Sscottl	ural_write(sc, RAL_PHY_CSR7, val);
1507136849Sscottl
1508149871Sscottl	for (ntries = 0; ntries < 100; ntries++) {
1509149871Sscottl		if (!(ural_read(sc, RAL_PHY_CSR8) & RAL_BBP_BUSY))
1510190809Sdelphij			break;
1511149871Sscottl		if (ural_pause(sc, hz / 100))
1512136849Sscottl			break;
1513136849Sscottl	}
1514136849Sscottl	if (ntries == 100) {
1515136849Sscottl		device_printf(sc->sc_dev, "could not read BBP\n");
1516149871Sscottl		return 0;
1517149871Sscottl	}
1518190809Sdelphij
1519149871Sscottl	return ural_read(sc, RAL_PHY_CSR7) & 0xff;
1520136849Sscottl}
1521136849Sscottl
1522149871Sscottlstatic void
1523149871Sscottlural_rf_write(struct ural_softc *sc, uint8_t reg, uint32_t val)
1524149871Sscottl{
1525149871Sscottl	uint32_t tmp;
1526149871Sscottl	int ntries;
1527149871Sscottl
1528149871Sscottl	for (ntries = 0; ntries < 100; ntries++) {
1529149871Sscottl		if (!(ural_read(sc, RAL_PHY_CSR10) & RAL_RF_LOBUSY))
1530149871Sscottl			break;
1531149871Sscottl		if (ural_pause(sc, hz / 100))
1532149871Sscottl			break;
1533149871Sscottl	}
1534149871Sscottl	if (ntries == 100) {
1535149871Sscottl		device_printf(sc->sc_dev, "could not write to RF\n");
1536149871Sscottl		return;
1537149871Sscottl	}
1538149871Sscottl
1539149871Sscottl	tmp = RAL_RF_BUSY | RAL_RF_20BIT | (val & 0xfffff) << 2 | (reg & 0x3);
1540149871Sscottl	ural_write(sc, RAL_PHY_CSR9,  tmp & 0xffff);
1541149871Sscottl	ural_write(sc, RAL_PHY_CSR10, tmp >> 16);
1542136849Sscottl
1543136849Sscottl	/* remember last written value in sc */
1544149871Sscottl	sc->rf_regs[reg] = val;
1545149871Sscottl
1546149871Sscottl	DPRINTFN(15, "RF R[%u] <- 0x%05x\n", reg & 0x3, val & 0xfffff);
1547149871Sscottl}
1548149871Sscottl
1549149871Sscottlstatic void
1550149871Sscottlural_scan_start(struct ieee80211com *ic)
1551149871Sscottl{
1552149871Sscottl	struct ural_softc *sc = ic->ic_softc;
1553136849Sscottl
1554136849Sscottl	RAL_LOCK(sc);
1555136849Sscottl	ural_write(sc, RAL_TXRX_CSR19, 0);
1556136849Sscottl	ural_set_bssid(sc, ieee80211broadcastaddr);
1557136849Sscottl	RAL_UNLOCK(sc);
1558149871Sscottl}
1559149871Sscottl
1560136849Sscottlstatic void
1561136849Sscottlural_scan_end(struct ieee80211com *ic)
1562136849Sscottl{
1563136849Sscottl	struct ural_softc *sc = ic->ic_softc;
1564136849Sscottl
1565136849Sscottl	RAL_LOCK(sc);
1566136849Sscottl	ural_enable_tsf_sync(sc);
1567136849Sscottl	ural_set_bssid(sc, sc->sc_bssid);
1568136849Sscottl	RAL_UNLOCK(sc);
1569136849Sscottl
1570136849Sscottl}
1571149871Sscottl
1572136849Sscottlstatic void
1573136849Sscottlural_getradiocaps(struct ieee80211com *ic,
1574149871Sscottl    int maxchans, int *nchans, struct ieee80211_channel chans[])
1575149871Sscottl{
1576136849Sscottl	struct ural_softc *sc = ic->ic_softc;
1577136849Sscottl	uint8_t bands[IEEE80211_MODE_BYTES];
1578136849Sscottl
1579136849Sscottl	memset(bands, 0, sizeof(bands));
1580149871Sscottl	setbit(bands, IEEE80211_MODE_11B);
1581136849Sscottl	setbit(bands, IEEE80211_MODE_11G);
1582136849Sscottl	ieee80211_add_channels_default_2ghz(chans, maxchans, nchans, bands, 0);
1583136849Sscottl
1584136849Sscottl	if (sc->rf_rev == RAL_RF_5222) {
1585149871Sscottl		setbit(bands, IEEE80211_MODE_11A);
1586136849Sscottl		ieee80211_add_channel_list_5ghz(chans, maxchans, nchans,
1587136849Sscottl		    ural_chan_5ghz, nitems(ural_chan_5ghz), bands, 0);
1588136849Sscottl	}
1589136849Sscottl}
1590136849Sscottl
1591136849Sscottlstatic void
1592136849Sscottlural_set_channel(struct ieee80211com *ic)
1593136849Sscottl{
1594136849Sscottl	struct ural_softc *sc = ic->ic_softc;
1595136849Sscottl
1596149871Sscottl	RAL_LOCK(sc);
1597136849Sscottl	ural_set_chan(sc, ic->ic_curchan);
1598149871Sscottl	RAL_UNLOCK(sc);
1599149871Sscottl}
1600136849Sscottl
1601149871Sscottlstatic void
1602136849Sscottlural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c)
1603136849Sscottl{
1604149871Sscottl	struct ieee80211com *ic = &sc->sc_ic;
1605136849Sscottl	uint8_t power, tmp;
1606136849Sscottl	int i, chan;
1607149871Sscottl
1608149871Sscottl	chan = ieee80211_chan2ieee(ic, c);
1609136849Sscottl	if (chan == 0 || chan == IEEE80211_CHAN_ANY)
1610136849Sscottl		return;
1611136849Sscottl
1612136849Sscottl	if (IEEE80211_IS_CHAN_2GHZ(c))
1613136849Sscottl		power = min(sc->txpow[chan - 1], 31);
1614136849Sscottl	else
1615136849Sscottl		power = 31;
1616136849Sscottl
1617136849Sscottl	/* adjust txpower using ifconfig settings */
1618136849Sscottl	power -= (100 - ic->ic_txpowlimit) / 8;
1619136849Sscottl
1620136862Sscottl	DPRINTFN(2, "setting channel to %u, txpower to %u\n", chan, power);
1621136849Sscottl
1622136849Sscottl	switch (sc->rf_rev) {
1623136849Sscottl	case RAL_RF_2522:
1624136849Sscottl		ural_rf_write(sc, RAL_RF1, 0x00814);
1625136849Sscottl		ural_rf_write(sc, RAL_RF2, ural_rf2522_r2[chan - 1]);
1626136849Sscottl		ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040);
1627136849Sscottl		break;
1628136849Sscottl
1629136849Sscottl	case RAL_RF_2523:
1630136849Sscottl		ural_rf_write(sc, RAL_RF1, 0x08804);
1631136849Sscottl		ural_rf_write(sc, RAL_RF2, ural_rf2523_r2[chan - 1]);
1632136849Sscottl		ural_rf_write(sc, RAL_RF3, power << 7 | 0x38044);
1633136849Sscottl		ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
1634136849Sscottl		break;
1635136849Sscottl
1636136849Sscottl	case RAL_RF_2524:
1637149871Sscottl		ural_rf_write(sc, RAL_RF1, 0x0c808);
1638136849Sscottl		ural_rf_write(sc, RAL_RF2, ural_rf2524_r2[chan - 1]);
1639136849Sscottl		ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040);
1640136849Sscottl		ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
1641136849Sscottl		break;
1642136849Sscottl
1643136849Sscottl	case RAL_RF_2525:
1644149871Sscottl		ural_rf_write(sc, RAL_RF1, 0x08808);
1645149871Sscottl		ural_rf_write(sc, RAL_RF2, ural_rf2525_hi_r2[chan - 1]);
1646149871Sscottl		ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044);
1647149871Sscottl		ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
1648149871Sscottl
1649149871Sscottl		ural_rf_write(sc, RAL_RF1, 0x08808);
1650149871Sscottl		ural_rf_write(sc, RAL_RF2, ural_rf2525_r2[chan - 1]);
1651136849Sscottl		ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044);
1652136849Sscottl		ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
1653136849Sscottl		break;
1654136849Sscottl
1655136849Sscottl	case RAL_RF_2525E:
1656149871Sscottl		ural_rf_write(sc, RAL_RF1, 0x08808);
1657136849Sscottl		ural_rf_write(sc, RAL_RF2, ural_rf2525e_r2[chan - 1]);
1658149871Sscottl		ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044);
1659149871Sscottl		ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00286 : 0x00282);
1660136849Sscottl		break;
1661136849Sscottl
1662136849Sscottl	case RAL_RF_2526:
1663136849Sscottl		ural_rf_write(sc, RAL_RF2, ural_rf2526_hi_r2[chan - 1]);
1664136849Sscottl		ural_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381);
1665136849Sscottl		ural_rf_write(sc, RAL_RF1, 0x08804);
1666136849Sscottl
1667149871Sscottl		ural_rf_write(sc, RAL_RF2, ural_rf2526_r2[chan - 1]);
1668149871Sscottl		ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044);
1669136849Sscottl		ural_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381);
1670136849Sscottl		break;
1671149871Sscottl
1672149871Sscottl	/* dual-band RF */
1673149871Sscottl	case RAL_RF_5222:
1674149871Sscottl		for (i = 0; ural_rf5222[i].chan != chan; i++);
1675149871Sscottl
1676149871Sscottl		ural_rf_write(sc, RAL_RF1, ural_rf5222[i].r1);
1677149871Sscottl		ural_rf_write(sc, RAL_RF2, ural_rf5222[i].r2);
1678149871Sscottl		ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040);
1679149871Sscottl		ural_rf_write(sc, RAL_RF4, ural_rf5222[i].r4);
1680136849Sscottl		break;
1681149871Sscottl	}
1682149871Sscottl
1683136849Sscottl	if (ic->ic_opmode != IEEE80211_M_MONITOR &&
1684149871Sscottl	    (ic->ic_flags & IEEE80211_F_SCAN) == 0) {
1685149871Sscottl		/* set Japan filter bit for channel 14 */
1686136849Sscottl		tmp = ural_bbp_read(sc, 70);
1687136849Sscottl
1688136849Sscottl		tmp &= ~RAL_JAPAN_FILTER;
1689136849Sscottl		if (chan == 14)
1690136849Sscottl			tmp |= RAL_JAPAN_FILTER;
1691136849Sscottl
1692136849Sscottl		ural_bbp_write(sc, 70, tmp);
1693136849Sscottl
1694136849Sscottl		/* clear CRC errors */
1695149871Sscottl		ural_read(sc, RAL_STA_CSR0);
1696136849Sscottl
1697136849Sscottl		ural_pause(sc, hz / 100);
1698136849Sscottl		ural_disable_rf_tune(sc);
1699136849Sscottl	}
1700136849Sscottl
1701136849Sscottl	/* XXX doesn't belong here */
1702136849Sscottl	/* update basic rate set */
1703136849Sscottl	ural_set_basicrates(sc, c);
1704136849Sscottl
1705136849Sscottl	/* give the hardware some time to do the switchover */
1706136849Sscottl	ural_pause(sc, hz / 100);
1707149871Sscottl}
1708136849Sscottl
1709136849Sscottl/*
1710149871Sscottl * Disable RF auto-tuning.
1711149871Sscottl */
1712190809Sdelphijstatic void
1713149871Sscottlural_disable_rf_tune(struct ural_softc *sc)
1714149871Sscottl{
1715136849Sscottl	uint32_t tmp;
1716136849Sscottl
1717149871Sscottl	if (sc->rf_rev != RAL_RF_2523) {
1718149871Sscottl		tmp = sc->rf_regs[RAL_RF1] & ~RAL_RF1_AUTOTUNE;
1719149871Sscottl		ural_rf_write(sc, RAL_RF1, tmp);
1720190809Sdelphij	}
1721149871Sscottl
1722149871Sscottl	tmp = sc->rf_regs[RAL_RF3] & ~RAL_RF3_AUTOTUNE;
1723149871Sscottl	ural_rf_write(sc, RAL_RF3, tmp);
1724136849Sscottl
1725136849Sscottl	DPRINTFN(2, "disabling RF autotune\n");
1726136849Sscottl}
1727136849Sscottl
1728136849Sscottl/*
1729136849Sscottl * Refer to IEEE Std 802.11-1999 pp. 123 for more information on TSF
1730136849Sscottl * synchronization.
1731136849Sscottl */
1732136849Sscottlstatic void
1733136849Sscottlural_enable_tsf_sync(struct ural_softc *sc)
1734136849Sscottl{
1735136849Sscottl	struct ieee80211com *ic = &sc->sc_ic;
1736136849Sscottl	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1737136849Sscottl	uint16_t logcwmin, preload, tmp;
1738149871Sscottl
1739136849Sscottl	/* first, disable TSF synchronization */
1740136849Sscottl	ural_write(sc, RAL_TXRX_CSR19, 0);
1741136849Sscottl
1742136849Sscottl	tmp = (16 * vap->iv_bss->ni_intval) << 4;
1743136849Sscottl	ural_write(sc, RAL_TXRX_CSR18, tmp);
1744136849Sscottl
1745136849Sscottl	logcwmin = (ic->ic_opmode == IEEE80211_M_IBSS) ? 2 : 0;
1746136849Sscottl	preload = (ic->ic_opmode == IEEE80211_M_IBSS) ? 320 : 6;
1747190809Sdelphij	tmp = logcwmin << 12 | preload;
1748190809Sdelphij	ural_write(sc, RAL_TXRX_CSR20, tmp);
1749190809Sdelphij
1750190809Sdelphij	/* finally, enable TSF synchronization */
1751190809Sdelphij	tmp = RAL_ENABLE_TSF | RAL_ENABLE_TBCN;
1752190809Sdelphij	if (ic->ic_opmode == IEEE80211_M_STA)
1753136849Sscottl		tmp |= RAL_ENABLE_TSF_SYNC(1);
1754149871Sscottl	else
1755149871Sscottl		tmp |= RAL_ENABLE_TSF_SYNC(2) | RAL_ENABLE_BEACON_GENERATOR;
1756136849Sscottl	ural_write(sc, RAL_TXRX_CSR19, tmp);
1757136849Sscottl
1758136849Sscottl	DPRINTF("enabling TSF synchronization\n");
1759136849Sscottl}
1760136849Sscottl
1761136849Sscottlstatic void
1762136849Sscottlural_enable_tsf(struct ural_softc *sc)
1763136849Sscottl{
1764136849Sscottl	/* first, disable TSF synchronization */
1765136849Sscottl	ural_write(sc, RAL_TXRX_CSR19, 0);
1766136849Sscottl	ural_write(sc, RAL_TXRX_CSR19, RAL_ENABLE_TSF | RAL_ENABLE_TSF_SYNC(2));
1767136849Sscottl}
1768136849Sscottl
1769136849Sscottl#define RAL_RXTX_TURNAROUND	5	/* us */
1770136849Sscottlstatic void
1771136849Sscottlural_update_slot(struct ural_softc *sc)
1772136849Sscottl{
1773136849Sscottl	struct ieee80211com *ic = &sc->sc_ic;
1774136849Sscottl	uint16_t slottime, sifs, eifs;
1775149871Sscottl
1776149871Sscottl	slottime = IEEE80211_GET_SLOTTIME(ic);
1777149871Sscottl
1778149871Sscottl	/*
1779136849Sscottl	 * These settings may sound a bit inconsistent but this is what the
1780149871Sscottl	 * reference driver does.
1781149871Sscottl	 */
1782149871Sscottl	if (ic->ic_curmode == IEEE80211_MODE_11B) {
1783149871Sscottl		sifs = 16 - RAL_RXTX_TURNAROUND;
1784149871Sscottl		eifs = 364;
1785149871Sscottl	} else {
1786149871Sscottl		sifs = 10 - RAL_RXTX_TURNAROUND;
1787149871Sscottl		eifs = 64;
1788149871Sscottl	}
1789149871Sscottl
1790149871Sscottl	ural_write(sc, RAL_MAC_CSR10, slottime);
1791149871Sscottl	ural_write(sc, RAL_MAC_CSR11, sifs);
1792149871Sscottl	ural_write(sc, RAL_MAC_CSR12, eifs);
1793149871Sscottl}
1794136849Sscottl
1795149871Sscottlstatic void
1796149871Sscottlural_set_txpreamble(struct ural_softc *sc)
1797149871Sscottl{
1798149871Sscottl	struct ieee80211com *ic = &sc->sc_ic;
1799149871Sscottl	uint16_t tmp;
1800149871Sscottl
1801149871Sscottl	tmp = ural_read(sc, RAL_TXRX_CSR10);
1802149871Sscottl
1803149871Sscottl	tmp &= ~RAL_SHORT_PREAMBLE;
1804149871Sscottl	if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
1805149871Sscottl		tmp |= RAL_SHORT_PREAMBLE;
1806149871Sscottl
1807149871Sscottl	ural_write(sc, RAL_TXRX_CSR10, tmp);
1808149871Sscottl}
1809149871Sscottl
1810149871Sscottlstatic void
1811149871Sscottlural_set_basicrates(struct ural_softc *sc, const struct ieee80211_channel *c)
1812149871Sscottl{
1813149871Sscottl	/* XXX wrong, take from rate set */
1814149871Sscottl	/* update basic rate set */
1815149871Sscottl	if (IEEE80211_IS_CHAN_5GHZ(c)) {
1816149871Sscottl		/* 11a basic rates: 6, 12, 24Mbps */
1817149871Sscottl		ural_write(sc, RAL_TXRX_CSR11, 0x150);
1818149871Sscottl	} else if (IEEE80211_IS_CHAN_ANYG(c)) {
1819149871Sscottl		/* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */
1820136849Sscottl		ural_write(sc, RAL_TXRX_CSR11, 0x15f);
1821149871Sscottl	} else {
1822149871Sscottl		/* 11b basic rates: 1, 2Mbps */
1823149871Sscottl		ural_write(sc, RAL_TXRX_CSR11, 0x3);
1824149871Sscottl	}
1825149871Sscottl}
1826149871Sscottl
1827136849Sscottlstatic void
1828136849Sscottlural_set_bssid(struct ural_softc *sc, const uint8_t *bssid)
1829136849Sscottl{
1830149871Sscottl	uint16_t tmp;
1831136862Sscottl
1832136849Sscottl	tmp = bssid[0] | bssid[1] << 8;
1833136849Sscottl	ural_write(sc, RAL_MAC_CSR5, tmp);
1834149871Sscottl
1835136849Sscottl	tmp = bssid[2] | bssid[3] << 8;
1836136849Sscottl	ural_write(sc, RAL_MAC_CSR6, tmp);
1837136849Sscottl
1838136849Sscottl	tmp = bssid[4] | bssid[5] << 8;
1839149871Sscottl	ural_write(sc, RAL_MAC_CSR7, tmp);
1840149871Sscottl
1841136849Sscottl	DPRINTF("setting BSSID to %6D\n", bssid, ":");
1842136849Sscottl}
1843136849Sscottl
1844136849Sscottlstatic void
1845136849Sscottlural_set_macaddr(struct ural_softc *sc, const uint8_t *addr)
1846149871Sscottl{
1847136849Sscottl	uint16_t tmp;
1848149871Sscottl
1849149871Sscottl	tmp = addr[0] | addr[1] << 8;
1850136849Sscottl	ural_write(sc, RAL_MAC_CSR2, tmp);
1851136849Sscottl
1852136849Sscottl	tmp = addr[2] | addr[3] << 8;
1853136849Sscottl	ural_write(sc, RAL_MAC_CSR3, tmp);
1854136849Sscottl
1855149871Sscottl	tmp = addr[4] | addr[5] << 8;
1856136849Sscottl	ural_write(sc, RAL_MAC_CSR4, tmp);
1857149871Sscottl
1858149871Sscottl	DPRINTF("setting MAC address to %6D\n", addr, ":");
1859136849Sscottl}
1860149871Sscottl
1861149871Sscottlstatic void
1862136849Sscottlural_setpromisc(struct ural_softc *sc)
1863149871Sscottl{
1864149871Sscottl	uint32_t tmp;
1865136849Sscottl
1866136849Sscottl	tmp = ural_read(sc, RAL_TXRX_CSR2);
1867136849Sscottl
1868149871Sscottl	tmp &= ~RAL_DROP_NOT_TO_ME;
1869149871Sscottl	if (sc->sc_ic.ic_promisc == 0)
1870149871Sscottl		tmp |= RAL_DROP_NOT_TO_ME;
1871136849Sscottl
1872136849Sscottl	ural_write(sc, RAL_TXRX_CSR2, tmp);
1873136849Sscottl
1874136849Sscottl	DPRINTF("%s promiscuous mode\n", sc->sc_ic.ic_promisc ?
1875149871Sscottl	    "entering" : "leaving");
1876149871Sscottl}
1877149871Sscottl
1878136849Sscottlstatic void
1879136849Sscottlural_update_promisc(struct ieee80211com *ic)
1880136849Sscottl{
1881149871Sscottl	struct ural_softc *sc = ic->ic_softc;
1882149871Sscottl
1883149871Sscottl	RAL_LOCK(sc);
1884136849Sscottl	if (sc->sc_running)
1885136849Sscottl		ural_setpromisc(sc);
1886136849Sscottl	RAL_UNLOCK(sc);
1887149871Sscottl}
1888149871Sscottl
1889136849Sscottlstatic const char *
1890136849Sscottlural_get_rf(int rev)
1891136849Sscottl{
1892149871Sscottl	switch (rev) {
1893149871Sscottl	case RAL_RF_2522:	return "RT2522";
1894136849Sscottl	case RAL_RF_2523:	return "RT2523";
1895136849Sscottl	case RAL_RF_2524:	return "RT2524";
1896136849Sscottl	case RAL_RF_2525:	return "RT2525";
1897136849Sscottl	case RAL_RF_2525E:	return "RT2525e";
1898136849Sscottl	case RAL_RF_2526:	return "RT2526";
1899136849Sscottl	case RAL_RF_5222:	return "RT5222";
1900136849Sscottl	default:		return "unknown";
1901136849Sscottl	}
1902136849Sscottl}
1903136849Sscottl
1904136849Sscottlstatic void
1905136849Sscottlural_read_eeprom(struct ural_softc *sc)
1906136849Sscottl{
1907136849Sscottl	struct ieee80211com *ic = &sc->sc_ic;
1908136849Sscottl	uint16_t val;
1909149871Sscottl
1910136849Sscottl	ural_eeprom_read(sc, RAL_EEPROM_CONFIG0, &val, 2);
1911149871Sscottl	val = le16toh(val);
1912136849Sscottl	sc->rf_rev =   (val >> 11) & 0x7;
1913136849Sscottl	sc->hw_radio = (val >> 10) & 0x1;
1914149871Sscottl	sc->led_mode = (val >> 6)  & 0x7;
1915136849Sscottl	sc->rx_ant =   (val >> 4)  & 0x3;
1916136849Sscottl	sc->tx_ant =   (val >> 2)  & 0x3;
1917149871Sscottl	sc->nb_ant =   val & 0x3;
1918149871Sscottl
1919136849Sscottl	/* read MAC address */
1920136849Sscottl	ural_eeprom_read(sc, RAL_EEPROM_ADDRESS, ic->ic_macaddr, 6);
1921136849Sscottl
1922136849Sscottl	/* read default values for BBP registers */
1923149871Sscottl	ural_eeprom_read(sc, RAL_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16);
1924149871Sscottl
1925149871Sscottl	/* read Tx power for all b/g channels */
1926149871Sscottl	ural_eeprom_read(sc, RAL_EEPROM_TXPOWER, sc->txpow, 14);
1927149871Sscottl}
1928149871Sscottl
1929149871Sscottlstatic int
1930149871Sscottlural_bbp_init(struct ural_softc *sc)
1931149871Sscottl{
1932149871Sscottl	int i, ntries;
1933149871Sscottl
1934149871Sscottl	/* wait for BBP to be ready */
1935149871Sscottl	for (ntries = 0; ntries < 100; ntries++) {
1936149871Sscottl		if (ural_bbp_read(sc, RAL_BBP_VERSION) != 0)
1937149871Sscottl			break;
1938136849Sscottl		if (ural_pause(sc, hz / 100))
1939136849Sscottl			break;
1940136849Sscottl	}
1941136849Sscottl	if (ntries == 100) {
1942136849Sscottl		device_printf(sc->sc_dev, "timeout waiting for BBP\n");
1943136849Sscottl		return EIO;
1944136849Sscottl	}
1945136849Sscottl
1946136849Sscottl	/* initialize BBP registers to default values */
1947136849Sscottl	for (i = 0; i < nitems(ural_def_bbp); i++)
1948136849Sscottl		ural_bbp_write(sc, ural_def_bbp[i].reg, ural_def_bbp[i].val);
1949136849Sscottl
1950136849Sscottl#if 0
1951136849Sscottl	/* initialize BBP registers to values stored in EEPROM */
1952136849Sscottl	for (i = 0; i < 16; i++) {
1953136849Sscottl		if (sc->bbp_prom[i].reg == 0xff)
1954136849Sscottl			continue;
1955136849Sscottl		ural_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
1956136849Sscottl	}
1957136849Sscottl#endif
1958136849Sscottl
1959136849Sscottl	return 0;
1960149871Sscottl}
1961149871Sscottl
1962136849Sscottlstatic void
1963136849Sscottlural_set_txantenna(struct ural_softc *sc, int antenna)
1964267368Sdelphij{
1965136849Sscottl	uint16_t tmp;
1966136849Sscottl	uint8_t tx;
1967136849Sscottl
1968136849Sscottl	tx = ural_bbp_read(sc, RAL_BBP_TX) & ~RAL_BBP_ANTMASK;
1969136849Sscottl	if (antenna == 1)
1970136849Sscottl		tx |= RAL_BBP_ANTA;
1971136849Sscottl	else if (antenna == 2)
1972136849Sscottl		tx |= RAL_BBP_ANTB;
1973136849Sscottl	else
1974136849Sscottl		tx |= RAL_BBP_DIVERSITY;
1975136849Sscottl
1976136849Sscottl	/* need to force I/Q flip for RF 2525e, 2526 and 5222 */
1977136849Sscottl	if (sc->rf_rev == RAL_RF_2525E || sc->rf_rev == RAL_RF_2526 ||
1978149871Sscottl	    sc->rf_rev == RAL_RF_5222)
1979136849Sscottl		tx |= RAL_BBP_FLIPIQ;
1980136849Sscottl
1981136849Sscottl	ural_bbp_write(sc, RAL_BBP_TX, tx);
1982136849Sscottl
1983136849Sscottl	/* update values in PHY_CSR5 and PHY_CSR6 */
1984269617Sjhb	tmp = ural_read(sc, RAL_PHY_CSR5) & ~0x7;
1985136849Sscottl	ural_write(sc, RAL_PHY_CSR5, tmp | (tx & 0x7));
1986136849Sscottl
1987136849Sscottl	tmp = ural_read(sc, RAL_PHY_CSR6) & ~0x7;
1988136849Sscottl	ural_write(sc, RAL_PHY_CSR6, tmp | (tx & 0x7));
1989136849Sscottl}
1990136849Sscottl
1991136849Sscottlstatic void
1992136849Sscottlural_set_rxantenna(struct ural_softc *sc, int antenna)
1993295790Sjhibbits{
1994149871Sscottl	uint8_t rx;
1995136849Sscottl
1996136849Sscottl	rx = ural_bbp_read(sc, RAL_BBP_RX) & ~RAL_BBP_ANTMASK;
1997136849Sscottl	if (antenna == 1)
1998136849Sscottl		rx |= RAL_BBP_ANTA;
1999269617Sjhb	else if (antenna == 2)
2000269617Sjhb		rx |= RAL_BBP_ANTB;
2001190809Sdelphij	else
2002149871Sscottl		rx |= RAL_BBP_DIVERSITY;
2003136849Sscottl
2004136849Sscottl	/* need to force no I/Q flip for RF 2525e and 2526 */
2005136849Sscottl	if (sc->rf_rev == RAL_RF_2525E || sc->rf_rev == RAL_RF_2526)
2006136849Sscottl		rx &= ~RAL_BBP_FLIPIQ;
2007136849Sscottl
2008149871Sscottl	ural_bbp_write(sc, RAL_BBP_RX, rx);
2009149871Sscottl}
2010149871Sscottl
2011149871Sscottlstatic void
2012136849Sscottlural_init(struct ural_softc *sc)
2013136849Sscottl{
2014149871Sscottl	struct ieee80211com *ic = &sc->sc_ic;
2015149871Sscottl	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
2016149871Sscottl	uint16_t tmp;
2017136849Sscottl	int i, ntries;
2018136849Sscottl
2019136849Sscottl	RAL_LOCK_ASSERT(sc, MA_OWNED);
2020136849Sscottl
2021136849Sscottl	ural_set_testmode(sc);
2022149871Sscottl	ural_write(sc, 0x308, 0x00f0);	/* XXX magic */
2023149871Sscottl
2024136849Sscottl	ural_stop(sc);
2025136849Sscottl
2026136849Sscottl	/* initialize MAC registers to default values */
2027136849Sscottl	for (i = 0; i < nitems(ural_def_mac); i++)
2028136849Sscottl		ural_write(sc, ural_def_mac[i].reg, ural_def_mac[i].val);
2029136849Sscottl
2030136849Sscottl	/* wait for BBP and RF to wake up (this can take a long time!) */
2031190809Sdelphij	for (ntries = 0; ntries < 100; ntries++) {
2032269617Sjhb		tmp = ural_read(sc, RAL_MAC_CSR17);
2033269617Sjhb		if ((tmp & (RAL_BBP_AWAKE | RAL_RF_AWAKE)) ==
2034190809Sdelphij		    (RAL_BBP_AWAKE | RAL_RF_AWAKE))
2035136849Sscottl			break;
2036136849Sscottl		if (ural_pause(sc, hz / 100))
2037136849Sscottl			break;
2038136849Sscottl	}
2039269617Sjhb	if (ntries == 100) {
2040190809Sdelphij		device_printf(sc->sc_dev,
2041149871Sscottl		    "timeout waiting for BBP/RF to wakeup\n");
2042136849Sscottl		goto fail;
2043269617Sjhb	}
2044136849Sscottl
2045136849Sscottl	/* we're ready! */
2046136849Sscottl	ural_write(sc, RAL_MAC_CSR1, RAL_HOST_READY);
2047136849Sscottl
2048136849Sscottl	/* set basic rate set (will be updated later) */
2049149871Sscottl	ural_write(sc, RAL_TXRX_CSR11, 0x15f);
2050149871Sscottl
2051149871Sscottl	if (ural_bbp_init(sc) != 0)
2052136849Sscottl		goto fail;
2053136849Sscottl
2054269617Sjhb	ural_set_chan(sc, ic->ic_curchan);
2055136849Sscottl
2056136849Sscottl	/* clear statistic registers (STA_CSR0 to STA_CSR10) */
2057136849Sscottl	ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta);
2058269617Sjhb
2059136849Sscottl	ural_set_txantenna(sc, sc->tx_ant);
2060136849Sscottl	ural_set_rxantenna(sc, sc->rx_ant);
2061136849Sscottl
2062136849Sscottl	ural_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
2063136849Sscottl
2064136849Sscottl	/*
2065136849Sscottl	 * Allocate Tx and Rx xfer queues.
2066136849Sscottl	 */
2067136849Sscottl	ural_setup_tx_list(sc);
2068190863Sdelphij
2069190810Sdelphij	/* kick Rx */
2070190810Sdelphij	tmp = RAL_DROP_PHY | RAL_DROP_CRC;
2071139044Snjl	if (ic->ic_opmode != IEEE80211_M_MONITOR) {
2072136849Sscottl		tmp |= RAL_DROP_CTL | RAL_DROP_BAD_VERSION;
2073136849Sscottl		if (ic->ic_opmode != IEEE80211_M_HOSTAP)
2074136849Sscottl			tmp |= RAL_DROP_TODS;
2075136849Sscottl		if (ic->ic_promisc == 0)
2076136849Sscottl			tmp |= RAL_DROP_NOT_TO_ME;
2077136849Sscottl	}
2078149871Sscottl	ural_write(sc, RAL_TXRX_CSR2, tmp);
2079136849Sscottl
2080136849Sscottl	sc->sc_running = 1;
2081136849Sscottl	usbd_xfer_set_stall(sc->sc_xfer[URAL_BULK_WR]);
2082149871Sscottl	usbd_transfer_start(sc->sc_xfer[URAL_BULK_RD]);
2083136849Sscottl	return;
2084136849Sscottl
2085136849Sscottlfail:	ural_stop(sc);
2086136849Sscottl}
2087136849Sscottl
2088136849Sscottlstatic void
2089136849Sscottlural_stop(struct ural_softc *sc)
2090136849Sscottl{
2091269617Sjhb
2092269617Sjhb	RAL_LOCK_ASSERT(sc, MA_OWNED);
2093269617Sjhb
2094269617Sjhb	sc->sc_running = 0;
2095269617Sjhb
2096136849Sscottl	/*
2097136849Sscottl	 * Drain all the transfers, if not already drained:
2098136849Sscottl	 */
2099136849Sscottl	RAL_UNLOCK(sc);
2100136849Sscottl	usbd_transfer_drain(sc->sc_xfer[URAL_BULK_WR]);
2101136849Sscottl	usbd_transfer_drain(sc->sc_xfer[URAL_BULK_RD]);
2102136849Sscottl	RAL_LOCK(sc);
2103136849Sscottl
2104136849Sscottl	ural_unsetup_tx_list(sc);
2105269617Sjhb
2106269617Sjhb	/* disable Rx */
2107269617Sjhb	ural_write(sc, RAL_TXRX_CSR2, RAL_DISABLE_RX);
2108269617Sjhb	/* reset ASIC and BBP (but won't reset MAC registers!) */
2109269617Sjhb	ural_write(sc, RAL_MAC_CSR1, RAL_RESET_ASIC | RAL_RESET_BBP);
2110269617Sjhb	/* wait a little */
2111269617Sjhb	ural_pause(sc, hz / 10);
2112269617Sjhb	ural_write(sc, RAL_MAC_CSR1, 0);
2113269617Sjhb	/* wait a little */
2114269617Sjhb	ural_pause(sc, hz / 10);
2115269617Sjhb}
2116269617Sjhb
2117269617Sjhbstatic int
2118136849Sscottlural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2119149871Sscottl	const struct ieee80211_bpf_params *params)
2120149871Sscottl{
2121136849Sscottl	struct ieee80211com *ic = ni->ni_ic;
2122136849Sscottl	struct ural_softc *sc = ic->ic_softc;
2123136849Sscottl
2124136849Sscottl	RAL_LOCK(sc);
2125136849Sscottl	/* prevent management frames from being sent if we're not ready */
2126136849Sscottl	if (!sc->sc_running) {
2127136849Sscottl		RAL_UNLOCK(sc);
2128136849Sscottl		m_freem(m);
2129136849Sscottl		return ENETDOWN;
2130136849Sscottl	}
2131136849Sscottl	if (sc->tx_nfree < RAL_TX_MINFREE) {
2132136849Sscottl		RAL_UNLOCK(sc);
2133136849Sscottl		m_freem(m);
2134136849Sscottl		return EIO;
2135136849Sscottl	}
2136136849Sscottl
2137136849Sscottl	if (params == NULL) {
2138136849Sscottl		/*
2139136849Sscottl		 * Legacy path; interpret frame contents to decide
2140136849Sscottl		 * precisely how to send the frame.
2141136849Sscottl		 */
2142136849Sscottl		if (ural_tx_mgt(sc, m, ni) != 0)
2143136849Sscottl			goto bad;
2144136849Sscottl	} else {
2145136849Sscottl		/*
2146136849Sscottl		 * Caller supplied explicit parameters to use in
2147136849Sscottl		 * sending the frame.
2148136849Sscottl		 */
2149136849Sscottl		if (ural_tx_raw(sc, m, ni, params) != 0)
2150136849Sscottl			goto bad;
2151136849Sscottl	}
2152136849Sscottl	RAL_UNLOCK(sc);
2153136849Sscottl	return 0;
2154136849Sscottlbad:
2155136849Sscottl	RAL_UNLOCK(sc);
2156136849Sscottl	return EIO;		/* XXX */
2157136849Sscottl}
2158149871Sscottl
2159136849Sscottlstatic void
2160136849Sscottlural_ratectl_start(struct ural_softc *sc, struct ieee80211_node *ni)
2161136849Sscottl{
2162136849Sscottl	struct ieee80211vap *vap = ni->ni_vap;
2163136849Sscottl	struct ural_vap *uvp = URAL_VAP(vap);
2164136849Sscottl
2165149871Sscottl	/* clear statistic registers (STA_CSR0 to STA_CSR10) */
2166149871Sscottl	ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta);
2167149871Sscottl
2168136849Sscottl	usb_callout_reset(&uvp->ratectl_ch, hz, ural_ratectl_timeout, uvp);
2169149871Sscottl}
2170269617Sjhb
2171149871Sscottlstatic void
2172269617Sjhbural_ratectl_timeout(void *arg)
2173149871Sscottl{
2174149871Sscottl	struct ural_vap *uvp = arg;
2175149871Sscottl	struct ieee80211vap *vap = &uvp->vap;
2176149871Sscottl	struct ieee80211com *ic = vap->iv_ic;
2177136849Sscottl
2178136849Sscottl	ieee80211_runtask(ic, &uvp->ratectl_task);
2179136849Sscottl}
2180136849Sscottl
2181136849Sscottlstatic void
2182136849Sscottlural_ratectl_task(void *arg, int pending)
2183136849Sscottl{
2184136849Sscottl	struct ural_vap *uvp = arg;
2185136849Sscottl	struct ieee80211vap *vap = &uvp->vap;
2186136849Sscottl	struct ural_softc *sc = vap->iv_ic->ic_softc;
2187149871Sscottl	struct ieee80211_ratectl_tx_stats *txs = &sc->sc_txs;
2188149871Sscottl	int fail;
2189136849Sscottl
2190149871Sscottl	RAL_LOCK(sc);
2191149871Sscottl	/* read and clear statistic registers (STA_CSR0 to STA_CSR10) */
2192149871Sscottl	ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof(sc->sta));
2193149871Sscottl
2194149871Sscottl	txs->flags = IEEE80211_RATECTL_TX_STATS_RETRIES;
2195149871Sscottl	txs->nsuccess = sc->sta[7] +	/* TX ok w/o retry */
2196149871Sscottl			sc->sta[8];	/* TX ok w/ retry */
2197149871Sscottl	fail = sc->sta[9];		/* TX retry-fail count */
2198136849Sscottl	txs->nframes = txs->nsuccess + fail;
2199136849Sscottl	/* XXX fail * maxretry */
2200136849Sscottl	txs->nretries = sc->sta[8] + fail;
2201136849Sscottl
2202136849Sscottl	ieee80211_ratectl_tx_update(vap, txs);
2203149871Sscottl
2204149871Sscottl	/* count TX retry-fail as Tx errors */
2205136849Sscottl	if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS, fail);
2206149871Sscottl
2207136849Sscottl	usb_callout_reset(&uvp->ratectl_ch, hz, ural_ratectl_timeout, uvp);
2208136849Sscottl	RAL_UNLOCK(sc);
2209136849Sscottl}
2210136849Sscottl
2211136849Sscottlstatic int
2212136849Sscottlural_pause(struct ural_softc *sc, int timeout)
2213136849Sscottl{
2214136849Sscottl
2215149871Sscottl	usb_pause_mtx(&sc->sc_mtx, timeout);
2216149871Sscottl	return (0);
2217149871Sscottl}
2218136849Sscottl