svn commit: r187610 - in head: share/man/man4 sys/dev/usb
sys/modules/urtw
Weongyo Jeong
weongyo at FreeBSD.org
Thu Jan 22 21:04:50 PST 2009
Author: weongyo
Date: Fri Jan 23 05:04:49 2009
New Revision: 187610
URL: http://svn.freebsd.org/changeset/base/187610
Log:
Add a new USB wireless driver, urtw(4) for supporting Realtek's 8187L
chipset.
Added:
head/share/man/man4/urtw.4 (contents, props changed)
head/sys/dev/usb/if_urtw.c (contents, props changed)
head/sys/dev/usb/if_urtwreg.h (contents, props changed)
head/sys/dev/usb/if_urtwvar.h (contents, props changed)
head/sys/modules/urtw/
head/sys/modules/urtw/Makefile (contents, props changed)
Modified:
head/sys/dev/usb/usbdevs
Added: head/share/man/man4/urtw.4
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/share/man/man4/urtw.4 Fri Jan 23 05:04:49 2009 (r187610)
@@ -0,0 +1,118 @@
+.\" Copyright (c) 2008 Weongyo Jeong
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd November 15 2008 $
+.Dt URTW 4
+.Os
+.Sh NAME
+.Nm urtw
+.Nd Realtek RTL8187L USB IEEE 802.11b/g wireless network device
+.Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following lines in your kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device ehci"
+.Cd "device uhci"
+.Cd "device ohci"
+.Cd "device usb"
+.Cd "device urtw"
+.Cd "device wlan"
+.Ed
+.Pp
+Alternatively, to load the driver as a module at boot time,
+place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+if_urtw_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver supports USB 802.11b/g wireless adapters based on the
+Realtek RTL8187L.
+.Pp
+.Nm
+supports
+.Cm station
+and
+.Cm monitor
+mode operation.
+Only one virtual interface may be configured at any time.
+For more information on configuring this device, see
+.Xr ifconfig 8 .
+.Sh HARDWARE
+The following adapters should work:
+.Pp
+.Bl -column "Card " "Radio " "Bus" -compact -offset 6n
+.It Em "Card Radio Bus"
+.It Li "Netgear WG111v2" Ta RTL8225 Ta USB
+.It Li "Safehome WLG-1500SMA5" Ta RTL8225 Ta USB
+.It Li "Shuttle XPC Accessory PN20" Ta RTL8225 Ta USB
+.El
+.Sh EXAMPLES
+Join an existing BSS network (i.e., connect to an access point):
+.Pp
+.Bd -literal -offset indent
+ifconfig wlan create wlandev urtw0 inet 192.168.0.20 \e
+ netmask 0xffffff00
+.Ed
+.Pp
+Join a specific BSS network with network name
+.Dq Li my_net :
+.Pp
+.Dl "ifconfig wlan create wlandev urtw0 ssid my_net up"
+.Pp
+Join a specific BSS network with 64-bit WEP encryption:
+.Bd -literal -offset indent
+ifconfig wlan create wlandev urtw0 ssid my_net \e
+ wepmode on wepkey 0x1234567890 weptxkey 1 up
+.Ed
+.Sh SEE ALSO
+.Xr intro 4 ,
+.Xr netintro 4 ,
+.Xr usb 4 ,
+.Xr wlan 4 ,
+.Xr wlan_ccmp 4 ,
+.Xr wlan_tkip 4 ,
+.Xr wlan_wep 4 ,
+.Xr ifconfig 8 ,
+.Xr wpa_supplicant 8
+.Rs
+.%T Realtek
+.%O http://www.realtek.com.tw
+.Re
+.Sh HISTORY
+The
+.Nm
+device driver first appeared in
+.Fx 8.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Weongyo Jeong
+.Aq weongyo at FreeBSD.org .
Added: head/sys/dev/usb/if_urtw.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/dev/usb/if_urtw.c Fri Jan 23 05:04:49 2009 (r187610)
@@ -0,0 +1,3324 @@
+/*-
+ * Copyright (c) 2008 Weongyo Jeong <weongyo at FreeBSD.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+#include <sys/sockio.h>
+#include <sys/sysctl.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/kdb.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/ethernet.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+#endif
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_regdomain.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdi_util.h>
+#include "usbdevs.h"
+
+#include <dev/usb/if_urtwreg.h>
+#include <dev/usb/if_urtwvar.h>
+
+SYSCTL_NODE(_hw_usb, OID_AUTO, urtw, CTLFLAG_RW, 0, "USB Realtek 8187L");
+#ifdef URTW_DEBUG
+int urtw_debug = 0;
+SYSCTL_INT(_hw_usb_urtw, OID_AUTO, debug, CTLFLAG_RW, &urtw_debug, 0,
+ "control debugging printfs");
+TUNABLE_INT("hw.usb.urtw.debug", &urtw_debug);
+enum {
+ URTW_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
+ URTW_DEBUG_RECV = 0x00000002, /* basic recv operation */
+ URTW_DEBUG_RESET = 0x00000004, /* reset processing */
+ URTW_DEBUG_TX_PROC = 0x00000008, /* tx ISR proc */
+ URTW_DEBUG_RX_PROC = 0x00000010, /* rx ISR proc */
+ URTW_DEBUG_STATE = 0x00000020, /* 802.11 state transitions */
+ URTW_DEBUG_STAT = 0x00000040, /* statistic */
+ URTW_DEBUG_ANY = 0xffffffff
+};
+#define DPRINTF(sc, m, fmt, ...) do { \
+ if (sc->sc_debug & (m)) \
+ printf(fmt, __VA_ARGS__); \
+} while (0)
+#else
+#define DPRINTF(sc, m, fmt, ...) do { \
+ (void) sc; \
+} while (0)
+#endif
+int urtw_preamble_mode = URTW_PREAMBLE_MODE_LONG;
+SYSCTL_INT(_hw_usb_urtw, OID_AUTO, preamble_mode, CTLFLAG_RW,
+ &urtw_preamble_mode, 0, "set the preable mode (long or short)");
+TUNABLE_INT("hw.usb.urtw.preamble_mode", &urtw_preamble_mode);
+
+/* recognized device vendors/products */
+static const struct usb_devno urtw_devs[] = {
+#define URTW_DEV(v,p) { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }
+ URTW_DEV(REALTEK, RTL8187),
+ URTW_DEV(NETGEAR, WG111V2)
+#undef URTW_DEV
+};
+
+#define urtw_read8_m(sc, val, data) do { \
+ error = urtw_read8_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+#define urtw_write8_m(sc, val, data) do { \
+ error = urtw_write8_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+#define urtw_read16_m(sc, val, data) do { \
+ error = urtw_read16_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+#define urtw_write16_m(sc, val, data) do { \
+ error = urtw_write16_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+#define urtw_read32_m(sc, val, data) do { \
+ error = urtw_read32_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+#define urtw_write32_m(sc, val, data) do { \
+ error = urtw_write32_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+#define urtw_8187_write_phy_ofdm(sc, val, data) do { \
+ error = urtw_8187_write_phy_ofdm_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+#define urtw_8187_write_phy_cck(sc, val, data) do { \
+ error = urtw_8187_write_phy_cck_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+#define urtw_8225_write(sc, val, data) do { \
+ error = urtw_8225_write_c(sc, val, data); \
+ if (error != 0) \
+ goto fail; \
+} while (0)
+
+struct urtw_pair {
+ uint32_t reg;
+ uint32_t val;
+};
+
+static uint8_t urtw_8225_agc[] = {
+ 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b,
+ 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
+ 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85,
+ 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a,
+ 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f,
+ 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24,
+ 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19,
+ 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
+ 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
+};
+
+static uint32_t urtw_8225_channel[] = {
+ 0x0000, /* dummy channel 0 */
+ 0x085c, /* 1 */
+ 0x08dc, /* 2 */
+ 0x095c, /* 3 */
+ 0x09dc, /* 4 */
+ 0x0a5c, /* 5 */
+ 0x0adc, /* 6 */
+ 0x0b5c, /* 7 */
+ 0x0bdc, /* 8 */
+ 0x0c5c, /* 9 */
+ 0x0cdc, /* 10 */
+ 0x0d5c, /* 11 */
+ 0x0ddc, /* 12 */
+ 0x0e5c, /* 13 */
+ 0x0f72, /* 14 */
+};
+
+static uint8_t urtw_8225_gain[] = {
+ 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
+ 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
+ 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
+ 0x33, 0x80, 0x79, 0xc5, /* -78dbm */
+ 0x43, 0x78, 0x76, 0xc5, /* -74dbm */
+ 0x53, 0x60, 0x73, 0xc5, /* -70dbm */
+ 0x63, 0x58, 0x70, 0xc5, /* -66dbm */
+};
+
+static struct urtw_pair urtw_8225_rf_part1[] = {
+ { 0x00, 0x0067 }, { 0x01, 0x0fe0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
+ { 0x04, 0x0486 }, { 0x05, 0x0bc0 }, { 0x06, 0x0ae6 }, { 0x07, 0x082a },
+ { 0x08, 0x001f }, { 0x09, 0x0334 }, { 0x0a, 0x0fd4 }, { 0x0b, 0x0391 },
+ { 0x0c, 0x0050 }, { 0x0d, 0x06db }, { 0x0e, 0x0029 }, { 0x0f, 0x0914 },
+};
+
+static struct urtw_pair urtw_8225_rf_part2[] = {
+ { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
+ { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
+ { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x09 }, { 0x0b, 0x80 },
+ { 0x0c, 0x01 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 }, { 0x10, 0x84 },
+ { 0x11, 0x06 }, { 0x12, 0x20 }, { 0x13, 0x20 }, { 0x14, 0x00 },
+ { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 }, { 0x18, 0xef },
+ { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x76 }, { 0x1c, 0x04 },
+ { 0x1e, 0x95 }, { 0x1f, 0x75 }, { 0x20, 0x1f }, { 0x21, 0x27 },
+ { 0x22, 0x16 }, { 0x24, 0x46 }, { 0x25, 0x20 }, { 0x26, 0x90 },
+ { 0x27, 0x88 }
+};
+
+static struct urtw_pair urtw_8225_rf_part3[] = {
+ { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
+ { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x10, 0x9b },
+ { 0x11, 0x88 }, { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 },
+ { 0x1a, 0xa0 }, { 0x1b, 0x08 }, { 0x40, 0x86 }, { 0x41, 0x8d },
+ { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x1f }, { 0x45, 0x1e },
+ { 0x46, 0x1a }, { 0x47, 0x15 }, { 0x48, 0x10 }, { 0x49, 0x0a },
+ { 0x4a, 0x05 }, { 0x4b, 0x02 }, { 0x4c, 0x05 }
+};
+
+static uint16_t urtw_8225_rxgain[] = {
+ 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
+ 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
+ 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
+ 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
+ 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
+ 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
+ 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
+ 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
+ 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
+ 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
+ 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
+ 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
+};
+
+static uint8_t urtw_8225_threshold[] = {
+ 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
+};
+
+static uint8_t urtw_8225_tx_gain_cck_ofdm[] = {
+ 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
+};
+
+static uint8_t urtw_8225_txpwr_cck[] = {
+ 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
+ 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
+ 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
+ 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
+ 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
+ 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
+};
+
+static uint8_t urtw_8225_txpwr_cck_ch14[] = {
+ 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
+ 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
+ 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
+};
+
+static uint8_t urtw_8225_txpwr_ofdm[]={
+ 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
+};
+
+static uint8_t urtw_8225v2_gain_bg[]={
+ 0x23, 0x15, 0xa5, /* -82-1dbm */
+ 0x23, 0x15, 0xb5, /* -82-2dbm */
+ 0x23, 0x15, 0xc5, /* -82-3dbm */
+ 0x33, 0x15, 0xc5, /* -78dbm */
+ 0x43, 0x15, 0xc5, /* -74dbm */
+ 0x53, 0x15, 0xc5, /* -70dbm */
+ 0x63, 0x15, 0xc5, /* -66dbm */
+};
+
+static struct urtw_pair urtw_8225v2_rf_part1[] = {
+ { 0x00, 0x02bf }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
+ { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
+ { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
+ { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
+};
+
+static struct urtw_pair urtw_8225v2_rf_part2[] = {
+ { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
+ { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
+ { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x08 }, { 0x0b, 0x80 },
+ { 0x0c, 0x01 }, { 0x0d, 0x43 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 },
+ { 0x10, 0x84 }, { 0x11, 0x07 }, { 0x12, 0x20 }, { 0x13, 0x20 },
+ { 0x14, 0x00 }, { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 },
+ { 0x18, 0xef }, { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x15 },
+ { 0x1c, 0x04 }, { 0x1d, 0xc5 }, { 0x1e, 0x95 }, { 0x1f, 0x75 },
+ { 0x20, 0x1f }, { 0x21, 0x17 }, { 0x22, 0x16 }, { 0x23, 0x80 },
+ { 0x24, 0x46 }, { 0x25, 0x00 }, { 0x26, 0x90 }, { 0x27, 0x88 }
+};
+
+static struct urtw_pair urtw_8225v2_rf_part3[] = {
+ { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
+ { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x09, 0x11 },
+ { 0x0a, 0x17 }, { 0x0b, 0x11 }, { 0x10, 0x9b }, { 0x11, 0x88 },
+ { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 }, { 0x1a, 0xa0 },
+ { 0x1b, 0x08 }, { 0x1d, 0x00 }, { 0x40, 0x86 }, { 0x41, 0x9d },
+ { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x36 }, { 0x45, 0x35 },
+ { 0x46, 0x2e }, { 0x47, 0x25 }, { 0x48, 0x1c }, { 0x49, 0x12 },
+ { 0x4a, 0x09 }, { 0x4b, 0x04 }, { 0x4c, 0x05 }
+};
+
+static uint16_t urtw_8225v2_rxgain[] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
+ 0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
+ 0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
+ 0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
+ 0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
+ 0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
+ 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
+ 0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
+ 0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
+ 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
+ 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
+ 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
+};
+
+static uint8_t urtw_8225v2_tx_gain_cck_ofdm[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
+ 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
+ 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
+};
+
+static uint8_t urtw_8225v2_txpwr_cck[] = {
+ 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
+};
+
+static uint8_t urtw_8225v2_txpwr_cck_ch14[] = {
+ 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
+};
+
+static struct urtw_pair urtw_ratetable[] = {
+ { 2, 0 }, { 4, 1 }, { 11, 2 }, { 12, 4 }, { 18, 5 },
+ { 22, 3 }, { 24, 6 }, { 36, 7 }, { 48, 8 }, { 72, 9 },
+ { 96, 10 }, { 108, 11 }
+};
+
+static struct ieee80211vap *urtw_vap_create(struct ieee80211com *,
+ const char name[IFNAMSIZ], int unit, int opmode,
+ int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
+ const uint8_t mac[IEEE80211_ADDR_LEN]);
+static void urtw_vap_delete(struct ieee80211vap *);
+static void urtw_init(void *);
+static void urtw_stop(struct ifnet *, int);
+static int urtw_ioctl(struct ifnet *, u_long, caddr_t);
+static void urtw_start(struct ifnet *);
+static int urtw_alloc_rx_data_list(struct urtw_softc *);
+static int urtw_alloc_tx_data_list(struct urtw_softc *);
+static void urtw_free_data_list(struct urtw_softc *,
+ usbd_pipe_handle, usbd_pipe_handle,
+ struct urtw_data data[], int);
+static int urtw_raw_xmit(struct ieee80211_node *, struct mbuf *,
+ const struct ieee80211_bpf_params *);
+static void urtw_scan_start(struct ieee80211com *);
+static void urtw_scan_end(struct ieee80211com *);
+static void urtw_set_channel(struct ieee80211com *);
+static void urtw_update_mcast(struct ifnet *);
+static void urtw_rxeof(usbd_xfer_handle, usbd_private_handle,
+ usbd_status);
+static int urtw_tx_start(struct urtw_softc *,
+ struct ieee80211_node *, struct mbuf *, int);
+static void urtw_txeof_low(usbd_xfer_handle, usbd_private_handle,
+ usbd_status);
+static void urtw_txeof_normal(usbd_xfer_handle,
+ usbd_private_handle, usbd_status);
+static int urtw_newstate(struct ieee80211vap *,
+ enum ieee80211_state, int);
+static void urtw_ledtask(void *);
+static void urtw_ledusbtask(void *);
+static void urtw_ctxtask(void *);
+static void urtw_task(void *);
+static void urtw_watchdog(void *);
+static void urtw_set_multi(void *);
+static int urtw_isbmode(uint16_t);
+static uint16_t urtw_rate2rtl(int);
+static uint16_t urtw_rtl2rate(int);
+static usbd_status urtw_set_rate(struct urtw_softc *);
+static usbd_status urtw_update_msr(struct urtw_softc *);
+static usbd_status urtw_read8_c(struct urtw_softc *, int, uint8_t *);
+static usbd_status urtw_read16_c(struct urtw_softc *, int, uint16_t *);
+static usbd_status urtw_read32_c(struct urtw_softc *, int, uint32_t *);
+static usbd_status urtw_write8_c(struct urtw_softc *, int, uint8_t);
+static usbd_status urtw_write16_c(struct urtw_softc *, int, uint16_t);
+static usbd_status urtw_write32_c(struct urtw_softc *, int, uint32_t);
+static usbd_status urtw_eprom_cs(struct urtw_softc *, int);
+static usbd_status urtw_eprom_ck(struct urtw_softc *);
+static usbd_status urtw_eprom_sendbits(struct urtw_softc *, int16_t *,
+ int);
+static usbd_status urtw_eprom_read32(struct urtw_softc *, uint32_t,
+ uint32_t *);
+static usbd_status urtw_eprom_readbit(struct urtw_softc *, int16_t *);
+static usbd_status urtw_eprom_writebit(struct urtw_softc *, int16_t);
+static usbd_status urtw_get_macaddr(struct urtw_softc *);
+static usbd_status urtw_get_txpwr(struct urtw_softc *);
+static usbd_status urtw_get_rfchip(struct urtw_softc *);
+static usbd_status urtw_led_init(struct urtw_softc *);
+static usbd_status urtw_8185_rf_pins_enable(struct urtw_softc *);
+static usbd_status urtw_8185_tx_antenna(struct urtw_softc *, uint8_t);
+static usbd_status urtw_8187_write_phy(struct urtw_softc *, uint8_t,
+ uint32_t);
+static usbd_status urtw_8187_write_phy_ofdm_c(struct urtw_softc *,
+ uint8_t, uint32_t);
+static usbd_status urtw_8187_write_phy_cck_c(struct urtw_softc *, uint8_t,
+ uint32_t);
+static usbd_status urtw_8225_setgain(struct urtw_softc *, int16_t);
+static usbd_status urtw_8225_usb_init(struct urtw_softc *);
+static usbd_status urtw_8225_write_c(struct urtw_softc *, uint8_t,
+ uint16_t);
+static usbd_status urtw_8225_write_s16(struct urtw_softc *, uint8_t, int,
+ uint16_t *);
+static usbd_status urtw_8225_read(struct urtw_softc *, uint8_t,
+ uint32_t *);
+static usbd_status urtw_8225_rf_init(struct urtw_softc *);
+static usbd_status urtw_8225_rf_set_chan(struct urtw_softc *, int);
+static usbd_status urtw_8225_rf_set_sens(struct urtw_softc *, int);
+static usbd_status urtw_8225_set_txpwrlvl(struct urtw_softc *, int);
+static usbd_status urtw_8225v2_rf_init(struct urtw_softc *);
+static usbd_status urtw_8225v2_rf_set_chan(struct urtw_softc *, int);
+static usbd_status urtw_8225v2_set_txpwrlvl(struct urtw_softc *, int);
+static usbd_status urtw_8225v2_setgain(struct urtw_softc *, int16_t);
+static usbd_status urtw_8225_isv2(struct urtw_softc *, int *);
+static usbd_status urtw_read8e(struct urtw_softc *, int, uint8_t *);
+static usbd_status urtw_write8e(struct urtw_softc *, int, uint8_t);
+static usbd_status urtw_8180_set_anaparam(struct urtw_softc *, uint32_t);
+static usbd_status urtw_8185_set_anaparam2(struct urtw_softc *, uint32_t);
+static usbd_status urtw_open_pipes(struct urtw_softc *);
+static usbd_status urtw_close_pipes(struct urtw_softc *);
+static usbd_status urtw_intr_enable(struct urtw_softc *);
+static usbd_status urtw_intr_disable(struct urtw_softc *);
+static usbd_status urtw_reset(struct urtw_softc *);
+static usbd_status urtw_led_on(struct urtw_softc *, int);
+static usbd_status urtw_led_ctl(struct urtw_softc *, int);
+static usbd_status urtw_led_blink(struct urtw_softc *);
+static usbd_status urtw_led_mode0(struct urtw_softc *, int);
+static usbd_status urtw_led_mode1(struct urtw_softc *, int);
+static usbd_status urtw_led_mode2(struct urtw_softc *, int);
+static usbd_status urtw_led_mode3(struct urtw_softc *, int);
+static usbd_status urtw_rx_setconf(struct urtw_softc *);
+static usbd_status urtw_rx_enable(struct urtw_softc *);
+static usbd_status urtw_tx_enable(struct urtw_softc *sc);
+
+static int
+urtw_match(device_t dev)
+{
+ struct usb_attach_arg *uaa = device_get_ivars(dev);
+ const struct usb_devno *ud;
+
+ if (uaa->iface != NULL)
+ return UMATCH_NONE;
+ ud = usb_lookup(urtw_devs, uaa->vendor, uaa->product);
+
+ return (ud != NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
+}
+
+static int
+urtw_attach(device_t dev)
+{
+ int ret = 0;
+ struct urtw_softc *sc = device_get_softc(dev);
+ struct usb_attach_arg *uaa = device_get_ivars(dev);
+ struct ieee80211com *ic;
+ struct ifnet *ifp;
+ uint8_t bands;
+ uint32_t data;
+ usbd_status error;
+
+ sc->sc_dev = dev;
+ sc->sc_udev = uaa->device;
+#ifdef URTW_DEBUG
+ sc->sc_debug = urtw_debug;
+#endif
+
+ mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
+ MTX_DEF);
+ callout_init(&sc->sc_led_ch, 0);
+ callout_init(&sc->sc_watchdog_ch, 0);
+ usb_init_task(&sc->sc_ledtask, urtw_ledusbtask, sc);
+ usb_init_task(&sc->sc_ctxtask, urtw_ctxtask, sc);
+ usb_init_task(&sc->sc_task, urtw_task, sc);
+
+ urtw_read32_m(sc, URTW_RX, &data);
+ sc->sc_epromtype = (data & URTW_RX_9356SEL) ? URTW_EEPROM_93C56 :
+ URTW_EEPROM_93C46;
+
+ error = urtw_get_rfchip(sc);
+ if (error != 0)
+ goto fail;
+ error = urtw_get_macaddr(sc);
+ if (error != 0)
+ goto fail;
+ error = urtw_get_txpwr(sc);
+ if (error != 0)
+ goto fail;
+ error = urtw_led_init(sc);
+ if (error != 0)
+ goto fail;
+
+ sc->sc_rts_retry = URTW_DEFAULT_RTS_RETRY;
+ sc->sc_tx_retry = URTW_DEFAULT_TX_RETRY;
+ sc->sc_currate = 3;
+ sc->sc_preamble_mode = urtw_preamble_mode;
+
+ ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
+ if (ifp == NULL) {
+ device_printf(sc->sc_dev, "can not allocate ifnet\n");
+ ret = ENXIO;
+ goto fail;
+ }
+
+ ifp->if_softc = sc;
+ if_initname(ifp, "urtw", device_get_unit(sc->sc_dev));
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
+ IFF_NEEDSGIANT; /* USB stack is still under Giant lock */
+ ifp->if_init = urtw_init;
+ ifp->if_ioctl = urtw_ioctl;
+ ifp->if_start = urtw_start;
+ /* XXX URTW_TX_DATA_LIST_COUNT */
+ IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
+ ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
+ IFQ_SET_READY(&ifp->if_snd);
+
+ ic = ifp->if_l2com;
+ ic->ic_ifp = ifp;
+ ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
+ ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
+
+ /* set device capabilities */
+ ic->ic_caps =
+ IEEE80211_C_STA | /* station mode */
+ IEEE80211_C_MONITOR | /* monitor mode supported */
+ IEEE80211_C_TXPMGT | /* tx power management */
+ IEEE80211_C_SHPREAMBLE | /* short preamble supported */
+ IEEE80211_C_SHSLOT | /* short slot time supported */
+ IEEE80211_C_BGSCAN | /* capable of bg scanning */
+ IEEE80211_C_WPA; /* 802.11i */
+
+ IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_bssid);
+
+ bands = 0;
+ setbit(&bands, IEEE80211_MODE_11B);
+ setbit(&bands, IEEE80211_MODE_11G);
+ ieee80211_init_channels(ic, NULL, &bands);
+
+ ieee80211_ifattach(ic);
+ ic->ic_raw_xmit = urtw_raw_xmit;
+ ic->ic_scan_start = urtw_scan_start;
+ ic->ic_scan_end = urtw_scan_end;
+ ic->ic_set_channel = urtw_set_channel;
+
+ ic->ic_vap_create = urtw_vap_create;
+ ic->ic_vap_delete = urtw_vap_delete;
+ ic->ic_update_mcast = urtw_update_mcast;
+
+ bpfattach(ifp, DLT_IEEE802_11_RADIO,
+ sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap));
+
+ sc->sc_rxtap_len = sizeof sc->sc_rxtap;
+ sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
+ sc->sc_rxtap.wr_ihdr.it_present = htole32(URTW_RX_RADIOTAP_PRESENT);
+
+ sc->sc_txtap_len = sizeof sc->sc_txtap;
+ sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
+ sc->sc_txtap.wt_ihdr.it_present = htole32(URTW_TX_RADIOTAP_PRESENT);
+
+ if (bootverbose)
+ ieee80211_announce(ic);
+
+ usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
+fail:
+ return (ret);
+}
+
+static usbd_status
+urtw_open_pipes(struct urtw_softc *sc)
+{
+ usbd_status error;
+
+ /*
+ * NB: there is no way to distinguish each pipes so we need to hardcode
+ * pipe numbers
+ */
+
+ /* tx pipe - low priority packets */
+ error = usbd_open_pipe(sc->sc_iface, 0x2, USBD_EXCLUSIVE_USE,
+ &sc->sc_txpipe_low);
+ if (error != 0) {
+ device_printf(sc->sc_dev, "could not open Tx low pipe: %s\n",
+ usbd_errstr(error));
+ goto fail;
+ }
+ /* tx pipe - normal priority packets */
+ error = usbd_open_pipe(sc->sc_iface, 0x3, USBD_EXCLUSIVE_USE,
+ &sc->sc_txpipe_normal);
+ if (error != 0) {
+ device_printf(sc->sc_dev, "could not open Tx normal pipe: %s\n",
+ usbd_errstr(error));
+ goto fail;
+ }
+ /* rx pipe */
+ error = usbd_open_pipe(sc->sc_iface, 0x81, USBD_EXCLUSIVE_USE,
+ &sc->sc_rxpipe);
+ if (error != 0) {
+ device_printf(sc->sc_dev, "could not open Rx pipe: %s\n",
+ usbd_errstr(error));
+ goto fail;
+ }
+
+ return (0);
+fail:
+ (void)urtw_close_pipes(sc);
+ return (error);
+}
+
+static usbd_status
+urtw_close_pipes(struct urtw_softc *sc)
+{
+ usbd_status error = 0;
+
+ if (sc->sc_rxpipe != NULL) {
+ error = usbd_close_pipe(sc->sc_rxpipe);
+ if (error != 0)
+ goto fail;
+ sc->sc_rxpipe = NULL;
+ }
+ if (sc->sc_txpipe_low != NULL) {
+ error = usbd_close_pipe(sc->sc_txpipe_low);
+ if (error != 0)
+ goto fail;
+ sc->sc_txpipe_low = NULL;
+ }
+ if (sc->sc_txpipe_normal != NULL) {
+ error = usbd_close_pipe(sc->sc_txpipe_normal);
+ if (error != 0)
+ goto fail;
+ sc->sc_txpipe_normal = NULL;
+ }
+fail:
+ return (error);
+}
+
+static int
+urtw_alloc_data_list(struct urtw_softc *sc, struct urtw_data data[],
+ int ndata, int maxsz, int fillmbuf)
+{
+ int i, error;
+
+ for (i = 0; i < ndata; i++) {
+ struct urtw_data *dp = &data[i];
+
+ dp->sc = sc;
+ dp->xfer = usbd_alloc_xfer(sc->sc_udev);
+ if (dp->xfer == NULL) {
+ device_printf(sc->sc_dev, "could not allocate xfer\n");
+ error = ENOMEM;
+ goto fail;
+ }
+ if (fillmbuf) {
+ dp->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+ if (dp->m == NULL) {
+ device_printf(sc->sc_dev,
+ "could not allocate rx mbuf\n");
+ error = ENOMEM;
+ goto fail;
+ }
+ dp->buf = mtod(dp->m, uint8_t *);
+ } else {
+ dp->m = NULL;
+ dp->buf = usbd_alloc_buffer(dp->xfer, maxsz);
+ if (dp->buf == NULL) {
+ device_printf(sc->sc_dev,
+ "could not allocate buffer\n");
+ error = ENOMEM;
+ goto fail;
+ }
+ if (((unsigned long)dp->buf) % 4)
+ device_printf(sc->sc_dev,
+ "warn: unaligned buffer %p\n", dp->buf);
+ }
+ dp->ni = NULL;
+ }
+
+ return 0;
+
+fail: urtw_free_data_list(sc, NULL, NULL, data, ndata);
+ return error;
+}
+
+static void
+urtw_free_data_list(struct urtw_softc *sc, usbd_pipe_handle pipe1,
+ usbd_pipe_handle pipe2, struct urtw_data data[], int ndata)
+{
+ int i;
+
+ /* make sure no transfers are pending */
+ if (pipe1 != NULL)
+ usbd_abort_pipe(pipe1);
+ if (pipe2 != NULL)
+ usbd_abort_pipe(pipe2);
+
+ for (i = 0; i < ndata; i++) {
+ struct urtw_data *dp = &data[i];
+
+ if (dp->xfer != NULL) {
+ usbd_free_xfer(dp->xfer);
+ dp->xfer = NULL;
+ }
+ if (dp->m != NULL) {
+ m_freem(dp->m);
+ dp->m = NULL;
+ }
+ if (dp->ni != NULL) {
+ ieee80211_free_node(dp->ni);
+ dp->ni = NULL;
+ }
+ }
+}
+
+static int
+urtw_alloc_rx_data_list(struct urtw_softc *sc)
+{
+
+ return urtw_alloc_data_list(sc,
+ sc->sc_rxdata, URTW_RX_DATA_LIST_COUNT, MCLBYTES, 1 /* mbufs */);
+}
+
+static void
+urtw_free_rx_data_list(struct urtw_softc *sc)
+{
+
+ urtw_free_data_list(sc, sc->sc_rxpipe, NULL, sc->sc_rxdata,
+ URTW_RX_DATA_LIST_COUNT);
+}
+
+static int
+urtw_alloc_tx_data_list(struct urtw_softc *sc)
+{
+
+ return urtw_alloc_data_list(sc,
+ sc->sc_txdata, URTW_TX_DATA_LIST_COUNT, URTW_TX_MAXSIZE,
+ 0 /* no mbufs */);
+}
+
+static void
+urtw_free_tx_data_list(struct urtw_softc *sc)
+{
+
+ urtw_free_data_list(sc, sc->sc_txpipe_low, sc->sc_txpipe_normal,
+ sc->sc_txdata, URTW_TX_DATA_LIST_COUNT);
+}
+
+static usbd_status
+urtw_led_init(struct urtw_softc *sc)
+{
+ uint32_t rev;
+ usbd_status error;
+
+ urtw_read8_m(sc, URTW_PSR, &sc->sc_psr);
+ error = urtw_eprom_read32(sc, URTW_EPROM_SWREV, &rev);
+ if (error != 0)
+ goto fail;
+
+ switch (rev & URTW_EPROM_CID_MASK) {
+ case URTW_EPROM_CID_ALPHA0:
+ sc->sc_strategy = URTW_SW_LED_MODE1;
+ break;
+ case URTW_EPROM_CID_SERCOMM_PS:
+ sc->sc_strategy = URTW_SW_LED_MODE3;
+ break;
+ case URTW_EPROM_CID_HW_LED:
+ sc->sc_strategy = URTW_HW_LED;
+ break;
+ case URTW_EPROM_CID_RSVD0:
+ case URTW_EPROM_CID_RSVD1:
+ default:
+ sc->sc_strategy = URTW_SW_LED_MODE0;
+ break;
+ }
+
+ sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0;
+
+fail:
+ return (error);
+}
+
+/* XXX why we should allocalte memory buffer instead of using memory stack? */
+static usbd_status
+urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index,
+ uint16_t *data)
+{
+ uint8_t *buf;
+ uint16_t data16;
+ usb_device_request_t *req;
+ usbd_status error = 0;
+
+ data16 = *data;
+ req = (usb_device_request_t *)malloc(sizeof(usb_device_request_t),
+ M_80211_VAP, M_NOWAIT | M_ZERO);
+ if (req == NULL) {
+ device_printf(sc->sc_dev, "could not allocate a memory\n");
+ goto fail0;
+ }
+ buf = (uint8_t *)malloc(2, M_80211_VAP, M_NOWAIT | M_ZERO);
+ if (req == NULL) {
+ device_printf(sc->sc_dev, "could not allocate a memory\n");
+ goto fail1;
+ }
+
+ req->bmRequestType = UT_WRITE_VENDOR_DEVICE;
+ req->bRequest = URTW_8187_SETREGS_REQ;
+ USETW(req->wValue, addr);
+ USETW(req->wIndex, index);
+ USETW(req->wLength, sizeof(uint16_t));
+ buf[0] = (data16 & 0x00ff);
+ buf[1] = (data16 & 0xff00) >> 8;
+
+ error = usbd_do_request(sc->sc_udev, req, buf);
+
+ free(buf, M_80211_VAP);
+fail1: free(req, M_80211_VAP);
+fail0: return (error);
+}
+
+static usbd_status
+urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data)
+{
+ int i;
+ int16_t bit;
+ uint8_t rlen = 12, wlen = 6;
+ uint16_t o1, o2, o3, tmp;
+ uint32_t d2w = ((uint32_t)(addr & 0x1f)) << 27;
+ uint32_t mask = 0x80000000, value = 0;
+ usbd_status error;
+
+ urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &o1);
+ urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &o2);
+ urtw_read16_m(sc, URTW_RF_PINS_SELECT, &o3);
+ urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2 | URTW_RF_PINS_MAGIC4);
+ urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3 | URTW_RF_PINS_MAGIC4);
+ o1 &= ~URTW_RF_PINS_MAGIC4;
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN);
+ DELAY(5);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1);
+ DELAY(5);
+
+ for (i = 0; i < (wlen / 2); i++, mask = mask >> 1) {
+ bit = ((d2w & mask) != 0) ? 1 : 0;
+
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
+ DELAY(2);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
+ URTW_BB_HOST_BANG_CLK);
+ DELAY(2);
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
+ URTW_BB_HOST_BANG_CLK);
+ DELAY(2);
+ mask = mask >> 1;
+ if (i == 2)
+ break;
+ bit = ((d2w & mask) != 0) ? 1 : 0;
+ urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
+ URTW_BB_HOST_BANG_CLK);
+ DELAY(2);
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list