if_urtwn.c revision 295907
11556Srgrimes/*	$OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $	*/
21556Srgrimes
31556Srgrimes/*-
41556Srgrimes * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
51556Srgrimes * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
61556Srgrimes * Copyright (c) 2015 Andriy Voskoboinyk <avos@FreeBSD.org>
71556Srgrimes *
81556Srgrimes * Permission to use, copy, modify, and distribute this software for any
91556Srgrimes * purpose with or without fee is hereby granted, provided that the above
101556Srgrimes * copyright notice and this permission notice appear in all copies.
111556Srgrimes *
121556Srgrimes * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
131556Srgrimes * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
141556Srgrimes * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
151556Srgrimes * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
161556Srgrimes * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
171556Srgrimes * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
181556Srgrimes * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
191556Srgrimes */
201556Srgrimes
211556Srgrimes#include <sys/cdefs.h>
221556Srgrimes__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_urtwn.c 295907 2016-02-23 01:56:58Z kevlo $");
231556Srgrimes
241556Srgrimes/*
251556Srgrimes * Driver for Realtek RTL8188CE-VAU/RTL8188CUS/RTL8188EU/RTL8188RU/RTL8192CU.
261556Srgrimes */
271556Srgrimes
281556Srgrimes#include "opt_wlan.h"
291556Srgrimes#include "opt_urtwn.h"
301556Srgrimes
311556Srgrimes#include <sys/param.h>
321556Srgrimes#include <sys/sockio.h>
331556Srgrimes#include <sys/sysctl.h>
3436150Scharnier#include <sys/lock.h>
3536150Scharnier#include <sys/mutex.h>
3636150Scharnier#include <sys/condvar.h>
371556Srgrimes#include <sys/mbuf.h>
3899110Sobrien#include <sys/kernel.h>
3999110Sobrien#include <sys/socket.h>
401556Srgrimes#include <sys/systm.h>
4117987Speter#include <sys/malloc.h>
4217987Speter#include <sys/module.h>
4317987Speter#include <sys/bus.h>
4417987Speter#include <sys/endian.h>
4517987Speter#include <sys/linker.h>
4617987Speter#include <sys/firmware.h>
4717987Speter#include <sys/kdb.h>
4817987Speter
4919281Sache#include <machine/bus.h>
5038887Stegge#include <machine/resource.h>
51108286Stjr#include <sys/rman.h>
5217987Speter
531556Srgrimes#include <net/bpf.h>
541556Srgrimes#include <net/if.h>
551556Srgrimes#include <net/if_var.h>
561556Srgrimes#include <net/if_arp.h>
571556Srgrimes#include <net/ethernet.h>
581556Srgrimes#include <net/if_dl.h>
591556Srgrimes#include <net/if_media.h>
601556Srgrimes#include <net/if_types.h>
611556Srgrimes
621556Srgrimes#include <netinet/in.h>
631556Srgrimes#include <netinet/in_systm.h>
641556Srgrimes#include <netinet/in_var.h>
651556Srgrimes#include <netinet/if_ether.h>
661556Srgrimes#include <netinet/ip.h>
671556Srgrimes
681556Srgrimes#include <net80211/ieee80211_var.h>
691556Srgrimes#include <net80211/ieee80211_input.h>
701556Srgrimes#include <net80211/ieee80211_regdomain.h>
711556Srgrimes#include <net80211/ieee80211_radiotap.h>
721556Srgrimes#include <net80211/ieee80211_ratectl.h>
7317987Speter
7417987Speter#include <dev/usb/usb.h>
751556Srgrimes#include <dev/usb/usbdi.h>
761556Srgrimes#include <dev/usb/usb_device.h>
771556Srgrimes#include "usbdevs.h"
781556Srgrimes
791556Srgrimes#include <dev/usb/usb_debug.h>
801556Srgrimes
811556Srgrimes#include <dev/usb/wlan/if_urtwnreg.h>
821556Srgrimes#include <dev/usb/wlan/if_urtwnvar.h>
831556Srgrimes
841556Srgrimes#ifdef USB_DEBUG
851556Srgrimesenum {
861556Srgrimes	URTWN_DEBUG_XMIT	= 0x00000001,	/* basic xmit operation */
871556Srgrimes	URTWN_DEBUG_RECV	= 0x00000002,	/* basic recv operation */
881556Srgrimes	URTWN_DEBUG_STATE	= 0x00000004,	/* 802.11 state transitions */
89117261Sdds	URTWN_DEBUG_RA		= 0x00000008,	/* f/w rate adaptation setup */
90117261Sdds	URTWN_DEBUG_USB		= 0x00000010,	/* usb requests */
91117261Sdds	URTWN_DEBUG_FIRMWARE	= 0x00000020,	/* firmware(9) loading debug */
92117261Sdds	URTWN_DEBUG_BEACON	= 0x00000040,	/* beacon handling */
93117261Sdds	URTWN_DEBUG_INTR	= 0x00000080,	/* ISR */
941556Srgrimes	URTWN_DEBUG_TEMP	= 0x00000100,	/* temperature calibration */
9590111Simp	URTWN_DEBUG_ROM		= 0x00000200,	/* various ROM info */
9690111Simp	URTWN_DEBUG_KEY		= 0x00000400,	/* crypto keys management */
9790111Simp	URTWN_DEBUG_TXPWR	= 0x00000800,	/* dump Tx power values */
9890111Simp	URTWN_DEBUG_ANY		= 0xffffffff
9990111Simp};
10090111Simp
101164081Sstefanf#define URTWN_DPRINTF(_sc, _m, ...) do {			\
10290111Simp	if ((_sc)->sc_debug & (_m))				\
103155301Sschweikh		device_printf((_sc)->sc_dev, __VA_ARGS__);	\
10490111Simp} while(0)
10590111Simp
10690111Simp#else
10790111Simp#define URTWN_DPRINTF(_sc, _m, ...)	do { (void) sc; } while (0)
10890111Simp#endif
10990111Simp
11090111Simp#define	IEEE80211_HAS_ADDR4(wh)	IEEE80211_IS_DSTODS(wh)
11190111Simp
11290111Simp/* various supported device vendors/products */
1131556Srgrimesstatic const STRUCT_USB_HOST_ID urtwn_devs[] = {
11490111Simp#define URTWN_DEV(v,p)  { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
115118374Sache#define	URTWN_RTL8188E_DEV(v,p)	\
11619281Sache	{ USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, URTWN_RTL8188E) }
11719281Sache#define URTWN_RTL8188E  1
11819281Sache	URTWN_DEV(ABOCOM,	RTL8188CU_1),
11919281Sache	URTWN_DEV(ABOCOM,	RTL8188CU_2),
12019281Sache	URTWN_DEV(ABOCOM,	RTL8192CU),
121118374Sache	URTWN_DEV(ASUS,		RTL8192CU),
12219281Sache	URTWN_DEV(ASUS,		USBN10NANO),
12319281Sache	URTWN_DEV(AZUREWAVE,	RTL8188CE_1),
1241556Srgrimes	URTWN_DEV(AZUREWAVE,	RTL8188CE_2),
1251556Srgrimes	URTWN_DEV(AZUREWAVE,	RTL8188CU),
12690111Simp	URTWN_DEV(BELKIN,	F7D2102),
12790111Simp	URTWN_DEV(BELKIN,	RTL8188CU),
1281556Srgrimes	URTWN_DEV(BELKIN,	RTL8192CU),
1291556Srgrimes	URTWN_DEV(CHICONY,	RTL8188CUS_1),
1301556Srgrimes	URTWN_DEV(CHICONY,	RTL8188CUS_2),
13190111Simp	URTWN_DEV(CHICONY,	RTL8188CUS_3),
13290111Simp	URTWN_DEV(CHICONY,	RTL8188CUS_4),
1331556Srgrimes	URTWN_DEV(CHICONY,	RTL8188CUS_5),
1341556Srgrimes	URTWN_DEV(COREGA,	RTL8192CU),
13539137Stegge	URTWN_DEV(DLINK,	RTL8188CU),
1361556Srgrimes	URTWN_DEV(DLINK,	RTL8192CU_1),
1371556Srgrimes	URTWN_DEV(DLINK,	RTL8192CU_2),
1381556Srgrimes	URTWN_DEV(DLINK,	RTL8192CU_3),
1391556Srgrimes	URTWN_DEV(DLINK,	DWA131B),
1401556Srgrimes	URTWN_DEV(EDIMAX,	EW7811UN),
1411556Srgrimes	URTWN_DEV(EDIMAX,	RTL8192CU),
1421556Srgrimes	URTWN_DEV(FEIXUN,	RTL8188CU),
1431556Srgrimes	URTWN_DEV(FEIXUN,	RTL8192CU),
1441556Srgrimes	URTWN_DEV(GUILLEMOT,	HWNUP150),
1451556Srgrimes	URTWN_DEV(HAWKING,	RTL8192CU),
1461556Srgrimes	URTWN_DEV(HP3,		RTL8188CU),
14790111Simp	URTWN_DEV(NETGEAR,	WNA1000M),
14817987Speter	URTWN_DEV(NETGEAR,	RTL8192CU),
1491556Srgrimes	URTWN_DEV(NETGEAR4,	RTL8188CU),
1501556Srgrimes	URTWN_DEV(NOVATECH,	RTL8188CU),
1511556Srgrimes	URTWN_DEV(PLANEX2,	RTL8188CU_1),
1521556Srgrimes	URTWN_DEV(PLANEX2,	RTL8188CU_2),
1531556Srgrimes	URTWN_DEV(PLANEX2,	RTL8188CU_3),
1541556Srgrimes	URTWN_DEV(PLANEX2,	RTL8188CU_4),
1551556Srgrimes	URTWN_DEV(PLANEX2,	RTL8188CUS),
1561556Srgrimes	URTWN_DEV(PLANEX2,	RTL8192CU),
1571556Srgrimes	URTWN_DEV(REALTEK,	RTL8188CE_0),
1581556Srgrimes	URTWN_DEV(REALTEK,	RTL8188CE_1),
1591556Srgrimes	URTWN_DEV(REALTEK,	RTL8188CTV),
1601556Srgrimes	URTWN_DEV(REALTEK,	RTL8188CU_0),
1611556Srgrimes	URTWN_DEV(REALTEK,	RTL8188CU_1),
1621556Srgrimes	URTWN_DEV(REALTEK,	RTL8188CU_2),
1631556Srgrimes	URTWN_DEV(REALTEK,	RTL8188CU_3),
1641556Srgrimes	URTWN_DEV(REALTEK,	RTL8188CU_COMBO),
1651556Srgrimes	URTWN_DEV(REALTEK,	RTL8188CUS),
1661556Srgrimes	URTWN_DEV(REALTEK,	RTL8188RU_1),
1671556Srgrimes	URTWN_DEV(REALTEK,	RTL8188RU_2),
1681556Srgrimes	URTWN_DEV(REALTEK,	RTL8188RU_3),
1691556Srgrimes	URTWN_DEV(REALTEK,	RTL8191CU),
1701556Srgrimes	URTWN_DEV(REALTEK,	RTL8192CE),
1711556Srgrimes	URTWN_DEV(REALTEK,	RTL8192CU),
1721556Srgrimes	URTWN_DEV(SITECOMEU,	RTL8188CU_1),
1731556Srgrimes	URTWN_DEV(SITECOMEU,	RTL8188CU_2),
1741556Srgrimes	URTWN_DEV(SITECOMEU,	RTL8192CU),
1751556Srgrimes	URTWN_DEV(TRENDNET,	RTL8188CU),
1761556Srgrimes	URTWN_DEV(TRENDNET,	RTL8192CU),
1771556Srgrimes	URTWN_DEV(ZYXEL,	RTL8192CU),
1781556Srgrimes	/* URTWN_RTL8188E */
1791556Srgrimes	URTWN_RTL8188E_DEV(ABOCOM,	RTL8188EU),
1801556Srgrimes	URTWN_RTL8188E_DEV(DLINK,	DWA123D1),
1811556Srgrimes	URTWN_RTL8188E_DEV(DLINK,	DWA125D1),
1821556Srgrimes	URTWN_RTL8188E_DEV(ELECOM,	WDC150SU2M),
1831556Srgrimes	URTWN_RTL8188E_DEV(REALTEK,	RTL8188ETV),
1841556Srgrimes	URTWN_RTL8188E_DEV(REALTEK,	RTL8188EU),
1851556Srgrimes#undef URTWN_RTL8188E_DEV
1861556Srgrimes#undef URTWN_DEV
1871556Srgrimes};
1881556Srgrimes
1891556Srgrimesstatic device_probe_t	urtwn_match;
1901556Srgrimesstatic device_attach_t	urtwn_attach;
1911556Srgrimesstatic device_detach_t	urtwn_detach;
1921556Srgrimes
1931556Srgrimesstatic usb_callback_t   urtwn_bulk_tx_callback;
1941556Srgrimesstatic usb_callback_t	urtwn_bulk_rx_callback;
1951556Srgrimes
1961556Srgrimesstatic void		urtwn_sysctlattach(struct urtwn_softc *);
1971556Srgrimesstatic void		urtwn_drain_mbufq(struct urtwn_softc *);
1981556Srgrimesstatic usb_error_t	urtwn_do_request(struct urtwn_softc *,
1991556Srgrimes			    struct usb_device_request *, void *);
2001556Srgrimesstatic struct ieee80211vap *urtwn_vap_create(struct ieee80211com *,
2011556Srgrimes		    const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
2021556Srgrimes                    const uint8_t [IEEE80211_ADDR_LEN],
20390111Simp                    const uint8_t [IEEE80211_ADDR_LEN]);
20417987Speterstatic void		urtwn_vap_delete(struct ieee80211vap *);
20525233Sstevestatic struct mbuf *	urtwn_rx_copy_to_mbuf(struct urtwn_softc *,
206104672Stjr			    struct r92c_rx_stat *, int);
2071556Srgrimesstatic struct mbuf *	urtwn_report_intr(struct usb_xfer *,
2081556Srgrimes			    struct urtwn_data *);
2091556Srgrimesstatic struct mbuf *	urtwn_rxeof(struct urtwn_softc *, uint8_t *, int);
2101556Srgrimesstatic void		urtwn_r88e_ratectl_tx_complete(struct urtwn_softc *,
2111556Srgrimes			    void *);
2121556Srgrimesstatic struct ieee80211_node *urtwn_rx_frame(struct urtwn_softc *,
2131556Srgrimes			    struct mbuf *, int8_t *);
2141556Srgrimesstatic void		urtwn_txeof(struct urtwn_softc *, struct urtwn_data *,
2151556Srgrimes			    int);
21638887Steggestatic int		urtwn_alloc_list(struct urtwn_softc *,
21738887Stegge			    struct urtwn_data[], int, int);
21838887Steggestatic int		urtwn_alloc_rx_list(struct urtwn_softc *);
21938887Steggestatic int		urtwn_alloc_tx_list(struct urtwn_softc *);
22039137Steggestatic void		urtwn_free_list(struct urtwn_softc *,
22139137Stegge			    struct urtwn_data data[], int);
22238887Steggestatic void		urtwn_free_rx_list(struct urtwn_softc *);
2231556Srgrimesstatic void		urtwn_free_tx_list(struct urtwn_softc *);
2241556Srgrimesstatic struct urtwn_data *	_urtwn_getbuf(struct urtwn_softc *);
2251556Srgrimesstatic struct urtwn_data *	urtwn_getbuf(struct urtwn_softc *);
2261556Srgrimesstatic usb_error_t	urtwn_write_region_1(struct urtwn_softc *, uint16_t,
2271556Srgrimes			    uint8_t *, int);
2281556Srgrimesstatic usb_error_t	urtwn_write_1(struct urtwn_softc *, uint16_t, uint8_t);
2291556Srgrimesstatic usb_error_t	urtwn_write_2(struct urtwn_softc *, uint16_t, uint16_t);
2301556Srgrimesstatic usb_error_t	urtwn_write_4(struct urtwn_softc *, uint16_t, uint32_t);
2311556Srgrimesstatic usb_error_t	urtwn_read_region_1(struct urtwn_softc *, uint16_t,
2321556Srgrimes			    uint8_t *, int);
2331556Srgrimesstatic uint8_t		urtwn_read_1(struct urtwn_softc *, uint16_t);
2341556Srgrimesstatic uint16_t		urtwn_read_2(struct urtwn_softc *, uint16_t);
2351556Srgrimesstatic uint32_t		urtwn_read_4(struct urtwn_softc *, uint16_t);
2361556Srgrimesstatic int		urtwn_fw_cmd(struct urtwn_softc *, uint8_t,
2371556Srgrimes			    const void *, int);
2381556Srgrimesstatic void		urtwn_cmdq_cb(void *, int);
2391556Srgrimesstatic int		urtwn_cmd_sleepable(struct urtwn_softc *, const void *,
2401556Srgrimes			    size_t, CMD_FUNC_PROTO);
2411556Srgrimesstatic void		urtwn_r92c_rf_write(struct urtwn_softc *, int,
2421556Srgrimes			    uint8_t, uint32_t);
2431556Srgrimesstatic void		urtwn_r88e_rf_write(struct urtwn_softc *, int,
2441556Srgrimes			    uint8_t, uint32_t);
2451556Srgrimesstatic uint32_t		urtwn_rf_read(struct urtwn_softc *, int, uint8_t);
2461556Srgrimesstatic int		urtwn_llt_write(struct urtwn_softc *, uint32_t,
2471556Srgrimes			    uint32_t);
2481556Srgrimesstatic int		urtwn_efuse_read_next(struct urtwn_softc *, uint8_t *);
2491556Srgrimesstatic int		urtwn_efuse_read_data(struct urtwn_softc *, uint8_t *,
2501556Srgrimes			    uint8_t, uint8_t);
2511556Srgrimes#ifdef USB_DEBUG
2521556Srgrimesstatic void		urtwn_dump_rom_contents(struct urtwn_softc *,
2531556Srgrimes			    uint8_t *, uint16_t);
2541556Srgrimes#endif
2551556Srgrimesstatic int		urtwn_efuse_read(struct urtwn_softc *, uint8_t *,
2561556Srgrimes			    uint16_t);
2571556Srgrimesstatic int		urtwn_efuse_switch_power(struct urtwn_softc *);
2581556Srgrimesstatic int		urtwn_read_chipid(struct urtwn_softc *);
2591556Srgrimesstatic int		urtwn_read_rom(struct urtwn_softc *);
2601556Srgrimesstatic int		urtwn_r88e_read_rom(struct urtwn_softc *);
2611556Srgrimesstatic int		urtwn_ra_init(struct urtwn_softc *);
2621556Srgrimesstatic void		urtwn_init_beacon(struct urtwn_softc *,
2631556Srgrimes			    struct urtwn_vap *);
2641556Srgrimesstatic int		urtwn_setup_beacon(struct urtwn_softc *,
26590111Simp			    struct ieee80211_node *);
26617987Speterstatic void		urtwn_update_beacon(struct ieee80211vap *, int);
2671556Srgrimesstatic int		urtwn_tx_beacon(struct urtwn_softc *sc,
2681556Srgrimes			    struct urtwn_vap *);
2691556Srgrimesstatic int		urtwn_key_alloc(struct ieee80211vap *,
270108935Stjr			    struct ieee80211_key *, ieee80211_keyix *,
2711556Srgrimes			    ieee80211_keyix *);
27217987Speterstatic void		urtwn_key_set_cb(struct urtwn_softc *,
2731556Srgrimes			    union sec_param *);
2741556Srgrimesstatic void		urtwn_key_del_cb(struct urtwn_softc *,
2751556Srgrimes			    union sec_param *);
27639137Steggestatic int		urtwn_key_set(struct ieee80211vap *,
27739137Stegge			    const struct ieee80211_key *);
2781556Srgrimesstatic int		urtwn_key_delete(struct ieee80211vap *,
2791556Srgrimes			    const struct ieee80211_key *);
2801556Srgrimesstatic void		urtwn_tsf_task_adhoc(void *, int);
2811556Srgrimesstatic void		urtwn_tsf_sync_enable(struct urtwn_softc *,
2821556Srgrimes			    struct ieee80211vap *);
2831556Srgrimesstatic void		urtwn_get_tsf(struct urtwn_softc *, uint64_t *);
2841556Srgrimesstatic void		urtwn_set_led(struct urtwn_softc *, int, int);
2851556Srgrimesstatic void		urtwn_set_mode(struct urtwn_softc *, uint8_t);
2861556Srgrimesstatic void		urtwn_ibss_recv_mgmt(struct ieee80211_node *,
2871556Srgrimes			    struct mbuf *, int,
2881556Srgrimes			    const struct ieee80211_rx_stats *, int, int);
2891556Srgrimesstatic int		urtwn_newstate(struct ieee80211vap *,
2901556Srgrimes			    enum ieee80211_state, int);
2911556Srgrimesstatic void		urtwn_calib_to(void *);
2921556Srgrimesstatic void		urtwn_calib_cb(struct urtwn_softc *,
2931556Srgrimes			    union sec_param *);
2941556Srgrimesstatic void		urtwn_watchdog(void *);
2951556Srgrimesstatic void		urtwn_update_avgrssi(struct urtwn_softc *, int, int8_t);
2961556Srgrimesstatic int8_t		urtwn_get_rssi(struct urtwn_softc *, int, void *);
2971556Srgrimesstatic int8_t		urtwn_r88e_get_rssi(struct urtwn_softc *, int, void *);
2981556Srgrimesstatic int		urtwn_tx_data(struct urtwn_softc *,
2991556Srgrimes			    struct ieee80211_node *, struct mbuf *,
30017987Speter			    struct urtwn_data *);
30183675Steggestatic int		urtwn_tx_raw(struct urtwn_softc *,
3021556Srgrimes			    struct ieee80211_node *, struct mbuf *,
3031556Srgrimes			    struct urtwn_data *,
3041556Srgrimes			    const struct ieee80211_bpf_params *);
3051556Srgrimesstatic void		urtwn_tx_start(struct urtwn_softc *, struct mbuf *,
3061556Srgrimes			    uint8_t, struct urtwn_data *);
3071556Srgrimesstatic int		urtwn_transmit(struct ieee80211com *, struct mbuf *);
3081556Srgrimesstatic void		urtwn_start(struct urtwn_softc *);
3091556Srgrimesstatic void		urtwn_parent(struct ieee80211com *);
3101556Srgrimesstatic int		urtwn_r92c_power_on(struct urtwn_softc *);
3111556Srgrimesstatic int		urtwn_r88e_power_on(struct urtwn_softc *);
312155301Sschweikhstatic void		urtwn_r92c_power_off(struct urtwn_softc *);
31390111Simpstatic void		urtwn_r88e_power_off(struct urtwn_softc *);
31438887Steggestatic int		urtwn_llt_init(struct urtwn_softc *);
31538887Stegge#ifndef URTWN_WITHOUT_UCODE
31638887Steggestatic void		urtwn_fw_reset(struct urtwn_softc *);
31738887Steggestatic void		urtwn_r88e_fw_reset(struct urtwn_softc *);
31838887Steggestatic int		urtwn_fw_loadpage(struct urtwn_softc *, int,
31938887Stegge			    const uint8_t *, int);
32038887Steggestatic int		urtwn_load_firmware(struct urtwn_softc *);
32138887Stegge#endif
32238887Steggestatic int		urtwn_dma_init(struct urtwn_softc *);
32338887Steggestatic int		urtwn_mac_init(struct urtwn_softc *);
32438887Steggestatic void		urtwn_bb_init(struct urtwn_softc *);
32538887Steggestatic void		urtwn_rf_init(struct urtwn_softc *);
32638887Steggestatic void		urtwn_cam_init(struct urtwn_softc *);
32738887Steggestatic int		urtwn_cam_write(struct urtwn_softc *, uint32_t,
32838887Stegge			    uint32_t);
32938887Steggestatic void		urtwn_pa_bias_init(struct urtwn_softc *);
33038887Steggestatic void		urtwn_rxfilter_init(struct urtwn_softc *);
33138887Steggestatic void		urtwn_edca_init(struct urtwn_softc *);
33238887Steggestatic void		urtwn_write_txpower(struct urtwn_softc *, int,
33338887Stegge			    uint16_t[]);
33438887Steggestatic void		urtwn_get_txpower(struct urtwn_softc *, int,
335155301Sschweikh		      	    struct ieee80211_channel *,
33638887Stegge			    struct ieee80211_channel *, uint16_t[]);
33738887Steggestatic void		urtwn_r88e_get_txpower(struct urtwn_softc *, int,
33838887Stegge		      	    struct ieee80211_channel *,
33938887Stegge			    struct ieee80211_channel *, uint16_t[]);
34038887Steggestatic void		urtwn_set_txpower(struct urtwn_softc *,
34138887Stegge		    	    struct ieee80211_channel *,
34238887Stegge			    struct ieee80211_channel *);
34338887Steggestatic void		urtwn_set_rx_bssid_all(struct urtwn_softc *, int);
34438887Steggestatic void		urtwn_set_gain(struct urtwn_softc *, uint8_t);
34538887Steggestatic void		urtwn_scan_start(struct ieee80211com *);
34638887Steggestatic void		urtwn_scan_end(struct ieee80211com *);
34738887Steggestatic void		urtwn_set_channel(struct ieee80211com *);
34838887Steggestatic int		urtwn_wme_update(struct ieee80211com *);
34938887Steggestatic void		urtwn_update_slot(struct ieee80211com *);
35038887Steggestatic void		urtwn_update_slot_cb(struct urtwn_softc *,
3511556Srgrimes			    union sec_param *);
3521556Srgrimesstatic void		urtwn_update_aifs(struct urtwn_softc *, uint8_t);
3531556Srgrimesstatic void		urtwn_set_promisc(struct urtwn_softc *);
3541556Srgrimesstatic void		urtwn_update_promisc(struct ieee80211com *);
3551556Srgrimesstatic void		urtwn_update_mcast(struct ieee80211com *);
35690111Simpstatic struct ieee80211_node *urtwn_r88e_node_alloc(struct ieee80211vap *,
35717987Speter			    const uint8_t mac[IEEE80211_ADDR_LEN]);
3581556Srgrimesstatic void		urtwn_r88e_newassoc(struct ieee80211_node *, int);
359178631Sstefanfstatic void		urtwn_r88e_node_free(struct ieee80211_node *);
36038887Steggestatic void		urtwn_set_chan(struct urtwn_softc *,
361108935Stjr		    	    struct ieee80211_channel *,
36238887Stegge			    struct ieee80211_channel *);
3631556Srgrimesstatic void		urtwn_iq_calib(struct urtwn_softc *);
36425233Sstevestatic void		urtwn_lc_calib(struct urtwn_softc *);
3651556Srgrimesstatic void		urtwn_temp_calib(struct urtwn_softc *);
36646684Skrisstatic int		urtwn_init(struct urtwn_softc *);
3671556Srgrimesstatic void		urtwn_stop(struct urtwn_softc *);
3681556Srgrimesstatic void		urtwn_abort_xfers(struct urtwn_softc *);
36946684Skrisstatic int		urtwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
3701556Srgrimes			    const struct ieee80211_bpf_params *);
3711556Srgrimesstatic void		urtwn_ms_delay(struct urtwn_softc *);
3721556Srgrimes
3738855Srgrimes/* Aliases. */
3741556Srgrimes#define	urtwn_bb_write	urtwn_write_4
375178631Sstefanf#define urtwn_bb_read	urtwn_read_4
3768855Srgrimes
3771556Srgrimesstatic const struct usb_config urtwn_config[URTWN_N_TRANSFER] = {
37883676Stegge	[URTWN_BULK_RX] = {
37983676Stegge		.type = UE_BULK,
3801556Srgrimes		.endpoint = UE_ADDR_ANY,
38183676Stegge		.direction = UE_DIR_IN,
3821556Srgrimes		.bufsize = URTWN_RXBUFSZ,
38383676Stegge		.flags = {
3841556Srgrimes			.pipe_bof = 1,
3851556Srgrimes			.short_xfer_ok = 1
3861556Srgrimes		},
38738887Stegge		.callback = urtwn_bulk_rx_callback,
38838887Stegge	},
38938887Stegge	[URTWN_BULK_TX_BE] = {
39038887Stegge		.type = UE_BULK,
39138887Stegge		.endpoint = 0x03,
39238887Stegge		.direction = UE_DIR_OUT,
39338887Stegge		.bufsize = URTWN_TXBUFSZ,
3941556Srgrimes		.flags = {
39538887Stegge			.ext_buffer = 1,
39638887Stegge			.pipe_bof = 1,
397178631Sstefanf			.force_short_xfer = 1
3981556Srgrimes		},
3991556Srgrimes		.callback = urtwn_bulk_tx_callback,
40038887Stegge		.timeout = URTWN_TX_TIMEOUT,	/* ms */
40138887Stegge	},
4021556Srgrimes	[URTWN_BULK_TX_BK] = {
4031556Srgrimes		.type = UE_BULK,
4041556Srgrimes		.endpoint = 0x03,
4051556Srgrimes		.direction = UE_DIR_OUT,
4061556Srgrimes		.bufsize = URTWN_TXBUFSZ,
4071556Srgrimes		.flags = {
4081556Srgrimes			.ext_buffer = 1,
4091556Srgrimes			.pipe_bof = 1,
4101556Srgrimes			.force_short_xfer = 1,
4111556Srgrimes		},
41290111Simp		.callback = urtwn_bulk_tx_callback,
41317987Speter		.timeout = URTWN_TX_TIMEOUT,	/* ms */
4141556Srgrimes	},
4151556Srgrimes	[URTWN_BULK_TX_VI] = {
4161556Srgrimes		.type = UE_BULK,
4171556Srgrimes		.endpoint = 0x02,
4181556Srgrimes		.direction = UE_DIR_OUT,
4191556Srgrimes		.bufsize = URTWN_TXBUFSZ,
4201556Srgrimes		.flags = {
4211556Srgrimes			.ext_buffer = 1,
4221556Srgrimes			.pipe_bof = 1,
4231556Srgrimes			.force_short_xfer = 1
4241556Srgrimes		},
425108935Stjr		.callback = urtwn_bulk_tx_callback,
426115424Sfenner		.timeout = URTWN_TX_TIMEOUT,	/* ms */
4271556Srgrimes	},
4281556Srgrimes	[URTWN_BULK_TX_VO] = {
4291556Srgrimes		.type = UE_BULK,
4301556Srgrimes		.endpoint = 0x02,
4311556Srgrimes		.direction = UE_DIR_OUT,
4328855Srgrimes		.bufsize = URTWN_TXBUFSZ,
4331556Srgrimes		.flags = {
4341556Srgrimes			.ext_buffer = 1,
4351556Srgrimes			.pipe_bof = 1,
4361556Srgrimes			.force_short_xfer = 1
4371556Srgrimes		},
4381556Srgrimes		.callback = urtwn_bulk_tx_callback,
4391556Srgrimes		.timeout = URTWN_TX_TIMEOUT,	/* ms */
4401556Srgrimes	},
4411556Srgrimes};
4421556Srgrimes
4431556Srgrimesstatic const struct wme_to_queue {
444115424Sfenner	uint16_t reg;
445115424Sfenner	uint8_t qid;
4461556Srgrimes} wme2queue[WME_NUM_AC] = {
4471556Srgrimes	{ R92C_EDCA_BE_PARAM, URTWN_BULK_TX_BE},
4481556Srgrimes	{ R92C_EDCA_BK_PARAM, URTWN_BULK_TX_BK},
4491556Srgrimes	{ R92C_EDCA_VI_PARAM, URTWN_BULK_TX_VI},
4501556Srgrimes	{ R92C_EDCA_VO_PARAM, URTWN_BULK_TX_VO}
4511556Srgrimes};
4521556Srgrimes
4531556Srgrimesstatic int
4541556Srgrimesurtwn_match(device_t self)
4551556Srgrimes{
4561556Srgrimes	struct usb_attach_arg *uaa = device_get_ivars(self);
4571556Srgrimes
4581556Srgrimes	if (uaa->usb_mode != USB_MODE_HOST)
45983675Stegge		return (ENXIO);
4601556Srgrimes	if (uaa->info.bConfigIndex != URTWN_CONFIG_INDEX)
461115424Sfenner		return (ENXIO);
462115424Sfenner	if (uaa->info.bIfaceIndex != URTWN_IFACE_INDEX)
463115424Sfenner		return (ENXIO);
464115424Sfenner
465115424Sfenner	return (usbd_lookup_id_by_uaa(urtwn_devs, sizeof(urtwn_devs), uaa));
466115424Sfenner}
467115424Sfenner
468115424Sfennerstatic int
469115424Sfennerurtwn_attach(device_t self)
4701556Srgrimes{
4711556Srgrimes	struct usb_attach_arg *uaa = device_get_ivars(self);
47217987Speter	struct urtwn_softc *sc = device_get_softc(self);
4731556Srgrimes	struct ieee80211com *ic = &sc->sc_ic;
4741556Srgrimes	uint8_t bands[howmany(IEEE80211_MODE_MAX, 8)];
4751556Srgrimes	int error;
4761556Srgrimes
4771556Srgrimes	device_set_usb_desc(self);
47845916Scracauer	sc->sc_udev = uaa->device;
4791556Srgrimes	sc->sc_dev = self;
4801556Srgrimes	if (USB_GET_DRIVER_INFO(uaa) == URTWN_RTL8188E)
4811556Srgrimes		sc->chip |= URTWN_CHIP_88E;
4821556Srgrimes
4831556Srgrimes#ifdef USB_DEBUG
4841556Srgrimes	int debug;
4851556Srgrimes	if (resource_int_value(device_get_name(sc->sc_dev),
4861556Srgrimes	    device_get_unit(sc->sc_dev), "debug", &debug) == 0)
4871556Srgrimes		sc->sc_debug = debug;
4881556Srgrimes#endif
4891556Srgrimes
4901556Srgrimes	mtx_init(&sc->sc_mtx, device_get_nameunit(self),
49117987Speter	    MTX_NETWORK_LOCK, MTX_DEF);
49290111Simp	URTWN_CMDQ_LOCK_INIT(sc);
49390111Simp	URTWN_NT_LOCK_INIT(sc);
49417987Speter	callout_init(&sc->sc_calib_to, 0);
49517987Speter	callout_init(&sc->sc_watchdog_ch, 0);
49617987Speter	mbufq_init(&sc->sc_snd, ifqmaxlen);
49745514Stegge
49817987Speter	sc->sc_iface_index = URTWN_IFACE_INDEX;
49917987Speter	error = usbd_transfer_setup(uaa->device, &sc->sc_iface_index,
50017987Speter	    sc->sc_xfer, urtwn_config, URTWN_N_TRANSFER, sc, &sc->sc_mtx);
50120425Ssteve	if (error) {
50220425Ssteve		device_printf(self, "could not allocate USB transfers, "
50317987Speter		    "err=%s\n", usbd_errstr(error));
50417987Speter		goto detach;
50517987Speter	}
50617987Speter
50717987Speter	URTWN_LOCK(sc);
50817987Speter
50920425Ssteve	error = urtwn_read_chipid(sc);
51020425Ssteve	if (error) {
51117987Speter		device_printf(sc->sc_dev, "unsupported test chip\n");
51217987Speter		URTWN_UNLOCK(sc);
51317987Speter		goto detach;
51417987Speter	}
51520425Ssteve
51620425Ssteve	/* Determine number of Tx/Rx chains. */
51717987Speter	if (sc->chip & URTWN_CHIP_92C) {
51817987Speter		sc->ntxchains = (sc->chip & URTWN_CHIP_92C_1T2R) ? 1 : 2;
51917987Speter		sc->nrxchains = 2;
52017987Speter	} else {
52117987Speter		sc->ntxchains = 1;
52217987Speter		sc->nrxchains = 1;
52317987Speter	}
52417987Speter
52517987Speter	if (sc->chip & URTWN_CHIP_88E)
52617987Speter		error = urtwn_r88e_read_rom(sc);
527112254Sru	else
52817987Speter		error = urtwn_read_rom(sc);
52917987Speter	if (error != 0) {
53017987Speter		device_printf(sc->sc_dev, "%s: cannot read rom, error %d\n",
53117987Speter		    __func__, error);
53217987Speter		URTWN_UNLOCK(sc);
53325233Ssteve		goto detach;
53417987Speter	}
53517987Speter
53645514Stegge	device_printf(sc->sc_dev, "MAC/BB RTL%s, RF 6052 %dT%dR\n",
53717987Speter	    (sc->chip & URTWN_CHIP_92C) ? "8192CU" :
53817987Speter	    (sc->chip & URTWN_CHIP_88E) ? "8188EU" :
53917987Speter	    (sc->board_type == R92C_BOARD_TYPE_HIGHPA) ? "8188RU" :
54017987Speter	    (sc->board_type == R92C_BOARD_TYPE_MINICARD) ? "8188CE-VAU" :
54145514Stegge	    "8188CUS", sc->ntxchains, sc->nrxchains);
54245514Stegge
54317987Speter	URTWN_UNLOCK(sc);
54417987Speter
54517987Speter	ic->ic_softc = sc;
54617987Speter	ic->ic_name = device_get_nameunit(self);
54745514Stegge	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
54817987Speter	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
54917987Speter
55045514Stegge	/* set device capabilities */
55117987Speter	ic->ic_caps =
55217987Speter		  IEEE80211_C_STA		/* station mode */
55317987Speter		| IEEE80211_C_MONITOR		/* monitor mode */
55417987Speter		| IEEE80211_C_IBSS		/* adhoc mode */
55545514Stegge		| IEEE80211_C_HOSTAP		/* hostap mode */
55645514Stegge		| IEEE80211_C_SHPREAMBLE	/* short preamble supported */
55745514Stegge		| IEEE80211_C_SHSLOT		/* short slot time supported */
55845514Stegge		| IEEE80211_C_BGSCAN		/* capable of bg scanning */
55945514Stegge		| IEEE80211_C_WPA		/* 802.11i */
56045514Stegge		| IEEE80211_C_WME		/* 802.11e */
56145514Stegge		;
56245514Stegge
56345514Stegge	ic->ic_cryptocaps =
56417987Speter	    IEEE80211_CRYPTO_WEP |
56517987Speter	    IEEE80211_CRYPTO_TKIP |
56617987Speter	    IEEE80211_CRYPTO_AES_CCM;
56717987Speter
56845514Stegge	memset(bands, 0, sizeof(bands));
56945514Stegge	setbit(bands, IEEE80211_MODE_11B);
57020425Ssteve	setbit(bands, IEEE80211_MODE_11G);
57120425Ssteve	ieee80211_init_channels(ic, NULL, bands);
57217987Speter
57317987Speter	ieee80211_ifattach(ic);
57445514Stegge	ic->ic_raw_xmit = urtwn_raw_xmit;
57545514Stegge	ic->ic_scan_start = urtwn_scan_start;
576155301Sschweikh	ic->ic_scan_end = urtwn_scan_end;
57745514Stegge	ic->ic_set_channel = urtwn_set_channel;
57845514Stegge	ic->ic_transmit = urtwn_transmit;
57945514Stegge	ic->ic_parent = urtwn_parent;
58045514Stegge	ic->ic_vap_create = urtwn_vap_create;
58145514Stegge	ic->ic_vap_delete = urtwn_vap_delete;
58245514Stegge	ic->ic_wme.wme_update = urtwn_wme_update;
58317987Speter	ic->ic_updateslot = urtwn_update_slot;
58417987Speter	ic->ic_update_promisc = urtwn_update_promisc;
58517987Speter	ic->ic_update_mcast = urtwn_update_mcast;
58617987Speter	if (sc->chip & URTWN_CHIP_88E) {
58717987Speter		ic->ic_node_alloc = urtwn_r88e_node_alloc;
58845514Stegge		ic->ic_newassoc = urtwn_r88e_newassoc;
58920425Ssteve		sc->sc_node_free = ic->ic_node_free;
59020425Ssteve		ic->ic_node_free = urtwn_r88e_node_free;
59117987Speter	}
59217987Speter
59345514Stegge	ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr,
59445514Stegge	    sizeof(sc->sc_txtap), URTWN_TX_RADIOTAP_PRESENT,
59517987Speter	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
59617987Speter	    URTWN_RX_RADIOTAP_PRESENT);
59717987Speter
59817987Speter	TASK_INIT(&sc->cmdq_task, 0, urtwn_cmdq_cb, sc);
59917987Speter
60017987Speter	urtwn_sysctlattach(sc);
60117987Speter
60217987Speter	if (bootverbose)
60317987Speter		ieee80211_announce(ic);
60420425Ssteve
60520425Ssteve	return (0);
60617987Speter
60717987Speterdetach:
60817987Speter	urtwn_detach(self);
60917987Speter	return (ENXIO);			/* failure */
61017987Speter}
61117987Speter
6121556Srgrimesstatic void
6131556Srgrimesurtwn_sysctlattach(struct urtwn_softc *sc)
6141556Srgrimes{
6151556Srgrimes#ifdef USB_DEBUG
6161556Srgrimes	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
6171556Srgrimes	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
61890111Simp
61917987Speter	SYSCTL_ADD_U32(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
6201556Srgrimes	    "debug", CTLFLAG_RW, &sc->sc_debug, sc->sc_debug,
6211556Srgrimes	    "control debugging printfs");
6221556Srgrimes#endif
6231556Srgrimes}
62445644Stegge
6251556Srgrimesstatic int
6261556Srgrimesurtwn_detach(device_t self)
6271556Srgrimes{
6281556Srgrimes	struct urtwn_softc *sc = device_get_softc(self);
62917987Speter	struct ieee80211com *ic = &sc->sc_ic;
63017987Speter	unsigned int x;
631108935Stjr
6321556Srgrimes	/* Prevent further ioctls. */
633164081Sstefanf	URTWN_LOCK(sc);
6341556Srgrimes	sc->sc_flags |= URTWN_DETACHED;
6351556Srgrimes	URTWN_UNLOCK(sc);
6361556Srgrimes
6371556Srgrimes	urtwn_stop(sc);
6381556Srgrimes
6391556Srgrimes	callout_drain(&sc->sc_watchdog_ch);
6401556Srgrimes	callout_drain(&sc->sc_calib_to);
641179022Sstefanf
642179022Sstefanf	/* stop all USB transfers */
643179022Sstefanf	usbd_transfer_unsetup(sc->sc_xfer, URTWN_N_TRANSFER);
644179022Sstefanf
645179022Sstefanf	/* Prevent further allocations from RX/TX data lists. */
646179022Sstefanf	URTWN_LOCK(sc);
647179022Sstefanf	STAILQ_INIT(&sc->sc_tx_active);
64825233Ssteve	STAILQ_INIT(&sc->sc_tx_inactive);
6491556Srgrimes	STAILQ_INIT(&sc->sc_tx_pending);
6501556Srgrimes
65160592Scracauer	STAILQ_INIT(&sc->sc_rx_active);
65217987Speter	STAILQ_INIT(&sc->sc_rx_inactive);
6531556Srgrimes	URTWN_UNLOCK(sc);
6541556Srgrimes
6551556Srgrimes	/* drain USB transfers */
6561556Srgrimes	for (x = 0; x != URTWN_N_TRANSFER; x++)
6571556Srgrimes		usbd_transfer_drain(sc->sc_xfer[x]);
65817987Speter
6591556Srgrimes	/* Free data buffers. */
66096939Stjr	URTWN_LOCK(sc);
66196939Stjr	urtwn_free_tx_list(sc);
66296939Stjr	urtwn_free_rx_list(sc);
66396939Stjr	URTWN_UNLOCK(sc);
66496939Stjr
66596939Stjr	if (ic->ic_softc == sc) {
66696939Stjr		ieee80211_draintask(ic, &sc->cmdq_task);
66796939Stjr		ieee80211_ifdetach(ic);
668112254Sru	}
669112254Sru
67096939Stjr	URTWN_NT_LOCK_DESTROY(sc);
67196939Stjr	URTWN_CMDQ_LOCK_DESTROY(sc);
6721556Srgrimes	mtx_destroy(&sc->sc_mtx);
6731556Srgrimes
6741556Srgrimes	return (0);
675164081Sstefanf}
67617987Speter
67725233Sstevestatic void
67825233Ssteveurtwn_drain_mbufq(struct urtwn_softc *sc)
67917987Speter{
6801556Srgrimes	struct mbuf *m;
68120425Ssteve	struct ieee80211_node *ni;
68217987Speter	URTWN_ASSERT_LOCKED(sc);
6831556Srgrimes	while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
68417987Speter		ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
68517987Speter		m->m_pkthdr.rcvif = NULL;
68617987Speter		ieee80211_free_node(ni);
6871556Srgrimes		m_freem(m);
68817987Speter	}
68917987Speter}
69083675Stegge
69154132Scracauerstatic usb_error_t
69217987Speterurtwn_do_request(struct urtwn_softc *sc, struct usb_device_request *req,
69317987Speter    void *data)
69417987Speter{
69517987Speter	usb_error_t err;
69617987Speter	int ntries = 10;
6971556Srgrimes
6981556Srgrimes	URTWN_ASSERT_LOCKED(sc);
69920425Ssteve
7001556Srgrimes	while (ntries--) {
7011556Srgrimes		err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
70217987Speter		    req, data, 0, NULL, 250 /* ms */);
70320425Ssteve		if (err == 0)
70417987Speter			break;
70517987Speter
70617987Speter		URTWN_DPRINTF(sc, URTWN_DEBUG_USB,
70717987Speter		    "%s: control request failed, %s (retries left: %d)\n",
70817987Speter		    __func__, usbd_errstr(err), ntries);
70917987Speter		usb_pause_mtx(&sc->sc_mtx, hz / 100);
71017987Speter	}
71117987Speter	return (err);
71217987Speter}
71317987Speter
71417987Speterstatic struct ieee80211vap *
71517987Speterurtwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
71620425Ssteve    enum ieee80211_opmode opmode, int flags,
71717987Speter    const uint8_t bssid[IEEE80211_ADDR_LEN],
71817987Speter    const uint8_t mac[IEEE80211_ADDR_LEN])
71917987Speter{
72017987Speter	struct urtwn_softc *sc = ic->ic_softc;
72117987Speter	struct urtwn_vap *uvp;
72217987Speter	struct ieee80211vap *vap;
7231556Srgrimes
72417987Speter	if (!TAILQ_EMPTY(&ic->ic_vaps))		/* only one at a time */
72517987Speter		return (NULL);
72617987Speter
72717987Speter	uvp = malloc(sizeof(struct urtwn_vap), M_80211_VAP, M_WAITOK | M_ZERO);
72817987Speter	vap = &uvp->vap;
72917987Speter	/* enable s/w bmiss handling for sta mode */
73017987Speter
73117987Speter	if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
73217987Speter	    flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
73317987Speter		/* out of memory */
73417987Speter		free(uvp, M_80211_VAP);
73517987Speter		return (NULL);
73617987Speter	}
73717987Speter
73817987Speter	if (opmode == IEEE80211_M_HOSTAP || opmode == IEEE80211_M_IBSS)
73917987Speter		urtwn_init_beacon(sc, uvp);
74017987Speter
74145644Stegge	/* override state transition machine */
74245644Stegge	uvp->newstate = vap->iv_newstate;
74338887Stegge	vap->iv_newstate = urtwn_newstate;
74445644Stegge	vap->iv_update_beacon = urtwn_update_beacon;
74525233Ssteve	vap->iv_key_alloc = urtwn_key_alloc;
74625233Ssteve	vap->iv_key_set = urtwn_key_set;
74738887Stegge	vap->iv_key_delete = urtwn_key_delete;
74838887Stegge	if (opmode == IEEE80211_M_IBSS) {
74938887Stegge		uvp->recv_mgmt = vap->iv_recv_mgmt;
75017987Speter		vap->iv_recv_mgmt = urtwn_ibss_recv_mgmt;
75117987Speter		TASK_INIT(&uvp->tsf_task_adhoc, 0, urtwn_tsf_task_adhoc, vap);
75217987Speter	}
75317987Speter
75420425Ssteve	if (URTWN_CHIP_HAS_RATECTL(sc))
75520425Ssteve		ieee80211_ratectl_init(vap);
756155301Sschweikh	/* complete setup */
757155301Sschweikh	ieee80211_vap_attach(vap, ieee80211_media_change,
758155301Sschweikh	    ieee80211_media_status, mac);
75938887Stegge	ic->ic_opmode = opmode;
76038887Stegge	return (vap);
7611556Srgrimes}
76220425Ssteve
76317987Speterstatic void
7641556Srgrimesurtwn_vap_delete(struct ieee80211vap *vap)
76517987Speter{
76617987Speter	struct ieee80211com *ic = vap->iv_ic;
76717987Speter	struct urtwn_softc *sc = ic->ic_softc;
76817987Speter	struct urtwn_vap *uvp = URTWN_VAP(vap);
769164003Sstefanf
770164003Sstefanf	if (uvp->bcn_mbuf != NULL)
771164003Sstefanf		m_freem(uvp->bcn_mbuf);
772164003Sstefanf	if (vap->iv_opmode == IEEE80211_M_IBSS)
773164003Sstefanf		ieee80211_draintask(ic, &uvp->tsf_task_adhoc);
77417987Speter	if (URTWN_CHIP_HAS_RATECTL(sc))
77517987Speter		ieee80211_ratectl_deinit(vap);
7761556Srgrimes	ieee80211_vap_detach(vap);
777179022Sstefanf	free(uvp, M_80211_VAP);
77817987Speter}
7791556Srgrimes
7801556Srgrimesstatic struct mbuf *
7811556Srgrimesurtwn_rx_copy_to_mbuf(struct urtwn_softc *sc, struct r92c_rx_stat *stat,
7821556Srgrimes    int totlen)
7831556Srgrimes{
7841556Srgrimes	struct ieee80211com *ic = &sc->sc_ic;
7851556Srgrimes	struct mbuf *m;
7861556Srgrimes	uint32_t rxdw0;
7871556Srgrimes	int pktlen;
7881556Srgrimes
7891556Srgrimes	/*
7901556Srgrimes	 * don't pass packets to the ieee80211 framework if the driver isn't
7911556Srgrimes	 * RUNNING.
7921556Srgrimes	 */
7931556Srgrimes	if (!(sc->sc_flags & URTWN_RUNNING))
7941556Srgrimes		return (NULL);
7951556Srgrimes
7961556Srgrimes	rxdw0 = le32toh(stat->rxdw0);
7971556Srgrimes	if (rxdw0 & (R92C_RXDW0_CRCERR | R92C_RXDW0_ICVERR)) {
7981556Srgrimes		/*
7991556Srgrimes		 * This should not happen since we setup our Rx filter
8001556Srgrimes		 * to not receive these frames.
8011556Srgrimes		 */
8021556Srgrimes		URTWN_DPRINTF(sc, URTWN_DEBUG_RECV,
8031556Srgrimes		    "%s: RX flags error (%s)\n", __func__,
8041556Srgrimes		    rxdw0 & R92C_RXDW0_CRCERR ? "CRC" : "ICV");
8051556Srgrimes		goto fail;
80690111Simp	}
80725233Ssteve
8081556Srgrimes	pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN);
80925233Ssteve	if (pktlen < sizeof(struct ieee80211_frame_ack)) {
81025233Ssteve		URTWN_DPRINTF(sc, URTWN_DEBUG_RECV,
81125233Ssteve		    "%s: frame is too short: %d\n", __func__, pktlen);
8121556Srgrimes		goto fail;
8131556Srgrimes	}
81425233Ssteve
81525233Ssteve	if (__predict_false(totlen > MCLBYTES)) {
81625233Ssteve		/* convert to m_getjcl if this happens */
81725233Ssteve		device_printf(sc->sc_dev, "%s: frame too long: %d (%d)\n",
81825233Ssteve		    __func__, pktlen, totlen);
81925233Ssteve		goto fail;
82025233Ssteve	}
82125233Ssteve
82225233Ssteve	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
82318202Speter	if (__predict_false(m == NULL)) {
82425233Ssteve		device_printf(sc->sc_dev, "%s: could not allocate RX mbuf\n",
82520425Ssteve		    __func__);
82625233Ssteve		goto fail;
82725233Ssteve	}
82825233Ssteve
82925233Ssteve	/* Finalize mbuf. */
83025233Ssteve	memcpy(mtod(m, uint8_t *), (uint8_t *)stat, totlen);
83125233Ssteve	m->m_pkthdr.len = m->m_len = totlen;
83225233Ssteve
83325233Ssteve	return (m);
83425233Sstevefail:
83525233Ssteve	counter_u64_add(ic->ic_ierrors, 1);
83625233Ssteve	return (NULL);
8371556Srgrimes}
8381556Srgrimes
8391556Srgrimesstatic struct mbuf *
8401556Srgrimesurtwn_report_intr(struct usb_xfer *xfer, struct urtwn_data *data)
8411556Srgrimes{
8421556Srgrimes	struct urtwn_softc *sc = data->sc;
8431556Srgrimes	struct ieee80211com *ic = &sc->sc_ic;
8441556Srgrimes	struct r92c_rx_stat *stat;
8451556Srgrimes	uint8_t *buf;
8461556Srgrimes	int len;
8471556Srgrimes
848164081Sstefanf	usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
84917987Speter
8501556Srgrimes	if (len < sizeof(*stat)) {
8511556Srgrimes		counter_u64_add(ic->ic_ierrors, 1);
8521556Srgrimes		return (NULL);
85317987Speter	}
8541556Srgrimes
8551556Srgrimes	buf = data->buf;
8561556Srgrimes	stat = (struct r92c_rx_stat *)buf;
8571556Srgrimes
8581556Srgrimes	if (sc->chip & URTWN_CHIP_88E) {
8591556Srgrimes		int report_sel = MS(le32toh(stat->rxdw3), R88E_RXDW3_RPT);
860164081Sstefanf
8611556Srgrimes		switch (report_sel) {
8621556Srgrimes		case R88E_RXDW3_RPT_RX:
86383675Stegge			return (urtwn_rxeof(sc, buf, len));
8641556Srgrimes		case R88E_RXDW3_RPT_TX1:
8651556Srgrimes			urtwn_r88e_ratectl_tx_complete(sc, &stat[1]);
8661556Srgrimes			break;
8671556Srgrimes		default:
8681556Srgrimes			URTWN_DPRINTF(sc, URTWN_DEBUG_INTR,
8691556Srgrimes			    "%s: case %d was not handled\n", __func__,
8701556Srgrimes			    report_sel);
8711556Srgrimes			break;
8721556Srgrimes		}
87318202Speter	} else
8741556Srgrimes		return (urtwn_rxeof(sc, buf, len));
8751556Srgrimes
8761556Srgrimes	return (NULL);
8771556Srgrimes}
87817987Speter
8791556Srgrimesstatic struct mbuf *
8801556Srgrimesurtwn_rxeof(struct urtwn_softc *sc, uint8_t *buf, int len)
8811556Srgrimes{
8821556Srgrimes	struct r92c_rx_stat *stat;
8831556Srgrimes	struct mbuf *m, *m0 = NULL, *prevm = NULL;
8841556Srgrimes	uint32_t rxdw0;
8851556Srgrimes	int totlen, pktlen, infosz, npkts;
88617987Speter
8871556Srgrimes	/* Get the number of encapsulated frames. */
8881556Srgrimes	stat = (struct r92c_rx_stat *)buf;
8891556Srgrimes	npkts = MS(le32toh(stat->rxdw2), R92C_RXDW2_PKTCNT);
8901556Srgrimes	URTWN_DPRINTF(sc, URTWN_DEBUG_RECV,
8911556Srgrimes	    "%s: Rx %d frames in one chunk\n", __func__, npkts);
8921556Srgrimes
8931556Srgrimes	/* Process all of them. */
8941556Srgrimes	while (npkts-- > 0) {
895164081Sstefanf		if (len < sizeof(*stat))
89638887Stegge			break;
89738887Stegge		stat = (struct r92c_rx_stat *)buf;
89838887Stegge		rxdw0 = le32toh(stat->rxdw0);
89938887Stegge
90038887Stegge		pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN);
90138887Stegge		if (pktlen == 0)
9021556Srgrimes			break;
903102410Scharnier
9041556Srgrimes		infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
905149825Srse
90638887Stegge		/* Make sure everything fits in xfer. */
90738887Stegge		totlen = sizeof(*stat) + infosz + pktlen;
90838887Stegge		if (totlen > len)
9091556Srgrimes			break;
9101556Srgrimes
91138887Stegge		m = urtwn_rx_copy_to_mbuf(sc, stat, totlen);
9121556Srgrimes		if (m0 == NULL)
9131556Srgrimes			m0 = m;
9141556Srgrimes		if (prevm == NULL)
9151556Srgrimes			prevm = m;
9161556Srgrimes		else {
9171556Srgrimes			prevm->m_next = m;
9181556Srgrimes			prevm = m;
9191556Srgrimes		}
92018202Speter
92118202Speter		/* Next chunk is 128-byte aligned. */
92218202Speter		totlen = (totlen + 127) & ~127;
92318202Speter		buf += totlen;
92418202Speter		len -= totlen;
92518202Speter	}
9261556Srgrimes
9271556Srgrimes	return (m0);
9281556Srgrimes}
9291556Srgrimes
9301556Srgrimesstatic void
9311556Srgrimesurtwn_r88e_ratectl_tx_complete(struct urtwn_softc *sc, void *arg)
9321556Srgrimes{
9331556Srgrimes	struct r88e_tx_rpt_ccx *rpt = arg;
9341556Srgrimes	struct ieee80211vap *vap;
9351556Srgrimes	struct ieee80211_node *ni;
9361556Srgrimes	uint8_t macid;
9371556Srgrimes	int ntries;
9381556Srgrimes
93990111Simp	macid = MS(rpt->rptb1, R88E_RPTB1_MACID);
94017987Speter	ntries = MS(rpt->rptb2, R88E_RPTB2_RETRY_CNT);
94125233Ssteve
9421556Srgrimes	URTWN_NT_LOCK(sc);
9431556Srgrimes	ni = sc->node_list[macid];
9441556Srgrimes	if (ni != NULL) {
9451556Srgrimes		vap = ni->ni_vap;
9461556Srgrimes		URTWN_DPRINTF(sc, URTWN_DEBUG_INTR, "%s: frame for macid %d was"
9471556Srgrimes		    "%s sent (%d retries)\n", __func__, macid,
9481556Srgrimes		    (rpt->rptb1 & R88E_RPTB1_PKT_OK) ? "" : " not",
9491556Srgrimes		    ntries);
9501556Srgrimes
9511556Srgrimes		if (rpt->rptb1 & R88E_RPTB1_PKT_OK) {
9521556Srgrimes			ieee80211_ratectl_tx_complete(vap, ni,
9531556Srgrimes			    IEEE80211_RATECTL_TX_SUCCESS, &ntries, NULL);
9541556Srgrimes		} else {
9551556Srgrimes			ieee80211_ratectl_tx_complete(vap, ni,
9561556Srgrimes			    IEEE80211_RATECTL_TX_FAILURE, &ntries, NULL);
9571556Srgrimes		}
9581556Srgrimes	} else {
9591556Srgrimes		URTWN_DPRINTF(sc, URTWN_DEBUG_INTR, "%s: macid %d, ni is NULL\n",
9601556Srgrimes		    __func__, macid);
9611556Srgrimes	}
9621556Srgrimes	URTWN_NT_UNLOCK(sc);
9631556Srgrimes}
96490111Simp
96590111Simpstatic struct ieee80211_node *
9661556Srgrimesurtwn_rx_frame(struct urtwn_softc *sc, struct mbuf *m, int8_t *rssi_p)
9671556Srgrimes{
9681556Srgrimes	struct ieee80211com *ic = &sc->sc_ic;
96925233Ssteve	struct ieee80211_frame_min *wh;
9701556Srgrimes	struct r92c_rx_stat *stat;
9711556Srgrimes	uint32_t rxdw0, rxdw3;
97217987Speter	uint8_t rate, cipher;
97338887Stegge	int8_t rssi = URTWN_NOISE_FLOOR + 1;
9741556Srgrimes	int infosz;
97517987Speter
9761556Srgrimes	stat = mtod(m, struct r92c_rx_stat *);
97738887Stegge	rxdw0 = le32toh(stat->rxdw0);
97838887Stegge	rxdw3 = le32toh(stat->rxdw3);
9791556Srgrimes
9801556Srgrimes	rate = MS(rxdw3, R92C_RXDW3_RATE);
9811556Srgrimes	cipher = MS(rxdw0, R92C_RXDW0_CIPHER);
9821556Srgrimes	infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
98338887Stegge
984155301Sschweikh	/* Get RSSI from PHY status descriptor if present. */
98538887Stegge	if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) {
98638887Stegge		if (sc->chip & URTWN_CHIP_88E)
9871556Srgrimes			rssi = urtwn_r88e_get_rssi(sc, rate, &stat[1]);
9881556Srgrimes		else
9891556Srgrimes			rssi = urtwn_get_rssi(sc, rate, &stat[1]);
9901556Srgrimes		/* Update our average RSSI. */
99138887Stegge		urtwn_update_avgrssi(sc, rate, rssi);
99238887Stegge	}
99338887Stegge
99438887Stegge	if (ieee80211_radiotap_active(ic)) {
99538887Stegge		struct urtwn_rx_radiotap_header *tap = &sc->sc_rxtap;
99638887Stegge
99738887Stegge		tap->wr_flags = 0;
99838887Stegge
9991556Srgrimes		urtwn_get_tsf(sc, &tap->wr_tsft);
100038887Stegge		if (__predict_false(le32toh((uint32_t)tap->wr_tsft) <
100138887Stegge				    le32toh(stat->rxdw5))) {
100238887Stegge			tap->wr_tsft = le32toh(tap->wr_tsft  >> 32) - 1;
100338887Stegge			tap->wr_tsft = (uint64_t)htole32(tap->wr_tsft) << 32;
100438887Stegge		} else
100538887Stegge			tap->wr_tsft &= 0xffffffff00000000;
100638887Stegge		tap->wr_tsft += stat->rxdw5;
10071556Srgrimes
100838887Stegge		/* Map HW rate index to 802.11 rate. */
10091556Srgrimes		if (!(rxdw3 & R92C_RXDW3_HT)) {
101038887Stegge			tap->wr_rate = ridx2rate[rate];
10111556Srgrimes		} else if (rate >= 12) {	/* MCS0~15. */
10121556Srgrimes			/* Bit 7 set means HT MCS instead of rate. */
10131556Srgrimes			tap->wr_rate = 0x80 | (rate - 12);
101438887Stegge		}
10151556Srgrimes		tap->wr_dbm_antsignal = rssi;
10161556Srgrimes		tap->wr_dbm_antnoise = URTWN_NOISE_FLOOR;
101738887Stegge	}
101838887Stegge
101938887Stegge	*rssi_p = rssi;
102038887Stegge
102138887Stegge	/* Drop descriptor. */
102238887Stegge	m_adj(m, sizeof(*stat) + infosz);
102338887Stegge	wh = mtod(m, struct ieee80211_frame_min *);
102438887Stegge
102538887Stegge	if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
102638887Stegge	    cipher != R92C_CAM_ALGO_NONE) {
10271556Srgrimes		m->m_flags |= M_WEP;
10281556Srgrimes	}
10291556Srgrimes
103038887Stegge	if (m->m_len >= sizeof(*wh))
103138887Stegge		return (ieee80211_find_rxnode(ic, wh));
10321556Srgrimes
10331556Srgrimes	return (NULL);
1034149825Srse}
10351556Srgrimes
10361556Srgrimesstatic void
10371556Srgrimesurtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
10381556Srgrimes{
10391556Srgrimes	struct urtwn_softc *sc = usbd_xfer_softc(xfer);
10401556Srgrimes	struct ieee80211com *ic = &sc->sc_ic;
10411556Srgrimes	struct ieee80211_node *ni;
10421556Srgrimes	struct mbuf *m = NULL, *next;
10431556Srgrimes	struct urtwn_data *data;
10441556Srgrimes	int8_t nf, rssi;
10451556Srgrimes
10461556Srgrimes	URTWN_ASSERT_LOCKED(sc);
10471556Srgrimes
10481556Srgrimes	switch (USB_GET_STATE(xfer)) {
10491556Srgrimes	case USB_ST_TRANSFERRED:
10501556Srgrimes		data = STAILQ_FIRST(&sc->sc_rx_active);
10511556Srgrimes		if (data == NULL)
10521556Srgrimes			goto tr_setup;
10531556Srgrimes		STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
10541556Srgrimes		m = urtwn_report_intr(xfer, data);
1055117261Sdds		STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
10561556Srgrimes		/* FALLTHROUGH */
10571556Srgrimes	case USB_ST_SETUP:
10581556Srgrimestr_setup:
105990111Simp		data = STAILQ_FIRST(&sc->sc_rx_inactive);
106017987Speter		if (data == NULL) {
10611556Srgrimes			KASSERT(m == NULL, ("mbuf isn't NULL"));
10621556Srgrimes			return;
10631556Srgrimes		}
10641556Srgrimes		STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
10651556Srgrimes		STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
10661556Srgrimes		usbd_xfer_set_frame_data(xfer, 0, data->buf,
10671556Srgrimes		    usbd_xfer_max_len(xfer));
10681556Srgrimes		usbd_transfer_submit(xfer);
10691556Srgrimes
10701556Srgrimes		/*
10711556Srgrimes		 * To avoid LOR we should unlock our private mutex here to call
10721556Srgrimes		 * ieee80211_input() because here is at the end of a USB
10731556Srgrimes		 * callback and safe to unlock.
10741556Srgrimes		 */
10751556Srgrimes		while (m != NULL) {
10761556Srgrimes			next = m->m_next;
10771556Srgrimes			m->m_next = NULL;
10781556Srgrimes
10791556Srgrimes			ni = urtwn_rx_frame(sc, m, &rssi);
10801556Srgrimes			URTWN_UNLOCK(sc);
10811556Srgrimes
10821556Srgrimes			nf = URTWN_NOISE_FLOOR;
10831556Srgrimes			if (ni != NULL) {
10841556Srgrimes				(void)ieee80211_input(ni, m, rssi - nf, nf);
10851556Srgrimes				ieee80211_free_node(ni);
10861556Srgrimes			} else {
10871556Srgrimes				(void)ieee80211_input_all(ic, m, rssi - nf,
10881556Srgrimes				    nf);
10898855Srgrimes			}
10908855Srgrimes
10911556Srgrimes			URTWN_LOCK(sc);
10921556Srgrimes			m = next;
10931556Srgrimes		}
10941556Srgrimes		break;
10951556Srgrimes	default:
10961556Srgrimes		/* needs it to the inactive queue due to a error. */
10971556Srgrimes		data = STAILQ_FIRST(&sc->sc_rx_active);
10981556Srgrimes		if (data != NULL) {
10991556Srgrimes			STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
11001556Srgrimes			STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
11011556Srgrimes		}
11021556Srgrimes		if (error != USB_ERR_CANCELLED) {
11031556Srgrimes			usbd_xfer_set_stall(xfer);
11041556Srgrimes			counter_u64_add(ic->ic_ierrors, 1);
11051556Srgrimes			goto tr_setup;
11061556Srgrimes		}
11071556Srgrimes		break;
11081556Srgrimes	}
11091556Srgrimes}
11101556Srgrimes
11111556Srgrimesstatic void
11121556Srgrimesurtwn_txeof(struct urtwn_softc *sc, struct urtwn_data *data, int status)
111390111Simp{
111490111Simp
111525233Ssteve	URTWN_ASSERT_LOCKED(sc);
11161556Srgrimes
11171556Srgrimes	if (data->ni != NULL)	/* not a beacon frame */
11181556Srgrimes		ieee80211_tx_complete(data->ni, data->m, status);
11191556Srgrimes
11201556Srgrimes	data->ni = NULL;
11211556Srgrimes	data->m = NULL;
11221556Srgrimes
11231556Srgrimes	sc->sc_txtimer = 0;
11241556Srgrimes
11251556Srgrimes	STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
11261556Srgrimes}
11271556Srgrimes
11281556Srgrimesstatic int
11291556Srgrimesurtwn_alloc_list(struct urtwn_softc *sc, struct urtwn_data data[],
11301556Srgrimes    int ndata, int maxsz)
11311556Srgrimes{
11321556Srgrimes	int i, error;
113326488Sache
11341556Srgrimes	for (i = 0; i < ndata; i++) {
11351556Srgrimes		struct urtwn_data *dp = &data[i];
113638887Stegge		dp->sc = sc;
113738887Stegge		dp->m = NULL;
11381556Srgrimes		dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT);
11391556Srgrimes		if (dp->buf == NULL) {
11401556Srgrimes			device_printf(sc->sc_dev,
11411556Srgrimes			    "could not allocate buffer\n");
11421556Srgrimes			error = ENOMEM;
11431556Srgrimes			goto fail;
11441556Srgrimes		}
11451556Srgrimes		dp->ni = NULL;
11461556Srgrimes	}
11471556Srgrimes
11481556Srgrimes	return (0);
11491556Srgrimesfail:
11501556Srgrimes	urtwn_free_list(sc, data, ndata);
115138887Stegge	return (error);
115238887Stegge}
11531556Srgrimes
11541556Srgrimesstatic int
11551556Srgrimesurtwn_alloc_rx_list(struct urtwn_softc *sc)
11561556Srgrimes{
11571556Srgrimes        int error, i;
11581556Srgrimes
11591556Srgrimes	error = urtwn_alloc_list(sc, sc->sc_rx, URTWN_RX_LIST_COUNT,
11601556Srgrimes	    URTWN_RXBUFSZ);
11611556Srgrimes	if (error != 0)
11621556Srgrimes		return (error);
11631556Srgrimes
11641556Srgrimes	STAILQ_INIT(&sc->sc_rx_active);
116538887Stegge	STAILQ_INIT(&sc->sc_rx_inactive);
116638887Stegge
11671556Srgrimes	for (i = 0; i < URTWN_RX_LIST_COUNT; i++)
11681556Srgrimes		STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], next);
11691556Srgrimes
11701556Srgrimes	return (0);
11711556Srgrimes}
11721556Srgrimes
1173147812Sdelphijstatic int
11741556Srgrimesurtwn_alloc_tx_list(struct urtwn_softc *sc)
11751556Srgrimes{
11761556Srgrimes	int error, i;
11771556Srgrimes
11781556Srgrimes	error = urtwn_alloc_list(sc, sc->sc_tx, URTWN_TX_LIST_COUNT,
11791556Srgrimes	    URTWN_TXBUFSZ);
11801556Srgrimes	if (error != 0)
118138887Stegge		return (error);
118238887Stegge
11831556Srgrimes	STAILQ_INIT(&sc->sc_tx_active);
11841556Srgrimes	STAILQ_INIT(&sc->sc_tx_inactive);
11851556Srgrimes	STAILQ_INIT(&sc->sc_tx_pending);
11861556Srgrimes
11871556Srgrimes	for (i = 0; i < URTWN_TX_LIST_COUNT; i++)
11881556Srgrimes		STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i], next);
11891556Srgrimes
11901556Srgrimes	return (0);
11911556Srgrimes}
11921556Srgrimes
11931556Srgrimesstatic void
11941556Srgrimesurtwn_free_list(struct urtwn_softc *sc, struct urtwn_data data[], int ndata)
11951556Srgrimes{
11961556Srgrimes	int i;
11971556Srgrimes
11981556Srgrimes	for (i = 0; i < ndata; i++) {
11991556Srgrimes		struct urtwn_data *dp = &data[i];
12001556Srgrimes
12011556Srgrimes		if (dp->buf != NULL) {
12021556Srgrimes			free(dp->buf, M_USBDEV);
12031556Srgrimes			dp->buf = NULL;
12041556Srgrimes		}
12051556Srgrimes		if (dp->ni != NULL) {
12061556Srgrimes			ieee80211_free_node(dp->ni);
120738887Stegge			dp->ni = NULL;
120838887Stegge		}
120938887Stegge	}
121038887Stegge}
121138887Stegge
121238887Steggestatic void
12131556Srgrimesurtwn_free_rx_list(struct urtwn_softc *sc)
12141556Srgrimes{
12151556Srgrimes	urtwn_free_list(sc, sc->sc_rx, URTWN_RX_LIST_COUNT);
12161556Srgrimes}
121745514Stegge
12181556Srgrimesstatic void
12191556Srgrimesurtwn_free_tx_list(struct urtwn_softc *sc)
12201556Srgrimes{
12211556Srgrimes	urtwn_free_list(sc, sc->sc_tx, URTWN_TX_LIST_COUNT);
122217987Speter}
122317987Speter
122417987Speterstatic void
12251556Srgrimesurtwn_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
12261556Srgrimes{
12271556Srgrimes	struct urtwn_softc *sc = usbd_xfer_softc(xfer);
12281556Srgrimes	struct urtwn_data *data;
12291556Srgrimes
12301556Srgrimes	URTWN_ASSERT_LOCKED(sc);
12311556Srgrimes
12321556Srgrimes	switch (USB_GET_STATE(xfer)){
12331556Srgrimes	case USB_ST_TRANSFERRED:
12341556Srgrimes		data = STAILQ_FIRST(&sc->sc_tx_active);
12351556Srgrimes		if (data == NULL)
12361556Srgrimes			goto tr_setup;
12371556Srgrimes		STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next);
12381556Srgrimes		urtwn_txeof(sc, data, 0);
12391556Srgrimes		/* FALLTHROUGH */
12401556Srgrimes	case USB_ST_SETUP:
124190111Simptr_setup:
124290111Simp		data = STAILQ_FIRST(&sc->sc_tx_pending);
12431556Srgrimes		if (data == NULL) {
12441556Srgrimes			URTWN_DPRINTF(sc, URTWN_DEBUG_XMIT,
12451556Srgrimes			    "%s: empty pending queue\n", __func__);
12461556Srgrimes			goto finish;
12471556Srgrimes		}
12481556Srgrimes		STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next);
12491556Srgrimes		STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next);
12501556Srgrimes		usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
12511556Srgrimes		usbd_transfer_submit(xfer);
12521556Srgrimes		break;
12531556Srgrimes	default:
12541556Srgrimes		data = STAILQ_FIRST(&sc->sc_tx_active);
12551556Srgrimes		if (data == NULL)
12561556Srgrimes			goto tr_setup;
12571556Srgrimes		STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next);
12581556Srgrimes		urtwn_txeof(sc, data, 1);
12591556Srgrimes		if (error != USB_ERR_CANCELLED) {
12601556Srgrimes			usbd_xfer_set_stall(xfer);
12611556Srgrimes			goto tr_setup;
126290111Simp		}
126390111Simp		break;
12641556Srgrimes	}
12651556Srgrimesfinish:
12661556Srgrimes	/* Kick-start more transmit */
12671556Srgrimes	urtwn_start(sc);
12681556Srgrimes}
12691556Srgrimes
12701556Srgrimesstatic struct urtwn_data *
12711556Srgrimes_urtwn_getbuf(struct urtwn_softc *sc)
12721556Srgrimes{
12731556Srgrimes	struct urtwn_data *bf;
12741556Srgrimes
127590111Simp	bf = STAILQ_FIRST(&sc->sc_tx_inactive);
127617987Speter	if (bf != NULL)
127717987Speter		STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next);
12781556Srgrimes	else {
12791556Srgrimes		URTWN_DPRINTF(sc, URTWN_DEBUG_XMIT,
12801556Srgrimes		    "%s: out of xmit buffers\n", __func__);
12811556Srgrimes	}
12821556Srgrimes	return (bf);
12831556Srgrimes}
12848855Srgrimes
12851556Srgrimesstatic struct urtwn_data *
12861556Srgrimesurtwn_getbuf(struct urtwn_softc *sc)
12871556Srgrimes{
12881556Srgrimes        struct urtwn_data *bf;
12891556Srgrimes
12901556Srgrimes	URTWN_ASSERT_LOCKED(sc);
12911556Srgrimes
12921556Srgrimes	bf = _urtwn_getbuf(sc);
12931556Srgrimes	if (bf == NULL) {
12941556Srgrimes		URTWN_DPRINTF(sc, URTWN_DEBUG_XMIT, "%s: stop queue\n",
12951556Srgrimes		    __func__);
12961556Srgrimes	}
12971556Srgrimes	return (bf);
12981556Srgrimes}
12991556Srgrimes
13001556Srgrimesstatic usb_error_t
13011556Srgrimesurtwn_write_region_1(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf,
13021556Srgrimes    int len)
13031556Srgrimes{
13041556Srgrimes	usb_device_request_t req;
13051556Srgrimes
13061556Srgrimes	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
13071556Srgrimes	req.bRequest = R92C_REQ_REGS;
13081556Srgrimes	USETW(req.wValue, addr);
13091556Srgrimes	USETW(req.wIndex, 0);
13101556Srgrimes	USETW(req.wLength, len);
13111556Srgrimes	return (urtwn_do_request(sc, &req, buf));
13121556Srgrimes}
13131556Srgrimes
13141556Srgrimesstatic usb_error_t
13151556Srgrimesurtwn_write_1(struct urtwn_softc *sc, uint16_t addr, uint8_t val)
13161556Srgrimes{
13171556Srgrimes	return (urtwn_write_region_1(sc, addr, &val, sizeof(val)));
13181556Srgrimes}
13191556Srgrimes
13201556Srgrimesstatic usb_error_t
132190111Simpurtwn_write_2(struct urtwn_softc *sc, uint16_t addr, uint16_t val)
132290111Simp{
13231556Srgrimes	val = htole16(val);
13241556Srgrimes	return (urtwn_write_region_1(sc, addr, (uint8_t *)&val, sizeof(val)));
13251556Srgrimes}
13261556Srgrimes
13271556Srgrimesstatic usb_error_t
132845514Steggeurtwn_write_4(struct urtwn_softc *sc, uint16_t addr, uint32_t val)
13291556Srgrimes{
13301556Srgrimes	val = htole32(val);
133117987Speter	return (urtwn_write_region_1(sc, addr, (uint8_t *)&val, sizeof(val)));
133217525Sache}
133390111Simp
133490111Simpstatic usb_error_t
133525233Ssteveurtwn_read_region_1(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf,
133625233Ssteve    int len)
13371556Srgrimes{
13381556Srgrimes	usb_device_request_t req;
13391556Srgrimes
13401556Srgrimes	req.bmRequestType = UT_READ_VENDOR_DEVICE;
13411556Srgrimes	req.bRequest = R92C_REQ_REGS;
13421556Srgrimes	USETW(req.wValue, addr);
13431556Srgrimes	USETW(req.wIndex, 0);
13441556Srgrimes	USETW(req.wLength, len);
134545514Stegge	return (urtwn_do_request(sc, &req, buf));
134645514Stegge}
13471556Srgrimes
13481556Srgrimesstatic uint8_t
13491556Srgrimesurtwn_read_1(struct urtwn_softc *sc, uint16_t addr)
135038887Stegge{
135138887Stegge	uint8_t val;
13521556Srgrimes
135345514Stegge	if (urtwn_read_region_1(sc, addr, &val, 1) != 0)
135445514Stegge		return (0xff);
13551556Srgrimes	return (val);
13561556Srgrimes}
13571556Srgrimes
13581556Srgrimesstatic uint16_t
13591556Srgrimesurtwn_read_2(struct urtwn_softc *sc, uint16_t addr)
136038887Stegge{
136138887Stegge	uint16_t val;
136238887Stegge
136338887Stegge	if (urtwn_read_region_1(sc, addr, (uint8_t *)&val, 2) != 0)
13641556Srgrimes		return (0xffff);
136545514Stegge	return (le16toh(val));
136645514Stegge}
136745514Stegge
13681556Srgrimesstatic uint32_t
13691556Srgrimesurtwn_read_4(struct urtwn_softc *sc, uint16_t addr)
137045514Stegge{
137145514Stegge	uint32_t val;
13721556Srgrimes
13731556Srgrimes	if (urtwn_read_region_1(sc, addr, (uint8_t *)&val, 4) != 0)
13741556Srgrimes		return (0xffffffff);
13751556Srgrimes	return (le32toh(val));
137645514Stegge}
13771556Srgrimes
137845514Steggestatic int
137945514Steggeurtwn_fw_cmd(struct urtwn_softc *sc, uint8_t id, const void *buf, int len)
13801556Srgrimes{
13811556Srgrimes	struct r92c_fw_cmd cmd;
13821556Srgrimes	usb_error_t error;
13831556Srgrimes	int ntries;
13841556Srgrimes
13851556Srgrimes	if (!(sc->sc_flags & URTWN_FW_LOADED)) {
13861556Srgrimes		URTWN_DPRINTF(sc, URTWN_DEBUG_FIRMWARE, "%s: firmware "
13871556Srgrimes		    "was not loaded; command (id %d) will be discarded\n",
138826488Sache		    __func__, id);
13891556Srgrimes		return (0);
13901556Srgrimes	}
139138887Stegge
139238887Stegge	/* Wait for current FW box to be empty. */
13931556Srgrimes	for (ntries = 0; ntries < 100; ntries++) {
13941556Srgrimes		if (!(urtwn_read_1(sc, R92C_HMETFR) & (1 << sc->fwcur)))
13951556Srgrimes			break;
13961556Srgrimes		urtwn_ms_delay(sc);
13971556Srgrimes	}
13981556Srgrimes	if (ntries == 100) {
13991556Srgrimes		device_printf(sc->sc_dev,
14001556Srgrimes		    "could not send firmware command\n");
140126488Sache		return (ETIMEDOUT);
14021556Srgrimes	}
14031556Srgrimes	memset(&cmd, 0, sizeof(cmd));
14041556Srgrimes	cmd.id = id;
14051556Srgrimes	if (len > 3)
14061556Srgrimes		cmd.id |= R92C_CMD_FLAG_EXT;
140745514Stegge	KASSERT(len <= sizeof(cmd.msg), ("urtwn_fw_cmd\n"));
140845514Stegge	memcpy(cmd.msg, buf, len);
140917987Speter
141017987Speter	/* Write the first word last since that will trigger the FW. */
14111556Srgrimes	error = urtwn_write_region_1(sc, R92C_HMEBOX_EXT(sc->fwcur),
14121556Srgrimes	    (uint8_t *)&cmd + 4, 2);
141338887Stegge	if (error != USB_ERR_NORMAL_COMPLETION)
141438887Stegge		return (EIO);
14151556Srgrimes	error = urtwn_write_region_1(sc, R92C_HMEBOX(sc->fwcur),
14161556Srgrimes	    (uint8_t *)&cmd + 0, 4);
14171556Srgrimes	if (error != USB_ERR_NORMAL_COMPLETION)
14181556Srgrimes		return (EIO);
141938887Stegge
142038887Stegge	sc->fwcur = (sc->fwcur + 1) % R92C_H2C_NBOX;
14211556Srgrimes	return (0);
14221556Srgrimes}
142317557Sache
142417557Sachestatic void
142517525Sacheurtwn_cmdq_cb(void *arg, int pending)
14261556Srgrimes{
14271556Srgrimes	struct urtwn_softc *sc = arg;
14281556Srgrimes	struct urtwn_cmdq *item;
14291556Srgrimes
14301556Srgrimes	/*
14311556Srgrimes	 * Device must be powered on (via urtwn_power_on())
14321556Srgrimes	 * before any command may be sent.
14331556Srgrimes	 */
14341556Srgrimes	URTWN_LOCK(sc);
14351556Srgrimes	if (!(sc->sc_flags & URTWN_RUNNING)) {
14361556Srgrimes		URTWN_UNLOCK(sc);
14371556Srgrimes		return;
143845514Stegge	}
143945514Stegge
14401556Srgrimes	URTWN_CMDQ_LOCK(sc);
14411556Srgrimes	while (sc->cmdq[sc->cmdq_first].func != NULL) {
14421556Srgrimes		item = &sc->cmdq[sc->cmdq_first];
14431556Srgrimes		sc->cmdq_first = (sc->cmdq_first + 1) % URTWN_CMDQ_SIZE;
14441556Srgrimes		URTWN_CMDQ_UNLOCK(sc);
14451556Srgrimes
14461556Srgrimes		item->func(sc, &item->data);
14471556Srgrimes
14481556Srgrimes		URTWN_CMDQ_LOCK(sc);
14491556Srgrimes		memset(item, 0, sizeof (*item));
14501556Srgrimes	}
14511556Srgrimes	URTWN_CMDQ_UNLOCK(sc);
14521556Srgrimes	URTWN_UNLOCK(sc);
14531556Srgrimes}
14541556Srgrimes
14551556Srgrimesstatic int
14561556Srgrimesurtwn_cmd_sleepable(struct urtwn_softc *sc, const void *ptr, size_t len,
14571556Srgrimes    CMD_FUNC_PROTO)
145890111Simp{
145938887Stegge	struct ieee80211com *ic = &sc->sc_ic;
146025233Ssteve
14611556Srgrimes	KASSERT(len <= sizeof(union sec_param), ("buffer overflow"));
14621556Srgrimes
146338887Stegge	URTWN_CMDQ_LOCK(sc);
14641556Srgrimes	if (sc->cmdq[sc->cmdq_last].func != NULL) {
14651556Srgrimes		device_printf(sc->sc_dev, "%s: cmdq overflow\n", __func__);
14661556Srgrimes		URTWN_CMDQ_UNLOCK(sc);
14671556Srgrimes
14681556Srgrimes		return (EAGAIN);
146938887Stegge	}
147038887Stegge
147138887Stegge	if (ptr != NULL)
147238887Stegge		memcpy(&sc->cmdq[sc->cmdq_last].data, ptr, len);
14731556Srgrimes	sc->cmdq[sc->cmdq_last].func = func;
14741556Srgrimes	sc->cmdq_last = (sc->cmdq_last + 1) % URTWN_CMDQ_SIZE;
14751556Srgrimes	URTWN_CMDQ_UNLOCK(sc);
14761556Srgrimes
14771556Srgrimes	ieee80211_runtask(ic, &sc->cmdq_task);
14781556Srgrimes
14791556Srgrimes	return (0);
14801556Srgrimes}
14811556Srgrimes
14821556Srgrimesstatic __inline void
14831556Srgrimesurtwn_rf_write(struct urtwn_softc *sc, int chain, uint8_t addr, uint32_t val)
14841556Srgrimes{
14851556Srgrimes
14861556Srgrimes	sc->sc_rf_write(sc, chain, addr, val);
148790111Simp}
148890111Simp
14891556Srgrimesstatic void
14901556Srgrimesurtwn_r92c_rf_write(struct urtwn_softc *sc, int chain, uint8_t addr,
14911556Srgrimes    uint32_t val)
14921556Srgrimes{
14931556Srgrimes	urtwn_bb_write(sc, R92C_LSSI_PARAM(chain),
14941556Srgrimes	    SM(R92C_LSSI_PARAM_ADDR, addr) |
14951556Srgrimes	    SM(R92C_LSSI_PARAM_DATA, val));
14961556Srgrimes}
14971556Srgrimes
14981556Srgrimesstatic void
14991556Srgrimesurtwn_r88e_rf_write(struct urtwn_softc *sc, int chain, uint8_t addr,
150045514Steggeuint32_t val)
15011556Srgrimes{
15021556Srgrimes	urtwn_bb_write(sc, R92C_LSSI_PARAM(chain),
15031556Srgrimes	    SM(R88E_LSSI_PARAM_ADDR, addr) |
150417987Speter	    SM(R92C_LSSI_PARAM_DATA, val));
150517987Speter}
150617987Speter
150717987Speterstatic uint32_t
150817987Speterurtwn_rf_read(struct urtwn_softc *sc, int chain, uint8_t addr)
150917987Speter{
151090111Simp	uint32_t reg[R92C_MAX_CHAINS], val;
151190111Simp
151217987Speter	reg[0] = urtwn_bb_read(sc, R92C_HSSI_PARAM2(0));
151317987Speter	if (chain != 0)
151417987Speter		reg[chain] = urtwn_bb_read(sc, R92C_HSSI_PARAM2(chain));
151517987Speter
151617987Speter	urtwn_bb_write(sc, R92C_HSSI_PARAM2(0),
151717987Speter	    reg[0] & ~R92C_HSSI_PARAM2_READ_EDGE);
151817987Speter	urtwn_ms_delay(sc);
151917987Speter
152017987Speter	urtwn_bb_write(sc, R92C_HSSI_PARAM2(chain),
152117987Speter	    RW(reg[chain], R92C_HSSI_PARAM2_READ_ADDR, addr) |
152217987Speter	    R92C_HSSI_PARAM2_READ_EDGE);
152317987Speter	urtwn_ms_delay(sc);
152417987Speter
152517987Speter	urtwn_bb_write(sc, R92C_HSSI_PARAM2(0),
152617987Speter	    reg[0] | R92C_HSSI_PARAM2_READ_EDGE);
152717987Speter	urtwn_ms_delay(sc);
152817987Speter
1529108286Stjr	if (urtwn_bb_read(sc, R92C_HSSI_PARAM1(chain)) & R92C_HSSI_PARAM1_PI)
1530108286Stjr		val = urtwn_bb_read(sc, R92C_HSPI_READBACK(chain));
1531108286Stjr	else
1532108286Stjr		val = urtwn_bb_read(sc, R92C_LSSI_READBACK(chain));
1533108286Stjr	return (MS(val, R92C_LSSI_READBACK_DATA));
1534108286Stjr}
1535108286Stjr
1536108286Stjrstatic int
1537108286Stjrurtwn_llt_write(struct urtwn_softc *sc, uint32_t addr, uint32_t data)
1538108286Stjr{
1539108286Stjr	usb_error_t error;
1540108286Stjr	int ntries;
1541108286Stjr
1542108286Stjr	error = urtwn_write_4(sc, R92C_LLT_INIT,
1543108286Stjr	    SM(R92C_LLT_INIT_OP, R92C_LLT_INIT_OP_WRITE) |
1544108286Stjr	    SM(R92C_LLT_INIT_ADDR, addr) |
1545108286Stjr	    SM(R92C_LLT_INIT_DATA, data));
1546108286Stjr	if (error != USB_ERR_NORMAL_COMPLETION)
1547108286Stjr		return (EIO);
1548108286Stjr	/* Wait for write operation to complete. */
1549108286Stjr	for (ntries = 0; ntries < 20; ntries++) {
1550		if (MS(urtwn_read_4(sc, R92C_LLT_INIT), R92C_LLT_INIT_OP) ==
1551		    R92C_LLT_INIT_OP_NO_ACTIVE)
1552			return (0);
1553		urtwn_ms_delay(sc);
1554	}
1555	return (ETIMEDOUT);
1556}
1557
1558static int
1559urtwn_efuse_read_next(struct urtwn_softc *sc, uint8_t *val)
1560{
1561	uint32_t reg;
1562	usb_error_t error;
1563	int ntries;
1564
1565	if (sc->last_rom_addr >= URTWN_EFUSE_MAX_LEN)
1566		return (EFAULT);
1567
1568	reg = urtwn_read_4(sc, R92C_EFUSE_CTRL);
1569	reg = RW(reg, R92C_EFUSE_CTRL_ADDR, sc->last_rom_addr);
1570	reg &= ~R92C_EFUSE_CTRL_VALID;
1571
1572	error = urtwn_write_4(sc, R92C_EFUSE_CTRL, reg);
1573	if (error != USB_ERR_NORMAL_COMPLETION)
1574		return (EIO);
1575	/* Wait for read operation to complete. */
1576	for (ntries = 0; ntries < 100; ntries++) {
1577		reg = urtwn_read_4(sc, R92C_EFUSE_CTRL);
1578		if (reg & R92C_EFUSE_CTRL_VALID)
1579			break;
1580		urtwn_ms_delay(sc);
1581	}
1582	if (ntries == 100) {
1583		device_printf(sc->sc_dev,
1584		    "could not read efuse byte at address 0x%x\n",
1585		    sc->last_rom_addr);
1586		return (ETIMEDOUT);
1587	}
1588
1589	*val = MS(reg, R92C_EFUSE_CTRL_DATA);
1590	sc->last_rom_addr++;
1591
1592	return (0);
1593}
1594
1595static int
1596urtwn_efuse_read_data(struct urtwn_softc *sc, uint8_t *rom, uint8_t off,
1597    uint8_t msk)
1598{
1599	uint8_t reg;
1600	int i, error;
1601
1602	for (i = 0; i < 4; i++) {
1603		if (msk & (1 << i))
1604			continue;
1605		error = urtwn_efuse_read_next(sc, &reg);
1606		if (error != 0)
1607			return (error);
1608		URTWN_DPRINTF(sc, URTWN_DEBUG_ROM, "rom[0x%03X] == 0x%02X\n",
1609		    off * 8 + i * 2, reg);
1610		rom[off * 8 + i * 2 + 0] = reg;
1611
1612		error = urtwn_efuse_read_next(sc, &reg);
1613		if (error != 0)
1614			return (error);
1615		URTWN_DPRINTF(sc, URTWN_DEBUG_ROM, "rom[0x%03X] == 0x%02X\n",
1616		    off * 8 + i * 2 + 1, reg);
1617		rom[off * 8 + i * 2 + 1] = reg;
1618	}
1619
1620	return (0);
1621}
1622
1623#ifdef USB_DEBUG
1624static void
1625urtwn_dump_rom_contents(struct urtwn_softc *sc, uint8_t *rom, uint16_t size)
1626{
1627	int i;
1628
1629	/* Dump ROM contents. */
1630	device_printf(sc->sc_dev, "%s:", __func__);
1631	for (i = 0; i < size; i++) {
1632		if (i % 32 == 0)
1633			printf("\n%03X: ", i);
1634		else if (i % 4 == 0)
1635			printf(" ");
1636
1637		printf("%02X", rom[i]);
1638	}
1639	printf("\n");
1640}
1641#endif
1642
1643static int
1644urtwn_efuse_read(struct urtwn_softc *sc, uint8_t *rom, uint16_t size)
1645{
1646#define URTWN_CHK(res) do {	\
1647	if ((error = res) != 0)	\
1648		goto end;	\
1649} while(0)
1650	uint8_t msk, off, reg;
1651	int error;
1652
1653	URTWN_CHK(urtwn_efuse_switch_power(sc));
1654
1655	/* Read full ROM image. */
1656	sc->last_rom_addr = 0;
1657	memset(rom, 0xff, size);
1658
1659	URTWN_CHK(urtwn_efuse_read_next(sc, &reg));
1660	while (reg != 0xff) {
1661		/* check for extended header */
1662		if ((sc->chip & URTWN_CHIP_88E) && (reg & 0x1f) == 0x0f) {
1663			off = reg >> 5;
1664			URTWN_CHK(urtwn_efuse_read_next(sc, &reg));
1665
1666			if ((reg & 0x0f) != 0x0f)
1667				off = ((reg & 0xf0) >> 1) | off;
1668			else
1669				continue;
1670		} else
1671			off = reg >> 4;
1672		msk = reg & 0xf;
1673
1674		URTWN_CHK(urtwn_efuse_read_data(sc, rom, off, msk));
1675		URTWN_CHK(urtwn_efuse_read_next(sc, &reg));
1676	}
1677
1678end:
1679
1680#ifdef USB_DEBUG
1681	if (sc->sc_debug & URTWN_DEBUG_ROM)
1682		urtwn_dump_rom_contents(sc, rom, size);
1683#endif
1684
1685	urtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_OFF);
1686
1687	if (error != 0) {
1688		device_printf(sc->sc_dev, "%s: error while reading ROM\n",
1689		    __func__);
1690	}
1691
1692	return (error);
1693#undef URTWN_CHK
1694}
1695
1696static int
1697urtwn_efuse_switch_power(struct urtwn_softc *sc)
1698{
1699	usb_error_t error;
1700	uint32_t reg;
1701
1702	error = urtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_ON);
1703	if (error != USB_ERR_NORMAL_COMPLETION)
1704		return (EIO);
1705
1706	reg = urtwn_read_2(sc, R92C_SYS_ISO_CTRL);
1707	if (!(reg & R92C_SYS_ISO_CTRL_PWC_EV12V)) {
1708		error = urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
1709		    reg | R92C_SYS_ISO_CTRL_PWC_EV12V);
1710		if (error != USB_ERR_NORMAL_COMPLETION)
1711			return (EIO);
1712	}
1713	reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
1714	if (!(reg & R92C_SYS_FUNC_EN_ELDR)) {
1715		error = urtwn_write_2(sc, R92C_SYS_FUNC_EN,
1716		    reg | R92C_SYS_FUNC_EN_ELDR);
1717		if (error != USB_ERR_NORMAL_COMPLETION)
1718			return (EIO);
1719	}
1720	reg = urtwn_read_2(sc, R92C_SYS_CLKR);
1721	if ((reg & (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) !=
1722	    (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) {
1723		error = urtwn_write_2(sc, R92C_SYS_CLKR,
1724		    reg | R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M);
1725		if (error != USB_ERR_NORMAL_COMPLETION)
1726			return (EIO);
1727	}
1728
1729	return (0);
1730}
1731
1732static int
1733urtwn_read_chipid(struct urtwn_softc *sc)
1734{
1735	uint32_t reg;
1736
1737	if (sc->chip & URTWN_CHIP_88E)
1738		return (0);
1739
1740	reg = urtwn_read_4(sc, R92C_SYS_CFG);
1741	if (reg & R92C_SYS_CFG_TRP_VAUX_EN)
1742		return (EIO);
1743
1744	if (reg & R92C_SYS_CFG_TYPE_92C) {
1745		sc->chip |= URTWN_CHIP_92C;
1746		/* Check if it is a castrated 8192C. */
1747		if (MS(urtwn_read_4(sc, R92C_HPON_FSM),
1748		    R92C_HPON_FSM_CHIP_BONDING_ID) ==
1749		    R92C_HPON_FSM_CHIP_BONDING_ID_92C_1T2R)
1750			sc->chip |= URTWN_CHIP_92C_1T2R;
1751	}
1752	if (reg & R92C_SYS_CFG_VENDOR_UMC) {
1753		sc->chip |= URTWN_CHIP_UMC;
1754		if (MS(reg, R92C_SYS_CFG_CHIP_VER_RTL) == 0)
1755			sc->chip |= URTWN_CHIP_UMC_A_CUT;
1756	}
1757	return (0);
1758}
1759
1760static int
1761urtwn_read_rom(struct urtwn_softc *sc)
1762{
1763	struct r92c_rom *rom = &sc->rom.r92c_rom;
1764	int error;
1765
1766	/* Read full ROM image. */
1767	error = urtwn_efuse_read(sc, (uint8_t *)rom, sizeof(*rom));
1768	if (error != 0)
1769		return (error);
1770
1771	/* XXX Weird but this is what the vendor driver does. */
1772	sc->last_rom_addr = 0x1fa;
1773	error = urtwn_efuse_read_next(sc, &sc->pa_setting);
1774	if (error != 0)
1775		return (error);
1776	URTWN_DPRINTF(sc, URTWN_DEBUG_ROM, "%s: PA setting=0x%x\n", __func__,
1777	    sc->pa_setting);
1778
1779	sc->board_type = MS(rom->rf_opt1, R92C_ROM_RF1_BOARD_TYPE);
1780
1781	sc->regulatory = MS(rom->rf_opt1, R92C_ROM_RF1_REGULATORY);
1782	URTWN_DPRINTF(sc, URTWN_DEBUG_ROM, "%s: regulatory type=%d\n",
1783	    __func__, sc->regulatory);
1784	IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, rom->macaddr);
1785
1786	sc->sc_rf_write = urtwn_r92c_rf_write;
1787	sc->sc_power_on = urtwn_r92c_power_on;
1788	sc->sc_power_off = urtwn_r92c_power_off;
1789
1790	return (0);
1791}
1792
1793static int
1794urtwn_r88e_read_rom(struct urtwn_softc *sc)
1795{
1796	struct r88e_rom *rom = &sc->rom.r88e_rom;
1797	int error;
1798
1799	error = urtwn_efuse_read(sc, (uint8_t *)rom, sizeof(sc->rom.r88e_rom));
1800	if (error != 0)
1801		return (error);
1802
1803	sc->bw20_tx_pwr_diff = (rom->tx_pwr_diff >> 4);
1804	if (sc->bw20_tx_pwr_diff & 0x08)
1805		sc->bw20_tx_pwr_diff |= 0xf0;
1806	sc->ofdm_tx_pwr_diff = (rom->tx_pwr_diff & 0xf);
1807	if (sc->ofdm_tx_pwr_diff & 0x08)
1808		sc->ofdm_tx_pwr_diff |= 0xf0;
1809	sc->regulatory = MS(rom->rf_board_opt, R92C_ROM_RF1_REGULATORY);
1810	URTWN_DPRINTF(sc, URTWN_DEBUG_ROM, "%s: regulatory type %d\n",
1811	    __func__,sc->regulatory);
1812	IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, rom->macaddr);
1813
1814	sc->sc_rf_write = urtwn_r88e_rf_write;
1815	sc->sc_power_on = urtwn_r88e_power_on;
1816	sc->sc_power_off = urtwn_r88e_power_off;
1817
1818	return (0);
1819}
1820
1821/*
1822 * Initialize rate adaptation in firmware.
1823 */
1824static int
1825urtwn_ra_init(struct urtwn_softc *sc)
1826{
1827	struct ieee80211com *ic = &sc->sc_ic;
1828	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1829	struct ieee80211_node *ni;
1830	struct ieee80211_rateset *rs;
1831	struct r92c_fw_cmd_macid_cfg cmd;
1832	uint32_t rates, basicrates;
1833	uint8_t mode;
1834	int maxrate, maxbasicrate, error, i, j;
1835
1836	ni = ieee80211_ref_node(vap->iv_bss);
1837	rs = &ni->ni_rates;
1838
1839	/* Get normal and basic rates mask. */
1840	rates = basicrates = 0;
1841	maxrate = maxbasicrate = 0;
1842	for (i = 0; i < rs->rs_nrates; i++) {
1843		/* Convert 802.11 rate to HW rate index. */
1844		for (j = 0; j < nitems(ridx2rate); j++)
1845			if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) ==
1846			    ridx2rate[j])
1847				break;
1848		if (j == nitems(ridx2rate))	/* Unknown rate, skip. */
1849			continue;
1850		rates |= 1 << j;
1851		if (j > maxrate)
1852			maxrate = j;
1853		if (rs->rs_rates[i] & IEEE80211_RATE_BASIC) {
1854			basicrates |= 1 << j;
1855			if (j > maxbasicrate)
1856				maxbasicrate = j;
1857		}
1858	}
1859	if (ic->ic_curmode == IEEE80211_MODE_11B)
1860		mode = R92C_RAID_11B;
1861	else
1862		mode = R92C_RAID_11BG;
1863	URTWN_DPRINTF(sc, URTWN_DEBUG_RA,
1864	    "%s: mode 0x%x, rates 0x%08x, basicrates 0x%08x\n", __func__,
1865	    mode, rates, basicrates);
1866
1867	/* Set rates mask for group addressed frames. */
1868	cmd.macid = URTWN_MACID_BC | URTWN_MACID_VALID;
1869	cmd.mask = htole32(mode << 28 | basicrates);
1870	error = urtwn_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd));
1871	if (error != 0) {
1872		ieee80211_free_node(ni);
1873		device_printf(sc->sc_dev,
1874		    "could not add broadcast station\n");
1875		return (error);
1876	}
1877	/* Set initial MRR rate. */
1878	URTWN_DPRINTF(sc, URTWN_DEBUG_RA, "%s: maxbasicrate %d\n", __func__,
1879	    maxbasicrate);
1880	urtwn_write_1(sc, R92C_INIDATA_RATE_SEL(URTWN_MACID_BC),
1881	    maxbasicrate);
1882
1883	/* Set rates mask for unicast frames. */
1884	cmd.macid = URTWN_MACID_BSS | URTWN_MACID_VALID;
1885	cmd.mask = htole32(mode << 28 | rates);
1886	error = urtwn_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd));
1887	if (error != 0) {
1888		ieee80211_free_node(ni);
1889		device_printf(sc->sc_dev, "could not add BSS station\n");
1890		return (error);
1891	}
1892	/* Set initial MRR rate. */
1893	URTWN_DPRINTF(sc, URTWN_DEBUG_RA, "%s: maxrate %d\n", __func__,
1894	    maxrate);
1895	urtwn_write_1(sc, R92C_INIDATA_RATE_SEL(URTWN_MACID_BSS),
1896	    maxrate);
1897
1898	/* Indicate highest supported rate. */
1899	ni->ni_txrate = rs->rs_rates[rs->rs_nrates - 1];
1900	ieee80211_free_node(ni);
1901
1902	return (0);
1903}
1904
1905static void
1906urtwn_init_beacon(struct urtwn_softc *sc, struct urtwn_vap *uvp)
1907{
1908	struct r92c_tx_desc *txd = &uvp->bcn_desc;
1909
1910	txd->txdw0 = htole32(
1911	    SM(R92C_TXDW0_OFFSET, sizeof(*txd)) | R92C_TXDW0_BMCAST |
1912	    R92C_TXDW0_OWN | R92C_TXDW0_FSG | R92C_TXDW0_LSG);
1913	txd->txdw1 = htole32(
1914	    SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BEACON) |
1915	    SM(R92C_TXDW1_RAID, R92C_RAID_11B));
1916
1917	if (sc->chip & URTWN_CHIP_88E) {
1918		txd->txdw1 |= htole32(SM(R88E_TXDW1_MACID, URTWN_MACID_BC));
1919		txd->txdseq |= htole16(R88E_TXDSEQ_HWSEQ_EN);
1920	} else {
1921		txd->txdw1 |= htole32(SM(R92C_TXDW1_MACID, URTWN_MACID_BC));
1922		txd->txdw4 |= htole32(R92C_TXDW4_HWSEQ_EN);
1923	}
1924
1925	txd->txdw4 = htole32(R92C_TXDW4_DRVRATE);
1926	txd->txdw5 = htole32(SM(R92C_TXDW5_DATARATE, URTWN_RIDX_CCK1));
1927}
1928
1929static int
1930urtwn_setup_beacon(struct urtwn_softc *sc, struct ieee80211_node *ni)
1931{
1932 	struct ieee80211vap *vap = ni->ni_vap;
1933	struct urtwn_vap *uvp = URTWN_VAP(vap);
1934	struct mbuf *m;
1935	int error;
1936
1937	URTWN_ASSERT_LOCKED(sc);
1938
1939	if (ni->ni_chan == IEEE80211_CHAN_ANYC)
1940		return (EINVAL);
1941
1942	m = ieee80211_beacon_alloc(ni);
1943	if (m == NULL) {
1944		device_printf(sc->sc_dev,
1945		    "%s: could not allocate beacon frame\n", __func__);
1946		return (ENOMEM);
1947	}
1948
1949	if (uvp->bcn_mbuf != NULL)
1950		m_freem(uvp->bcn_mbuf);
1951
1952	uvp->bcn_mbuf = m;
1953
1954	if ((error = urtwn_tx_beacon(sc, uvp)) != 0)
1955		return (error);
1956
1957	/* XXX bcnq stuck workaround */
1958	if ((error = urtwn_tx_beacon(sc, uvp)) != 0)
1959		return (error);
1960
1961	URTWN_DPRINTF(sc, URTWN_DEBUG_BEACON, "%s: beacon was %srecognized\n",
1962	    __func__, urtwn_read_1(sc, R92C_TDECTRL + 2) &
1963	    (R92C_TDECTRL_BCN_VALID >> 16) ? "" : "not ");
1964
1965	return (0);
1966}
1967
1968static void
1969urtwn_update_beacon(struct ieee80211vap *vap, int item)
1970{
1971	struct urtwn_softc *sc = vap->iv_ic->ic_softc;
1972	struct urtwn_vap *uvp = URTWN_VAP(vap);
1973	struct ieee80211_beacon_offsets *bo = &vap->iv_bcn_off;
1974	struct ieee80211_node *ni = vap->iv_bss;
1975	int mcast = 0;
1976
1977	URTWN_LOCK(sc);
1978	if (uvp->bcn_mbuf == NULL) {
1979		uvp->bcn_mbuf = ieee80211_beacon_alloc(ni);
1980		if (uvp->bcn_mbuf == NULL) {
1981			device_printf(sc->sc_dev,
1982			    "%s: could not allocate beacon frame\n", __func__);
1983			URTWN_UNLOCK(sc);
1984			return;
1985		}
1986	}
1987	URTWN_UNLOCK(sc);
1988
1989	if (item == IEEE80211_BEACON_TIM)
1990		mcast = 1;	/* XXX */
1991
1992	setbit(bo->bo_flags, item);
1993	ieee80211_beacon_update(ni, uvp->bcn_mbuf, mcast);
1994
1995	URTWN_LOCK(sc);
1996	urtwn_tx_beacon(sc, uvp);
1997	URTWN_UNLOCK(sc);
1998}
1999
2000/*
2001 * Push a beacon frame into the chip. Beacon will
2002 * be repeated by the chip every R92C_BCN_INTERVAL.
2003 */
2004static int
2005urtwn_tx_beacon(struct urtwn_softc *sc, struct urtwn_vap *uvp)
2006{
2007	struct r92c_tx_desc *desc = &uvp->bcn_desc;
2008	struct urtwn_data *bf;
2009
2010	URTWN_ASSERT_LOCKED(sc);
2011
2012	bf = urtwn_getbuf(sc);
2013	if (bf == NULL)
2014		return (ENOMEM);
2015
2016	memcpy(bf->buf, desc, sizeof(*desc));
2017	urtwn_tx_start(sc, uvp->bcn_mbuf, IEEE80211_FC0_TYPE_MGT, bf);
2018
2019	sc->sc_txtimer = 5;
2020	callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc);
2021
2022	return (0);
2023}
2024
2025static int
2026urtwn_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
2027    ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
2028{
2029	struct urtwn_softc *sc = vap->iv_ic->ic_softc;
2030	uint8_t i;
2031
2032	if (!(&vap->iv_nw_keys[0] <= k &&
2033	     k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) {
2034		if (!(k->wk_flags & IEEE80211_KEY_SWCRYPT)) {
2035			URTWN_LOCK(sc);
2036			/*
2037			 * First 4 slots for group keys,
2038			 * what is left - for pairwise.
2039			 * XXX incompatible with IBSS RSN.
2040			 */
2041			for (i = IEEE80211_WEP_NKID;
2042			     i < R92C_CAM_ENTRY_COUNT; i++) {
2043				if ((sc->keys_bmap & (1 << i)) == 0) {
2044					sc->keys_bmap |= 1 << i;
2045					*keyix = i;
2046					break;
2047				}
2048			}
2049			URTWN_UNLOCK(sc);
2050			if (i == R92C_CAM_ENTRY_COUNT) {
2051				device_printf(sc->sc_dev,
2052				    "%s: no free space in the key table\n",
2053				    __func__);
2054				return 0;
2055			}
2056		} else
2057			*keyix = 0;
2058	} else {
2059		*keyix = k - vap->iv_nw_keys;
2060	}
2061	*rxkeyix = *keyix;
2062	return 1;
2063}
2064
2065static void
2066urtwn_key_set_cb(struct urtwn_softc *sc, union sec_param *data)
2067{
2068	struct ieee80211_key *k = &data->key;
2069	uint8_t algo, keyid;
2070	int i, error;
2071
2072	if (k->wk_keyix < IEEE80211_WEP_NKID)
2073		keyid = k->wk_keyix;
2074	else
2075		keyid = 0;
2076
2077	/* Map net80211 cipher to HW crypto algorithm. */
2078	switch (k->wk_cipher->ic_cipher) {
2079	case IEEE80211_CIPHER_WEP:
2080		if (k->wk_keylen < 8)
2081			algo = R92C_CAM_ALGO_WEP40;
2082		else
2083			algo = R92C_CAM_ALGO_WEP104;
2084		break;
2085	case IEEE80211_CIPHER_TKIP:
2086		algo = R92C_CAM_ALGO_TKIP;
2087		break;
2088	case IEEE80211_CIPHER_AES_CCM:
2089		algo = R92C_CAM_ALGO_AES;
2090		break;
2091	default:
2092		device_printf(sc->sc_dev, "%s: undefined cipher %d\n",
2093		    __func__, k->wk_cipher->ic_cipher);
2094		return;
2095	}
2096
2097	URTWN_DPRINTF(sc, URTWN_DEBUG_KEY,
2098	    "%s: keyix %d, keyid %d, algo %d/%d, flags %04X, len %d, "
2099	    "macaddr %s\n", __func__, k->wk_keyix, keyid,
2100	    k->wk_cipher->ic_cipher, algo, k->wk_flags, k->wk_keylen,
2101	    ether_sprintf(k->wk_macaddr));
2102
2103	/* Write key. */
2104	for (i = 0; i < 4; i++) {
2105		error = urtwn_cam_write(sc, R92C_CAM_KEY(k->wk_keyix, i),
2106		    LE_READ_4(&k->wk_key[i * 4]));
2107		if (error != 0)
2108			goto fail;
2109	}
2110
2111	/* Write CTL0 last since that will validate the CAM entry. */
2112	error = urtwn_cam_write(sc, R92C_CAM_CTL1(k->wk_keyix),
2113	    LE_READ_4(&k->wk_macaddr[2]));
2114	if (error != 0)
2115		goto fail;
2116	error = urtwn_cam_write(sc, R92C_CAM_CTL0(k->wk_keyix),
2117	    SM(R92C_CAM_ALGO, algo) |
2118	    SM(R92C_CAM_KEYID, keyid) |
2119	    SM(R92C_CAM_MACLO, LE_READ_2(&k->wk_macaddr[0])) |
2120	    R92C_CAM_VALID);
2121	if (error != 0)
2122		goto fail;
2123
2124	return;
2125
2126fail:
2127	device_printf(sc->sc_dev, "%s fails, error %d\n", __func__, error);
2128}
2129
2130static void
2131urtwn_key_del_cb(struct urtwn_softc *sc, union sec_param *data)
2132{
2133	struct ieee80211_key *k = &data->key;
2134	int i;
2135
2136	URTWN_DPRINTF(sc, URTWN_DEBUG_KEY,
2137	    "%s: keyix %d, flags %04X, macaddr %s\n", __func__,
2138	    k->wk_keyix, k->wk_flags, ether_sprintf(k->wk_macaddr));
2139
2140	urtwn_cam_write(sc, R92C_CAM_CTL0(k->wk_keyix), 0);
2141	urtwn_cam_write(sc, R92C_CAM_CTL1(k->wk_keyix), 0);
2142
2143	/* Clear key. */
2144	for (i = 0; i < 4; i++)
2145		urtwn_cam_write(sc, R92C_CAM_KEY(k->wk_keyix, i), 0);
2146	sc->keys_bmap &= ~(1 << k->wk_keyix);
2147}
2148
2149static int
2150urtwn_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
2151{
2152	struct urtwn_softc *sc = vap->iv_ic->ic_softc;
2153
2154	if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
2155		/* Not for us. */
2156		return (1);
2157	}
2158
2159	return (!urtwn_cmd_sleepable(sc, k, sizeof(*k), urtwn_key_set_cb));
2160}
2161
2162static int
2163urtwn_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
2164{
2165	struct urtwn_softc *sc = vap->iv_ic->ic_softc;
2166
2167	if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
2168		/* Not for us. */
2169		return (1);
2170	}
2171
2172	return (!urtwn_cmd_sleepable(sc, k, sizeof(*k), urtwn_key_del_cb));
2173}
2174
2175static void
2176urtwn_tsf_task_adhoc(void *arg, int pending)
2177{
2178	struct ieee80211vap *vap = arg;
2179	struct urtwn_softc *sc = vap->iv_ic->ic_softc;
2180	struct ieee80211_node *ni;
2181	uint32_t reg;
2182
2183	URTWN_LOCK(sc);
2184	ni = ieee80211_ref_node(vap->iv_bss);
2185	reg = urtwn_read_1(sc, R92C_BCN_CTRL);
2186
2187	/* Accept beacons with the same BSSID. */
2188	urtwn_set_rx_bssid_all(sc, 0);
2189
2190	/* Enable synchronization. */
2191	reg &= ~R92C_BCN_CTRL_DIS_TSF_UDT0;
2192	urtwn_write_1(sc, R92C_BCN_CTRL, reg);
2193
2194	/* Synchronize. */
2195	usb_pause_mtx(&sc->sc_mtx, hz * ni->ni_intval * 5 / 1000);
2196
2197	/* Disable synchronization. */
2198	reg |= R92C_BCN_CTRL_DIS_TSF_UDT0;
2199	urtwn_write_1(sc, R92C_BCN_CTRL, reg);
2200
2201	/* Remove beacon filter. */
2202	urtwn_set_rx_bssid_all(sc, 1);
2203
2204	/* Enable beaconing. */
2205	urtwn_write_1(sc, R92C_MBID_NUM,
2206	    urtwn_read_1(sc, R92C_MBID_NUM) | R92C_MBID_TXBCN_RPT0);
2207	reg |= R92C_BCN_CTRL_EN_BCN;
2208
2209	urtwn_write_1(sc, R92C_BCN_CTRL, reg);
2210	ieee80211_free_node(ni);
2211	URTWN_UNLOCK(sc);
2212}
2213
2214static void
2215urtwn_tsf_sync_enable(struct urtwn_softc *sc, struct ieee80211vap *vap)
2216{
2217	struct ieee80211com *ic = &sc->sc_ic;
2218	struct urtwn_vap *uvp = URTWN_VAP(vap);
2219
2220	/* Reset TSF. */
2221	urtwn_write_1(sc, R92C_DUAL_TSF_RST, R92C_DUAL_TSF_RST0);
2222
2223	switch (vap->iv_opmode) {
2224	case IEEE80211_M_STA:
2225		/* Enable TSF synchronization. */
2226		urtwn_write_1(sc, R92C_BCN_CTRL,
2227		    urtwn_read_1(sc, R92C_BCN_CTRL) &
2228		    ~R92C_BCN_CTRL_DIS_TSF_UDT0);
2229		break;
2230	case IEEE80211_M_IBSS:
2231		ieee80211_runtask(ic, &uvp->tsf_task_adhoc);
2232		break;
2233	case IEEE80211_M_HOSTAP:
2234		/* Enable beaconing. */
2235		urtwn_write_1(sc, R92C_MBID_NUM,
2236		    urtwn_read_1(sc, R92C_MBID_NUM) | R92C_MBID_TXBCN_RPT0);
2237		urtwn_write_1(sc, R92C_BCN_CTRL,
2238		    urtwn_read_1(sc, R92C_BCN_CTRL) | R92C_BCN_CTRL_EN_BCN);
2239		break;
2240	default:
2241		device_printf(sc->sc_dev, "undefined opmode %d\n",
2242		    vap->iv_opmode);
2243		return;
2244	}
2245}
2246
2247static void
2248urtwn_get_tsf(struct urtwn_softc *sc, uint64_t *buf)
2249{
2250	urtwn_read_region_1(sc, R92C_TSFTR, (uint8_t *)buf, sizeof(*buf));
2251}
2252
2253static void
2254urtwn_set_led(struct urtwn_softc *sc, int led, int on)
2255{
2256	uint8_t reg;
2257
2258	if (led == URTWN_LED_LINK) {
2259		if (sc->chip & URTWN_CHIP_88E) {
2260			reg = urtwn_read_1(sc, R92C_LEDCFG2) & 0xf0;
2261			urtwn_write_1(sc, R92C_LEDCFG2, reg | 0x60);
2262			if (!on) {
2263				reg = urtwn_read_1(sc, R92C_LEDCFG2) & 0x90;
2264				urtwn_write_1(sc, R92C_LEDCFG2,
2265				    reg | R92C_LEDCFG0_DIS);
2266				urtwn_write_1(sc, R92C_MAC_PINMUX_CFG,
2267				    urtwn_read_1(sc, R92C_MAC_PINMUX_CFG) &
2268				    0xfe);
2269			}
2270		} else {
2271			reg = urtwn_read_1(sc, R92C_LEDCFG0) & 0x70;
2272			if (!on)
2273				reg |= R92C_LEDCFG0_DIS;
2274			urtwn_write_1(sc, R92C_LEDCFG0, reg);
2275		}
2276		sc->ledlink = on;       /* Save LED state. */
2277	}
2278}
2279
2280static void
2281urtwn_set_mode(struct urtwn_softc *sc, uint8_t mode)
2282{
2283	uint8_t reg;
2284
2285	reg = urtwn_read_1(sc, R92C_MSR);
2286	reg = (reg & ~R92C_MSR_MASK) | mode;
2287	urtwn_write_1(sc, R92C_MSR, reg);
2288}
2289
2290static void
2291urtwn_ibss_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype,
2292    const struct ieee80211_rx_stats *rxs,
2293    int rssi, int nf)
2294{
2295	struct ieee80211vap *vap = ni->ni_vap;
2296	struct urtwn_softc *sc = vap->iv_ic->ic_softc;
2297	struct urtwn_vap *uvp = URTWN_VAP(vap);
2298	uint64_t ni_tstamp, curr_tstamp;
2299
2300	uvp->recv_mgmt(ni, m, subtype, rxs, rssi, nf);
2301
2302	if (vap->iv_state == IEEE80211_S_RUN &&
2303	    (subtype == IEEE80211_FC0_SUBTYPE_BEACON ||
2304	    subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)) {
2305		ni_tstamp = le64toh(ni->ni_tstamp.tsf);
2306		URTWN_LOCK(sc);
2307		urtwn_get_tsf(sc, &curr_tstamp);
2308		URTWN_UNLOCK(sc);
2309		curr_tstamp = le64toh(curr_tstamp);
2310
2311		if (ni_tstamp >= curr_tstamp)
2312			(void) ieee80211_ibss_merge(ni);
2313	}
2314}
2315
2316static int
2317urtwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2318{
2319	struct urtwn_vap *uvp = URTWN_VAP(vap);
2320	struct ieee80211com *ic = vap->iv_ic;
2321	struct urtwn_softc *sc = ic->ic_softc;
2322	struct ieee80211_node *ni;
2323	enum ieee80211_state ostate;
2324	uint32_t reg;
2325	uint8_t mode;
2326	int error = 0;
2327
2328	ostate = vap->iv_state;
2329	URTWN_DPRINTF(sc, URTWN_DEBUG_STATE, "%s -> %s\n",
2330	    ieee80211_state_name[ostate], ieee80211_state_name[nstate]);
2331
2332	IEEE80211_UNLOCK(ic);
2333	URTWN_LOCK(sc);
2334	callout_stop(&sc->sc_watchdog_ch);
2335
2336	if (ostate == IEEE80211_S_RUN) {
2337		/* Stop calibration. */
2338		callout_stop(&sc->sc_calib_to);
2339
2340		/* Turn link LED off. */
2341		urtwn_set_led(sc, URTWN_LED_LINK, 0);
2342
2343		/* Set media status to 'No Link'. */
2344		urtwn_set_mode(sc, R92C_MSR_NOLINK);
2345
2346		/* Stop Rx of data frames. */
2347		urtwn_write_2(sc, R92C_RXFLTMAP2, 0);
2348
2349		/* Disable TSF synchronization. */
2350		urtwn_write_1(sc, R92C_BCN_CTRL,
2351		    (urtwn_read_1(sc, R92C_BCN_CTRL) & ~R92C_BCN_CTRL_EN_BCN) |
2352		    R92C_BCN_CTRL_DIS_TSF_UDT0);
2353
2354		/* Disable beaconing. */
2355		urtwn_write_1(sc, R92C_MBID_NUM,
2356		    urtwn_read_1(sc, R92C_MBID_NUM) & ~R92C_MBID_TXBCN_RPT0);
2357
2358		/* Reset TSF. */
2359		urtwn_write_1(sc, R92C_DUAL_TSF_RST, R92C_DUAL_TSF_RST0);
2360
2361		/* Reset EDCA parameters. */
2362		urtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002f3217);
2363		urtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005e4317);
2364		urtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x00105320);
2365		urtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a444);
2366	}
2367
2368	switch (nstate) {
2369	case IEEE80211_S_INIT:
2370		/* Turn link LED off. */
2371		urtwn_set_led(sc, URTWN_LED_LINK, 0);
2372		break;
2373	case IEEE80211_S_SCAN:
2374		/* Pause AC Tx queues. */
2375		urtwn_write_1(sc, R92C_TXPAUSE,
2376		    urtwn_read_1(sc, R92C_TXPAUSE) | R92C_TX_QUEUE_AC);
2377		break;
2378	case IEEE80211_S_AUTH:
2379		urtwn_set_chan(sc, ic->ic_curchan, NULL);
2380		break;
2381	case IEEE80211_S_RUN:
2382		if (vap->iv_opmode == IEEE80211_M_MONITOR) {
2383			/* Turn link LED on. */
2384			urtwn_set_led(sc, URTWN_LED_LINK, 1);
2385			break;
2386		}
2387
2388		ni = ieee80211_ref_node(vap->iv_bss);
2389
2390		if (ic->ic_bsschan == IEEE80211_CHAN_ANYC ||
2391		    ni->ni_chan == IEEE80211_CHAN_ANYC) {
2392			device_printf(sc->sc_dev,
2393			    "%s: could not move to RUN state\n", __func__);
2394			error = EINVAL;
2395			goto end_run;
2396		}
2397
2398		switch (vap->iv_opmode) {
2399		case IEEE80211_M_STA:
2400			mode = R92C_MSR_INFRA;
2401			break;
2402		case IEEE80211_M_IBSS:
2403			mode = R92C_MSR_ADHOC;
2404			break;
2405		case IEEE80211_M_HOSTAP:
2406			mode = R92C_MSR_AP;
2407			break;
2408		default:
2409			device_printf(sc->sc_dev, "undefined opmode %d\n",
2410			    vap->iv_opmode);
2411			error = EINVAL;
2412			goto end_run;
2413		}
2414
2415		/* Set media status to 'Associated'. */
2416		urtwn_set_mode(sc, mode);
2417
2418		/* Set BSSID. */
2419		urtwn_write_4(sc, R92C_BSSID + 0, LE_READ_4(&ni->ni_bssid[0]));
2420		urtwn_write_4(sc, R92C_BSSID + 4, LE_READ_2(&ni->ni_bssid[4]));
2421
2422		if (ic->ic_curmode == IEEE80211_MODE_11B)
2423			urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 0);
2424		else	/* 802.11b/g */
2425			urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 3);
2426
2427		/* Enable Rx of data frames. */
2428		urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff);
2429
2430		/* Flush all AC queues. */
2431		urtwn_write_1(sc, R92C_TXPAUSE, 0);
2432
2433		/* Set beacon interval. */
2434		urtwn_write_2(sc, R92C_BCN_INTERVAL, ni->ni_intval);
2435
2436		/* Allow Rx from our BSSID only. */
2437		if (ic->ic_promisc == 0) {
2438			reg = urtwn_read_4(sc, R92C_RCR);
2439
2440			if (vap->iv_opmode != IEEE80211_M_HOSTAP)
2441				reg |= R92C_RCR_CBSSID_DATA;
2442			if (vap->iv_opmode != IEEE80211_M_IBSS)
2443				reg |= R92C_RCR_CBSSID_BCN;
2444
2445			urtwn_write_4(sc, R92C_RCR, reg);
2446		}
2447
2448		if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
2449		    vap->iv_opmode == IEEE80211_M_IBSS) {
2450			error = urtwn_setup_beacon(sc, ni);
2451			if (error != 0) {
2452				device_printf(sc->sc_dev,
2453				    "unable to push beacon into the chip, "
2454				    "error %d\n", error);
2455				goto end_run;
2456			}
2457		}
2458
2459		/* Enable TSF synchronization. */
2460		urtwn_tsf_sync_enable(sc, vap);
2461
2462		urtwn_write_1(sc, R92C_SIFS_CCK + 1, 10);
2463		urtwn_write_1(sc, R92C_SIFS_OFDM + 1, 10);
2464		urtwn_write_1(sc, R92C_SPEC_SIFS + 1, 10);
2465		urtwn_write_1(sc, R92C_MAC_SPEC_SIFS + 1, 10);
2466		urtwn_write_1(sc, R92C_R2T_SIFS + 1, 10);
2467		urtwn_write_1(sc, R92C_T2T_SIFS + 1, 10);
2468
2469		/* Intialize rate adaptation. */
2470		if (!(sc->chip & URTWN_CHIP_88E))
2471			urtwn_ra_init(sc);
2472		/* Turn link LED on. */
2473		urtwn_set_led(sc, URTWN_LED_LINK, 1);
2474
2475		sc->avg_pwdb = -1;	/* Reset average RSSI. */
2476		/* Reset temperature calibration state machine. */
2477		sc->sc_flags &= ~URTWN_TEMP_MEASURED;
2478		sc->thcal_lctemp = 0;
2479		/* Start periodic calibration. */
2480		callout_reset(&sc->sc_calib_to, 2*hz, urtwn_calib_to, sc);
2481
2482end_run:
2483		ieee80211_free_node(ni);
2484		break;
2485	default:
2486		break;
2487	}
2488
2489	URTWN_UNLOCK(sc);
2490	IEEE80211_LOCK(ic);
2491	return (error != 0 ? error : uvp->newstate(vap, nstate, arg));
2492}
2493
2494static void
2495urtwn_calib_to(void *arg)
2496{
2497	struct urtwn_softc *sc = arg;
2498
2499	/* Do it in a process context. */
2500	urtwn_cmd_sleepable(sc, NULL, 0, urtwn_calib_cb);
2501}
2502
2503static void
2504urtwn_calib_cb(struct urtwn_softc *sc, union sec_param *data)
2505{
2506	/* Do temperature compensation. */
2507	urtwn_temp_calib(sc);
2508
2509	if ((urtwn_read_1(sc, R92C_MSR) & R92C_MSR_MASK) != R92C_MSR_NOLINK)
2510		callout_reset(&sc->sc_calib_to, 2*hz, urtwn_calib_to, sc);
2511}
2512
2513static void
2514urtwn_watchdog(void *arg)
2515{
2516	struct urtwn_softc *sc = arg;
2517
2518	if (sc->sc_txtimer > 0) {
2519		if (--sc->sc_txtimer == 0) {
2520			device_printf(sc->sc_dev, "device timeout\n");
2521			counter_u64_add(sc->sc_ic.ic_oerrors, 1);
2522			return;
2523		}
2524		callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc);
2525	}
2526}
2527
2528static void
2529urtwn_update_avgrssi(struct urtwn_softc *sc, int rate, int8_t rssi)
2530{
2531	int pwdb;
2532
2533	/* Convert antenna signal to percentage. */
2534	if (rssi <= -100 || rssi >= 20)
2535		pwdb = 0;
2536	else if (rssi >= 0)
2537		pwdb = 100;
2538	else
2539		pwdb = 100 + rssi;
2540	if (!(sc->chip & URTWN_CHIP_88E)) {
2541		if (rate <= URTWN_RIDX_CCK11) {
2542			/* CCK gain is smaller than OFDM/MCS gain. */
2543			pwdb += 6;
2544			if (pwdb > 100)
2545				pwdb = 100;
2546			if (pwdb <= 14)
2547				pwdb -= 4;
2548			else if (pwdb <= 26)
2549				pwdb -= 8;
2550			else if (pwdb <= 34)
2551				pwdb -= 6;
2552			else if (pwdb <= 42)
2553				pwdb -= 2;
2554		}
2555	}
2556	if (sc->avg_pwdb == -1)	/* Init. */
2557		sc->avg_pwdb = pwdb;
2558	else if (sc->avg_pwdb < pwdb)
2559		sc->avg_pwdb = ((sc->avg_pwdb * 19 + pwdb) / 20) + 1;
2560	else
2561		sc->avg_pwdb = ((sc->avg_pwdb * 19 + pwdb) / 20);
2562	URTWN_DPRINTF(sc, URTWN_DEBUG_RA, "%s: PWDB %d, EMA %d\n", __func__,
2563	    pwdb, sc->avg_pwdb);
2564}
2565
2566static int8_t
2567urtwn_get_rssi(struct urtwn_softc *sc, int rate, void *physt)
2568{
2569	static const int8_t cckoff[] = { 16, -12, -26, -46 };
2570	struct r92c_rx_phystat *phy;
2571	struct r92c_rx_cck *cck;
2572	uint8_t rpt;
2573	int8_t rssi;
2574
2575	if (rate <= URTWN_RIDX_CCK11) {
2576		cck = (struct r92c_rx_cck *)physt;
2577		if (sc->sc_flags & URTWN_FLAG_CCK_HIPWR) {
2578			rpt = (cck->agc_rpt >> 5) & 0x3;
2579			rssi = (cck->agc_rpt & 0x1f) << 1;
2580		} else {
2581			rpt = (cck->agc_rpt >> 6) & 0x3;
2582			rssi = cck->agc_rpt & 0x3e;
2583		}
2584		rssi = cckoff[rpt] - rssi;
2585	} else {	/* OFDM/HT. */
2586		phy = (struct r92c_rx_phystat *)physt;
2587		rssi = ((le32toh(phy->phydw1) >> 1) & 0x7f) - 110;
2588	}
2589	return (rssi);
2590}
2591
2592static int8_t
2593urtwn_r88e_get_rssi(struct urtwn_softc *sc, int rate, void *physt)
2594{
2595	struct r92c_rx_phystat *phy;
2596	struct r88e_rx_cck *cck;
2597	uint8_t cck_agc_rpt, lna_idx, vga_idx;
2598	int8_t rssi;
2599
2600	rssi = 0;
2601	if (rate <= URTWN_RIDX_CCK11) {
2602		cck = (struct r88e_rx_cck *)physt;
2603		cck_agc_rpt = cck->agc_rpt;
2604		lna_idx = (cck_agc_rpt & 0xe0) >> 5;
2605		vga_idx = cck_agc_rpt & 0x1f;
2606		switch (lna_idx) {
2607		case 7:
2608			if (vga_idx <= 27)
2609				rssi = -100 + 2* (27 - vga_idx);
2610			else
2611				rssi = -100;
2612			break;
2613		case 6:
2614			rssi = -48 + 2 * (2 - vga_idx);
2615			break;
2616		case 5:
2617			rssi = -42 + 2 * (7 - vga_idx);
2618			break;
2619		case 4:
2620			rssi = -36 + 2 * (7 - vga_idx);
2621			break;
2622		case 3:
2623			rssi = -24 + 2 * (7 - vga_idx);
2624			break;
2625		case 2:
2626			rssi = -12 + 2 * (5 - vga_idx);
2627			break;
2628		case 1:
2629			rssi = 8 - (2 * vga_idx);
2630			break;
2631		case 0:
2632			rssi = 14 - (2 * vga_idx);
2633			break;
2634		}
2635		rssi += 6;
2636	} else {	/* OFDM/HT. */
2637		phy = (struct r92c_rx_phystat *)physt;
2638		rssi = ((le32toh(phy->phydw1) >> 1) & 0x7f) - 110;
2639	}
2640	return (rssi);
2641}
2642
2643static __inline uint8_t
2644rate2ridx(uint8_t rate)
2645{
2646	switch (rate) {
2647	case 12:	return 4;
2648	case 18:	return 5;
2649	case 24:	return 6;
2650	case 36:	return 7;
2651	case 48:	return 8;
2652	case 72:	return 9;
2653	case 96:	return 10;
2654	case 108:	return 11;
2655	case 2:		return 0;
2656	case 4:		return 1;
2657	case 11:	return 2;
2658	case 22:	return 3;
2659	default:	return 0;
2660	}
2661}
2662
2663static int
2664urtwn_tx_data(struct urtwn_softc *sc, struct ieee80211_node *ni,
2665    struct mbuf *m, struct urtwn_data *data)
2666{
2667	const struct ieee80211_txparam *tp;
2668	struct ieee80211com *ic = &sc->sc_ic;
2669	struct ieee80211vap *vap = ni->ni_vap;
2670	struct ieee80211_key *k = NULL;
2671	struct ieee80211_channel *chan;
2672	struct ieee80211_frame *wh;
2673	struct r92c_tx_desc *txd;
2674	uint8_t macid, raid, rate, ridx, subtype, type, tid, qsel;
2675	int hasqos, ismcast;
2676
2677	URTWN_ASSERT_LOCKED(sc);
2678
2679	/*
2680	 * Software crypto.
2681	 */
2682	wh = mtod(m, struct ieee80211_frame *);
2683	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
2684	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
2685	hasqos = IEEE80211_QOS_HAS_SEQ(wh);
2686	ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
2687
2688	/* Select TX ring for this frame. */
2689	if (hasqos) {
2690		tid = ((const struct ieee80211_qosframe *)wh)->i_qos[0];
2691		tid &= IEEE80211_QOS_TID;
2692	} else
2693		tid = 0;
2694
2695	chan = (ni->ni_chan != IEEE80211_CHAN_ANYC) ?
2696		ni->ni_chan : ic->ic_curchan;
2697	tp = &vap->iv_txparms[ieee80211_chan2mode(chan)];
2698
2699	/* Choose a TX rate index. */
2700	if (type == IEEE80211_FC0_TYPE_MGT)
2701		rate = tp->mgmtrate;
2702	else if (ismcast)
2703		rate = tp->mcastrate;
2704	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
2705		rate = tp->ucastrate;
2706	else if (m->m_flags & M_EAPOL)
2707		rate = tp->mgmtrate;
2708	else {
2709		if (URTWN_CHIP_HAS_RATECTL(sc)) {
2710			/* XXX pass pktlen */
2711			(void) ieee80211_ratectl_rate(ni, NULL, 0);
2712			rate = ni->ni_txrate;
2713		} else {
2714			if (ic->ic_curmode != IEEE80211_MODE_11B)
2715				rate = 108;
2716			else
2717				rate = 22;
2718		}
2719	}
2720
2721	ridx = rate2ridx(rate);
2722	if (ic->ic_curmode != IEEE80211_MODE_11B)
2723		raid = R92C_RAID_11BG;
2724	else
2725		raid = R92C_RAID_11B;
2726
2727	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
2728		k = ieee80211_crypto_encap(ni, m);
2729		if (k == NULL) {
2730			device_printf(sc->sc_dev,
2731			    "ieee80211_crypto_encap returns NULL.\n");
2732			return (ENOBUFS);
2733		}
2734
2735		/* in case packet header moved, reset pointer */
2736		wh = mtod(m, struct ieee80211_frame *);
2737	}
2738
2739	/* Fill Tx descriptor. */
2740	txd = (struct r92c_tx_desc *)data->buf;
2741	memset(txd, 0, sizeof(*txd));
2742
2743	txd->txdw0 |= htole32(
2744	    SM(R92C_TXDW0_OFFSET, sizeof(*txd)) |
2745	    R92C_TXDW0_OWN | R92C_TXDW0_FSG | R92C_TXDW0_LSG);
2746	if (ismcast)
2747		txd->txdw0 |= htole32(R92C_TXDW0_BMCAST);
2748
2749	if (!ismcast) {
2750		if (sc->chip & URTWN_CHIP_88E) {
2751			struct urtwn_node *un = URTWN_NODE(ni);
2752			macid = un->id;
2753		} else
2754			macid = URTWN_MACID_BSS;
2755
2756		if (type == IEEE80211_FC0_TYPE_DATA) {
2757			qsel = tid % URTWN_MAX_TID;
2758
2759			if (sc->chip & URTWN_CHIP_88E) {
2760				txd->txdw2 |= htole32(
2761				    R88E_TXDW2_AGGBK |
2762				    R88E_TXDW2_CCX_RPT);
2763			} else
2764				txd->txdw1 |= htole32(R92C_TXDW1_AGGBK);
2765
2766			if (ic->ic_flags & IEEE80211_F_USEPROT) {
2767				switch (ic->ic_protmode) {
2768				case IEEE80211_PROT_CTSONLY:
2769					txd->txdw4 |= htole32(
2770					    R92C_TXDW4_CTS2SELF |
2771					    R92C_TXDW4_HWRTSEN);
2772					break;
2773				case IEEE80211_PROT_RTSCTS:
2774					txd->txdw4 |= htole32(
2775					    R92C_TXDW4_RTSEN |
2776					    R92C_TXDW4_HWRTSEN);
2777					break;
2778				default:
2779					break;
2780				}
2781			}
2782			txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE,
2783			    URTWN_RIDX_OFDM24));
2784			txd->txdw5 |= htole32(0x0001ff00);
2785		} else	/* IEEE80211_FC0_TYPE_MGT */
2786			qsel = R92C_TXDW1_QSEL_MGNT;
2787	} else {
2788		macid = URTWN_MACID_BC;
2789		qsel = R92C_TXDW1_QSEL_MGNT;
2790	}
2791
2792	txd->txdw1 |= htole32(
2793	    SM(R92C_TXDW1_QSEL, qsel) |
2794	    SM(R92C_TXDW1_RAID, raid));
2795
2796	if (sc->chip & URTWN_CHIP_88E)
2797		txd->txdw1 |= htole32(SM(R88E_TXDW1_MACID, macid));
2798	else
2799		txd->txdw1 |= htole32(SM(R92C_TXDW1_MACID, macid));
2800
2801	txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, ridx));
2802	/* Force this rate if needed. */
2803	if (URTWN_CHIP_HAS_RATECTL(sc) || ismcast ||
2804	    (m->m_flags & M_EAPOL) || type != IEEE80211_FC0_TYPE_DATA)
2805		txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
2806
2807	if (!hasqos) {
2808		/* Use HW sequence numbering for non-QoS frames. */
2809		if (sc->chip & URTWN_CHIP_88E)
2810			txd->txdseq = htole16(R88E_TXDSEQ_HWSEQ_EN);
2811		else
2812			txd->txdw4 |= htole32(R92C_TXDW4_HWSEQ_EN);
2813	} else {
2814		/* Set sequence number. */
2815		txd->txdseq = htole16(M_SEQNO_GET(m) % IEEE80211_SEQ_RANGE);
2816	}
2817
2818	if (k != NULL && !(k->wk_flags & IEEE80211_KEY_SWCRYPT)) {
2819		uint8_t cipher;
2820
2821		switch (k->wk_cipher->ic_cipher) {
2822		case IEEE80211_CIPHER_WEP:
2823		case IEEE80211_CIPHER_TKIP:
2824			cipher = R92C_TXDW1_CIPHER_RC4;
2825			break;
2826		case IEEE80211_CIPHER_AES_CCM:
2827			cipher = R92C_TXDW1_CIPHER_AES;
2828			break;
2829		default:
2830			device_printf(sc->sc_dev, "%s: unknown cipher %d\n",
2831			    __func__, k->wk_cipher->ic_cipher);
2832			return (EINVAL);
2833		}
2834
2835		txd->txdw1 |= htole32(SM(R92C_TXDW1_CIPHER, cipher));
2836	}
2837
2838	if (ieee80211_radiotap_active_vap(vap)) {
2839		struct urtwn_tx_radiotap_header *tap = &sc->sc_txtap;
2840
2841		tap->wt_flags = 0;
2842		if (k != NULL)
2843			tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
2844		ieee80211_radiotap_tx(vap, m);
2845	}
2846
2847	data->ni = ni;
2848
2849	urtwn_tx_start(sc, m, type, data);
2850
2851	return (0);
2852}
2853
2854static int
2855urtwn_tx_raw(struct urtwn_softc *sc, struct ieee80211_node *ni,
2856    struct mbuf *m, struct urtwn_data *data,
2857    const struct ieee80211_bpf_params *params)
2858{
2859	struct ieee80211vap *vap = ni->ni_vap;
2860	struct ieee80211_key *k = NULL;
2861	struct ieee80211_frame *wh;
2862	struct r92c_tx_desc *txd;
2863	uint8_t cipher, ridx, type;
2864
2865	/* Encrypt the frame if need be. */
2866	cipher = R92C_TXDW1_CIPHER_NONE;
2867	if (params->ibp_flags & IEEE80211_BPF_CRYPTO) {
2868		/* Retrieve key for TX. */
2869		k = ieee80211_crypto_encap(ni, m);
2870		if (k == NULL)
2871			return (ENOBUFS);
2872
2873		if (!(k->wk_flags & IEEE80211_KEY_SWCRYPT)) {
2874			switch (k->wk_cipher->ic_cipher) {
2875			case IEEE80211_CIPHER_WEP:
2876			case IEEE80211_CIPHER_TKIP:
2877				cipher = R92C_TXDW1_CIPHER_RC4;
2878				break;
2879			case IEEE80211_CIPHER_AES_CCM:
2880				cipher = R92C_TXDW1_CIPHER_AES;
2881				break;
2882			default:
2883				device_printf(sc->sc_dev,
2884				    "%s: unknown cipher %d\n",
2885				    __func__, k->wk_cipher->ic_cipher);
2886				return (EINVAL);
2887			}
2888		}
2889	}
2890
2891	wh = mtod(m, struct ieee80211_frame *);
2892	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
2893
2894	/* Fill Tx descriptor. */
2895	txd = (struct r92c_tx_desc *)data->buf;
2896	memset(txd, 0, sizeof(*txd));
2897
2898	txd->txdw0 |= htole32(
2899	    SM(R92C_TXDW0_OFFSET, sizeof(*txd)) |
2900	    R92C_TXDW0_OWN | R92C_TXDW0_FSG | R92C_TXDW0_LSG);
2901	if (IEEE80211_IS_MULTICAST(wh->i_addr1))
2902		txd->txdw0 |= htole32(R92C_TXDW0_BMCAST);
2903
2904	if (params->ibp_flags & IEEE80211_BPF_RTS)
2905		txd->txdw4 |= htole32(R92C_TXDW4_RTSEN);
2906	if (params->ibp_flags & IEEE80211_BPF_CTS)
2907		txd->txdw4 |= htole32(R92C_TXDW4_CTS2SELF);
2908	if (txd->txdw4 & htole32(R92C_TXDW4_RTSEN | R92C_TXDW4_CTS2SELF)) {
2909		txd->txdw4 |= htole32(R92C_TXDW4_HWRTSEN);
2910		txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE,
2911		    URTWN_RIDX_OFDM24));
2912	}
2913
2914	if (sc->chip & URTWN_CHIP_88E)
2915		txd->txdw1 |= htole32(SM(R88E_TXDW1_MACID, URTWN_MACID_BC));
2916	else
2917		txd->txdw1 |= htole32(SM(R92C_TXDW1_MACID, URTWN_MACID_BC));
2918
2919	txd->txdw1 |= htole32(SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_MGNT));
2920	txd->txdw1 |= htole32(SM(R92C_TXDW1_CIPHER, cipher));
2921
2922	/* Choose a TX rate index. */
2923	ridx = rate2ridx(params->ibp_rate0);
2924	txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, ridx));
2925	txd->txdw5 |= htole32(0x0001ff00);
2926	txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
2927
2928	if (!IEEE80211_QOS_HAS_SEQ(wh)) {
2929		/* Use HW sequence numbering for non-QoS frames. */
2930		if (sc->chip & URTWN_CHIP_88E)
2931			txd->txdseq = htole16(R88E_TXDSEQ_HWSEQ_EN);
2932		else
2933			txd->txdw4 |= htole32(R92C_TXDW4_HWSEQ_EN);
2934	} else {
2935		/* Set sequence number. */
2936		txd->txdseq = htole16(M_SEQNO_GET(m) % IEEE80211_SEQ_RANGE);
2937	}
2938
2939	if (ieee80211_radiotap_active_vap(vap)) {
2940		struct urtwn_tx_radiotap_header *tap = &sc->sc_txtap;
2941
2942		tap->wt_flags = 0;
2943		if (k != NULL)
2944			tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
2945		ieee80211_radiotap_tx(vap, m);
2946	}
2947
2948	data->ni = ni;
2949
2950	urtwn_tx_start(sc, m, type, data);
2951
2952	return (0);
2953}
2954
2955static void
2956urtwn_tx_start(struct urtwn_softc *sc, struct mbuf *m, uint8_t type,
2957    struct urtwn_data *data)
2958{
2959	struct usb_xfer *xfer;
2960	struct r92c_tx_desc *txd;
2961	uint16_t ac, sum;
2962	int i, xferlen;
2963
2964	URTWN_ASSERT_LOCKED(sc);
2965
2966	ac = M_WME_GETAC(m);
2967
2968	switch (type) {
2969	case IEEE80211_FC0_TYPE_CTL:
2970	case IEEE80211_FC0_TYPE_MGT:
2971		xfer = sc->sc_xfer[URTWN_BULK_TX_VO];
2972		break;
2973	default:
2974		xfer = sc->sc_xfer[wme2queue[ac].qid];
2975		break;
2976	}
2977
2978	txd = (struct r92c_tx_desc *)data->buf;
2979	txd->txdw0 |= htole32(SM(R92C_TXDW0_PKTLEN, m->m_pkthdr.len));
2980
2981	/* Compute Tx descriptor checksum. */
2982	sum = 0;
2983	for (i = 0; i < sizeof(*txd) / 2; i++)
2984		sum ^= ((uint16_t *)txd)[i];
2985	txd->txdsum = sum;	/* NB: already little endian. */
2986
2987	xferlen = sizeof(*txd) + m->m_pkthdr.len;
2988	m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)&txd[1]);
2989
2990	data->buflen = xferlen;
2991	data->m = m;
2992
2993	STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next);
2994	usbd_transfer_start(xfer);
2995}
2996
2997static int
2998urtwn_transmit(struct ieee80211com *ic, struct mbuf *m)
2999{
3000	struct urtwn_softc *sc = ic->ic_softc;
3001	int error;
3002
3003	URTWN_LOCK(sc);
3004	if ((sc->sc_flags & URTWN_RUNNING) == 0) {
3005		URTWN_UNLOCK(sc);
3006		return (ENXIO);
3007	}
3008	error = mbufq_enqueue(&sc->sc_snd, m);
3009	if (error) {
3010		URTWN_UNLOCK(sc);
3011		return (error);
3012	}
3013	urtwn_start(sc);
3014	URTWN_UNLOCK(sc);
3015
3016	return (0);
3017}
3018
3019static void
3020urtwn_start(struct urtwn_softc *sc)
3021{
3022	struct ieee80211_node *ni;
3023	struct mbuf *m;
3024	struct urtwn_data *bf;
3025
3026	URTWN_ASSERT_LOCKED(sc);
3027	while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
3028		bf = urtwn_getbuf(sc);
3029		if (bf == NULL) {
3030			mbufq_prepend(&sc->sc_snd, m);
3031			break;
3032		}
3033		ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
3034		m->m_pkthdr.rcvif = NULL;
3035		if (urtwn_tx_data(sc, ni, m, bf) != 0) {
3036			if_inc_counter(ni->ni_vap->iv_ifp,
3037			    IFCOUNTER_OERRORS, 1);
3038			STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
3039			m_freem(m);
3040			ieee80211_free_node(ni);
3041			break;
3042		}
3043		sc->sc_txtimer = 5;
3044		callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc);
3045	}
3046}
3047
3048static void
3049urtwn_parent(struct ieee80211com *ic)
3050{
3051	struct urtwn_softc *sc = ic->ic_softc;
3052
3053	URTWN_LOCK(sc);
3054	if (sc->sc_flags & URTWN_DETACHED) {
3055		URTWN_UNLOCK(sc);
3056		return;
3057	}
3058	URTWN_UNLOCK(sc);
3059
3060	if (ic->ic_nrunning > 0) {
3061		if (urtwn_init(sc) != 0) {
3062			struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
3063			if (vap != NULL)
3064				ieee80211_stop(vap);
3065		} else
3066			ieee80211_start_all(ic);
3067	} else
3068		urtwn_stop(sc);
3069}
3070
3071static __inline int
3072urtwn_power_on(struct urtwn_softc *sc)
3073{
3074
3075	return sc->sc_power_on(sc);
3076}
3077
3078static int
3079urtwn_r92c_power_on(struct urtwn_softc *sc)
3080{
3081	uint32_t reg;
3082	usb_error_t error;
3083	int ntries;
3084
3085	/* Wait for autoload done bit. */
3086	for (ntries = 0; ntries < 1000; ntries++) {
3087		if (urtwn_read_1(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_PFM_ALDN)
3088			break;
3089		urtwn_ms_delay(sc);
3090	}
3091	if (ntries == 1000) {
3092		device_printf(sc->sc_dev,
3093		    "timeout waiting for chip autoload\n");
3094		return (ETIMEDOUT);
3095	}
3096
3097	/* Unlock ISO/CLK/Power control register. */
3098	error = urtwn_write_1(sc, R92C_RSV_CTRL, 0);
3099	if (error != USB_ERR_NORMAL_COMPLETION)
3100		return (EIO);
3101	/* Move SPS into PWM mode. */
3102	error = urtwn_write_1(sc, R92C_SPS0_CTRL, 0x2b);
3103	if (error != USB_ERR_NORMAL_COMPLETION)
3104		return (EIO);
3105	urtwn_ms_delay(sc);
3106
3107	reg = urtwn_read_1(sc, R92C_LDOV12D_CTRL);
3108	if (!(reg & R92C_LDOV12D_CTRL_LDV12_EN)) {
3109		error = urtwn_write_1(sc, R92C_LDOV12D_CTRL,
3110		    reg | R92C_LDOV12D_CTRL_LDV12_EN);
3111		if (error != USB_ERR_NORMAL_COMPLETION)
3112			return (EIO);
3113		urtwn_ms_delay(sc);
3114		error = urtwn_write_1(sc, R92C_SYS_ISO_CTRL,
3115		    urtwn_read_1(sc, R92C_SYS_ISO_CTRL) &
3116		    ~R92C_SYS_ISO_CTRL_MD2PP);
3117		if (error != USB_ERR_NORMAL_COMPLETION)
3118			return (EIO);
3119	}
3120
3121	/* Auto enable WLAN. */
3122	error = urtwn_write_2(sc, R92C_APS_FSMCO,
3123	    urtwn_read_2(sc, R92C_APS_FSMCO) | R92C_APS_FSMCO_APFM_ONMAC);
3124	if (error != USB_ERR_NORMAL_COMPLETION)
3125		return (EIO);
3126	for (ntries = 0; ntries < 1000; ntries++) {
3127		if (!(urtwn_read_2(sc, R92C_APS_FSMCO) &
3128		    R92C_APS_FSMCO_APFM_ONMAC))
3129			break;
3130		urtwn_ms_delay(sc);
3131	}
3132	if (ntries == 1000) {
3133		device_printf(sc->sc_dev,
3134		    "timeout waiting for MAC auto ON\n");
3135		return (ETIMEDOUT);
3136	}
3137
3138	/* Enable radio, GPIO and LED functions. */
3139	error = urtwn_write_2(sc, R92C_APS_FSMCO,
3140	    R92C_APS_FSMCO_AFSM_HSUS |
3141	    R92C_APS_FSMCO_PDN_EN |
3142	    R92C_APS_FSMCO_PFM_ALDN);
3143	if (error != USB_ERR_NORMAL_COMPLETION)
3144		return (EIO);
3145	/* Release RF digital isolation. */
3146	error = urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
3147	    urtwn_read_2(sc, R92C_SYS_ISO_CTRL) & ~R92C_SYS_ISO_CTRL_DIOR);
3148	if (error != USB_ERR_NORMAL_COMPLETION)
3149		return (EIO);
3150
3151	/* Initialize MAC. */
3152	error = urtwn_write_1(sc, R92C_APSD_CTRL,
3153	    urtwn_read_1(sc, R92C_APSD_CTRL) & ~R92C_APSD_CTRL_OFF);
3154	if (error != USB_ERR_NORMAL_COMPLETION)
3155		return (EIO);
3156	for (ntries = 0; ntries < 200; ntries++) {
3157		if (!(urtwn_read_1(sc, R92C_APSD_CTRL) &
3158		    R92C_APSD_CTRL_OFF_STATUS))
3159			break;
3160		urtwn_ms_delay(sc);
3161	}
3162	if (ntries == 200) {
3163		device_printf(sc->sc_dev,
3164		    "timeout waiting for MAC initialization\n");
3165		return (ETIMEDOUT);
3166	}
3167
3168	/* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
3169	reg = urtwn_read_2(sc, R92C_CR);
3170	reg |= R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN |
3171	    R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | R92C_CR_PROTOCOL_EN |
3172	    R92C_CR_SCHEDULE_EN | R92C_CR_MACTXEN | R92C_CR_MACRXEN |
3173	    R92C_CR_ENSEC;
3174	error = urtwn_write_2(sc, R92C_CR, reg);
3175	if (error != USB_ERR_NORMAL_COMPLETION)
3176		return (EIO);
3177
3178	error = urtwn_write_1(sc, 0xfe10, 0x19);
3179	if (error != USB_ERR_NORMAL_COMPLETION)
3180		return (EIO);
3181	return (0);
3182}
3183
3184static int
3185urtwn_r88e_power_on(struct urtwn_softc *sc)
3186{
3187	uint32_t reg;
3188	usb_error_t error;
3189	int ntries;
3190
3191	/* Wait for power ready bit. */
3192	for (ntries = 0; ntries < 5000; ntries++) {
3193		if (urtwn_read_4(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_SUS_HOST)
3194			break;
3195		urtwn_ms_delay(sc);
3196	}
3197	if (ntries == 5000) {
3198		device_printf(sc->sc_dev,
3199		    "timeout waiting for chip power up\n");
3200		return (ETIMEDOUT);
3201	}
3202
3203	/* Reset BB. */
3204	error = urtwn_write_1(sc, R92C_SYS_FUNC_EN,
3205	    urtwn_read_1(sc, R92C_SYS_FUNC_EN) & ~(R92C_SYS_FUNC_EN_BBRSTB |
3206	    R92C_SYS_FUNC_EN_BB_GLB_RST));
3207	if (error != USB_ERR_NORMAL_COMPLETION)
3208		return (EIO);
3209
3210	error = urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 2,
3211	    urtwn_read_1(sc, R92C_AFE_XTAL_CTRL + 2) | 0x80);
3212	if (error != USB_ERR_NORMAL_COMPLETION)
3213		return (EIO);
3214
3215	/* Disable HWPDN. */
3216	error = urtwn_write_2(sc, R92C_APS_FSMCO,
3217	    urtwn_read_2(sc, R92C_APS_FSMCO) & ~R92C_APS_FSMCO_APDM_HPDN);
3218	if (error != USB_ERR_NORMAL_COMPLETION)
3219		return (EIO);
3220
3221	/* Disable WL suspend. */
3222	error = urtwn_write_2(sc, R92C_APS_FSMCO,
3223	    urtwn_read_2(sc, R92C_APS_FSMCO) &
3224	    ~(R92C_APS_FSMCO_AFSM_HSUS | R92C_APS_FSMCO_AFSM_PCIE));
3225	if (error != USB_ERR_NORMAL_COMPLETION)
3226		return (EIO);
3227
3228	error = urtwn_write_2(sc, R92C_APS_FSMCO,
3229	    urtwn_read_2(sc, R92C_APS_FSMCO) | R92C_APS_FSMCO_APFM_ONMAC);
3230	if (error != USB_ERR_NORMAL_COMPLETION)
3231		return (EIO);
3232	for (ntries = 0; ntries < 5000; ntries++) {
3233		if (!(urtwn_read_2(sc, R92C_APS_FSMCO) &
3234		    R92C_APS_FSMCO_APFM_ONMAC))
3235			break;
3236		urtwn_ms_delay(sc);
3237	}
3238	if (ntries == 5000)
3239		return (ETIMEDOUT);
3240
3241	/* Enable LDO normal mode. */
3242	error = urtwn_write_1(sc, R92C_LPLDO_CTRL,
3243	    urtwn_read_1(sc, R92C_LPLDO_CTRL) & ~R92C_LPLDO_CTRL_SLEEP);
3244	if (error != USB_ERR_NORMAL_COMPLETION)
3245		return (EIO);
3246
3247	/* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
3248	error = urtwn_write_2(sc, R92C_CR, 0);
3249	if (error != USB_ERR_NORMAL_COMPLETION)
3250		return (EIO);
3251	reg = urtwn_read_2(sc, R92C_CR);
3252	reg |= R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN |
3253	    R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | R92C_CR_PROTOCOL_EN |
3254	    R92C_CR_SCHEDULE_EN | R92C_CR_ENSEC | R92C_CR_CALTMR_EN;
3255	error = urtwn_write_2(sc, R92C_CR, reg);
3256	if (error != USB_ERR_NORMAL_COMPLETION)
3257		return (EIO);
3258
3259	return (0);
3260}
3261
3262static __inline void
3263urtwn_power_off(struct urtwn_softc *sc)
3264{
3265
3266	return sc->sc_power_off(sc);
3267}
3268
3269static void
3270urtwn_r92c_power_off(struct urtwn_softc *sc)
3271{
3272	uint32_t reg;
3273
3274	/* Block all Tx queues. */
3275	urtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
3276
3277	/* Disable RF */
3278	urtwn_rf_write(sc, 0, 0, 0);
3279
3280	urtwn_write_1(sc, R92C_APSD_CTRL, R92C_APSD_CTRL_OFF);
3281
3282	/* Reset BB state machine */
3283	urtwn_write_1(sc, R92C_SYS_FUNC_EN,
3284	    R92C_SYS_FUNC_EN_USBD | R92C_SYS_FUNC_EN_USBA |
3285	    R92C_SYS_FUNC_EN_BB_GLB_RST);
3286	urtwn_write_1(sc, R92C_SYS_FUNC_EN,
3287	    R92C_SYS_FUNC_EN_USBD | R92C_SYS_FUNC_EN_USBA);
3288
3289	/*
3290	 * Reset digital sequence
3291	 */
3292#ifndef URTWN_WITHOUT_UCODE
3293	if (urtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RDY) {
3294		/* Reset MCU ready status */
3295		urtwn_write_1(sc, R92C_MCUFWDL, 0);
3296
3297		/* If firmware in ram code, do reset */
3298		urtwn_fw_reset(sc);
3299	}
3300#endif
3301
3302	/* Reset MAC and Enable 8051 */
3303	urtwn_write_1(sc, R92C_SYS_FUNC_EN + 1,
3304	    (R92C_SYS_FUNC_EN_CPUEN |
3305	     R92C_SYS_FUNC_EN_ELDR |
3306	     R92C_SYS_FUNC_EN_HWPDN) >> 8);
3307
3308	/* Reset MCU ready status */
3309	urtwn_write_1(sc, R92C_MCUFWDL, 0);
3310
3311	/* Disable MAC clock */
3312	urtwn_write_2(sc, R92C_SYS_CLKR,
3313	    R92C_SYS_CLKR_ANAD16V_EN |
3314	    R92C_SYS_CLKR_ANA8M |
3315	    R92C_SYS_CLKR_LOADER_EN |
3316	    R92C_SYS_CLKR_80M_SSC_DIS |
3317	    R92C_SYS_CLKR_SYS_EN |
3318	    R92C_SYS_CLKR_RING_EN |
3319	    0x4000);
3320
3321	/* Disable AFE PLL */
3322	urtwn_write_1(sc, R92C_AFE_PLL_CTRL, 0x80);
3323
3324	/* Gated AFE DIG_CLOCK */
3325	urtwn_write_2(sc, R92C_AFE_XTAL_CTRL, 0x880F);
3326
3327	/* Isolated digital to PON */
3328	urtwn_write_1(sc, R92C_SYS_ISO_CTRL,
3329	    R92C_SYS_ISO_CTRL_MD2PP |
3330	    R92C_SYS_ISO_CTRL_PA2PCIE |
3331	    R92C_SYS_ISO_CTRL_PD2CORE |
3332	    R92C_SYS_ISO_CTRL_IP2MAC |
3333	    R92C_SYS_ISO_CTRL_DIOP |
3334	    R92C_SYS_ISO_CTRL_DIOE);
3335
3336	/*
3337	 * Pull GPIO PIN to balance level and LED control
3338	 */
3339	/* 1. Disable GPIO[7:0] */
3340	urtwn_write_2(sc, R92C_GPIO_IOSEL, 0x0000);
3341
3342	reg = urtwn_read_4(sc, R92C_GPIO_PIN_CTRL) & ~0x0000ff00;
3343	reg |= ((reg << 8) & 0x0000ff00) | 0x00ff0000;
3344	urtwn_write_4(sc, R92C_GPIO_PIN_CTRL, reg);
3345
3346	/* Disable GPIO[10:8] */
3347	urtwn_write_1(sc, R92C_MAC_PINMUX_CFG, 0x00);
3348
3349	reg = urtwn_read_2(sc, R92C_GPIO_IO_SEL) & ~0x00f0;
3350	reg |= (((reg & 0x000f) << 4) | 0x0780);
3351	urtwn_write_2(sc, R92C_GPIO_IO_SEL, reg);
3352
3353	/* Disable LED0 & 1 */
3354	urtwn_write_2(sc, R92C_LEDCFG0, 0x8080);
3355
3356	/*
3357	 * Reset digital sequence
3358	 */
3359	/* Disable ELDR clock */
3360	urtwn_write_2(sc, R92C_SYS_CLKR,
3361	    R92C_SYS_CLKR_ANAD16V_EN |
3362	    R92C_SYS_CLKR_ANA8M |
3363	    R92C_SYS_CLKR_LOADER_EN |
3364	    R92C_SYS_CLKR_80M_SSC_DIS |
3365	    R92C_SYS_CLKR_SYS_EN |
3366	    R92C_SYS_CLKR_RING_EN |
3367	    0x4000);
3368
3369	/* Isolated ELDR to PON */
3370	urtwn_write_1(sc, R92C_SYS_ISO_CTRL + 1,
3371	    (R92C_SYS_ISO_CTRL_DIOR |
3372	     R92C_SYS_ISO_CTRL_PWC_EV12V) >> 8);
3373
3374	/*
3375	 * Disable analog sequence
3376	 */
3377	/* Disable A15 power */
3378	urtwn_write_1(sc, R92C_LDOA15_CTRL, R92C_LDOA15_CTRL_OBUF);
3379	/* Disable digital core power */
3380	urtwn_write_1(sc, R92C_LDOV12D_CTRL,
3381	    urtwn_read_1(sc, R92C_LDOV12D_CTRL) &
3382	      ~R92C_LDOV12D_CTRL_LDV12_EN);
3383
3384	/* Enter PFM mode */
3385	urtwn_write_1(sc, R92C_SPS0_CTRL, 0x23);
3386
3387	/* Set USB suspend */
3388	urtwn_write_2(sc, R92C_APS_FSMCO,
3389	    R92C_APS_FSMCO_APDM_HOST |
3390	    R92C_APS_FSMCO_AFSM_HSUS |
3391	    R92C_APS_FSMCO_PFM_ALDN);
3392
3393	/* Lock ISO/CLK/Power control register. */
3394	urtwn_write_1(sc, R92C_RSV_CTRL, 0x0E);
3395}
3396
3397static void
3398urtwn_r88e_power_off(struct urtwn_softc *sc)
3399{
3400	uint8_t reg;
3401	int ntries;
3402
3403	/* Disable any kind of TX reports. */
3404	urtwn_write_1(sc, R88E_TX_RPT_CTRL,
3405	    urtwn_read_1(sc, R88E_TX_RPT_CTRL) &
3406	      ~(R88E_TX_RPT1_ENA | R88E_TX_RPT2_ENA));
3407
3408	/* Stop Rx. */
3409	urtwn_write_1(sc, R92C_CR, 0);
3410
3411	/* Move card to Low Power State. */
3412	/* Block all Tx queues. */
3413	urtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
3414
3415	for (ntries = 0; ntries < 20; ntries++) {
3416		/* Should be zero if no packet is transmitting. */
3417		if (urtwn_read_4(sc, R88E_SCH_TXCMD) == 0)
3418			break;
3419
3420		urtwn_ms_delay(sc);
3421	}
3422	if (ntries == 20) {
3423		device_printf(sc->sc_dev, "%s: failed to block Tx queues\n",
3424		    __func__);
3425		return;
3426	}
3427
3428	/* CCK and OFDM are disabled, and clock are gated. */
3429	urtwn_write_1(sc, R92C_SYS_FUNC_EN,
3430	    urtwn_read_1(sc, R92C_SYS_FUNC_EN) & ~R92C_SYS_FUNC_EN_BBRSTB);
3431
3432	urtwn_ms_delay(sc);
3433
3434	/* Reset MAC TRX */
3435	urtwn_write_1(sc, R92C_CR,
3436	    R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN |
3437	    R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN |
3438	    R92C_CR_PROTOCOL_EN | R92C_CR_SCHEDULE_EN);
3439
3440	/* check if removed later */
3441	urtwn_write_1(sc, R92C_CR + 1,
3442	    urtwn_read_1(sc, R92C_CR + 1) & ~(R92C_CR_ENSEC >> 8));
3443
3444	/* Respond TxOK to scheduler */
3445	urtwn_write_1(sc, R92C_DUAL_TSF_RST,
3446	    urtwn_read_1(sc, R92C_DUAL_TSF_RST) | 0x20);
3447
3448	/* If firmware in ram code, do reset. */
3449#ifndef URTWN_WITHOUT_UCODE
3450	if (urtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RDY)
3451		urtwn_r88e_fw_reset(sc);
3452#endif
3453
3454	/* Reset MCU ready status. */
3455	urtwn_write_1(sc, R92C_MCUFWDL, 0x00);
3456
3457	/* Disable 32k. */
3458	urtwn_write_1(sc, R88E_32K_CTRL,
3459	    urtwn_read_1(sc, R88E_32K_CTRL) & ~0x01);
3460
3461	/* Move card to Disabled state. */
3462	/* Turn off RF. */
3463	urtwn_write_1(sc, R92C_RF_CTRL, 0);
3464
3465	/* LDO Sleep mode. */
3466	urtwn_write_1(sc, R92C_LPLDO_CTRL,
3467	    urtwn_read_1(sc, R92C_LPLDO_CTRL) | R92C_LPLDO_CTRL_SLEEP);
3468
3469	/* Turn off MAC by HW state machine */
3470	urtwn_write_1(sc, R92C_APS_FSMCO + 1,
3471	    urtwn_read_1(sc, R92C_APS_FSMCO + 1) |
3472	    (R92C_APS_FSMCO_APFM_OFF >> 8));
3473
3474	for (ntries = 0; ntries < 20; ntries++) {
3475		/* Wait until it will be disabled. */
3476		if ((urtwn_read_1(sc, R92C_APS_FSMCO + 1) &
3477		    (R92C_APS_FSMCO_APFM_OFF >> 8)) == 0)
3478			break;
3479
3480		urtwn_ms_delay(sc);
3481	}
3482	if (ntries == 20) {
3483		device_printf(sc->sc_dev, "%s: could not turn off MAC\n",
3484		    __func__);
3485		return;
3486	}
3487
3488	/* schmit trigger */
3489	urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 2,
3490	    urtwn_read_1(sc, R92C_AFE_XTAL_CTRL + 2) | 0x80);
3491
3492	/* Enable WL suspend. */
3493	urtwn_write_1(sc, R92C_APS_FSMCO + 1,
3494	    (urtwn_read_1(sc, R92C_APS_FSMCO + 1) & ~0x10) | 0x08);
3495
3496	/* Enable bandgap mbias in suspend. */
3497	urtwn_write_1(sc, R92C_APS_FSMCO + 3, 0);
3498
3499	/* Clear SIC_EN register. */
3500	urtwn_write_1(sc, R92C_GPIO_MUXCFG + 1,
3501	    urtwn_read_1(sc, R92C_GPIO_MUXCFG + 1) & ~0x10);
3502
3503	/* Set USB suspend enable local register */
3504	urtwn_write_1(sc, R92C_USB_SUSPEND,
3505	    urtwn_read_1(sc, R92C_USB_SUSPEND) | 0x10);
3506
3507	/* Reset MCU IO Wrapper. */
3508	reg = urtwn_read_1(sc, R92C_RSV_CTRL + 1);
3509	urtwn_write_1(sc, R92C_RSV_CTRL + 1, reg & ~0x08);
3510	urtwn_write_1(sc, R92C_RSV_CTRL + 1, reg | 0x08);
3511
3512	/* marked as 'For Power Consumption' code. */
3513	urtwn_write_1(sc, R92C_GPIO_OUT, urtwn_read_1(sc, R92C_GPIO_IN));
3514	urtwn_write_1(sc, R92C_GPIO_IOSEL, 0xff);
3515
3516	urtwn_write_1(sc, R92C_GPIO_IO_SEL,
3517	    urtwn_read_1(sc, R92C_GPIO_IO_SEL) << 4);
3518	urtwn_write_1(sc, R92C_GPIO_MOD,
3519	    urtwn_read_1(sc, R92C_GPIO_MOD) | 0x0f);
3520
3521	/* Set LNA, TRSW, EX_PA Pin to output mode. */
3522	urtwn_write_4(sc, R88E_BB_PAD_CTRL, 0x00080808);
3523}
3524
3525static int
3526urtwn_llt_init(struct urtwn_softc *sc)
3527{
3528	int i, error, page_count, pktbuf_count;
3529
3530	page_count = (sc->chip & URTWN_CHIP_88E) ?
3531	    R88E_TX_PAGE_COUNT : R92C_TX_PAGE_COUNT;
3532	pktbuf_count = (sc->chip & URTWN_CHIP_88E) ?
3533	    R88E_TXPKTBUF_COUNT : R92C_TXPKTBUF_COUNT;
3534
3535	/* Reserve pages [0; page_count]. */
3536	for (i = 0; i < page_count; i++) {
3537		if ((error = urtwn_llt_write(sc, i, i + 1)) != 0)
3538			return (error);
3539	}
3540	/* NB: 0xff indicates end-of-list. */
3541	if ((error = urtwn_llt_write(sc, i, 0xff)) != 0)
3542		return (error);
3543	/*
3544	 * Use pages [page_count + 1; pktbuf_count - 1]
3545	 * as ring buffer.
3546	 */
3547	for (++i; i < pktbuf_count - 1; i++) {
3548		if ((error = urtwn_llt_write(sc, i, i + 1)) != 0)
3549			return (error);
3550	}
3551	/* Make the last page point to the beginning of the ring buffer. */
3552	error = urtwn_llt_write(sc, i, page_count + 1);
3553	return (error);
3554}
3555
3556#ifndef URTWN_WITHOUT_UCODE
3557static void
3558urtwn_fw_reset(struct urtwn_softc *sc)
3559{
3560	uint16_t reg;
3561	int ntries;
3562
3563	/* Tell 8051 to reset itself. */
3564	urtwn_write_1(sc, R92C_HMETFR + 3, 0x20);
3565
3566	/* Wait until 8051 resets by itself. */
3567	for (ntries = 0; ntries < 100; ntries++) {
3568		reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
3569		if (!(reg & R92C_SYS_FUNC_EN_CPUEN))
3570			return;
3571		urtwn_ms_delay(sc);
3572	}
3573	/* Force 8051 reset. */
3574	urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN);
3575}
3576
3577static void
3578urtwn_r88e_fw_reset(struct urtwn_softc *sc)
3579{
3580	uint16_t reg;
3581
3582	reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
3583	urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN);
3584	urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg | R92C_SYS_FUNC_EN_CPUEN);
3585}
3586
3587static int
3588urtwn_fw_loadpage(struct urtwn_softc *sc, int page, const uint8_t *buf, int len)
3589{
3590	uint32_t reg;
3591	usb_error_t error = USB_ERR_NORMAL_COMPLETION;
3592	int off, mlen;
3593
3594	reg = urtwn_read_4(sc, R92C_MCUFWDL);
3595	reg = RW(reg, R92C_MCUFWDL_PAGE, page);
3596	urtwn_write_4(sc, R92C_MCUFWDL, reg);
3597
3598	off = R92C_FW_START_ADDR;
3599	while (len > 0) {
3600		if (len > 196)
3601			mlen = 196;
3602		else if (len > 4)
3603			mlen = 4;
3604		else
3605			mlen = 1;
3606		/* XXX fix this deconst */
3607		error = urtwn_write_region_1(sc, off,
3608		    __DECONST(uint8_t *, buf), mlen);
3609		if (error != USB_ERR_NORMAL_COMPLETION)
3610			break;
3611		off += mlen;
3612		buf += mlen;
3613		len -= mlen;
3614	}
3615	return (error);
3616}
3617
3618static int
3619urtwn_load_firmware(struct urtwn_softc *sc)
3620{
3621	const struct firmware *fw;
3622	const struct r92c_fw_hdr *hdr;
3623	const char *imagename;
3624	const u_char *ptr;
3625	size_t len;
3626	uint32_t reg;
3627	int mlen, ntries, page, error;
3628
3629	URTWN_UNLOCK(sc);
3630	/* Read firmware image from the filesystem. */
3631	if (sc->chip & URTWN_CHIP_88E)
3632		imagename = "urtwn-rtl8188eufw";
3633	else if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) ==
3634		    URTWN_CHIP_UMC_A_CUT)
3635		imagename = "urtwn-rtl8192cfwU";
3636	else
3637		imagename = "urtwn-rtl8192cfwT";
3638
3639	fw = firmware_get(imagename);
3640	URTWN_LOCK(sc);
3641	if (fw == NULL) {
3642		device_printf(sc->sc_dev,
3643		    "failed loadfirmware of file %s\n", imagename);
3644		return (ENOENT);
3645	}
3646
3647	len = fw->datasize;
3648
3649	if (len < sizeof(*hdr)) {
3650		device_printf(sc->sc_dev, "firmware too short\n");
3651		error = EINVAL;
3652		goto fail;
3653	}
3654	ptr = fw->data;
3655	hdr = (const struct r92c_fw_hdr *)ptr;
3656	/* Check if there is a valid FW header and skip it. */
3657	if ((le16toh(hdr->signature) >> 4) == 0x88c ||
3658	    (le16toh(hdr->signature) >> 4) == 0x88e ||
3659	    (le16toh(hdr->signature) >> 4) == 0x92c) {
3660		URTWN_DPRINTF(sc, URTWN_DEBUG_FIRMWARE,
3661		    "FW V%d.%d %02d-%02d %02d:%02d\n",
3662		    le16toh(hdr->version), le16toh(hdr->subversion),
3663		    hdr->month, hdr->date, hdr->hour, hdr->minute);
3664		ptr += sizeof(*hdr);
3665		len -= sizeof(*hdr);
3666	}
3667
3668	if (urtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RAM_DL_SEL) {
3669		if (sc->chip & URTWN_CHIP_88E)
3670			urtwn_r88e_fw_reset(sc);
3671		else
3672			urtwn_fw_reset(sc);
3673		urtwn_write_1(sc, R92C_MCUFWDL, 0);
3674	}
3675
3676	if (!(sc->chip & URTWN_CHIP_88E)) {
3677		urtwn_write_2(sc, R92C_SYS_FUNC_EN,
3678		    urtwn_read_2(sc, R92C_SYS_FUNC_EN) |
3679		    R92C_SYS_FUNC_EN_CPUEN);
3680	}
3681	urtwn_write_1(sc, R92C_MCUFWDL,
3682	    urtwn_read_1(sc, R92C_MCUFWDL) | R92C_MCUFWDL_EN);
3683	urtwn_write_1(sc, R92C_MCUFWDL + 2,
3684	    urtwn_read_1(sc, R92C_MCUFWDL + 2) & ~0x08);
3685
3686	/* Reset the FWDL checksum. */
3687	urtwn_write_1(sc, R92C_MCUFWDL,
3688	    urtwn_read_1(sc, R92C_MCUFWDL) | R92C_MCUFWDL_CHKSUM_RPT);
3689
3690	for (page = 0; len > 0; page++) {
3691		mlen = min(len, R92C_FW_PAGE_SIZE);
3692		error = urtwn_fw_loadpage(sc, page, ptr, mlen);
3693		if (error != 0) {
3694			device_printf(sc->sc_dev,
3695			    "could not load firmware page\n");
3696			goto fail;
3697		}
3698		ptr += mlen;
3699		len -= mlen;
3700	}
3701	urtwn_write_1(sc, R92C_MCUFWDL,
3702	    urtwn_read_1(sc, R92C_MCUFWDL) & ~R92C_MCUFWDL_EN);
3703	urtwn_write_1(sc, R92C_MCUFWDL + 1, 0);
3704
3705	/* Wait for checksum report. */
3706	for (ntries = 0; ntries < 1000; ntries++) {
3707		if (urtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_CHKSUM_RPT)
3708			break;
3709		urtwn_ms_delay(sc);
3710	}
3711	if (ntries == 1000) {
3712		device_printf(sc->sc_dev,
3713		    "timeout waiting for checksum report\n");
3714		error = ETIMEDOUT;
3715		goto fail;
3716	}
3717
3718	reg = urtwn_read_4(sc, R92C_MCUFWDL);
3719	reg = (reg & ~R92C_MCUFWDL_WINTINI_RDY) | R92C_MCUFWDL_RDY;
3720	urtwn_write_4(sc, R92C_MCUFWDL, reg);
3721	if (sc->chip & URTWN_CHIP_88E)
3722		urtwn_r88e_fw_reset(sc);
3723	/* Wait for firmware readiness. */
3724	for (ntries = 0; ntries < 1000; ntries++) {
3725		if (urtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_WINTINI_RDY)
3726			break;
3727		urtwn_ms_delay(sc);
3728	}
3729	if (ntries == 1000) {
3730		device_printf(sc->sc_dev,
3731		    "timeout waiting for firmware readiness\n");
3732		error = ETIMEDOUT;
3733		goto fail;
3734	}
3735fail:
3736	firmware_put(fw, FIRMWARE_UNLOAD);
3737	return (error);
3738}
3739#endif
3740
3741static int
3742urtwn_dma_init(struct urtwn_softc *sc)
3743{
3744	struct usb_endpoint *ep, *ep_end;
3745	usb_error_t usb_err;
3746	uint32_t reg;
3747	int hashq, hasnq, haslq, nqueues, ntx;
3748	int error, pagecount, npubqpages, nqpages, nrempages, tx_boundary;
3749
3750	/* Initialize LLT table. */
3751	error = urtwn_llt_init(sc);
3752	if (error != 0)
3753		return (error);
3754
3755	/* Determine the number of bulk-out pipes. */
3756	ntx = 0;
3757	ep = sc->sc_udev->endpoints;
3758	ep_end = sc->sc_udev->endpoints + sc->sc_udev->endpoints_max;
3759	for (; ep != ep_end; ep++) {
3760		if ((ep->edesc == NULL) ||
3761		    (ep->iface_index != sc->sc_iface_index))
3762			continue;
3763		if (UE_GET_DIR(ep->edesc->bEndpointAddress) == UE_DIR_OUT)
3764			ntx++;
3765	}
3766	if (ntx == 0) {
3767		device_printf(sc->sc_dev,
3768		    "%d: invalid number of Tx bulk pipes\n", ntx);
3769		return (EIO);
3770	}
3771
3772	/* Get Tx queues to USB endpoints mapping. */
3773	hashq = hasnq = haslq = nqueues = 0;
3774	switch (ntx) {
3775	case 1: hashq = 1; break;
3776	case 2: hashq = hasnq = 1; break;
3777	case 3: case 4: hashq = hasnq = haslq = 1; break;
3778	}
3779	nqueues = hashq + hasnq + haslq;
3780	if (nqueues == 0)
3781		return (EIO);
3782
3783	npubqpages = nqpages = nrempages = pagecount = 0;
3784	if (sc->chip & URTWN_CHIP_88E)
3785		tx_boundary = R88E_TX_PAGE_BOUNDARY;
3786	else {
3787		pagecount = R92C_TX_PAGE_COUNT;
3788		npubqpages = R92C_PUBQ_NPAGES;
3789		tx_boundary = R92C_TX_PAGE_BOUNDARY;
3790	}
3791
3792	/* Set number of pages for normal priority queue. */
3793	if (sc->chip & URTWN_CHIP_88E) {
3794		usb_err = urtwn_write_2(sc, R92C_RQPN_NPQ, 0xd);
3795		if (usb_err != USB_ERR_NORMAL_COMPLETION)
3796			return (EIO);
3797		usb_err = urtwn_write_4(sc, R92C_RQPN, 0x808e000d);
3798		if (usb_err != USB_ERR_NORMAL_COMPLETION)
3799			return (EIO);
3800	} else {
3801		/* Get the number of pages for each queue. */
3802		nqpages = (pagecount - npubqpages) / nqueues;
3803		/*
3804		 * The remaining pages are assigned to the high priority
3805		 * queue.
3806		 */
3807		nrempages = (pagecount - npubqpages) % nqueues;
3808		usb_err = urtwn_write_1(sc, R92C_RQPN_NPQ, hasnq ? nqpages : 0);
3809		if (usb_err != USB_ERR_NORMAL_COMPLETION)
3810			return (EIO);
3811		usb_err = urtwn_write_4(sc, R92C_RQPN,
3812		    /* Set number of pages for public queue. */
3813		    SM(R92C_RQPN_PUBQ, npubqpages) |
3814		    /* Set number of pages for high priority queue. */
3815		    SM(R92C_RQPN_HPQ, hashq ? nqpages + nrempages : 0) |
3816		    /* Set number of pages for low priority queue. */
3817		    SM(R92C_RQPN_LPQ, haslq ? nqpages : 0) |
3818		    /* Load values. */
3819		    R92C_RQPN_LD);
3820		if (usb_err != USB_ERR_NORMAL_COMPLETION)
3821			return (EIO);
3822	}
3823
3824	usb_err = urtwn_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, tx_boundary);
3825	if (usb_err != USB_ERR_NORMAL_COMPLETION)
3826		return (EIO);
3827	usb_err = urtwn_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, tx_boundary);
3828	if (usb_err != USB_ERR_NORMAL_COMPLETION)
3829		return (EIO);
3830	usb_err = urtwn_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD, tx_boundary);
3831	if (usb_err != USB_ERR_NORMAL_COMPLETION)
3832		return (EIO);
3833	usb_err = urtwn_write_1(sc, R92C_TRXFF_BNDY, tx_boundary);
3834	if (usb_err != USB_ERR_NORMAL_COMPLETION)
3835		return (EIO);
3836	usb_err = urtwn_write_1(sc, R92C_TDECTRL + 1, tx_boundary);
3837	if (usb_err != USB_ERR_NORMAL_COMPLETION)
3838		return (EIO);
3839
3840	/* Set queue to USB pipe mapping. */
3841	reg = urtwn_read_2(sc, R92C_TRXDMA_CTRL);
3842	reg &= ~R92C_TRXDMA_CTRL_QMAP_M;
3843	if (nqueues == 1) {
3844		if (hashq)
3845			reg |= R92C_TRXDMA_CTRL_QMAP_HQ;
3846		else if (hasnq)
3847			reg |= R92C_TRXDMA_CTRL_QMAP_NQ;
3848		else
3849			reg |= R92C_TRXDMA_CTRL_QMAP_LQ;
3850	} else if (nqueues == 2) {
3851		/*
3852		 * All 2-endpoints configs have high and normal
3853		 * priority queues.
3854		 */
3855		reg |= R92C_TRXDMA_CTRL_QMAP_HQ_NQ;
3856	} else
3857		reg |= R92C_TRXDMA_CTRL_QMAP_3EP;
3858	usb_err = urtwn_write_2(sc, R92C_TRXDMA_CTRL, reg);
3859	if (usb_err != USB_ERR_NORMAL_COMPLETION)
3860		return (EIO);
3861
3862	/* Set Tx/Rx transfer page boundary. */
3863	usb_err = urtwn_write_2(sc, R92C_TRXFF_BNDY + 2,
3864	    (sc->chip & URTWN_CHIP_88E) ? 0x23ff : 0x27ff);
3865	if (usb_err != USB_ERR_NORMAL_COMPLETION)
3866		return (EIO);
3867
3868	/* Set Tx/Rx transfer page size. */
3869	usb_err = urtwn_write_1(sc, R92C_PBP,
3870	    SM(R92C_PBP_PSRX, R92C_PBP_128) |
3871	    SM(R92C_PBP_PSTX, R92C_PBP_128));
3872	if (usb_err != USB_ERR_NORMAL_COMPLETION)
3873		return (EIO);
3874
3875	return (0);
3876}
3877
3878static int
3879urtwn_mac_init(struct urtwn_softc *sc)
3880{
3881	usb_error_t error;
3882	int i;
3883
3884	/* Write MAC initialization values. */
3885	if (sc->chip & URTWN_CHIP_88E) {
3886		for (i = 0; i < nitems(rtl8188eu_mac); i++) {
3887			error = urtwn_write_1(sc, rtl8188eu_mac[i].reg,
3888			    rtl8188eu_mac[i].val);
3889			if (error != USB_ERR_NORMAL_COMPLETION)
3890				return (EIO);
3891		}
3892		urtwn_write_1(sc, R92C_MAX_AGGR_NUM, 0x07);
3893	} else {
3894		for (i = 0; i < nitems(rtl8192cu_mac); i++)
3895			error = urtwn_write_1(sc, rtl8192cu_mac[i].reg,
3896			    rtl8192cu_mac[i].val);
3897			if (error != USB_ERR_NORMAL_COMPLETION)
3898				return (EIO);
3899	}
3900
3901	return (0);
3902}
3903
3904static void
3905urtwn_bb_init(struct urtwn_softc *sc)
3906{
3907	const struct urtwn_bb_prog *prog;
3908	uint32_t reg;
3909	uint8_t crystalcap;
3910	int i;
3911
3912	/* Enable BB and RF. */
3913	urtwn_write_2(sc, R92C_SYS_FUNC_EN,
3914	    urtwn_read_2(sc, R92C_SYS_FUNC_EN) |
3915	    R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST |
3916	    R92C_SYS_FUNC_EN_DIO_RF);
3917
3918	if (!(sc->chip & URTWN_CHIP_88E))
3919		urtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);
3920
3921	urtwn_write_1(sc, R92C_RF_CTRL,
3922	    R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
3923	urtwn_write_1(sc, R92C_SYS_FUNC_EN,
3924	    R92C_SYS_FUNC_EN_USBA | R92C_SYS_FUNC_EN_USBD |
3925	    R92C_SYS_FUNC_EN_BB_GLB_RST | R92C_SYS_FUNC_EN_BBRSTB);
3926
3927	if (!(sc->chip & URTWN_CHIP_88E)) {
3928		urtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f);
3929		urtwn_write_1(sc, 0x15, 0xe9);
3930		urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
3931	}
3932
3933	/* Select BB programming based on board type. */
3934	if (sc->chip & URTWN_CHIP_88E)
3935		prog = &rtl8188eu_bb_prog;
3936	else if (!(sc->chip & URTWN_CHIP_92C)) {
3937		if (sc->board_type == R92C_BOARD_TYPE_MINICARD)
3938			prog = &rtl8188ce_bb_prog;
3939		else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA)
3940			prog = &rtl8188ru_bb_prog;
3941		else
3942			prog = &rtl8188cu_bb_prog;
3943	} else {
3944		if (sc->board_type == R92C_BOARD_TYPE_MINICARD)
3945			prog = &rtl8192ce_bb_prog;
3946		else
3947			prog = &rtl8192cu_bb_prog;
3948	}
3949	/* Write BB initialization values. */
3950	for (i = 0; i < prog->count; i++) {
3951		urtwn_bb_write(sc, prog->regs[i], prog->vals[i]);
3952		urtwn_ms_delay(sc);
3953	}
3954
3955	if (sc->chip & URTWN_CHIP_92C_1T2R) {
3956		/* 8192C 1T only configuration. */
3957		reg = urtwn_bb_read(sc, R92C_FPGA0_TXINFO);
3958		reg = (reg & ~0x00000003) | 0x2;
3959		urtwn_bb_write(sc, R92C_FPGA0_TXINFO, reg);
3960
3961		reg = urtwn_bb_read(sc, R92C_FPGA1_TXINFO);
3962		reg = (reg & ~0x00300033) | 0x00200022;
3963		urtwn_bb_write(sc, R92C_FPGA1_TXINFO, reg);
3964
3965		reg = urtwn_bb_read(sc, R92C_CCK0_AFESETTING);
3966		reg = (reg & ~0xff000000) | 0x45 << 24;
3967		urtwn_bb_write(sc, R92C_CCK0_AFESETTING, reg);
3968
3969		reg = urtwn_bb_read(sc, R92C_OFDM0_TRXPATHENA);
3970		reg = (reg & ~0x000000ff) | 0x23;
3971		urtwn_bb_write(sc, R92C_OFDM0_TRXPATHENA, reg);
3972
3973		reg = urtwn_bb_read(sc, R92C_OFDM0_AGCPARAM1);
3974		reg = (reg & ~0x00000030) | 1 << 4;
3975		urtwn_bb_write(sc, R92C_OFDM0_AGCPARAM1, reg);
3976
3977		reg = urtwn_bb_read(sc, 0xe74);
3978		reg = (reg & ~0x0c000000) | 2 << 26;
3979		urtwn_bb_write(sc, 0xe74, reg);
3980		reg = urtwn_bb_read(sc, 0xe78);
3981		reg = (reg & ~0x0c000000) | 2 << 26;
3982		urtwn_bb_write(sc, 0xe78, reg);
3983		reg = urtwn_bb_read(sc, 0xe7c);
3984		reg = (reg & ~0x0c000000) | 2 << 26;
3985		urtwn_bb_write(sc, 0xe7c, reg);
3986		reg = urtwn_bb_read(sc, 0xe80);
3987		reg = (reg & ~0x0c000000) | 2 << 26;
3988		urtwn_bb_write(sc, 0xe80, reg);
3989		reg = urtwn_bb_read(sc, 0xe88);
3990		reg = (reg & ~0x0c000000) | 2 << 26;
3991		urtwn_bb_write(sc, 0xe88, reg);
3992	}
3993
3994	/* Write AGC values. */
3995	for (i = 0; i < prog->agccount; i++) {
3996		urtwn_bb_write(sc, R92C_OFDM0_AGCRSSITABLE,
3997		    prog->agcvals[i]);
3998		urtwn_ms_delay(sc);
3999	}
4000
4001	if (sc->chip & URTWN_CHIP_88E) {
4002		urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553422);
4003		urtwn_ms_delay(sc);
4004		urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553420);
4005		urtwn_ms_delay(sc);
4006
4007		crystalcap = sc->rom.r88e_rom.crystalcap;
4008		if (crystalcap == 0xff)
4009			crystalcap = 0x20;
4010		crystalcap &= 0x3f;
4011		reg = urtwn_bb_read(sc, R92C_AFE_XTAL_CTRL);
4012		urtwn_bb_write(sc, R92C_AFE_XTAL_CTRL,
4013		    RW(reg, R92C_AFE_XTAL_CTRL_ADDR,
4014		    crystalcap | crystalcap << 6));
4015	} else {
4016		if (urtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) &
4017		    R92C_HSSI_PARAM2_CCK_HIPWR)
4018			sc->sc_flags |= URTWN_FLAG_CCK_HIPWR;
4019	}
4020}
4021
4022static void
4023urtwn_rf_init(struct urtwn_softc *sc)
4024{
4025	const struct urtwn_rf_prog *prog;
4026	uint32_t reg, type;
4027	int i, j, idx, off;
4028
4029	/* Select RF programming based on board type. */
4030	if (sc->chip & URTWN_CHIP_88E)
4031		prog = rtl8188eu_rf_prog;
4032	else if (!(sc->chip & URTWN_CHIP_92C)) {
4033		if (sc->board_type == R92C_BOARD_TYPE_MINICARD)
4034			prog = rtl8188ce_rf_prog;
4035		else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA)
4036			prog = rtl8188ru_rf_prog;
4037		else
4038			prog = rtl8188cu_rf_prog;
4039	} else
4040		prog = rtl8192ce_rf_prog;
4041
4042	for (i = 0; i < sc->nrxchains; i++) {
4043		/* Save RF_ENV control type. */
4044		idx = i / 2;
4045		off = (i % 2) * 16;
4046		reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(idx));
4047		type = (reg >> off) & 0x10;
4048
4049		/* Set RF_ENV enable. */
4050		reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(i));
4051		reg |= 0x100000;
4052		urtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(i), reg);
4053		urtwn_ms_delay(sc);
4054		/* Set RF_ENV output high. */
4055		reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(i));
4056		reg |= 0x10;
4057		urtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(i), reg);
4058		urtwn_ms_delay(sc);
4059		/* Set address and data lengths of RF registers. */
4060		reg = urtwn_bb_read(sc, R92C_HSSI_PARAM2(i));
4061		reg &= ~R92C_HSSI_PARAM2_ADDR_LENGTH;
4062		urtwn_bb_write(sc, R92C_HSSI_PARAM2(i), reg);
4063		urtwn_ms_delay(sc);
4064		reg = urtwn_bb_read(sc, R92C_HSSI_PARAM2(i));
4065		reg &= ~R92C_HSSI_PARAM2_DATA_LENGTH;
4066		urtwn_bb_write(sc, R92C_HSSI_PARAM2(i), reg);
4067		urtwn_ms_delay(sc);
4068
4069		/* Write RF initialization values for this chain. */
4070		for (j = 0; j < prog[i].count; j++) {
4071			if (prog[i].regs[j] >= 0xf9 &&
4072			    prog[i].regs[j] <= 0xfe) {
4073				/*
4074				 * These are fake RF registers offsets that
4075				 * indicate a delay is required.
4076				 */
4077				usb_pause_mtx(&sc->sc_mtx, hz / 20);	/* 50ms */
4078				continue;
4079			}
4080			urtwn_rf_write(sc, i, prog[i].regs[j],
4081			    prog[i].vals[j]);
4082			urtwn_ms_delay(sc);
4083		}
4084
4085		/* Restore RF_ENV control type. */
4086		reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(idx));
4087		reg &= ~(0x10 << off) | (type << off);
4088		urtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(idx), reg);
4089
4090		/* Cache RF register CHNLBW. */
4091		sc->rf_chnlbw[i] = urtwn_rf_read(sc, i, R92C_RF_CHNLBW);
4092	}
4093
4094	if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) ==
4095	    URTWN_CHIP_UMC_A_CUT) {
4096		urtwn_rf_write(sc, 0, R92C_RF_RX_G1, 0x30255);
4097		urtwn_rf_write(sc, 0, R92C_RF_RX_G2, 0x50a00);
4098	}
4099}
4100
4101static void
4102urtwn_cam_init(struct urtwn_softc *sc)
4103{
4104	/* Invalidate all CAM entries. */
4105	urtwn_write_4(sc, R92C_CAMCMD,
4106	    R92C_CAMCMD_POLLING | R92C_CAMCMD_CLR);
4107}
4108
4109static int
4110urtwn_cam_write(struct urtwn_softc *sc, uint32_t addr, uint32_t data)
4111{
4112	usb_error_t error;
4113
4114	error = urtwn_write_4(sc, R92C_CAMWRITE, data);
4115	if (error != USB_ERR_NORMAL_COMPLETION)
4116		return (EIO);
4117	error = urtwn_write_4(sc, R92C_CAMCMD,
4118	    R92C_CAMCMD_POLLING | R92C_CAMCMD_WRITE |
4119	    SM(R92C_CAMCMD_ADDR, addr));
4120	if (error != USB_ERR_NORMAL_COMPLETION)
4121		return (EIO);
4122
4123	return (0);
4124}
4125
4126static void
4127urtwn_pa_bias_init(struct urtwn_softc *sc)
4128{
4129	uint8_t reg;
4130	int i;
4131
4132	for (i = 0; i < sc->nrxchains; i++) {
4133		if (sc->pa_setting & (1 << i))
4134			continue;
4135		urtwn_rf_write(sc, i, R92C_RF_IPA, 0x0f406);
4136		urtwn_rf_write(sc, i, R92C_RF_IPA, 0x4f406);
4137		urtwn_rf_write(sc, i, R92C_RF_IPA, 0x8f406);
4138		urtwn_rf_write(sc, i, R92C_RF_IPA, 0xcf406);
4139	}
4140	if (!(sc->pa_setting & 0x10)) {
4141		reg = urtwn_read_1(sc, 0x16);
4142		reg = (reg & ~0xf0) | 0x90;
4143		urtwn_write_1(sc, 0x16, reg);
4144	}
4145}
4146
4147static void
4148urtwn_rxfilter_init(struct urtwn_softc *sc)
4149{
4150	struct ieee80211com *ic = &sc->sc_ic;
4151	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
4152	uint32_t rcr;
4153	uint16_t filter;
4154
4155	URTWN_ASSERT_LOCKED(sc);
4156
4157	/* Accept all multicast frames. */
4158	urtwn_write_4(sc, R92C_MAR + 0, 0xffffffff);
4159	urtwn_write_4(sc, R92C_MAR + 4, 0xffffffff);
4160
4161	/* Filter for management frames. */
4162	filter = 0x7f3f;
4163	switch (vap->iv_opmode) {
4164	case IEEE80211_M_STA:
4165		filter &= ~(
4166		    R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_ASSOC_REQ) |
4167		    R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_REASSOC_REQ) |
4168		    R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_PROBE_REQ));
4169		break;
4170	case IEEE80211_M_HOSTAP:
4171		filter &= ~(
4172		    R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_ASSOC_RESP) |
4173		    R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_REASSOC_RESP) |
4174		    R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_BEACON));
4175		break;
4176	case IEEE80211_M_MONITOR:
4177	case IEEE80211_M_IBSS:
4178		break;
4179	default:
4180		device_printf(sc->sc_dev, "%s: undefined opmode %d\n",
4181		    __func__, vap->iv_opmode);
4182		break;
4183	}
4184	urtwn_write_2(sc, R92C_RXFLTMAP0, filter);
4185
4186	/* Reject all control frames. */
4187	urtwn_write_2(sc, R92C_RXFLTMAP1, 0x0000);
4188
4189	/* Reject all data frames. */
4190	urtwn_write_2(sc, R92C_RXFLTMAP2, 0x0000);
4191
4192	rcr = R92C_RCR_AM | R92C_RCR_AB | R92C_RCR_APM |
4193	      R92C_RCR_HTC_LOC_CTRL | R92C_RCR_APP_PHYSTS |
4194	      R92C_RCR_APP_ICV | R92C_RCR_APP_MIC;
4195
4196	if (vap->iv_opmode == IEEE80211_M_MONITOR) {
4197		/* Accept all frames. */
4198		rcr |= R92C_RCR_ACF | R92C_RCR_ADF | R92C_RCR_AMF |
4199		       R92C_RCR_AAP;
4200	}
4201
4202	/* Set Rx filter. */
4203	urtwn_write_4(sc, R92C_RCR, rcr);
4204
4205	if (ic->ic_promisc != 0) {
4206		/* Update Rx filter. */
4207		urtwn_set_promisc(sc);
4208	}
4209}
4210
4211static void
4212urtwn_edca_init(struct urtwn_softc *sc)
4213{
4214	urtwn_write_2(sc, R92C_SPEC_SIFS, 0x100a);
4215	urtwn_write_2(sc, R92C_MAC_SPEC_SIFS, 0x100a);
4216	urtwn_write_2(sc, R92C_SIFS_CCK, 0x100a);
4217	urtwn_write_2(sc, R92C_SIFS_OFDM, 0x100a);
4218	urtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x005ea42b);
4219	urtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a44f);
4220	urtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005ea324);
4221	urtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002fa226);
4222}
4223
4224static void
4225urtwn_write_txpower(struct urtwn_softc *sc, int chain,
4226    uint16_t power[URTWN_RIDX_COUNT])
4227{
4228	uint32_t reg;
4229
4230	/* Write per-CCK rate Tx power. */
4231	if (chain == 0) {
4232		reg = urtwn_bb_read(sc, R92C_TXAGC_A_CCK1_MCS32);
4233		reg = RW(reg, R92C_TXAGC_A_CCK1,  power[0]);
4234		urtwn_bb_write(sc, R92C_TXAGC_A_CCK1_MCS32, reg);
4235		reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11);
4236		reg = RW(reg, R92C_TXAGC_A_CCK2,  power[1]);
4237		reg = RW(reg, R92C_TXAGC_A_CCK55, power[2]);
4238		reg = RW(reg, R92C_TXAGC_A_CCK11, power[3]);
4239		urtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg);
4240	} else {
4241		reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK1_55_MCS32);
4242		reg = RW(reg, R92C_TXAGC_B_CCK1,  power[0]);
4243		reg = RW(reg, R92C_TXAGC_B_CCK2,  power[1]);
4244		reg = RW(reg, R92C_TXAGC_B_CCK55, power[2]);
4245		urtwn_bb_write(sc, R92C_TXAGC_B_CCK1_55_MCS32, reg);
4246		reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11);
4247		reg = RW(reg, R92C_TXAGC_B_CCK11, power[3]);
4248		urtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg);
4249	}
4250	/* Write per-OFDM rate Tx power. */
4251	urtwn_bb_write(sc, R92C_TXAGC_RATE18_06(chain),
4252	    SM(R92C_TXAGC_RATE06, power[ 4]) |
4253	    SM(R92C_TXAGC_RATE09, power[ 5]) |
4254	    SM(R92C_TXAGC_RATE12, power[ 6]) |
4255	    SM(R92C_TXAGC_RATE18, power[ 7]));
4256	urtwn_bb_write(sc, R92C_TXAGC_RATE54_24(chain),
4257	    SM(R92C_TXAGC_RATE24, power[ 8]) |
4258	    SM(R92C_TXAGC_RATE36, power[ 9]) |
4259	    SM(R92C_TXAGC_RATE48, power[10]) |
4260	    SM(R92C_TXAGC_RATE54, power[11]));
4261	/* Write per-MCS Tx power. */
4262	urtwn_bb_write(sc, R92C_TXAGC_MCS03_MCS00(chain),
4263	    SM(R92C_TXAGC_MCS00,  power[12]) |
4264	    SM(R92C_TXAGC_MCS01,  power[13]) |
4265	    SM(R92C_TXAGC_MCS02,  power[14]) |
4266	    SM(R92C_TXAGC_MCS03,  power[15]));
4267	urtwn_bb_write(sc, R92C_TXAGC_MCS07_MCS04(chain),
4268	    SM(R92C_TXAGC_MCS04,  power[16]) |
4269	    SM(R92C_TXAGC_MCS05,  power[17]) |
4270	    SM(R92C_TXAGC_MCS06,  power[18]) |
4271	    SM(R92C_TXAGC_MCS07,  power[19]));
4272	urtwn_bb_write(sc, R92C_TXAGC_MCS11_MCS08(chain),
4273	    SM(R92C_TXAGC_MCS08,  power[20]) |
4274	    SM(R92C_TXAGC_MCS09,  power[21]) |
4275	    SM(R92C_TXAGC_MCS10,  power[22]) |
4276	    SM(R92C_TXAGC_MCS11,  power[23]));
4277	urtwn_bb_write(sc, R92C_TXAGC_MCS15_MCS12(chain),
4278	    SM(R92C_TXAGC_MCS12,  power[24]) |
4279	    SM(R92C_TXAGC_MCS13,  power[25]) |
4280	    SM(R92C_TXAGC_MCS14,  power[26]) |
4281	    SM(R92C_TXAGC_MCS15,  power[27]));
4282}
4283
4284static void
4285urtwn_get_txpower(struct urtwn_softc *sc, int chain,
4286    struct ieee80211_channel *c, struct ieee80211_channel *extc,
4287    uint16_t power[URTWN_RIDX_COUNT])
4288{
4289	struct ieee80211com *ic = &sc->sc_ic;
4290	struct r92c_rom *rom = &sc->rom.r92c_rom;
4291	uint16_t cckpow, ofdmpow, htpow, diff, max;
4292	const struct urtwn_txpwr *base;
4293	int ridx, chan, group;
4294
4295	/* Determine channel group. */
4296	chan = ieee80211_chan2ieee(ic, c);	/* XXX center freq! */
4297	if (chan <= 3)
4298		group = 0;
4299	else if (chan <= 9)
4300		group = 1;
4301	else
4302		group = 2;
4303
4304	/* Get original Tx power based on board type and RF chain. */
4305	if (!(sc->chip & URTWN_CHIP_92C)) {
4306		if (sc->board_type == R92C_BOARD_TYPE_HIGHPA)
4307			base = &rtl8188ru_txagc[chain];
4308		else
4309			base = &rtl8192cu_txagc[chain];
4310	} else
4311		base = &rtl8192cu_txagc[chain];
4312
4313	memset(power, 0, URTWN_RIDX_COUNT * sizeof(power[0]));
4314	if (sc->regulatory == 0) {
4315		for (ridx = URTWN_RIDX_CCK1; ridx <= URTWN_RIDX_CCK11; ridx++)
4316			power[ridx] = base->pwr[0][ridx];
4317	}
4318	for (ridx = URTWN_RIDX_OFDM6; ridx < URTWN_RIDX_COUNT; ridx++) {
4319		if (sc->regulatory == 3) {
4320			power[ridx] = base->pwr[0][ridx];
4321			/* Apply vendor limits. */
4322			if (extc != NULL)
4323				max = rom->ht40_max_pwr[group];
4324			else
4325				max = rom->ht20_max_pwr[group];
4326			max = (max >> (chain * 4)) & 0xf;
4327			if (power[ridx] > max)
4328				power[ridx] = max;
4329		} else if (sc->regulatory == 1) {
4330			if (extc == NULL)
4331				power[ridx] = base->pwr[group][ridx];
4332		} else if (sc->regulatory != 2)
4333			power[ridx] = base->pwr[0][ridx];
4334	}
4335
4336	/* Compute per-CCK rate Tx power. */
4337	cckpow = rom->cck_tx_pwr[chain][group];
4338	for (ridx = URTWN_RIDX_CCK1; ridx <= URTWN_RIDX_CCK11; ridx++) {
4339		power[ridx] += cckpow;
4340		if (power[ridx] > R92C_MAX_TX_PWR)
4341			power[ridx] = R92C_MAX_TX_PWR;
4342	}
4343
4344	htpow = rom->ht40_1s_tx_pwr[chain][group];
4345	if (sc->ntxchains > 1) {
4346		/* Apply reduction for 2 spatial streams. */
4347		diff = rom->ht40_2s_tx_pwr_diff[group];
4348		diff = (diff >> (chain * 4)) & 0xf;
4349		htpow = (htpow > diff) ? htpow - diff : 0;
4350	}
4351
4352	/* Compute per-OFDM rate Tx power. */
4353	diff = rom->ofdm_tx_pwr_diff[group];
4354	diff = (diff >> (chain * 4)) & 0xf;
4355	ofdmpow = htpow + diff;	/* HT->OFDM correction. */
4356	for (ridx = URTWN_RIDX_OFDM6; ridx <= URTWN_RIDX_OFDM54; ridx++) {
4357		power[ridx] += ofdmpow;
4358		if (power[ridx] > R92C_MAX_TX_PWR)
4359			power[ridx] = R92C_MAX_TX_PWR;
4360	}
4361
4362	/* Compute per-MCS Tx power. */
4363	if (extc == NULL) {
4364		diff = rom->ht20_tx_pwr_diff[group];
4365		diff = (diff >> (chain * 4)) & 0xf;
4366		htpow += diff;	/* HT40->HT20 correction. */
4367	}
4368	for (ridx = 12; ridx <= 27; ridx++) {
4369		power[ridx] += htpow;
4370		if (power[ridx] > R92C_MAX_TX_PWR)
4371			power[ridx] = R92C_MAX_TX_PWR;
4372	}
4373#ifdef USB_DEBUG
4374	if (sc->sc_debug & URTWN_DEBUG_TXPWR) {
4375		/* Dump per-rate Tx power values. */
4376		printf("Tx power for chain %d:\n", chain);
4377		for (ridx = URTWN_RIDX_CCK1; ridx < URTWN_RIDX_COUNT; ridx++)
4378			printf("Rate %d = %u\n", ridx, power[ridx]);
4379	}
4380#endif
4381}
4382
4383static void
4384urtwn_r88e_get_txpower(struct urtwn_softc *sc, int chain,
4385    struct ieee80211_channel *c, struct ieee80211_channel *extc,
4386    uint16_t power[URTWN_RIDX_COUNT])
4387{
4388	struct ieee80211com *ic = &sc->sc_ic;
4389	struct r88e_rom *rom = &sc->rom.r88e_rom;
4390	uint16_t cckpow, ofdmpow, bw20pow, htpow;
4391	const struct urtwn_r88e_txpwr *base;
4392	int ridx, chan, group;
4393
4394	/* Determine channel group. */
4395	chan = ieee80211_chan2ieee(ic, c);	/* XXX center freq! */
4396	if (chan <= 2)
4397		group = 0;
4398	else if (chan <= 5)
4399		group = 1;
4400	else if (chan <= 8)
4401		group = 2;
4402	else if (chan <= 11)
4403		group = 3;
4404	else if (chan <= 13)
4405		group = 4;
4406	else
4407		group = 5;
4408
4409	/* Get original Tx power based on board type and RF chain. */
4410	base = &rtl8188eu_txagc[chain];
4411
4412	memset(power, 0, URTWN_RIDX_COUNT * sizeof(power[0]));
4413	if (sc->regulatory == 0) {
4414		for (ridx = URTWN_RIDX_CCK1; ridx <= URTWN_RIDX_CCK11; ridx++)
4415			power[ridx] = base->pwr[0][ridx];
4416	}
4417	for (ridx = URTWN_RIDX_OFDM6; ridx < URTWN_RIDX_COUNT; ridx++) {
4418		if (sc->regulatory == 3)
4419			power[ridx] = base->pwr[0][ridx];
4420		else if (sc->regulatory == 1) {
4421			if (extc == NULL)
4422				power[ridx] = base->pwr[group][ridx];
4423		} else if (sc->regulatory != 2)
4424			power[ridx] = base->pwr[0][ridx];
4425	}
4426
4427	/* Compute per-CCK rate Tx power. */
4428	cckpow = rom->cck_tx_pwr[group];
4429	for (ridx = URTWN_RIDX_CCK1; ridx <= URTWN_RIDX_CCK11; ridx++) {
4430		power[ridx] += cckpow;
4431		if (power[ridx] > R92C_MAX_TX_PWR)
4432			power[ridx] = R92C_MAX_TX_PWR;
4433	}
4434
4435	htpow = rom->ht40_tx_pwr[group];
4436
4437	/* Compute per-OFDM rate Tx power. */
4438	ofdmpow = htpow + sc->ofdm_tx_pwr_diff;
4439	for (ridx = URTWN_RIDX_OFDM6; ridx <= URTWN_RIDX_OFDM54; ridx++) {
4440		power[ridx] += ofdmpow;
4441		if (power[ridx] > R92C_MAX_TX_PWR)
4442			power[ridx] = R92C_MAX_TX_PWR;
4443	}
4444
4445	bw20pow = htpow + sc->bw20_tx_pwr_diff;
4446	for (ridx = 12; ridx <= 27; ridx++) {
4447		power[ridx] += bw20pow;
4448		if (power[ridx] > R92C_MAX_TX_PWR)
4449			power[ridx] = R92C_MAX_TX_PWR;
4450	}
4451}
4452
4453static void
4454urtwn_set_txpower(struct urtwn_softc *sc, struct ieee80211_channel *c,
4455    struct ieee80211_channel *extc)
4456{
4457	uint16_t power[URTWN_RIDX_COUNT];
4458	int i;
4459
4460	for (i = 0; i < sc->ntxchains; i++) {
4461		/* Compute per-rate Tx power values. */
4462		if (sc->chip & URTWN_CHIP_88E)
4463			urtwn_r88e_get_txpower(sc, i, c, extc, power);
4464		else
4465			urtwn_get_txpower(sc, i, c, extc, power);
4466		/* Write per-rate Tx power values to hardware. */
4467		urtwn_write_txpower(sc, i, power);
4468	}
4469}
4470
4471static void
4472urtwn_set_rx_bssid_all(struct urtwn_softc *sc, int enable)
4473{
4474	uint32_t reg;
4475
4476	reg = urtwn_read_4(sc, R92C_RCR);
4477	if (enable)
4478		reg &= ~R92C_RCR_CBSSID_BCN;
4479	else
4480		reg |= R92C_RCR_CBSSID_BCN;
4481	urtwn_write_4(sc, R92C_RCR, reg);
4482}
4483
4484static void
4485urtwn_set_gain(struct urtwn_softc *sc, uint8_t gain)
4486{
4487	uint32_t reg;
4488
4489	reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0));
4490	reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, gain);
4491	urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg);
4492
4493	if (!(sc->chip & URTWN_CHIP_88E)) {
4494		reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
4495		reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, gain);
4496		urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
4497	}
4498}
4499
4500static void
4501urtwn_scan_start(struct ieee80211com *ic)
4502{
4503	struct urtwn_softc *sc = ic->ic_softc;
4504
4505	URTWN_LOCK(sc);
4506	/* Receive beacons / probe responses from any BSSID. */
4507	if (ic->ic_opmode != IEEE80211_M_IBSS)
4508		urtwn_set_rx_bssid_all(sc, 1);
4509
4510	/* Set gain for scanning. */
4511	urtwn_set_gain(sc, 0x20);
4512	URTWN_UNLOCK(sc);
4513}
4514
4515static void
4516urtwn_scan_end(struct ieee80211com *ic)
4517{
4518	struct urtwn_softc *sc = ic->ic_softc;
4519
4520	URTWN_LOCK(sc);
4521	/* Restore limitations. */
4522	if (ic->ic_promisc == 0 && ic->ic_opmode != IEEE80211_M_IBSS)
4523		urtwn_set_rx_bssid_all(sc, 0);
4524
4525	/* Set gain under link. */
4526	urtwn_set_gain(sc, 0x32);
4527	URTWN_UNLOCK(sc);
4528}
4529
4530static void
4531urtwn_set_channel(struct ieee80211com *ic)
4532{
4533	struct urtwn_softc *sc = ic->ic_softc;
4534	struct ieee80211_channel *c = ic->ic_curchan;
4535	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
4536
4537	URTWN_LOCK(sc);
4538	if (vap->iv_state == IEEE80211_S_SCAN) {
4539		/* Make link LED blink during scan. */
4540		urtwn_set_led(sc, URTWN_LED_LINK, !sc->ledlink);
4541	}
4542	urtwn_set_chan(sc, c, NULL);
4543	sc->sc_rxtap.wr_chan_freq = htole16(c->ic_freq);
4544	sc->sc_rxtap.wr_chan_flags = htole16(c->ic_flags);
4545	sc->sc_txtap.wt_chan_freq = htole16(c->ic_freq);
4546	sc->sc_txtap.wt_chan_flags = htole16(c->ic_flags);
4547	URTWN_UNLOCK(sc);
4548}
4549
4550static int
4551urtwn_wme_update(struct ieee80211com *ic)
4552{
4553	const struct wmeParams *wmep =
4554	    ic->ic_wme.wme_chanParams.cap_wmeParams;
4555	struct urtwn_softc *sc = ic->ic_softc;
4556	uint8_t aifs, acm, slottime;
4557	int ac;
4558
4559	acm = 0;
4560	slottime = IEEE80211_GET_SLOTTIME(ic);
4561
4562	URTWN_LOCK(sc);
4563	for (ac = WME_AC_BE; ac < WME_NUM_AC; ac++) {
4564		/* AIFS[AC] = AIFSN[AC] * aSlotTime + aSIFSTime. */
4565		aifs = wmep[ac].wmep_aifsn * slottime + IEEE80211_DUR_SIFS;
4566		urtwn_write_4(sc, wme2queue[ac].reg,
4567		    SM(R92C_EDCA_PARAM_TXOP, wmep[ac].wmep_txopLimit) |
4568		    SM(R92C_EDCA_PARAM_ECWMIN, wmep[ac].wmep_logcwmin) |
4569		    SM(R92C_EDCA_PARAM_ECWMAX, wmep[ac].wmep_logcwmax) |
4570		    SM(R92C_EDCA_PARAM_AIFS, aifs));
4571		if (ac != WME_AC_BE)
4572			acm |= wmep[ac].wmep_acm << ac;
4573	}
4574
4575	if (acm != 0)
4576		acm |= R92C_ACMHWCTRL_EN;
4577	urtwn_write_1(sc, R92C_ACMHWCTRL,
4578	    (urtwn_read_1(sc, R92C_ACMHWCTRL) & ~R92C_ACMHWCTRL_ACM_MASK) |
4579	    acm);
4580
4581	URTWN_UNLOCK(sc);
4582
4583	return 0;
4584}
4585
4586static void
4587urtwn_update_slot(struct ieee80211com *ic)
4588{
4589	urtwn_cmd_sleepable(ic->ic_softc, NULL, 0, urtwn_update_slot_cb);
4590}
4591
4592static void
4593urtwn_update_slot_cb(struct urtwn_softc *sc, union sec_param *data)
4594{
4595	struct ieee80211com *ic = &sc->sc_ic;
4596	uint8_t slottime;
4597
4598	slottime = IEEE80211_GET_SLOTTIME(ic);
4599
4600	URTWN_DPRINTF(sc, URTWN_DEBUG_ANY, "%s: setting slot time to %uus\n",
4601	    __func__, slottime);
4602
4603	urtwn_write_1(sc, R92C_SLOT, slottime);
4604	urtwn_update_aifs(sc, slottime);
4605}
4606
4607static void
4608urtwn_update_aifs(struct urtwn_softc *sc, uint8_t slottime)
4609{
4610	const struct wmeParams *wmep =
4611	    sc->sc_ic.ic_wme.wme_chanParams.cap_wmeParams;
4612	uint8_t aifs, ac;
4613
4614	for (ac = WME_AC_BE; ac < WME_NUM_AC; ac++) {
4615		/* AIFS[AC] = AIFSN[AC] * aSlotTime + aSIFSTime. */
4616		aifs = wmep[ac].wmep_aifsn * slottime + IEEE80211_DUR_SIFS;
4617		urtwn_write_1(sc, wme2queue[ac].reg, aifs);
4618        }
4619}
4620
4621static void
4622urtwn_set_promisc(struct urtwn_softc *sc)
4623{
4624	struct ieee80211com *ic = &sc->sc_ic;
4625	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
4626	uint32_t rcr, mask1, mask2;
4627
4628	URTWN_ASSERT_LOCKED(sc);
4629
4630	if (vap->iv_opmode == IEEE80211_M_MONITOR)
4631		return;
4632
4633	mask1 = R92C_RCR_ACF | R92C_RCR_ADF | R92C_RCR_AMF | R92C_RCR_AAP;
4634	mask2 = R92C_RCR_APM;
4635
4636	if (vap->iv_state == IEEE80211_S_RUN) {
4637		switch (vap->iv_opmode) {
4638		case IEEE80211_M_STA:
4639			mask2 |= R92C_RCR_CBSSID_DATA;
4640			/* FALLTHROUGH */
4641		case IEEE80211_M_HOSTAP:
4642			mask2 |= R92C_RCR_CBSSID_BCN;
4643			break;
4644		case IEEE80211_M_IBSS:
4645			mask2 |= R92C_RCR_CBSSID_DATA;
4646			break;
4647		default:
4648			device_printf(sc->sc_dev, "%s: undefined opmode %d\n",
4649			    __func__, vap->iv_opmode);
4650			return;
4651		}
4652	}
4653
4654	rcr = urtwn_read_4(sc, R92C_RCR);
4655	if (ic->ic_promisc == 0)
4656		rcr = (rcr & ~mask1) | mask2;
4657	else
4658		rcr = (rcr & ~mask2) | mask1;
4659	urtwn_write_4(sc, R92C_RCR, rcr);
4660}
4661
4662static void
4663urtwn_update_promisc(struct ieee80211com *ic)
4664{
4665	struct urtwn_softc *sc = ic->ic_softc;
4666
4667	URTWN_LOCK(sc);
4668	if (sc->sc_flags & URTWN_RUNNING)
4669		urtwn_set_promisc(sc);
4670	URTWN_UNLOCK(sc);
4671}
4672
4673static void
4674urtwn_update_mcast(struct ieee80211com *ic)
4675{
4676	/* XXX do nothing?  */
4677}
4678
4679static struct ieee80211_node *
4680urtwn_r88e_node_alloc(struct ieee80211vap *vap,
4681    const uint8_t mac[IEEE80211_ADDR_LEN])
4682{
4683	struct urtwn_node *un;
4684
4685	un = malloc(sizeof (struct urtwn_node), M_80211_NODE,
4686	    M_NOWAIT | M_ZERO);
4687
4688	if (un == NULL)
4689		return NULL;
4690
4691	un->id = URTWN_MACID_UNDEFINED;
4692
4693	return &un->ni;
4694}
4695
4696static void
4697urtwn_r88e_newassoc(struct ieee80211_node *ni, int isnew)
4698{
4699	struct urtwn_softc *sc = ni->ni_ic->ic_softc;
4700	struct urtwn_node *un = URTWN_NODE(ni);
4701	uint8_t id;
4702
4703	if (!isnew)
4704		return;
4705
4706	URTWN_NT_LOCK(sc);
4707	for (id = 0; id <= URTWN_MACID_MAX(sc); id++) {
4708		if (id != URTWN_MACID_BC && sc->node_list[id] == NULL) {
4709			un->id = id;
4710			sc->node_list[id] = ni;
4711			break;
4712		}
4713	}
4714	URTWN_NT_UNLOCK(sc);
4715
4716	if (id > URTWN_MACID_MAX(sc)) {
4717		device_printf(sc->sc_dev, "%s: node table is full\n",
4718		    __func__);
4719	}
4720}
4721
4722static void
4723urtwn_r88e_node_free(struct ieee80211_node *ni)
4724{
4725	struct urtwn_softc *sc = ni->ni_ic->ic_softc;
4726	struct urtwn_node *un = URTWN_NODE(ni);
4727
4728	URTWN_NT_LOCK(sc);
4729	if (un->id != URTWN_MACID_UNDEFINED)
4730		sc->node_list[un->id] = NULL;
4731	URTWN_NT_UNLOCK(sc);
4732
4733	sc->sc_node_free(ni);
4734}
4735
4736static void
4737urtwn_set_chan(struct urtwn_softc *sc, struct ieee80211_channel *c,
4738    struct ieee80211_channel *extc)
4739{
4740	struct ieee80211com *ic = &sc->sc_ic;
4741	uint32_t reg;
4742	u_int chan;
4743	int i;
4744
4745	chan = ieee80211_chan2ieee(ic, c);	/* XXX center freq! */
4746	if (chan == 0 || chan == IEEE80211_CHAN_ANY) {
4747		device_printf(sc->sc_dev,
4748		    "%s: invalid channel %x\n", __func__, chan);
4749		return;
4750	}
4751
4752	/* Set Tx power for this new channel. */
4753	urtwn_set_txpower(sc, c, extc);
4754
4755	for (i = 0; i < sc->nrxchains; i++) {
4756		urtwn_rf_write(sc, i, R92C_RF_CHNLBW,
4757		    RW(sc->rf_chnlbw[i], R92C_RF_CHNLBW_CHNL, chan));
4758	}
4759#ifndef IEEE80211_NO_HT
4760	if (extc != NULL) {
4761		/* Is secondary channel below or above primary? */
4762		int prichlo = c->ic_freq < extc->ic_freq;
4763
4764		urtwn_write_1(sc, R92C_BWOPMODE,
4765		    urtwn_read_1(sc, R92C_BWOPMODE) & ~R92C_BWOPMODE_20MHZ);
4766
4767		reg = urtwn_read_1(sc, R92C_RRSR + 2);
4768		reg = (reg & ~0x6f) | (prichlo ? 1 : 2) << 5;
4769		urtwn_write_1(sc, R92C_RRSR + 2, reg);
4770
4771		urtwn_bb_write(sc, R92C_FPGA0_RFMOD,
4772		    urtwn_bb_read(sc, R92C_FPGA0_RFMOD) | R92C_RFMOD_40MHZ);
4773		urtwn_bb_write(sc, R92C_FPGA1_RFMOD,
4774		    urtwn_bb_read(sc, R92C_FPGA1_RFMOD) | R92C_RFMOD_40MHZ);
4775
4776		/* Set CCK side band. */
4777		reg = urtwn_bb_read(sc, R92C_CCK0_SYSTEM);
4778		reg = (reg & ~0x00000010) | (prichlo ? 0 : 1) << 4;
4779		urtwn_bb_write(sc, R92C_CCK0_SYSTEM, reg);
4780
4781		reg = urtwn_bb_read(sc, R92C_OFDM1_LSTF);
4782		reg = (reg & ~0x00000c00) | (prichlo ? 1 : 2) << 10;
4783		urtwn_bb_write(sc, R92C_OFDM1_LSTF, reg);
4784
4785		urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2,
4786		    urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) &
4787		    ~R92C_FPGA0_ANAPARAM2_CBW20);
4788
4789		reg = urtwn_bb_read(sc, 0x818);
4790		reg = (reg & ~0x0c000000) | (prichlo ? 2 : 1) << 26;
4791		urtwn_bb_write(sc, 0x818, reg);
4792
4793		/* Select 40MHz bandwidth. */
4794		urtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
4795		    (sc->rf_chnlbw[0] & ~0xfff) | chan);
4796	} else
4797#endif
4798	{
4799		urtwn_write_1(sc, R92C_BWOPMODE,
4800		    urtwn_read_1(sc, R92C_BWOPMODE) | R92C_BWOPMODE_20MHZ);
4801
4802		urtwn_bb_write(sc, R92C_FPGA0_RFMOD,
4803		    urtwn_bb_read(sc, R92C_FPGA0_RFMOD) & ~R92C_RFMOD_40MHZ);
4804		urtwn_bb_write(sc, R92C_FPGA1_RFMOD,
4805		    urtwn_bb_read(sc, R92C_FPGA1_RFMOD) & ~R92C_RFMOD_40MHZ);
4806
4807		if (!(sc->chip & URTWN_CHIP_88E)) {
4808			urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2,
4809			    urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) |
4810			    R92C_FPGA0_ANAPARAM2_CBW20);
4811		}
4812
4813		/* Select 20MHz bandwidth. */
4814		urtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
4815		    (sc->rf_chnlbw[0] & ~0xfff) | chan |
4816		    ((sc->chip & URTWN_CHIP_88E) ? R88E_RF_CHNLBW_BW20 :
4817		    R92C_RF_CHNLBW_BW20));
4818	}
4819}
4820
4821static void
4822urtwn_iq_calib(struct urtwn_softc *sc)
4823{
4824	/* TODO */
4825}
4826
4827static void
4828urtwn_lc_calib(struct urtwn_softc *sc)
4829{
4830	uint32_t rf_ac[2];
4831	uint8_t txmode;
4832	int i;
4833
4834	txmode = urtwn_read_1(sc, R92C_OFDM1_LSTF + 3);
4835	if ((txmode & 0x70) != 0) {
4836		/* Disable all continuous Tx. */
4837		urtwn_write_1(sc, R92C_OFDM1_LSTF + 3, txmode & ~0x70);
4838
4839		/* Set RF mode to standby mode. */
4840		for (i = 0; i < sc->nrxchains; i++) {
4841			rf_ac[i] = urtwn_rf_read(sc, i, R92C_RF_AC);
4842			urtwn_rf_write(sc, i, R92C_RF_AC,
4843			    RW(rf_ac[i], R92C_RF_AC_MODE,
4844				R92C_RF_AC_MODE_STANDBY));
4845		}
4846	} else {
4847		/* Block all Tx queues. */
4848		urtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
4849	}
4850	/* Start calibration. */
4851	urtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
4852	    urtwn_rf_read(sc, 0, R92C_RF_CHNLBW) | R92C_RF_CHNLBW_LCSTART);
4853
4854	/* Give calibration the time to complete. */
4855	usb_pause_mtx(&sc->sc_mtx, hz / 10);		/* 100ms */
4856
4857	/* Restore configuration. */
4858	if ((txmode & 0x70) != 0) {
4859		/* Restore Tx mode. */
4860		urtwn_write_1(sc, R92C_OFDM1_LSTF + 3, txmode);
4861		/* Restore RF mode. */
4862		for (i = 0; i < sc->nrxchains; i++)
4863			urtwn_rf_write(sc, i, R92C_RF_AC, rf_ac[i]);
4864	} else {
4865		/* Unblock all Tx queues. */
4866		urtwn_write_1(sc, R92C_TXPAUSE, 0x00);
4867	}
4868}
4869
4870static void
4871urtwn_temp_calib(struct urtwn_softc *sc)
4872{
4873	uint8_t temp;
4874
4875	URTWN_ASSERT_LOCKED(sc);
4876
4877	if (!(sc->sc_flags & URTWN_TEMP_MEASURED)) {
4878		/* Start measuring temperature. */
4879		URTWN_DPRINTF(sc, URTWN_DEBUG_TEMP,
4880		    "%s: start measuring temperature\n", __func__);
4881		if (sc->chip & URTWN_CHIP_88E) {
4882			urtwn_rf_write(sc, 0, R88E_RF_T_METER,
4883			    R88E_RF_T_METER_START);
4884		} else {
4885			urtwn_rf_write(sc, 0, R92C_RF_T_METER,
4886			    R92C_RF_T_METER_START);
4887		}
4888		sc->sc_flags |= URTWN_TEMP_MEASURED;
4889		return;
4890	}
4891	sc->sc_flags &= ~URTWN_TEMP_MEASURED;
4892
4893	/* Read measured temperature. */
4894	if (sc->chip & URTWN_CHIP_88E) {
4895		temp = MS(urtwn_rf_read(sc, 0, R88E_RF_T_METER),
4896		    R88E_RF_T_METER_VAL);
4897	} else {
4898		temp = MS(urtwn_rf_read(sc, 0, R92C_RF_T_METER),
4899		    R92C_RF_T_METER_VAL);
4900	}
4901	if (temp == 0) {	/* Read failed, skip. */
4902		URTWN_DPRINTF(sc, URTWN_DEBUG_TEMP,
4903		    "%s: temperature read failed, skipping\n", __func__);
4904		return;
4905	}
4906
4907	URTWN_DPRINTF(sc, URTWN_DEBUG_TEMP,
4908	    "%s: temperature: previous %u, current %u\n",
4909	    __func__, sc->thcal_lctemp, temp);
4910
4911	/*
4912	 * Redo LC calibration if temperature changed significantly since
4913	 * last calibration.
4914	 */
4915	if (sc->thcal_lctemp == 0) {
4916		/* First LC calibration is performed in urtwn_init(). */
4917		sc->thcal_lctemp = temp;
4918	} else if (abs(temp - sc->thcal_lctemp) > 1) {
4919		URTWN_DPRINTF(sc, URTWN_DEBUG_TEMP,
4920		    "%s: LC calib triggered by temp: %u -> %u\n",
4921		    __func__, sc->thcal_lctemp, temp);
4922		urtwn_lc_calib(sc);
4923		/* Record temperature of last LC calibration. */
4924		sc->thcal_lctemp = temp;
4925	}
4926}
4927
4928static int
4929urtwn_init(struct urtwn_softc *sc)
4930{
4931	struct ieee80211com *ic = &sc->sc_ic;
4932	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
4933	uint8_t macaddr[IEEE80211_ADDR_LEN];
4934	uint32_t reg;
4935	usb_error_t usb_err = USB_ERR_NORMAL_COMPLETION;
4936	int error;
4937
4938	URTWN_LOCK(sc);
4939	if (sc->sc_flags & URTWN_RUNNING) {
4940		URTWN_UNLOCK(sc);
4941		return (0);
4942	}
4943
4944	/* Init firmware commands ring. */
4945	sc->fwcur = 0;
4946
4947	/* Allocate Tx/Rx buffers. */
4948	error = urtwn_alloc_rx_list(sc);
4949	if (error != 0)
4950		goto fail;
4951
4952	error = urtwn_alloc_tx_list(sc);
4953	if (error != 0)
4954		goto fail;
4955
4956	/* Power on adapter. */
4957	error = urtwn_power_on(sc);
4958	if (error != 0)
4959		goto fail;
4960
4961	/* Initialize DMA. */
4962	error = urtwn_dma_init(sc);
4963	if (error != 0)
4964		goto fail;
4965
4966	/* Set info size in Rx descriptors (in 64-bit words). */
4967	urtwn_write_1(sc, R92C_RX_DRVINFO_SZ, 4);
4968
4969	/* Init interrupts. */
4970	if (sc->chip & URTWN_CHIP_88E) {
4971		usb_err = urtwn_write_4(sc, R88E_HISR, 0xffffffff);
4972		if (usb_err != USB_ERR_NORMAL_COMPLETION)
4973			goto fail;
4974		usb_err = urtwn_write_4(sc, R88E_HIMR, R88E_HIMR_CPWM | R88E_HIMR_CPWM2 |
4975		    R88E_HIMR_TBDER | R88E_HIMR_PSTIMEOUT);
4976		if (usb_err != USB_ERR_NORMAL_COMPLETION)
4977			goto fail;
4978		usb_err = urtwn_write_4(sc, R88E_HIMRE, R88E_HIMRE_RXFOVW |
4979		    R88E_HIMRE_TXFOVW | R88E_HIMRE_RXERR | R88E_HIMRE_TXERR);
4980		if (usb_err != USB_ERR_NORMAL_COMPLETION)
4981			goto fail;
4982		usb_err = urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION,
4983		    urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) |
4984		    R92C_USB_SPECIAL_OPTION_INT_BULK_SEL);
4985		if (usb_err != USB_ERR_NORMAL_COMPLETION)
4986			goto fail;
4987	} else {
4988		usb_err = urtwn_write_4(sc, R92C_HISR, 0xffffffff);
4989		if (usb_err != USB_ERR_NORMAL_COMPLETION)
4990			goto fail;
4991		usb_err = urtwn_write_4(sc, R92C_HIMR, 0xffffffff);
4992		if (usb_err != USB_ERR_NORMAL_COMPLETION)
4993			goto fail;
4994	}
4995
4996	/* Set MAC address. */
4997	IEEE80211_ADDR_COPY(macaddr, vap ? vap->iv_myaddr : ic->ic_macaddr);
4998	usb_err = urtwn_write_region_1(sc, R92C_MACID, macaddr, IEEE80211_ADDR_LEN);
4999	if (usb_err != USB_ERR_NORMAL_COMPLETION)
5000		goto fail;
5001
5002	/* Set initial network type. */
5003	urtwn_set_mode(sc, R92C_MSR_INFRA);
5004
5005	/* Initialize Rx filter. */
5006	urtwn_rxfilter_init(sc);
5007
5008	/* Set response rate. */
5009	reg = urtwn_read_4(sc, R92C_RRSR);
5010	reg = RW(reg, R92C_RRSR_RATE_BITMAP, R92C_RRSR_RATE_CCK_ONLY_1M);
5011	urtwn_write_4(sc, R92C_RRSR, reg);
5012
5013	/* Set short/long retry limits. */
5014	urtwn_write_2(sc, R92C_RL,
5015	    SM(R92C_RL_SRL, 0x30) | SM(R92C_RL_LRL, 0x30));
5016
5017	/* Initialize EDCA parameters. */
5018	urtwn_edca_init(sc);
5019
5020	/* Setup rate fallback. */
5021	if (!(sc->chip & URTWN_CHIP_88E)) {
5022		urtwn_write_4(sc, R92C_DARFRC + 0, 0x00000000);
5023		urtwn_write_4(sc, R92C_DARFRC + 4, 0x10080404);
5024		urtwn_write_4(sc, R92C_RARFRC + 0, 0x04030201);
5025		urtwn_write_4(sc, R92C_RARFRC + 4, 0x08070605);
5026	}
5027
5028	urtwn_write_1(sc, R92C_FWHW_TXQ_CTRL,
5029	    urtwn_read_1(sc, R92C_FWHW_TXQ_CTRL) |
5030	    R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW);
5031	/* Set ACK timeout. */
5032	urtwn_write_1(sc, R92C_ACKTO, 0x40);
5033
5034	/* Setup USB aggregation. */
5035	reg = urtwn_read_4(sc, R92C_TDECTRL);
5036	reg = RW(reg, R92C_TDECTRL_BLK_DESC_NUM, 6);
5037	urtwn_write_4(sc, R92C_TDECTRL, reg);
5038	urtwn_write_1(sc, R92C_TRXDMA_CTRL,
5039	    urtwn_read_1(sc, R92C_TRXDMA_CTRL) |
5040	    R92C_TRXDMA_CTRL_RXDMA_AGG_EN);
5041	urtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48);
5042	if (sc->chip & URTWN_CHIP_88E)
5043		urtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH + 1, 4);
5044	else {
5045		urtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4);
5046		urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION,
5047		    urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) |
5048		    R92C_USB_SPECIAL_OPTION_AGG_EN);
5049		urtwn_write_1(sc, R92C_USB_AGG_TH, 8);
5050		urtwn_write_1(sc, R92C_USB_AGG_TO, 6);
5051	}
5052
5053	/* Initialize beacon parameters. */
5054	urtwn_write_2(sc, R92C_BCN_CTRL, 0x1010);
5055	urtwn_write_2(sc, R92C_TBTT_PROHIBIT, 0x6404);
5056	urtwn_write_1(sc, R92C_DRVERLYINT, 0x05);
5057	urtwn_write_1(sc, R92C_BCNDMATIM, 0x02);
5058	urtwn_write_2(sc, R92C_BCNTCFG, 0x660f);
5059
5060	if (!(sc->chip & URTWN_CHIP_88E)) {
5061		/* Setup AMPDU aggregation. */
5062		urtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631);	/* MCS7~0 */
5063		urtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16);
5064		urtwn_write_2(sc, R92C_MAX_AGGR_NUM, 0x0708);
5065
5066		urtwn_write_1(sc, R92C_BCN_MAX_ERR, 0xff);
5067	}
5068
5069#ifndef URTWN_WITHOUT_UCODE
5070	/* Load 8051 microcode. */
5071	error = urtwn_load_firmware(sc);
5072	if (error == 0)
5073		sc->sc_flags |= URTWN_FW_LOADED;
5074#endif
5075
5076	/* Initialize MAC/BB/RF blocks. */
5077	error = urtwn_mac_init(sc);
5078	if (error != 0) {
5079		device_printf(sc->sc_dev,
5080		    "%s: error while initializing MAC block\n", __func__);
5081		goto fail;
5082	}
5083	urtwn_bb_init(sc);
5084	urtwn_rf_init(sc);
5085
5086	/* Reinitialize Rx filter (D3845 is not committed yet). */
5087	urtwn_rxfilter_init(sc);
5088
5089	if (sc->chip & URTWN_CHIP_88E) {
5090		urtwn_write_2(sc, R92C_CR,
5091		    urtwn_read_2(sc, R92C_CR) | R92C_CR_MACTXEN |
5092		    R92C_CR_MACRXEN);
5093	}
5094
5095	/* Turn CCK and OFDM blocks on. */
5096	reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD);
5097	reg |= R92C_RFMOD_CCK_EN;
5098	usb_err = urtwn_bb_write(sc, R92C_FPGA0_RFMOD, reg);
5099	if (usb_err != USB_ERR_NORMAL_COMPLETION)
5100		goto fail;
5101	reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD);
5102	reg |= R92C_RFMOD_OFDM_EN;
5103	usb_err = urtwn_bb_write(sc, R92C_FPGA0_RFMOD, reg);
5104	if (usb_err != USB_ERR_NORMAL_COMPLETION)
5105		goto fail;
5106
5107	/* Clear per-station keys table. */
5108	urtwn_cam_init(sc);
5109
5110	/* Enable decryption / encryption. */
5111	urtwn_write_2(sc, R92C_SECCFG,
5112	    R92C_SECCFG_TXUCKEY_DEF | R92C_SECCFG_RXUCKEY_DEF |
5113	    R92C_SECCFG_TXENC_ENA | R92C_SECCFG_RXDEC_ENA |
5114	    R92C_SECCFG_TXBCKEY_DEF | R92C_SECCFG_RXBCKEY_DEF);
5115
5116	/*
5117	 * Install static keys (if any).
5118	 * Must be called after urtwn_cam_init().
5119	 */
5120	ieee80211_runtask(ic, &sc->cmdq_task);
5121
5122	/* Enable hardware sequence numbering. */
5123	urtwn_write_1(sc, R92C_HWSEQ_CTRL, R92C_TX_QUEUE_ALL);
5124
5125	/* Enable per-packet TX report. */
5126	if (sc->chip & URTWN_CHIP_88E) {
5127		urtwn_write_1(sc, R88E_TX_RPT_CTRL,
5128		    urtwn_read_1(sc, R88E_TX_RPT_CTRL) | R88E_TX_RPT1_ENA);
5129	}
5130
5131	/* Perform LO and IQ calibrations. */
5132	urtwn_iq_calib(sc);
5133	/* Perform LC calibration. */
5134	urtwn_lc_calib(sc);
5135
5136	/* Fix USB interference issue. */
5137	if (!(sc->chip & URTWN_CHIP_88E)) {
5138		urtwn_write_1(sc, 0xfe40, 0xe0);
5139		urtwn_write_1(sc, 0xfe41, 0x8d);
5140		urtwn_write_1(sc, 0xfe42, 0x80);
5141
5142		urtwn_pa_bias_init(sc);
5143	}
5144
5145	/* Initialize GPIO setting. */
5146	urtwn_write_1(sc, R92C_GPIO_MUXCFG,
5147	    urtwn_read_1(sc, R92C_GPIO_MUXCFG) & ~R92C_GPIO_MUXCFG_ENBT);
5148
5149	/* Fix for lower temperature. */
5150	if (!(sc->chip & URTWN_CHIP_88E))
5151		urtwn_write_1(sc, 0x15, 0xe9);
5152
5153	usbd_transfer_start(sc->sc_xfer[URTWN_BULK_RX]);
5154
5155	sc->sc_flags |= URTWN_RUNNING;
5156
5157	callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc);
5158fail:
5159	if (usb_err != USB_ERR_NORMAL_COMPLETION)
5160		error = EIO;
5161
5162	URTWN_UNLOCK(sc);
5163
5164	return (error);
5165}
5166
5167static void
5168urtwn_stop(struct urtwn_softc *sc)
5169{
5170
5171	URTWN_LOCK(sc);
5172	if (!(sc->sc_flags & URTWN_RUNNING)) {
5173		URTWN_UNLOCK(sc);
5174		return;
5175	}
5176
5177	sc->sc_flags &= ~(URTWN_RUNNING | URTWN_FW_LOADED |
5178	    URTWN_TEMP_MEASURED);
5179	sc->thcal_lctemp = 0;
5180	callout_stop(&sc->sc_watchdog_ch);
5181
5182	urtwn_abort_xfers(sc);
5183	urtwn_drain_mbufq(sc);
5184	urtwn_power_off(sc);
5185	URTWN_UNLOCK(sc);
5186}
5187
5188static void
5189urtwn_abort_xfers(struct urtwn_softc *sc)
5190{
5191	int i;
5192
5193	URTWN_ASSERT_LOCKED(sc);
5194
5195	/* abort any pending transfers */
5196	for (i = 0; i < URTWN_N_TRANSFER; i++)
5197		usbd_transfer_stop(sc->sc_xfer[i]);
5198}
5199
5200static int
5201urtwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
5202    const struct ieee80211_bpf_params *params)
5203{
5204	struct ieee80211com *ic = ni->ni_ic;
5205	struct urtwn_softc *sc = ic->ic_softc;
5206	struct urtwn_data *bf;
5207	int error;
5208
5209	/* prevent management frames from being sent if we're not ready */
5210	URTWN_LOCK(sc);
5211	if (!(sc->sc_flags & URTWN_RUNNING)) {
5212		error = ENETDOWN;
5213		goto end;
5214	}
5215
5216	bf = urtwn_getbuf(sc);
5217	if (bf == NULL) {
5218		error = ENOBUFS;
5219		goto end;
5220	}
5221
5222	if (params == NULL) {
5223		/*
5224		 * Legacy path; interpret frame contents to decide
5225		 * precisely how to send the frame.
5226		 */
5227		error = urtwn_tx_data(sc, ni, m, bf);
5228	} else {
5229		/*
5230		 * Caller supplied explicit parameters to use in
5231		 * sending the frame.
5232		 */
5233		error = urtwn_tx_raw(sc, ni, m, bf, params);
5234	}
5235	if (error != 0) {
5236		STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
5237		goto end;
5238	}
5239
5240	sc->sc_txtimer = 5;
5241	callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc);
5242
5243end:
5244	if (error != 0)
5245		m_freem(m);
5246
5247	URTWN_UNLOCK(sc);
5248
5249	return (error);
5250}
5251
5252static void
5253urtwn_ms_delay(struct urtwn_softc *sc)
5254{
5255	usb_pause_mtx(&sc->sc_mtx, hz / 1000);
5256}
5257
5258static device_method_t urtwn_methods[] = {
5259	/* Device interface */
5260	DEVMETHOD(device_probe,		urtwn_match),
5261	DEVMETHOD(device_attach,	urtwn_attach),
5262	DEVMETHOD(device_detach,	urtwn_detach),
5263
5264	DEVMETHOD_END
5265};
5266
5267static driver_t urtwn_driver = {
5268	"urtwn",
5269	urtwn_methods,
5270	sizeof(struct urtwn_softc)
5271};
5272
5273static devclass_t urtwn_devclass;
5274
5275DRIVER_MODULE(urtwn, uhub, urtwn_driver, urtwn_devclass, NULL, NULL);
5276MODULE_DEPEND(urtwn, usb, 1, 1, 1);
5277MODULE_DEPEND(urtwn, wlan, 1, 1, 1);
5278#ifndef URTWN_WITHOUT_UCODE
5279MODULE_DEPEND(urtwn, firmware, 1, 1, 1);
5280#endif
5281MODULE_VERSION(urtwn, 1);
5282USB_PNP_HOST_INFO(urtwn_devs);
5283