if_urtwn.c revision 265345
1100978Srwatson/*	$OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $	*/
2126097Srwatson
3126097Srwatson/*-
4100978Srwatson * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
5100978Srwatson *
6100978Srwatson * Permission to use, copy, modify, and distribute this software for any
7100978Srwatson * purpose with or without fee is hereby granted, provided that the above
8106392Srwatson * copyright notice and this permission notice appear in all copies.
9106392Srwatson *
10106392Srwatson * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11106392Srwatson * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12100978Srwatson * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13100978Srwatson * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14100978Srwatson * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15100978Srwatson * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16100978Srwatson * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17100978Srwatson */
18100978Srwatson
19100978Srwatson#include <sys/cdefs.h>
20100978Srwatson__FBSDID("$FreeBSD: stable/10/sys/dev/usb/wlan/if_urtwn.c 265345 2014-05-05 01:50:01Z kevlo $");
21100978Srwatson
22100978Srwatson/*
23100978Srwatson * Driver for Realtek RTL8188CE-VAU/RTL8188CUS/RTL8188RU/RTL8192CU.
24100978Srwatson */
25100978Srwatson
26100978Srwatson#include <sys/param.h>
27100978Srwatson#include <sys/sockio.h>
28100978Srwatson#include <sys/sysctl.h>
29100978Srwatson#include <sys/lock.h>
30100978Srwatson#include <sys/mutex.h>
31100978Srwatson#include <sys/mbuf.h>
32100978Srwatson#include <sys/kernel.h>
33100978Srwatson#include <sys/socket.h>
34100978Srwatson#include <sys/systm.h>
35100978Srwatson#include <sys/malloc.h>
36100978Srwatson#include <sys/module.h>
37100978Srwatson#include <sys/bus.h>
38100978Srwatson#include <sys/endian.h>
39100978Srwatson#include <sys/linker.h>
40100978Srwatson#include <sys/firmware.h>
41100978Srwatson#include <sys/kdb.h>
42100978Srwatson
43100978Srwatson#include <machine/bus.h>
44100978Srwatson#include <machine/resource.h>
45101826Srwatson#include <sys/rman.h>
46101826Srwatson
47100978Srwatson#include <net/bpf.h>
48100978Srwatson#include <net/if.h>
49100978Srwatson#include <net/if_arp.h>
50100978Srwatson#include <net/ethernet.h>
51100978Srwatson#include <net/if_dl.h>
52102123Srwatson#include <net/if_media.h>
53102123Srwatson#include <net/if_types.h>
54105693Srwatson
55105693Srwatson#include <netinet/in.h>
56105693Srwatson#include <netinet/in_systm.h>
57105693Srwatson#include <netinet/in_var.h>
58102123Srwatson#include <netinet/if_ether.h>
59105693Srwatson#include <netinet/ip.h>
60105693Srwatson
61105693Srwatson#include <net80211/ieee80211_var.h>
62105693Srwatson#include <net80211/ieee80211_regdomain.h>
63105693Srwatson#include <net80211/ieee80211_radiotap.h>
64105693Srwatson#include <net80211/ieee80211_ratectl.h>
65105693Srwatson
66105693Srwatson#include <dev/usb/usb.h>
67105693Srwatson#include <dev/usb/usbdi.h>
68102123Srwatson#include "usbdevs.h"
69105693Srwatson
70105693Srwatson#define USB_DEBUG_VAR urtwn_debug
71105693Srwatson#include <dev/usb/usb_debug.h>
72100978Srwatson
73105693Srwatson#include <dev/usb/wlan/if_urtwnreg.h>
74100978Srwatson
75100978Srwatson#ifdef USB_DEBUG
76105693Srwatsonstatic int urtwn_debug = 0;
77105693Srwatson
78100978SrwatsonSYSCTL_NODE(_hw_usb, OID_AUTO, urtwn, CTLFLAG_RW, 0, "USB urtwn");
79120657SrwatsonSYSCTL_INT(_hw_usb_urtwn, OID_AUTO, debug, CTLFLAG_RW, &urtwn_debug, 0,
80119546Srwatson    "Debug level");
81119546Srwatson#endif
82119546Srwatson
83119546Srwatson#define	URTWN_RSSI(r)  (r) - 110
84119546Srwatson#define	IEEE80211_HAS_ADDR4(wh)	\
85119546Srwatson	(((wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
86122810Srwatson
87119546Srwatson/* various supported device vendors/products */
88119546Srwatsonstatic const STRUCT_USB_HOST_ID urtwn_devs[] = {
89119546Srwatson#define URTWN_DEV(v,p)  { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
90119546Srwatson	URTWN_DEV(ABOCOM,	RTL8188CU_1),
91119546Srwatson	URTWN_DEV(ABOCOM,	RTL8188CU_2),
92119546Srwatson	URTWN_DEV(ABOCOM,	RTL8192CU),
93119546Srwatson	URTWN_DEV(ASUS,		RTL8192CU),
94119546Srwatson	URTWN_DEV(ASUS,		USBN10NANO),
95119546Srwatson	URTWN_DEV(AZUREWAVE,	RTL8188CE_1),
96119546Srwatson	URTWN_DEV(AZUREWAVE,	RTL8188CE_2),
97119546Srwatson	URTWN_DEV(AZUREWAVE,	RTL8188CU),
98119546Srwatson	URTWN_DEV(BELKIN,	F7D2102),
99119546Srwatson	URTWN_DEV(BELKIN,	RTL8188CU),
100119546Srwatson	URTWN_DEV(BELKIN,	RTL8192CU),
101120657Srwatson	URTWN_DEV(CHICONY,	RTL8188CUS_1),
102105693Srwatson	URTWN_DEV(CHICONY,	RTL8188CUS_2),
103106093Srwatson	URTWN_DEV(CHICONY,	RTL8188CUS_3),
104105693Srwatson	URTWN_DEV(CHICONY,	RTL8188CUS_4),
105105693Srwatson	URTWN_DEV(CHICONY,	RTL8188CUS_5),
106100978Srwatson	URTWN_DEV(COREGA,	RTL8192CU),
107100978Srwatson	URTWN_DEV(DLINK,	RTL8188CU),
108100978Srwatson	URTWN_DEV(DLINK,	RTL8192CU_1),
109100978Srwatson	URTWN_DEV(DLINK,	RTL8192CU_2),
110100978Srwatson	URTWN_DEV(DLINK,	RTL8192CU_3),
111100978Srwatson	URTWN_DEV(DLINK,	DWA131B),
112100978Srwatson	URTWN_DEV(EDIMAX,	EW7811UN),
113122875Srwatson	URTWN_DEV(EDIMAX,	RTL8192CU),
114106468Srwatson	URTWN_DEV(FEIXUN,	RTL8188CU),
115122875Srwatson	URTWN_DEV(FEIXUN,	RTL8192CU),
116100978Srwatson	URTWN_DEV(GUILLEMOT,	HWNUP150),
117113487Srwatson	URTWN_DEV(HAWKING,	RTL8192CU),
118100978Srwatson	URTWN_DEV(HP3,		RTL8188CU),
119100978Srwatson	URTWN_DEV(NETGEAR,	WNA1000M),
120100978Srwatson	URTWN_DEV(NETGEAR,	RTL8192CU),
121100978Srwatson	URTWN_DEV(NETGEAR4,	RTL8188CU),
122100978Srwatson	URTWN_DEV(NOVATECH,	RTL8188CU),
123126121Spjd	URTWN_DEV(PLANEX2,	RTL8188CU_1),
124126121Spjd	URTWN_DEV(PLANEX2,	RTL8188CU_2),
125125293Srwatson	URTWN_DEV(PLANEX2,	RTL8188CU_3),
126104338Srwatson	URTWN_DEV(PLANEX2,	RTL8188CU_4),
127100978Srwatson	URTWN_DEV(PLANEX2,	RTL8188CUS),
128100978Srwatson	URTWN_DEV(PLANEX2,	RTL8192CU),
129100978Srwatson	URTWN_DEV(REALTEK,	RTL8188CE_0),
130100978Srwatson	URTWN_DEV(REALTEK,	RTL8188CE_1),
131100978Srwatson	URTWN_DEV(REALTEK,	RTL8188CTV),
132100978Srwatson	URTWN_DEV(REALTEK,	RTL8188CU_0),
133100978Srwatson	URTWN_DEV(REALTEK,	RTL8188CU_1),
134100978Srwatson	URTWN_DEV(REALTEK,	RTL8188CU_2),
135100978Srwatson	URTWN_DEV(REALTEK,	RTL8188CU_COMBO),
136100978Srwatson	URTWN_DEV(REALTEK,	RTL8188CUS),
137100978Srwatson	URTWN_DEV(REALTEK,	RTL8188RU_1),
138100978Srwatson	URTWN_DEV(REALTEK,	RTL8188RU_2),
139100978Srwatson	URTWN_DEV(REALTEK,	RTL8191CU),
140100978Srwatson	URTWN_DEV(REALTEK,	RTL8192CE),
141100978Srwatson	URTWN_DEV(REALTEK,	RTL8192CU),
142100978Srwatson	URTWN_DEV(SITECOMEU,	RTL8188CU_1),
143100978Srwatson	URTWN_DEV(SITECOMEU,	RTL8188CU_2),
144122875Srwatson	URTWN_DEV(SITECOMEU,	RTL8192CU),
145112675Srwatson	URTWN_DEV(TRENDNET,	RTL8188CU),
146104541Srwatson	URTWN_DEV(TRENDNET,	RTL8192CU),
147125293Srwatson	URTWN_DEV(ZYXEL,	RTL8192CU),
148113487Srwatson#undef URTWN_DEV
149113487Srwatson};
150100978Srwatson
151107105Srwatsonstatic device_probe_t	urtwn_match;
152100978Srwatsonstatic device_attach_t	urtwn_attach;
153113487Srwatsonstatic device_detach_t	urtwn_detach;
154105988Srwatson
155100978Srwatsonstatic usb_callback_t   urtwn_bulk_tx_callback;
156100978Srwatsonstatic usb_callback_t	urtwn_bulk_rx_callback;
157100978Srwatson
158100978Srwatsonstatic usb_error_t	urtwn_do_request(struct urtwn_softc *sc,
159122875Srwatson			    struct usb_device_request *req, void *data);
160100978Srwatsonstatic struct ieee80211vap *urtwn_vap_create(struct ieee80211com *,
161100978Srwatson		    const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
162125293Srwatson                    const uint8_t [IEEE80211_ADDR_LEN],
163107105Srwatson                    const uint8_t [IEEE80211_ADDR_LEN]);
164113487Srwatsonstatic void		urtwn_vap_delete(struct ieee80211vap *);
165100978Srwatsonstatic struct mbuf *	urtwn_rx_frame(struct urtwn_softc *, uint8_t *, int,
166100978Srwatson			    int *);
167100978Srwatsonstatic struct mbuf *	urtwn_rxeof(struct usb_xfer *, struct urtwn_data *,
168122524Srwatson			    int *, int8_t *);
169122524Srwatsonstatic void		urtwn_txeof(struct usb_xfer *, struct urtwn_data *);
170122524Srwatsonstatic int		urtwn_alloc_list(struct urtwn_softc *,
171122524Srwatson			    struct urtwn_data[], int, int);
172122524Srwatsonstatic int		urtwn_alloc_rx_list(struct urtwn_softc *);
173100978Srwatsonstatic int		urtwn_alloc_tx_list(struct urtwn_softc *);
174100978Srwatsonstatic void		urtwn_free_tx_list(struct urtwn_softc *);
175100978Srwatsonstatic void		urtwn_free_rx_list(struct urtwn_softc *);
176100978Srwatsonstatic void		urtwn_free_list(struct urtwn_softc *,
177105988Srwatson			    struct urtwn_data data[], int);
178105988Srwatsonstatic struct urtwn_data *	_urtwn_getbuf(struct urtwn_softc *);
179105988Srwatsonstatic struct urtwn_data *	urtwn_getbuf(struct urtwn_softc *);
180105988Srwatsonstatic int		urtwn_write_region_1(struct urtwn_softc *, uint16_t,
181107698Srwatson			    uint8_t *, int);
182100978Srwatsonstatic void		urtwn_write_1(struct urtwn_softc *, uint16_t, uint8_t);
183107698Srwatsonstatic void		urtwn_write_2(struct urtwn_softc *, uint16_t, uint16_t);
184107698Srwatsonstatic void		urtwn_write_4(struct urtwn_softc *, uint16_t, uint32_t);
185107698Srwatsonstatic int		urtwn_read_region_1(struct urtwn_softc *, uint16_t,
186107698Srwatson			    uint8_t *, int);
187105988Srwatsonstatic uint8_t		urtwn_read_1(struct urtwn_softc *, uint16_t);
188105988Srwatsonstatic uint16_t		urtwn_read_2(struct urtwn_softc *, uint16_t);
189100978Srwatsonstatic uint32_t		urtwn_read_4(struct urtwn_softc *, uint16_t);
190100978Srwatsonstatic int		urtwn_fw_cmd(struct urtwn_softc *, uint8_t,
191100978Srwatson			    const void *, int);
192100978Srwatsonstatic void		urtwn_rf_write(struct urtwn_softc *, int, uint8_t,
193107698Srwatson			    uint32_t);
194107698Srwatsonstatic uint32_t		urtwn_rf_read(struct urtwn_softc *, int, uint8_t);
195100978Srwatsonstatic int		urtwn_llt_write(struct urtwn_softc *, uint32_t,
196100978Srwatson			    uint32_t);
197100978Srwatsonstatic uint8_t		urtwn_efuse_read_1(struct urtwn_softc *, uint16_t);
198100978Srwatsonstatic void		urtwn_efuse_read(struct urtwn_softc *);
199100978Srwatsonstatic int		urtwn_read_chipid(struct urtwn_softc *);
200100978Srwatsonstatic void		urtwn_read_rom(struct urtwn_softc *);
201100978Srwatsonstatic int		urtwn_ra_init(struct urtwn_softc *);
202100978Srwatsonstatic void		urtwn_tsf_sync_enable(struct urtwn_softc *);
203100978Srwatsonstatic void		urtwn_set_led(struct urtwn_softc *, int, int);
204100978Srwatsonstatic int		urtwn_newstate(struct ieee80211vap *,
205100978Srwatson			    enum ieee80211_state, int);
206100978Srwatsonstatic void		urtwn_watchdog(void *);
207125293Srwatsonstatic void		urtwn_update_avgrssi(struct urtwn_softc *, int, int8_t);
208100978Srwatsonstatic int8_t		urtwn_get_rssi(struct urtwn_softc *, int, void *);
209100978Srwatsonstatic int		urtwn_tx_start(struct urtwn_softc *,
210100978Srwatson			    struct ieee80211_node *, struct mbuf *,
211100978Srwatson			    struct urtwn_data *);
212100978Srwatsonstatic void		urtwn_start(struct ifnet *);
213100978Srwatsonstatic void		urtwn_start_locked(struct ifnet *,
214122875Srwatson			    struct urtwn_softc *);
215100978Srwatsonstatic int		urtwn_ioctl(struct ifnet *, u_long, caddr_t);
216100978Srwatsonstatic int		urtwn_power_on(struct urtwn_softc *);
217100978Srwatsonstatic int		urtwn_llt_init(struct urtwn_softc *);
218123607Srwatsonstatic void		urtwn_fw_reset(struct urtwn_softc *);
219100978Srwatsonstatic int		urtwn_fw_loadpage(struct urtwn_softc *, int,
220100978Srwatson			    const uint8_t *, int);
221100978Srwatsonstatic int		urtwn_load_firmware(struct urtwn_softc *);
222100978Srwatsonstatic int		urtwn_dma_init(struct urtwn_softc *);
223100978Srwatsonstatic void		urtwn_mac_init(struct urtwn_softc *);
224100978Srwatsonstatic void		urtwn_bb_init(struct urtwn_softc *);
225100978Srwatsonstatic void		urtwn_rf_init(struct urtwn_softc *);
226100978Srwatsonstatic void		urtwn_cam_init(struct urtwn_softc *);
227119244Srwatsonstatic void		urtwn_pa_bias_init(struct urtwn_softc *);
228119244Srwatsonstatic void		urtwn_rxfilter_init(struct urtwn_softc *);
229100978Srwatsonstatic void		urtwn_edca_init(struct urtwn_softc *);
230122875Srwatsonstatic void		urtwn_write_txpower(struct urtwn_softc *, int,
231100978Srwatson			    uint16_t[]);
232100978Srwatsonstatic void		urtwn_get_txpower(struct urtwn_softc *, int,
233100978Srwatson		      	    struct ieee80211_channel *,
234100978Srwatson			    struct ieee80211_channel *, uint16_t[]);
235123173Srwatsonstatic void		urtwn_set_txpower(struct urtwn_softc *,
236122524Srwatson		    	    struct ieee80211_channel *,
237106468Srwatson			    struct ieee80211_channel *);
238100978Srwatsonstatic void		urtwn_scan_start(struct ieee80211com *);
239106468Srwatsonstatic void		urtwn_scan_end(struct ieee80211com *);
240106468Srwatsonstatic void		urtwn_set_channel(struct ieee80211com *);
241106468Srwatsonstatic void		urtwn_set_chan(struct urtwn_softc *,
242106468Srwatson		    	    struct ieee80211_channel *,
243100978Srwatson			    struct ieee80211_channel *);
244100978Srwatsonstatic void		urtwn_update_mcast(struct ifnet *);
245104338Srwatsonstatic void		urtwn_iq_calib(struct urtwn_softc *);
246100978Srwatsonstatic void		urtwn_lc_calib(struct urtwn_softc *);
247100978Srwatsonstatic void		urtwn_init(void *);
248100978Srwatsonstatic void		urtwn_init_locked(void *);
249100978Srwatsonstatic void		urtwn_stop(struct ifnet *);
250100978Srwatsonstatic void		urtwn_stop_locked(struct ifnet *);
251122875Srwatsonstatic void		urtwn_abort_xfers(struct urtwn_softc *);
252106308Srwatsonstatic int		urtwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
253106308Srwatson			    const struct ieee80211_bpf_params *);
254106308Srwatson
255106308Srwatson/* Aliases. */
256107089Srwatson#define	urtwn_bb_write	urtwn_write_4
257107089Srwatson#define urtwn_bb_read	urtwn_read_4
258107089Srwatson
259100978Srwatsonstatic const struct usb_config urtwn_config[URTWN_N_TRANSFER] = {
260125293Srwatson	[URTWN_BULK_RX] = {
261100978Srwatson		.type = UE_BULK,
262125293Srwatson		.endpoint = UE_ADDR_ANY,
263125293Srwatson		.direction = UE_DIR_IN,
264125293Srwatson		.bufsize = URTWN_RXBUFSZ,
265125293Srwatson		.flags = {
266100978Srwatson			.pipe_bof = 1,
267100978Srwatson			.short_xfer_ok = 1
268100978Srwatson		},
269100978Srwatson		.callback = urtwn_bulk_rx_callback,
270100978Srwatson	},
271100978Srwatson	[URTWN_BULK_TX_BE] = {
272100978Srwatson		.type = UE_BULK,
273100978Srwatson		.endpoint = 0x03,
274101934Srwatson		.direction = UE_DIR_OUT,
275100978Srwatson		.bufsize = URTWN_TXBUFSZ,
276104571Srwatson		.flags = {
277104571Srwatson			.ext_buffer = 1,
278100978Srwatson			.pipe_bof = 1,
279111939Srwatson			.force_short_xfer = 1
280106412Srwatson		},
281106412Srwatson		.callback = urtwn_bulk_tx_callback,
282106024Srwatson		.timeout = URTWN_TX_TIMEOUT,	/* ms */
283106369Srwatson	},
284106023Srwatson	[URTWN_BULK_TX_BK] = {
285111936Srwatson		.type = UE_BULK,
286126121Spjd		.endpoint = 0x03,
287126121Spjd		.direction = UE_DIR_OUT,
288100978Srwatson		.bufsize = URTWN_TXBUFSZ,
289106212Srwatson		.flags = {
290100978Srwatson			.ext_buffer = 1,
291100978Srwatson			.pipe_bof = 1,
292100978Srwatson			.force_short_xfer = 1,
293100978Srwatson		},
294100978Srwatson		.callback = urtwn_bulk_tx_callback,
295100978Srwatson		.timeout = URTWN_TX_TIMEOUT,	/* ms */
296100978Srwatson	},
297100978Srwatson	[URTWN_BULK_TX_VI] = {
298119198Srwatson		.type = UE_BULK,
299119198Srwatson		.endpoint = 0x02,
300106468Srwatson		.direction = UE_DIR_OUT,
301106468Srwatson		.bufsize = URTWN_TXBUFSZ,
302100978Srwatson		.flags = {
303100978Srwatson			.ext_buffer = 1,
304100978Srwatson			.pipe_bof = 1,
305100978Srwatson			.force_short_xfer = 1
306104529Srwatson		},
307104529Srwatson		.callback = urtwn_bulk_tx_callback,
308119198Srwatson		.timeout = URTWN_TX_TIMEOUT,	/* ms */
309119198Srwatson	},
310100978Srwatson	[URTWN_BULK_TX_VO] = {
311100978Srwatson		.type = UE_BULK,
312104546Srwatson		.endpoint = 0x02,
313104546Srwatson		.direction = UE_DIR_OUT,
314104546Srwatson		.bufsize = URTWN_TXBUFSZ,
315104546Srwatson		.flags = {
316100978Srwatson			.ext_buffer = 1,
317106212Srwatson			.pipe_bof = 1,
318102129Srwatson			.force_short_xfer = 1
319102129Srwatson		},
320102129Srwatson		.callback = urtwn_bulk_tx_callback,
321102129Srwatson		.timeout = URTWN_TX_TIMEOUT,	/* ms */
322100978Srwatson	},
323100978Srwatson};
324100978Srwatson
325100978Srwatsonstatic int
326100978Srwatsonurtwn_match(device_t self)
327100978Srwatson{
328100978Srwatson	struct usb_attach_arg *uaa = device_get_ivars(self);
329100978Srwatson
330100978Srwatson	if (uaa->usb_mode != USB_MODE_HOST)
331100978Srwatson		return (ENXIO);
332100978Srwatson	if (uaa->info.bConfigIndex != URTWN_CONFIG_INDEX)
333100978Srwatson		return (ENXIO);
334100978Srwatson	if (uaa->info.bIfaceIndex != URTWN_IFACE_INDEX)
335100978Srwatson		return (ENXIO);
336100978Srwatson
337100978Srwatson	return (usbd_lookup_id_by_uaa(urtwn_devs, sizeof(urtwn_devs), uaa));
338100978Srwatson}
339100978Srwatson
340100978Srwatsonstatic int
341102129Srwatsonurtwn_attach(device_t self)
342102129Srwatson{
343102129Srwatson	struct usb_attach_arg *uaa = device_get_ivars(self);
344102129Srwatson	struct urtwn_softc *sc = device_get_softc(self);
345122807Srwatson	struct ifnet *ifp;
346100978Srwatson	struct ieee80211com *ic;
347122807Srwatson	uint8_t iface_index, bands;
348100978Srwatson	int error;
349100978Srwatson
350100978Srwatson	device_set_usb_desc(self);
351100978Srwatson	sc->sc_udev = uaa->device;
352100978Srwatson	sc->sc_dev = self;
353122807Srwatson
354100978Srwatson	mtx_init(&sc->sc_mtx, device_get_nameunit(self),
355125293Srwatson	    MTX_NETWORK_LOCK, MTX_DEF);
356100978Srwatson	callout_init(&sc->sc_watchdog_ch, 0);
357107271Srwatson
358100978Srwatson	iface_index = URTWN_IFACE_INDEX;
359100978Srwatson	error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
360100978Srwatson	    urtwn_config, URTWN_N_TRANSFER, sc, &sc->sc_mtx);
361100978Srwatson	if (error) {
362100978Srwatson		device_printf(self, "could not allocate USB transfers, "
363100978Srwatson		    "err=%s\n", usbd_errstr(error));
364100978Srwatson		goto detach;
365106093Srwatson	}
366100978Srwatson
367100978Srwatson	URTWN_LOCK(sc);
368
369	error = urtwn_read_chipid(sc);
370	if (error) {
371		device_printf(sc->sc_dev, "unsupported test chip\n");
372		URTWN_UNLOCK(sc);
373		goto detach;
374	}
375
376	/* Determine number of Tx/Rx chains. */
377	if (sc->chip & URTWN_CHIP_92C) {
378		sc->ntxchains = (sc->chip & URTWN_CHIP_92C_1T2R) ? 1 : 2;
379		sc->nrxchains = 2;
380	} else {
381		sc->ntxchains = 1;
382		sc->nrxchains = 1;
383	}
384	urtwn_read_rom(sc);
385
386	device_printf(sc->sc_dev, "MAC/BB RTL%s, RF 6052 %dT%dR\n",
387	    (sc->chip & URTWN_CHIP_92C) ? "8192CU" :
388	    (sc->board_type == R92C_BOARD_TYPE_HIGHPA) ? "8188RU" :
389	    (sc->board_type == R92C_BOARD_TYPE_MINICARD) ? "8188CE-VAU" :
390	    "8188CUS", sc->ntxchains, sc->nrxchains);
391
392	URTWN_UNLOCK(sc);
393
394	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
395	if (ifp == NULL) {
396		device_printf(sc->sc_dev, "can not if_alloc()\n");
397		goto detach;
398	}
399	ic = ifp->if_l2com;
400
401	ifp->if_softc = sc;
402	if_initname(ifp, "urtwn", device_get_unit(sc->sc_dev));
403	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
404	ifp->if_init = urtwn_init;
405	ifp->if_ioctl = urtwn_ioctl;
406	ifp->if_start = urtwn_start;
407	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
408	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
409	IFQ_SET_READY(&ifp->if_snd);
410
411	ic->ic_ifp = ifp;
412	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
413	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
414
415	/* set device capabilities */
416	ic->ic_caps =
417		  IEEE80211_C_STA		/* station mode */
418		| IEEE80211_C_MONITOR		/* monitor mode */
419		| IEEE80211_C_SHPREAMBLE	/* short preamble supported */
420		| IEEE80211_C_SHSLOT		/* short slot time supported */
421		| IEEE80211_C_BGSCAN		/* capable of bg scanning */
422		| IEEE80211_C_WPA		/* 802.11i */
423		;
424
425	bands = 0;
426	setbit(&bands, IEEE80211_MODE_11B);
427	setbit(&bands, IEEE80211_MODE_11G);
428	ieee80211_init_channels(ic, NULL, &bands);
429
430	ieee80211_ifattach(ic, sc->sc_bssid);
431	ic->ic_raw_xmit = urtwn_raw_xmit;
432	ic->ic_scan_start = urtwn_scan_start;
433	ic->ic_scan_end = urtwn_scan_end;
434	ic->ic_set_channel = urtwn_set_channel;
435
436	ic->ic_vap_create = urtwn_vap_create;
437	ic->ic_vap_delete = urtwn_vap_delete;
438	ic->ic_update_mcast = urtwn_update_mcast;
439
440	ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr,
441	    sizeof(sc->sc_txtap), URTWN_TX_RADIOTAP_PRESENT,
442	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
443	    URTWN_RX_RADIOTAP_PRESENT);
444
445	if (bootverbose)
446		ieee80211_announce(ic);
447
448	return (0);
449
450detach:
451	urtwn_detach(self);
452	return (ENXIO);			/* failure */
453}
454
455static int
456urtwn_detach(device_t self)
457{
458	struct urtwn_softc *sc = device_get_softc(self);
459	struct ifnet *ifp = sc->sc_ifp;
460	struct ieee80211com *ic = ifp->if_l2com;
461	unsigned int x;
462
463	/* Prevent further ioctls. */
464	URTWN_LOCK(sc);
465	sc->sc_flags |= URTWN_DETACHED;
466	URTWN_UNLOCK(sc);
467
468	urtwn_stop(ifp);
469
470	callout_drain(&sc->sc_watchdog_ch);
471
472	/* Prevent further allocations from RX/TX data lists. */
473	URTWN_LOCK(sc);
474	STAILQ_INIT(&sc->sc_tx_active);
475	STAILQ_INIT(&sc->sc_tx_inactive);
476	STAILQ_INIT(&sc->sc_tx_pending);
477
478	STAILQ_INIT(&sc->sc_rx_active);
479	STAILQ_INIT(&sc->sc_rx_inactive);
480	URTWN_UNLOCK(sc);
481
482	/* drain USB transfers */
483	for (x = 0; x != URTWN_N_TRANSFER; x++)
484		usbd_transfer_drain(sc->sc_xfer[x]);
485
486	/* Free data buffers. */
487	URTWN_LOCK(sc);
488	urtwn_free_tx_list(sc);
489	urtwn_free_rx_list(sc);
490	URTWN_UNLOCK(sc);
491
492	/* stop all USB transfers */
493	usbd_transfer_unsetup(sc->sc_xfer, URTWN_N_TRANSFER);
494	ieee80211_ifdetach(ic);
495
496	if_free(ifp);
497	mtx_destroy(&sc->sc_mtx);
498
499	return (0);
500}
501
502static void
503urtwn_free_tx_list(struct urtwn_softc *sc)
504{
505	urtwn_free_list(sc, sc->sc_tx, URTWN_TX_LIST_COUNT);
506}
507
508static void
509urtwn_free_rx_list(struct urtwn_softc *sc)
510{
511	urtwn_free_list(sc, sc->sc_rx, URTWN_RX_LIST_COUNT);
512}
513
514static void
515urtwn_free_list(struct urtwn_softc *sc, struct urtwn_data data[], int ndata)
516{
517	int i;
518
519	for (i = 0; i < ndata; i++) {
520		struct urtwn_data *dp = &data[i];
521
522		if (dp->buf != NULL) {
523			free(dp->buf, M_USBDEV);
524			dp->buf = NULL;
525		}
526		if (dp->ni != NULL) {
527			ieee80211_free_node(dp->ni);
528			dp->ni = NULL;
529		}
530	}
531}
532
533static usb_error_t
534urtwn_do_request(struct urtwn_softc *sc, struct usb_device_request *req,
535    void *data)
536{
537	usb_error_t err;
538	int ntries = 10;
539
540	URTWN_ASSERT_LOCKED(sc);
541
542	while (ntries--) {
543		err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
544		    req, data, 0, NULL, 250 /* ms */);
545		if (err == 0)
546			break;
547
548		DPRINTFN(1, "Control request failed, %s (retrying)\n",
549		    usbd_errstr(err));
550		usb_pause_mtx(&sc->sc_mtx, hz / 100);
551	}
552	return (err);
553}
554
555static struct ieee80211vap *
556urtwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
557    enum ieee80211_opmode opmode, int flags,
558    const uint8_t bssid[IEEE80211_ADDR_LEN],
559    const uint8_t mac[IEEE80211_ADDR_LEN])
560{
561	struct urtwn_vap *uvp;
562	struct ieee80211vap *vap;
563
564	if (!TAILQ_EMPTY(&ic->ic_vaps))		/* only one at a time */
565		return (NULL);
566
567	uvp = (struct urtwn_vap *) malloc(sizeof(struct urtwn_vap),
568	    M_80211_VAP, M_NOWAIT | M_ZERO);
569	if (uvp == NULL)
570		return (NULL);
571	vap = &uvp->vap;
572	/* enable s/w bmiss handling for sta mode */
573
574	if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
575	    flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
576		/* out of memory */
577		free(uvp, M_80211_VAP);
578		return (NULL);
579	}
580
581	/* override state transition machine */
582	uvp->newstate = vap->iv_newstate;
583	vap->iv_newstate = urtwn_newstate;
584
585	/* complete setup */
586	ieee80211_vap_attach(vap, ieee80211_media_change,
587	    ieee80211_media_status);
588	ic->ic_opmode = opmode;
589	return (vap);
590}
591
592static void
593urtwn_vap_delete(struct ieee80211vap *vap)
594{
595	struct urtwn_vap *uvp = URTWN_VAP(vap);
596
597	ieee80211_vap_detach(vap);
598	free(uvp, M_80211_VAP);
599}
600
601static struct mbuf *
602urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p)
603{
604	struct ifnet *ifp = sc->sc_ifp;
605	struct ieee80211com *ic = ifp->if_l2com;
606	struct ieee80211_frame *wh;
607	struct mbuf *m;
608	struct r92c_rx_stat *stat;
609	uint32_t rxdw0, rxdw3;
610	uint8_t rate;
611	int8_t rssi = 0;
612	int infosz;
613
614	/*
615	 * don't pass packets to the ieee80211 framework if the driver isn't
616	 * RUNNING.
617	 */
618	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
619		return (NULL);
620
621	stat = (struct r92c_rx_stat *)buf;
622	rxdw0 = le32toh(stat->rxdw0);
623	rxdw3 = le32toh(stat->rxdw3);
624
625	if (rxdw0 & (R92C_RXDW0_CRCERR | R92C_RXDW0_ICVERR)) {
626		/*
627		 * This should not happen since we setup our Rx filter
628		 * to not receive these frames.
629		 */
630		ifp->if_ierrors++;
631		return (NULL);
632	}
633
634	rate = MS(rxdw3, R92C_RXDW3_RATE);
635	infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
636
637	/* Get RSSI from PHY status descriptor if present. */
638	if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) {
639		rssi = urtwn_get_rssi(sc, rate, &stat[1]);
640		/* Update our average RSSI. */
641		urtwn_update_avgrssi(sc, rate, rssi);
642		/*
643		 * Convert the RSSI to a range that will be accepted
644		 * by net80211.
645		 */
646		rssi = URTWN_RSSI(rssi);
647	}
648
649	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
650	if (m == NULL) {
651		device_printf(sc->sc_dev, "could not create RX mbuf\n");
652		return (NULL);
653	}
654
655	/* Finalize mbuf. */
656	m->m_pkthdr.rcvif = ifp;
657	wh = (struct ieee80211_frame *)((uint8_t *)&stat[1] + infosz);
658	memcpy(mtod(m, uint8_t *), wh, pktlen);
659	m->m_pkthdr.len = m->m_len = pktlen;
660
661	if (ieee80211_radiotap_active(ic)) {
662		struct urtwn_rx_radiotap_header *tap = &sc->sc_rxtap;
663
664		tap->wr_flags = 0;
665		/* Map HW rate index to 802.11 rate. */
666		if (!(rxdw3 & R92C_RXDW3_HT)) {
667			switch (rate) {
668			/* CCK. */
669			case  0: tap->wr_rate =   2; break;
670			case  1: tap->wr_rate =   4; break;
671			case  2: tap->wr_rate =  11; break;
672			case  3: tap->wr_rate =  22; break;
673			/* OFDM. */
674			case  4: tap->wr_rate =  12; break;
675			case  5: tap->wr_rate =  18; break;
676			case  6: tap->wr_rate =  24; break;
677			case  7: tap->wr_rate =  36; break;
678			case  8: tap->wr_rate =  48; break;
679			case  9: tap->wr_rate =  72; break;
680			case 10: tap->wr_rate =  96; break;
681			case 11: tap->wr_rate = 108; break;
682			}
683		} else if (rate >= 12) {	/* MCS0~15. */
684			/* Bit 7 set means HT MCS instead of rate. */
685			tap->wr_rate = 0x80 | (rate - 12);
686		}
687		tap->wr_dbm_antsignal = rssi;
688		tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
689		tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
690	}
691
692	*rssi_p = rssi;
693
694	return (m);
695}
696
697static struct mbuf *
698urtwn_rxeof(struct usb_xfer *xfer, struct urtwn_data *data, int *rssi,
699    int8_t *nf)
700{
701	struct urtwn_softc *sc = data->sc;
702	struct ifnet *ifp = sc->sc_ifp;
703	struct r92c_rx_stat *stat;
704	struct mbuf *m, *m0 = NULL, *prevm = NULL;
705	uint32_t rxdw0;
706	uint8_t *buf;
707	int len, totlen, pktlen, infosz, npkts;
708
709	usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
710
711	if (len < sizeof(*stat)) {
712		ifp->if_ierrors++;
713		return (NULL);
714	}
715
716	buf = data->buf;
717	/* Get the number of encapsulated frames. */
718	stat = (struct r92c_rx_stat *)buf;
719	npkts = MS(le32toh(stat->rxdw2), R92C_RXDW2_PKTCNT);
720	DPRINTFN(6, "Rx %d frames in one chunk\n", npkts);
721
722	/* Process all of them. */
723	while (npkts-- > 0) {
724		if (len < sizeof(*stat))
725			break;
726		stat = (struct r92c_rx_stat *)buf;
727		rxdw0 = le32toh(stat->rxdw0);
728
729		pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN);
730		if (pktlen == 0)
731			break;
732
733		infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
734
735		/* Make sure everything fits in xfer. */
736		totlen = sizeof(*stat) + infosz + pktlen;
737		if (totlen > len)
738			break;
739
740		m = urtwn_rx_frame(sc, buf, pktlen, rssi);
741		if (m0 == NULL)
742			m0 = m;
743		if (prevm == NULL)
744			prevm = m;
745		else {
746			prevm->m_next = m;
747			prevm = m;
748		}
749
750		/* Next chunk is 128-byte aligned. */
751		totlen = (totlen + 127) & ~127;
752		buf += totlen;
753		len -= totlen;
754	}
755
756	return (m0);
757}
758
759static void
760urtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
761{
762	struct urtwn_softc *sc = usbd_xfer_softc(xfer);
763	struct ifnet *ifp = sc->sc_ifp;
764	struct ieee80211com *ic = ifp->if_l2com;
765	struct ieee80211_frame *wh;
766	struct ieee80211_node *ni;
767	struct mbuf *m = NULL, *next;
768	struct urtwn_data *data;
769	int8_t nf;
770	int rssi = 1;
771
772	URTWN_ASSERT_LOCKED(sc);
773
774	switch (USB_GET_STATE(xfer)) {
775	case USB_ST_TRANSFERRED:
776		data = STAILQ_FIRST(&sc->sc_rx_active);
777		if (data == NULL)
778			goto tr_setup;
779		STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
780		m = urtwn_rxeof(xfer, data, &rssi, &nf);
781		STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
782		/* FALLTHROUGH */
783	case USB_ST_SETUP:
784tr_setup:
785		data = STAILQ_FIRST(&sc->sc_rx_inactive);
786		if (data == NULL) {
787			KASSERT(m == NULL, ("mbuf isn't NULL"));
788			return;
789		}
790		STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
791		STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
792		usbd_xfer_set_frame_data(xfer, 0, data->buf,
793		    usbd_xfer_max_len(xfer));
794		usbd_transfer_submit(xfer);
795
796		/*
797		 * To avoid LOR we should unlock our private mutex here to call
798		 * ieee80211_input() because here is at the end of a USB
799		 * callback and safe to unlock.
800		 */
801		URTWN_UNLOCK(sc);
802		while (m != NULL) {
803			next = m->m_next;
804			m->m_next = NULL;
805			wh = mtod(m, struct ieee80211_frame *);
806			ni = ieee80211_find_rxnode(ic,
807			    (struct ieee80211_frame_min *)wh);
808			nf = URTWN_NOISE_FLOOR;
809			if (ni != NULL) {
810				(void)ieee80211_input(ni, m, rssi, nf);
811				ieee80211_free_node(ni);
812			} else
813				(void)ieee80211_input_all(ic, m, rssi, nf);
814			m = next;
815		}
816		URTWN_LOCK(sc);
817		break;
818	default:
819		/* needs it to the inactive queue due to a error. */
820		data = STAILQ_FIRST(&sc->sc_rx_active);
821		if (data != NULL) {
822			STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
823			STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
824		}
825		if (error != USB_ERR_CANCELLED) {
826			usbd_xfer_set_stall(xfer);
827			ifp->if_ierrors++;
828			goto tr_setup;
829		}
830		break;
831	}
832}
833
834static void
835urtwn_txeof(struct usb_xfer *xfer, struct urtwn_data *data)
836{
837	struct urtwn_softc *sc = usbd_xfer_softc(xfer);
838	struct ifnet *ifp = sc->sc_ifp;
839	struct mbuf *m;
840
841	URTWN_ASSERT_LOCKED(sc);
842
843	/*
844	 * Do any tx complete callback.  Note this must be done before releasing
845	 * the node reference.
846	 */
847	if (data->m) {
848		m = data->m;
849		if (m->m_flags & M_TXCB) {
850			/* XXX status? */
851			ieee80211_process_callback(data->ni, m, 0);
852		}
853		m_freem(m);
854		data->m = NULL;
855	}
856	if (data->ni) {
857		ieee80211_free_node(data->ni);
858		data->ni = NULL;
859	}
860	sc->sc_txtimer = 0;
861	ifp->if_opackets++;
862	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
863}
864
865static void
866urtwn_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
867{
868	struct urtwn_softc *sc = usbd_xfer_softc(xfer);
869	struct ifnet *ifp = sc->sc_ifp;
870	struct urtwn_data *data;
871
872	URTWN_ASSERT_LOCKED(sc);
873
874	switch (USB_GET_STATE(xfer)){
875	case USB_ST_TRANSFERRED:
876		data = STAILQ_FIRST(&sc->sc_tx_active);
877		if (data == NULL)
878			goto tr_setup;
879		STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next);
880		urtwn_txeof(xfer, data);
881		STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
882		/* FALLTHROUGH */
883	case USB_ST_SETUP:
884tr_setup:
885		data = STAILQ_FIRST(&sc->sc_tx_pending);
886		if (data == NULL) {
887			DPRINTF("%s: empty pending queue\n", __func__);
888			return;
889		}
890		STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next);
891		STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next);
892		usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
893		usbd_transfer_submit(xfer);
894		urtwn_start_locked(ifp, sc);
895		break;
896	default:
897		data = STAILQ_FIRST(&sc->sc_tx_active);
898		if (data == NULL)
899			goto tr_setup;
900		if (data->ni != NULL) {
901			ieee80211_free_node(data->ni);
902			data->ni = NULL;
903			ifp->if_oerrors++;
904		}
905		if (error != USB_ERR_CANCELLED) {
906			usbd_xfer_set_stall(xfer);
907			goto tr_setup;
908		}
909		break;
910	}
911}
912
913static struct urtwn_data *
914_urtwn_getbuf(struct urtwn_softc *sc)
915{
916	struct urtwn_data *bf;
917
918	bf = STAILQ_FIRST(&sc->sc_tx_inactive);
919	if (bf != NULL)
920		STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next);
921	else
922		bf = NULL;
923	if (bf == NULL)
924		DPRINTF("%s: %s\n", __func__, "out of xmit buffers");
925	return (bf);
926}
927
928static struct urtwn_data *
929urtwn_getbuf(struct urtwn_softc *sc)
930{
931        struct urtwn_data *bf;
932
933	URTWN_ASSERT_LOCKED(sc);
934
935	bf = _urtwn_getbuf(sc);
936	if (bf == NULL) {
937		struct ifnet *ifp = sc->sc_ifp;
938		DPRINTF("%s: stop queue\n", __func__);
939		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
940	}
941	return (bf);
942}
943
944static int
945urtwn_write_region_1(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf,
946    int len)
947{
948	usb_device_request_t req;
949
950	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
951	req.bRequest = R92C_REQ_REGS;
952	USETW(req.wValue, addr);
953	USETW(req.wIndex, 0);
954	USETW(req.wLength, len);
955	return (urtwn_do_request(sc, &req, buf));
956}
957
958static void
959urtwn_write_1(struct urtwn_softc *sc, uint16_t addr, uint8_t val)
960{
961	urtwn_write_region_1(sc, addr, &val, 1);
962}
963
964
965static void
966urtwn_write_2(struct urtwn_softc *sc, uint16_t addr, uint16_t val)
967{
968	val = htole16(val);
969	urtwn_write_region_1(sc, addr, (uint8_t *)&val, 2);
970}
971
972static void
973urtwn_write_4(struct urtwn_softc *sc, uint16_t addr, uint32_t val)
974{
975	val = htole32(val);
976	urtwn_write_region_1(sc, addr, (uint8_t *)&val, 4);
977}
978
979static int
980urtwn_read_region_1(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf,
981    int len)
982{
983	usb_device_request_t req;
984
985	req.bmRequestType = UT_READ_VENDOR_DEVICE;
986	req.bRequest = R92C_REQ_REGS;
987	USETW(req.wValue, addr);
988	USETW(req.wIndex, 0);
989	USETW(req.wLength, len);
990	return (urtwn_do_request(sc, &req, buf));
991}
992
993static uint8_t
994urtwn_read_1(struct urtwn_softc *sc, uint16_t addr)
995{
996	uint8_t val;
997
998	if (urtwn_read_region_1(sc, addr, &val, 1) != 0)
999		return (0xff);
1000	return (val);
1001}
1002
1003static uint16_t
1004urtwn_read_2(struct urtwn_softc *sc, uint16_t addr)
1005{
1006	uint16_t val;
1007
1008	if (urtwn_read_region_1(sc, addr, (uint8_t *)&val, 2) != 0)
1009		return (0xffff);
1010	return (le16toh(val));
1011}
1012
1013static uint32_t
1014urtwn_read_4(struct urtwn_softc *sc, uint16_t addr)
1015{
1016	uint32_t val;
1017
1018	if (urtwn_read_region_1(sc, addr, (uint8_t *)&val, 4) != 0)
1019		return (0xffffffff);
1020	return (le32toh(val));
1021}
1022
1023static int
1024urtwn_fw_cmd(struct urtwn_softc *sc, uint8_t id, const void *buf, int len)
1025{
1026	struct r92c_fw_cmd cmd;
1027	int ntries;
1028
1029	/* Wait for current FW box to be empty. */
1030	for (ntries = 0; ntries < 100; ntries++) {
1031		if (!(urtwn_read_1(sc, R92C_HMETFR) & (1 << sc->fwcur)))
1032			break;
1033		DELAY(1);
1034	}
1035	if (ntries == 100) {
1036		device_printf(sc->sc_dev,
1037		    "could not send firmware command\n");
1038		return (ETIMEDOUT);
1039	}
1040	memset(&cmd, 0, sizeof(cmd));
1041	cmd.id = id;
1042	if (len > 3)
1043		cmd.id |= R92C_CMD_FLAG_EXT;
1044	KASSERT(len <= sizeof(cmd.msg), ("urtwn_fw_cmd\n"));
1045	memcpy(cmd.msg, buf, len);
1046
1047	/* Write the first word last since that will trigger the FW. */
1048	urtwn_write_region_1(sc, R92C_HMEBOX_EXT(sc->fwcur),
1049	    (uint8_t *)&cmd + 4, 2);
1050	urtwn_write_region_1(sc, R92C_HMEBOX(sc->fwcur),
1051	    (uint8_t *)&cmd + 0, 4);
1052
1053	sc->fwcur = (sc->fwcur + 1) % R92C_H2C_NBOX;
1054	return (0);
1055}
1056
1057static void
1058urtwn_rf_write(struct urtwn_softc *sc, int chain, uint8_t addr, uint32_t val)
1059{
1060	urtwn_bb_write(sc, R92C_LSSI_PARAM(chain),
1061	    SM(R92C_LSSI_PARAM_ADDR, addr) |
1062	    SM(R92C_LSSI_PARAM_DATA, val));
1063}
1064
1065static uint32_t
1066urtwn_rf_read(struct urtwn_softc *sc, int chain, uint8_t addr)
1067{
1068	uint32_t reg[R92C_MAX_CHAINS], val;
1069
1070	reg[0] = urtwn_bb_read(sc, R92C_HSSI_PARAM2(0));
1071	if (chain != 0)
1072		reg[chain] = urtwn_bb_read(sc, R92C_HSSI_PARAM2(chain));
1073
1074	urtwn_bb_write(sc, R92C_HSSI_PARAM2(0),
1075	    reg[0] & ~R92C_HSSI_PARAM2_READ_EDGE);
1076	DELAY(1000);
1077
1078	urtwn_bb_write(sc, R92C_HSSI_PARAM2(chain),
1079	    RW(reg[chain], R92C_HSSI_PARAM2_READ_ADDR, addr) |
1080	    R92C_HSSI_PARAM2_READ_EDGE);
1081	DELAY(1000);
1082
1083	urtwn_bb_write(sc, R92C_HSSI_PARAM2(0),
1084	    reg[0] | R92C_HSSI_PARAM2_READ_EDGE);
1085	DELAY(1000);
1086
1087	if (urtwn_bb_read(sc, R92C_HSSI_PARAM1(chain)) & R92C_HSSI_PARAM1_PI)
1088		val = urtwn_bb_read(sc, R92C_HSPI_READBACK(chain));
1089	else
1090		val = urtwn_bb_read(sc, R92C_LSSI_READBACK(chain));
1091	return (MS(val, R92C_LSSI_READBACK_DATA));
1092}
1093
1094static int
1095urtwn_llt_write(struct urtwn_softc *sc, uint32_t addr, uint32_t data)
1096{
1097	int ntries;
1098
1099	urtwn_write_4(sc, R92C_LLT_INIT,
1100	    SM(R92C_LLT_INIT_OP, R92C_LLT_INIT_OP_WRITE) |
1101	    SM(R92C_LLT_INIT_ADDR, addr) |
1102	    SM(R92C_LLT_INIT_DATA, data));
1103	/* Wait for write operation to complete. */
1104	for (ntries = 0; ntries < 20; ntries++) {
1105		if (MS(urtwn_read_4(sc, R92C_LLT_INIT), R92C_LLT_INIT_OP) ==
1106		    R92C_LLT_INIT_OP_NO_ACTIVE)
1107			return (0);
1108		DELAY(5);
1109	}
1110	return (ETIMEDOUT);
1111}
1112
1113static uint8_t
1114urtwn_efuse_read_1(struct urtwn_softc *sc, uint16_t addr)
1115{
1116	uint32_t reg;
1117	int ntries;
1118
1119	reg = urtwn_read_4(sc, R92C_EFUSE_CTRL);
1120	reg = RW(reg, R92C_EFUSE_CTRL_ADDR, addr);
1121	reg &= ~R92C_EFUSE_CTRL_VALID;
1122	urtwn_write_4(sc, R92C_EFUSE_CTRL, reg);
1123	/* Wait for read operation to complete. */
1124	for (ntries = 0; ntries < 100; ntries++) {
1125		reg = urtwn_read_4(sc, R92C_EFUSE_CTRL);
1126		if (reg & R92C_EFUSE_CTRL_VALID)
1127			return (MS(reg, R92C_EFUSE_CTRL_DATA));
1128		DELAY(5);
1129	}
1130	device_printf(sc->sc_dev,
1131	    "could not read efuse byte at address 0x%x\n", addr);
1132	return (0xff);
1133}
1134
1135static void
1136urtwn_efuse_read(struct urtwn_softc *sc)
1137{
1138	uint8_t *rom = (uint8_t *)&sc->rom;
1139	uint16_t addr = 0;
1140	uint32_t reg;
1141	uint8_t off, msk;
1142	int i;
1143
1144	reg = urtwn_read_2(sc, R92C_SYS_ISO_CTRL);
1145	if (!(reg & R92C_SYS_ISO_CTRL_PWC_EV12V)) {
1146		urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
1147		    reg | R92C_SYS_ISO_CTRL_PWC_EV12V);
1148	}
1149	reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
1150	if (!(reg & R92C_SYS_FUNC_EN_ELDR)) {
1151		urtwn_write_2(sc, R92C_SYS_FUNC_EN,
1152		    reg | R92C_SYS_FUNC_EN_ELDR);
1153	}
1154	reg = urtwn_read_2(sc, R92C_SYS_CLKR);
1155	if ((reg & (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) !=
1156	    (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) {
1157		urtwn_write_2(sc, R92C_SYS_CLKR,
1158		    reg | R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M);
1159	}
1160	memset(&sc->rom, 0xff, sizeof(sc->rom));
1161	while (addr < 512) {
1162		reg = urtwn_efuse_read_1(sc, addr);
1163		if (reg == 0xff)
1164			break;
1165		addr++;
1166		off = reg >> 4;
1167		msk = reg & 0xf;
1168		for (i = 0; i < 4; i++) {
1169			if (msk & (1 << i))
1170				continue;
1171			rom[off * 8 + i * 2 + 0] =
1172			    urtwn_efuse_read_1(sc, addr);
1173			addr++;
1174			rom[off * 8 + i * 2 + 1] =
1175			    urtwn_efuse_read_1(sc, addr);
1176			addr++;
1177		}
1178	}
1179#ifdef URTWN_DEBUG
1180	if (urtwn_debug >= 2) {
1181		/* Dump ROM content. */
1182		printf("\n");
1183		for (i = 0; i < sizeof(sc->rom); i++)
1184			printf("%02x:", rom[i]);
1185		printf("\n");
1186	}
1187#endif
1188}
1189
1190static int
1191urtwn_read_chipid(struct urtwn_softc *sc)
1192{
1193	uint32_t reg;
1194
1195	reg = urtwn_read_4(sc, R92C_SYS_CFG);
1196	if (reg & R92C_SYS_CFG_TRP_VAUX_EN)
1197		return (EIO);
1198
1199	if (reg & R92C_SYS_CFG_TYPE_92C) {
1200		sc->chip |= URTWN_CHIP_92C;
1201		/* Check if it is a castrated 8192C. */
1202		if (MS(urtwn_read_4(sc, R92C_HPON_FSM),
1203		    R92C_HPON_FSM_CHIP_BONDING_ID) ==
1204		    R92C_HPON_FSM_CHIP_BONDING_ID_92C_1T2R)
1205			sc->chip |= URTWN_CHIP_92C_1T2R;
1206	}
1207	if (reg & R92C_SYS_CFG_VENDOR_UMC) {
1208		sc->chip |= URTWN_CHIP_UMC;
1209		if (MS(reg, R92C_SYS_CFG_CHIP_VER_RTL) == 0)
1210			sc->chip |= URTWN_CHIP_UMC_A_CUT;
1211	}
1212	return (0);
1213}
1214
1215static void
1216urtwn_read_rom(struct urtwn_softc *sc)
1217{
1218	struct r92c_rom *rom = &sc->rom;
1219
1220	/* Read full ROM image. */
1221	urtwn_efuse_read(sc);
1222
1223	/* XXX Weird but this is what the vendor driver does. */
1224	sc->pa_setting = urtwn_efuse_read_1(sc, 0x1fa);
1225	DPRINTF("PA setting=0x%x\n", sc->pa_setting);
1226
1227	sc->board_type = MS(rom->rf_opt1, R92C_ROM_RF1_BOARD_TYPE);
1228
1229	sc->regulatory = MS(rom->rf_opt1, R92C_ROM_RF1_REGULATORY);
1230	DPRINTF("regulatory type=%d\n", sc->regulatory);
1231
1232	IEEE80211_ADDR_COPY(sc->sc_bssid, rom->macaddr);
1233}
1234
1235/*
1236 * Initialize rate adaptation in firmware.
1237 */
1238static int
1239urtwn_ra_init(struct urtwn_softc *sc)
1240{
1241	static const uint8_t map[] =
1242	    { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
1243	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
1244	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1245	struct ieee80211_node *ni;
1246	struct ieee80211_rateset *rs;
1247	struct r92c_fw_cmd_macid_cfg cmd;
1248	uint32_t rates, basicrates;
1249	uint8_t mode;
1250	int maxrate, maxbasicrate, error, i, j;
1251
1252	ni = ieee80211_ref_node(vap->iv_bss);
1253	rs = &ni->ni_rates;
1254
1255	/* Get normal and basic rates mask. */
1256	rates = basicrates = 0;
1257	maxrate = maxbasicrate = 0;
1258	for (i = 0; i < rs->rs_nrates; i++) {
1259		/* Convert 802.11 rate to HW rate index. */
1260		for (j = 0; j < nitems(map); j++)
1261			if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == map[j])
1262				break;
1263		if (j == nitems(map))	/* Unknown rate, skip. */
1264			continue;
1265		rates |= 1 << j;
1266		if (j > maxrate)
1267			maxrate = j;
1268		if (rs->rs_rates[i] & IEEE80211_RATE_BASIC) {
1269			basicrates |= 1 << j;
1270			if (j > maxbasicrate)
1271				maxbasicrate = j;
1272		}
1273	}
1274	if (ic->ic_curmode == IEEE80211_MODE_11B)
1275		mode = R92C_RAID_11B;
1276	else
1277		mode = R92C_RAID_11BG;
1278	DPRINTF("mode=0x%x rates=0x%08x, basicrates=0x%08x\n",
1279	    mode, rates, basicrates);
1280
1281	/* Set rates mask for group addressed frames. */
1282	cmd.macid = URTWN_MACID_BC | URTWN_MACID_VALID;
1283	cmd.mask = htole32(mode << 28 | basicrates);
1284	error = urtwn_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd));
1285	if (error != 0) {
1286		ieee80211_free_node(ni);
1287		device_printf(sc->sc_dev,
1288		    "could not add broadcast station\n");
1289		return (error);
1290	}
1291	/* Set initial MRR rate. */
1292	DPRINTF("maxbasicrate=%d\n", maxbasicrate);
1293	urtwn_write_1(sc, R92C_INIDATA_RATE_SEL(URTWN_MACID_BC),
1294	    maxbasicrate);
1295
1296	/* Set rates mask for unicast frames. */
1297	cmd.macid = URTWN_MACID_BSS | URTWN_MACID_VALID;
1298	cmd.mask = htole32(mode << 28 | rates);
1299	error = urtwn_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd));
1300	if (error != 0) {
1301		ieee80211_free_node(ni);
1302		device_printf(sc->sc_dev, "could not add BSS station\n");
1303		return (error);
1304	}
1305	/* Set initial MRR rate. */
1306	DPRINTF("maxrate=%d\n", maxrate);
1307	urtwn_write_1(sc, R92C_INIDATA_RATE_SEL(URTWN_MACID_BSS),
1308	    maxrate);
1309
1310	/* Indicate highest supported rate. */
1311	ni->ni_txrate = rs->rs_rates[rs->rs_nrates - 1];
1312	ieee80211_free_node(ni);
1313
1314	return (0);
1315}
1316
1317void
1318urtwn_tsf_sync_enable(struct urtwn_softc *sc)
1319{
1320	struct ifnet *ifp = sc->sc_ifp;
1321	struct ieee80211com *ic = ifp->if_l2com;
1322	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1323	struct ieee80211_node *ni = vap->iv_bss;
1324
1325	uint64_t tsf;
1326
1327	/* Enable TSF synchronization. */
1328	urtwn_write_1(sc, R92C_BCN_CTRL,
1329	    urtwn_read_1(sc, R92C_BCN_CTRL) & ~R92C_BCN_CTRL_DIS_TSF_UDT0);
1330
1331	urtwn_write_1(sc, R92C_BCN_CTRL,
1332	    urtwn_read_1(sc, R92C_BCN_CTRL) & ~R92C_BCN_CTRL_EN_BCN);
1333
1334	/* Set initial TSF. */
1335	memcpy(&tsf, ni->ni_tstamp.data, 8);
1336	tsf = le64toh(tsf);
1337	tsf = tsf - (tsf % (vap->iv_bss->ni_intval * IEEE80211_DUR_TU));
1338	tsf -= IEEE80211_DUR_TU;
1339	urtwn_write_4(sc, R92C_TSFTR + 0, tsf);
1340	urtwn_write_4(sc, R92C_TSFTR + 4, tsf >> 32);
1341
1342	urtwn_write_1(sc, R92C_BCN_CTRL,
1343	    urtwn_read_1(sc, R92C_BCN_CTRL) | R92C_BCN_CTRL_EN_BCN);
1344}
1345
1346static void
1347urtwn_set_led(struct urtwn_softc *sc, int led, int on)
1348{
1349	uint8_t reg;
1350
1351	if (led == URTWN_LED_LINK) {
1352		reg = urtwn_read_1(sc, R92C_LEDCFG0) & 0x70;
1353		if (!on)
1354			reg |= R92C_LEDCFG0_DIS;
1355		urtwn_write_1(sc, R92C_LEDCFG0, reg);
1356		sc->ledlink = on;	/* Save LED state. */
1357	}
1358}
1359
1360static int
1361urtwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1362{
1363	struct urtwn_vap *uvp = URTWN_VAP(vap);
1364	struct ieee80211com *ic = vap->iv_ic;
1365	struct urtwn_softc *sc = ic->ic_ifp->if_softc;
1366	struct ieee80211_node *ni;
1367	enum ieee80211_state ostate;
1368	uint32_t reg;
1369
1370	ostate = vap->iv_state;
1371	DPRINTF("%s -> %s\n", ieee80211_state_name[ostate],
1372	    ieee80211_state_name[nstate]);
1373
1374	IEEE80211_UNLOCK(ic);
1375	URTWN_LOCK(sc);
1376	callout_stop(&sc->sc_watchdog_ch);
1377
1378	if (ostate == IEEE80211_S_RUN) {
1379		/* Turn link LED off. */
1380		urtwn_set_led(sc, URTWN_LED_LINK, 0);
1381
1382		/* Set media status to 'No Link'. */
1383		reg = urtwn_read_4(sc, R92C_CR);
1384		reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_NOLINK);
1385		urtwn_write_4(sc, R92C_CR, reg);
1386
1387		/* Stop Rx of data frames. */
1388		urtwn_write_2(sc, R92C_RXFLTMAP2, 0);
1389
1390		/* Rest TSF. */
1391		urtwn_write_1(sc, R92C_DUAL_TSF_RST, 0x03);
1392
1393		/* Disable TSF synchronization. */
1394		urtwn_write_1(sc, R92C_BCN_CTRL,
1395		    urtwn_read_1(sc, R92C_BCN_CTRL) |
1396		    R92C_BCN_CTRL_DIS_TSF_UDT0);
1397
1398		/* Reset EDCA parameters. */
1399		urtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002f3217);
1400		urtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005e4317);
1401		urtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x00105320);
1402		urtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a444);
1403	}
1404
1405	switch (nstate) {
1406	case IEEE80211_S_INIT:
1407		/* Turn link LED off. */
1408		urtwn_set_led(sc, URTWN_LED_LINK, 0);
1409		break;
1410	case IEEE80211_S_SCAN:
1411		if (ostate != IEEE80211_S_SCAN) {
1412			/* Allow Rx from any BSSID. */
1413			urtwn_write_4(sc, R92C_RCR,
1414			    urtwn_read_4(sc, R92C_RCR) &
1415			    ~(R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN));
1416
1417			/* Set gain for scanning. */
1418			reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0));
1419			reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
1420			urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg);
1421
1422			reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
1423			reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
1424			urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
1425		}
1426
1427		/* Make link LED blink during scan. */
1428		urtwn_set_led(sc, URTWN_LED_LINK, !sc->ledlink);
1429
1430		/* Pause AC Tx queues. */
1431		urtwn_write_1(sc, R92C_TXPAUSE,
1432		    urtwn_read_1(sc, R92C_TXPAUSE) | 0x0f);
1433
1434		urtwn_set_chan(sc, ic->ic_curchan, NULL);
1435		break;
1436	case IEEE80211_S_AUTH:
1437		/* Set initial gain under link. */
1438		reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0));
1439		reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
1440		urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg);
1441
1442		reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
1443		reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
1444		urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
1445
1446		urtwn_set_chan(sc, ic->ic_curchan, NULL);
1447		break;
1448	case IEEE80211_S_RUN:
1449		if (vap->iv_opmode == IEEE80211_M_MONITOR) {
1450			/* Enable Rx of data frames. */
1451			urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff);
1452
1453			/* Turn link LED on. */
1454			urtwn_set_led(sc, URTWN_LED_LINK, 1);
1455			break;
1456		}
1457
1458		ni = ieee80211_ref_node(vap->iv_bss);
1459		/* Set media status to 'Associated'. */
1460		reg = urtwn_read_4(sc, R92C_CR);
1461		reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_INFRA);
1462		urtwn_write_4(sc, R92C_CR, reg);
1463
1464		/* Set BSSID. */
1465		urtwn_write_4(sc, R92C_BSSID + 0, LE_READ_4(&ni->ni_bssid[0]));
1466		urtwn_write_4(sc, R92C_BSSID + 4, LE_READ_2(&ni->ni_bssid[4]));
1467
1468		if (ic->ic_curmode == IEEE80211_MODE_11B)
1469			urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 0);
1470		else	/* 802.11b/g */
1471			urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 3);
1472
1473		/* Enable Rx of data frames. */
1474		urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff);
1475
1476		/* Flush all AC queues. */
1477		urtwn_write_1(sc, R92C_TXPAUSE, 0);
1478
1479		/* Set beacon interval. */
1480		urtwn_write_2(sc, R92C_BCN_INTERVAL, ni->ni_intval);
1481
1482		/* Allow Rx from our BSSID only. */
1483		urtwn_write_4(sc, R92C_RCR,
1484		    urtwn_read_4(sc, R92C_RCR) |
1485		    R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN);
1486
1487		/* Enable TSF synchronization. */
1488		urtwn_tsf_sync_enable(sc);
1489
1490		urtwn_write_1(sc, R92C_SIFS_CCK + 1, 10);
1491		urtwn_write_1(sc, R92C_SIFS_OFDM + 1, 10);
1492		urtwn_write_1(sc, R92C_SPEC_SIFS + 1, 10);
1493		urtwn_write_1(sc, R92C_MAC_SPEC_SIFS + 1, 10);
1494		urtwn_write_1(sc, R92C_R2T_SIFS + 1, 10);
1495		urtwn_write_1(sc, R92C_T2T_SIFS + 1, 10);
1496
1497		/* Intialize rate adaptation. */
1498		urtwn_ra_init(sc);
1499		/* Turn link LED on. */
1500		urtwn_set_led(sc, URTWN_LED_LINK, 1);
1501
1502		sc->avg_pwdb = -1;	/* Reset average RSSI. */
1503		/* Reset temperature calibration state machine. */
1504		sc->thcal_state = 0;
1505		sc->thcal_lctemp = 0;
1506		ieee80211_free_node(ni);
1507		break;
1508	default:
1509		break;
1510	}
1511	URTWN_UNLOCK(sc);
1512	IEEE80211_LOCK(ic);
1513	return(uvp->newstate(vap, nstate, arg));
1514}
1515
1516static void
1517urtwn_watchdog(void *arg)
1518{
1519	struct urtwn_softc *sc = arg;
1520	struct ifnet *ifp = sc->sc_ifp;
1521
1522	if (sc->sc_txtimer > 0) {
1523		if (--sc->sc_txtimer == 0) {
1524			device_printf(sc->sc_dev, "device timeout\n");
1525			ifp->if_oerrors++;
1526			return;
1527		}
1528		callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc);
1529	}
1530}
1531
1532static void
1533urtwn_update_avgrssi(struct urtwn_softc *sc, int rate, int8_t rssi)
1534{
1535	int pwdb;
1536
1537	/* Convert antenna signal to percentage. */
1538	if (rssi <= -100 || rssi >= 20)
1539		pwdb = 0;
1540	else if (rssi >= 0)
1541		pwdb = 100;
1542	else
1543		pwdb = 100 + rssi;
1544	if (rate <= 3) {
1545		/* CCK gain is smaller than OFDM/MCS gain. */
1546		pwdb += 6;
1547		if (pwdb > 100)
1548			pwdb = 100;
1549		if (pwdb <= 14)
1550			pwdb -= 4;
1551		else if (pwdb <= 26)
1552			pwdb -= 8;
1553		else if (pwdb <= 34)
1554			pwdb -= 6;
1555		else if (pwdb <= 42)
1556			pwdb -= 2;
1557	}
1558	if (sc->avg_pwdb == -1)	/* Init. */
1559		sc->avg_pwdb = pwdb;
1560	else if (sc->avg_pwdb < pwdb)
1561		sc->avg_pwdb = ((sc->avg_pwdb * 19 + pwdb) / 20) + 1;
1562	else
1563		sc->avg_pwdb = ((sc->avg_pwdb * 19 + pwdb) / 20);
1564	DPRINTFN(4, "PWDB=%d EMA=%d\n", pwdb, sc->avg_pwdb);
1565}
1566
1567static int8_t
1568urtwn_get_rssi(struct urtwn_softc *sc, int rate, void *physt)
1569{
1570	static const int8_t cckoff[] = { 16, -12, -26, -46 };
1571	struct r92c_rx_phystat *phy;
1572	struct r92c_rx_cck *cck;
1573	uint8_t rpt;
1574	int8_t rssi;
1575
1576	if (rate <= 3) {
1577		cck = (struct r92c_rx_cck *)physt;
1578		if (sc->sc_flags & URTWN_FLAG_CCK_HIPWR) {
1579			rpt = (cck->agc_rpt >> 5) & 0x3;
1580			rssi = (cck->agc_rpt & 0x1f) << 1;
1581		} else {
1582			rpt = (cck->agc_rpt >> 6) & 0x3;
1583			rssi = cck->agc_rpt & 0x3e;
1584		}
1585		rssi = cckoff[rpt] - rssi;
1586	} else {	/* OFDM/HT. */
1587		phy = (struct r92c_rx_phystat *)physt;
1588		rssi = ((le32toh(phy->phydw1) >> 1) & 0x7f) - 110;
1589	}
1590	return (rssi);
1591}
1592
1593static int
1594urtwn_tx_start(struct urtwn_softc *sc, struct ieee80211_node *ni,
1595    struct mbuf *m0, struct urtwn_data *data)
1596{
1597	struct ifnet *ifp = sc->sc_ifp;
1598	struct ieee80211_frame *wh;
1599	struct ieee80211_key *k;
1600	struct ieee80211com *ic = ifp->if_l2com;
1601	struct ieee80211vap *vap = ni->ni_vap;
1602	struct usb_xfer *xfer;
1603	struct r92c_tx_desc *txd;
1604	uint8_t raid, type;
1605	uint16_t sum;
1606	int i, hasqos, xferlen;
1607	struct usb_xfer *urtwn_pipes[4] = {
1608		sc->sc_xfer[URTWN_BULK_TX_BE],
1609		sc->sc_xfer[URTWN_BULK_TX_BK],
1610		sc->sc_xfer[URTWN_BULK_TX_VI],
1611		sc->sc_xfer[URTWN_BULK_TX_VO]
1612	};
1613
1614	URTWN_ASSERT_LOCKED(sc);
1615
1616	/*
1617	 * Software crypto.
1618	 */
1619	wh = mtod(m0, struct ieee80211_frame *);
1620	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1621		k = ieee80211_crypto_encap(ni, m0);
1622		if (k == NULL) {
1623			device_printf(sc->sc_dev,
1624			    "ieee80211_crypto_encap returns NULL.\n");
1625			/* XXX we don't expect the fragmented frames */
1626			m_freem(m0);
1627			return (ENOBUFS);
1628		}
1629
1630		/* in case packet header moved, reset pointer */
1631		wh = mtod(m0, struct ieee80211_frame *);
1632	}
1633
1634	switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
1635	case IEEE80211_FC0_TYPE_CTL:
1636	case IEEE80211_FC0_TYPE_MGT:
1637		xfer = sc->sc_xfer[URTWN_BULK_TX_VO];
1638		break;
1639	default:
1640		KASSERT(M_WME_GETAC(m0) < 4,
1641		    ("unsupported WME pipe %d", M_WME_GETAC(m0)));
1642		xfer = urtwn_pipes[M_WME_GETAC(m0)];
1643		break;
1644	}
1645
1646	hasqos = 0;
1647
1648	/* Fill Tx descriptor. */
1649	txd = (struct r92c_tx_desc *)data->buf;
1650	memset(txd, 0, sizeof(*txd));
1651
1652	txd->txdw0 |= htole32(
1653	    SM(R92C_TXDW0_PKTLEN, m0->m_pkthdr.len) |
1654	    SM(R92C_TXDW0_OFFSET, sizeof(*txd)) |
1655	    R92C_TXDW0_OWN | R92C_TXDW0_FSG | R92C_TXDW0_LSG);
1656	if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1657		txd->txdw0 |= htole32(R92C_TXDW0_BMCAST);
1658
1659	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1660	if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
1661	    type == IEEE80211_FC0_TYPE_DATA) {
1662		if (ic->ic_curmode == IEEE80211_MODE_11B)
1663			raid = R92C_RAID_11B;
1664		else
1665			raid = R92C_RAID_11BG;
1666		txd->txdw1 |= htole32(
1667		    SM(R92C_TXDW1_MACID, URTWN_MACID_BSS) |
1668		    SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BE) |
1669		    SM(R92C_TXDW1_RAID, raid) |
1670		    R92C_TXDW1_AGGBK);
1671
1672		if (ic->ic_flags & IEEE80211_F_USEPROT) {
1673			if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
1674				txd->txdw4 |= htole32(R92C_TXDW4_CTS2SELF |
1675				    R92C_TXDW4_HWRTSEN);
1676			} else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) {
1677				txd->txdw4 |= htole32(R92C_TXDW4_RTSEN |
1678				    R92C_TXDW4_HWRTSEN);
1679			}
1680		}
1681		/* Send RTS at OFDM24. */
1682		txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, 8));
1683		txd->txdw5 |= htole32(0x0001ff00);
1684		/* Send data at OFDM54. */
1685		txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11));
1686	} else {
1687		txd->txdw1 |= htole32(
1688		    SM(R92C_TXDW1_MACID, 0) |
1689		    SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_MGNT) |
1690		    SM(R92C_TXDW1_RAID, R92C_RAID_11B));
1691
1692		/* Force CCK1. */
1693		txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
1694		txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 0));
1695	}
1696	/* Set sequence number (already little endian). */
1697	txd->txdseq |= *(uint16_t *)wh->i_seq;
1698
1699	if (!hasqos) {
1700		/* Use HW sequence numbering for non-QoS frames. */
1701		txd->txdw4  |= htole32(R92C_TXDW4_HWSEQ);
1702		txd->txdseq |= htole16(0x8000);
1703	} else
1704		txd->txdw4 |= htole32(R92C_TXDW4_QOS);
1705
1706	/* Compute Tx descriptor checksum. */
1707	sum = 0;
1708	for (i = 0; i < sizeof(*txd) / 2; i++)
1709		sum ^= ((uint16_t *)txd)[i];
1710	txd->txdsum = sum; 	/* NB: already little endian. */
1711
1712	if (ieee80211_radiotap_active_vap(vap)) {
1713		struct urtwn_tx_radiotap_header *tap = &sc->sc_txtap;
1714
1715		tap->wt_flags = 0;
1716		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
1717		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
1718		ieee80211_radiotap_tx(vap, m0);
1719	}
1720
1721	xferlen = sizeof(*txd) + m0->m_pkthdr.len;
1722	m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&txd[1]);
1723
1724	data->buflen = xferlen;
1725	data->ni = ni;
1726	data->m = m0;
1727
1728	STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next);
1729	usbd_transfer_start(xfer);
1730	return (0);
1731}
1732
1733static void
1734urtwn_start(struct ifnet *ifp)
1735{
1736	struct urtwn_softc *sc = ifp->if_softc;
1737
1738	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1739		return;
1740	URTWN_LOCK(sc);
1741	urtwn_start_locked(ifp, sc);
1742	URTWN_UNLOCK(sc);
1743}
1744
1745static void
1746urtwn_start_locked(struct ifnet *ifp, struct urtwn_softc *sc)
1747{
1748	struct ieee80211_node *ni;
1749	struct mbuf *m;
1750	struct urtwn_data *bf;
1751
1752	URTWN_ASSERT_LOCKED(sc);
1753	for (;;) {
1754		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1755		if (m == NULL)
1756			break;
1757		bf = urtwn_getbuf(sc);
1758		if (bf == NULL) {
1759			IFQ_DRV_PREPEND(&ifp->if_snd, m);
1760			break;
1761		}
1762		ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
1763		m->m_pkthdr.rcvif = NULL;
1764
1765		if (urtwn_tx_start(sc, ni, m, bf) != 0) {
1766			ifp->if_oerrors++;
1767			STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
1768			ieee80211_free_node(ni);
1769			break;
1770		}
1771
1772		sc->sc_txtimer = 5;
1773		callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc);
1774	}
1775}
1776
1777static int
1778urtwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1779{
1780	struct urtwn_softc *sc = ifp->if_softc;
1781	struct ieee80211com *ic = ifp->if_l2com;
1782	struct ifreq *ifr = (struct ifreq *) data;
1783	int error = 0, startall = 0;
1784
1785	URTWN_LOCK(sc);
1786	error = (sc->sc_flags & URTWN_DETACHED) ? ENXIO : 0;
1787	URTWN_UNLOCK(sc);
1788	if (error != 0)
1789		return (error);
1790
1791	switch (cmd) {
1792	case SIOCSIFFLAGS:
1793		if (ifp->if_flags & IFF_UP) {
1794			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
1795				urtwn_init(ifp->if_softc);
1796				startall = 1;
1797			}
1798		} else {
1799			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1800				urtwn_stop(ifp);
1801		}
1802		if (startall)
1803			ieee80211_start_all(ic);
1804		break;
1805	case SIOCGIFMEDIA:
1806		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1807		break;
1808	case SIOCGIFADDR:
1809		error = ether_ioctl(ifp, cmd, data);
1810		break;
1811	default:
1812		error = EINVAL;
1813		break;
1814	}
1815	return (error);
1816}
1817
1818static int
1819urtwn_alloc_list(struct urtwn_softc *sc, struct urtwn_data data[],
1820    int ndata, int maxsz)
1821{
1822	int i, error;
1823
1824	for (i = 0; i < ndata; i++) {
1825		struct urtwn_data *dp = &data[i];
1826		dp->sc = sc;
1827		dp->m = NULL;
1828		dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT);
1829		if (dp->buf == NULL) {
1830			device_printf(sc->sc_dev,
1831			    "could not allocate buffer\n");
1832			error = ENOMEM;
1833			goto fail;
1834		}
1835		dp->ni = NULL;
1836	}
1837
1838	return (0);
1839fail:
1840	urtwn_free_list(sc, data, ndata);
1841	return (error);
1842}
1843
1844static int
1845urtwn_alloc_rx_list(struct urtwn_softc *sc)
1846{
1847        int error, i;
1848
1849	error = urtwn_alloc_list(sc, sc->sc_rx, URTWN_RX_LIST_COUNT,
1850	    URTWN_RXBUFSZ);
1851	if (error != 0)
1852		return (error);
1853
1854	STAILQ_INIT(&sc->sc_rx_active);
1855	STAILQ_INIT(&sc->sc_rx_inactive);
1856
1857	for (i = 0; i < URTWN_RX_LIST_COUNT; i++)
1858		STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], next);
1859
1860	return (0);
1861}
1862
1863static int
1864urtwn_alloc_tx_list(struct urtwn_softc *sc)
1865{
1866	int error, i;
1867
1868	error = urtwn_alloc_list(sc, sc->sc_tx, URTWN_TX_LIST_COUNT,
1869	    URTWN_TXBUFSZ);
1870	if (error != 0)
1871		return (error);
1872
1873	STAILQ_INIT(&sc->sc_tx_active);
1874	STAILQ_INIT(&sc->sc_tx_inactive);
1875	STAILQ_INIT(&sc->sc_tx_pending);
1876
1877	for (i = 0; i < URTWN_TX_LIST_COUNT; i++)
1878		STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i], next);
1879
1880	return (0);
1881}
1882
1883static int
1884urtwn_power_on(struct urtwn_softc *sc)
1885{
1886	uint32_t reg;
1887	int ntries;
1888
1889	/* Wait for autoload done bit. */
1890	for (ntries = 0; ntries < 1000; ntries++) {
1891		if (urtwn_read_1(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_PFM_ALDN)
1892			break;
1893		DELAY(5);
1894	}
1895	if (ntries == 1000) {
1896		device_printf(sc->sc_dev,
1897		    "timeout waiting for chip autoload\n");
1898		return (ETIMEDOUT);
1899	}
1900
1901	/* Unlock ISO/CLK/Power control register. */
1902	urtwn_write_1(sc, R92C_RSV_CTRL, 0);
1903	/* Move SPS into PWM mode. */
1904	urtwn_write_1(sc, R92C_SPS0_CTRL, 0x2b);
1905	DELAY(100);
1906
1907	reg = urtwn_read_1(sc, R92C_LDOV12D_CTRL);
1908	if (!(reg & R92C_LDOV12D_CTRL_LDV12_EN)) {
1909		urtwn_write_1(sc, R92C_LDOV12D_CTRL,
1910		    reg | R92C_LDOV12D_CTRL_LDV12_EN);
1911		DELAY(100);
1912		urtwn_write_1(sc, R92C_SYS_ISO_CTRL,
1913		    urtwn_read_1(sc, R92C_SYS_ISO_CTRL) &
1914		    ~R92C_SYS_ISO_CTRL_MD2PP);
1915	}
1916
1917	/* Auto enable WLAN. */
1918	urtwn_write_2(sc, R92C_APS_FSMCO,
1919	    urtwn_read_2(sc, R92C_APS_FSMCO) | R92C_APS_FSMCO_APFM_ONMAC);
1920	for (ntries = 0; ntries < 1000; ntries++) {
1921		if (!(urtwn_read_2(sc, R92C_APS_FSMCO) &
1922		    R92C_APS_FSMCO_APFM_ONMAC))
1923			break;
1924		DELAY(5);
1925	}
1926	if (ntries == 1000) {
1927		device_printf(sc->sc_dev,
1928		    "timeout waiting for MAC auto ON\n");
1929		return (ETIMEDOUT);
1930	}
1931
1932	/* Enable radio, GPIO and LED functions. */
1933	urtwn_write_2(sc, R92C_APS_FSMCO,
1934	    R92C_APS_FSMCO_AFSM_HSUS |
1935	    R92C_APS_FSMCO_PDN_EN |
1936	    R92C_APS_FSMCO_PFM_ALDN);
1937	/* Release RF digital isolation. */
1938	urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
1939	    urtwn_read_2(sc, R92C_SYS_ISO_CTRL) & ~R92C_SYS_ISO_CTRL_DIOR);
1940
1941	/* Initialize MAC. */
1942	urtwn_write_1(sc, R92C_APSD_CTRL,
1943	    urtwn_read_1(sc, R92C_APSD_CTRL) & ~R92C_APSD_CTRL_OFF);
1944	for (ntries = 0; ntries < 200; ntries++) {
1945		if (!(urtwn_read_1(sc, R92C_APSD_CTRL) &
1946		    R92C_APSD_CTRL_OFF_STATUS))
1947			break;
1948		DELAY(5);
1949	}
1950	if (ntries == 200) {
1951		device_printf(sc->sc_dev,
1952		    "timeout waiting for MAC initialization\n");
1953		return (ETIMEDOUT);
1954	}
1955
1956	/* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
1957	reg = urtwn_read_2(sc, R92C_CR);
1958	reg |= R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN |
1959	    R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | R92C_CR_PROTOCOL_EN |
1960	    R92C_CR_SCHEDULE_EN | R92C_CR_MACTXEN | R92C_CR_MACRXEN |
1961	    R92C_CR_ENSEC;
1962	urtwn_write_2(sc, R92C_CR, reg);
1963
1964	urtwn_write_1(sc, 0xfe10, 0x19);
1965	return (0);
1966}
1967
1968static int
1969urtwn_llt_init(struct urtwn_softc *sc)
1970{
1971	int i, error;
1972
1973	/* Reserve pages [0; R92C_TX_PAGE_COUNT]. */
1974	for (i = 0; i < R92C_TX_PAGE_COUNT; i++) {
1975		if ((error = urtwn_llt_write(sc, i, i + 1)) != 0)
1976			return (error);
1977	}
1978	/* NB: 0xff indicates end-of-list. */
1979	if ((error = urtwn_llt_write(sc, i, 0xff)) != 0)
1980		return (error);
1981	/*
1982	 * Use pages [R92C_TX_PAGE_COUNT + 1; R92C_TXPKTBUF_COUNT - 1]
1983	 * as ring buffer.
1984	 */
1985	for (++i; i < R92C_TXPKTBUF_COUNT - 1; i++) {
1986		if ((error = urtwn_llt_write(sc, i, i + 1)) != 0)
1987			return (error);
1988	}
1989	/* Make the last page point to the beginning of the ring buffer. */
1990	error = urtwn_llt_write(sc, i, R92C_TX_PAGE_COUNT + 1);
1991	return (error);
1992}
1993
1994static void
1995urtwn_fw_reset(struct urtwn_softc *sc)
1996{
1997	uint16_t reg;
1998	int ntries;
1999
2000	/* Tell 8051 to reset itself. */
2001	urtwn_write_1(sc, R92C_HMETFR + 3, 0x20);
2002
2003	/* Wait until 8051 resets by itself. */
2004	for (ntries = 0; ntries < 100; ntries++) {
2005		reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
2006		if (!(reg & R92C_SYS_FUNC_EN_CPUEN))
2007			return;
2008		DELAY(50);
2009	}
2010	/* Force 8051 reset. */
2011	urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN);
2012}
2013
2014static int
2015urtwn_fw_loadpage(struct urtwn_softc *sc, int page, const uint8_t *buf, int len)
2016{
2017	uint32_t reg;
2018	int off, mlen, error = 0;
2019
2020	reg = urtwn_read_4(sc, R92C_MCUFWDL);
2021	reg = RW(reg, R92C_MCUFWDL_PAGE, page);
2022	urtwn_write_4(sc, R92C_MCUFWDL, reg);
2023
2024	off = R92C_FW_START_ADDR;
2025	while (len > 0) {
2026		if (len > 196)
2027			mlen = 196;
2028		else if (len > 4)
2029			mlen = 4;
2030		else
2031			mlen = 1;
2032		/* XXX fix this deconst */
2033		error = urtwn_write_region_1(sc, off,
2034		    __DECONST(uint8_t *, buf), mlen);
2035		if (error != 0)
2036			break;
2037		off += mlen;
2038		buf += mlen;
2039		len -= mlen;
2040	}
2041	return (error);
2042}
2043
2044static int
2045urtwn_load_firmware(struct urtwn_softc *sc)
2046{
2047	const struct firmware *fw;
2048	const struct r92c_fw_hdr *hdr;
2049	const char *imagename;
2050	const u_char *ptr;
2051	size_t len;
2052	uint32_t reg;
2053	int mlen, ntries, page, error;
2054
2055	URTWN_UNLOCK(sc);
2056	/* Read firmware image from the filesystem. */
2057	if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) ==
2058	    URTWN_CHIP_UMC_A_CUT)
2059		imagename = "urtwn-rtl8192cfwU";
2060	else
2061		imagename = "urtwn-rtl8192cfwT";
2062
2063	fw = firmware_get(imagename);
2064	URTWN_LOCK(sc);
2065	if (fw == NULL) {
2066		device_printf(sc->sc_dev,
2067		    "failed loadfirmware of file %s\n", imagename);
2068		return (ENOENT);
2069	}
2070
2071	len = fw->datasize;
2072
2073	if (len < sizeof(*hdr)) {
2074		device_printf(sc->sc_dev, "firmware too short\n");
2075		error = EINVAL;
2076		goto fail;
2077	}
2078	ptr = fw->data;
2079	hdr = (const struct r92c_fw_hdr *)ptr;
2080	/* Check if there is a valid FW header and skip it. */
2081	if ((le16toh(hdr->signature) >> 4) == 0x88c ||
2082	    (le16toh(hdr->signature) >> 4) == 0x92c) {
2083		DPRINTF("FW V%d.%d %02d-%02d %02d:%02d\n",
2084		    le16toh(hdr->version), le16toh(hdr->subversion),
2085		    hdr->month, hdr->date, hdr->hour, hdr->minute);
2086		ptr += sizeof(*hdr);
2087		len -= sizeof(*hdr);
2088	}
2089
2090	if (urtwn_read_1(sc, R92C_MCUFWDL) & 0x80) {
2091		urtwn_fw_reset(sc);
2092		urtwn_write_1(sc, R92C_MCUFWDL, 0);
2093	}
2094	urtwn_write_2(sc, R92C_SYS_FUNC_EN,
2095	    urtwn_read_2(sc, R92C_SYS_FUNC_EN) |
2096	    R92C_SYS_FUNC_EN_CPUEN);
2097	urtwn_write_1(sc, R92C_MCUFWDL,
2098	    urtwn_read_1(sc, R92C_MCUFWDL) | R92C_MCUFWDL_EN);
2099	urtwn_write_1(sc, R92C_MCUFWDL + 2,
2100	    urtwn_read_1(sc, R92C_MCUFWDL + 2) & ~0x08);
2101
2102	/* Reset the FWDL checksum. */
2103	urtwn_write_1(sc, R92C_MCUFWDL,
2104	    urtwn_read_1(sc, R92C_MCUFWDL) | R92C_MCUFWDL_CHKSUM_RPT);
2105
2106	for (page = 0; len > 0; page++) {
2107		mlen = min(len, R92C_FW_PAGE_SIZE);
2108		error = urtwn_fw_loadpage(sc, page, ptr, mlen);
2109		if (error != 0) {
2110			device_printf(sc->sc_dev,
2111			    "could not load firmware page\n");
2112			goto fail;
2113		}
2114		ptr += mlen;
2115		len -= mlen;
2116	}
2117	urtwn_write_1(sc, R92C_MCUFWDL,
2118	    urtwn_read_1(sc, R92C_MCUFWDL) & ~R92C_MCUFWDL_EN);
2119	urtwn_write_1(sc, R92C_MCUFWDL + 1, 0);
2120
2121	/* Wait for checksum report. */
2122	for (ntries = 0; ntries < 1000; ntries++) {
2123		if (urtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_CHKSUM_RPT)
2124			break;
2125		DELAY(5);
2126	}
2127	if (ntries == 1000) {
2128		device_printf(sc->sc_dev,
2129		    "timeout waiting for checksum report\n");
2130		error = ETIMEDOUT;
2131		goto fail;
2132	}
2133
2134	reg = urtwn_read_4(sc, R92C_MCUFWDL);
2135	reg = (reg & ~R92C_MCUFWDL_WINTINI_RDY) | R92C_MCUFWDL_RDY;
2136	urtwn_write_4(sc, R92C_MCUFWDL, reg);
2137	/* Wait for firmware readiness. */
2138	for (ntries = 0; ntries < 1000; ntries++) {
2139		if (urtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_WINTINI_RDY)
2140			break;
2141		DELAY(5);
2142	}
2143	if (ntries == 1000) {
2144		device_printf(sc->sc_dev,
2145		    "timeout waiting for firmware readiness\n");
2146		error = ETIMEDOUT;
2147		goto fail;
2148	}
2149fail:
2150	firmware_put(fw, FIRMWARE_UNLOAD);
2151	return (error);
2152}
2153
2154static int
2155urtwn_dma_init(struct urtwn_softc *sc)
2156{
2157	int hashq, hasnq, haslq, nqueues, nqpages, nrempages;
2158	uint32_t reg;
2159	int error;
2160
2161	/* Initialize LLT table. */
2162	error = urtwn_llt_init(sc);
2163	if (error != 0)
2164		return (error);
2165
2166	/* Get Tx queues to USB endpoints mapping. */
2167	hashq = hasnq = haslq = 0;
2168	reg = urtwn_read_2(sc, R92C_USB_EP + 1);
2169	DPRINTFN(2, "USB endpoints mapping 0x%x\n", reg);
2170	if (MS(reg, R92C_USB_EP_HQ) != 0)
2171		hashq = 1;
2172	if (MS(reg, R92C_USB_EP_NQ) != 0)
2173		hasnq = 1;
2174	if (MS(reg, R92C_USB_EP_LQ) != 0)
2175		haslq = 1;
2176	nqueues = hashq + hasnq + haslq;
2177	if (nqueues == 0)
2178		return (EIO);
2179	/* Get the number of pages for each queue. */
2180	nqpages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) / nqueues;
2181	/* The remaining pages are assigned to the high priority queue. */
2182	nrempages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) % nqueues;
2183
2184	/* Set number of pages for normal priority queue. */
2185	urtwn_write_1(sc, R92C_RQPN_NPQ, hasnq ? nqpages : 0);
2186	urtwn_write_4(sc, R92C_RQPN,
2187	    /* Set number of pages for public queue. */
2188	    SM(R92C_RQPN_PUBQ, R92C_PUBQ_NPAGES) |
2189	    /* Set number of pages for high priority queue. */
2190	    SM(R92C_RQPN_HPQ, hashq ? nqpages + nrempages : 0) |
2191	    /* Set number of pages for low priority queue. */
2192	    SM(R92C_RQPN_LPQ, haslq ? nqpages : 0) |
2193	    /* Load values. */
2194	    R92C_RQPN_LD);
2195
2196	urtwn_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, R92C_TX_PAGE_BOUNDARY);
2197	urtwn_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, R92C_TX_PAGE_BOUNDARY);
2198	urtwn_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD, R92C_TX_PAGE_BOUNDARY);
2199	urtwn_write_1(sc, R92C_TRXFF_BNDY, R92C_TX_PAGE_BOUNDARY);
2200	urtwn_write_1(sc, R92C_TDECTRL + 1, R92C_TX_PAGE_BOUNDARY);
2201
2202	/* Set queue to USB pipe mapping. */
2203	reg = urtwn_read_2(sc, R92C_TRXDMA_CTRL);
2204	reg &= ~R92C_TRXDMA_CTRL_QMAP_M;
2205	if (nqueues == 1) {
2206		if (hashq)
2207			reg |= R92C_TRXDMA_CTRL_QMAP_HQ;
2208		else if (hasnq)
2209			reg |= R92C_TRXDMA_CTRL_QMAP_NQ;
2210		else
2211			reg |= R92C_TRXDMA_CTRL_QMAP_LQ;
2212	} else if (nqueues == 2) {
2213		/* All 2-endpoints configs have a high priority queue. */
2214		if (!hashq)
2215			return (EIO);
2216		if (hasnq)
2217			reg |= R92C_TRXDMA_CTRL_QMAP_HQ_NQ;
2218		else
2219			reg |= R92C_TRXDMA_CTRL_QMAP_HQ_LQ;
2220	} else
2221		reg |= R92C_TRXDMA_CTRL_QMAP_3EP;
2222	urtwn_write_2(sc, R92C_TRXDMA_CTRL, reg);
2223
2224	/* Set Tx/Rx transfer page boundary. */
2225	urtwn_write_2(sc, R92C_TRXFF_BNDY + 2, 0x27ff);
2226
2227	/* Set Tx/Rx transfer page size. */
2228	urtwn_write_1(sc, R92C_PBP,
2229	    SM(R92C_PBP_PSRX, R92C_PBP_128) |
2230	    SM(R92C_PBP_PSTX, R92C_PBP_128));
2231	return (0);
2232}
2233
2234static void
2235urtwn_mac_init(struct urtwn_softc *sc)
2236{
2237	int i;
2238
2239	/* Write MAC initialization values. */
2240	for (i = 0; i < nitems(rtl8192cu_mac); i++)
2241		urtwn_write_1(sc, rtl8192cu_mac[i].reg, rtl8192cu_mac[i].val);
2242}
2243
2244static void
2245urtwn_bb_init(struct urtwn_softc *sc)
2246{
2247	const struct urtwn_bb_prog *prog;
2248	uint32_t reg;
2249	int i;
2250
2251	/* Enable BB and RF. */
2252	urtwn_write_2(sc, R92C_SYS_FUNC_EN,
2253	    urtwn_read_2(sc, R92C_SYS_FUNC_EN) |
2254	    R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST |
2255	    R92C_SYS_FUNC_EN_DIO_RF);
2256
2257	urtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);
2258
2259	urtwn_write_1(sc, R92C_RF_CTRL,
2260	    R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
2261	urtwn_write_1(sc, R92C_SYS_FUNC_EN,
2262	    R92C_SYS_FUNC_EN_USBA | R92C_SYS_FUNC_EN_USBD |
2263	    R92C_SYS_FUNC_EN_BB_GLB_RST | R92C_SYS_FUNC_EN_BBRSTB);
2264
2265	urtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f);
2266	urtwn_write_1(sc, 0x15, 0xe9);
2267	urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
2268
2269	/* Select BB programming based on board type. */
2270	if (!(sc->chip & URTWN_CHIP_92C)) {
2271		if (sc->board_type == R92C_BOARD_TYPE_MINICARD)
2272			prog = &rtl8188ce_bb_prog;
2273		else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA)
2274			prog = &rtl8188ru_bb_prog;
2275		else
2276			prog = &rtl8188cu_bb_prog;
2277	} else {
2278		if (sc->board_type == R92C_BOARD_TYPE_MINICARD)
2279			prog = &rtl8192ce_bb_prog;
2280		else
2281			prog = &rtl8192cu_bb_prog;
2282	}
2283	/* Write BB initialization values. */
2284	for (i = 0; i < prog->count; i++) {
2285		urtwn_bb_write(sc, prog->regs[i], prog->vals[i]);
2286		DELAY(1);
2287	}
2288
2289	if (sc->chip & URTWN_CHIP_92C_1T2R) {
2290		/* 8192C 1T only configuration. */
2291		reg = urtwn_bb_read(sc, R92C_FPGA0_TXINFO);
2292		reg = (reg & ~0x00000003) | 0x2;
2293		urtwn_bb_write(sc, R92C_FPGA0_TXINFO, reg);
2294
2295		reg = urtwn_bb_read(sc, R92C_FPGA1_TXINFO);
2296		reg = (reg & ~0x00300033) | 0x00200022;
2297		urtwn_bb_write(sc, R92C_FPGA1_TXINFO, reg);
2298
2299		reg = urtwn_bb_read(sc, R92C_CCK0_AFESETTING);
2300		reg = (reg & ~0xff000000) | 0x45 << 24;
2301		urtwn_bb_write(sc, R92C_CCK0_AFESETTING, reg);
2302
2303		reg = urtwn_bb_read(sc, R92C_OFDM0_TRXPATHENA);
2304		reg = (reg & ~0x000000ff) | 0x23;
2305		urtwn_bb_write(sc, R92C_OFDM0_TRXPATHENA, reg);
2306
2307		reg = urtwn_bb_read(sc, R92C_OFDM0_AGCPARAM1);
2308		reg = (reg & ~0x00000030) | 1 << 4;
2309		urtwn_bb_write(sc, R92C_OFDM0_AGCPARAM1, reg);
2310
2311		reg = urtwn_bb_read(sc, 0xe74);
2312		reg = (reg & ~0x0c000000) | 2 << 26;
2313		urtwn_bb_write(sc, 0xe74, reg);
2314		reg = urtwn_bb_read(sc, 0xe78);
2315		reg = (reg & ~0x0c000000) | 2 << 26;
2316		urtwn_bb_write(sc, 0xe78, reg);
2317		reg = urtwn_bb_read(sc, 0xe7c);
2318		reg = (reg & ~0x0c000000) | 2 << 26;
2319		urtwn_bb_write(sc, 0xe7c, reg);
2320		reg = urtwn_bb_read(sc, 0xe80);
2321		reg = (reg & ~0x0c000000) | 2 << 26;
2322		urtwn_bb_write(sc, 0xe80, reg);
2323		reg = urtwn_bb_read(sc, 0xe88);
2324		reg = (reg & ~0x0c000000) | 2 << 26;
2325		urtwn_bb_write(sc, 0xe88, reg);
2326	}
2327
2328	/* Write AGC values. */
2329	for (i = 0; i < prog->agccount; i++) {
2330		urtwn_bb_write(sc, R92C_OFDM0_AGCRSSITABLE,
2331		    prog->agcvals[i]);
2332		DELAY(1);
2333	}
2334
2335	if (urtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) &
2336	    R92C_HSSI_PARAM2_CCK_HIPWR)
2337		sc->sc_flags |= URTWN_FLAG_CCK_HIPWR;
2338}
2339
2340void
2341urtwn_rf_init(struct urtwn_softc *sc)
2342{
2343	const struct urtwn_rf_prog *prog;
2344	uint32_t reg, type;
2345	int i, j, idx, off;
2346
2347	/* Select RF programming based on board type. */
2348	if (!(sc->chip & URTWN_CHIP_92C)) {
2349		if (sc->board_type == R92C_BOARD_TYPE_MINICARD)
2350			prog = rtl8188ce_rf_prog;
2351		else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA)
2352			prog = rtl8188ru_rf_prog;
2353		else
2354			prog = rtl8188cu_rf_prog;
2355	} else
2356		prog = rtl8192ce_rf_prog;
2357
2358	for (i = 0; i < sc->nrxchains; i++) {
2359		/* Save RF_ENV control type. */
2360		idx = i / 2;
2361		off = (i % 2) * 16;
2362		reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(idx));
2363		type = (reg >> off) & 0x10;
2364
2365		/* Set RF_ENV enable. */
2366		reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(i));
2367		reg |= 0x100000;
2368		urtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(i), reg);
2369		DELAY(1);
2370		/* Set RF_ENV output high. */
2371		reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(i));
2372		reg |= 0x10;
2373		urtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(i), reg);
2374		DELAY(1);
2375		/* Set address and data lengths of RF registers. */
2376		reg = urtwn_bb_read(sc, R92C_HSSI_PARAM2(i));
2377		reg &= ~R92C_HSSI_PARAM2_ADDR_LENGTH;
2378		urtwn_bb_write(sc, R92C_HSSI_PARAM2(i), reg);
2379		DELAY(1);
2380		reg = urtwn_bb_read(sc, R92C_HSSI_PARAM2(i));
2381		reg &= ~R92C_HSSI_PARAM2_DATA_LENGTH;
2382		urtwn_bb_write(sc, R92C_HSSI_PARAM2(i), reg);
2383		DELAY(1);
2384
2385		/* Write RF initialization values for this chain. */
2386		for (j = 0; j < prog[i].count; j++) {
2387			if (prog[i].regs[j] >= 0xf9 &&
2388			    prog[i].regs[j] <= 0xfe) {
2389				/*
2390				 * These are fake RF registers offsets that
2391				 * indicate a delay is required.
2392				 */
2393				usb_pause_mtx(&sc->sc_mtx, 50);
2394				continue;
2395			}
2396			urtwn_rf_write(sc, i, prog[i].regs[j],
2397			    prog[i].vals[j]);
2398			DELAY(1);
2399		}
2400
2401		/* Restore RF_ENV control type. */
2402		reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(idx));
2403		reg &= ~(0x10 << off) | (type << off);
2404		urtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(idx), reg);
2405
2406		/* Cache RF register CHNLBW. */
2407		sc->rf_chnlbw[i] = urtwn_rf_read(sc, i, R92C_RF_CHNLBW);
2408	}
2409
2410	if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) ==
2411	    URTWN_CHIP_UMC_A_CUT) {
2412		urtwn_rf_write(sc, 0, R92C_RF_RX_G1, 0x30255);
2413		urtwn_rf_write(sc, 0, R92C_RF_RX_G2, 0x50a00);
2414	}
2415}
2416
2417static void
2418urtwn_cam_init(struct urtwn_softc *sc)
2419{
2420	/* Invalidate all CAM entries. */
2421	urtwn_write_4(sc, R92C_CAMCMD,
2422	    R92C_CAMCMD_POLLING | R92C_CAMCMD_CLR);
2423}
2424
2425static void
2426urtwn_pa_bias_init(struct urtwn_softc *sc)
2427{
2428	uint8_t reg;
2429	int i;
2430
2431	for (i = 0; i < sc->nrxchains; i++) {
2432		if (sc->pa_setting & (1 << i))
2433			continue;
2434		urtwn_rf_write(sc, i, R92C_RF_IPA, 0x0f406);
2435		urtwn_rf_write(sc, i, R92C_RF_IPA, 0x4f406);
2436		urtwn_rf_write(sc, i, R92C_RF_IPA, 0x8f406);
2437		urtwn_rf_write(sc, i, R92C_RF_IPA, 0xcf406);
2438	}
2439	if (!(sc->pa_setting & 0x10)) {
2440		reg = urtwn_read_1(sc, 0x16);
2441		reg = (reg & ~0xf0) | 0x90;
2442		urtwn_write_1(sc, 0x16, reg);
2443	}
2444}
2445
2446static void
2447urtwn_rxfilter_init(struct urtwn_softc *sc)
2448{
2449	/* Initialize Rx filter. */
2450	/* TODO: use better filter for monitor mode. */
2451	urtwn_write_4(sc, R92C_RCR,
2452	    R92C_RCR_AAP | R92C_RCR_APM | R92C_RCR_AM | R92C_RCR_AB |
2453	    R92C_RCR_APP_ICV | R92C_RCR_AMF | R92C_RCR_HTC_LOC_CTRL |
2454	    R92C_RCR_APP_MIC | R92C_RCR_APP_PHYSTS);
2455	/* Accept all multicast frames. */
2456	urtwn_write_4(sc, R92C_MAR + 0, 0xffffffff);
2457	urtwn_write_4(sc, R92C_MAR + 4, 0xffffffff);
2458	/* Accept all management frames. */
2459	urtwn_write_2(sc, R92C_RXFLTMAP0, 0xffff);
2460	/* Reject all control frames. */
2461	urtwn_write_2(sc, R92C_RXFLTMAP1, 0x0000);
2462	/* Accept all data frames. */
2463	urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff);
2464}
2465
2466static void
2467urtwn_edca_init(struct urtwn_softc *sc)
2468{
2469	urtwn_write_2(sc, R92C_SPEC_SIFS, 0x100a);
2470	urtwn_write_2(sc, R92C_MAC_SPEC_SIFS, 0x100a);
2471	urtwn_write_2(sc, R92C_SIFS_CCK, 0x100a);
2472	urtwn_write_2(sc, R92C_SIFS_OFDM, 0x100a);
2473	urtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x005ea42b);
2474	urtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a44f);
2475	urtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005ea324);
2476	urtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002fa226);
2477}
2478
2479void
2480urtwn_write_txpower(struct urtwn_softc *sc, int chain,
2481    uint16_t power[URTWN_RIDX_COUNT])
2482{
2483	uint32_t reg;
2484
2485	/* Write per-CCK rate Tx power. */
2486	if (chain == 0) {
2487		reg = urtwn_bb_read(sc, R92C_TXAGC_A_CCK1_MCS32);
2488		reg = RW(reg, R92C_TXAGC_A_CCK1,  power[0]);
2489		urtwn_bb_write(sc, R92C_TXAGC_A_CCK1_MCS32, reg);
2490		reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11);
2491		reg = RW(reg, R92C_TXAGC_A_CCK2,  power[1]);
2492		reg = RW(reg, R92C_TXAGC_A_CCK55, power[2]);
2493		reg = RW(reg, R92C_TXAGC_A_CCK11, power[3]);
2494		urtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg);
2495	} else {
2496		reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK1_55_MCS32);
2497		reg = RW(reg, R92C_TXAGC_B_CCK1,  power[0]);
2498		reg = RW(reg, R92C_TXAGC_B_CCK2,  power[1]);
2499		reg = RW(reg, R92C_TXAGC_B_CCK55, power[2]);
2500		urtwn_bb_write(sc, R92C_TXAGC_B_CCK1_55_MCS32, reg);
2501		reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11);
2502		reg = RW(reg, R92C_TXAGC_B_CCK11, power[3]);
2503		urtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg);
2504	}
2505	/* Write per-OFDM rate Tx power. */
2506	urtwn_bb_write(sc, R92C_TXAGC_RATE18_06(chain),
2507	    SM(R92C_TXAGC_RATE06, power[ 4]) |
2508	    SM(R92C_TXAGC_RATE09, power[ 5]) |
2509	    SM(R92C_TXAGC_RATE12, power[ 6]) |
2510	    SM(R92C_TXAGC_RATE18, power[ 7]));
2511	urtwn_bb_write(sc, R92C_TXAGC_RATE54_24(chain),
2512	    SM(R92C_TXAGC_RATE24, power[ 8]) |
2513	    SM(R92C_TXAGC_RATE36, power[ 9]) |
2514	    SM(R92C_TXAGC_RATE48, power[10]) |
2515	    SM(R92C_TXAGC_RATE54, power[11]));
2516	/* Write per-MCS Tx power. */
2517	urtwn_bb_write(sc, R92C_TXAGC_MCS03_MCS00(chain),
2518	    SM(R92C_TXAGC_MCS00,  power[12]) |
2519	    SM(R92C_TXAGC_MCS01,  power[13]) |
2520	    SM(R92C_TXAGC_MCS02,  power[14]) |
2521	    SM(R92C_TXAGC_MCS03,  power[15]));
2522	urtwn_bb_write(sc, R92C_TXAGC_MCS07_MCS04(chain),
2523	    SM(R92C_TXAGC_MCS04,  power[16]) |
2524	    SM(R92C_TXAGC_MCS05,  power[17]) |
2525	    SM(R92C_TXAGC_MCS06,  power[18]) |
2526	    SM(R92C_TXAGC_MCS07,  power[19]));
2527	urtwn_bb_write(sc, R92C_TXAGC_MCS11_MCS08(chain),
2528	    SM(R92C_TXAGC_MCS08,  power[20]) |
2529	    SM(R92C_TXAGC_MCS09,  power[21]) |
2530	    SM(R92C_TXAGC_MCS10,  power[22]) |
2531	    SM(R92C_TXAGC_MCS11,  power[23]));
2532	urtwn_bb_write(sc, R92C_TXAGC_MCS15_MCS12(chain),
2533	    SM(R92C_TXAGC_MCS12,  power[24]) |
2534	    SM(R92C_TXAGC_MCS13,  power[25]) |
2535	    SM(R92C_TXAGC_MCS14,  power[26]) |
2536	    SM(R92C_TXAGC_MCS15,  power[27]));
2537}
2538
2539void
2540urtwn_get_txpower(struct urtwn_softc *sc, int chain,
2541    struct ieee80211_channel *c, struct ieee80211_channel *extc,
2542    uint16_t power[URTWN_RIDX_COUNT])
2543{
2544	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
2545	struct r92c_rom *rom = &sc->rom;
2546	uint16_t cckpow, ofdmpow, htpow, diff, max;
2547	const struct urtwn_txpwr *base;
2548	int ridx, chan, group;
2549
2550	/* Determine channel group. */
2551	chan = ieee80211_chan2ieee(ic, c);	/* XXX center freq! */
2552	if (chan <= 3)
2553		group = 0;
2554	else if (chan <= 9)
2555		group = 1;
2556	else
2557		group = 2;
2558
2559	/* Get original Tx power based on board type and RF chain. */
2560	if (!(sc->chip & URTWN_CHIP_92C)) {
2561		if (sc->board_type == R92C_BOARD_TYPE_HIGHPA)
2562			base = &rtl8188ru_txagc[chain];
2563		else
2564			base = &rtl8192cu_txagc[chain];
2565	} else
2566		base = &rtl8192cu_txagc[chain];
2567
2568	memset(power, 0, URTWN_RIDX_COUNT * sizeof(power[0]));
2569	if (sc->regulatory == 0) {
2570		for (ridx = 0; ridx <= 3; ridx++)
2571			power[ridx] = base->pwr[0][ridx];
2572	}
2573	for (ridx = 4; ridx < URTWN_RIDX_COUNT; ridx++) {
2574		if (sc->regulatory == 3) {
2575			power[ridx] = base->pwr[0][ridx];
2576			/* Apply vendor limits. */
2577			if (extc != NULL)
2578				max = rom->ht40_max_pwr[group];
2579			else
2580				max = rom->ht20_max_pwr[group];
2581			max = (max >> (chain * 4)) & 0xf;
2582			if (power[ridx] > max)
2583				power[ridx] = max;
2584		} else if (sc->regulatory == 1) {
2585			if (extc == NULL)
2586				power[ridx] = base->pwr[group][ridx];
2587		} else if (sc->regulatory != 2)
2588			power[ridx] = base->pwr[0][ridx];
2589	}
2590
2591	/* Compute per-CCK rate Tx power. */
2592	cckpow = rom->cck_tx_pwr[chain][group];
2593	for (ridx = 0; ridx <= 3; ridx++) {
2594		power[ridx] += cckpow;
2595		if (power[ridx] > R92C_MAX_TX_PWR)
2596			power[ridx] = R92C_MAX_TX_PWR;
2597	}
2598
2599	htpow = rom->ht40_1s_tx_pwr[chain][group];
2600	if (sc->ntxchains > 1) {
2601		/* Apply reduction for 2 spatial streams. */
2602		diff = rom->ht40_2s_tx_pwr_diff[group];
2603		diff = (diff >> (chain * 4)) & 0xf;
2604		htpow = (htpow > diff) ? htpow - diff : 0;
2605	}
2606
2607	/* Compute per-OFDM rate Tx power. */
2608	diff = rom->ofdm_tx_pwr_diff[group];
2609	diff = (diff >> (chain * 4)) & 0xf;
2610	ofdmpow = htpow + diff;	/* HT->OFDM correction. */
2611	for (ridx = 4; ridx <= 11; ridx++) {
2612		power[ridx] += ofdmpow;
2613		if (power[ridx] > R92C_MAX_TX_PWR)
2614			power[ridx] = R92C_MAX_TX_PWR;
2615	}
2616
2617	/* Compute per-MCS Tx power. */
2618	if (extc == NULL) {
2619		diff = rom->ht20_tx_pwr_diff[group];
2620		diff = (diff >> (chain * 4)) & 0xf;
2621		htpow += diff;	/* HT40->HT20 correction. */
2622	}
2623	for (ridx = 12; ridx <= 27; ridx++) {
2624		power[ridx] += htpow;
2625		if (power[ridx] > R92C_MAX_TX_PWR)
2626			power[ridx] = R92C_MAX_TX_PWR;
2627	}
2628#ifdef URTWN_DEBUG
2629	if (urtwn_debug >= 4) {
2630		/* Dump per-rate Tx power values. */
2631		printf("Tx power for chain %d:\n", chain);
2632		for (ridx = 0; ridx < URTWN_RIDX_COUNT; ridx++)
2633			printf("Rate %d = %u\n", ridx, power[ridx]);
2634	}
2635#endif
2636}
2637
2638void
2639urtwn_set_txpower(struct urtwn_softc *sc, struct ieee80211_channel *c,
2640    struct ieee80211_channel *extc)
2641{
2642	uint16_t power[URTWN_RIDX_COUNT];
2643	int i;
2644
2645	for (i = 0; i < sc->ntxchains; i++) {
2646		/* Compute per-rate Tx power values. */
2647		urtwn_get_txpower(sc, i, c, extc, power);
2648		/* Write per-rate Tx power values to hardware. */
2649		urtwn_write_txpower(sc, i, power);
2650	}
2651}
2652
2653static void
2654urtwn_scan_start(struct ieee80211com *ic)
2655{
2656	/* XXX do nothing?  */
2657}
2658
2659static void
2660urtwn_scan_end(struct ieee80211com *ic)
2661{
2662	/* XXX do nothing?  */
2663}
2664
2665static void
2666urtwn_set_channel(struct ieee80211com *ic)
2667{
2668	struct urtwn_softc *sc = ic->ic_ifp->if_softc;
2669
2670	URTWN_LOCK(sc);
2671	urtwn_set_chan(sc, ic->ic_curchan, NULL);
2672	URTWN_UNLOCK(sc);
2673}
2674
2675static void
2676urtwn_update_mcast(struct ifnet *ifp)
2677{
2678	/* XXX do nothing?  */
2679}
2680
2681static void
2682urtwn_set_chan(struct urtwn_softc *sc, struct ieee80211_channel *c,
2683    struct ieee80211_channel *extc)
2684{
2685	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
2686	uint32_t reg;
2687	u_int chan;
2688	int i;
2689
2690	chan = ieee80211_chan2ieee(ic, c);	/* XXX center freq! */
2691	if (chan == 0 || chan == IEEE80211_CHAN_ANY) {
2692		device_printf(sc->sc_dev,
2693		    "%s: invalid channel %x\n", __func__, chan);
2694		return;
2695	}
2696
2697	/* Set Tx power for this new channel. */
2698	urtwn_set_txpower(sc, c, extc);
2699
2700	for (i = 0; i < sc->nrxchains; i++) {
2701		urtwn_rf_write(sc, i, R92C_RF_CHNLBW,
2702		    RW(sc->rf_chnlbw[i], R92C_RF_CHNLBW_CHNL, chan));
2703	}
2704#ifndef IEEE80211_NO_HT
2705	if (extc != NULL) {
2706		/* Is secondary channel below or above primary? */
2707		int prichlo = c->ic_freq < extc->ic_freq;
2708
2709		urtwn_write_1(sc, R92C_BWOPMODE,
2710		    urtwn_read_1(sc, R92C_BWOPMODE) & ~R92C_BWOPMODE_20MHZ);
2711
2712		reg = urtwn_read_1(sc, R92C_RRSR + 2);
2713		reg = (reg & ~0x6f) | (prichlo ? 1 : 2) << 5;
2714		urtwn_write_1(sc, R92C_RRSR + 2, reg);
2715
2716		urtwn_bb_write(sc, R92C_FPGA0_RFMOD,
2717		    urtwn_bb_read(sc, R92C_FPGA0_RFMOD) | R92C_RFMOD_40MHZ);
2718		urtwn_bb_write(sc, R92C_FPGA1_RFMOD,
2719		    urtwn_bb_read(sc, R92C_FPGA1_RFMOD) | R92C_RFMOD_40MHZ);
2720
2721		/* Set CCK side band. */
2722		reg = urtwn_bb_read(sc, R92C_CCK0_SYSTEM);
2723		reg = (reg & ~0x00000010) | (prichlo ? 0 : 1) << 4;
2724		urtwn_bb_write(sc, R92C_CCK0_SYSTEM, reg);
2725
2726		reg = urtwn_bb_read(sc, R92C_OFDM1_LSTF);
2727		reg = (reg & ~0x00000c00) | (prichlo ? 1 : 2) << 10;
2728		urtwn_bb_write(sc, R92C_OFDM1_LSTF, reg);
2729
2730		urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2,
2731		    urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) &
2732		    ~R92C_FPGA0_ANAPARAM2_CBW20);
2733
2734		reg = urtwn_bb_read(sc, 0x818);
2735		reg = (reg & ~0x0c000000) | (prichlo ? 2 : 1) << 26;
2736		urtwn_bb_write(sc, 0x818, reg);
2737
2738		/* Select 40MHz bandwidth. */
2739		urtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
2740		    (sc->rf_chnlbw[0] & ~0xfff) | chan);
2741	} else
2742#endif
2743	{
2744		urtwn_write_1(sc, R92C_BWOPMODE,
2745		    urtwn_read_1(sc, R92C_BWOPMODE) | R92C_BWOPMODE_20MHZ);
2746
2747		urtwn_bb_write(sc, R92C_FPGA0_RFMOD,
2748		    urtwn_bb_read(sc, R92C_FPGA0_RFMOD) & ~R92C_RFMOD_40MHZ);
2749		urtwn_bb_write(sc, R92C_FPGA1_RFMOD,
2750		    urtwn_bb_read(sc, R92C_FPGA1_RFMOD) & ~R92C_RFMOD_40MHZ);
2751
2752		urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2,
2753		    urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) |
2754		    R92C_FPGA0_ANAPARAM2_CBW20);
2755
2756		/* Select 20MHz bandwidth. */
2757		urtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
2758		    (sc->rf_chnlbw[0] & ~0xfff) | R92C_RF_CHNLBW_BW20 | chan);
2759	}
2760}
2761
2762static void
2763urtwn_iq_calib(struct urtwn_softc *sc)
2764{
2765	/* TODO */
2766}
2767
2768static void
2769urtwn_lc_calib(struct urtwn_softc *sc)
2770{
2771	uint32_t rf_ac[2];
2772	uint8_t txmode;
2773	int i;
2774
2775	txmode = urtwn_read_1(sc, R92C_OFDM1_LSTF + 3);
2776	if ((txmode & 0x70) != 0) {
2777		/* Disable all continuous Tx. */
2778		urtwn_write_1(sc, R92C_OFDM1_LSTF + 3, txmode & ~0x70);
2779
2780		/* Set RF mode to standby mode. */
2781		for (i = 0; i < sc->nrxchains; i++) {
2782			rf_ac[i] = urtwn_rf_read(sc, i, R92C_RF_AC);
2783			urtwn_rf_write(sc, i, R92C_RF_AC,
2784			    RW(rf_ac[i], R92C_RF_AC_MODE,
2785				R92C_RF_AC_MODE_STANDBY));
2786		}
2787	} else {
2788		/* Block all Tx queues. */
2789		urtwn_write_1(sc, R92C_TXPAUSE, 0xff);
2790	}
2791	/* Start calibration. */
2792	urtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
2793	    urtwn_rf_read(sc, 0, R92C_RF_CHNLBW) | R92C_RF_CHNLBW_LCSTART);
2794
2795	/* Give calibration the time to complete. */
2796	usb_pause_mtx(&sc->sc_mtx, 100);
2797
2798	/* Restore configuration. */
2799	if ((txmode & 0x70) != 0) {
2800		/* Restore Tx mode. */
2801		urtwn_write_1(sc, R92C_OFDM1_LSTF + 3, txmode);
2802		/* Restore RF mode. */
2803		for (i = 0; i < sc->nrxchains; i++)
2804			urtwn_rf_write(sc, i, R92C_RF_AC, rf_ac[i]);
2805	} else {
2806		/* Unblock all Tx queues. */
2807		urtwn_write_1(sc, R92C_TXPAUSE, 0x00);
2808	}
2809}
2810
2811static void
2812urtwn_init_locked(void *arg)
2813{
2814	struct urtwn_softc *sc = arg;
2815	struct ifnet *ifp = sc->sc_ifp;
2816	uint32_t reg;
2817	int error;
2818
2819	URTWN_ASSERT_LOCKED(sc);
2820
2821	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
2822		urtwn_stop_locked(ifp);
2823
2824	/* Init firmware commands ring. */
2825	sc->fwcur = 0;
2826
2827	/* Allocate Tx/Rx buffers. */
2828	error = urtwn_alloc_rx_list(sc);
2829	if (error != 0)
2830		goto fail;
2831
2832	error = urtwn_alloc_tx_list(sc);
2833	if (error != 0)
2834		goto fail;
2835
2836	/* Power on adapter. */
2837	error = urtwn_power_on(sc);
2838	if (error != 0)
2839		goto fail;
2840
2841	/* Initialize DMA. */
2842	error = urtwn_dma_init(sc);
2843	if (error != 0)
2844		goto fail;
2845
2846	/* Set info size in Rx descriptors (in 64-bit words). */
2847	urtwn_write_1(sc, R92C_RX_DRVINFO_SZ, 4);
2848
2849	/* Init interrupts. */
2850	urtwn_write_4(sc, R92C_HISR, 0xffffffff);
2851	urtwn_write_4(sc, R92C_HIMR, 0xffffffff);
2852
2853	/* Set MAC address. */
2854	urtwn_write_region_1(sc, R92C_MACID, IF_LLADDR(ifp),
2855	    IEEE80211_ADDR_LEN);
2856
2857	/* Set initial network type. */
2858	reg = urtwn_read_4(sc, R92C_CR);
2859	reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_INFRA);
2860	urtwn_write_4(sc, R92C_CR, reg);
2861
2862	urtwn_rxfilter_init(sc);
2863
2864	reg = urtwn_read_4(sc, R92C_RRSR);
2865	reg = RW(reg, R92C_RRSR_RATE_BITMAP, R92C_RRSR_RATE_CCK_ONLY_1M);
2866	urtwn_write_4(sc, R92C_RRSR, reg);
2867
2868	/* Set short/long retry limits. */
2869	urtwn_write_2(sc, R92C_RL,
2870	    SM(R92C_RL_SRL, 0x30) | SM(R92C_RL_LRL, 0x30));
2871
2872	/* Initialize EDCA parameters. */
2873	urtwn_edca_init(sc);
2874
2875	/* Setup rate fallback. */
2876	urtwn_write_4(sc, R92C_DARFRC + 0, 0x00000000);
2877	urtwn_write_4(sc, R92C_DARFRC + 4, 0x10080404);
2878	urtwn_write_4(sc, R92C_RARFRC + 0, 0x04030201);
2879	urtwn_write_4(sc, R92C_RARFRC + 4, 0x08070605);
2880
2881	urtwn_write_1(sc, R92C_FWHW_TXQ_CTRL,
2882	    urtwn_read_1(sc, R92C_FWHW_TXQ_CTRL) |
2883	    R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW);
2884	/* Set ACK timeout. */
2885	urtwn_write_1(sc, R92C_ACKTO, 0x40);
2886
2887	/* Setup USB aggregation. */
2888	reg = urtwn_read_4(sc, R92C_TDECTRL);
2889	reg = RW(reg, R92C_TDECTRL_BLK_DESC_NUM, 6);
2890	urtwn_write_4(sc, R92C_TDECTRL, reg);
2891	urtwn_write_1(sc, R92C_TRXDMA_CTRL,
2892	    urtwn_read_1(sc, R92C_TRXDMA_CTRL) |
2893	    R92C_TRXDMA_CTRL_RXDMA_AGG_EN);
2894	urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION,
2895	    urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) |
2896	    R92C_USB_SPECIAL_OPTION_AGG_EN);
2897	urtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48);
2898	urtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4);
2899	urtwn_write_1(sc, R92C_USB_AGG_TH, 8);
2900	urtwn_write_1(sc, R92C_USB_AGG_TO, 6);
2901
2902	/* Initialize beacon parameters. */
2903	urtwn_write_2(sc, R92C_TBTT_PROHIBIT, 0x6404);
2904	urtwn_write_1(sc, R92C_DRVERLYINT, 0x05);
2905	urtwn_write_1(sc, R92C_BCNDMATIM, 0x02);
2906	urtwn_write_2(sc, R92C_BCNTCFG, 0x660f);
2907
2908	/* Setup AMPDU aggregation. */
2909	urtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631);	/* MCS7~0 */
2910	urtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16);
2911	urtwn_write_2(sc, 0x4ca, 0x0708);
2912
2913	urtwn_write_1(sc, R92C_BCN_MAX_ERR, 0xff);
2914	urtwn_write_1(sc, R92C_BCN_CTRL, R92C_BCN_CTRL_DIS_TSF_UDT0);
2915
2916	/* Load 8051 microcode. */
2917	error = urtwn_load_firmware(sc);
2918	if (error != 0)
2919		goto fail;
2920
2921	/* Initialize MAC/BB/RF blocks. */
2922	urtwn_mac_init(sc);
2923	urtwn_bb_init(sc);
2924	urtwn_rf_init(sc);
2925
2926	/* Turn CCK and OFDM blocks on. */
2927	reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD);
2928	reg |= R92C_RFMOD_CCK_EN;
2929	urtwn_bb_write(sc, R92C_FPGA0_RFMOD, reg);
2930	reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD);
2931	reg |= R92C_RFMOD_OFDM_EN;
2932	urtwn_bb_write(sc, R92C_FPGA0_RFMOD, reg);
2933
2934	/* Clear per-station keys table. */
2935	urtwn_cam_init(sc);
2936
2937	/* Enable hardware sequence numbering. */
2938	urtwn_write_1(sc, R92C_HWSEQ_CTRL, 0xff);
2939
2940	/* Perform LO and IQ calibrations. */
2941	urtwn_iq_calib(sc);
2942	/* Perform LC calibration. */
2943	urtwn_lc_calib(sc);
2944
2945	/* Fix USB interference issue. */
2946	urtwn_write_1(sc, 0xfe40, 0xe0);
2947	urtwn_write_1(sc, 0xfe41, 0x8d);
2948	urtwn_write_1(sc, 0xfe42, 0x80);
2949
2950	urtwn_pa_bias_init(sc);
2951
2952	/* Initialize GPIO setting. */
2953	urtwn_write_1(sc, R92C_GPIO_MUXCFG,
2954	    urtwn_read_1(sc, R92C_GPIO_MUXCFG) & ~R92C_GPIO_MUXCFG_ENBT);
2955
2956	/* Fix for lower temperature. */
2957	urtwn_write_1(sc, 0x15, 0xe9);
2958
2959	usbd_transfer_start(sc->sc_xfer[URTWN_BULK_RX]);
2960
2961	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
2962	ifp->if_drv_flags |= IFF_DRV_RUNNING;
2963
2964	callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc);
2965fail:
2966	return;
2967}
2968
2969static void
2970urtwn_init(void *arg)
2971{
2972	struct urtwn_softc *sc = arg;
2973
2974	URTWN_LOCK(sc);
2975	urtwn_init_locked(arg);
2976	URTWN_UNLOCK(sc);
2977}
2978
2979static void
2980urtwn_stop_locked(struct ifnet *ifp)
2981{
2982	struct urtwn_softc *sc = ifp->if_softc;
2983
2984	URTWN_ASSERT_LOCKED(sc);
2985
2986	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
2987
2988	callout_stop(&sc->sc_watchdog_ch);
2989	urtwn_abort_xfers(sc);
2990}
2991
2992static void
2993urtwn_stop(struct ifnet *ifp)
2994{
2995	struct urtwn_softc *sc = ifp->if_softc;
2996
2997	URTWN_LOCK(sc);
2998	urtwn_stop_locked(ifp);
2999	URTWN_UNLOCK(sc);
3000}
3001
3002static void
3003urtwn_abort_xfers(struct urtwn_softc *sc)
3004{
3005	int i;
3006
3007	URTWN_ASSERT_LOCKED(sc);
3008
3009	/* abort any pending transfers */
3010	for (i = 0; i < URTWN_N_TRANSFER; i++)
3011		usbd_transfer_stop(sc->sc_xfer[i]);
3012}
3013
3014static int
3015urtwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
3016    const struct ieee80211_bpf_params *params)
3017{
3018	struct ieee80211com *ic = ni->ni_ic;
3019	struct ifnet *ifp = ic->ic_ifp;
3020	struct urtwn_softc *sc = ifp->if_softc;
3021	struct urtwn_data *bf;
3022
3023	/* prevent management frames from being sent if we're not ready */
3024	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
3025		m_freem(m);
3026		ieee80211_free_node(ni);
3027		return (ENETDOWN);
3028	}
3029	URTWN_LOCK(sc);
3030	bf = urtwn_getbuf(sc);
3031	if (bf == NULL) {
3032		ieee80211_free_node(ni);
3033		m_freem(m);
3034		URTWN_UNLOCK(sc);
3035		return (ENOBUFS);
3036	}
3037
3038	ifp->if_opackets++;
3039	if (urtwn_tx_start(sc, ni, m, bf) != 0) {
3040		ieee80211_free_node(ni);
3041		ifp->if_oerrors++;
3042		STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
3043		URTWN_UNLOCK(sc);
3044		return (EIO);
3045	}
3046	URTWN_UNLOCK(sc);
3047
3048	sc->sc_txtimer = 5;
3049	return (0);
3050}
3051
3052static device_method_t urtwn_methods[] = {
3053	/* Device interface */
3054	DEVMETHOD(device_probe,		urtwn_match),
3055	DEVMETHOD(device_attach,	urtwn_attach),
3056	DEVMETHOD(device_detach,	urtwn_detach),
3057
3058	{ 0, 0 }
3059};
3060
3061static driver_t urtwn_driver = {
3062	"urtwn",
3063	urtwn_methods,
3064	sizeof(struct urtwn_softc)
3065};
3066
3067static devclass_t urtwn_devclass;
3068
3069DRIVER_MODULE(urtwn, uhub, urtwn_driver, urtwn_devclass, NULL, NULL);
3070MODULE_DEPEND(urtwn, usb, 1, 1, 1);
3071MODULE_DEPEND(urtwn, wlan, 1, 1, 1);
3072MODULE_DEPEND(urtwn, firmware, 1, 1, 1);
3073MODULE_VERSION(urtwn, 1);
3074