LCOV - code coverage report
Current view: top level - dev/usb - if_urtw.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 1950 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 96 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13