Home | History | Annotate | Line # | Download | only in usb
if_urtw.c revision 1.15.2.2
      1  1.15.2.2    martin /*	$NetBSD: if_urtw.c,v 1.15.2.2 2020/04/08 14:08:13 martin Exp $	*/
      2       1.1  christos /*	$OpenBSD: if_urtw.c,v 1.39 2011/07/03 15:47:17 matthew Exp $	*/
      3       1.1  christos 
      4       1.1  christos /*-
      5       1.1  christos  * Copyright (c) 2009 Martynas Venckus <martynas (at) openbsd.org>
      6       1.1  christos  * Copyright (c) 2008 Weongyo Jeong <weongyo (at) FreeBSD.org>
      7       1.1  christos  *
      8       1.1  christos  * Permission to use, copy, modify, and distribute this software for any
      9       1.1  christos  * purpose with or without fee is hereby granted, provided that the above
     10       1.1  christos  * copyright notice and this permission notice appear in all copies.
     11       1.1  christos  *
     12       1.1  christos  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     13       1.1  christos  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     14       1.1  christos  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     15       1.1  christos  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     16       1.1  christos  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     17       1.1  christos  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     18       1.1  christos  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     19       1.1  christos  */
     20       1.1  christos 
     21       1.1  christos #include <sys/cdefs.h>
     22  1.15.2.2    martin __KERNEL_RCSID(0, "$NetBSD: if_urtw.c,v 1.15.2.2 2020/04/08 14:08:13 martin Exp $");
     23      1.12     skrll 
     24      1.12     skrll #ifdef _KERNEL_OPT
     25      1.12     skrll #include "opt_usb.h"
     26      1.12     skrll #endif
     27       1.1  christos 
     28       1.1  christos #include <sys/param.h>
     29       1.1  christos #include <sys/sockio.h>
     30       1.1  christos #include <sys/proc.h>
     31       1.1  christos #include <sys/mbuf.h>
     32       1.1  christos #include <sys/kernel.h>
     33       1.1  christos #include <sys/socket.h>
     34       1.1  christos #include <sys/systm.h>
     35       1.1  christos #include <sys/callout.h>
     36       1.1  christos #include <sys/conf.h>
     37       1.1  christos #include <sys/device.h>
     38       1.1  christos #include <sys/module.h>
     39       1.1  christos #include <sys/bus.h>
     40       1.1  christos 
     41       1.1  christos #include <machine/endian.h>
     42       1.1  christos #include <net/bpf.h>
     43       1.1  christos #include <net/if.h>
     44       1.1  christos #include <net/if_arp.h>
     45       1.1  christos #include <net/if_dl.h>
     46       1.1  christos #include <net/if_ether.h>
     47       1.1  christos #include <net/if_media.h>
     48       1.1  christos #include <net/if_types.h>
     49       1.1  christos 
     50       1.1  christos #include <netinet/in.h>
     51       1.1  christos #include <netinet/in_systm.h>
     52       1.1  christos #include <netinet/in_var.h>
     53       1.1  christos #include <netinet/if_inarp.h>
     54       1.1  christos #include <netinet/ip.h>
     55       1.1  christos 
     56       1.1  christos #include <net80211/ieee80211_var.h>
     57       1.1  christos #include <net80211/ieee80211_radiotap.h>
     58       1.1  christos 
     59       1.1  christos #include <dev/usb/usb.h>
     60       1.1  christos #include <dev/usb/usbdi.h>
     61       1.1  christos #include <dev/usb/usbdi_util.h>
     62       1.1  christos #include <dev/usb/usbdivar.h>
     63       1.1  christos #include <dev/usb/usbdevs.h>
     64       1.1  christos 
     65       1.1  christos #include "if_urtwreg.h"
     66       1.1  christos 
     67       1.1  christos #ifdef URTW_DEBUG
     68       1.1  christos #define	DPRINTF(x)	do { if (urtw_debug) printf x; } while (0)
     69       1.1  christos #define	DPRINTFN(n, x)	do { if (urtw_debug >= (n)) printf x; } while (0)
     70       1.1  christos int urtw_debug = 0;
     71       1.1  christos #else
     72       1.1  christos #define	DPRINTF(x)
     73       1.1  christos #define	DPRINTFN(n, x)
     74       1.1  christos #endif
     75       1.1  christos 
     76       1.1  christos /*
     77       1.1  christos  * Recognized device vendors/products.
     78       1.1  christos  */
     79       1.1  christos static const struct urtw_type {
     80       1.1  christos 	struct usb_devno	dev;
     81       1.1  christos 	uint8_t			rev;
     82       1.1  christos } urtw_devs[] = {
     83       1.1  christos #define	URTW_DEV_RTL8187(v, p)	\
     84       1.1  christos 	    { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, URTW_HWREV_8187 }
     85       1.1  christos #define	URTW_DEV_RTL8187B(v, p)	\
     86       1.1  christos 	    { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, URTW_HWREV_8187B }
     87       1.1  christos 	/* Realtek RTL8187 devices. */
     88       1.1  christos 	URTW_DEV_RTL8187(ASUSTEK,	P5B_WIFI),
     89       1.1  christos 	URTW_DEV_RTL8187(DICKSMITH,	RTL8187),
     90       1.1  christos 	URTW_DEV_RTL8187(LINKSYS4,	WUSB54GC_2),
     91       1.1  christos 	URTW_DEV_RTL8187(LOGITEC,	RTL8187),
     92       1.1  christos 	URTW_DEV_RTL8187(NETGEAR,	WG111V2),
     93       1.1  christos 	URTW_DEV_RTL8187(REALTEK,	RTL8187),
     94       1.1  christos 	URTW_DEV_RTL8187(SITECOMEU,	WL168V1),
     95       1.1  christos 	URTW_DEV_RTL8187(SPHAIRON,	RTL8187),
     96       1.1  christos 	URTW_DEV_RTL8187(SURECOM,	EP9001G2A),
     97       1.1  christos 	/* Realtek RTL8187B devices. */
     98       1.1  christos 	URTW_DEV_RTL8187B(BELKIN,	F5D7050E),
     99       1.1  christos 	URTW_DEV_RTL8187B(NETGEAR,	WG111V3),
    100       1.1  christos 	URTW_DEV_RTL8187B(REALTEK,	RTL8187B_0),
    101       1.1  christos 	URTW_DEV_RTL8187B(REALTEK,	RTL8187B_1),
    102       1.1  christos 	URTW_DEV_RTL8187B(REALTEK,	RTL8187B_2),
    103       1.1  christos 	URTW_DEV_RTL8187B(SITECOMEU,	WL168V4)
    104       1.1  christos #undef	URTW_DEV_RTL8187
    105       1.1  christos #undef	URTW_DEV_RTL8187B
    106       1.1  christos };
    107       1.1  christos #define	urtw_lookup(v, p)	\
    108       1.1  christos 	    ((const struct urtw_type *)usb_lookup(urtw_devs, v, p))
    109       1.1  christos 
    110       1.1  christos /*
    111       1.1  christos  * Helper read/write macros.
    112       1.1  christos  */
    113       1.1  christos #define urtw_read8_m(sc, val, data)	do {			\
    114       1.1  christos 	error = urtw_read8_c(sc, val, data, 0);			\
    115       1.1  christos 	if (error != 0)						\
    116       1.1  christos 		goto fail;					\
    117       1.1  christos } while (0)
    118       1.1  christos #define urtw_read8_idx_m(sc, val, data, idx)	do {		\
    119       1.1  christos 	error = urtw_read8_c(sc, val, data, idx);		\
    120       1.1  christos 	if (error != 0)						\
    121       1.1  christos 		goto fail;					\
    122       1.1  christos } while (0)
    123       1.1  christos #define urtw_write8_m(sc, val, data)	do {			\
    124       1.1  christos 	error = urtw_write8_c(sc, val, data, 0);		\
    125       1.1  christos 	if (error != 0)						\
    126       1.1  christos 		goto fail;					\
    127       1.1  christos } while (0)
    128       1.1  christos #define urtw_write8_idx_m(sc, val, data, idx)	do {		\
    129       1.1  christos 	error = urtw_write8_c(sc, val, data, idx);		\
    130       1.1  christos 	if (error != 0)						\
    131       1.1  christos 		goto fail;					\
    132       1.1  christos } while (0)
    133       1.1  christos #define urtw_read16_m(sc, val, data)	do {			\
    134       1.1  christos 	error = urtw_read16_c(sc, val, data, 0);		\
    135       1.1  christos 	if (error != 0)						\
    136       1.1  christos 		goto fail;					\
    137       1.1  christos } while (0)
    138       1.1  christos #define urtw_read16_idx_m(sc, val, data, idx)	do {		\
    139       1.1  christos 	error = urtw_read16_c(sc, val, data, idx);		\
    140       1.1  christos 	if (error != 0)						\
    141       1.1  christos 		goto fail;					\
    142       1.1  christos } while (0)
    143       1.1  christos #define urtw_write16_m(sc, val, data)	do {			\
    144       1.1  christos 	error = urtw_write16_c(sc, val, data, 0);		\
    145       1.1  christos 	if (error != 0)						\
    146       1.1  christos 		goto fail;					\
    147       1.1  christos } while (0)
    148       1.1  christos #define urtw_write16_idx_m(sc, val, data, idx)	do {		\
    149       1.1  christos 	error = urtw_write16_c(sc, val, data, idx);		\
    150       1.1  christos 	if (error != 0)						\
    151       1.1  christos 		goto fail;					\
    152       1.1  christos } while (0)
    153       1.1  christos #define urtw_read32_m(sc, val, data)	do {			\
    154       1.1  christos 	error = urtw_read32_c(sc, val, data, 0);		\
    155       1.1  christos 	if (error != 0)						\
    156       1.1  christos 		goto fail;					\
    157       1.1  christos } while (0)
    158       1.1  christos #define urtw_read32_idx_m(sc, val, data, idx)	do {		\
    159       1.1  christos 	error = urtw_read32_c(sc, val, data, idx);		\
    160       1.1  christos 	if (error != 0)						\
    161       1.1  christos 		goto fail;					\
    162       1.1  christos } while (0)
    163       1.1  christos #define urtw_write32_m(sc, val, data)	do {			\
    164       1.1  christos 	error = urtw_write32_c(sc, val, data, 0);		\
    165       1.1  christos 	if (error != 0)						\
    166       1.1  christos 		goto fail;					\
    167       1.1  christos } while (0)
    168       1.1  christos #define urtw_write32_idx_m(sc, val, data, idx)	do {		\
    169       1.1  christos 	error = urtw_write32_c(sc, val, data, idx);		\
    170       1.1  christos 	if (error != 0)						\
    171       1.1  christos 		goto fail;					\
    172       1.1  christos } while (0)
    173       1.1  christos #define urtw_8187_write_phy_ofdm(sc, val, data)	do {		\
    174       1.1  christos 	error = urtw_8187_write_phy_ofdm_c(sc, val, data);	\
    175       1.1  christos 	if (error != 0)						\
    176       1.1  christos 		goto fail;					\
    177       1.1  christos } while (0)
    178       1.1  christos #define urtw_8187_write_phy_cck(sc, val, data)	do {		\
    179       1.1  christos 	error = urtw_8187_write_phy_cck_c(sc, val, data);	\
    180       1.1  christos 	if (error != 0)						\
    181       1.1  christos 		goto fail;					\
    182       1.1  christos } while (0)
    183       1.1  christos #define urtw_8225_write(sc, val, data)	do {			\
    184       1.1  christos 	error = urtw_8225_write_c(sc, val, data);		\
    185       1.1  christos 	if (error != 0)						\
    186       1.1  christos 		goto fail;					\
    187       1.1  christos } while (0)
    188       1.1  christos 
    189       1.1  christos struct urtw_pair {
    190       1.1  christos 	uint32_t	reg;
    191       1.1  christos 	uint32_t	val;
    192       1.1  christos };
    193       1.1  christos 
    194       1.1  christos struct urtw_pair_idx {
    195       1.1  christos 	uint8_t		reg;
    196       1.1  christos 	uint8_t		val;
    197       1.1  christos 	uint8_t		idx;
    198       1.1  christos };
    199       1.1  christos 
    200       1.1  christos static struct urtw_pair_idx urtw_8187b_regtbl[] = {
    201       1.1  christos 	{ 0xf0, 0x32, 0 }, { 0xf1, 0x32, 0 }, { 0xf2, 0x00, 0 },
    202       1.1  christos 	{ 0xf3, 0x00, 0 }, { 0xf4, 0x32, 0 }, { 0xf5, 0x43, 0 },
    203       1.1  christos 	{ 0xf6, 0x00, 0 }, { 0xf7, 0x00, 0 }, { 0xf8, 0x46, 0 },
    204       1.1  christos 	{ 0xf9, 0xa4, 0 }, { 0xfa, 0x00, 0 }, { 0xfb, 0x00, 0 },
    205       1.1  christos 	{ 0xfc, 0x96, 0 }, { 0xfd, 0xa4, 0 }, { 0xfe, 0x00, 0 },
    206       1.1  christos 	{ 0xff, 0x00, 0 },
    207       1.1  christos 
    208       1.1  christos 	{ 0x58, 0x4b, 1 }, { 0x59, 0x00, 1 }, { 0x5a, 0x4b, 1 },
    209       1.1  christos 	{ 0x5b, 0x00, 1 }, { 0x60, 0x4b, 1 }, { 0x61, 0x09, 1 },
    210       1.1  christos 	{ 0x62, 0x4b, 1 }, { 0x63, 0x09, 1 }, { 0xce, 0x0f, 1 },
    211       1.1  christos 	{ 0xcf, 0x00, 1 }, { 0xe0, 0xff, 1 }, { 0xe1, 0x0f, 1 },
    212       1.1  christos 	{ 0xe2, 0x00, 1 }, { 0xf0, 0x4e, 1 }, { 0xf1, 0x01, 1 },
    213       1.1  christos 	{ 0xf2, 0x02, 1 }, { 0xf3, 0x03, 1 }, { 0xf4, 0x04, 1 },
    214       1.1  christos 	{ 0xf5, 0x05, 1 }, { 0xf6, 0x06, 1 }, { 0xf7, 0x07, 1 },
    215       1.1  christos 	{ 0xf8, 0x08, 1 },
    216       1.1  christos 
    217       1.1  christos 	{ 0x4e, 0x00, 2 }, { 0x0c, 0x04, 2 }, { 0x21, 0x61, 2 },
    218       1.1  christos 	{ 0x22, 0x68, 2 }, { 0x23, 0x6f, 2 }, { 0x24, 0x76, 2 },
    219       1.1  christos 	{ 0x25, 0x7d, 2 }, { 0x26, 0x84, 2 }, { 0x27, 0x8d, 2 },
    220       1.1  christos 	{ 0x4d, 0x08, 2 }, { 0x50, 0x05, 2 }, { 0x51, 0xf5, 2 },
    221       1.1  christos 	{ 0x52, 0x04, 2 }, { 0x53, 0xa0, 2 }, { 0x54, 0x1f, 2 },
    222       1.1  christos 	{ 0x55, 0x23, 2 }, { 0x56, 0x45, 2 }, { 0x57, 0x67, 2 },
    223       1.1  christos 	{ 0x58, 0x08, 2 }, { 0x59, 0x08, 2 }, { 0x5a, 0x08, 2 },
    224       1.1  christos 	{ 0x5b, 0x08, 2 }, { 0x60, 0x08, 2 }, { 0x61, 0x08, 2 },
    225       1.1  christos 	{ 0x62, 0x08, 2 }, { 0x63, 0x08, 2 }, { 0x64, 0xcf, 2 },
    226       1.1  christos 	{ 0x72, 0x56, 2 }, { 0x73, 0x9a, 2 },
    227       1.1  christos 
    228       1.1  christos 	{ 0x34, 0xf0, 0 }, { 0x35, 0x0f, 0 }, { 0x5b, 0x40, 0 },
    229       1.1  christos 	{ 0x84, 0x88, 0 }, { 0x85, 0x24, 0 }, { 0x88, 0x54, 0 },
    230       1.1  christos 	{ 0x8b, 0xb8, 0 }, { 0x8c, 0x07, 0 }, { 0x8d, 0x00, 0 },
    231       1.1  christos 	{ 0x94, 0x1b, 0 }, { 0x95, 0x12, 0 }, { 0x96, 0x00, 0 },
    232       1.1  christos 	{ 0x97, 0x06, 0 }, { 0x9d, 0x1a, 0 }, { 0x9f, 0x10, 0 },
    233       1.1  christos 	{ 0xb4, 0x22, 0 }, { 0xbe, 0x80, 0 }, { 0xdb, 0x00, 0 },
    234       1.1  christos 	{ 0xee, 0x00, 0 }, { 0x91, 0x03, 0 },
    235       1.1  christos 
    236       1.1  christos 	{ 0x4c, 0x00, 2 }, { 0x9f, 0x00, 3 }, { 0x8c, 0x01, 0 },
    237       1.1  christos 	{ 0x8d, 0x10, 0 }, { 0x8e, 0x08, 0 }, { 0x8f, 0x00, 0 }
    238       1.1  christos };
    239       1.1  christos 
    240       1.1  christos static uint8_t urtw_8225_agc[] = {
    241       1.1  christos 	0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b,
    242       1.1  christos 	0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
    243       1.1  christos 	0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85,
    244       1.1  christos 	0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a,
    245       1.1  christos 	0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f,
    246       1.1  christos 	0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24,
    247       1.1  christos 	0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19,
    248       1.1  christos 	0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
    249       1.1  christos 	0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
    250       1.1  christos 	0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    251       1.1  christos 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    252       1.1  christos 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
    253       1.1  christos };
    254       1.1  christos 
    255       1.1  christos static uint32_t urtw_8225_channel[] = {
    256       1.1  christos 	0x0000,		/* dummy channel 0 */
    257       1.1  christos 	0x085c,		/* 1 */
    258       1.1  christos 	0x08dc,		/* 2 */
    259       1.1  christos 	0x095c,		/* 3 */
    260       1.1  christos 	0x09dc,		/* 4 */
    261       1.1  christos 	0x0a5c,		/* 5 */
    262       1.1  christos 	0x0adc,		/* 6 */
    263       1.1  christos 	0x0b5c,		/* 7 */
    264       1.1  christos 	0x0bdc,		/* 8 */
    265       1.1  christos 	0x0c5c,		/* 9 */
    266       1.1  christos 	0x0cdc,		/* 10 */
    267       1.1  christos 	0x0d5c,		/* 11 */
    268       1.1  christos 	0x0ddc,		/* 12 */
    269       1.1  christos 	0x0e5c,		/* 13 */
    270       1.1  christos 	0x0f72,		/* 14 */
    271       1.1  christos };
    272       1.1  christos 
    273       1.1  christos static uint8_t urtw_8225_gain[] = {
    274       1.1  christos 	0x23, 0x88, 0x7c, 0xa5,		/* -82dbm */
    275       1.1  christos 	0x23, 0x88, 0x7c, 0xb5,		/* -82dbm */
    276       1.1  christos 	0x23, 0x88, 0x7c, 0xc5,		/* -82dbm */
    277       1.1  christos 	0x33, 0x80, 0x79, 0xc5,		/* -78dbm */
    278       1.1  christos 	0x43, 0x78, 0x76, 0xc5,		/* -74dbm */
    279       1.1  christos 	0x53, 0x60, 0x73, 0xc5,		/* -70dbm */
    280       1.1  christos 	0x63, 0x58, 0x70, 0xc5,		/* -66dbm */
    281       1.1  christos };
    282       1.1  christos 
    283       1.1  christos static struct urtw_pair urtw_8225_rf_part1[] = {
    284       1.1  christos 	{ 0x00, 0x0067 }, { 0x01, 0x0fe0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
    285       1.1  christos 	{ 0x04, 0x0486 }, { 0x05, 0x0bc0 }, { 0x06, 0x0ae6 }, { 0x07, 0x082a },
    286       1.1  christos 	{ 0x08, 0x001f }, { 0x09, 0x0334 }, { 0x0a, 0x0fd4 }, { 0x0b, 0x0391 },
    287       1.1  christos 	{ 0x0c, 0x0050 }, { 0x0d, 0x06db }, { 0x0e, 0x0029 }, { 0x0f, 0x0914 }
    288       1.1  christos };
    289       1.1  christos 
    290       1.1  christos static struct urtw_pair urtw_8225_rf_part2[] = {
    291       1.1  christos 	{ 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
    292       1.1  christos 	{ 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
    293       1.1  christos 	{ 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x09 }, { 0x0b, 0x80 },
    294       1.1  christos 	{ 0x0c, 0x01 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 }, { 0x10, 0x84 },
    295       1.1  christos 	{ 0x11, 0x06 }, { 0x12, 0x20 }, { 0x13, 0x20 }, { 0x14, 0x00 },
    296       1.1  christos 	{ 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 }, { 0x18, 0xef },
    297       1.1  christos 	{ 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x76 }, { 0x1c, 0x04 },
    298       1.1  christos 	{ 0x1e, 0x95 }, { 0x1f, 0x75 }, { 0x20, 0x1f }, { 0x21, 0x27 },
    299       1.1  christos 	{ 0x22, 0x16 }, { 0x24, 0x46 }, { 0x25, 0x20 }, { 0x26, 0x90 },
    300       1.1  christos 	{ 0x27, 0x88 }
    301       1.1  christos };
    302       1.1  christos 
    303       1.1  christos static struct urtw_pair urtw_8225_rf_part3[] = {
    304       1.1  christos 	{ 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
    305       1.1  christos 	{ 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x10, 0x9b },
    306       1.1  christos 	{ 0x11, 0x88 }, { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 },
    307       1.1  christos 	{ 0x1a, 0xa0 }, { 0x1b, 0x08 }, { 0x40, 0x86 }, { 0x41, 0x8d },
    308       1.1  christos 	{ 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x1f }, { 0x45, 0x1e },
    309       1.1  christos 	{ 0x46, 0x1a }, { 0x47, 0x15 }, { 0x48, 0x10 }, { 0x49, 0x0a },
    310       1.1  christos 	{ 0x4a, 0x05 }, { 0x4b, 0x02 }, { 0x4c, 0x05 }
    311       1.1  christos };
    312       1.1  christos 
    313       1.1  christos static uint16_t urtw_8225_rxgain[] = {
    314       1.1  christos 	0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
    315       1.1  christos 	0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
    316       1.1  christos 	0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
    317       1.1  christos 	0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
    318       1.1  christos 	0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
    319       1.1  christos 	0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
    320       1.1  christos 	0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
    321       1.1  christos 	0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
    322       1.1  christos 	0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
    323       1.1  christos 	0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
    324       1.1  christos 	0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
    325       1.1  christos 	0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
    326       1.1  christos };
    327       1.1  christos 
    328       1.1  christos static uint8_t urtw_8225_threshold[] = {
    329       1.1  christos 	0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
    330       1.1  christos };
    331       1.1  christos 
    332       1.1  christos static uint8_t urtw_8225_tx_gain_cck_ofdm[] = {
    333       1.1  christos 	0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
    334       1.1  christos };
    335       1.1  christos 
    336       1.1  christos static uint8_t urtw_8225_txpwr_cck[] = {
    337       1.1  christos 	0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
    338       1.1  christos 	0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
    339       1.1  christos 	0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
    340       1.1  christos 	0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
    341       1.1  christos 	0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
    342       1.1  christos 	0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
    343       1.1  christos };
    344       1.1  christos 
    345       1.1  christos static uint8_t urtw_8225_txpwr_cck_ch14[] = {
    346       1.1  christos 	0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
    347       1.1  christos 	0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
    348       1.1  christos 	0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
    349       1.1  christos 	0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
    350       1.1  christos 	0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
    351       1.1  christos 	0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
    352       1.1  christos };
    353       1.1  christos 
    354       1.1  christos static uint8_t urtw_8225_txpwr_ofdm[] = {
    355       1.1  christos 	0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
    356       1.1  christos };
    357       1.1  christos 
    358       1.1  christos static uint8_t urtw_8225v2_agc[] = {
    359       1.1  christos 	0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57,
    360       1.1  christos 	0x55, 0x53, 0x51, 0x4f, 0x4d, 0x4b, 0x49, 0x47,
    361       1.1  christos 	0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x39, 0x37,
    362       1.1  christos 	0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27,
    363       1.1  christos 	0x25, 0x23, 0x21, 0x1f, 0x1d, 0x1b, 0x19, 0x17,
    364       1.1  christos 	0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0b, 0x09, 0x07,
    365       1.1  christos 	0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    366       1.1  christos 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    367       1.1  christos 	0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
    368       1.1  christos 	0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
    369       1.1  christos 	0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2a,
    370       1.1  christos 	0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d,
    371       1.1  christos 	0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f,
    372       1.1  christos 	0x2f, 0x2f, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31,
    373       1.1  christos 	0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
    374       1.1  christos 	0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
    375       1.1  christos };
    376       1.1  christos 
    377       1.1  christos static uint8_t urtw_8225v2_ofdm[] = {
    378       1.1  christos 	0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60,
    379       1.1  christos 	0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
    380       1.1  christos 	0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
    381       1.1  christos 	0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
    382       1.1  christos 	0x0a, 0xe1, 0x2c, 0x8a, 0x86, 0x83, 0x34, 0x0f,
    383       1.1  christos 	0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
    384       1.1  christos 	0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
    385       1.1  christos 	0x6d, 0x3c, 0xfb, 0x07
    386       1.1  christos };
    387       1.1  christos 
    388       1.1  christos static uint8_t urtw_8225v2_gain_bg[] = {
    389       1.1  christos 	0x23, 0x15, 0xa5,		/* -82-1dbm */
    390       1.1  christos 	0x23, 0x15, 0xb5,		/* -82-2dbm */
    391       1.1  christos 	0x23, 0x15, 0xc5,		/* -82-3dbm */
    392       1.1  christos 	0x33, 0x15, 0xc5,		/* -78dbm */
    393       1.1  christos 	0x43, 0x15, 0xc5,		/* -74dbm */
    394       1.1  christos 	0x53, 0x15, 0xc5,		/* -70dbm */
    395       1.1  christos 	0x63, 0x15, 0xc5,		/* -66dbm */
    396       1.1  christos };
    397       1.1  christos 
    398       1.1  christos static struct urtw_pair urtw_8225v2_rf_part1[] = {
    399       1.1  christos 	{ 0x00, 0x02bf }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
    400       1.1  christos 	{ 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
    401       1.1  christos 	{ 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
    402       1.1  christos 	{ 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
    403       1.1  christos };
    404       1.1  christos 
    405       1.1  christos static struct urtw_pair urtw_8225v2_rf_part2[] = {
    406       1.1  christos 	{ 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
    407       1.1  christos 	{ 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
    408       1.1  christos 	{ 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x08 }, { 0x0b, 0x80 },
    409       1.1  christos 	{ 0x0c, 0x01 }, { 0x0d, 0x43 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 },
    410       1.1  christos 	{ 0x10, 0x84 }, { 0x11, 0x07 }, { 0x12, 0x20 }, { 0x13, 0x20 },
    411       1.1  christos 	{ 0x14, 0x00 }, { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 },
    412       1.1  christos 	{ 0x18, 0xef }, { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x15 },
    413       1.1  christos 	{ 0x1c, 0x04 }, { 0x1d, 0xc5 }, { 0x1e, 0x95 }, { 0x1f, 0x75 },
    414       1.1  christos 	{ 0x20, 0x1f }, { 0x21, 0x17 }, { 0x22, 0x16 }, { 0x23, 0x80 },
    415       1.1  christos 	{ 0x24, 0x46 }, { 0x25, 0x00 }, { 0x26, 0x90 }, { 0x27, 0x88 }
    416       1.1  christos };
    417       1.1  christos 
    418       1.1  christos static struct urtw_pair urtw_8225v2_rf_part3[] = {
    419       1.1  christos 	{ 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
    420       1.1  christos 	{ 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x09, 0x11 },
    421       1.1  christos 	{ 0x0a, 0x17 }, { 0x0b, 0x11 }, { 0x10, 0x9b }, { 0x11, 0x88 },
    422       1.1  christos 	{ 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 }, { 0x1a, 0xa0 },
    423       1.1  christos 	{ 0x1b, 0x08 }, { 0x1d, 0x00 }, { 0x40, 0x86 }, { 0x41, 0x9d },
    424       1.1  christos 	{ 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x36 }, { 0x45, 0x35 },
    425       1.1  christos 	{ 0x46, 0x2e }, { 0x47, 0x25 }, { 0x48, 0x1c }, { 0x49, 0x12 },
    426       1.1  christos 	{ 0x4a, 0x09 }, { 0x4b, 0x04 }, { 0x4c, 0x05 }
    427       1.1  christos };
    428       1.1  christos 
    429       1.1  christos static uint16_t urtw_8225v2_rxgain[] = {
    430       1.1  christos 	0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
    431       1.1  christos 	0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
    432       1.1  christos 	0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
    433       1.1  christos 	0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
    434       1.1  christos 	0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
    435       1.1  christos 	0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
    436       1.1  christos 	0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
    437       1.1  christos 	0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
    438       1.1  christos 	0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
    439       1.1  christos 	0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
    440       1.1  christos 	0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
    441       1.1  christos 	0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
    442       1.1  christos };
    443       1.1  christos 
    444       1.1  christos static uint8_t urtw_8225v2_tx_gain_cck_ofdm[] = {
    445       1.1  christos 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
    446       1.1  christos 	0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
    447       1.1  christos 	0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
    448       1.1  christos 	0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    449       1.1  christos 	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
    450       1.1  christos 	0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
    451       1.1  christos };
    452       1.1  christos 
    453       1.1  christos static uint8_t urtw_8225v2_txpwr_cck[] = {
    454       1.1  christos 	0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
    455       1.1  christos 	0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
    456       1.1  christos 	0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
    457       1.1  christos 	0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
    458       1.1  christos };
    459       1.1  christos 
    460       1.1  christos static uint8_t urtw_8225v2_txpwr_cck_ch14[] = {
    461       1.1  christos 	0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
    462       1.1  christos 	0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
    463       1.1  christos 	0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
    464       1.1  christos 	0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
    465       1.1  christos };
    466       1.1  christos 
    467       1.1  christos static struct urtw_pair urtw_8225v2_b_rf[] = {
    468       1.1  christos 	{ 0x00, 0x00b7 }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
    469       1.1  christos 	{ 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
    470       1.1  christos 	{ 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
    471       1.1  christos 	{ 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 },
    472       1.1  christos 	{ 0x00, 0x01b7 }
    473       1.1  christos };
    474       1.1  christos 
    475       1.1  christos static struct urtw_pair urtw_ratetable[] = {
    476       1.1  christos 	{  2,  0 }, {   4,  1 }, { 11, 2 }, { 12, 4 }, { 18, 5 },
    477       1.1  christos 	{ 22,  3 }, {  24,  6 }, { 36, 7 }, { 48, 8 }, { 72, 9 },
    478       1.1  christos 	{ 96, 10 }, { 108, 11 }
    479       1.1  christos };
    480       1.1  christos 
    481  1.15.2.2    martin static int		urtw_init(struct ifnet *);
    482  1.15.2.2    martin static void		urtw_stop(struct ifnet *, int);
    483  1.15.2.2    martin static int		urtw_ioctl(struct ifnet *, u_long, void *);
    484  1.15.2.2    martin static void		urtw_start(struct ifnet *);
    485  1.15.2.2    martin static int		urtw_alloc_rx_data_list(struct urtw_softc *);
    486  1.15.2.2    martin static void		urtw_free_rx_data_list(struct urtw_softc *);
    487  1.15.2.2    martin static int		urtw_alloc_tx_data_list(struct urtw_softc *);
    488  1.15.2.2    martin static void		urtw_free_tx_data_list(struct urtw_softc *);
    489  1.15.2.2    martin static void		urtw_rxeof(struct usbd_xfer *, void *,
    490       1.1  christos 		    usbd_status);
    491  1.15.2.2    martin static int		urtw_tx_start(struct urtw_softc *,
    492       1.1  christos 		    struct ieee80211_node *, struct mbuf *, int);
    493  1.15.2.2    martin static void		urtw_txeof_low(struct usbd_xfer *, void *,
    494       1.1  christos 		    usbd_status);
    495  1.15.2.2    martin static void		urtw_txeof_normal(struct usbd_xfer *, void *,
    496       1.1  christos 		    usbd_status);
    497  1.15.2.2    martin static void		urtw_next_scan(void *);
    498  1.15.2.2    martin static void		urtw_task(void *);
    499  1.15.2.2    martin static void		urtw_ledusbtask(void *);
    500  1.15.2.2    martin static void		urtw_ledtask(void *);
    501  1.15.2.2    martin static int		urtw_media_change(struct ifnet *);
    502  1.15.2.2    martin static int		urtw_newstate(struct ieee80211com *, enum ieee80211_state, int);
    503  1.15.2.2    martin static void		urtw_watchdog(struct ifnet *);
    504  1.15.2.2    martin static void		urtw_set_chan(struct urtw_softc *, struct ieee80211_channel *);
    505  1.15.2.2    martin static int		urtw_isbmode(uint16_t);
    506  1.15.2.2    martin static uint16_t	urtw_rate2rtl(int);
    507  1.15.2.2    martin static uint16_t	urtw_rtl2rate(int);
    508  1.15.2.2    martin static usbd_status	urtw_set_rate(struct urtw_softc *);
    509  1.15.2.2    martin static usbd_status	urtw_update_msr(struct urtw_softc *);
    510  1.15.2.2    martin static usbd_status	urtw_read8_c(struct urtw_softc *, int, uint8_t *, uint8_t);
    511  1.15.2.2    martin static usbd_status	urtw_read16_c(struct urtw_softc *, int, uint16_t *, uint8_t);
    512  1.15.2.2    martin static usbd_status	urtw_read32_c(struct urtw_softc *, int, uint32_t *, uint8_t);
    513  1.15.2.2    martin static usbd_status	urtw_write8_c(struct urtw_softc *, int, uint8_t, uint8_t);
    514  1.15.2.2    martin static usbd_status	urtw_write16_c(struct urtw_softc *, int, uint16_t, uint8_t);
    515  1.15.2.2    martin static usbd_status	urtw_write32_c(struct urtw_softc *, int, uint32_t, uint8_t);
    516  1.15.2.2    martin static usbd_status	urtw_eprom_cs(struct urtw_softc *, int);
    517  1.15.2.2    martin static usbd_status	urtw_eprom_ck(struct urtw_softc *);
    518  1.15.2.2    martin static usbd_status	urtw_eprom_sendbits(struct urtw_softc *, int16_t *,
    519       1.1  christos 		    int);
    520  1.15.2.2    martin static usbd_status	urtw_eprom_read32(struct urtw_softc *, uint32_t,
    521       1.1  christos 		    uint32_t *);
    522  1.15.2.2    martin static usbd_status	urtw_eprom_readbit(struct urtw_softc *, int16_t *);
    523  1.15.2.2    martin static usbd_status	urtw_eprom_writebit(struct urtw_softc *, int16_t);
    524  1.15.2.2    martin static usbd_status	urtw_get_macaddr(struct urtw_softc *);
    525  1.15.2.2    martin static usbd_status	urtw_get_txpwr(struct urtw_softc *);
    526  1.15.2.2    martin static usbd_status	urtw_get_rfchip(struct urtw_softc *);
    527  1.15.2.2    martin static usbd_status	urtw_led_init(struct urtw_softc *);
    528  1.15.2.2    martin static usbd_status	urtw_8185_rf_pins_enable(struct urtw_softc *);
    529  1.15.2.2    martin static usbd_status	urtw_8185_tx_antenna(struct urtw_softc *, uint8_t);
    530  1.15.2.2    martin static usbd_status	urtw_8187_write_phy(struct urtw_softc *, uint8_t, uint32_t);
    531  1.15.2.2    martin static usbd_status	urtw_8187_write_phy_ofdm_c(struct urtw_softc *, uint8_t,
    532       1.1  christos 		    uint32_t);
    533  1.15.2.2    martin static usbd_status	urtw_8187_write_phy_cck_c(struct urtw_softc *, uint8_t,
    534       1.1  christos 		    uint32_t);
    535  1.15.2.2    martin static usbd_status	urtw_8225_setgain(struct urtw_softc *, int16_t);
    536  1.15.2.2    martin static usbd_status	urtw_8225_usb_init(struct urtw_softc *);
    537  1.15.2.2    martin static usbd_status	urtw_8225_write_c(struct urtw_softc *, uint8_t, uint16_t);
    538  1.15.2.2    martin static usbd_status	urtw_8225_write_s16(struct urtw_softc *, uint8_t, int,
    539       1.1  christos 		    uint16_t);
    540  1.15.2.2    martin static usbd_status	urtw_8225_read(struct urtw_softc *, uint8_t, uint32_t *);
    541  1.15.2.2    martin static usbd_status	urtw_8225_rf_init(struct urtw_rf *);
    542  1.15.2.2    martin static usbd_status	urtw_8225_rf_set_chan(struct urtw_rf *, int);
    543  1.15.2.2    martin static usbd_status	urtw_8225_rf_set_sens(struct urtw_rf *);
    544  1.15.2.2    martin static usbd_status	urtw_8225_set_txpwrlvl(struct urtw_softc *, int);
    545  1.15.2.2    martin static usbd_status	urtw_8225v2_rf_init(struct urtw_rf *);
    546  1.15.2.2    martin static usbd_status	urtw_8225v2_rf_set_chan(struct urtw_rf *, int);
    547  1.15.2.2    martin static usbd_status	urtw_8225v2_set_txpwrlvl(struct urtw_softc *, int);
    548  1.15.2.2    martin static usbd_status	urtw_8225v2_setgain(struct urtw_softc *, int16_t);
    549  1.15.2.2    martin static usbd_status	urtw_8225_isv2(struct urtw_softc *, int *);
    550  1.15.2.2    martin static usbd_status	urtw_read8e(struct urtw_softc *, int, uint8_t *);
    551  1.15.2.2    martin static usbd_status	urtw_write8e(struct urtw_softc *, int, uint8_t);
    552  1.15.2.2    martin static usbd_status	urtw_8180_set_anaparam(struct urtw_softc *, uint32_t);
    553  1.15.2.2    martin static usbd_status	urtw_8185_set_anaparam2(struct urtw_softc *, uint32_t);
    554  1.15.2.2    martin static usbd_status	urtw_open_pipes(struct urtw_softc *);
    555  1.15.2.2    martin static usbd_status	urtw_close_pipes(struct urtw_softc *);
    556  1.15.2.2    martin static usbd_status	urtw_intr_enable(struct urtw_softc *);
    557  1.15.2.2    martin static usbd_status	urtw_intr_disable(struct urtw_softc *);
    558  1.15.2.2    martin static usbd_status	urtw_reset(struct urtw_softc *);
    559  1.15.2.2    martin static usbd_status	urtw_led_on(struct urtw_softc *, int);
    560  1.15.2.2    martin static usbd_status	urtw_led_ctl(struct urtw_softc *, int);
    561  1.15.2.2    martin static usbd_status	urtw_led_blink(struct urtw_softc *);
    562  1.15.2.2    martin static usbd_status	urtw_led_mode0(struct urtw_softc *, int);
    563  1.15.2.2    martin static usbd_status	urtw_led_mode1(struct urtw_softc *, int);
    564  1.15.2.2    martin static usbd_status	urtw_led_mode2(struct urtw_softc *, int);
    565  1.15.2.2    martin static usbd_status	urtw_led_mode3(struct urtw_softc *, int);
    566  1.15.2.2    martin static usbd_status	urtw_rx_setconf(struct urtw_softc *);
    567  1.15.2.2    martin static usbd_status	urtw_rx_enable(struct urtw_softc *);
    568  1.15.2.2    martin static usbd_status	urtw_tx_enable(struct urtw_softc *);
    569  1.15.2.2    martin static usbd_status	urtw_8187b_update_wmm(struct urtw_softc *);
    570  1.15.2.2    martin static usbd_status	urtw_8187b_reset(struct urtw_softc *);
    571  1.15.2.2    martin static int		urtw_8187b_init(struct ifnet *);
    572  1.15.2.2    martin static usbd_status	urtw_8225v2_b_config_mac(struct urtw_softc *);
    573  1.15.2.2    martin static usbd_status	urtw_8225v2_b_init_rfe(struct urtw_softc *);
    574  1.15.2.2    martin static usbd_status	urtw_8225v2_b_update_chan(struct urtw_softc *);
    575  1.15.2.2    martin static usbd_status	urtw_8225v2_b_rf_init(struct urtw_rf *);
    576  1.15.2.2    martin static usbd_status	urtw_8225v2_b_rf_set_chan(struct urtw_rf *, int);
    577  1.15.2.2    martin static usbd_status	urtw_8225v2_b_set_txpwrlvl(struct urtw_softc *, int);
    578  1.15.2.2    martin static int		urtw_set_bssid(struct urtw_softc *, const uint8_t *);
    579  1.15.2.2    martin static int		urtw_set_macaddr(struct urtw_softc *, const uint8_t *);
    580  1.15.2.2    martin 
    581  1.15.2.2    martin static int urtw_match(device_t, cfdata_t, void *);
    582  1.15.2.2    martin static void urtw_attach(device_t, device_t, void *);
    583  1.15.2.2    martin static int urtw_detach(device_t, int);
    584  1.15.2.2    martin static int urtw_activate(device_t, enum devact);
    585       1.1  christos 
    586       1.1  christos CFATTACH_DECL_NEW(urtw, sizeof(struct urtw_softc),
    587       1.1  christos 	urtw_match,
    588       1.1  christos 	urtw_attach,
    589       1.1  christos 	urtw_detach,
    590       1.1  christos 	urtw_activate
    591       1.1  christos );
    592       1.1  christos 
    593  1.15.2.2    martin static int
    594       1.1  christos urtw_match(device_t parent, cfdata_t match, void *aux)
    595       1.1  christos {
    596       1.1  christos 	struct usb_attach_arg *uaa = aux;
    597       1.1  christos 
    598       1.7     skrll 	return urtw_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
    599       1.7     skrll 	    UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
    600       1.1  christos }
    601       1.1  christos 
    602  1.15.2.2    martin static void
    603       1.1  christos urtw_attach(device_t parent, device_t self, void *aux)
    604       1.1  christos {
    605       1.1  christos 	struct urtw_softc *sc = device_private(self);
    606       1.1  christos 	struct usb_attach_arg *uaa = aux;
    607       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
    608       1.1  christos 	struct ifnet *ifp = &sc->sc_if;
    609       1.1  christos 	usbd_status error;
    610       1.1  christos 	uint8_t data8;
    611       1.1  christos 	uint32_t data;
    612       1.1  christos 	int i;
    613       1.1  christos 
    614       1.1  christos 	sc->sc_dev = self;
    615       1.7     skrll 	sc->sc_udev = uaa->uaa_device;
    616       1.7     skrll 	sc->sc_hwrev = urtw_lookup(uaa->uaa_vendor, uaa->uaa_product)->rev;
    617       1.1  christos 
    618      1.11   msaitoh 	aprint_naive("\n");
    619      1.11   msaitoh 	aprint_normal(": ");
    620       1.1  christos 
    621       1.1  christos 	if (sc->sc_hwrev & URTW_HWREV_8187) {
    622       1.1  christos 		urtw_read32_m(sc, URTW_TX_CONF, &data);
    623       1.1  christos 		data &= URTW_TX_HWREV_MASK;
    624       1.1  christos 		switch (data) {
    625       1.1  christos 		case URTW_TX_HWREV_8187_D:
    626       1.1  christos 			sc->sc_hwrev |= URTW_HWREV_8187_D;
    627      1.11   msaitoh 			aprint_normal("RTL8187 rev D");
    628       1.1  christos 			break;
    629       1.1  christos 		case URTW_TX_HWREV_8187B_D:
    630       1.1  christos 			/*
    631       1.1  christos 			 * Detect Realtek RTL8187B devices that use
    632       1.1  christos 			 * USB IDs of RTL8187.
    633       1.1  christos 			 */
    634       1.1  christos 			sc->sc_hwrev = URTW_HWREV_8187B | URTW_HWREV_8187B_B;
    635      1.11   msaitoh 			aprint_normal("RTL8187B rev B (early)");
    636       1.1  christos 			break;
    637       1.1  christos 		default:
    638       1.1  christos 			sc->sc_hwrev |= URTW_HWREV_8187_B;
    639      1.11   msaitoh 			aprint_normal("RTL8187 rev 0x%02x", data >> 25);
    640       1.1  christos 			break;
    641       1.1  christos 		}
    642       1.1  christos 	} else {
    643       1.1  christos 		/* RTL8187B hwrev register. */
    644       1.1  christos 		urtw_read8_m(sc, URTW_8187B_HWREV, &data8);
    645       1.1  christos 		switch (data8) {
    646       1.1  christos 		case URTW_8187B_HWREV_8187B_B:
    647       1.1  christos 			sc->sc_hwrev |= URTW_HWREV_8187B_B;
    648      1.11   msaitoh 			aprint_normal("RTL8187B rev B");
    649       1.1  christos 			break;
    650       1.1  christos 		case URTW_8187B_HWREV_8187B_D:
    651       1.1  christos 			sc->sc_hwrev |= URTW_HWREV_8187B_D;
    652      1.11   msaitoh 			aprint_normal("RTL8187B rev D");
    653       1.1  christos 			break;
    654       1.1  christos 		case URTW_8187B_HWREV_8187B_E:
    655       1.1  christos 			sc->sc_hwrev |= URTW_HWREV_8187B_E;
    656      1.11   msaitoh 			aprint_normal("RTL8187B rev E");
    657       1.1  christos 			break;
    658       1.1  christos 		default:
    659       1.1  christos 			sc->sc_hwrev |= URTW_HWREV_8187B_B;
    660      1.11   msaitoh 			aprint_normal("RTL8187B rev 0x%02x", data8);
    661       1.1  christos 			break;
    662       1.1  christos 		}
    663       1.1  christos 	}
    664       1.1  christos 
    665       1.1  christos 	urtw_read32_m(sc, URTW_RX, &data);
    666       1.1  christos 	sc->sc_epromtype = (data & URTW_RX_9356SEL) ? URTW_EEPROM_93C56 :
    667       1.1  christos 	    URTW_EEPROM_93C46;
    668       1.1  christos 
    669       1.1  christos 	error = urtw_get_rfchip(sc);
    670       1.1  christos 	if (error != 0)
    671       1.1  christos 		goto fail;
    672       1.1  christos 	error = urtw_get_macaddr(sc);
    673       1.1  christos 	if (error != 0)
    674       1.1  christos 		goto fail;
    675       1.1  christos 	error = urtw_get_txpwr(sc);
    676       1.1  christos 	if (error != 0)
    677       1.1  christos 		goto fail;
    678       1.1  christos 	error = urtw_led_init(sc);		/* XXX incompleted */
    679       1.1  christos 	if (error != 0)
    680       1.1  christos 		goto fail;
    681       1.1  christos 
    682       1.1  christos 	sc->sc_rts_retry = URTW_DEFAULT_RTS_RETRY;
    683       1.1  christos 	sc->sc_tx_retry = URTW_DEFAULT_TX_RETRY;
    684       1.1  christos 	sc->sc_currate = 3;
    685       1.1  christos 	/* XXX for what? */
    686       1.1  christos 	sc->sc_preamble_mode = 2;
    687       1.1  christos 
    688       1.5  jmcneill 	usb_init_task(&sc->sc_task, urtw_task, sc, 0);
    689       1.5  jmcneill 	usb_init_task(&sc->sc_ledtask, urtw_ledusbtask, sc, 0);
    690       1.1  christos 	callout_init(&sc->scan_to, 0);
    691       1.1  christos 	callout_setfunc(&sc->scan_to, urtw_next_scan, sc);
    692       1.1  christos 	callout_init(&sc->sc_led_ch, 0);
    693       1.1  christos 	callout_setfunc(&sc->sc_led_ch, urtw_ledtask, sc);
    694       1.1  christos 
    695       1.1  christos 	ic->ic_ifp = ifp;
    696       1.1  christos 	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
    697       1.1  christos 	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
    698       1.1  christos 	ic->ic_state = IEEE80211_S_INIT;
    699       1.1  christos 
    700       1.1  christos 	/* set device capabilities */
    701       1.1  christos 	ic->ic_caps =
    702       1.1  christos 	    IEEE80211_C_MONITOR |	/* monitor mode supported */
    703       1.1  christos 	    IEEE80211_C_TXPMGT |	/* tx power management */
    704       1.1  christos 	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
    705       1.1  christos 	    IEEE80211_C_SHSLOT |	/* short slot time supported */
    706       1.1  christos 	    IEEE80211_C_WEP |		/* s/w WEP */
    707       1.1  christos 	    IEEE80211_C_WPA;		/* WPA/RSN */
    708       1.1  christos 
    709       1.1  christos 	/* set supported .11b and .11g rates */
    710       1.1  christos 	ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
    711       1.1  christos 	ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
    712       1.1  christos 
    713       1.1  christos 	/* set supported .11b and .11g channels (1 through 14) */
    714       1.1  christos 	for (i = 1; i <= 14; i++) {
    715       1.1  christos 		ic->ic_channels[i].ic_freq =
    716       1.1  christos 		    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
    717       1.1  christos 		ic->ic_channels[i].ic_flags =
    718       1.1  christos 		    IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
    719       1.1  christos 		    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
    720       1.1  christos 	}
    721       1.1  christos 
    722       1.1  christos 	ifp->if_softc = sc;
    723       1.1  christos 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    724       1.1  christos 	if (sc->sc_hwrev & URTW_HWREV_8187) {
    725       1.1  christos 		ifp->if_init = urtw_init;
    726       1.1  christos 	} else {
    727       1.1  christos 		ifp->if_init = urtw_8187b_init;
    728       1.1  christos 	}
    729       1.1  christos 	ifp->if_ioctl = urtw_ioctl;
    730       1.1  christos 	ifp->if_start = urtw_start;
    731       1.1  christos 	ifp->if_watchdog = urtw_watchdog;
    732       1.1  christos 	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
    733       1.1  christos 	IFQ_SET_READY(&ifp->if_snd);
    734       1.1  christos 	memcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
    735       1.1  christos 
    736       1.1  christos 	if_attach(ifp);
    737       1.1  christos 	ieee80211_ifattach(ic);
    738       1.1  christos 
    739       1.1  christos 	/* override state transition machine */
    740       1.1  christos 	sc->sc_newstate = ic->ic_newstate;
    741       1.1  christos 	ic->ic_newstate = urtw_newstate;
    742  1.15.2.2    martin 
    743  1.15.2.2    martin 	/* XXX media locking needs revisiting */
    744  1.15.2.2    martin 	mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB);
    745  1.15.2.2    martin 	ieee80211_media_init_with_lock(ic,
    746  1.15.2.2    martin 	    urtw_media_change, ieee80211_media_status, &sc->sc_media_mtx);
    747       1.1  christos 
    748       1.1  christos 	bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
    749       1.1  christos 	    sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
    750       1.1  christos 	    &sc->sc_drvbpf);
    751       1.1  christos 
    752       1.7     skrll 	sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
    753       1.1  christos 	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
    754       1.1  christos 	sc->sc_rxtap.wr_ihdr.it_present = htole32(URTW_RX_RADIOTAP_PRESENT);
    755       1.1  christos 
    756       1.7     skrll 	sc->sc_txtap_len = sizeof(sc->sc_txtapu);
    757       1.1  christos 	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
    758       1.1  christos 	sc->sc_txtap.wt_ihdr.it_present = htole32(URTW_TX_RADIOTAP_PRESENT);
    759       1.1  christos 
    760      1.11   msaitoh 	aprint_normal(", address %s\n", ether_sprintf(ic->ic_myaddr));
    761       1.1  christos 
    762       1.1  christos 	ieee80211_announce(ic);
    763       1.1  christos 
    764       1.1  christos 	return;
    765       1.1  christos fail:
    766      1.11   msaitoh 	aprint_error(": %s failed!\n", __func__);
    767       1.1  christos 	sc->sc_dying = true;
    768       1.1  christos }
    769       1.1  christos 
    770  1.15.2.2    martin static int
    771       1.1  christos urtw_detach(device_t self, int flags)
    772       1.1  christos {
    773       1.1  christos 	struct urtw_softc *sc = device_private(self);
    774       1.1  christos 	struct ifnet *ifp = &sc->sc_if;
    775       1.1  christos 	int s;
    776       1.1  christos 
    777       1.1  christos 	s = splusb();
    778       1.1  christos 
    779       1.1  christos 	sc->sc_dying = true;
    780       1.1  christos 
    781  1.15.2.1  christos 	callout_halt(&sc->scan_to, NULL);
    782  1.15.2.1  christos 	callout_halt(&sc->sc_led_ch, NULL);
    783       1.1  christos 	callout_destroy(&sc->scan_to);
    784       1.1  christos 	callout_destroy(&sc->sc_led_ch);
    785       1.1  christos 
    786  1.15.2.1  christos 	usb_rem_task_wait(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER, NULL);
    787  1.15.2.1  christos 	usb_rem_task_wait(sc->sc_udev, &sc->sc_ledtask, USB_TASKQ_DRIVER,
    788  1.15.2.1  christos 	    NULL);
    789       1.1  christos 
    790       1.1  christos 	if (ifp->if_softc != NULL) {
    791       1.1  christos 		bpf_detach(ifp);
    792       1.1  christos 		ieee80211_ifdetach(&sc->sc_ic);	/* free all nodes */
    793       1.1  christos 		if_detach(ifp);
    794       1.1  christos 	}
    795       1.1  christos 
    796       1.1  christos 	/* abort and free xfers */
    797       1.1  christos 	urtw_free_tx_data_list(sc);
    798       1.1  christos 	urtw_free_rx_data_list(sc);
    799       1.1  christos 	urtw_close_pipes(sc);
    800       1.1  christos 
    801       1.1  christos 	splx(s);
    802       1.1  christos 
    803       1.7     skrll 	return 0;
    804       1.1  christos }
    805       1.1  christos 
    806  1.15.2.2    martin static int
    807       1.1  christos urtw_activate(device_t self, enum devact act)
    808       1.1  christos {
    809       1.1  christos 	struct urtw_softc *sc = device_private(self);
    810       1.1  christos 
    811       1.1  christos 	switch (act) {
    812       1.1  christos 	case DVACT_DEACTIVATE:
    813       1.1  christos 		sc->sc_dying = true;
    814       1.1  christos 		break;
    815       1.1  christos 	}
    816       1.1  christos 
    817       1.7     skrll 	return 0;
    818       1.1  christos }
    819       1.1  christos 
    820  1.15.2.2    martin static usbd_status
    821       1.1  christos urtw_close_pipes(struct urtw_softc *sc)
    822       1.1  christos {
    823       1.1  christos 	usbd_status error = 0;
    824       1.1  christos 
    825       1.1  christos 	if (sc->sc_rxpipe != NULL) {
    826       1.1  christos 		error = usbd_close_pipe(sc->sc_rxpipe);
    827       1.1  christos 		if (error != 0)
    828       1.1  christos 			goto fail;
    829       1.1  christos 		sc->sc_rxpipe = NULL;
    830       1.1  christos 	}
    831       1.1  christos 	if (sc->sc_txpipe_low != NULL) {
    832       1.1  christos 		error = usbd_close_pipe(sc->sc_txpipe_low);
    833       1.1  christos 		if (error != 0)
    834       1.1  christos 			goto fail;
    835       1.1  christos 		sc->sc_txpipe_low = NULL;
    836       1.1  christos 	}
    837       1.1  christos 	if (sc->sc_txpipe_normal != NULL) {
    838       1.1  christos 		error = usbd_close_pipe(sc->sc_txpipe_normal);
    839       1.1  christos 		if (error != 0)
    840       1.1  christos 			goto fail;
    841       1.1  christos 		sc->sc_txpipe_normal = NULL;
    842       1.1  christos 	}
    843       1.1  christos fail:
    844       1.7     skrll 	return error;
    845       1.1  christos }
    846       1.1  christos 
    847  1.15.2.2    martin static usbd_status
    848       1.1  christos urtw_open_pipes(struct urtw_softc *sc)
    849       1.1  christos {
    850       1.1  christos 	usbd_status error;
    851       1.1  christos 
    852       1.1  christos 	/*
    853       1.1  christos 	 * NB: there is no way to distinguish each pipes so we need to hardcode
    854       1.1  christos 	 * pipe numbers
    855       1.1  christos 	 */
    856       1.1  christos 
    857       1.1  christos 	/* tx pipe - low priority packets */
    858       1.1  christos 	if (sc->sc_hwrev & URTW_HWREV_8187)
    859       1.1  christos 		error = usbd_open_pipe(sc->sc_iface, 0x2,
    860       1.1  christos 		    USBD_EXCLUSIVE_USE, &sc->sc_txpipe_low);
    861       1.1  christos 	else
    862       1.1  christos 		error = usbd_open_pipe(sc->sc_iface, 0x6,
    863       1.1  christos 		    USBD_EXCLUSIVE_USE, &sc->sc_txpipe_low);
    864       1.1  christos 	if (error != 0) {
    865       1.1  christos 		printf("%s: could not open Tx low pipe: %s\n",
    866       1.1  christos 		    device_xname(sc->sc_dev), usbd_errstr(error));
    867       1.1  christos 		goto fail;
    868       1.1  christos 	}
    869       1.1  christos 	/* tx pipe - normal priority packets */
    870       1.1  christos 	if (sc->sc_hwrev & URTW_HWREV_8187)
    871       1.1  christos 		error = usbd_open_pipe(sc->sc_iface, 0x3,
    872       1.1  christos 		    USBD_EXCLUSIVE_USE, &sc->sc_txpipe_normal);
    873       1.1  christos 	else
    874       1.1  christos 		error = usbd_open_pipe(sc->sc_iface, 0x7,
    875       1.1  christos 		    USBD_EXCLUSIVE_USE, &sc->sc_txpipe_normal);
    876       1.1  christos 	if (error != 0) {
    877       1.1  christos 		printf("%s: could not open Tx normal pipe: %s\n",
    878       1.1  christos 		    device_xname(sc->sc_dev), usbd_errstr(error));
    879       1.1  christos 		goto fail;
    880       1.1  christos 	}
    881       1.1  christos 	/* rx pipe */
    882       1.1  christos 	if (sc->sc_hwrev & URTW_HWREV_8187)
    883       1.1  christos 		error = usbd_open_pipe(sc->sc_iface, 0x81,
    884       1.1  christos 		    USBD_EXCLUSIVE_USE, &sc->sc_rxpipe);
    885       1.1  christos 	else
    886       1.1  christos 		error = usbd_open_pipe(sc->sc_iface, 0x83,
    887       1.1  christos 		    USBD_EXCLUSIVE_USE, &sc->sc_rxpipe);
    888       1.1  christos 	if (error != 0) {
    889       1.1  christos 		printf("%s: could not open Rx pipe: %s\n",
    890       1.1  christos 		    device_xname(sc->sc_dev), usbd_errstr(error));
    891       1.1  christos 		goto fail;
    892       1.1  christos 	}
    893       1.1  christos 
    894       1.7     skrll 	return 0;
    895       1.1  christos fail:
    896       1.1  christos 	(void)urtw_close_pipes(sc);
    897       1.7     skrll 	return error;
    898       1.1  christos }
    899       1.1  christos 
    900  1.15.2.2    martin static int
    901       1.1  christos urtw_alloc_rx_data_list(struct urtw_softc *sc)
    902       1.1  christos {
    903       1.1  christos 	int i, error;
    904       1.1  christos 
    905       1.1  christos 	for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++) {
    906       1.1  christos 		struct urtw_rx_data *data = &sc->sc_rx_data[i];
    907       1.1  christos 
    908       1.1  christos 		data->sc = sc;
    909       1.1  christos 
    910       1.7     skrll 		error = usbd_create_xfer(sc->sc_rxpipe, MCLBYTES,
    911      1.14     skrll 		    0, 0, &data->xfer);
    912       1.7     skrll 		if (error) {
    913       1.7     skrll 
    914       1.1  christos 			printf("%s: could not allocate rx xfer\n",
    915       1.1  christos 			    device_xname(sc->sc_dev));
    916       1.1  christos 			error = ENOMEM;
    917       1.1  christos 			goto fail;
    918       1.1  christos 		}
    919       1.1  christos 
    920       1.1  christos 		MGETHDR(data->m, M_DONTWAIT, MT_DATA);
    921       1.1  christos 		if (data->m == NULL) {
    922       1.1  christos 			printf("%s: could not allocate rx mbuf\n",
    923       1.1  christos 			    device_xname(sc->sc_dev));
    924       1.1  christos 			error = ENOMEM;
    925       1.1  christos 			goto fail;
    926       1.1  christos 		}
    927       1.1  christos 		MCLGET(data->m, M_DONTWAIT);
    928       1.1  christos 		if (!(data->m->m_flags & M_EXT)) {
    929       1.1  christos 			printf("%s: could not allocate rx mbuf cluster\n",
    930       1.1  christos 			    device_xname(sc->sc_dev));
    931       1.1  christos 			error = ENOMEM;
    932       1.1  christos 			goto fail;
    933       1.1  christos 		}
    934       1.1  christos 		data->buf = mtod(data->m, uint8_t *);
    935       1.1  christos 	}
    936       1.1  christos 
    937       1.7     skrll 	return 0;
    938       1.1  christos 
    939       1.1  christos fail:
    940       1.1  christos 	urtw_free_rx_data_list(sc);
    941       1.7     skrll 	return error;
    942       1.1  christos }
    943       1.1  christos 
    944  1.15.2.2    martin static void
    945       1.1  christos urtw_free_rx_data_list(struct urtw_softc *sc)
    946       1.1  christos {
    947       1.1  christos 	int i;
    948       1.1  christos 
    949       1.1  christos 	/* Make sure no transfers are pending. */
    950       1.1  christos 	if (sc->sc_rxpipe != NULL)
    951       1.1  christos 		usbd_abort_pipe(sc->sc_rxpipe);
    952       1.1  christos 
    953       1.1  christos 	for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++) {
    954       1.1  christos 		struct urtw_rx_data *data = &sc->sc_rx_data[i];
    955       1.1  christos 
    956       1.1  christos 		if (data->xfer != NULL) {
    957       1.7     skrll 			usbd_destroy_xfer(data->xfer);
    958       1.1  christos 			data->xfer = NULL;
    959       1.1  christos 		}
    960       1.1  christos 		if (data->m != NULL) {
    961       1.1  christos 			m_freem(data->m);
    962       1.1  christos 			data->m = NULL;
    963       1.1  christos 		}
    964       1.1  christos 	}
    965       1.1  christos }
    966       1.1  christos 
    967  1.15.2.2    martin static int
    968       1.1  christos urtw_alloc_tx_data_list(struct urtw_softc *sc)
    969       1.1  christos {
    970       1.1  christos 	int i, error;
    971       1.1  christos 
    972       1.7     skrll 	for (size_t j = 0; j < URTW_PRIORITY_MAX; j++) {
    973       1.7     skrll 		for (i = 0; i < URTW_TX_DATA_LIST_COUNT; i++) {
    974       1.7     skrll 			struct urtw_tx_data *data = &sc->sc_tx_data[j][i];
    975       1.1  christos 
    976       1.7     skrll 			data->sc = sc;
    977       1.7     skrll 			data->ni = NULL;
    978       1.7     skrll 
    979       1.7     skrll 			error = usbd_create_xfer((j == URTW_PRIORITY_LOW) ?
    980       1.7     skrll 			    sc->sc_txpipe_low : sc->sc_txpipe_normal,
    981       1.7     skrll 			    URTW_TX_MAXSIZE, USBD_FORCE_SHORT_XFER, 0,
    982       1.7     skrll 			    &data->xfer);
    983       1.7     skrll 			if (error) {
    984       1.7     skrll 				printf("%s: could not allocate tx xfer\n",
    985       1.7     skrll 				    device_xname(sc->sc_dev));
    986       1.7     skrll 				goto fail;
    987       1.7     skrll 			}
    988       1.1  christos 
    989       1.7     skrll 			data->buf = usbd_get_buffer(data->xfer);
    990       1.1  christos 
    991       1.7     skrll 			if (((unsigned long)data->buf) % 4)
    992       1.7     skrll 				printf("%s: warn: unaligned buffer %p\n",
    993       1.7     skrll 				    device_xname(sc->sc_dev), data->buf);
    994       1.1  christos 		}
    995       1.1  christos 	}
    996       1.1  christos 
    997       1.7     skrll 	return 0;
    998       1.1  christos 
    999       1.1  christos fail:
   1000       1.1  christos 	urtw_free_tx_data_list(sc);
   1001       1.7     skrll 	return error;
   1002       1.1  christos }
   1003       1.1  christos 
   1004  1.15.2.2    martin static void
   1005       1.1  christos urtw_free_tx_data_list(struct urtw_softc *sc)
   1006       1.1  christos {
   1007       1.1  christos 	int i;
   1008       1.1  christos 
   1009       1.1  christos 	/* Make sure no transfers are pending. */
   1010       1.1  christos 	if (sc->sc_txpipe_low != NULL)
   1011       1.1  christos 		usbd_abort_pipe(sc->sc_txpipe_low);
   1012       1.1  christos 	if (sc->sc_txpipe_normal != NULL)
   1013       1.1  christos 		usbd_abort_pipe(sc->sc_txpipe_normal);
   1014       1.1  christos 
   1015       1.7     skrll 	for (size_t j = 0; j < URTW_PRIORITY_MAX; j++) {
   1016       1.7     skrll 		for (i = 0; i < URTW_TX_DATA_LIST_COUNT; i++) {
   1017       1.7     skrll 			struct urtw_tx_data *data = &sc->sc_tx_data[j][i];
   1018       1.7     skrll 
   1019       1.7     skrll 			if (data->xfer != NULL) {
   1020       1.7     skrll 				usbd_destroy_xfer(data->xfer);
   1021       1.7     skrll 				data->xfer = NULL;
   1022       1.7     skrll 			}
   1023       1.7     skrll 			if (data->ni != NULL) {
   1024       1.7     skrll 				ieee80211_free_node(data->ni);
   1025       1.7     skrll 				data->ni = NULL;
   1026       1.7     skrll 			}
   1027       1.1  christos 		}
   1028       1.1  christos 	}
   1029       1.1  christos }
   1030       1.1  christos 
   1031  1.15.2.2    martin static int
   1032       1.1  christos urtw_media_change(struct ifnet *ifp)
   1033       1.1  christos {
   1034       1.1  christos 	int error;
   1035       1.1  christos 
   1036       1.1  christos 	error = ieee80211_media_change(ifp);
   1037       1.1  christos 	if (error != ENETRESET)
   1038       1.7     skrll 		return error;
   1039       1.1  christos 
   1040       1.1  christos 	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
   1041       1.1  christos 	    (IFF_UP | IFF_RUNNING))
   1042       1.1  christos 		ifp->if_init(ifp);
   1043       1.1  christos 
   1044       1.7     skrll 	return 0;
   1045       1.1  christos }
   1046       1.1  christos 
   1047  1.15.2.2    martin static int
   1048       1.1  christos urtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
   1049       1.1  christos {
   1050       1.1  christos 	struct urtw_softc *sc = ic->ic_ifp->if_softc;
   1051       1.1  christos 
   1052  1.15.2.1  christos 	/*
   1053  1.15.2.1  christos 	 * XXXSMP: This does not wait for the task, if it is in flight,
   1054  1.15.2.1  christos 	 * to complete.  If this code works at all, it must rely on the
   1055  1.15.2.1  christos 	 * kernel lock to serialize with the USB task thread.
   1056  1.15.2.1  christos 	 */
   1057       1.1  christos 	usb_rem_task(sc->sc_udev, &sc->sc_task);
   1058       1.1  christos 	callout_stop(&sc->scan_to);
   1059       1.1  christos 
   1060       1.1  christos 	/* do it in a process context */
   1061       1.1  christos 	sc->sc_state = nstate;
   1062       1.1  christos 	sc->sc_arg = arg;
   1063       1.1  christos 	usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
   1064       1.1  christos 
   1065       1.7     skrll 	return 0;
   1066       1.1  christos }
   1067       1.1  christos 
   1068  1.15.2.2    martin static usbd_status
   1069       1.1  christos urtw_led_init(struct urtw_softc *sc)
   1070       1.1  christos {
   1071       1.1  christos 	uint32_t rev;
   1072       1.1  christos 	usbd_status error;
   1073       1.1  christos 
   1074       1.1  christos 	urtw_read8_m(sc, URTW_PSR, &sc->sc_psr);
   1075       1.1  christos 	error = urtw_eprom_read32(sc, URTW_EPROM_SWREV, &rev);
   1076       1.1  christos 	if (error != 0)
   1077       1.1  christos 		goto fail;
   1078       1.1  christos 
   1079       1.1  christos 	switch (rev & URTW_EPROM_CID_MASK) {
   1080       1.1  christos 	case URTW_EPROM_CID_ALPHA0:
   1081       1.1  christos 		sc->sc_strategy = URTW_SW_LED_MODE1;
   1082       1.1  christos 		break;
   1083       1.1  christos 	case URTW_EPROM_CID_SERCOMM_PS:
   1084       1.1  christos 		sc->sc_strategy = URTW_SW_LED_MODE3;
   1085       1.1  christos 		break;
   1086       1.1  christos 	case URTW_EPROM_CID_HW_LED:
   1087       1.1  christos 		sc->sc_strategy = URTW_HW_LED;
   1088       1.1  christos 		break;
   1089       1.1  christos 	case URTW_EPROM_CID_RSVD0:
   1090       1.1  christos 	case URTW_EPROM_CID_RSVD1:
   1091       1.1  christos 	default:
   1092       1.1  christos 		sc->sc_strategy = URTW_SW_LED_MODE0;
   1093       1.1  christos 		break;
   1094       1.1  christos 	}
   1095       1.1  christos 
   1096       1.1  christos 	sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0;
   1097       1.1  christos 
   1098       1.1  christos fail:
   1099       1.7     skrll 	return error;
   1100       1.1  christos }
   1101       1.1  christos 
   1102  1.15.2.2    martin static usbd_status
   1103       1.1  christos urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index,
   1104       1.1  christos     uint16_t data)
   1105       1.1  christos {
   1106       1.1  christos 	usb_device_request_t req;
   1107       1.1  christos 
   1108       1.1  christos 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
   1109       1.1  christos 	req.bRequest = URTW_8187_SETREGS_REQ;
   1110       1.1  christos 	USETW(req.wValue, addr);
   1111       1.1  christos 	USETW(req.wIndex, index);
   1112       1.1  christos 	USETW(req.wLength, sizeof(uint16_t));
   1113       1.1  christos 
   1114       1.7     skrll 	return usbd_do_request(sc->sc_udev, &req, &data);
   1115       1.1  christos }
   1116       1.1  christos 
   1117  1.15.2.2    martin static usbd_status
   1118       1.1  christos urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data)
   1119       1.1  christos {
   1120       1.1  christos 	int i;
   1121       1.1  christos 	int16_t bit;
   1122       1.1  christos 	uint8_t rlen = 12, wlen = 6;
   1123       1.1  christos 	uint16_t o1, o2, o3, tmp;
   1124       1.1  christos 	uint32_t d2w = ((uint32_t)(addr & 0x1f)) << 27;
   1125       1.1  christos 	uint32_t mask = 0x80000000, value = 0;
   1126       1.1  christos 	usbd_status error;
   1127       1.1  christos 
   1128       1.1  christos 	urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &o1);
   1129       1.1  christos 	urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &o2);
   1130       1.1  christos 	urtw_read16_m(sc, URTW_RF_PINS_SELECT, &o3);
   1131       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2 | 0xf);
   1132       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3 | 0xf);
   1133       1.1  christos 	o1 &= ~0xf;
   1134       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN);
   1135       1.1  christos 	DELAY(5);
   1136       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1);
   1137       1.1  christos 	DELAY(5);
   1138       1.1  christos 
   1139       1.1  christos 	for (i = 0; i < (wlen / 2); i++, mask = mask >> 1) {
   1140       1.1  christos 		bit = ((d2w & mask) != 0) ? 1 : 0;
   1141       1.1  christos 
   1142       1.1  christos 		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
   1143       1.1  christos 		DELAY(2);
   1144       1.1  christos 		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
   1145       1.1  christos 		    URTW_BB_HOST_BANG_CLK);
   1146       1.1  christos 		DELAY(2);
   1147       1.1  christos 		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
   1148       1.1  christos 		    URTW_BB_HOST_BANG_CLK);
   1149       1.1  christos 		DELAY(2);
   1150       1.1  christos 		mask = mask >> 1;
   1151       1.1  christos 		if (i == 2)
   1152       1.1  christos 			break;
   1153       1.1  christos 		bit = ((d2w & mask) != 0) ? 1 : 0;
   1154       1.1  christos 		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
   1155       1.1  christos 		    URTW_BB_HOST_BANG_CLK);
   1156       1.1  christos 		DELAY(2);
   1157       1.1  christos 		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
   1158       1.1  christos 		    URTW_BB_HOST_BANG_CLK);
   1159       1.1  christos 		DELAY(2);
   1160       1.1  christos 		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
   1161       1.1  christos 		DELAY(1);
   1162       1.1  christos 	}
   1163       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW |
   1164       1.1  christos 	    URTW_BB_HOST_BANG_CLK);
   1165       1.1  christos 	DELAY(2);
   1166       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW);
   1167       1.1  christos 	DELAY(2);
   1168       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_RW);
   1169       1.1  christos 	DELAY(2);
   1170       1.1  christos 
   1171       1.1  christos 	mask = 0x800;
   1172       1.1  christos 	for (i = 0; i < rlen; i++, mask = mask >> 1) {
   1173       1.1  christos 		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
   1174       1.1  christos 		    o1 | URTW_BB_HOST_BANG_RW);
   1175       1.1  christos 		DELAY(2);
   1176       1.1  christos 		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
   1177       1.1  christos 		    o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
   1178       1.1  christos 		DELAY(2);
   1179       1.1  christos 		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
   1180       1.1  christos 		    o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
   1181       1.1  christos 		DELAY(2);
   1182       1.1  christos 		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
   1183       1.1  christos 		    o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
   1184       1.1  christos 		DELAY(2);
   1185       1.1  christos 
   1186       1.1  christos 		urtw_read16_m(sc, URTW_RF_PINS_INPUT, &tmp);
   1187       1.1  christos 		value |= ((tmp & URTW_BB_HOST_BANG_CLK) ? mask : 0);
   1188       1.1  christos 		urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
   1189       1.1  christos 		    o1 | URTW_BB_HOST_BANG_RW);
   1190       1.1  christos 		DELAY(2);
   1191       1.1  christos 	}
   1192       1.1  christos 
   1193       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN |
   1194       1.1  christos 	    URTW_BB_HOST_BANG_RW);
   1195       1.1  christos 	DELAY(2);
   1196       1.1  christos 
   1197       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2);
   1198       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3);
   1199       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x3a0);
   1200       1.1  christos 
   1201       1.1  christos 	if (data != NULL)
   1202       1.1  christos 		*data = value;
   1203       1.1  christos fail:
   1204       1.7     skrll 	return error;
   1205       1.1  christos }
   1206       1.1  christos 
   1207  1.15.2.2    martin static usbd_status
   1208       1.1  christos urtw_8225_write_c(struct urtw_softc *sc, uint8_t addr, uint16_t data)
   1209       1.1  christos {
   1210       1.1  christos 	uint16_t d80, d82, d84;
   1211       1.1  christos 	usbd_status error;
   1212       1.1  christos 
   1213       1.1  christos 	urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &d80);
   1214       1.1  christos 	d80 &= 0xfff3;
   1215       1.1  christos 	urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &d82);
   1216       1.1  christos 	urtw_read16_m(sc, URTW_RF_PINS_SELECT, &d84);
   1217       1.1  christos 	d84 &= 0xfff0;
   1218       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_ENABLE, d82 | 0x0007);
   1219       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84 | 0x0007);
   1220       1.1  christos 	DELAY(10);
   1221       1.1  christos 
   1222       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
   1223       1.1  christos 	DELAY(2);
   1224       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80);
   1225       1.1  christos 	DELAY(10);
   1226       1.1  christos 
   1227       1.1  christos 	error = urtw_8225_write_s16(sc, addr, 0x8225, data);
   1228       1.1  christos 	if (error != 0)
   1229       1.1  christos 		goto fail;
   1230       1.1  christos 
   1231       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
   1232       1.1  christos 	DELAY(10);
   1233       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
   1234       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84);
   1235       1.1  christos 	usbd_delay_ms(sc->sc_udev, 2);
   1236       1.1  christos fail:
   1237       1.7     skrll 	return error;
   1238       1.1  christos }
   1239       1.1  christos 
   1240  1.15.2.2    martin static usbd_status
   1241       1.1  christos urtw_8225_isv2(struct urtw_softc *sc, int *ret)
   1242       1.1  christos {
   1243       1.1  christos 	uint32_t data;
   1244       1.1  christos 	usbd_status error;
   1245       1.1  christos 
   1246       1.1  christos 	*ret = 1;
   1247       1.1  christos 
   1248       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x0080);
   1249       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x0080);
   1250       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x0080);
   1251       1.1  christos 	usbd_delay_ms(sc->sc_udev, 500);
   1252       1.1  christos 
   1253       1.1  christos 	urtw_8225_write(sc, 0x0, 0x1b7);
   1254       1.1  christos 
   1255       1.1  christos 	error = urtw_8225_read(sc, 0x8, &data);
   1256       1.1  christos 	if (error != 0)
   1257       1.1  christos 		goto fail;
   1258       1.1  christos 	if (data != 0x588)
   1259       1.1  christos 		*ret = 0;
   1260       1.1  christos 	else {
   1261       1.1  christos 		error = urtw_8225_read(sc, 0x9, &data);
   1262       1.1  christos 		if (error != 0)
   1263       1.1  christos 			goto fail;
   1264       1.1  christos 		if (data != 0x700)
   1265       1.1  christos 			*ret = 0;
   1266       1.1  christos 	}
   1267       1.1  christos 
   1268       1.1  christos 	urtw_8225_write(sc, 0x0, 0xb7);
   1269       1.1  christos fail:
   1270       1.7     skrll 	return error;
   1271       1.1  christos }
   1272       1.1  christos 
   1273  1.15.2.2    martin static usbd_status
   1274       1.1  christos urtw_get_rfchip(struct urtw_softc *sc)
   1275       1.1  christos {
   1276       1.1  christos 	struct urtw_rf *rf = &sc->sc_rf;
   1277       1.1  christos 	int ret;
   1278       1.1  christos 	uint32_t data;
   1279       1.1  christos 	usbd_status error;
   1280       1.1  christos 
   1281       1.1  christos 	rf->rf_sc = sc;
   1282       1.1  christos 
   1283       1.1  christos 	if (sc->sc_hwrev & URTW_HWREV_8187) {
   1284       1.1  christos 		error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data);
   1285       1.1  christos 		if (error != 0)
   1286       1.1  christos 			panic("unsupported RF chip");
   1287       1.1  christos 			/* NOTREACHED */
   1288       1.1  christos 		switch (data & 0xff) {
   1289       1.1  christos 		case URTW_EPROM_RFCHIPID_RTL8225U:
   1290       1.1  christos 			error = urtw_8225_isv2(sc, &ret);
   1291       1.1  christos 			if (error != 0)
   1292       1.1  christos 				goto fail;
   1293       1.1  christos 			if (ret == 0) {
   1294       1.1  christos 				rf->init = urtw_8225_rf_init;
   1295       1.1  christos 				rf->set_chan = urtw_8225_rf_set_chan;
   1296       1.1  christos 				rf->set_sens = urtw_8225_rf_set_sens;
   1297       1.1  christos 				printf(", RFv1");
   1298       1.1  christos 			} else {
   1299       1.1  christos 				rf->init = urtw_8225v2_rf_init;
   1300       1.1  christos 				rf->set_chan = urtw_8225v2_rf_set_chan;
   1301       1.1  christos 				rf->set_sens = NULL;
   1302       1.1  christos 				printf(", RFv2");
   1303       1.1  christos 			}
   1304       1.1  christos 			break;
   1305       1.1  christos 		default:
   1306       1.1  christos 			goto fail;
   1307       1.1  christos 		}
   1308       1.1  christos 	} else {
   1309       1.1  christos 		rf->init = urtw_8225v2_b_rf_init;
   1310       1.1  christos 		rf->set_chan = urtw_8225v2_b_rf_set_chan;
   1311       1.1  christos 		rf->set_sens = NULL;
   1312       1.1  christos 	}
   1313       1.1  christos 
   1314       1.1  christos 	rf->max_sens = URTW_8225_RF_MAX_SENS;
   1315       1.1  christos 	rf->sens = URTW_8225_RF_DEF_SENS;
   1316       1.1  christos 
   1317       1.7     skrll 	return 0;
   1318       1.1  christos 
   1319       1.1  christos fail:
   1320       1.1  christos 	panic("unsupported RF chip %d", data & 0xff);
   1321       1.1  christos 	/* NOTREACHED */
   1322       1.1  christos }
   1323       1.1  christos 
   1324  1.15.2.2    martin static usbd_status
   1325       1.1  christos urtw_get_txpwr(struct urtw_softc *sc)
   1326       1.1  christos {
   1327       1.1  christos 	int i, j;
   1328       1.1  christos 	uint32_t data;
   1329       1.1  christos 	usbd_status error;
   1330       1.1  christos 
   1331       1.1  christos 	error = urtw_eprom_read32(sc, URTW_EPROM_TXPW_BASE, &data);
   1332       1.1  christos 	if (error != 0)
   1333       1.1  christos 		goto fail;
   1334       1.1  christos 	sc->sc_txpwr_cck_base = data & 0xf;
   1335       1.1  christos 	sc->sc_txpwr_ofdm_base = (data >> 4) & 0xf;
   1336       1.1  christos 
   1337       1.1  christos 	for (i = 1, j = 0; i < 6; i += 2, j++) {
   1338       1.1  christos 		error = urtw_eprom_read32(sc, URTW_EPROM_TXPW0 + j, &data);
   1339       1.1  christos 		if (error != 0)
   1340       1.1  christos 			goto fail;
   1341       1.1  christos 		sc->sc_txpwr_cck[i] = data & 0xf;
   1342       1.1  christos 		sc->sc_txpwr_cck[i + 1] = (data & 0xf00) >> 8;
   1343       1.1  christos 		sc->sc_txpwr_ofdm[i] = (data & 0xf0) >> 4;
   1344       1.1  christos 		sc->sc_txpwr_ofdm[i + 1] = (data & 0xf000) >> 12;
   1345       1.1  christos 	}
   1346       1.1  christos 	for (i = 1, j = 0; i < 4; i += 2, j++) {
   1347       1.1  christos 		error = urtw_eprom_read32(sc, URTW_EPROM_TXPW1 + j, &data);
   1348       1.1  christos 		if (error != 0)
   1349       1.1  christos 			goto fail;
   1350       1.1  christos 		sc->sc_txpwr_cck[i + 6] = data & 0xf;
   1351       1.1  christos 		sc->sc_txpwr_cck[i + 6 + 1] = (data & 0xf00) >> 8;
   1352       1.1  christos 		sc->sc_txpwr_ofdm[i + 6] = (data & 0xf0) >> 4;
   1353       1.1  christos 		sc->sc_txpwr_ofdm[i + 6 + 1] = (data & 0xf000) >> 12;
   1354       1.1  christos 	}
   1355       1.1  christos 	if (sc->sc_hwrev & URTW_HWREV_8187) {
   1356       1.1  christos 		for (i = 1, j = 0; i < 4; i += 2, j++) {
   1357       1.1  christos 			error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2 + j,
   1358       1.1  christos 			    &data);
   1359       1.1  christos 			if (error != 0)
   1360       1.1  christos 				goto fail;
   1361       1.1  christos 			sc->sc_txpwr_cck[i + 6 + 4] = data & 0xf;
   1362       1.1  christos 			sc->sc_txpwr_cck[i + 6 + 4 + 1] = (data & 0xf00) >> 8;
   1363       1.1  christos 			sc->sc_txpwr_ofdm[i + 6 + 4] = (data & 0xf0) >> 4;
   1364       1.1  christos 			sc->sc_txpwr_ofdm[i + 6 + 4 + 1] =
   1365       1.1  christos 			    (data & 0xf000) >> 12;
   1366       1.1  christos 		}
   1367       1.1  christos 	} else {
   1368       1.1  christos 		/* Channel 11. */
   1369       1.1  christos 		error = urtw_eprom_read32(sc, 0x1b, &data);
   1370       1.1  christos 		if (error != 0)
   1371       1.1  christos 			goto fail;
   1372       1.1  christos 		sc->sc_txpwr_cck[11] = data & 0xf;
   1373       1.1  christos 		sc->sc_txpwr_ofdm[11] = (data & 0xf0) >> 4;
   1374       1.1  christos 
   1375       1.1  christos 		/* Channel 12. */
   1376       1.1  christos 		error = urtw_eprom_read32(sc, 0xa, &data);
   1377       1.1  christos 		if (error != 0)
   1378       1.1  christos 			goto fail;
   1379       1.1  christos 		sc->sc_txpwr_cck[12] = data & 0xf;
   1380       1.1  christos 		sc->sc_txpwr_ofdm[12] = (data & 0xf0) >> 4;
   1381       1.1  christos 
   1382       1.1  christos 		/* Channel 13, 14. */
   1383       1.1  christos 		error = urtw_eprom_read32(sc, 0x1c, &data);
   1384       1.1  christos 		if (error != 0)
   1385       1.1  christos 			goto fail;
   1386       1.1  christos 		sc->sc_txpwr_cck[13] = data & 0xf;
   1387       1.1  christos 		sc->sc_txpwr_ofdm[13] = (data & 0xf0) >> 4;
   1388       1.1  christos 		sc->sc_txpwr_cck[14] = (data & 0xf00) >> 8;
   1389       1.1  christos 		sc->sc_txpwr_ofdm[14] = (data & 0xf000) >> 12;
   1390       1.1  christos 	}
   1391       1.1  christos fail:
   1392       1.7     skrll 	return error;
   1393       1.1  christos }
   1394       1.1  christos 
   1395  1.15.2.2    martin static usbd_status
   1396       1.1  christos urtw_get_macaddr(struct urtw_softc *sc)
   1397       1.1  christos {
   1398       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   1399       1.1  christos 	usbd_status error;
   1400       1.1  christos 	uint32_t data;
   1401       1.1  christos 
   1402       1.1  christos 	error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
   1403       1.1  christos 	if (error != 0)
   1404       1.1  christos 		goto fail;
   1405       1.1  christos 	ic->ic_myaddr[0] = data & 0xff;
   1406       1.1  christos 	ic->ic_myaddr[1] = (data & 0xff00) >> 8;
   1407       1.1  christos 	error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
   1408       1.1  christos 	if (error != 0)
   1409       1.1  christos 		goto fail;
   1410       1.1  christos 	ic->ic_myaddr[2] = data & 0xff;
   1411       1.1  christos 	ic->ic_myaddr[3] = (data & 0xff00) >> 8;
   1412       1.1  christos 	error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
   1413       1.1  christos 	if (error != 0)
   1414       1.1  christos 		goto fail;
   1415       1.1  christos 	ic->ic_myaddr[4] = data & 0xff;
   1416       1.1  christos 	ic->ic_myaddr[5] = (data & 0xff00) >> 8;
   1417       1.1  christos fail:
   1418       1.7     skrll 	return error;
   1419       1.1  christos }
   1420       1.1  christos 
   1421  1.15.2.2    martin static usbd_status
   1422       1.1  christos urtw_eprom_read32(struct urtw_softc *sc, uint32_t addr, uint32_t *data)
   1423       1.1  christos {
   1424       1.1  christos #define URTW_READCMD_LEN		3
   1425       1.1  christos 	int addrlen, i;
   1426       1.1  christos 	int16_t addrstr[8], data16, readcmd[] = { 1, 1, 0 };
   1427       1.1  christos 	usbd_status error;
   1428       1.1  christos 
   1429       1.1  christos 	/* NB: make sure the buffer is initialized */
   1430       1.1  christos 	*data = 0;
   1431       1.1  christos 
   1432       1.1  christos 	/* enable EPROM programming */
   1433       1.1  christos 	urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_PROGRAM_MODE);
   1434       1.1  christos 	DELAY(URTW_EPROM_DELAY);
   1435       1.1  christos 
   1436       1.1  christos 	error = urtw_eprom_cs(sc, URTW_EPROM_ENABLE);
   1437       1.1  christos 	if (error != 0)
   1438       1.1  christos 		goto fail;
   1439       1.1  christos 	error = urtw_eprom_ck(sc);
   1440       1.1  christos 	if (error != 0)
   1441       1.1  christos 		goto fail;
   1442       1.1  christos 	error = urtw_eprom_sendbits(sc, readcmd, URTW_READCMD_LEN);
   1443       1.1  christos 	if (error != 0)
   1444       1.1  christos 		goto fail;
   1445       1.1  christos 	if (sc->sc_epromtype == URTW_EEPROM_93C56) {
   1446       1.1  christos 		addrlen = 8;
   1447       1.1  christos 		addrstr[0] = addr & (1 << 7);
   1448       1.1  christos 		addrstr[1] = addr & (1 << 6);
   1449       1.1  christos 		addrstr[2] = addr & (1 << 5);
   1450       1.1  christos 		addrstr[3] = addr & (1 << 4);
   1451       1.1  christos 		addrstr[4] = addr & (1 << 3);
   1452       1.1  christos 		addrstr[5] = addr & (1 << 2);
   1453       1.1  christos 		addrstr[6] = addr & (1 << 1);
   1454       1.1  christos 		addrstr[7] = addr & (1 << 0);
   1455       1.1  christos 	} else {
   1456       1.1  christos 		addrlen=6;
   1457       1.1  christos 		addrstr[0] = addr & (1 << 5);
   1458       1.1  christos 		addrstr[1] = addr & (1 << 4);
   1459       1.1  christos 		addrstr[2] = addr & (1 << 3);
   1460       1.1  christos 		addrstr[3] = addr & (1 << 2);
   1461       1.1  christos 		addrstr[4] = addr & (1 << 1);
   1462       1.1  christos 		addrstr[5] = addr & (1 << 0);
   1463       1.1  christos 	}
   1464       1.1  christos 	error = urtw_eprom_sendbits(sc, addrstr, addrlen);
   1465       1.1  christos 	if (error != 0)
   1466       1.1  christos 		goto fail;
   1467       1.1  christos 
   1468       1.1  christos 	error = urtw_eprom_writebit(sc, 0);
   1469       1.1  christos 	if (error != 0)
   1470       1.1  christos 		goto fail;
   1471       1.1  christos 
   1472       1.1  christos 	for (i = 0; i < 16; i++) {
   1473       1.1  christos 		error = urtw_eprom_ck(sc);
   1474       1.1  christos 		if (error != 0)
   1475       1.1  christos 			goto fail;
   1476       1.1  christos 		error = urtw_eprom_readbit(sc, &data16);
   1477       1.1  christos 		if (error != 0)
   1478       1.1  christos 			goto fail;
   1479       1.1  christos 
   1480       1.1  christos 		(*data) |= (data16 << (15 - i));
   1481       1.1  christos 	}
   1482       1.1  christos 
   1483       1.1  christos 	error = urtw_eprom_cs(sc, URTW_EPROM_DISABLE);
   1484       1.1  christos 	if (error != 0)
   1485       1.1  christos 		goto fail;
   1486       1.1  christos 	error = urtw_eprom_ck(sc);
   1487       1.1  christos 	if (error != 0)
   1488       1.1  christos 		goto fail;
   1489       1.1  christos 
   1490       1.1  christos 	/* now disable EPROM programming */
   1491       1.1  christos 	urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_NORMAL_MODE);
   1492       1.1  christos fail:
   1493       1.7     skrll 	return error;
   1494       1.1  christos #undef URTW_READCMD_LEN
   1495       1.1  christos }
   1496       1.1  christos 
   1497  1.15.2.2    martin static usbd_status
   1498       1.1  christos urtw_eprom_readbit(struct urtw_softc *sc, int16_t *data)
   1499       1.1  christos {
   1500       1.1  christos 	uint8_t data8;
   1501       1.1  christos 	usbd_status error;
   1502       1.1  christos 
   1503       1.1  christos 	urtw_read8_m(sc, URTW_EPROM_CMD, &data8);
   1504       1.1  christos 	*data = (data8 & URTW_EPROM_READBIT) ? 1 : 0;
   1505       1.1  christos 	DELAY(URTW_EPROM_DELAY);
   1506       1.1  christos 
   1507       1.1  christos fail:
   1508       1.7     skrll 	return error;
   1509       1.1  christos }
   1510       1.1  christos 
   1511  1.15.2.2    martin static usbd_status
   1512       1.1  christos urtw_eprom_sendbits(struct urtw_softc *sc, int16_t *buf, int buflen)
   1513       1.1  christos {
   1514       1.1  christos 	int i = 0;
   1515       1.1  christos 	usbd_status error = 0;
   1516       1.1  christos 
   1517       1.1  christos 	for (i = 0; i < buflen; i++) {
   1518       1.1  christos 		error = urtw_eprom_writebit(sc, buf[i]);
   1519       1.1  christos 		if (error != 0)
   1520       1.1  christos 			goto fail;
   1521       1.1  christos 		error = urtw_eprom_ck(sc);
   1522       1.1  christos 		if (error != 0)
   1523       1.1  christos 			goto fail;
   1524       1.1  christos 	}
   1525       1.1  christos fail:
   1526       1.7     skrll 	return error;
   1527       1.1  christos }
   1528       1.1  christos 
   1529  1.15.2.2    martin static usbd_status
   1530       1.1  christos urtw_eprom_writebit(struct urtw_softc *sc, int16_t bit)
   1531       1.1  christos {
   1532       1.1  christos 	uint8_t data;
   1533       1.1  christos 	usbd_status error;
   1534       1.1  christos 
   1535       1.1  christos 	urtw_read8_m(sc, URTW_EPROM_CMD, &data);
   1536       1.1  christos 	if (bit != 0)
   1537       1.1  christos 		urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_WRITEBIT);
   1538       1.1  christos 	else
   1539       1.1  christos 		urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_WRITEBIT);
   1540       1.1  christos 	DELAY(URTW_EPROM_DELAY);
   1541       1.1  christos fail:
   1542       1.7     skrll 	return error;
   1543       1.1  christos }
   1544       1.1  christos 
   1545  1.15.2.2    martin static usbd_status
   1546       1.1  christos urtw_eprom_ck(struct urtw_softc *sc)
   1547       1.1  christos {
   1548       1.1  christos 	uint8_t data;
   1549       1.1  christos 	usbd_status error;
   1550       1.1  christos 
   1551       1.1  christos 	/* masking */
   1552       1.1  christos 	urtw_read8_m(sc, URTW_EPROM_CMD, &data);
   1553       1.1  christos 	urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CK);
   1554       1.1  christos 	DELAY(URTW_EPROM_DELAY);
   1555       1.1  christos 	/* unmasking */
   1556       1.1  christos 	urtw_read8_m(sc, URTW_EPROM_CMD, &data);
   1557       1.1  christos 	urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CK);
   1558       1.1  christos 	DELAY(URTW_EPROM_DELAY);
   1559       1.1  christos fail:
   1560       1.7     skrll 	return error;
   1561       1.1  christos }
   1562       1.1  christos 
   1563  1.15.2.2    martin static usbd_status
   1564       1.1  christos urtw_eprom_cs(struct urtw_softc *sc, int able)
   1565       1.1  christos {
   1566       1.1  christos 	uint8_t data;
   1567       1.1  christos 	usbd_status error;
   1568       1.1  christos 
   1569       1.1  christos 	urtw_read8_m(sc, URTW_EPROM_CMD, &data);
   1570       1.1  christos 	if (able == URTW_EPROM_ENABLE)
   1571       1.1  christos 		urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CS);
   1572       1.1  christos 	else
   1573       1.1  christos 		urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CS);
   1574       1.1  christos 	DELAY(URTW_EPROM_DELAY);
   1575       1.1  christos fail:
   1576       1.7     skrll 	return error;
   1577       1.1  christos }
   1578       1.1  christos 
   1579  1.15.2.2    martin static usbd_status
   1580       1.1  christos urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data, uint8_t idx)
   1581       1.1  christos {
   1582       1.1  christos 	usb_device_request_t req;
   1583       1.1  christos 	usbd_status error;
   1584       1.1  christos 
   1585       1.1  christos 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
   1586       1.1  christos 	req.bRequest = URTW_8187_GETREGS_REQ;
   1587       1.1  christos 	USETW(req.wValue, val | 0xff00);
   1588       1.1  christos 	USETW(req.wIndex, idx & 0x03);
   1589       1.1  christos 	USETW(req.wLength, sizeof(uint8_t));
   1590       1.1  christos 
   1591       1.1  christos 	error = usbd_do_request(sc->sc_udev, &req, data);
   1592       1.7     skrll 	return error;
   1593       1.1  christos }
   1594       1.1  christos 
   1595  1.15.2.2    martin static usbd_status
   1596       1.1  christos urtw_read8e(struct urtw_softc *sc, int val, uint8_t *data)
   1597       1.1  christos {
   1598       1.1  christos 	usb_device_request_t req;
   1599       1.1  christos 	usbd_status error;
   1600       1.1  christos 
   1601       1.1  christos 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
   1602       1.1  christos 	req.bRequest = URTW_8187_GETREGS_REQ;
   1603       1.1  christos 	USETW(req.wValue, val | 0xfe00);
   1604       1.1  christos 	USETW(req.wIndex, 0);
   1605       1.1  christos 	USETW(req.wLength, sizeof(uint8_t));
   1606       1.1  christos 
   1607       1.1  christos 	error = usbd_do_request(sc->sc_udev, &req, data);
   1608       1.7     skrll 	return error;
   1609       1.1  christos }
   1610       1.1  christos 
   1611  1.15.2.2    martin static usbd_status
   1612       1.1  christos urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data, uint8_t idx)
   1613       1.1  christos {
   1614       1.1  christos 	usb_device_request_t req;
   1615       1.1  christos 	usbd_status error;
   1616       1.1  christos 
   1617       1.1  christos 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
   1618       1.1  christos 	req.bRequest = URTW_8187_GETREGS_REQ;
   1619       1.1  christos 	USETW(req.wValue, val | 0xff00);
   1620       1.1  christos 	USETW(req.wIndex, idx & 0x03);
   1621       1.1  christos 	USETW(req.wLength, sizeof(uint16_t));
   1622       1.1  christos 
   1623       1.1  christos 	error = usbd_do_request(sc->sc_udev, &req, data);
   1624       1.7     skrll 	return error;
   1625       1.1  christos }
   1626       1.1  christos 
   1627  1.15.2.2    martin static usbd_status
   1628       1.1  christos urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data, uint8_t idx)
   1629       1.1  christos {
   1630       1.1  christos 	usb_device_request_t req;
   1631       1.1  christos 	usbd_status error;
   1632       1.1  christos 
   1633       1.1  christos 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
   1634       1.1  christos 	req.bRequest = URTW_8187_GETREGS_REQ;
   1635       1.1  christos 	USETW(req.wValue, val | 0xff00);
   1636       1.1  christos 	USETW(req.wIndex, idx & 0x03);
   1637       1.1  christos 	USETW(req.wLength, sizeof(uint32_t));
   1638       1.1  christos 
   1639       1.1  christos 	error = usbd_do_request(sc->sc_udev, &req, data);
   1640       1.7     skrll 	return error;
   1641       1.1  christos }
   1642       1.1  christos 
   1643  1.15.2.2    martin static usbd_status
   1644       1.1  christos urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data, uint8_t idx)
   1645       1.1  christos {
   1646       1.1  christos 	usb_device_request_t req;
   1647       1.1  christos 
   1648       1.1  christos 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
   1649       1.1  christos 	req.bRequest = URTW_8187_SETREGS_REQ;
   1650       1.1  christos 	USETW(req.wValue, val | 0xff00);
   1651       1.1  christos 	USETW(req.wIndex, idx & 0x03);
   1652       1.1  christos 	USETW(req.wLength, sizeof(uint8_t));
   1653       1.1  christos 
   1654       1.7     skrll 	return usbd_do_request(sc->sc_udev, &req, &data);
   1655       1.1  christos }
   1656       1.1  christos 
   1657  1.15.2.2    martin static usbd_status
   1658       1.1  christos urtw_write8e(struct urtw_softc *sc, int val, uint8_t data)
   1659       1.1  christos {
   1660       1.1  christos 	usb_device_request_t req;
   1661       1.1  christos 
   1662       1.1  christos 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
   1663       1.1  christos 	req.bRequest = URTW_8187_SETREGS_REQ;
   1664       1.1  christos 	USETW(req.wValue, val | 0xfe00);
   1665       1.1  christos 	USETW(req.wIndex, 0);
   1666       1.1  christos 	USETW(req.wLength, sizeof(uint8_t));
   1667       1.1  christos 
   1668       1.7     skrll 	return usbd_do_request(sc->sc_udev, &req, &data);
   1669       1.1  christos }
   1670       1.1  christos 
   1671  1.15.2.2    martin static usbd_status
   1672       1.1  christos urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data, uint8_t idx)
   1673       1.1  christos {
   1674       1.1  christos 	usb_device_request_t req;
   1675       1.1  christos 
   1676       1.1  christos 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
   1677       1.1  christos 	req.bRequest = URTW_8187_SETREGS_REQ;
   1678       1.1  christos 	USETW(req.wValue, val | 0xff00);
   1679       1.1  christos 	USETW(req.wIndex, idx & 0x03);
   1680       1.1  christos 	USETW(req.wLength, sizeof(uint16_t));
   1681       1.1  christos 
   1682       1.7     skrll 	return usbd_do_request(sc->sc_udev, &req, &data);
   1683       1.1  christos }
   1684       1.1  christos 
   1685  1.15.2.2    martin static usbd_status
   1686       1.1  christos urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data, uint8_t idx)
   1687       1.1  christos {
   1688       1.1  christos 	usb_device_request_t req;
   1689       1.1  christos 
   1690       1.1  christos 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
   1691       1.1  christos 	req.bRequest = URTW_8187_SETREGS_REQ;
   1692       1.1  christos 	USETW(req.wValue, val | 0xff00);
   1693       1.1  christos 	USETW(req.wIndex, idx & 0x03);
   1694       1.1  christos 	USETW(req.wLength, sizeof(uint32_t));
   1695       1.1  christos 
   1696       1.7     skrll 	return usbd_do_request(sc->sc_udev, &req, &data);
   1697       1.1  christos }
   1698       1.1  christos 
   1699       1.1  christos static usbd_status
   1700       1.1  christos urtw_set_mode(struct urtw_softc *sc, uint32_t mode)
   1701       1.1  christos {
   1702       1.1  christos 	uint8_t data;
   1703       1.1  christos 	usbd_status error;
   1704       1.1  christos 
   1705       1.1  christos 	urtw_read8_m(sc, URTW_EPROM_CMD, &data);
   1706       1.1  christos 	data = (data & ~URTW_EPROM_CMD_MASK) | (mode << URTW_EPROM_CMD_SHIFT);
   1707       1.1  christos 	data = data & ~(URTW_EPROM_CS | URTW_EPROM_CK);
   1708       1.1  christos 	urtw_write8_m(sc, URTW_EPROM_CMD, data);
   1709       1.1  christos fail:
   1710       1.7     skrll 	return error;
   1711       1.1  christos }
   1712       1.1  christos 
   1713  1.15.2.2    martin static usbd_status
   1714       1.1  christos urtw_8180_set_anaparam(struct urtw_softc *sc, uint32_t val)
   1715       1.1  christos {
   1716       1.1  christos 	uint8_t data;
   1717       1.1  christos 	usbd_status error;
   1718       1.1  christos 
   1719       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
   1720       1.1  christos 	if (error)
   1721       1.1  christos 		goto fail;
   1722       1.1  christos 
   1723       1.1  christos 	urtw_read8_m(sc, URTW_CONFIG3, &data);
   1724       1.1  christos 	urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
   1725       1.1  christos 	urtw_write32_m(sc, URTW_ANAPARAM, val);
   1726       1.1  christos 	urtw_read8_m(sc, URTW_CONFIG3, &data);
   1727       1.1  christos 	urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
   1728       1.1  christos 
   1729       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
   1730       1.1  christos 	if (error)
   1731       1.1  christos 		goto fail;
   1732       1.1  christos fail:
   1733       1.7     skrll 	return error;
   1734       1.1  christos }
   1735       1.1  christos 
   1736  1.15.2.2    martin static usbd_status
   1737       1.1  christos urtw_8185_set_anaparam2(struct urtw_softc *sc, uint32_t val)
   1738       1.1  christos {
   1739       1.1  christos 	uint8_t data;
   1740       1.1  christos 	usbd_status error;
   1741       1.1  christos 
   1742       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
   1743       1.1  christos 	if (error)
   1744       1.1  christos 		goto fail;
   1745       1.1  christos 
   1746       1.1  christos 	urtw_read8_m(sc, URTW_CONFIG3, &data);
   1747       1.1  christos 	urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
   1748       1.1  christos 	urtw_write32_m(sc, URTW_ANAPARAM2, val);
   1749       1.1  christos 	urtw_read8_m(sc, URTW_CONFIG3, &data);
   1750       1.1  christos 	urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
   1751       1.1  christos 
   1752       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
   1753       1.1  christos 	if (error)
   1754       1.1  christos 		goto fail;
   1755       1.1  christos fail:
   1756       1.7     skrll 	return error;
   1757       1.1  christos }
   1758       1.1  christos 
   1759  1.15.2.2    martin static usbd_status
   1760       1.1  christos urtw_intr_disable(struct urtw_softc *sc)
   1761       1.1  christos {
   1762       1.1  christos 	usbd_status error;
   1763       1.1  christos 
   1764       1.1  christos 	urtw_write16_m(sc, URTW_INTR_MASK, 0);
   1765       1.1  christos 
   1766       1.1  christos fail:
   1767       1.7     skrll 	return error;
   1768       1.1  christos }
   1769       1.1  christos 
   1770  1.15.2.2    martin static usbd_status
   1771       1.1  christos urtw_reset(struct urtw_softc *sc)
   1772       1.1  christos {
   1773       1.1  christos 	uint8_t data;
   1774       1.1  christos 	usbd_status error;
   1775       1.1  christos 
   1776       1.1  christos 	error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON);
   1777       1.1  christos 	if (error)
   1778       1.1  christos 		goto fail;
   1779       1.1  christos 	error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON);
   1780       1.1  christos 	if (error)
   1781       1.1  christos 		goto fail;
   1782       1.1  christos 
   1783       1.1  christos 	error = urtw_intr_disable(sc);
   1784       1.1  christos 	if (error)
   1785       1.1  christos 		goto fail;
   1786       1.1  christos 	usbd_delay_ms(sc->sc_udev, 100);
   1787       1.1  christos 
   1788       1.1  christos 	error = urtw_write8e(sc, 0x18, 0x10);
   1789       1.1  christos 	if (error != 0)
   1790       1.1  christos 		goto fail;
   1791       1.1  christos 	error = urtw_write8e(sc, 0x18, 0x11);
   1792       1.1  christos 	if (error != 0)
   1793       1.1  christos 		goto fail;
   1794       1.1  christos 	error = urtw_write8e(sc, 0x18, 0x00);
   1795       1.1  christos 	if (error != 0)
   1796       1.1  christos 		goto fail;
   1797       1.1  christos 	usbd_delay_ms(sc->sc_udev, 100);
   1798       1.1  christos 
   1799       1.1  christos 	urtw_read8_m(sc, URTW_CMD, &data);
   1800       1.1  christos 	data = (data & 2) | URTW_CMD_RST;
   1801       1.1  christos 	urtw_write8_m(sc, URTW_CMD, data);
   1802       1.1  christos 	usbd_delay_ms(sc->sc_udev, 100);
   1803       1.1  christos 
   1804       1.1  christos 	urtw_read8_m(sc, URTW_CMD, &data);
   1805       1.1  christos 	if (data & URTW_CMD_RST) {
   1806       1.1  christos 		printf("%s: reset timeout\n", device_xname(sc->sc_dev));
   1807       1.1  christos 		goto fail;
   1808       1.1  christos 	}
   1809       1.1  christos 
   1810       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_LOAD);
   1811       1.1  christos 	if (error)
   1812       1.1  christos 		goto fail;
   1813       1.1  christos 	usbd_delay_ms(sc->sc_udev, 100);
   1814       1.1  christos 
   1815       1.1  christos 	error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON);
   1816       1.1  christos 	if (error)
   1817       1.1  christos 		goto fail;
   1818       1.1  christos 	error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON);
   1819       1.1  christos 	if (error)
   1820       1.1  christos 		goto fail;
   1821       1.1  christos fail:
   1822       1.7     skrll 	return error;
   1823       1.1  christos }
   1824       1.1  christos 
   1825  1.15.2.2    martin static usbd_status
   1826       1.1  christos urtw_led_on(struct urtw_softc *sc, int type)
   1827       1.1  christos {
   1828       1.1  christos 	usbd_status error;
   1829       1.1  christos 
   1830       1.1  christos 	if (type == URTW_LED_GPIO) {
   1831       1.1  christos 		switch (sc->sc_gpio_ledpin) {
   1832       1.1  christos 		case URTW_LED_PIN_GPIO0:
   1833       1.1  christos 			urtw_write8_m(sc, URTW_GPIO, 0x01);
   1834       1.1  christos 			urtw_write8_m(sc, URTW_GP_ENABLE, 0x00);
   1835       1.1  christos 			break;
   1836       1.1  christos 		default:
   1837  1.15.2.2    martin 			panic("unsupported LED PIN type %#x",
   1838       1.1  christos 			    sc->sc_gpio_ledpin);
   1839       1.1  christos 			/* NOTREACHED */
   1840       1.1  christos 		}
   1841       1.1  christos 	} else {
   1842  1.15.2.2    martin 		panic("unsupported LED type %#x", type);
   1843       1.1  christos 		/* NOTREACHED */
   1844       1.1  christos 	}
   1845       1.1  christos 
   1846       1.1  christos 	sc->sc_gpio_ledon = 1;
   1847       1.1  christos fail:
   1848       1.7     skrll 	return error;
   1849       1.1  christos }
   1850       1.1  christos 
   1851       1.1  christos static usbd_status
   1852       1.1  christos urtw_led_off(struct urtw_softc *sc, int type)
   1853       1.1  christos {
   1854       1.1  christos 	usbd_status error;
   1855       1.1  christos 
   1856       1.1  christos 	if (type == URTW_LED_GPIO) {
   1857       1.1  christos 		switch (sc->sc_gpio_ledpin) {
   1858       1.1  christos 		case URTW_LED_PIN_GPIO0:
   1859       1.1  christos 			urtw_write8_m(sc, URTW_GPIO, 0x01);
   1860       1.1  christos 			urtw_write8_m(sc, URTW_GP_ENABLE, 0x01);
   1861       1.1  christos 			break;
   1862       1.1  christos 		default:
   1863  1.15.2.2    martin 			panic("unsupported LED PIN type %#x",
   1864       1.1  christos 			    sc->sc_gpio_ledpin);
   1865       1.1  christos 			/* NOTREACHED */
   1866       1.1  christos 		}
   1867       1.1  christos 	} else {
   1868  1.15.2.2    martin 		panic("unsupported LED type %#x", type);
   1869       1.1  christos 		/* NOTREACHED */
   1870       1.1  christos 	}
   1871       1.1  christos 
   1872       1.1  christos 	sc->sc_gpio_ledon = 0;
   1873       1.1  christos 
   1874       1.1  christos fail:
   1875       1.7     skrll 	return error;
   1876       1.1  christos }
   1877       1.1  christos 
   1878  1.15.2.2    martin static usbd_status
   1879       1.1  christos urtw_led_mode0(struct urtw_softc *sc, int mode)
   1880       1.1  christos {
   1881       1.1  christos 	switch (mode) {
   1882       1.1  christos 	case URTW_LED_CTL_POWER_ON:
   1883       1.1  christos 		sc->sc_gpio_ledstate = URTW_LED_POWER_ON_BLINK;
   1884       1.1  christos 		break;
   1885       1.1  christos 	case URTW_LED_CTL_TX:
   1886       1.1  christos 		if (sc->sc_gpio_ledinprogress == 1)
   1887       1.7     skrll 			return 0;
   1888       1.1  christos 
   1889       1.1  christos 		sc->sc_gpio_ledstate = URTW_LED_BLINK_NORMAL;
   1890       1.1  christos 		sc->sc_gpio_blinktime = 2;
   1891       1.1  christos 		break;
   1892       1.1  christos 	case URTW_LED_CTL_LINK:
   1893       1.1  christos 		sc->sc_gpio_ledstate = URTW_LED_ON;
   1894       1.1  christos 		break;
   1895       1.1  christos 	default:
   1896  1.15.2.2    martin 		panic("unsupported LED mode %#x", mode);
   1897       1.1  christos 		/* NOTREACHED */
   1898       1.1  christos 	}
   1899       1.1  christos 
   1900       1.1  christos 	switch (sc->sc_gpio_ledstate) {
   1901       1.1  christos 	case URTW_LED_ON:
   1902       1.1  christos 		if (sc->sc_gpio_ledinprogress != 0)
   1903       1.1  christos 			break;
   1904       1.1  christos 		urtw_led_on(sc, URTW_LED_GPIO);
   1905       1.1  christos 		break;
   1906       1.1  christos 	case URTW_LED_BLINK_NORMAL:
   1907       1.1  christos 		if (sc->sc_gpio_ledinprogress != 0)
   1908       1.1  christos 			break;
   1909       1.1  christos 		sc->sc_gpio_ledinprogress = 1;
   1910       1.1  christos 		sc->sc_gpio_blinkstate = (sc->sc_gpio_ledon != 0) ?
   1911       1.1  christos 			URTW_LED_OFF : URTW_LED_ON;
   1912       1.1  christos 		if (!sc->sc_dying)
   1913       1.1  christos 			callout_schedule(&sc->sc_led_ch, mstohz(100));
   1914       1.1  christos 		break;
   1915       1.1  christos 	case URTW_LED_POWER_ON_BLINK:
   1916       1.1  christos 		urtw_led_on(sc, URTW_LED_GPIO);
   1917       1.1  christos 		usbd_delay_ms(sc->sc_udev, 100);
   1918       1.1  christos 		urtw_led_off(sc, URTW_LED_GPIO);
   1919       1.1  christos 		break;
   1920       1.1  christos 	default:
   1921  1.15.2.2    martin 		panic("unknown LED status %#x", sc->sc_gpio_ledstate);
   1922       1.1  christos 		/* NOTREACHED */
   1923       1.1  christos 	}
   1924       1.7     skrll 	return 0;
   1925       1.1  christos }
   1926       1.1  christos 
   1927  1.15.2.2    martin static usbd_status
   1928       1.1  christos urtw_led_mode1(struct urtw_softc *sc, int mode)
   1929       1.1  christos {
   1930       1.7     skrll 	return USBD_INVAL;
   1931       1.1  christos }
   1932       1.1  christos 
   1933  1.15.2.2    martin static usbd_status
   1934       1.1  christos urtw_led_mode2(struct urtw_softc *sc, int mode)
   1935       1.1  christos {
   1936       1.7     skrll 	return USBD_INVAL;
   1937       1.1  christos }
   1938       1.1  christos 
   1939  1.15.2.2    martin static usbd_status
   1940       1.1  christos urtw_led_mode3(struct urtw_softc *sc, int mode)
   1941       1.1  christos {
   1942       1.7     skrll 	return USBD_INVAL;
   1943       1.1  christos }
   1944       1.1  christos 
   1945  1.15.2.2    martin static void
   1946       1.1  christos urtw_ledusbtask(void *arg)
   1947       1.1  christos {
   1948       1.1  christos 	struct urtw_softc *sc = arg;
   1949       1.1  christos 
   1950       1.1  christos 	if (sc->sc_strategy != URTW_SW_LED_MODE0)
   1951  1.15.2.2    martin 		panic("could not process a LED strategy %#x", sc->sc_strategy);
   1952       1.1  christos 
   1953       1.1  christos 	urtw_led_blink(sc);
   1954       1.1  christos }
   1955       1.1  christos 
   1956  1.15.2.2    martin static void
   1957       1.1  christos urtw_ledtask(void *arg)
   1958       1.1  christos {
   1959       1.1  christos 	struct urtw_softc *sc = arg;
   1960       1.1  christos 
   1961       1.1  christos 	/*
   1962       1.1  christos 	 * NB: to change a status of the led we need at least a sleep so we
   1963       1.1  christos 	 * can't do it here
   1964       1.1  christos 	 */
   1965       1.1  christos 	usb_add_task(sc->sc_udev, &sc->sc_ledtask, USB_TASKQ_DRIVER);
   1966       1.1  christos }
   1967       1.1  christos 
   1968  1.15.2.2    martin static usbd_status
   1969       1.1  christos urtw_led_ctl(struct urtw_softc *sc, int mode)
   1970       1.1  christos {
   1971       1.1  christos 	usbd_status error = 0;
   1972       1.1  christos 
   1973       1.1  christos 	switch (sc->sc_strategy) {
   1974       1.1  christos 	case URTW_SW_LED_MODE0:
   1975       1.1  christos 		error = urtw_led_mode0(sc, mode);
   1976       1.1  christos 		break;
   1977       1.1  christos 	case URTW_SW_LED_MODE1:
   1978       1.1  christos 		error = urtw_led_mode1(sc, mode);
   1979       1.1  christos 		break;
   1980       1.1  christos 	case URTW_SW_LED_MODE2:
   1981       1.1  christos 		error = urtw_led_mode2(sc, mode);
   1982       1.1  christos 		break;
   1983       1.1  christos 	case URTW_SW_LED_MODE3:
   1984       1.1  christos 		error = urtw_led_mode3(sc, mode);
   1985       1.1  christos 		break;
   1986       1.1  christos 	default:
   1987       1.1  christos 		panic("unsupported LED mode %d", sc->sc_strategy);
   1988       1.1  christos 		/* NOTREACHED */
   1989       1.1  christos 	}
   1990       1.1  christos 
   1991       1.7     skrll 	return error;
   1992       1.1  christos }
   1993       1.1  christos 
   1994  1.15.2.2    martin static usbd_status
   1995       1.1  christos urtw_led_blink(struct urtw_softc *sc)
   1996       1.1  christos {
   1997       1.1  christos 	uint8_t ing = 0;
   1998       1.1  christos 
   1999       1.1  christos 	if (sc->sc_gpio_blinkstate == URTW_LED_ON)
   2000       1.6  christos 		(void)urtw_led_on(sc, URTW_LED_GPIO);
   2001       1.1  christos 	else
   2002       1.6  christos 		(void)urtw_led_off(sc, URTW_LED_GPIO);
   2003       1.1  christos 	sc->sc_gpio_blinktime--;
   2004       1.1  christos 	if (sc->sc_gpio_blinktime == 0)
   2005       1.1  christos 		ing = 1;
   2006       1.1  christos 	else {
   2007       1.1  christos 		if (sc->sc_gpio_ledstate != URTW_LED_BLINK_NORMAL &&
   2008       1.1  christos 		    sc->sc_gpio_ledstate != URTW_LED_BLINK_SLOWLY &&
   2009       1.1  christos 		    sc->sc_gpio_ledstate != URTW_LED_BLINK_CM3)
   2010       1.1  christos 			ing = 1;
   2011       1.1  christos 	}
   2012       1.1  christos 	if (ing == 1) {
   2013       1.1  christos 		if (sc->sc_gpio_ledstate == URTW_LED_ON &&
   2014       1.1  christos 		    sc->sc_gpio_ledon == 0)
   2015       1.6  christos 			(void)urtw_led_on(sc, URTW_LED_GPIO);
   2016       1.1  christos 		else if (sc->sc_gpio_ledstate == URTW_LED_OFF &&
   2017       1.1  christos 		    sc->sc_gpio_ledon == 1)
   2018       1.6  christos 			(void)urtw_led_off(sc, URTW_LED_GPIO);
   2019       1.1  christos 
   2020       1.1  christos 		sc->sc_gpio_blinktime = 0;
   2021       1.1  christos 		sc->sc_gpio_ledinprogress = 0;
   2022       1.7     skrll 		return 0;
   2023       1.1  christos 	}
   2024       1.1  christos 
   2025       1.1  christos 	sc->sc_gpio_blinkstate = (sc->sc_gpio_blinkstate != URTW_LED_ON) ?
   2026       1.1  christos 	    URTW_LED_ON : URTW_LED_OFF;
   2027       1.1  christos 
   2028       1.1  christos 	switch (sc->sc_gpio_ledstate) {
   2029       1.1  christos 	case URTW_LED_BLINK_NORMAL:
   2030       1.1  christos 		if (!sc->sc_dying)
   2031       1.1  christos 			callout_schedule(&sc->sc_led_ch, mstohz(100));
   2032       1.1  christos 		break;
   2033       1.1  christos 	default:
   2034  1.15.2.2    martin 		panic("unknown LED status %#x", sc->sc_gpio_ledstate);
   2035       1.1  christos 		/* NOTREACHED */
   2036       1.1  christos 	}
   2037       1.7     skrll 	return 0;
   2038       1.1  christos }
   2039       1.1  christos 
   2040  1.15.2.2    martin static usbd_status
   2041       1.1  christos urtw_update_msr(struct urtw_softc *sc)
   2042       1.1  christos {
   2043       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   2044       1.1  christos 	uint8_t data;
   2045       1.1  christos 	usbd_status error;
   2046       1.1  christos 
   2047       1.1  christos 	urtw_read8_m(sc, URTW_MSR, &data);
   2048       1.1  christos 	data &= ~URTW_MSR_LINK_MASK;
   2049       1.1  christos 
   2050       1.1  christos 	/* Should always be set. */
   2051       1.1  christos 	if (sc->sc_hwrev & URTW_HWREV_8187B)
   2052       1.1  christos 		data |= URTW_MSR_LINK_ENEDCA;
   2053       1.1  christos 
   2054       1.1  christos 	if (sc->sc_state == IEEE80211_S_RUN) {
   2055       1.1  christos 		switch (ic->ic_opmode) {
   2056       1.1  christos 		case IEEE80211_M_STA:
   2057       1.1  christos 		case IEEE80211_M_MONITOR:
   2058       1.1  christos 			data |= URTW_MSR_LINK_STA;
   2059       1.1  christos 			break;
   2060       1.1  christos 		default:
   2061  1.15.2.2    martin 			panic("unsupported operation mode %#x",
   2062       1.1  christos 			    ic->ic_opmode);
   2063       1.1  christos 			/* NOTREACHED */
   2064       1.1  christos 		}
   2065       1.1  christos 	} else
   2066       1.1  christos 		data |= URTW_MSR_LINK_NONE;
   2067       1.1  christos 
   2068       1.1  christos 	urtw_write8_m(sc, URTW_MSR, data);
   2069       1.1  christos fail:
   2070       1.7     skrll 	return error;
   2071       1.1  christos }
   2072       1.1  christos 
   2073  1.15.2.2    martin static uint16_t
   2074       1.1  christos urtw_rate2rtl(int rate)
   2075       1.1  christos {
   2076       1.1  christos 	unsigned int i;
   2077       1.1  christos 
   2078       1.1  christos 	for (i = 0; i < __arraycount(urtw_ratetable); i++) {
   2079       1.1  christos 		if (rate == urtw_ratetable[i].reg)
   2080       1.7     skrll 			return urtw_ratetable[i].val;
   2081       1.1  christos 	}
   2082       1.1  christos 
   2083       1.7     skrll 	return 3;
   2084       1.1  christos }
   2085       1.1  christos 
   2086  1.15.2.2    martin static uint16_t
   2087       1.1  christos urtw_rtl2rate(int rate)
   2088       1.1  christos {
   2089       1.1  christos 	unsigned int i;
   2090       1.1  christos 
   2091       1.1  christos 	for (i = 0; i < __arraycount(urtw_ratetable); i++) {
   2092       1.1  christos 		if (rate == urtw_ratetable[i].val)
   2093       1.7     skrll 			return urtw_ratetable[i].reg;
   2094       1.1  christos 	}
   2095       1.1  christos 
   2096       1.7     skrll 	return 0;
   2097       1.1  christos }
   2098       1.1  christos 
   2099  1.15.2.2    martin static usbd_status
   2100       1.1  christos urtw_set_rate(struct urtw_softc *sc)
   2101       1.1  christos {
   2102       1.1  christos 	int i, basic_rate, min_rr_rate, max_rr_rate;
   2103       1.1  christos 	uint16_t data;
   2104       1.1  christos 	usbd_status error;
   2105       1.1  christos 
   2106       1.1  christos 	basic_rate = urtw_rate2rtl(48);
   2107       1.1  christos 	min_rr_rate = urtw_rate2rtl(12);
   2108       1.1  christos 	max_rr_rate = urtw_rate2rtl(48);
   2109       1.1  christos 
   2110       1.1  christos 	urtw_write8_m(sc, URTW_RESP_RATE,
   2111       1.1  christos 	    max_rr_rate << URTW_RESP_MAX_RATE_SHIFT |
   2112       1.1  christos 	    min_rr_rate << URTW_RESP_MIN_RATE_SHIFT);
   2113       1.1  christos 
   2114       1.1  christos 	urtw_read16_m(sc, URTW_8187_BRSR, &data);
   2115       1.1  christos 	data &= ~URTW_BRSR_MBR_8185;
   2116       1.1  christos 
   2117       1.1  christos 	for (i = 0; i <= basic_rate; i++)
   2118       1.1  christos 		data |= (1 << i);
   2119       1.1  christos 
   2120       1.1  christos 	urtw_write16_m(sc, URTW_8187_BRSR, data);
   2121       1.1  christos fail:
   2122       1.7     skrll 	return error;
   2123       1.1  christos }
   2124       1.1  christos 
   2125  1.15.2.2    martin static usbd_status
   2126       1.1  christos urtw_intr_enable(struct urtw_softc *sc)
   2127       1.1  christos {
   2128       1.1  christos 	usbd_status error;
   2129       1.1  christos 
   2130       1.1  christos 	urtw_write16_m(sc, URTW_INTR_MASK, 0xffff);
   2131       1.1  christos fail:
   2132       1.7     skrll 	return error;
   2133       1.1  christos }
   2134       1.1  christos 
   2135  1.15.2.2    martin static usbd_status
   2136       1.1  christos urtw_rx_setconf(struct urtw_softc *sc)
   2137       1.1  christos {
   2138       1.1  christos 	struct ifnet *ifp = sc->sc_ic.ic_ifp;
   2139       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   2140       1.1  christos 	uint32_t data;
   2141       1.1  christos 	usbd_status error;
   2142       1.1  christos 
   2143       1.1  christos 	urtw_read32_m(sc, URTW_RX, &data);
   2144       1.1  christos 	data = data &~ URTW_RX_FILTER_MASK;
   2145       1.1  christos #if 0
   2146       1.1  christos 	data = data | URTW_RX_FILTER_CTL;
   2147       1.1  christos #endif
   2148       1.1  christos 	data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA;
   2149       1.1  christos 	data = data | URTW_RX_FILTER_BCAST | URTW_RX_FILTER_MCAST;
   2150       1.1  christos 
   2151       1.1  christos 	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
   2152       1.1  christos 		data = data | URTW_RX_FILTER_ICVERR;
   2153       1.1  christos 		data = data | URTW_RX_FILTER_PWR;
   2154       1.1  christos 	}
   2155       1.1  christos 	if (sc->sc_crcmon == 1 && ic->ic_opmode == IEEE80211_M_MONITOR)
   2156       1.1  christos 		data = data | URTW_RX_FILTER_CRCERR;
   2157       1.1  christos 
   2158       1.1  christos 	if (ic->ic_opmode == IEEE80211_M_MONITOR ||
   2159       1.1  christos 	    (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) {
   2160       1.1  christos 		data = data | URTW_RX_FILTER_ALLMAC;
   2161       1.1  christos 	} else {
   2162       1.1  christos 		data = data | URTW_RX_FILTER_NICMAC;
   2163       1.1  christos 		data = data | URTW_RX_CHECK_BSSID;
   2164       1.1  christos 	}
   2165       1.1  christos 
   2166       1.1  christos 	data = data &~ URTW_RX_FIFO_THRESHOLD_MASK;
   2167       1.1  christos 	data = data | URTW_RX_FIFO_THRESHOLD_NONE | URTW_RX_AUTORESETPHY;
   2168       1.1  christos 	data = data &~ URTW_MAX_RX_DMA_MASK;
   2169       1.1  christos 	data = data | URTW_MAX_RX_DMA_2048 | URTW_RCR_ONLYERLPKT;
   2170       1.1  christos 
   2171       1.1  christos 	urtw_write32_m(sc, URTW_RX, data);
   2172       1.1  christos fail:
   2173       1.7     skrll 	return error;
   2174       1.1  christos }
   2175       1.1  christos 
   2176  1.15.2.2    martin static usbd_status
   2177       1.1  christos urtw_rx_enable(struct urtw_softc *sc)
   2178       1.1  christos {
   2179       1.1  christos 	int i;
   2180       1.1  christos 	struct urtw_rx_data *rx_data;
   2181       1.1  christos 	uint8_t data;
   2182       1.1  christos 	usbd_status error;
   2183       1.1  christos 
   2184       1.1  christos 	/*
   2185       1.1  christos 	 * Start up the receive pipe.
   2186       1.1  christos 	 */
   2187       1.1  christos 	for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++) {
   2188       1.1  christos 		rx_data = &sc->sc_rx_data[i];
   2189       1.1  christos 
   2190       1.7     skrll 		usbd_setup_xfer(rx_data->xfer, rx_data, rx_data->buf, MCLBYTES,
   2191       1.7     skrll 		    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urtw_rxeof);
   2192       1.1  christos 		error = usbd_transfer(rx_data->xfer);
   2193       1.1  christos 		if (error != USBD_IN_PROGRESS && error != 0) {
   2194       1.1  christos 			printf("%s: could not queue Rx transfer\n",
   2195       1.1  christos 			    device_xname(sc->sc_dev));
   2196       1.1  christos 			goto fail;
   2197       1.1  christos 		}
   2198       1.1  christos 	}
   2199       1.1  christos 
   2200       1.1  christos 	error = urtw_rx_setconf(sc);
   2201       1.1  christos 	if (error != 0)
   2202       1.1  christos 		goto fail;
   2203       1.1  christos 
   2204       1.1  christos 	urtw_read8_m(sc, URTW_CMD, &data);
   2205       1.1  christos 	urtw_write8_m(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE);
   2206       1.1  christos fail:
   2207       1.7     skrll 	return error;
   2208       1.1  christos }
   2209       1.1  christos 
   2210  1.15.2.2    martin static usbd_status
   2211       1.1  christos urtw_tx_enable(struct urtw_softc *sc)
   2212       1.1  christos {
   2213       1.1  christos 	uint8_t data8;
   2214       1.1  christos 	uint32_t data;
   2215       1.1  christos 	usbd_status error;
   2216       1.1  christos 
   2217       1.1  christos 	if (sc->sc_hwrev & URTW_HWREV_8187) {
   2218       1.1  christos 		urtw_read8_m(sc, URTW_CW_CONF, &data8);
   2219       1.1  christos 		data8 &= ~(URTW_CW_CONF_PERPACKET_CW |
   2220       1.1  christos 		    URTW_CW_CONF_PERPACKET_RETRY);
   2221       1.1  christos 		urtw_write8_m(sc, URTW_CW_CONF, data8);
   2222       1.1  christos 
   2223      1.13     skrll 		urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
   2224       1.1  christos 		data8 &= ~URTW_TX_AGC_CTL_PERPACKET_GAIN;
   2225       1.1  christos 		data8 &= ~URTW_TX_AGC_CTL_PERPACKET_ANTSEL;
   2226       1.1  christos 		data8 &= ~URTW_TX_AGC_CTL_FEEDBACK_ANT;
   2227       1.1  christos 		urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
   2228       1.1  christos 
   2229       1.1  christos 		urtw_read32_m(sc, URTW_TX_CONF, &data);
   2230       1.1  christos 		data &= ~URTW_TX_LOOPBACK_MASK;
   2231       1.1  christos 		data |= URTW_TX_LOOPBACK_NONE;
   2232       1.1  christos 		data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
   2233       1.1  christos 		data |= sc->sc_tx_retry << URTW_TX_DPRETRY_SHIFT;
   2234       1.1  christos 		data |= sc->sc_rts_retry << URTW_TX_RTSRETRY_SHIFT;
   2235       1.1  christos 		data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
   2236       1.1  christos 		data |= URTW_TX_MXDMA_2048 | URTW_TX_CWMIN | URTW_TX_DISCW;
   2237       1.1  christos 		data &= ~URTW_TX_SWPLCPLEN;
   2238       1.1  christos 		data |= URTW_TX_NOICV;
   2239       1.1  christos 		urtw_write32_m(sc, URTW_TX_CONF, data);
   2240       1.1  christos 	} else {
   2241       1.1  christos 		data = URTW_TX_DURPROCMODE | URTW_TX_DISREQQSIZE |
   2242       1.1  christos 		    URTW_TX_MXDMA_2048 | URTW_TX_SHORTRETRY |
   2243       1.1  christos 		    URTW_TX_LONGRETRY;
   2244       1.1  christos 		urtw_write32_m(sc, URTW_TX_CONF, data);
   2245       1.1  christos 	}
   2246       1.1  christos 
   2247       1.1  christos 	urtw_read8_m(sc, URTW_CMD, &data8);
   2248       1.1  christos 	urtw_write8_m(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE);
   2249       1.1  christos fail:
   2250       1.7     skrll 	return error;
   2251       1.1  christos }
   2252       1.1  christos 
   2253  1.15.2.2    martin static int
   2254       1.1  christos urtw_init(struct ifnet *ifp)
   2255       1.1  christos {
   2256       1.1  christos 	struct urtw_softc *sc = ifp->if_softc;
   2257       1.1  christos 	struct urtw_rf *rf = &sc->sc_rf;
   2258       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   2259       1.1  christos 	usbd_status error;
   2260       1.1  christos 
   2261       1.1  christos 	urtw_stop(ifp, 0);
   2262       1.1  christos 
   2263       1.1  christos 	error = urtw_reset(sc);
   2264       1.1  christos 	if (error)
   2265       1.1  christos 		goto fail;
   2266       1.1  christos 
   2267       1.1  christos 	urtw_write8_m(sc, 0x85, 0);
   2268       1.1  christos 	urtw_write8_m(sc, URTW_GPIO, 0);
   2269       1.1  christos 
   2270       1.1  christos 	/* for led */
   2271       1.1  christos 	urtw_write8_m(sc, 0x85, 4);
   2272       1.1  christos 	error = urtw_led_ctl(sc, URTW_LED_CTL_POWER_ON);
   2273       1.1  christos 	if (error != 0)
   2274       1.1  christos 		goto fail;
   2275       1.1  christos 
   2276       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
   2277       1.1  christos 	if (error)
   2278       1.1  christos 		goto fail;
   2279       1.1  christos 
   2280       1.1  christos 	/* applying MAC address again. */
   2281       1.1  christos 	IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
   2282       1.1  christos 	error = urtw_set_macaddr(sc, ic->ic_myaddr);
   2283       1.1  christos 	if (error)
   2284       1.1  christos 		goto fail;
   2285       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
   2286       1.1  christos 	if (error)
   2287       1.1  christos 		goto fail;
   2288       1.1  christos 
   2289       1.1  christos 	error = urtw_update_msr(sc);
   2290       1.1  christos 	if (error)
   2291       1.1  christos 		goto fail;
   2292       1.1  christos 
   2293       1.1  christos 	urtw_write32_m(sc, URTW_INT_TIMEOUT, 0);
   2294       1.1  christos 	urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
   2295       1.1  christos 	urtw_write8_m(sc, URTW_RATE_FALLBACK, 0x81);
   2296       1.1  christos 	error = urtw_set_rate(sc);
   2297       1.1  christos 	if (error != 0)
   2298       1.1  christos 		goto fail;
   2299       1.1  christos 
   2300       1.1  christos 	error = rf->init(rf);
   2301       1.1  christos 	if (error != 0)
   2302       1.1  christos 		goto fail;
   2303       1.1  christos 	if (rf->set_sens != NULL)
   2304       1.1  christos 		rf->set_sens(rf);
   2305       1.1  christos 
   2306       1.1  christos 	urtw_write16_m(sc, 0x5e, 1);
   2307       1.1  christos 	urtw_write16_m(sc, 0xfe, 0x10);
   2308       1.1  christos 	urtw_write8_m(sc, URTW_TALLY_SEL, 0x80);
   2309       1.1  christos 	urtw_write8_m(sc, 0xff, 0x60);
   2310       1.1  christos 	urtw_write16_m(sc, 0x5e, 0);
   2311       1.1  christos 	urtw_write8_m(sc, 0x85, 4);
   2312       1.1  christos 
   2313       1.1  christos 	error = urtw_intr_enable(sc);
   2314       1.1  christos 	if (error != 0)
   2315       1.1  christos 		goto fail;
   2316       1.1  christos 
   2317       1.1  christos 	/* reset softc variables */
   2318       1.7     skrll 	for (size_t j = 0; j < URTW_PRIORITY_MAX; j++) {
   2319       1.7     skrll 		sc->sc_txidx[j] = sc->sc_tx_queued[j] = 0;
   2320       1.7     skrll 	}
   2321       1.1  christos 	sc->sc_txtimer = 0;
   2322       1.1  christos 
   2323       1.1  christos 	if (!(sc->sc_flags & URTW_INIT_ONCE)) {
   2324       1.1  christos 		error = usbd_set_config_no(sc->sc_udev, URTW_CONFIG_NO, 0);
   2325       1.1  christos 		if (error != 0) {
   2326       1.2     skrll 			aprint_error_dev(sc->sc_dev, "failed to set configuration"
   2327       1.2     skrll 			    ", err=%s\n", usbd_errstr(error));
   2328       1.1  christos 			goto fail;
   2329       1.1  christos 		}
   2330       1.1  christos 		/* get the first interface handle */
   2331       1.1  christos 		error = usbd_device2interface_handle(sc->sc_udev,
   2332       1.1  christos 		    URTW_IFACE_INDEX, &sc->sc_iface);
   2333       1.1  christos 		if (error != 0) {
   2334       1.1  christos 			printf("%s: could not get interface handle\n",
   2335       1.1  christos 			    device_xname(sc->sc_dev));
   2336       1.1  christos 			goto fail;
   2337       1.1  christos 		}
   2338       1.1  christos 		error = urtw_open_pipes(sc);
   2339       1.1  christos 		if (error != 0)
   2340       1.1  christos 			goto fail;
   2341       1.6  christos 		error = urtw_alloc_rx_data_list(sc);
   2342       1.1  christos 		if (error != 0)
   2343       1.1  christos 			goto fail;
   2344       1.6  christos 		error = urtw_alloc_tx_data_list(sc);
   2345       1.1  christos 		if (error != 0)
   2346       1.1  christos 			goto fail;
   2347       1.1  christos 		sc->sc_flags |= URTW_INIT_ONCE;
   2348       1.1  christos 	}
   2349       1.1  christos 
   2350       1.1  christos 	error = urtw_rx_enable(sc);
   2351       1.1  christos 	if (error != 0)
   2352       1.1  christos 		goto fail;
   2353       1.1  christos 	error = urtw_tx_enable(sc);
   2354       1.1  christos 	if (error != 0)
   2355       1.1  christos 		goto fail;
   2356       1.1  christos 
   2357       1.1  christos 	ifp->if_flags &= ~IFF_OACTIVE;
   2358       1.1  christos 	ifp->if_flags |= IFF_RUNNING;
   2359       1.1  christos 
   2360       1.1  christos 	if (ic->ic_opmode == IEEE80211_M_MONITOR)
   2361       1.1  christos 		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
   2362       1.1  christos 	else
   2363       1.1  christos 		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
   2364       1.1  christos 
   2365       1.7     skrll 	return 0;
   2366       1.1  christos fail:
   2367       1.7     skrll 	return error;
   2368       1.1  christos }
   2369       1.1  christos 
   2370  1.15.2.2    martin static int
   2371       1.1  christos urtw_ioctl(struct ifnet *ifp, u_long cmd, void *data)
   2372       1.1  christos {
   2373       1.1  christos #define IS_RUNNING(ifp) \
   2374       1.1  christos 	(((ifp)->if_flags & IFF_UP) && ((ifp)->if_flags & IFF_RUNNING))
   2375       1.1  christos 
   2376       1.1  christos 	struct urtw_softc *sc = ifp->if_softc;
   2377       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   2378       1.1  christos 	int s, error = 0;
   2379       1.1  christos 
   2380       1.1  christos 	if (sc->sc_dying)
   2381       1.7     skrll 		return ENXIO;
   2382       1.1  christos 
   2383       1.1  christos 	s = splnet();
   2384       1.1  christos 
   2385       1.1  christos 	switch (cmd) {
   2386       1.1  christos 	case SIOCSIFFLAGS:
   2387       1.1  christos 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
   2388       1.1  christos 			break;
   2389       1.1  christos 		switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
   2390       1.1  christos 		case IFF_UP|IFF_RUNNING:
   2391       1.1  christos 			break;
   2392       1.1  christos 		case IFF_UP:
   2393       1.1  christos 			ifp->if_init(ifp);
   2394       1.1  christos 			break;
   2395       1.1  christos 		case IFF_RUNNING:
   2396       1.1  christos 			urtw_stop(ifp, 1);
   2397       1.1  christos 			break;
   2398       1.1  christos 		case 0:
   2399       1.1  christos 			break;
   2400       1.1  christos 		}
   2401       1.1  christos 		break;
   2402       1.1  christos 
   2403       1.1  christos 	case SIOCADDMULTI:
   2404       1.1  christos 	case SIOCDELMULTI:
   2405       1.1  christos 		if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET)
   2406       1.1  christos 			error = 0;
   2407       1.1  christos 		break;
   2408       1.1  christos 
   2409       1.1  christos 	default:
   2410       1.1  christos 		error = ieee80211_ioctl(ic, cmd, data);
   2411       1.1  christos 		break;
   2412       1.1  christos 	}
   2413       1.1  christos 
   2414       1.1  christos 	if (error == ENETRESET) {
   2415       1.1  christos 		if (IS_RUNNING(ifp) &&
   2416       1.1  christos 		    (ic->ic_roaming != IEEE80211_ROAMING_MANUAL))
   2417       1.1  christos 			ifp->if_init(ifp);
   2418       1.1  christos 		error = 0;
   2419       1.1  christos 	}
   2420       1.1  christos 
   2421       1.1  christos 	splx(s);
   2422       1.1  christos 
   2423       1.7     skrll 	return error;
   2424       1.1  christos #undef IS_RUNNING
   2425       1.1  christos }
   2426       1.1  christos 
   2427  1.15.2.2    martin static void
   2428       1.1  christos urtw_start(struct ifnet *ifp)
   2429       1.1  christos {
   2430       1.1  christos 	struct urtw_softc *sc = ifp->if_softc;
   2431       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   2432       1.1  christos 	struct ieee80211_node *ni;
   2433       1.1  christos 	struct ether_header *eh;
   2434       1.1  christos 	struct mbuf *m0;
   2435       1.1  christos 
   2436       1.1  christos 	/*
   2437       1.1  christos 	 * net80211 may still try to send management frames even if the
   2438       1.1  christos 	 * IFF_RUNNING flag is not set...
   2439       1.1  christos 	 */
   2440       1.1  christos 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
   2441       1.1  christos 		return;
   2442       1.1  christos 
   2443       1.1  christos 	for (;;) {
   2444       1.1  christos 		IF_POLL(&ic->ic_mgtq, m0);
   2445       1.1  christos 		if (m0 != NULL) {
   2446       1.7     skrll 
   2447       1.7     skrll 			if (sc->sc_tx_queued[URTW_PRIORITY_NORMAL] >=
   2448       1.1  christos 			    URTW_TX_DATA_LIST_COUNT) {
   2449       1.1  christos 				ifp->if_flags |= IFF_OACTIVE;
   2450       1.1  christos 				break;
   2451       1.1  christos 			}
   2452       1.1  christos 			IF_DEQUEUE(&ic->ic_mgtq, m0);
   2453       1.8     ozaki 			ni = M_GETCTX(m0, struct ieee80211_node *);
   2454       1.9     ozaki 			M_CLEARCTX(m0);
   2455      1.15   msaitoh 			bpf_mtap3(ic->ic_rawbpf, m0, BPF_D_OUT);
   2456       1.1  christos 			if (urtw_tx_start(sc, ni, m0, URTW_PRIORITY_NORMAL)
   2457       1.1  christos 			    != 0)
   2458       1.1  christos 				break;
   2459       1.1  christos 		} else {
   2460       1.1  christos 			if (ic->ic_state != IEEE80211_S_RUN)
   2461       1.1  christos 				break;
   2462       1.1  christos 			IFQ_POLL(&ifp->if_snd, m0);
   2463       1.1  christos 			if (m0 == NULL)
   2464       1.1  christos 				break;
   2465       1.7     skrll 			if (sc->sc_tx_queued[URTW_PRIORITY_NORMAL] >=
   2466       1.1  christos 			    URTW_TX_DATA_LIST_COUNT) {
   2467       1.1  christos 				ifp->if_flags |= IFF_OACTIVE;
   2468       1.1  christos 				break;
   2469       1.1  christos 			}
   2470       1.1  christos 			IFQ_DEQUEUE(&ifp->if_snd, m0);
   2471       1.1  christos 			if (m0->m_len < sizeof(struct ether_header) &&
   2472       1.1  christos 			    !(m0 = m_pullup(m0, sizeof(struct ether_header))))
   2473       1.1  christos 				continue;
   2474       1.1  christos 
   2475       1.1  christos 			eh = mtod(m0, struct ether_header *);
   2476       1.1  christos 			ni = ieee80211_find_txnode(ic, eh->ether_dhost);
   2477       1.1  christos 			if (ni == NULL) {
   2478       1.1  christos 				m_freem(m0);
   2479       1.1  christos 				continue;
   2480       1.1  christos 			}
   2481      1.15   msaitoh 			bpf_mtap(ifp, m0, BPF_D_OUT);
   2482       1.1  christos 			m0 = ieee80211_encap(ic, m0, ni);
   2483       1.1  christos 			if (m0 == NULL) {
   2484       1.1  christos 				ieee80211_free_node(ni);
   2485       1.1  christos 				continue;
   2486       1.1  christos 			}
   2487      1.15   msaitoh 			bpf_mtap3(ic->ic_rawbpf, m0, BPF_D_OUT);
   2488       1.1  christos 			if (urtw_tx_start(sc, ni, m0, URTW_PRIORITY_NORMAL)
   2489       1.1  christos 			    != 0) {
   2490       1.1  christos 				ieee80211_free_node(ni);
   2491  1.15.2.2    martin 				if_statinc(ifp, if_oerrors);
   2492       1.1  christos 				break;
   2493       1.1  christos 			}
   2494       1.1  christos 		}
   2495       1.1  christos 		sc->sc_txtimer = 5;
   2496       1.1  christos 		ifp->if_timer = 1;
   2497       1.1  christos 	}
   2498       1.1  christos }
   2499       1.1  christos 
   2500  1.15.2.2    martin static void
   2501       1.1  christos urtw_watchdog(struct ifnet *ifp)
   2502       1.1  christos {
   2503       1.1  christos 	struct urtw_softc *sc = ifp->if_softc;
   2504       1.1  christos 
   2505       1.1  christos 	ifp->if_timer = 0;
   2506       1.1  christos 
   2507       1.1  christos 	if (sc->sc_txtimer > 0) {
   2508       1.1  christos 		if (--sc->sc_txtimer == 0) {
   2509       1.1  christos 			printf("%s: device timeout\n", device_xname(sc->sc_dev));
   2510  1.15.2.2    martin 			if_statinc(ifp, if_oerrors);
   2511       1.1  christos 			return;
   2512       1.1  christos 		}
   2513       1.1  christos 		ifp->if_timer = 1;
   2514       1.1  christos 	}
   2515       1.1  christos 
   2516       1.1  christos 	ieee80211_watchdog(&sc->sc_ic);
   2517       1.1  christos }
   2518       1.1  christos 
   2519  1.15.2.2    martin static void
   2520       1.7     skrll urtw_txeof_low(struct usbd_xfer *xfer, void *priv,
   2521       1.1  christos     usbd_status status)
   2522       1.1  christos {
   2523       1.1  christos 	struct urtw_tx_data *data = priv;
   2524       1.1  christos 	struct urtw_softc *sc = data->sc;
   2525       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   2526       1.1  christos 	struct ifnet *ifp = ic->ic_ifp;
   2527       1.1  christos 	int s;
   2528       1.1  christos 
   2529       1.1  christos 	if (status != USBD_NORMAL_COMPLETION) {
   2530       1.1  christos 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
   2531       1.1  christos 			return;
   2532       1.1  christos 
   2533       1.1  christos 		printf("%s: could not transmit buffer: %s\n",
   2534       1.1  christos 		    device_xname(sc->sc_dev), usbd_errstr(status));
   2535       1.1  christos 
   2536       1.1  christos 		if (status == USBD_STALLED)
   2537       1.1  christos 			usbd_clear_endpoint_stall_async(sc->sc_txpipe_low);
   2538       1.1  christos 
   2539  1.15.2.2    martin 		if_statinc(ifp, if_oerrors);
   2540       1.1  christos 		return;
   2541       1.1  christos 	}
   2542       1.1  christos 
   2543       1.1  christos 	s = splnet();
   2544       1.1  christos 
   2545       1.1  christos 	ieee80211_free_node(data->ni);
   2546       1.1  christos 	data->ni = NULL;
   2547       1.1  christos 
   2548       1.1  christos 	sc->sc_txtimer = 0;
   2549  1.15.2.2    martin 	if_statinc(ifp, if_opackets);
   2550       1.1  christos 
   2551       1.7     skrll 	sc->sc_tx_queued[URTW_PRIORITY_LOW]--;
   2552       1.1  christos 	ifp->if_flags &= ~IFF_OACTIVE;
   2553       1.1  christos 	urtw_start(ifp);
   2554       1.1  christos 
   2555       1.1  christos 	splx(s);
   2556       1.1  christos }
   2557       1.1  christos 
   2558  1.15.2.2    martin static void
   2559       1.7     skrll urtw_txeof_normal(struct usbd_xfer *xfer, void *priv,
   2560       1.1  christos     usbd_status status)
   2561       1.1  christos {
   2562       1.1  christos 	struct urtw_tx_data *data = priv;
   2563       1.1  christos 	struct urtw_softc *sc = data->sc;
   2564       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   2565       1.1  christos 	struct ifnet *ifp = ic->ic_ifp;
   2566       1.1  christos 	int s;
   2567       1.1  christos 
   2568       1.1  christos 	if (status != USBD_NORMAL_COMPLETION) {
   2569       1.1  christos 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
   2570       1.1  christos 			return;
   2571       1.1  christos 
   2572       1.1  christos 		printf("%s: could not transmit buffer: %s\n",
   2573       1.1  christos 		    device_xname(sc->sc_dev), usbd_errstr(status));
   2574       1.1  christos 
   2575       1.1  christos 		if (status == USBD_STALLED)
   2576       1.1  christos 			usbd_clear_endpoint_stall_async(sc->sc_txpipe_normal);
   2577       1.1  christos 
   2578  1.15.2.2    martin 		if_statinc(ifp, if_oerrors);
   2579       1.1  christos 		return;
   2580       1.1  christos 	}
   2581       1.1  christos 
   2582       1.1  christos 	s = splnet();
   2583       1.1  christos 
   2584       1.1  christos 	ieee80211_free_node(data->ni);
   2585       1.1  christos 	data->ni = NULL;
   2586       1.1  christos 
   2587       1.1  christos 	sc->sc_txtimer = 0;
   2588  1.15.2.2    martin 	if_statinc(ifp, if_opackets);
   2589       1.1  christos 
   2590       1.7     skrll 	sc->sc_tx_queued[URTW_PRIORITY_NORMAL]--;
   2591       1.1  christos 	ifp->if_flags &= ~IFF_OACTIVE;
   2592       1.1  christos 	urtw_start(ifp);
   2593       1.1  christos 
   2594       1.1  christos 	splx(s);
   2595       1.1  christos }
   2596       1.1  christos 
   2597  1.15.2.2    martin static int
   2598       1.1  christos urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
   2599       1.1  christos     int prior)
   2600       1.1  christos {
   2601       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   2602       1.1  christos 	struct urtw_tx_data *data;
   2603       1.1  christos 	struct ieee80211_frame *wh;
   2604       1.1  christos 	struct ieee80211_key *k;
   2605       1.1  christos 	usbd_status error;
   2606       1.1  christos 	int xferlen;
   2607       1.1  christos 
   2608       1.1  christos 	wh = mtod(m0, struct ieee80211_frame *);
   2609       1.1  christos 
   2610       1.1  christos 	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
   2611       1.1  christos 		k = ieee80211_crypto_encap(ic, ni, m0);
   2612       1.1  christos 		if (k == NULL) {
   2613       1.1  christos 			m_freem(m0);
   2614       1.7     skrll 			return ENOBUFS;
   2615       1.1  christos 		}
   2616       1.1  christos 		/* packet header may have moved, reset our local pointer */
   2617       1.1  christos 		wh = mtod(m0, struct ieee80211_frame *);
   2618       1.1  christos 	}
   2619       1.1  christos 
   2620       1.1  christos 	if (sc->sc_drvbpf != NULL) {
   2621       1.1  christos 		struct urtw_tx_radiotap_header *tap = &sc->sc_txtap;
   2622       1.1  christos 
   2623       1.1  christos 		tap->wt_flags = 0;
   2624       1.1  christos 		tap->wt_rate = 0;
   2625       1.1  christos 		tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
   2626       1.1  christos 		tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
   2627       1.1  christos 
   2628      1.15   msaitoh 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0, BPF_D_OUT);
   2629       1.1  christos 	}
   2630       1.1  christos 
   2631       1.1  christos 	if (sc->sc_hwrev & URTW_HWREV_8187)
   2632       1.1  christos 		xferlen = m0->m_pkthdr.len + 4 * 3;
   2633       1.1  christos 	else
   2634       1.1  christos 		xferlen = m0->m_pkthdr.len + 4 * 8;
   2635       1.1  christos 
   2636       1.1  christos 	if ((0 == xferlen % 64) || (0 == xferlen % 512))
   2637       1.1  christos 		xferlen += 1;
   2638       1.1  christos 
   2639       1.7     skrll 	data = &sc->sc_tx_data[prior][sc->sc_txidx[prior]];
   2640       1.7     skrll 	sc->sc_txidx[prior] =
   2641       1.7     skrll 	    (sc->sc_txidx[prior] + 1) % URTW_TX_DATA_LIST_COUNT;
   2642       1.1  christos 
   2643       1.7     skrll 	memset(data->buf, 0, URTW_TX_MAXSIZE);
   2644       1.1  christos 	data->buf[0] = m0->m_pkthdr.len & 0xff;
   2645       1.1  christos 	data->buf[1] = (m0->m_pkthdr.len & 0x0f00) >> 8;
   2646       1.1  christos 	data->buf[1] |= (1 << 7);
   2647       1.1  christos 
   2648       1.1  christos 	/* XXX sc_preamble_mode is always 2. */
   2649       1.1  christos 	if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
   2650       1.1  christos 	    (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) &&
   2651       1.1  christos 	    (sc->sc_preamble_mode == 1) && (sc->sc_currate != 0))
   2652       1.1  christos 		data->buf[2] |= 1;
   2653       1.1  christos 	if ((m0->m_pkthdr.len > ic->ic_rtsthreshold) &&
   2654       1.1  christos 	    prior == URTW_PRIORITY_LOW)
   2655       1.1  christos 		panic("TODO tx.");
   2656       1.1  christos 	if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
   2657       1.1  christos 		data->buf[2] |= (1 << 1);
   2658       1.1  christos 	/* RTS rate - 10 means we use a basic rate. */
   2659       1.1  christos 	data->buf[2] |= (urtw_rate2rtl(2) << 3);
   2660       1.1  christos 	/*
   2661       1.1  christos 	 * XXX currently TX rate control depends on the rate value of
   2662       1.1  christos 	 * RX descriptor because I don't know how to we can control TX rate
   2663       1.1  christos 	 * in more smart way.  Please fix me you find a thing.
   2664       1.1  christos 	 */
   2665       1.1  christos 	data->buf[3] = sc->sc_currate;
   2666       1.1  christos 	if (prior == URTW_PRIORITY_NORMAL) {
   2667       1.1  christos 		if (IEEE80211_IS_MULTICAST(wh->i_addr1))
   2668       1.1  christos 			data->buf[3] = urtw_rate2rtl(ni->ni_rates.rs_rates[0]);
   2669       1.1  christos 		else if (ic->ic_fixed_rate != -1)
   2670       1.1  christos 			data->buf[3] = urtw_rate2rtl(ic->ic_fixed_rate);
   2671       1.1  christos 	}
   2672       1.1  christos 
   2673       1.1  christos 	if (sc->sc_hwrev & URTW_HWREV_8187) {
   2674       1.1  christos 		data->buf[8] = 3;		/* CW minimum */
   2675       1.1  christos 		data->buf[8] |= (7 << 4);	/* CW maximum */
   2676       1.1  christos 		data->buf[9] |= 11;		/* retry limitation */
   2677       1.1  christos 		m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)&data->buf[12]);
   2678       1.1  christos 	} else {
   2679       1.1  christos 		data->buf[21] |= 11;		/* retry limitation */
   2680       1.1  christos 		m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)&data->buf[32]);
   2681       1.1  christos 	}
   2682       1.1  christos 
   2683       1.1  christos 	data->ni = ni;
   2684       1.1  christos 
   2685       1.1  christos 	/* mbuf is no longer needed. */
   2686       1.1  christos 	m_freem(m0);
   2687       1.1  christos 
   2688       1.7     skrll 	usbd_setup_xfer(data->xfer, data, data->buf, xferlen,
   2689       1.7     skrll 	    USBD_FORCE_SHORT_XFER, URTW_DATA_TIMEOUT,
   2690       1.1  christos 	    (prior == URTW_PRIORITY_LOW) ? urtw_txeof_low : urtw_txeof_normal);
   2691       1.1  christos 	error = usbd_transfer(data->xfer);
   2692       1.1  christos 	if (error != USBD_IN_PROGRESS && error != USBD_NORMAL_COMPLETION) {
   2693       1.1  christos 		printf("%s: could not send frame: %s\n",
   2694       1.1  christos 		    device_xname(sc->sc_dev), usbd_errstr(error));
   2695       1.7     skrll 		return EIO;
   2696       1.1  christos 	}
   2697       1.1  christos 
   2698       1.1  christos 	error = urtw_led_ctl(sc, URTW_LED_CTL_TX);
   2699       1.1  christos 	if (error != 0)
   2700       1.1  christos 		printf("%s: could not control LED (%d)\n",
   2701       1.1  christos 		    device_xname(sc->sc_dev), error);
   2702       1.1  christos 
   2703       1.7     skrll 	sc->sc_tx_queued[prior]++;
   2704       1.1  christos 
   2705       1.7     skrll 	return 0;
   2706       1.1  christos }
   2707       1.1  christos 
   2708  1.15.2.2    martin static usbd_status
   2709       1.1  christos urtw_8225_usb_init(struct urtw_softc *sc)
   2710       1.1  christos {
   2711       1.1  christos 	uint8_t data;
   2712       1.1  christos 	usbd_status error;
   2713       1.1  christos 
   2714       1.1  christos 	urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 0);
   2715       1.1  christos 	urtw_write8_m(sc, URTW_GPIO, 0);
   2716       1.1  christos 	error = urtw_read8e(sc, 0x53, &data);
   2717       1.1  christos 	if (error)
   2718       1.1  christos 		goto fail;
   2719       1.1  christos 	error = urtw_write8e(sc, 0x53, data | (1 << 7));
   2720       1.1  christos 	if (error)
   2721       1.1  christos 		goto fail;
   2722       1.1  christos 	urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 4);
   2723       1.1  christos 	urtw_write8_m(sc, URTW_GPIO, 0x20);
   2724       1.1  christos 	urtw_write8_m(sc, URTW_GP_ENABLE, 0);
   2725       1.1  christos 
   2726       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x80);
   2727       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x80);
   2728       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x80);
   2729       1.1  christos 
   2730       1.1  christos 	usbd_delay_ms(sc->sc_udev, 500);
   2731       1.1  christos fail:
   2732       1.7     skrll 	return error;
   2733       1.1  christos }
   2734       1.1  christos 
   2735  1.15.2.2    martin static usbd_status
   2736       1.1  christos urtw_8185_rf_pins_enable(struct urtw_softc *sc)
   2737       1.1  christos {
   2738       1.1  christos 	usbd_status error = 0;
   2739       1.1  christos 
   2740       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1ff7);
   2741       1.1  christos fail:
   2742       1.7     skrll 	return error;
   2743       1.1  christos }
   2744       1.1  christos 
   2745  1.15.2.2    martin static usbd_status
   2746       1.1  christos urtw_8187_write_phy(struct urtw_softc *sc, uint8_t addr, uint32_t data)
   2747       1.1  christos {
   2748       1.1  christos 	uint32_t phyw;
   2749       1.1  christos 	usbd_status error;
   2750       1.1  christos 
   2751       1.1  christos 	phyw = ((data << 8) | (addr | 0x80));
   2752       1.1  christos 	urtw_write8_m(sc, 0x7f, ((phyw & 0xff000000) >> 24));
   2753       1.1  christos 	urtw_write8_m(sc, 0x7e, ((phyw & 0x00ff0000) >> 16));
   2754       1.1  christos 	urtw_write8_m(sc, 0x7d, ((phyw & 0x0000ff00) >> 8));
   2755       1.1  christos 	urtw_write8_m(sc, 0x7c, ((phyw & 0x000000ff)));
   2756       1.1  christos 	/*
   2757       1.1  christos 	 * Delay removed from 8185 to 8187.
   2758       1.1  christos 	 * usbd_delay_ms(sc->sc_udev, 1);
   2759       1.1  christos 	 */
   2760       1.1  christos fail:
   2761       1.7     skrll 	return error;
   2762       1.1  christos }
   2763       1.1  christos 
   2764  1.15.2.2    martin static usbd_status
   2765       1.1  christos urtw_8187_write_phy_ofdm_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
   2766       1.1  christos {
   2767       1.1  christos 	data = data & 0xff;
   2768       1.7     skrll 	return urtw_8187_write_phy(sc, addr, data);
   2769       1.1  christos }
   2770       1.1  christos 
   2771  1.15.2.2    martin static usbd_status
   2772       1.1  christos urtw_8187_write_phy_cck_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
   2773       1.1  christos {
   2774       1.1  christos 	data = data & 0xff;
   2775       1.7     skrll 	return urtw_8187_write_phy(sc, addr, data | 0x10000);
   2776       1.1  christos }
   2777       1.1  christos 
   2778  1.15.2.2    martin static usbd_status
   2779       1.1  christos urtw_8225_setgain(struct urtw_softc *sc, int16_t gain)
   2780       1.1  christos {
   2781       1.1  christos 	usbd_status error;
   2782       1.1  christos 
   2783       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0x0d, urtw_8225_gain[gain * 4]);
   2784       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0x1b, urtw_8225_gain[gain * 4 + 2]);
   2785       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0x1d, urtw_8225_gain[gain * 4 + 3]);
   2786       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0x23, urtw_8225_gain[gain * 4 + 1]);
   2787       1.1  christos fail:
   2788       1.7     skrll 	return error;
   2789       1.1  christos }
   2790       1.1  christos 
   2791  1.15.2.2    martin static usbd_status
   2792       1.1  christos urtw_8225_set_txpwrlvl(struct urtw_softc *sc, int chan)
   2793       1.1  christos {
   2794       1.1  christos 	int i, idx, set;
   2795       1.1  christos 	uint8_t *cck_pwltable;
   2796       1.1  christos 	uint8_t cck_pwrlvl_max, ofdm_pwrlvl_min, ofdm_pwrlvl_max;
   2797       1.1  christos 	uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
   2798       1.1  christos 	uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
   2799       1.1  christos 	usbd_status error;
   2800       1.1  christos 
   2801       1.1  christos 	cck_pwrlvl_max = 11;
   2802       1.1  christos 	ofdm_pwrlvl_max = 25;	/* 12 -> 25 */
   2803       1.1  christos 	ofdm_pwrlvl_min = 10;
   2804       1.1  christos 
   2805       1.1  christos 	/* CCK power setting */
   2806       1.1  christos 	cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
   2807       1.1  christos 	idx = cck_pwrlvl % 6;
   2808       1.1  christos 	set = cck_pwrlvl / 6;
   2809       1.1  christos 	cck_pwltable = (chan == 14) ? urtw_8225_txpwr_cck_ch14 :
   2810       1.1  christos 	    urtw_8225_txpwr_cck;
   2811       1.1  christos 
   2812       1.1  christos 	urtw_write8_m(sc, URTW_TX_GAIN_CCK,
   2813       1.1  christos 	    urtw_8225_tx_gain_cck_ofdm[set] >> 1);
   2814       1.1  christos 	for (i = 0; i < 8; i++) {
   2815       1.1  christos 		urtw_8187_write_phy_cck(sc, 0x44 + i,
   2816       1.1  christos 		    cck_pwltable[idx * 8 + i]);
   2817       1.1  christos 	}
   2818       1.1  christos 	usbd_delay_ms(sc->sc_udev, 1);
   2819       1.1  christos 
   2820       1.1  christos 	/* OFDM power setting */
   2821       1.1  christos 	ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
   2822       1.1  christos 	    ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
   2823       1.1  christos 	ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
   2824       1.1  christos 
   2825       1.1  christos 	idx = ofdm_pwrlvl % 6;
   2826       1.1  christos 	set = ofdm_pwrlvl / 6;
   2827       1.1  christos 
   2828       1.1  christos 	error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON);
   2829       1.1  christos 	if (error)
   2830       1.1  christos 		goto fail;
   2831       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 2, 0x42);
   2832       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 6, 0);
   2833       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 8, 0);
   2834       1.1  christos 
   2835       1.1  christos 	urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
   2836       1.1  christos 	    urtw_8225_tx_gain_cck_ofdm[set] >> 1);
   2837       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0x5, urtw_8225_txpwr_ofdm[idx]);
   2838       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0x7, urtw_8225_txpwr_ofdm[idx]);
   2839       1.1  christos 	usbd_delay_ms(sc->sc_udev, 1);
   2840       1.1  christos fail:
   2841       1.7     skrll 	return error;
   2842       1.1  christos }
   2843       1.1  christos 
   2844  1.15.2.2    martin static usbd_status
   2845       1.1  christos urtw_8185_tx_antenna(struct urtw_softc *sc, uint8_t ant)
   2846       1.1  christos {
   2847       1.1  christos 	usbd_status error;
   2848       1.1  christos 
   2849       1.1  christos 	urtw_write8_m(sc, URTW_TX_ANTENNA, ant);
   2850       1.1  christos 	usbd_delay_ms(sc->sc_udev, 1);
   2851       1.1  christos fail:
   2852       1.7     skrll 	return error;
   2853       1.1  christos }
   2854       1.1  christos 
   2855  1.15.2.2    martin static usbd_status
   2856       1.1  christos urtw_8225_rf_init(struct urtw_rf *rf)
   2857       1.1  christos {
   2858       1.1  christos 	struct urtw_softc *sc = rf->rf_sc;
   2859       1.1  christos 	unsigned int i;
   2860       1.1  christos 	uint16_t data;
   2861       1.1  christos 	usbd_status error;
   2862       1.1  christos 
   2863       1.1  christos 	error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON);
   2864       1.1  christos 	if (error)
   2865       1.1  christos 		goto fail;
   2866       1.1  christos 
   2867       1.1  christos 	error = urtw_8225_usb_init(sc);
   2868       1.1  christos 	if (error)
   2869       1.1  christos 		goto fail;
   2870       1.1  christos 
   2871       1.1  christos 	urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
   2872       1.1  christos 	urtw_read16_m(sc, URTW_8187_BRSR, &data);	/* XXX ??? */
   2873       1.1  christos 	urtw_write16_m(sc, URTW_8187_BRSR, 0xffff);
   2874       1.1  christos 	urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
   2875       1.1  christos 
   2876       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
   2877       1.1  christos 	if (error)
   2878       1.1  christos 		goto fail;
   2879       1.1  christos 	urtw_write8_m(sc, URTW_CONFIG3, 0x44);
   2880       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
   2881       1.1  christos 	if (error)
   2882       1.1  christos 		goto fail;
   2883       1.1  christos 
   2884       1.1  christos 	error = urtw_8185_rf_pins_enable(sc);
   2885       1.1  christos 	if (error)
   2886       1.1  christos 		goto fail;
   2887       1.1  christos 
   2888       1.1  christos 	usbd_delay_ms(sc->sc_udev, 500);
   2889       1.1  christos 
   2890       1.1  christos 	for (i = 0; i < __arraycount(urtw_8225_rf_part1); i++) {
   2891       1.1  christos 		urtw_8225_write(sc, urtw_8225_rf_part1[i].reg,
   2892       1.1  christos 		    urtw_8225_rf_part1[i].val);
   2893       1.1  christos 	}
   2894       1.1  christos 	usbd_delay_ms(sc->sc_udev, 50);
   2895       1.1  christos 	urtw_8225_write(sc, 0x2, 0xc4d);
   2896       1.1  christos 	usbd_delay_ms(sc->sc_udev, 200);
   2897       1.1  christos 	urtw_8225_write(sc, 0x2, 0x44d);
   2898       1.1  christos 	usbd_delay_ms(sc->sc_udev, 200);
   2899       1.1  christos 	urtw_8225_write(sc, 0x0, 0x127);
   2900       1.1  christos 
   2901       1.1  christos 	for (i = 0; i < __arraycount(urtw_8225_rxgain); i++) {
   2902       1.1  christos 		urtw_8225_write(sc, 0x1, (uint8_t)(i + 1));
   2903       1.1  christos 		urtw_8225_write(sc, 0x2, urtw_8225_rxgain[i]);
   2904       1.1  christos 	}
   2905       1.1  christos 
   2906       1.1  christos 	urtw_8225_write(sc, 0x0, 0x27);
   2907       1.1  christos 	urtw_8225_write(sc, 0x0, 0x22f);
   2908       1.1  christos 
   2909       1.1  christos 	for (i = 0; i < __arraycount(urtw_8225_agc); i++) {
   2910       1.1  christos 		urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
   2911       1.1  christos 		urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
   2912       1.1  christos 	}
   2913       1.1  christos 
   2914       1.1  christos 	for (i = 0; i < __arraycount(urtw_8225_rf_part2); i++) {
   2915       1.1  christos 		urtw_8187_write_phy_ofdm(sc, urtw_8225_rf_part2[i].reg,
   2916       1.1  christos 		    urtw_8225_rf_part2[i].val);
   2917       1.1  christos 		usbd_delay_ms(sc->sc_udev, 1);
   2918       1.1  christos 	}
   2919       1.1  christos 
   2920       1.1  christos 	error = urtw_8225_setgain(sc, 4);
   2921       1.1  christos 	if (error)
   2922       1.1  christos 		goto fail;
   2923       1.1  christos 
   2924       1.1  christos 	for (i = 0; i < __arraycount(urtw_8225_rf_part3); i++) {
   2925       1.1  christos 		urtw_8187_write_phy_cck(sc, urtw_8225_rf_part3[i].reg,
   2926       1.1  christos 		    urtw_8225_rf_part3[i].val);
   2927       1.1  christos 		usbd_delay_ms(sc->sc_udev, 1);
   2928       1.1  christos 	}
   2929       1.1  christos 
   2930       1.1  christos 	urtw_write8_m(sc, 0x5b, 0x0d);
   2931       1.1  christos 
   2932       1.1  christos 	error = urtw_8225_set_txpwrlvl(sc, 1);
   2933       1.1  christos 	if (error)
   2934       1.1  christos 		goto fail;
   2935       1.1  christos 
   2936       1.1  christos 	urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
   2937       1.1  christos 	usbd_delay_ms(sc->sc_udev, 1);
   2938       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
   2939       1.1  christos 	usbd_delay_ms(sc->sc_udev, 1);
   2940       1.1  christos 
   2941       1.1  christos 	/* TX ant A, 0x0 for B */
   2942       1.1  christos 	error = urtw_8185_tx_antenna(sc, 0x3);
   2943       1.1  christos 	if (error)
   2944       1.1  christos 		goto fail;
   2945       1.1  christos 	urtw_write32_m(sc, 0x94, 0x3dc00002);
   2946       1.1  christos 
   2947       1.1  christos 	error = urtw_8225_rf_set_chan(rf, 1);
   2948       1.1  christos fail:
   2949       1.7     skrll 	return error;
   2950       1.1  christos }
   2951       1.1  christos 
   2952  1.15.2.2    martin static usbd_status
   2953       1.1  christos urtw_8225_rf_set_chan(struct urtw_rf *rf, int chan)
   2954       1.1  christos {
   2955       1.1  christos 	struct urtw_softc *sc = rf->rf_sc;
   2956       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   2957       1.1  christos 	struct ieee80211_channel *c = ic->ic_ibss_chan;
   2958       1.1  christos 	usbd_status error;
   2959       1.1  christos 
   2960       1.1  christos 	error = urtw_8225_set_txpwrlvl(sc, chan);
   2961       1.1  christos 	if (error)
   2962       1.1  christos 		goto fail;
   2963       1.1  christos 	urtw_8225_write(sc, 0x7, urtw_8225_channel[chan]);
   2964       1.1  christos 	usbd_delay_ms(sc->sc_udev, 10);
   2965       1.1  christos 
   2966       1.1  christos 	urtw_write8_m(sc, URTW_SIFS, 0x22);
   2967       1.1  christos 
   2968       1.1  christos 	if (sc->sc_state == IEEE80211_S_ASSOC &&
   2969       1.1  christos 	    ic->ic_flags & IEEE80211_F_SHSLOT)
   2970       1.1  christos 		urtw_write8_m(sc, URTW_SLOT, 0x9);
   2971       1.1  christos 	else
   2972       1.1  christos 		urtw_write8_m(sc, URTW_SLOT, 0x14);
   2973       1.1  christos 
   2974       1.1  christos 	if (IEEE80211_IS_CHAN_G(c)) {
   2975       1.1  christos 		urtw_write8_m(sc, URTW_DIFS, 0x14);
   2976       1.1  christos 		urtw_write8_m(sc, URTW_8187_EIFS, 0x5b - 0x14);
   2977       1.1  christos 		urtw_write8_m(sc, URTW_CW_VAL, 0x73);
   2978       1.1  christos 	} else {
   2979       1.1  christos 		urtw_write8_m(sc, URTW_DIFS, 0x24);
   2980       1.1  christos 		urtw_write8_m(sc, URTW_8187_EIFS, 0x5b - 0x24);
   2981       1.1  christos 		urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
   2982       1.1  christos 	}
   2983       1.1  christos 
   2984       1.1  christos fail:
   2985       1.7     skrll 	return error;
   2986       1.1  christos }
   2987       1.1  christos 
   2988  1.15.2.2    martin static usbd_status
   2989       1.1  christos urtw_8225_rf_set_sens(struct urtw_rf *rf)
   2990       1.1  christos {
   2991       1.1  christos 	struct urtw_softc *sc = rf->rf_sc;
   2992       1.1  christos 	usbd_status error;
   2993       1.1  christos 
   2994       1.1  christos 	if (rf->sens > 6)
   2995       1.7     skrll 		return -1;
   2996       1.1  christos 
   2997       1.1  christos 	if (rf->sens > 4)
   2998       1.1  christos 		urtw_8225_write(sc, 0x0c, 0x850);
   2999       1.1  christos 	else
   3000       1.1  christos 		urtw_8225_write(sc, 0x0c, 0x50);
   3001       1.1  christos 
   3002       1.1  christos 	rf->sens = 6 - rf->sens;
   3003       1.1  christos 	error = urtw_8225_setgain(sc, rf->sens);
   3004       1.1  christos 	if (error)
   3005       1.1  christos 		goto fail;
   3006       1.1  christos 
   3007       1.1  christos 	urtw_8187_write_phy_cck(sc, 0x41, urtw_8225_threshold[rf->sens]);
   3008       1.1  christos 
   3009       1.1  christos fail:
   3010       1.7     skrll 	return error;
   3011       1.1  christos }
   3012       1.1  christos 
   3013  1.15.2.2    martin static void
   3014       1.1  christos urtw_stop(struct ifnet *ifp, int disable)
   3015       1.1  christos {
   3016       1.1  christos 	struct urtw_softc *sc = ifp->if_softc;
   3017       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   3018       1.1  christos 	uint8_t data;
   3019       1.1  christos 	usbd_status error;
   3020       1.1  christos 
   3021       1.1  christos 	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
   3022       1.1  christos 
   3023       1.1  christos 	sc->sc_txtimer = 0;
   3024       1.1  christos 	ifp->if_timer = 0;
   3025       1.1  christos 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
   3026       1.1  christos 
   3027       1.1  christos 	callout_stop(&sc->scan_to);
   3028       1.1  christos 	callout_stop(&sc->sc_led_ch);
   3029       1.1  christos 
   3030       1.1  christos 	urtw_intr_disable(sc);
   3031       1.1  christos 	urtw_read8_m(sc, URTW_CMD, &data);
   3032       1.1  christos 	data &= ~URTW_CMD_TX_ENABLE;
   3033       1.1  christos 	data &= ~URTW_CMD_RX_ENABLE;
   3034       1.1  christos 	urtw_write8_m(sc, URTW_CMD, data);
   3035       1.1  christos 
   3036       1.1  christos 	if (sc->sc_rxpipe != NULL)
   3037       1.1  christos 		usbd_abort_pipe(sc->sc_rxpipe);
   3038       1.1  christos 	if (sc->sc_txpipe_low != NULL)
   3039       1.1  christos 		usbd_abort_pipe(sc->sc_txpipe_low);
   3040       1.1  christos 	if (sc->sc_txpipe_normal != NULL)
   3041       1.1  christos 		usbd_abort_pipe(sc->sc_txpipe_normal);
   3042       1.1  christos 
   3043       1.1  christos fail:
   3044       1.1  christos 	return;
   3045       1.1  christos }
   3046       1.1  christos 
   3047  1.15.2.2    martin static int
   3048       1.1  christos urtw_isbmode(uint16_t rate)
   3049       1.1  christos {
   3050       1.1  christos 	rate = urtw_rtl2rate(rate);
   3051       1.1  christos 
   3052       1.7     skrll 	return ((rate <= 22 && rate != 12 && rate != 18) ||
   3053       1.7     skrll 	    rate == 44) ? 1 : 0;
   3054       1.1  christos }
   3055       1.1  christos 
   3056  1.15.2.2    martin static void
   3057       1.7     skrll urtw_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
   3058       1.1  christos {
   3059       1.1  christos 	struct urtw_rx_data *data = priv;
   3060       1.1  christos 	struct urtw_softc *sc = data->sc;
   3061       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   3062       1.1  christos 	struct ifnet *ifp = ic->ic_ifp;
   3063       1.1  christos 	struct ieee80211_frame *wh;
   3064       1.1  christos 	struct ieee80211_node *ni;
   3065       1.1  christos 	struct mbuf *m, *mnew;
   3066       1.1  christos 	uint8_t *desc, quality, rate;
   3067       1.6  christos 	int actlen, flen, len, rssi, s;
   3068       1.1  christos 
   3069       1.1  christos 	if (status != USBD_NORMAL_COMPLETION) {
   3070       1.1  christos 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
   3071       1.1  christos 			return;
   3072       1.1  christos 
   3073       1.1  christos 		if (status == USBD_STALLED)
   3074       1.1  christos 			usbd_clear_endpoint_stall_async(sc->sc_rxpipe);
   3075  1.15.2.2    martin 		if_statinc(ifp, if_ierrors);
   3076       1.1  christos 		goto skip;
   3077       1.1  christos 	}
   3078       1.1  christos 
   3079       1.1  christos 	usbd_get_xfer_status(xfer, NULL, NULL, &actlen, NULL);
   3080       1.1  christos 	if (actlen < URTW_MIN_RXBUFSZ) {
   3081  1.15.2.2    martin 		if_statinc(ifp, if_ierrors);
   3082       1.1  christos 		goto skip;
   3083       1.1  christos 	}
   3084       1.1  christos 
   3085       1.1  christos 	if (sc->sc_hwrev & URTW_HWREV_8187)
   3086       1.1  christos 		/* 4 dword and 4 byte CRC */
   3087       1.1  christos 		len = actlen - (4 * 4);
   3088       1.1  christos 	else
   3089       1.1  christos 		/* 5 dword and 4 byte CRC */
   3090       1.1  christos 		len = actlen - (4 * 5);
   3091       1.1  christos 
   3092       1.1  christos 	desc = data->buf + len;
   3093       1.1  christos 	flen = ((desc[1] & 0x0f) << 8) + (desc[0] & 0xff);
   3094       1.1  christos 	if (flen > actlen) {
   3095  1.15.2.2    martin 		if_statinc(ifp, if_ierrors);
   3096       1.1  christos 		goto skip;
   3097       1.1  christos 	}
   3098       1.1  christos 
   3099       1.1  christos 	rate = (desc[2] & 0xf0) >> 4;
   3100       1.1  christos 	if (sc->sc_hwrev & URTW_HWREV_8187) {
   3101       1.1  christos 		quality = desc[4] & 0xff;
   3102       1.1  christos 		rssi = (desc[6] & 0xfe) >> 1;
   3103       1.1  christos 
   3104       1.1  christos 		/* XXX correct? */
   3105       1.1  christos 		if (!urtw_isbmode(rate)) {
   3106       1.1  christos 			rssi = (rssi > 90) ? 90 : ((rssi < 25) ? 25 : rssi);
   3107       1.1  christos 			rssi = ((90 - rssi) * 100) / 65;
   3108       1.1  christos 		} else {
   3109       1.1  christos 			rssi = (rssi > 90) ? 95 : ((rssi < 30) ? 30 : rssi);
   3110       1.1  christos 			rssi = ((95 - rssi) * 100) / 65;
   3111       1.1  christos 		}
   3112       1.1  christos 	} else {
   3113       1.1  christos 		quality = desc[12];
   3114       1.1  christos 		rssi = 14 - desc[14] / 2;
   3115       1.1  christos 	}
   3116       1.1  christos 
   3117       1.1  christos 	MGETHDR(mnew, M_DONTWAIT, MT_DATA);
   3118       1.1  christos 	if (mnew == NULL) {
   3119       1.1  christos 		printf("%s: could not allocate rx mbuf\n",
   3120       1.1  christos 		    device_xname(sc->sc_dev));
   3121  1.15.2.2    martin 		if_statinc(ifp, if_ierrors);
   3122       1.1  christos 		goto skip;
   3123       1.1  christos 	}
   3124       1.1  christos 	MCLGET(mnew, M_DONTWAIT);
   3125       1.1  christos 	if (!(mnew->m_flags & M_EXT)) {
   3126       1.1  christos 		printf("%s: could not allocate rx mbuf cluster\n",
   3127       1.1  christos 		    device_xname(sc->sc_dev));
   3128       1.1  christos 		m_freem(mnew);
   3129  1.15.2.2    martin 		if_statinc(ifp, if_ierrors);
   3130       1.1  christos 		goto skip;
   3131       1.1  christos 	}
   3132       1.1  christos 
   3133       1.1  christos 	m = data->m;
   3134       1.1  christos 	data->m = mnew;
   3135       1.1  christos 	data->buf = mtod(mnew, uint8_t *);
   3136       1.1  christos 
   3137       1.1  christos 	/* finalize mbuf */
   3138      1.10     ozaki 	m_set_rcvif(m, ifp);
   3139       1.1  christos 	m->m_pkthdr.len = m->m_len = flen - 4;
   3140       1.1  christos 
   3141       1.1  christos 	s = splnet();
   3142       1.1  christos 
   3143       1.1  christos 	if (sc->sc_drvbpf != NULL) {
   3144       1.1  christos 		struct urtw_rx_radiotap_header *tap = &sc->sc_rxtap;
   3145       1.1  christos 
   3146       1.1  christos 		/* XXX Are variables correct? */
   3147       1.1  christos 		tap->wr_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
   3148       1.1  christos 		tap->wr_chan_flags = htole16(ic->ic_ibss_chan->ic_flags);
   3149       1.1  christos 		tap->wr_dbm_antsignal = (int8_t)rssi;
   3150       1.1  christos 
   3151      1.15   msaitoh 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m, BPF_D_IN);
   3152       1.1  christos 	}
   3153       1.1  christos 	wh = mtod(m, struct ieee80211_frame *);
   3154       1.1  christos 	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA)
   3155       1.1  christos 		sc->sc_currate = (rate > 0) ? rate : sc->sc_currate;
   3156       1.1  christos 	ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
   3157       1.1  christos 
   3158       1.1  christos 	/* XXX correct? */
   3159       1.1  christos 	if (!urtw_isbmode(rate)) {
   3160       1.1  christos 		if (quality > 127)
   3161       1.1  christos 			quality = 0;
   3162       1.1  christos 		else if (quality < 27)
   3163       1.1  christos 			quality = 100;
   3164       1.1  christos 		else
   3165       1.1  christos 			quality = 127 - quality;
   3166       1.1  christos 	} else
   3167       1.1  christos 		quality = (quality > 64) ? 0 : ((64 - quality) * 100) / 64;
   3168       1.1  christos 
   3169       1.1  christos 	/* send the frame to the 802.11 layer */
   3170       1.1  christos 	ieee80211_input(ic, m, ni, rssi, 0);
   3171       1.1  christos 
   3172       1.1  christos 	/* node is no longer needed */
   3173       1.1  christos 	ieee80211_free_node(ni);
   3174       1.1  christos 
   3175       1.1  christos 	splx(s);
   3176       1.1  christos 
   3177       1.1  christos skip:	/* setup a new transfer */
   3178       1.7     skrll 	usbd_setup_xfer(xfer, data, data->buf, MCLBYTES,
   3179       1.1  christos 	    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urtw_rxeof);
   3180       1.1  christos 	(void)usbd_transfer(xfer);
   3181       1.1  christos }
   3182       1.1  christos 
   3183  1.15.2.2    martin static usbd_status
   3184       1.1  christos urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain)
   3185       1.1  christos {
   3186       1.1  christos 	uint8_t *gainp;
   3187       1.1  christos 	usbd_status error;
   3188       1.1  christos 
   3189       1.1  christos 	/* XXX for A? */
   3190       1.1  christos 	gainp = urtw_8225v2_gain_bg;
   3191       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0x0d, gainp[gain * 3]);
   3192       1.1  christos 	usbd_delay_ms(sc->sc_udev, 1);
   3193       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0x1b, gainp[gain * 3 + 1]);
   3194       1.1  christos 	usbd_delay_ms(sc->sc_udev, 1);
   3195       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0x1d, gainp[gain * 3 + 2]);
   3196       1.1  christos 	usbd_delay_ms(sc->sc_udev, 1);
   3197       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0x21, 0x17);
   3198       1.1  christos 	usbd_delay_ms(sc->sc_udev, 1);
   3199       1.1  christos fail:
   3200       1.7     skrll 	return error;
   3201       1.1  christos }
   3202       1.1  christos 
   3203  1.15.2.2    martin static usbd_status
   3204       1.1  christos urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan)
   3205       1.1  christos {
   3206       1.1  christos 	int i;
   3207       1.1  christos 	uint8_t *cck_pwrtable;
   3208       1.1  christos 	uint8_t cck_pwrlvl_max = 15, ofdm_pwrlvl_max = 25, ofdm_pwrlvl_min = 10;
   3209       1.1  christos 	uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
   3210       1.1  christos 	uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
   3211       1.1  christos 	usbd_status error;
   3212       1.1  christos 
   3213       1.1  christos 	/* CCK power setting */
   3214       1.1  christos 	cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
   3215       1.1  christos 	cck_pwrlvl += sc->sc_txpwr_cck_base;
   3216       1.1  christos 	cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
   3217       1.1  christos 	cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
   3218       1.1  christos 	    urtw_8225v2_txpwr_cck;
   3219       1.1  christos 
   3220       1.1  christos 	for (i = 0; i < 8; i++) {
   3221       1.1  christos 		urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
   3222       1.1  christos 	}
   3223       1.1  christos 	urtw_write8_m(sc, URTW_TX_GAIN_CCK,
   3224       1.1  christos 	    urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl]);
   3225       1.1  christos 	usbd_delay_ms(sc->sc_udev, 1);
   3226       1.1  christos 
   3227       1.1  christos 	/* OFDM power setting */
   3228       1.1  christos 	ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
   3229       1.1  christos 		ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
   3230       1.1  christos 	ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
   3231       1.1  christos 	ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
   3232       1.1  christos 
   3233       1.1  christos 	error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON);
   3234       1.1  christos 	if (error)
   3235       1.1  christos 		goto fail;
   3236       1.1  christos 
   3237       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 2, 0x42);
   3238       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 5, 0x0);
   3239       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 6, 0x40);
   3240       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 7, 0x0);
   3241       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 8, 0x40);
   3242       1.1  christos 
   3243       1.1  christos 	urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
   3244       1.1  christos 	    urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl]);
   3245       1.1  christos 	usbd_delay_ms(sc->sc_udev, 1);
   3246       1.1  christos fail:
   3247       1.7     skrll 	return error;
   3248       1.1  christos }
   3249       1.1  christos 
   3250  1.15.2.2    martin static usbd_status
   3251       1.1  christos urtw_8225v2_rf_init(struct urtw_rf *rf)
   3252       1.1  christos {
   3253       1.1  christos 	struct urtw_softc *sc = rf->rf_sc;
   3254       1.1  christos 	int i;
   3255       1.1  christos 	uint16_t data;
   3256       1.1  christos 	uint32_t data32;
   3257       1.1  christos 	usbd_status error;
   3258       1.1  christos 
   3259       1.1  christos 	error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON);
   3260       1.1  christos 	if (error)
   3261       1.1  christos 		goto fail;
   3262       1.1  christos 
   3263       1.1  christos 	error = urtw_8225_usb_init(sc);
   3264       1.1  christos 	if (error)
   3265       1.1  christos 		goto fail;
   3266       1.1  christos 
   3267       1.1  christos 	urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
   3268       1.1  christos 	urtw_read16_m(sc, URTW_8187_BRSR, &data);	/* XXX ??? */
   3269       1.1  christos 	urtw_write16_m(sc, URTW_8187_BRSR, 0xffff);
   3270       1.1  christos 	urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
   3271       1.1  christos 
   3272       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
   3273       1.1  christos 	if (error)
   3274       1.1  christos 		goto fail;
   3275       1.1  christos 	urtw_write8_m(sc, URTW_CONFIG3, 0x44);
   3276       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
   3277       1.1  christos 	if (error)
   3278       1.1  christos 		goto fail;
   3279       1.1  christos 
   3280       1.1  christos 	error = urtw_8185_rf_pins_enable(sc);
   3281       1.1  christos 	if (error)
   3282       1.1  christos 		goto fail;
   3283       1.1  christos 
   3284       1.1  christos 	usbd_delay_ms(sc->sc_udev, 1000);
   3285       1.1  christos 
   3286       1.1  christos 	for (i = 0; i < __arraycount(urtw_8225v2_rf_part1); i++) {
   3287       1.1  christos 		urtw_8225_write(sc, urtw_8225v2_rf_part1[i].reg,
   3288       1.1  christos 		    urtw_8225v2_rf_part1[i].val);
   3289       1.1  christos 		usbd_delay_ms(sc->sc_udev, 1);
   3290       1.1  christos 	}
   3291       1.1  christos 	usbd_delay_ms(sc->sc_udev, 50);
   3292       1.1  christos 
   3293       1.1  christos 	urtw_8225_write(sc, 0x0, 0x1b7);
   3294       1.1  christos 
   3295       1.1  christos 	for (i = 0; i < __arraycount(urtw_8225v2_rxgain); i++) {
   3296       1.1  christos 		urtw_8225_write(sc, 0x1, (uint8_t)(i + 1));
   3297       1.1  christos 		urtw_8225_write(sc, 0x2, urtw_8225v2_rxgain[i]);
   3298       1.1  christos 	}
   3299       1.1  christos 
   3300       1.1  christos 	urtw_8225_write(sc, 0x3, 0x2);
   3301       1.1  christos 	urtw_8225_write(sc, 0x5, 0x4);
   3302       1.1  christos 	urtw_8225_write(sc, 0x0, 0xb7);
   3303       1.1  christos 	urtw_8225_write(sc, 0x2, 0xc4d);
   3304       1.1  christos 	usbd_delay_ms(sc->sc_udev, 100);
   3305       1.1  christos 	urtw_8225_write(sc, 0x2, 0x44d);
   3306       1.1  christos 	usbd_delay_ms(sc->sc_udev, 100);
   3307       1.1  christos 
   3308       1.1  christos 	error = urtw_8225_read(sc, 0x6, &data32);
   3309       1.1  christos 	if (error != 0)
   3310       1.1  christos 		goto fail;
   3311       1.1  christos 	if (data32 != 0xe6)
   3312  1.15.2.2    martin 		printf("%s: expect 0xe6!! (%#x)\n", device_xname(sc->sc_dev),
   3313       1.1  christos 		    data32);
   3314       1.1  christos 	if (!(data32 & 0x80)) {
   3315       1.1  christos 		urtw_8225_write(sc, 0x02, 0x0c4d);
   3316       1.1  christos 		usbd_delay_ms(sc->sc_udev, 200);
   3317       1.1  christos 		urtw_8225_write(sc, 0x02, 0x044d);
   3318       1.1  christos 		usbd_delay_ms(sc->sc_udev, 100);
   3319       1.1  christos 		error = urtw_8225_read(sc, 0x6, &data32);
   3320       1.1  christos 		if (error != 0)
   3321       1.1  christos 			goto fail;
   3322       1.1  christos 		if (!(data32 & 0x80))
   3323       1.1  christos 			printf("%s: RF calibration failed\n",
   3324       1.1  christos 			    device_xname(sc->sc_dev));
   3325       1.1  christos 	}
   3326       1.1  christos 	usbd_delay_ms(sc->sc_udev, 100);
   3327       1.1  christos 
   3328       1.1  christos 	urtw_8225_write(sc, 0x0, 0x2bf);
   3329       1.1  christos 	for (i = 0; i < __arraycount(urtw_8225_agc); i++) {
   3330       1.1  christos 		urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
   3331       1.1  christos 		urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
   3332       1.1  christos 	}
   3333       1.1  christos 
   3334       1.1  christos 	for (i = 0; i < __arraycount(urtw_8225v2_rf_part2); i++) {
   3335       1.1  christos 		urtw_8187_write_phy_ofdm(sc, urtw_8225v2_rf_part2[i].reg,
   3336       1.1  christos 		    urtw_8225v2_rf_part2[i].val);
   3337       1.1  christos 	}
   3338       1.1  christos 
   3339       1.1  christos 	error = urtw_8225v2_setgain(sc, 4);
   3340       1.1  christos 	if (error)
   3341       1.1  christos 		goto fail;
   3342       1.1  christos 
   3343       1.1  christos 	for (i = 0; i < __arraycount(urtw_8225v2_rf_part3); i++) {
   3344       1.1  christos 		urtw_8187_write_phy_cck(sc, urtw_8225v2_rf_part3[i].reg,
   3345       1.1  christos 		    urtw_8225v2_rf_part3[i].val);
   3346       1.1  christos 	}
   3347       1.1  christos 
   3348       1.1  christos 	urtw_write8_m(sc, 0x5b, 0x0d);
   3349       1.1  christos 
   3350       1.1  christos 	error = urtw_8225v2_set_txpwrlvl(sc, 1);
   3351       1.1  christos 	if (error)
   3352       1.1  christos 		goto fail;
   3353       1.1  christos 
   3354       1.1  christos 	urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
   3355       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
   3356       1.1  christos 
   3357       1.1  christos 	/* TX ant A, 0x0 for B */
   3358       1.1  christos 	error = urtw_8185_tx_antenna(sc, 0x3);
   3359       1.1  christos 	if (error)
   3360       1.1  christos 		goto fail;
   3361       1.1  christos 	urtw_write32_m(sc, 0x94, 0x3dc00002);
   3362       1.1  christos 
   3363       1.1  christos 	error = urtw_8225_rf_set_chan(rf, 1);
   3364       1.1  christos fail:
   3365       1.7     skrll 	return error;
   3366       1.1  christos }
   3367       1.1  christos 
   3368  1.15.2.2    martin static usbd_status
   3369       1.1  christos urtw_8225v2_rf_set_chan(struct urtw_rf *rf, int chan)
   3370       1.1  christos {
   3371       1.1  christos 	struct urtw_softc *sc = rf->rf_sc;
   3372       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   3373       1.1  christos 	struct ieee80211_channel *c = ic->ic_ibss_chan;
   3374       1.1  christos 	usbd_status error;
   3375       1.1  christos 
   3376       1.1  christos 	error = urtw_8225v2_set_txpwrlvl(sc, chan);
   3377       1.1  christos 	if (error)
   3378       1.1  christos 		goto fail;
   3379       1.1  christos 
   3380       1.1  christos 	urtw_8225_write(sc, 0x7, urtw_8225_channel[chan]);
   3381       1.1  christos 	usbd_delay_ms(sc->sc_udev, 10);
   3382       1.1  christos 
   3383       1.1  christos 	urtw_write8_m(sc, URTW_SIFS, 0x22);
   3384       1.1  christos 
   3385       1.1  christos 	if(sc->sc_state == IEEE80211_S_ASSOC &&
   3386       1.1  christos 	    ic->ic_flags & IEEE80211_F_SHSLOT)
   3387       1.1  christos 		urtw_write8_m(sc, URTW_SLOT, 0x9);
   3388       1.1  christos 	else
   3389       1.1  christos 		urtw_write8_m(sc, URTW_SLOT, 0x14);
   3390       1.1  christos 
   3391       1.1  christos 	if (IEEE80211_IS_CHAN_G(c)) {
   3392       1.1  christos 		urtw_write8_m(sc, URTW_DIFS, 0x14);
   3393       1.1  christos 		urtw_write8_m(sc, URTW_8187_EIFS, 0x5b - 0x14);
   3394       1.1  christos 		urtw_write8_m(sc, URTW_CW_VAL, 0x73);
   3395       1.1  christos 	} else {
   3396       1.1  christos 		urtw_write8_m(sc, URTW_DIFS, 0x24);
   3397       1.1  christos 		urtw_write8_m(sc, URTW_8187_EIFS, 0x5b - 0x24);
   3398       1.1  christos 		urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
   3399       1.1  christos 	}
   3400       1.1  christos 
   3401       1.1  christos fail:
   3402       1.7     skrll 	return error;
   3403       1.1  christos }
   3404       1.1  christos 
   3405  1.15.2.2    martin static void
   3406       1.1  christos urtw_set_chan(struct urtw_softc *sc, struct ieee80211_channel *c)
   3407       1.1  christos {
   3408       1.1  christos 	struct urtw_rf *rf = &sc->sc_rf;
   3409       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   3410       1.1  christos 	usbd_status error = 0;
   3411       1.1  christos 	uint32_t data;
   3412       1.1  christos 	u_int chan;
   3413       1.1  christos 
   3414       1.1  christos 	chan = ieee80211_chan2ieee(ic, c);
   3415       1.1  christos 	if (chan == 0 || chan == IEEE80211_CHAN_ANY)
   3416       1.1  christos 		return;
   3417       1.1  christos 	/*
   3418       1.1  christos 	 * During changing the channel we need to temporary disable
   3419       1.1  christos 	 * TX.
   3420       1.1  christos 	 */
   3421       1.1  christos 	urtw_read32_m(sc, URTW_TX_CONF, &data);
   3422       1.1  christos 	data &= ~URTW_TX_LOOPBACK_MASK;
   3423       1.1  christos 	urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_MAC);
   3424       1.1  christos 	error = rf->set_chan(rf, chan);
   3425       1.1  christos 	if (error != 0) {
   3426       1.1  christos 		printf("%s could not change the channel\n",
   3427       1.1  christos 		    device_xname(sc->sc_dev));
   3428       1.1  christos 		return;
   3429       1.1  christos 	}
   3430       1.1  christos 	usbd_delay_ms(sc->sc_udev, 10);
   3431       1.1  christos 	urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_NONE);
   3432       1.1  christos 
   3433       1.1  christos fail:	return;
   3434       1.1  christos 
   3435       1.1  christos }
   3436       1.1  christos 
   3437  1.15.2.2    martin static void
   3438       1.1  christos urtw_next_scan(void *arg)
   3439       1.1  christos {
   3440       1.1  christos 	struct urtw_softc *sc = arg;
   3441       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   3442       1.1  christos 	int s;
   3443       1.1  christos 
   3444       1.1  christos 	if (sc->sc_dying)
   3445       1.1  christos 		return;
   3446       1.1  christos 
   3447       1.1  christos 	s = splnet();
   3448       1.1  christos 	if (ic->ic_state == IEEE80211_S_SCAN)
   3449       1.1  christos 		ieee80211_next_scan(ic);
   3450       1.1  christos 	splx(s);
   3451       1.1  christos }
   3452       1.1  christos 
   3453  1.15.2.2    martin static void
   3454       1.1  christos urtw_task(void *arg)
   3455       1.1  christos {
   3456       1.1  christos 	struct urtw_softc *sc = arg;
   3457       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   3458       1.1  christos 	struct ieee80211_node *ni;
   3459       1.1  christos 	enum ieee80211_state ostate;
   3460       1.1  christos 	usbd_status error = 0;
   3461       1.1  christos 
   3462       1.1  christos 	if (sc->sc_dying)
   3463       1.1  christos 		return;
   3464       1.1  christos 
   3465       1.1  christos 	ostate = ic->ic_state;
   3466       1.1  christos 
   3467       1.1  christos 	switch (sc->sc_state) {
   3468       1.1  christos 	case IEEE80211_S_INIT:
   3469       1.1  christos 		if (ostate == IEEE80211_S_RUN) {
   3470       1.1  christos 			/* turn link LED off */
   3471       1.1  christos 			(void)urtw_led_off(sc, URTW_LED_GPIO);
   3472       1.1  christos 		}
   3473       1.1  christos 		break;
   3474       1.1  christos 
   3475       1.1  christos 	case IEEE80211_S_SCAN:
   3476       1.1  christos 		urtw_set_chan(sc, ic->ic_curchan);
   3477       1.1  christos 		if (!sc->sc_dying)
   3478       1.1  christos 			callout_schedule(&sc->scan_to, mstohz(200));
   3479       1.1  christos 		break;
   3480       1.1  christos 
   3481       1.1  christos 	case IEEE80211_S_AUTH:
   3482       1.1  christos 	case IEEE80211_S_ASSOC:
   3483       1.1  christos 		urtw_set_chan(sc, ic->ic_curchan);
   3484       1.1  christos 		break;
   3485       1.1  christos 
   3486       1.1  christos 	case IEEE80211_S_RUN:
   3487       1.1  christos 		ni = ic->ic_bss;
   3488       1.1  christos 
   3489       1.1  christos 		urtw_set_chan(sc, ic->ic_curchan);
   3490       1.1  christos 
   3491       1.1  christos 		/* setting bssid. */
   3492       1.1  christos 		error = urtw_set_bssid(sc, ni->ni_bssid);
   3493       1.1  christos 		if (error != 0)
   3494       1.1  christos 			goto fail;
   3495       1.1  christos 		urtw_update_msr(sc);
   3496       1.1  christos 		/* XXX maybe the below would be incorrect. */
   3497       1.1  christos 		urtw_write16_m(sc, URTW_ATIM_WND, 2);
   3498       1.1  christos 		urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
   3499       1.1  christos 		urtw_write16_m(sc, URTW_BEACON_INTERVAL, 0x64);
   3500       1.1  christos 		urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 0x3ff);
   3501       1.1  christos 		error = urtw_led_ctl(sc, URTW_LED_CTL_LINK);
   3502       1.1  christos 		if (error != 0)
   3503       1.1  christos 			printf("%s: could not control LED (%d)\n",
   3504       1.1  christos 			    device_xname(sc->sc_dev), error);
   3505       1.1  christos 		break;
   3506       1.1  christos 	}
   3507       1.1  christos 
   3508       1.1  christos 	sc->sc_newstate(ic, sc->sc_state, sc->sc_arg);
   3509       1.1  christos 
   3510       1.1  christos fail:
   3511       1.1  christos 	if (error != 0) {
   3512       1.1  christos 		DPRINTF(("%s: error duing processing RUN state.",
   3513       1.1  christos 		    device_xname(sc->sc_dev)));
   3514       1.1  christos 	}
   3515       1.1  christos }
   3516       1.1  christos 
   3517  1.15.2.2    martin static usbd_status
   3518       1.1  christos urtw_8187b_update_wmm(struct urtw_softc *sc)
   3519       1.1  christos {
   3520       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   3521       1.1  christos 	struct ieee80211_channel *c = ic->ic_ibss_chan;
   3522       1.1  christos 	uint32_t data;
   3523       1.1  christos 	uint8_t aifs, sifs, slot, ecwmin, ecwmax;
   3524       1.1  christos 	usbd_status error;
   3525       1.1  christos 
   3526       1.1  christos 	sifs = 0xa;
   3527       1.1  christos 	if (IEEE80211_IS_CHAN_G(c))
   3528       1.1  christos 		slot = 0x9;
   3529       1.1  christos 	else
   3530       1.1  christos 		slot = 0x14;
   3531       1.1  christos 
   3532       1.1  christos 	aifs = (2 * slot) + sifs;
   3533       1.1  christos 	ecwmin = 3;
   3534       1.1  christos 	ecwmax = 7;
   3535       1.1  christos 
   3536       1.1  christos 	data = ((uint32_t)aifs << 0) |		/* AIFS, offset 0 */
   3537       1.1  christos 	    ((uint32_t)ecwmin << 8) |		/* ECW minimum, offset 8 */
   3538       1.1  christos 	    ((uint32_t)ecwmax << 12);		/* ECW maximum, offset 16 */
   3539       1.1  christos 
   3540       1.1  christos 	urtw_write32_m(sc, URTW_AC_VO, data);
   3541       1.1  christos 	urtw_write32_m(sc, URTW_AC_VI, data);
   3542       1.1  christos 	urtw_write32_m(sc, URTW_AC_BE, data);
   3543       1.1  christos 	urtw_write32_m(sc, URTW_AC_BK, data);
   3544       1.1  christos 
   3545       1.1  christos fail:
   3546       1.7     skrll 	return error;
   3547       1.1  christos }
   3548       1.1  christos 
   3549  1.15.2.2    martin static usbd_status
   3550       1.1  christos urtw_8187b_reset(struct urtw_softc *sc)
   3551       1.1  christos {
   3552       1.1  christos 	uint8_t data;
   3553       1.1  christos 	usbd_status error;
   3554       1.1  christos 
   3555       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
   3556       1.1  christos 	if (error)
   3557       1.1  christos 		goto fail;
   3558       1.1  christos 
   3559       1.1  christos 	urtw_read8_m(sc, URTW_CONFIG3, &data);
   3560       1.1  christos 	urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE |
   3561       1.1  christos 		URTW_CONFIG3_GNT_SELECT);
   3562       1.1  christos 
   3563       1.1  christos 	urtw_write32_m(sc, URTW_ANAPARAM2, URTW_8187B_8225_ANAPARAM2_ON);
   3564       1.1  christos 	urtw_write32_m(sc, URTW_ANAPARAM, URTW_8187B_8225_ANAPARAM_ON);
   3565       1.1  christos 	urtw_write8_m(sc, URTW_ANAPARAM3, URTW_8187B_8225_ANAPARAM3_ON);
   3566       1.1  christos 
   3567       1.1  christos 	urtw_write8_m(sc, 0x61, 0x10);
   3568       1.1  christos 	urtw_read8_m(sc, 0x62, &data);
   3569       1.1  christos 	urtw_write8_m(sc, 0x62, data & ~(1 << 5));
   3570       1.1  christos 	urtw_write8_m(sc, 0x62, data | (1 << 5));
   3571       1.1  christos 
   3572       1.1  christos 	urtw_read8_m(sc, URTW_CONFIG3, &data);
   3573       1.1  christos 	urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
   3574       1.1  christos 
   3575       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
   3576       1.1  christos 	if (error)
   3577       1.1  christos 		goto fail;
   3578       1.1  christos 
   3579       1.1  christos 	urtw_read8_m(sc, URTW_CMD, &data);
   3580       1.1  christos 	data = (data & 2) | URTW_CMD_RST;
   3581       1.1  christos 	urtw_write8_m(sc, URTW_CMD, data);
   3582       1.1  christos 	usbd_delay_ms(sc->sc_udev, 100);
   3583       1.1  christos 
   3584       1.1  christos 	urtw_read8_m(sc, URTW_CMD, &data);
   3585       1.1  christos 	if (data & URTW_CMD_RST) {
   3586       1.1  christos 		printf("%s: reset timeout\n", device_xname(sc->sc_dev));
   3587       1.1  christos 		goto fail;
   3588       1.1  christos 	}
   3589       1.1  christos 
   3590       1.1  christos fail:
   3591       1.7     skrll 	return error;
   3592       1.1  christos }
   3593       1.1  christos 
   3594  1.15.2.2    martin static int
   3595       1.1  christos urtw_8187b_init(struct ifnet *ifp)
   3596       1.1  christos {
   3597       1.1  christos 	struct urtw_softc *sc = ifp->if_softc;
   3598       1.1  christos 	struct urtw_rf *rf = &sc->sc_rf;
   3599       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   3600       1.1  christos 	uint8_t data;
   3601       1.1  christos 	usbd_status error;
   3602       1.1  christos 
   3603       1.1  christos 	urtw_stop(ifp, 0);
   3604       1.1  christos 
   3605       1.1  christos 	error = urtw_8187b_update_wmm(sc);
   3606       1.1  christos 	if (error != 0)
   3607       1.1  christos 		goto fail;
   3608       1.1  christos 	error = urtw_8187b_reset(sc);
   3609       1.1  christos 	if (error)
   3610       1.1  christos 		goto fail;
   3611       1.1  christos 
   3612       1.1  christos 	/* Applying MAC address again. */
   3613       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
   3614       1.1  christos 	if (error)
   3615       1.1  christos 		goto fail;
   3616       1.1  christos 	IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
   3617       1.1  christos 	error = urtw_set_macaddr(sc, ic->ic_myaddr);
   3618       1.1  christos 	if (error)
   3619       1.1  christos 		goto fail;
   3620       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
   3621       1.1  christos 	if (error)
   3622       1.1  christos 		goto fail;
   3623       1.1  christos 
   3624       1.1  christos 	error = urtw_update_msr(sc);
   3625       1.1  christos 	if (error)
   3626       1.1  christos 		goto fail;
   3627       1.1  christos 
   3628       1.1  christos 	error = rf->init(rf);
   3629       1.1  christos 	if (error != 0)
   3630       1.1  christos 		goto fail;
   3631       1.1  christos 
   3632       1.1  christos 	urtw_write8_m(sc, URTW_CMD, URTW_CMD_TX_ENABLE |
   3633       1.1  christos 		URTW_CMD_RX_ENABLE);
   3634       1.1  christos 	error = urtw_intr_enable(sc);
   3635       1.1  christos 	if (error != 0)
   3636       1.1  christos 		goto fail;
   3637       1.1  christos 
   3638       1.1  christos 	error = urtw_write8e(sc, 0x41, 0xf4);
   3639       1.1  christos 	if (error != 0)
   3640       1.1  christos 		goto fail;
   3641       1.1  christos 	error = urtw_write8e(sc, 0x40, 0x00);
   3642       1.1  christos 	if (error != 0)
   3643       1.1  christos 		goto fail;
   3644       1.1  christos 	error = urtw_write8e(sc, 0x42, 0x00);
   3645       1.1  christos 	if (error != 0)
   3646       1.1  christos 		goto fail;
   3647       1.1  christos 	error = urtw_write8e(sc, 0x42, 0x01);
   3648       1.1  christos 	if (error != 0)
   3649       1.1  christos 		goto fail;
   3650       1.1  christos 	error = urtw_write8e(sc, 0x40, 0x0f);
   3651       1.1  christos 	if (error != 0)
   3652       1.1  christos 		goto fail;
   3653       1.1  christos 	error = urtw_write8e(sc, 0x42, 0x00);
   3654       1.1  christos 	if (error != 0)
   3655       1.1  christos 		goto fail;
   3656       1.1  christos 	error = urtw_write8e(sc, 0x42, 0x01);
   3657       1.1  christos 	if (error != 0)
   3658       1.1  christos 		goto fail;
   3659       1.1  christos 
   3660       1.1  christos 	urtw_read8_m(sc, 0xdb, &data);
   3661       1.1  christos 	urtw_write8_m(sc, 0xdb, data | (1 << 2));
   3662       1.1  christos 	urtw_write16_idx_m(sc, 0x72, 0x59fa, 3);
   3663       1.1  christos 	urtw_write16_idx_m(sc, 0x74, 0x59d2, 3);
   3664       1.1  christos 	urtw_write16_idx_m(sc, 0x76, 0x59d2, 3);
   3665       1.1  christos 	urtw_write16_idx_m(sc, 0x78, 0x19fa, 3);
   3666       1.1  christos 	urtw_write16_idx_m(sc, 0x7a, 0x19fa, 3);
   3667       1.1  christos 	urtw_write16_idx_m(sc, 0x7c, 0x00d0, 3);
   3668       1.1  christos 	urtw_write8_m(sc, 0x61, 0);
   3669       1.1  christos 	urtw_write8_idx_m(sc, 0x80, 0x0f, 1);
   3670       1.1  christos 	urtw_write8_idx_m(sc, 0x83, 0x03, 1);
   3671       1.1  christos 	urtw_write8_m(sc, 0xda, 0x10);
   3672       1.1  christos 	urtw_write8_idx_m(sc, 0x4d, 0x08, 2);
   3673       1.1  christos 
   3674       1.1  christos 	urtw_write32_m(sc, URTW_HSSI_PARA, 0x0600321b);
   3675       1.1  christos 
   3676       1.1  christos 	urtw_write16_idx_m(sc, 0xec, 0x0800, 1);
   3677       1.1  christos 
   3678       1.1  christos 	urtw_write8_m(sc, URTW_ACM_CONTROL, 0);
   3679       1.1  christos 
   3680       1.1  christos 	/* Reset softc variables. */
   3681       1.7     skrll 	for (size_t j = 0; j < URTW_PRIORITY_MAX; j++) {
   3682       1.7     skrll 		sc->sc_txidx[j] = sc->sc_tx_queued[j] = 0;
   3683       1.7     skrll 	}
   3684       1.1  christos 	sc->sc_txtimer = 0;
   3685       1.1  christos 
   3686       1.1  christos 	if (!(sc->sc_flags & URTW_INIT_ONCE)) {
   3687       1.1  christos 		error = usbd_set_config_no(sc->sc_udev, URTW_CONFIG_NO, 0);
   3688       1.1  christos 		if (error != 0) {
   3689       1.2     skrll 			aprint_error_dev(sc->sc_dev, "failed to set configuration"
   3690       1.2     skrll 			    ", err=%s\n", usbd_errstr(error));
   3691       1.2     skrll 
   3692       1.1  christos 			goto fail;
   3693       1.1  christos 		}
   3694       1.1  christos 		/* Get the first interface handle. */
   3695       1.1  christos 		error = usbd_device2interface_handle(sc->sc_udev,
   3696       1.1  christos 		    URTW_IFACE_INDEX, &sc->sc_iface);
   3697       1.1  christos 		if (error != 0) {
   3698       1.1  christos 			printf("%s: could not get interface handle\n",
   3699       1.1  christos 			    device_xname(sc->sc_dev));
   3700       1.1  christos 			goto fail;
   3701       1.1  christos 		}
   3702       1.1  christos 		error = urtw_open_pipes(sc);
   3703       1.1  christos 		if (error != 0)
   3704       1.1  christos 			goto fail;
   3705       1.6  christos 		error = urtw_alloc_rx_data_list(sc);
   3706       1.1  christos 		if (error != 0)
   3707       1.1  christos 			goto fail;
   3708       1.6  christos 		error = urtw_alloc_tx_data_list(sc);
   3709       1.1  christos 		if (error != 0)
   3710       1.1  christos 			goto fail;
   3711       1.1  christos 		sc->sc_flags |= URTW_INIT_ONCE;
   3712       1.1  christos 	}
   3713       1.1  christos 
   3714       1.1  christos 	error = urtw_rx_enable(sc);
   3715       1.1  christos 	if (error != 0)
   3716       1.1  christos 		goto fail;
   3717       1.1  christos 	error = urtw_tx_enable(sc);
   3718       1.1  christos 	if (error != 0)
   3719       1.1  christos 		goto fail;
   3720       1.1  christos 
   3721       1.1  christos 	ifp->if_flags &= ~IFF_OACTIVE;
   3722       1.1  christos 	ifp->if_flags |= IFF_RUNNING;
   3723       1.1  christos 
   3724       1.1  christos 	if (ic->ic_opmode == IEEE80211_M_MONITOR)
   3725       1.1  christos 		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
   3726       1.1  christos 	else
   3727       1.1  christos 		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
   3728       1.1  christos 
   3729       1.1  christos fail:
   3730       1.7     skrll 	return error;
   3731       1.1  christos }
   3732       1.1  christos 
   3733  1.15.2.2    martin static usbd_status
   3734       1.1  christos urtw_8225v2_b_config_mac(struct urtw_softc *sc)
   3735       1.1  christos {
   3736       1.1  christos 	int i;
   3737       1.1  christos 	usbd_status error;
   3738       1.1  christos 
   3739       1.1  christos 	for (i = 0; i < __arraycount(urtw_8187b_regtbl); i++) {
   3740       1.1  christos 		urtw_write8_idx_m(sc, urtw_8187b_regtbl[i].reg,
   3741       1.1  christos 		    urtw_8187b_regtbl[i].val, urtw_8187b_regtbl[i].idx);
   3742       1.1  christos 	}
   3743       1.1  christos 
   3744       1.1  christos 	urtw_write16_m(sc, URTW_TID_AC_MAP, 0xfa50);
   3745       1.1  christos 	urtw_write16_m(sc, URTW_INT_MIG, 0);
   3746       1.1  christos 
   3747       1.1  christos 	urtw_write32_idx_m(sc, 0xf0, 0, 1);
   3748       1.1  christos 	urtw_write32_idx_m(sc, 0xf4, 0, 1);
   3749       1.1  christos 	urtw_write8_idx_m(sc, 0xf8, 0, 1);
   3750       1.1  christos 
   3751       1.1  christos 	urtw_write32_m(sc, URTW_RF_TIMING, 0x00004001);
   3752       1.1  christos 
   3753       1.1  christos fail:
   3754       1.7     skrll 	return error;
   3755       1.1  christos }
   3756       1.1  christos 
   3757  1.15.2.2    martin static usbd_status
   3758       1.1  christos urtw_8225v2_b_init_rfe(struct urtw_softc *sc)
   3759       1.1  christos {
   3760       1.1  christos 	usbd_status error;
   3761       1.1  christos 
   3762       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x0480);
   3763       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x2488);
   3764       1.1  christos 	urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1fff);
   3765       1.1  christos 	usbd_delay_ms(sc->sc_udev, 100);
   3766       1.1  christos 
   3767       1.1  christos fail:
   3768       1.7     skrll 	return error;
   3769       1.1  christos }
   3770       1.1  christos 
   3771  1.15.2.2    martin static usbd_status
   3772       1.1  christos urtw_8225v2_b_update_chan(struct urtw_softc *sc)
   3773       1.1  christos {
   3774       1.1  christos 	struct ieee80211com *ic = &sc->sc_ic;
   3775       1.1  christos 	struct ieee80211_channel *c = ic->ic_ibss_chan;
   3776       1.1  christos 	uint8_t aifs, difs, eifs, sifs, slot;
   3777       1.1  christos 	usbd_status error;
   3778       1.1  christos 
   3779       1.1  christos 	urtw_write8_m(sc, URTW_SIFS, 0x22);
   3780       1.1  christos 
   3781       1.1  christos 	sifs = 0xa;
   3782       1.1  christos 	if (IEEE80211_IS_CHAN_G(c)) {
   3783       1.1  christos 		slot = 0x9;
   3784       1.1  christos 		difs = 0x1c;
   3785       1.1  christos 		eifs = 0x5b;
   3786       1.1  christos 	} else {
   3787       1.1  christos 		slot = 0x14;
   3788       1.1  christos 		difs = 0x32;
   3789       1.1  christos 		eifs = 0x5b;
   3790       1.1  christos 	}
   3791       1.1  christos 	aifs = (2 * slot) + sifs;
   3792       1.1  christos 
   3793       1.1  christos 	urtw_write8_m(sc, URTW_SLOT, slot);
   3794       1.1  christos 
   3795       1.1  christos 	urtw_write8_m(sc, URTW_AC_VO, aifs);
   3796       1.1  christos 	urtw_write8_m(sc, URTW_AC_VI, aifs);
   3797       1.1  christos 	urtw_write8_m(sc, URTW_AC_BE, aifs);
   3798       1.1  christos 	urtw_write8_m(sc, URTW_AC_BK, aifs);
   3799       1.1  christos 
   3800       1.1  christos 	urtw_write8_m(sc, URTW_DIFS, difs);
   3801       1.1  christos 	urtw_write8_m(sc, URTW_8187B_EIFS, eifs);
   3802       1.1  christos 
   3803       1.1  christos fail:
   3804       1.7     skrll 	return error;
   3805       1.1  christos }
   3806       1.1  christos 
   3807  1.15.2.2    martin static usbd_status
   3808       1.1  christos urtw_8225v2_b_rf_init(struct urtw_rf *rf)
   3809       1.1  christos {
   3810       1.1  christos 	struct urtw_softc *sc = rf->rf_sc;
   3811       1.1  christos 	unsigned int i;
   3812       1.1  christos 	uint8_t data;
   3813       1.1  christos 	usbd_status error;
   3814       1.1  christos 
   3815       1.1  christos 	/* Set up ACK rate, retry limit, TX AGC, TX antenna. */
   3816       1.1  christos 	urtw_write16_m(sc, URTW_8187B_BRSR, 0x0fff);
   3817       1.1  christos 	urtw_read8_m(sc, URTW_CW_CONF, &data);
   3818       1.1  christos 	urtw_write8_m(sc, URTW_CW_CONF, data |
   3819       1.1  christos 		URTW_CW_CONF_PERPACKET_RETRY);
   3820       1.1  christos 	urtw_read8_m(sc, URTW_TX_AGC_CTL, &data);
   3821       1.1  christos 	urtw_write8_m(sc, URTW_TX_AGC_CTL, data |
   3822       1.1  christos 		URTW_TX_AGC_CTL_PERPACKET_GAIN |
   3823       1.1  christos 		URTW_TX_AGC_CTL_PERPACKET_ANTSEL);
   3824       1.1  christos 
   3825       1.1  christos 	/* Auto rate fallback control. */
   3826       1.1  christos 	urtw_write16_idx_m(sc, URTW_ARFR, 0x0fff, 1);	/* 1M ~ 54M */
   3827       1.1  christos 	urtw_read8_m(sc, URTW_RATE_FALLBACK, &data);
   3828       1.1  christos 	urtw_write8_m(sc, URTW_RATE_FALLBACK, data |
   3829       1.1  christos 		URTW_RATE_FALLBACK_ENABLE);
   3830       1.1  christos 
   3831       1.1  christos 	urtw_write16_m(sc, URTW_BEACON_INTERVAL, 100);
   3832       1.1  christos 	urtw_write16_m(sc, URTW_ATIM_WND, 2);
   3833       1.1  christos 	urtw_write16_idx_m(sc, URTW_FEMR, 0xffff, 1);
   3834       1.1  christos 
   3835       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
   3836       1.1  christos 	if (error)
   3837       1.1  christos 		goto fail;
   3838       1.1  christos 	urtw_read8_m(sc, URTW_CONFIG1, &data);
   3839       1.1  christos 	urtw_write8_m(sc, URTW_CONFIG1, (data & 0x3f) | 0x80);
   3840       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
   3841       1.1  christos 	if (error)
   3842       1.1  christos 		goto fail;
   3843       1.1  christos 
   3844       1.1  christos 	urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
   3845       1.1  christos 	urtw_8225v2_b_config_mac(sc);
   3846       1.1  christos 	urtw_write16_idx_m(sc, URTW_RFSW_CTRL, 0x569a, 2);
   3847       1.1  christos 
   3848       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
   3849       1.1  christos 	if (error)
   3850       1.1  christos 		goto fail;
   3851       1.1  christos 	urtw_read8_m(sc, URTW_CONFIG3, &data);
   3852       1.1  christos 	urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
   3853       1.1  christos 	error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
   3854       1.1  christos 	if (error)
   3855       1.1  christos 		goto fail;
   3856       1.1  christos 
   3857       1.1  christos 	urtw_8225v2_b_init_rfe(sc);
   3858       1.1  christos 
   3859       1.1  christos 	for (i = 0; i < __arraycount(urtw_8225v2_b_rf); i++) {
   3860       1.1  christos 		urtw_8225_write(sc, urtw_8225v2_b_rf[i].reg,
   3861       1.1  christos 		    urtw_8225v2_b_rf[i].val);
   3862       1.1  christos 	}
   3863       1.1  christos 
   3864       1.1  christos 	for (i = 0; i < __arraycount(urtw_8225v2_rxgain); i++) {
   3865       1.1  christos 		urtw_8225_write(sc, 0x1, (uint8_t)(i + 1));
   3866       1.1  christos 		urtw_8225_write(sc, 0x2, urtw_8225v2_rxgain[i]);
   3867       1.1  christos 	}
   3868       1.1  christos 
   3869       1.1  christos 	urtw_8225_write(sc, 0x03, 0x080);
   3870       1.1  christos 	urtw_8225_write(sc, 0x05, 0x004);
   3871       1.1  christos 	urtw_8225_write(sc, 0x00, 0x0b7);
   3872       1.1  christos 	urtw_8225_write(sc, 0x02, 0xc4d);
   3873       1.1  christos 	urtw_8225_write(sc, 0x02, 0x44d);
   3874       1.1  christos 	urtw_8225_write(sc, 0x00, 0x2bf);
   3875       1.1  christos 
   3876       1.1  christos 	urtw_write8_m(sc, URTW_TX_GAIN_CCK, 0x03);
   3877       1.1  christos 	urtw_write8_m(sc, URTW_TX_GAIN_OFDM, 0x07);
   3878       1.1  christos 	urtw_write8_m(sc, URTW_TX_ANTENNA, 0x03);
   3879       1.1  christos 
   3880       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0x80, 0x12);
   3881       1.1  christos 	for (i = 0; i < __arraycount(urtw_8225v2_agc); i++) {
   3882       1.1  christos 		urtw_8187_write_phy_ofdm(sc, 0x0f, urtw_8225v2_agc[i]);
   3883       1.1  christos 		urtw_8187_write_phy_ofdm(sc, 0x0e, (uint8_t)i + 0x80);
   3884       1.1  christos 		urtw_8187_write_phy_ofdm(sc, 0x0e, 0);
   3885       1.1  christos 	}
   3886       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0x80, 0x10);
   3887       1.1  christos 
   3888       1.1  christos 	for (i = 0; i < __arraycount(urtw_8225v2_ofdm); i++)
   3889       1.1  christos 		urtw_8187_write_phy_ofdm(sc, i, urtw_8225v2_ofdm[i]);
   3890       1.1  christos 
   3891       1.1  christos 	urtw_8225v2_b_update_chan(sc);
   3892       1.1  christos 
   3893       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0x97, 0x46);
   3894       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0xa4, 0xb6);
   3895       1.1  christos 	urtw_8187_write_phy_ofdm(sc, 0x85, 0xfc);
   3896       1.1  christos 	urtw_8187_write_phy_cck(sc, 0xc1, 0x88);
   3897       1.1  christos 
   3898       1.1  christos 	error = urtw_8225v2_b_rf_set_chan(rf, 1);
   3899       1.1  christos fail:
   3900       1.7     skrll 	return error;
   3901       1.1  christos }
   3902       1.1  christos 
   3903  1.15.2.2    martin static usbd_status
   3904       1.1  christos urtw_8225v2_b_rf_set_chan(struct urtw_rf *rf, int chan)
   3905       1.1  christos {
   3906       1.1  christos 	struct urtw_softc *sc = rf->rf_sc;
   3907       1.1  christos 	usbd_status error;
   3908       1.1  christos 
   3909       1.1  christos 	error = urtw_8225v2_b_set_txpwrlvl(sc, chan);
   3910       1.1  christos 	if (error)
   3911       1.1  christos 		goto fail;
   3912       1.1  christos 
   3913       1.1  christos 	urtw_8225_write(sc, 0x7, urtw_8225_channel[chan]);
   3914       1.1  christos 	/*
   3915       1.1  christos 	 * Delay removed from 8185 to 8187.
   3916       1.1  christos 	 * usbd_delay_ms(sc->sc_udev, 10);
   3917       1.1  christos 	 */
   3918       1.1  christos 
   3919       1.1  christos 	urtw_write16_m(sc, URTW_AC_VO, 0x5114);
   3920       1.1  christos 	urtw_write16_m(sc, URTW_AC_VI, 0x5114);
   3921       1.1  christos 	urtw_write16_m(sc, URTW_AC_BE, 0x5114);
   3922       1.1  christos 	urtw_write16_m(sc, URTW_AC_BK, 0x5114);
   3923       1.1  christos 
   3924       1.1  christos fail:
   3925       1.7     skrll 	return error;
   3926       1.1  christos }
   3927       1.1  christos 
   3928  1.15.2.2    martin static usbd_status
   3929       1.1  christos urtw_8225v2_b_set_txpwrlvl(struct urtw_softc *sc, int chan)
   3930       1.1  christos {
   3931       1.1  christos 	int i;
   3932       1.1  christos 	uint8_t *cck_pwrtable;
   3933       1.1  christos 	uint8_t cck_pwrlvl_min, cck_pwrlvl_max, ofdm_pwrlvl_min,
   3934       1.1  christos 	    ofdm_pwrlvl_max;
   3935       1.1  christos 	int8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
   3936       1.1  christos 	int8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
   3937       1.1  christos 	usbd_status error;
   3938       1.1  christos 
   3939       1.1  christos 	if (sc->sc_hwrev & URTW_HWREV_8187B_B) {
   3940       1.1  christos 		cck_pwrlvl_min = 0;
   3941       1.1  christos 		cck_pwrlvl_max = 15;
   3942       1.1  christos 		ofdm_pwrlvl_min = 2;
   3943       1.1  christos 		ofdm_pwrlvl_max = 17;
   3944       1.1  christos 	} else {
   3945       1.1  christos 		cck_pwrlvl_min = 7;
   3946       1.1  christos 		cck_pwrlvl_max = 22;
   3947       1.1  christos 		ofdm_pwrlvl_min = 10;
   3948       1.1  christos 		ofdm_pwrlvl_max = 25;
   3949       1.1  christos 	}
   3950       1.1  christos 
   3951       1.1  christos 	/* CCK power setting */
   3952       1.1  christos 	cck_pwrlvl = (cck_pwrlvl > (cck_pwrlvl_max - cck_pwrlvl_min)) ?
   3953       1.1  christos 	    cck_pwrlvl_max : (cck_pwrlvl + cck_pwrlvl_min);
   3954       1.1  christos 
   3955       1.1  christos 	cck_pwrlvl += sc->sc_txpwr_cck_base;
   3956       1.1  christos 	cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
   3957       1.1  christos 	cck_pwrlvl = (cck_pwrlvl < 0) ? 0 : cck_pwrlvl;
   3958       1.1  christos 
   3959       1.1  christos 	cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
   3960       1.1  christos 	    urtw_8225v2_txpwr_cck;
   3961       1.1  christos 
   3962       1.1  christos 	if (sc->sc_hwrev & URTW_HWREV_8187B_B) {
   3963       1.1  christos 		if (cck_pwrlvl <= 6)
   3964       1.1  christos 			; /* do nothing */
   3965       1.1  christos 		else if (cck_pwrlvl <= 11)
   3966       1.1  christos 			cck_pwrtable += 8;
   3967       1.1  christos 		else
   3968       1.1  christos 			cck_pwrtable += 16;
   3969       1.1  christos 	} else {
   3970       1.1  christos 		if (cck_pwrlvl <= 5)
   3971       1.1  christos 			; /* do nothing */
   3972       1.1  christos 		else if (cck_pwrlvl <= 11)
   3973       1.1  christos 			cck_pwrtable += 8;
   3974       1.1  christos 		else if (cck_pwrlvl <= 17)
   3975       1.1  christos 			cck_pwrtable += 16;
   3976       1.1  christos 		else
   3977       1.1  christos 			cck_pwrtable += 24;
   3978       1.1  christos 	}
   3979       1.1  christos 
   3980       1.1  christos 	for (i = 0; i < 8; i++) {
   3981       1.1  christos 		urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
   3982       1.1  christos 	}
   3983       1.1  christos 
   3984       1.1  christos 	urtw_write8_m(sc, URTW_TX_GAIN_CCK,
   3985       1.1  christos 	    urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl] << 1);
   3986       1.1  christos 	/*
   3987       1.1  christos 	 * Delay removed from 8185 to 8187.
   3988       1.1  christos 	 * usbd_delay_ms(sc->sc_udev, 1);
   3989       1.1  christos 	 */
   3990       1.1  christos 
   3991       1.1  christos 	/* OFDM power setting */
   3992       1.1  christos 	ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
   3993       1.1  christos 	    ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
   3994       1.1  christos 
   3995       1.1  christos 	ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
   3996       1.1  christos 	ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
   3997       1.1  christos 	ofdm_pwrlvl = (ofdm_pwrlvl < 0) ? 0 : ofdm_pwrlvl;
   3998       1.1  christos 
   3999       1.1  christos 	urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
   4000       1.1  christos 	    urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl] << 1);
   4001       1.1  christos 
   4002       1.1  christos 	if (sc->sc_hwrev & URTW_HWREV_8187B_B) {
   4003       1.1  christos 		if (ofdm_pwrlvl <= 11) {
   4004       1.1  christos 			urtw_8187_write_phy_ofdm(sc, 0x87, 0x60);
   4005       1.1  christos 			urtw_8187_write_phy_ofdm(sc, 0x89, 0x60);
   4006       1.1  christos 		} else {
   4007       1.1  christos 			urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
   4008       1.1  christos 			urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
   4009       1.1  christos 		}
   4010       1.1  christos 	} else {
   4011       1.1  christos 		if (ofdm_pwrlvl <= 11) {
   4012       1.1  christos 			urtw_8187_write_phy_ofdm(sc, 0x87, 0x5c);
   4013       1.1  christos 			urtw_8187_write_phy_ofdm(sc, 0x89, 0x5c);
   4014       1.1  christos 		} else if (ofdm_pwrlvl <= 17) {
   4015       1.1  christos 			urtw_8187_write_phy_ofdm(sc, 0x87, 0x54);
   4016       1.1  christos 			urtw_8187_write_phy_ofdm(sc, 0x89, 0x54);
   4017       1.1  christos 		} else {
   4018       1.1  christos 			urtw_8187_write_phy_ofdm(sc, 0x87, 0x50);
   4019       1.1  christos 			urtw_8187_write_phy_ofdm(sc, 0x89, 0x50);
   4020       1.1  christos 		}
   4021       1.1  christos 	}
   4022       1.1  christos 
   4023       1.1  christos 	/*
   4024       1.1  christos 	 * Delay removed from 8185 to 8187.
   4025       1.1  christos 	 * usbd_delay_ms(sc->sc_udev, 1);
   4026       1.1  christos 	 */
   4027       1.1  christos fail:
   4028       1.7     skrll 	return error;
   4029       1.1  christos }
   4030       1.1  christos 
   4031  1.15.2.2    martin static int
   4032       1.1  christos urtw_set_bssid(struct urtw_softc *sc, const uint8_t *bssid)
   4033       1.1  christos {
   4034       1.1  christos 	int error;
   4035       1.1  christos 
   4036       1.1  christos 	urtw_write32_m(sc, URTW_BSSID,
   4037       1.1  christos 	    bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24);
   4038       1.1  christos 	urtw_write16_m(sc, URTW_BSSID + 4,
   4039       1.1  christos 	    bssid[4] | bssid[5] << 8);
   4040       1.1  christos 
   4041       1.1  christos 	return 0;
   4042       1.1  christos 
   4043       1.1  christos fail:
   4044       1.1  christos 	return error;
   4045       1.1  christos }
   4046       1.1  christos 
   4047  1.15.2.2    martin static int
   4048       1.1  christos urtw_set_macaddr(struct urtw_softc *sc, const uint8_t *addr)
   4049       1.1  christos {
   4050       1.1  christos 	int error;
   4051       1.1  christos 
   4052       1.1  christos 	urtw_write32_m(sc, URTW_MAC0,
   4053       1.1  christos 	    addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24);
   4054       1.1  christos 	urtw_write16_m(sc, URTW_MAC4,
   4055       1.1  christos 	    addr[4] | addr[5] << 8);
   4056       1.1  christos 
   4057       1.1  christos 	return 0;
   4058       1.1  christos 
   4059       1.1  christos fail:
   4060       1.1  christos 	return error;
   4061       1.1  christos }
   4062       1.1  christos 
   4063  1.15.2.1  christos MODULE(MODULE_CLASS_DRIVER, if_urtw, NULL);
   4064       1.1  christos 
   4065       1.1  christos #ifdef _MODULE
   4066       1.1  christos #include "ioconf.c"
   4067       1.1  christos #endif
   4068       1.1  christos 
   4069       1.1  christos static int
   4070       1.1  christos if_urtw_modcmd(modcmd_t cmd, void *aux)
   4071       1.1  christos {
   4072       1.1  christos 	int error = 0;
   4073       1.1  christos 
   4074       1.1  christos 	switch (cmd) {
   4075       1.1  christos 	case MODULE_CMD_INIT:
   4076       1.1  christos #ifdef _MODULE
   4077       1.1  christos 		error = config_init_component(cfdriver_ioconf_urtw,
   4078       1.1  christos 		    cfattach_ioconf_urtw, cfdata_ioconf_urtw);
   4079       1.1  christos #endif
   4080       1.1  christos 		return error;
   4081       1.1  christos 	case MODULE_CMD_FINI:
   4082       1.1  christos #ifdef _MODULE
   4083       1.1  christos 		error = config_fini_component(cfdriver_ioconf_urtw,
   4084       1.1  christos 		    cfattach_ioconf_urtw, cfdata_ioconf_urtw);
   4085       1.1  christos #endif
   4086       1.1  christos 		return error;
   4087       1.1  christos 	default:
   4088       1.1  christos 		return ENOTTY;
   4089       1.1  christos 	}
   4090       1.1  christos }
   4091