Merge illumos-gate
[unleashed.git] / kernel / drivers / net / wifi / urtw / urtw.c
blob9f0355547912a60963164fb9fcf7a1975ddd1209
1 /*
2 * Copyright (c) 2018, Joyent, Inc.
3 */
5 /*
6 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
7 * Use is subject to license terms.
8 */
11 * Copyright (c) 2008 Weongyo Jeong
12 * All rights reserved.
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer,
19 * without modification.
20 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
21 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
22 * redistribution must be conditioned upon including a substantially
23 * similar Disclaimer requirement for further binary redistribution.
25 * NO WARRANTY
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
29 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
30 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
31 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
34 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
36 * THE POSSIBILITY OF SUCH DAMAGES.
38 #include <sys/sysmacros.h>
39 #include <sys/strsubr.h>
40 #include <sys/strsun.h>
41 #include <sys/mac_provider.h>
42 #include <sys/mac_wifi.h>
43 #include <sys/net80211.h>
44 #define USBDRV_MAJOR_VER 2
45 #define USBDRV_MINOR_VER 0
46 #include <sys/usb/usba.h>
47 #include <sys/usb/usba/usba_types.h>
49 #include "urtw_reg.h"
50 #include "urtw_var.h"
52 static void *urtw_soft_state_p = NULL;
54 #define URTW_TXBUF_SIZE (IEEE80211_MAX_LEN)
55 #define URTW_RXBUF_SIZE (URTW_TXBUF_SIZE)
57 * device operations
59 static int urtw_attach(dev_info_t *, ddi_attach_cmd_t);
60 static int urtw_detach(dev_info_t *, ddi_detach_cmd_t);
63 * Module Loading Data & Entry Points
65 DDI_DEFINE_STREAM_OPS(urtw_dev_ops, nulldev, nulldev, urtw_attach,
66 urtw_detach, nodev, NULL, D_MP, NULL, ddi_quiesce_not_needed);
68 static struct modldrv urtw_modldrv = {
69 &mod_driverops, /* Type of module. This one is a driver */
70 "RTL8187L/B driver v1.2", /* short description */
71 &urtw_dev_ops /* driver specific ops */
74 static struct modlinkage modlinkage = {
75 MODREV_1,
76 (void *)&urtw_modldrv,
77 NULL
80 static int urtw_m_stat(void *, uint_t, uint64_t *);
81 static int urtw_m_start(void *);
82 static void urtw_m_stop(void *);
83 static int urtw_m_promisc(void *, boolean_t);
84 static int urtw_m_multicst(void *, boolean_t, const uint8_t *);
85 static int urtw_m_unicst(void *, const uint8_t *);
86 static mblk_t *urtw_m_tx(void *, mblk_t *);
87 static void urtw_m_ioctl(void *, queue_t *, mblk_t *);
88 static int urtw_m_setprop(void *, const char *, mac_prop_id_t,
89 uint_t, const void *);
90 static int urtw_m_getprop(void *, const char *, mac_prop_id_t,
91 uint_t, void *);
92 static void urtw_m_propinfo(void *, const char *, mac_prop_id_t,
93 mac_prop_info_handle_t);
95 static mac_callbacks_t urtw_m_callbacks = {
96 MC_IOCTL | MC_SETPROP | MC_GETPROP | MC_PROPINFO,
97 urtw_m_stat,
98 urtw_m_start,
99 urtw_m_stop,
100 urtw_m_promisc,
101 urtw_m_multicst,
102 urtw_m_unicst,
103 urtw_m_tx,
104 NULL,
105 urtw_m_ioctl,
106 NULL,
107 NULL,
108 NULL,
109 urtw_m_setprop,
110 urtw_m_getprop,
111 urtw_m_propinfo
114 static int urtw_tx_start(struct urtw_softc *, mblk_t *, int);
115 static int urtw_rx_start(struct urtw_softc *);
119 * Supported rates for 802.11b/g modes (in 500Kbps unit).
121 static const struct ieee80211_rateset urtw_rateset_11b =
122 { 4, { 2, 4, 11, 22 } };
124 static const struct ieee80211_rateset urtw_rateset_11g =
125 { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
127 #define USB_VENDOR_DICKSMITH 0x1371 /* Dick Smith Electronics */
128 #define USB_VENDOR_LOGITEC 0x0789 /* Logitec */
129 #define USB_VENDOR_NETGEAR 0x0846 /* BayNETGEAR */
130 #define USB_VENDOR_REALTEK 0x0bda /* Realtek */
131 #define USB_VENDOR_SPHAIRON 0x114b /* Sphairon Access Systems */
132 #define USB_VENDOR_SURECOM 0x0769 /* Surecom Technology */
133 #define USB_VENDOR_BELKIN 0x050d /* Belkin Components */
134 #define USB_VENDOR_SITECOMEU 0x0df6 /* Sitecom Europe */
136 #define USB_PRODUCT_SPHAIRON_RTL8187 0x0150 /* RTL8187 */
137 #define USB_PRODUCT_DICKSMITH_RTL8187 0x9401 /* RTL8187 */
138 #define USB_PRODUCT_LOGITEC_RTL8187 0x010c /* RTL8187 */
139 #define USB_PRODUCT_REALTEK_RTL8187 0x8187 /* RTL8187 */
140 #define USB_PRODUCT_NETGEAR_WG111V2 0x6a00 /* WG111v2 */
141 #define USB_PRODUCT_SURECOM_EP9001G2A 0x11f2 /* EP-9001-G rev 2A */
142 #define USB_PRODUCT_BELKIN_F5D7050E 0x705e /* F5D705E 54g */
143 #define USB_PRODUCT_NETGEAR_WG111V3 0x4260 /* WG111v3 */
144 #define USB_PRODUCT_REALTEK_RTL8187B_0 0x8189 /* RTL8187B */
145 #define USB_PRODUCT_REALTEK_RTL8187B_1 0x8197 /* RTL8187B */
146 #define USB_PRODUCT_REALTEK_RTL8187B_2 0x8198 /* RTL8187B */
147 #define USB_PRODUCT_SITECOMEU_WL168 0x0028 /* WL-168 */
149 #define USB_PRODUCT_ANY 0xffff
151 struct usb_devno {
152 uint16_t v;
153 uint16_t p;
157 * Recognized device vendors/products.
159 static struct urtw_type {
160 struct usb_devno dev;
161 uint8_t rev;
162 } urtw_devs[] = {
163 #define URTW_DEV_RTL8187(v, p) \
164 { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, URTW_HWREV_8187 }
165 #define URTW_DEV_RTL8187B(v, p) \
166 { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, URTW_HWREV_8187B }
167 /* Realtek RTL8187 devices. */
168 URTW_DEV_RTL8187(DICKSMITH, RTL8187),
169 URTW_DEV_RTL8187(LOGITEC, RTL8187),
170 URTW_DEV_RTL8187(NETGEAR, WG111V2),
171 URTW_DEV_RTL8187(REALTEK, RTL8187),
172 URTW_DEV_RTL8187(SPHAIRON, RTL8187),
173 URTW_DEV_RTL8187(SURECOM, EP9001G2A),
174 /* Realtek RTL8187B devices. */
175 URTW_DEV_RTL8187B(BELKIN, F5D7050E),
176 URTW_DEV_RTL8187B(NETGEAR, WG111V3),
177 URTW_DEV_RTL8187B(REALTEK, RTL8187B_0),
178 URTW_DEV_RTL8187B(REALTEK, RTL8187B_1),
179 URTW_DEV_RTL8187B(REALTEK, RTL8187B_2),
180 URTW_DEV_RTL8187B(SITECOMEU, WL168)
181 #undef URTW_DEV_RTL8187
182 #undef URTW_DEV_RTL8187B
186 * Search for a vendor/product pair in an array. The item size is
187 * given as an argument.
189 struct urtw_type *
190 usb_match_device(struct urtw_type *tbl, uint32_t nentries,
191 uint16_t vendor, uint16_t product)
193 while (nentries-- > 0) {
194 uint16_t tproduct = tbl[nentries].dev.p;
195 if (tbl[nentries].dev.v == vendor &&
196 (tproduct == product || tproduct == USB_PRODUCT_ANY))
197 return (&tbl[nentries]);
199 return (NULL);
202 #define usb_lookup(tbl, vendor, product) \
203 usb_match_device(tbl, sizeof (tbl) / sizeof ((tbl)[0]), \
204 (vendor), (product))
206 #define urtw_lookup(v, p) (usb_lookup(urtw_devs, v, p))
208 struct urtw_pair {
209 uint32_t reg;
210 uint32_t val;
213 struct urtw_pair_idx {
214 uint8_t reg;
215 uint8_t val;
216 uint8_t idx;
219 static struct urtw_pair_idx urtw_8187b_regtbl[] = {
220 { 0xf0, 0x32, 0 }, { 0xf1, 0x32, 0 }, { 0xf2, 0x00, 0 },
221 { 0xf3, 0x00, 0 }, { 0xf4, 0x32, 0 }, { 0xf5, 0x43, 0 },
222 { 0xf6, 0x00, 0 }, { 0xf7, 0x00, 0 }, { 0xf8, 0x46, 0 },
223 { 0xf9, 0xa4, 0 }, { 0xfa, 0x00, 0 }, { 0xfb, 0x00, 0 },
224 { 0xfc, 0x96, 0 }, { 0xfd, 0xa4, 0 }, { 0xfe, 0x00, 0 },
225 { 0xff, 0x00, 0 },
227 { 0x58, 0x4b, 1 }, { 0x59, 0x00, 1 }, { 0x5a, 0x4b, 1 },
228 { 0x5b, 0x00, 1 }, { 0x60, 0x4b, 1 }, { 0x61, 0x09, 1 },
229 { 0x62, 0x4b, 1 }, { 0x63, 0x09, 1 }, { 0xce, 0x0f, 1 },
230 { 0xcf, 0x00, 1 }, { 0xe0, 0xff, 1 }, { 0xe1, 0x0f, 1 },
231 { 0xe2, 0x00, 1 }, { 0xf0, 0x4e, 1 }, { 0xf1, 0x01, 1 },
232 { 0xf2, 0x02, 1 }, { 0xf3, 0x03, 1 }, { 0xf4, 0x04, 1 },
233 { 0xf5, 0x05, 1 }, { 0xf6, 0x06, 1 }, { 0xf7, 0x07, 1 },
234 { 0xf8, 0x08, 1 },
236 { 0x4e, 0x00, 2 }, { 0x0c, 0x04, 2 }, { 0x21, 0x61, 2 },
237 { 0x22, 0x68, 2 }, { 0x23, 0x6f, 2 }, { 0x24, 0x76, 2 },
238 { 0x25, 0x7d, 2 }, { 0x26, 0x84, 2 }, { 0x27, 0x8d, 2 },
239 { 0x4d, 0x08, 2 }, { 0x50, 0x05, 2 }, { 0x51, 0xf5, 2 },
240 { 0x52, 0x04, 2 }, { 0x53, 0xa0, 2 }, { 0x54, 0x1f, 2 },
241 { 0x55, 0x23, 2 }, { 0x56, 0x45, 2 }, { 0x57, 0x67, 2 },
242 { 0x58, 0x08, 2 }, { 0x59, 0x08, 2 }, { 0x5a, 0x08, 2 },
243 { 0x5b, 0x08, 2 }, { 0x60, 0x08, 2 }, { 0x61, 0x08, 2 },
244 { 0x62, 0x08, 2 }, { 0x63, 0x08, 2 }, { 0x64, 0xcf, 2 },
245 { 0x72, 0x56, 2 }, { 0x73, 0x9a, 2 },
247 { 0x34, 0xf0, 0 }, { 0x35, 0x0f, 0 }, { 0x5b, 0x40, 0 },
248 { 0x84, 0x88, 0 }, { 0x85, 0x24, 0 }, { 0x88, 0x54, 0 },
249 { 0x8b, 0xb8, 0 }, { 0x8c, 0x07, 0 }, { 0x8d, 0x00, 0 },
250 { 0x94, 0x1b, 0 }, { 0x95, 0x12, 0 }, { 0x96, 0x00, 0 },
251 { 0x97, 0x06, 0 }, { 0x9d, 0x1a, 0 }, { 0x9f, 0x10, 0 },
252 { 0xb4, 0x22, 0 }, { 0xbe, 0x80, 0 }, { 0xdb, 0x00, 0 },
253 { 0xee, 0x00, 0 }, { 0x91, 0x03, 0 },
255 { 0x4c, 0x00, 2 }, { 0x9f, 0x00, 3 }, { 0x8c, 0x01, 0 },
256 { 0x8d, 0x10, 0 }, { 0x8e, 0x08, 0 }, { 0x8f, 0x00, 0 }
259 static uint8_t urtw_8225_agc[] = {
260 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b,
261 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
262 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85,
263 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a,
264 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f,
265 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24,
266 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19,
267 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
268 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
269 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
270 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
271 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
274 static uint8_t urtw_8225v2_agc[] = {
275 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57,
276 0x55, 0x53, 0x51, 0x4f, 0x4d, 0x4b, 0x49, 0x47,
277 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x39, 0x37,
278 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27,
279 0x25, 0x23, 0x21, 0x1f, 0x1d, 0x1b, 0x19, 0x17,
280 0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0b, 0x09, 0x07,
281 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
282 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
283 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
284 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
285 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2a,
286 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d,
287 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f,
288 0x2f, 0x2f, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31,
289 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
290 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
293 static uint8_t urtw_8225v2_ofdm[] = {
294 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60,
295 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
296 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
297 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
298 0x0a, 0xe1, 0x2c, 0x8a, 0x86, 0x83, 0x34, 0x0f,
299 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
300 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
301 0x6d, 0x3c, 0xfb, 0x07
304 static uint32_t urtw_8225_channel[] = {
305 0x0000, /* dummy channel 0 */
306 0x085c, /* 1 */
307 0x08dc, /* 2 */
308 0x095c, /* 3 */
309 0x09dc, /* 4 */
310 0x0a5c, /* 5 */
311 0x0adc, /* 6 */
312 0x0b5c, /* 7 */
313 0x0bdc, /* 8 */
314 0x0c5c, /* 9 */
315 0x0cdc, /* 10 */
316 0x0d5c, /* 11 */
317 0x0ddc, /* 12 */
318 0x0e5c, /* 13 */
319 0x0f72, /* 14 */
322 static uint8_t urtw_8225_gain[] = {
323 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
324 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
325 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
326 0x33, 0x80, 0x79, 0xc5, /* -78dbm */
327 0x43, 0x78, 0x76, 0xc5, /* -74dbm */
328 0x53, 0x60, 0x73, 0xc5, /* -70dbm */
329 0x63, 0x58, 0x70, 0xc5, /* -66dbm */
332 static struct urtw_pair urtw_8225_rf_part1[] = {
333 { 0x00, 0x0067 }, { 0x01, 0x0fe0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
334 { 0x04, 0x0486 }, { 0x05, 0x0bc0 }, { 0x06, 0x0ae6 }, { 0x07, 0x082a },
335 { 0x08, 0x001f }, { 0x09, 0x0334 }, { 0x0a, 0x0fd4 }, { 0x0b, 0x0391 },
336 { 0x0c, 0x0050 }, { 0x0d, 0x06db }, { 0x0e, 0x0029 }, { 0x0f, 0x0914 },
339 static struct urtw_pair urtw_8225_rf_part2[] = {
340 { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
341 { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
342 { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x09 }, { 0x0b, 0x80 },
343 { 0x0c, 0x01 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 }, { 0x10, 0x84 },
344 { 0x11, 0x06 }, { 0x12, 0x20 }, { 0x13, 0x20 }, { 0x14, 0x00 },
345 { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 }, { 0x18, 0xef },
346 { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x76 }, { 0x1c, 0x04 },
347 { 0x1e, 0x95 }, { 0x1f, 0x75 }, { 0x20, 0x1f }, { 0x21, 0x27 },
348 { 0x22, 0x16 }, { 0x24, 0x46 }, { 0x25, 0x20 }, { 0x26, 0x90 },
349 { 0x27, 0x88 }
352 static struct urtw_pair urtw_8225_rf_part3[] = {
353 { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
354 { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x10, 0x9b },
355 { 0x11, 0x88 }, { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 },
356 { 0x1a, 0xa0 }, { 0x1b, 0x08 }, { 0x40, 0x86 }, { 0x41, 0x8d },
357 { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x1f }, { 0x45, 0x1e },
358 { 0x46, 0x1a }, { 0x47, 0x15 }, { 0x48, 0x10 }, { 0x49, 0x0a },
359 { 0x4a, 0x05 }, { 0x4b, 0x02 }, { 0x4c, 0x05 }
362 static uint16_t urtw_8225_rxgain[] = {
363 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
364 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
365 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
366 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
367 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
368 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
369 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
370 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
371 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
372 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
373 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
374 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
377 static uint8_t urtw_8225_threshold[] = {
378 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
381 static uint8_t urtw_8225_tx_gain_cck_ofdm[] = {
382 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
385 static uint8_t urtw_8225_txpwr_cck[] = {
386 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
387 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
388 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
389 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
390 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
391 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
394 static uint8_t urtw_8225_txpwr_cck_ch14[] = {
395 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
396 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
397 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
398 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
399 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
400 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
403 static uint8_t urtw_8225_txpwr_ofdm[] = {
404 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
407 static uint8_t urtw_8225v2_gain_bg[] = {
408 0x23, 0x15, 0xa5, /* -82-1dbm */
409 0x23, 0x15, 0xb5, /* -82-2dbm */
410 0x23, 0x15, 0xc5, /* -82-3dbm */
411 0x33, 0x15, 0xc5, /* -78dbm */
412 0x43, 0x15, 0xc5, /* -74dbm */
413 0x53, 0x15, 0xc5, /* -70dbm */
414 0x63, 0x15, 0xc5, /* -66dbm */
417 static struct urtw_pair urtw_8225v2_rf_part1[] = {
418 { 0x00, 0x02bf }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
419 { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
420 { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
421 { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
424 static struct urtw_pair urtw_8225v2_rf_part2[] = {
425 { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
426 { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
427 { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x08 }, { 0x0b, 0x80 },
428 { 0x0c, 0x01 }, { 0x0d, 0x43 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 },
429 { 0x10, 0x84 }, { 0x11, 0x07 }, { 0x12, 0x20 }, { 0x13, 0x20 },
430 { 0x14, 0x00 }, { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 },
431 { 0x18, 0xef }, { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x15 },
432 { 0x1c, 0x04 }, { 0x1d, 0xc5 }, { 0x1e, 0x95 }, { 0x1f, 0x75 },
433 { 0x20, 0x1f }, { 0x21, 0x17 }, { 0x22, 0x16 }, { 0x23, 0x80 },
434 { 0x24, 0x46 }, { 0x25, 0x00 }, { 0x26, 0x90 }, { 0x27, 0x88 }
437 static struct urtw_pair urtw_8225v2_rf_part3[] = {
438 { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
439 { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x09, 0x11 },
440 { 0x0a, 0x17 }, { 0x0b, 0x11 }, { 0x10, 0x9b }, { 0x11, 0x88 },
441 { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 }, { 0x1a, 0xa0 },
442 { 0x1b, 0x08 }, { 0x1d, 0x00 }, { 0x40, 0x86 }, { 0x41, 0x9d },
443 { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x36 }, { 0x45, 0x35 },
444 { 0x46, 0x2e }, { 0x47, 0x25 }, { 0x48, 0x1c }, { 0x49, 0x12 },
445 { 0x4a, 0x09 }, { 0x4b, 0x04 }, { 0x4c, 0x05 }
448 static uint16_t urtw_8225v2_rxgain[] = {
449 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
450 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
451 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
452 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
453 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
454 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
455 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
456 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
457 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
458 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
459 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
460 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
463 static uint8_t urtw_8225v2_tx_gain_cck_ofdm[] = {
464 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
465 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
466 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
467 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
468 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
469 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
472 static uint8_t urtw_8225v2_txpwr_cck[] = {
473 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
474 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
475 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
476 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
479 static uint8_t urtw_8225v2_txpwr_cck_ch14[] = {
480 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
481 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
482 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
483 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
486 static struct urtw_pair urtw_8225v2_b_rf[] = {
487 { 0x00, 0x00b7 }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
488 { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
489 { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
490 { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 },
491 { 0x00, 0x01b7 }
494 static struct urtw_pair urtw_ratetable[] = {
495 { 2, 0 }, { 4, 1 }, { 11, 2 }, { 12, 4 }, { 18, 5 },
496 { 22, 3 }, { 24, 6 }, { 36, 7 }, { 48, 8 }, { 72, 9 },
497 { 96, 10 }, { 108, 11 }
500 static int urtw_8187_init(void *);
501 static void urtw_stop(struct urtw_softc *);
502 static int urtw_set_channel(struct urtw_softc *);
503 static void
504 urtw_rxeof(usb_pipe_handle_t, usb_bulk_req_t *);
505 static int
506 urtw_newstate(struct ieee80211com *, enum ieee80211_state, int);
507 static usbd_status
508 urtw_read8_c(struct urtw_softc *, int, uint8_t *, uint8_t);
509 static usbd_status
510 urtw_read16_c(struct urtw_softc *, int, uint16_t *, uint8_t);
511 static usbd_status
512 urtw_read32_c(struct urtw_softc *, int, uint32_t *, uint8_t);
513 static usbd_status
514 urtw_write8_c(struct urtw_softc *, int, uint8_t, uint8_t);
515 static usbd_status
516 urtw_write16_c(struct urtw_softc *, int, uint16_t, uint8_t);
517 static usbd_status
518 urtw_write32_c(struct urtw_softc *, int, uint32_t, uint8_t);
519 static usbd_status urtw_eprom_cs(struct urtw_softc *, int);
520 static usbd_status urtw_eprom_ck(struct urtw_softc *);
521 static usbd_status urtw_eprom_sendbits(struct urtw_softc *, int16_t *,
522 int);
523 static usbd_status urtw_eprom_read32(struct urtw_softc *, uint32_t,
524 uint32_t *);
525 static usbd_status urtw_eprom_readbit(struct urtw_softc *, int16_t *);
526 static usbd_status urtw_eprom_writebit(struct urtw_softc *, int16_t);
527 static usbd_status urtw_get_macaddr(struct urtw_softc *);
528 static usbd_status urtw_get_txpwr(struct urtw_softc *);
529 static usbd_status urtw_get_rfchip(struct urtw_softc *);
530 static usbd_status urtw_led_init(struct urtw_softc *);
531 static usbd_status
532 urtw_8225_read(struct urtw_softc *, uint8_t, uint32_t *);
533 static usbd_status urtw_8225_rf_init(struct urtw_rf *);
534 static usbd_status urtw_8225_rf_set_chan(struct urtw_rf *, int);
535 static usbd_status urtw_8225_rf_set_sens(struct urtw_rf *);
536 static usbd_status urtw_8225v2_rf_init(struct urtw_rf *);
537 static usbd_status urtw_8225v2_rf_set_chan(struct urtw_rf *, int);
538 static usbd_status urtw_open_pipes(struct urtw_softc *);
539 static void urtw_close_pipes(struct urtw_softc *);
540 static void urtw_led_launch(void *);
542 static void urtw_8187b_update_wmm(struct urtw_softc *);
543 static usbd_status urtw_8187b_reset(struct urtw_softc *);
544 static int urtw_8187b_init(void *);
545 static void urtw_8225v2_b_config_mac(struct urtw_softc *);
546 static void urtw_8225v2_b_init_rfe(struct urtw_softc *);
547 static usbd_status urtw_8225v2_b_update_chan(struct urtw_softc *);
548 static usbd_status urtw_8225v2_b_rf_init(struct urtw_rf *);
549 static usbd_status urtw_8225v2_b_rf_set_chan(struct urtw_rf *, int);
550 static void urtw_8225v2_b_set_txpwrlvl(struct urtw_softc *, int);
552 #ifdef DEBUG
554 #define URTW_DEBUG_XMIT 0x00000001
555 #define URTW_DEBUG_RECV 0x00000002
556 #define URTW_DEBUG_LED 0x00000004
557 #define URTW_DEBUG_GLD 0x00000008
558 #define URTW_DEBUG_RF 0x00000010
559 #define URTW_DEBUG_ATTACH 0x00000020
560 #define URTW_DEBUG_ACTIVE 0x00000040
561 #define URTW_DEBUG_HWTYPE 0x00000080
562 #define URTW_DEBUG_DEVREQ 0x00000100
563 #define URTW_DEBUG_HOTPLUG 0x00000200
564 #define URTW_DEBUG_STATE 0x00000400
565 #define URTW_DEBUG_TX_PROC 0x00000800
566 #define URTW_DEBUG_RX_PROC 0x00001000
567 #define URTW_DEBUG_EEPROM 0x00002000
568 #define URTW_DEBUG_RESET 0x00004000
569 #define URTW_DEBUG_ANY 0xffffffff
571 uint32_t urtw8187_dbg_flags = 0;
572 static void
573 urtw8187_dbg(dev_info_t *dip, int level, const char *fmt, ...)
575 char msg_buffer[255];
576 va_list ap;
578 if (dip == NULL) {
579 return;
582 va_start(ap, fmt);
583 (void) vsprintf(msg_buffer, fmt, ap);
584 cmn_err(level, "%s%d: %s", ddi_get_name(dip),
585 ddi_get_instance(dip), msg_buffer);
586 va_end(ap);
589 #define URTW8187_DBG(l, x) do {\
590 _NOTE(CONSTANTCONDITION) \
591 if ((l) & urtw8187_dbg_flags) \
592 urtw8187_dbg x;\
593 _NOTE(CONSTANTCONDITION) \
594 } while (0)
595 #else
596 #define URTW8187_DBG(l, x)
597 #endif
599 static usbd_status
600 urtw_led_init(struct urtw_softc *sc)
602 uint32_t rev;
603 usbd_status error;
605 if (error = urtw_read8_c(sc, URTW_PSR, &sc->sc_psr, 0))
606 goto fail;
607 error = urtw_eprom_read32(sc, URTW_EPROM_SWREV, &rev);
608 if (error != 0)
609 goto fail;
611 switch (rev & URTW_EPROM_CID_MASK) {
612 case URTW_EPROM_CID_ALPHA0:
613 sc->sc_strategy = URTW_SW_LED_MODE1;
614 break;
615 case URTW_EPROM_CID_SERCOMM_PS:
616 sc->sc_strategy = URTW_SW_LED_MODE3;
617 break;
618 case URTW_EPROM_CID_HW_LED:
619 sc->sc_strategy = URTW_HW_LED;
620 break;
621 case URTW_EPROM_CID_RSVD0:
622 case URTW_EPROM_CID_RSVD1:
623 default:
624 sc->sc_strategy = URTW_SW_LED_MODE0;
625 break;
628 sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0;
630 fail:
631 return (error);
634 static usbd_status
635 urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index,
636 uint16_t *data)
638 usb_ctrl_setup_t req;
639 usb_cr_t cr;
640 usb_cb_flags_t cf;
641 mblk_t *mp = 0;
642 uint16_t data16;
643 usbd_status error;
645 data16 = *data;
646 bzero(&req, sizeof (req));
647 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
648 req.bRequest = URTW_8187_SETREGS_REQ;
649 req.wValue = addr;
650 req.wIndex = (uint16_t)index;
651 req.wLength = sizeof (uint16_t);
652 req.attrs = USB_ATTRS_NONE;
654 mp = allocb(sizeof (uint16_t), BPRI_MED);
655 if (mp == 0) {
656 cmn_err(CE_WARN, "urtw_8225_write_s16: allocb failed\n");
657 return (-1);
659 *(mp->b_rptr) = (data16 & 0x00ff);
660 *(mp->b_rptr + 1) = (data16 & 0xff00) >> 8;
661 mp->b_wptr += sizeof (uint16_t);
662 error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
663 &cr, &cf, 0);
664 if (error != USB_SUCCESS) {
665 URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
666 "urtw_8225_write_s16: could not set regs:"
667 "cr:%s(%d), cf:(%x)\n", usb_str_cr(cr), cr, cf));
669 if (mp)
670 freemsg(mp);
671 return (error);
675 static usbd_status
676 urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data)
678 int i;
679 int16_t bit;
680 uint8_t rlen = 12, wlen = 6;
681 uint16_t o1, o2, o3, tmp;
682 uint32_t d2w = ((uint32_t)(addr & 0x1f)) << 27;
683 uint32_t mask = 0x80000000, value = 0;
684 usbd_status error;
686 if (error = urtw_read16_c(sc, URTW_RF_PINS_OUTPUT, &o1, 0))
687 goto fail;
688 if (error = urtw_read16_c(sc, URTW_RF_PINS_ENABLE, &o2, 0))
689 goto fail;
690 if (error = urtw_read16_c(sc, URTW_RF_PINS_SELECT, &o3, 0))
691 goto fail;
692 if (error = urtw_write16_c(sc, URTW_RF_PINS_ENABLE, o2 | 0xf, 0))
693 goto fail;
694 if (error = urtw_write16_c(sc, URTW_RF_PINS_SELECT, o3 | 0xf, 0))
695 goto fail;
696 o1 &= ~0xf;
697 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
698 o1 | URTW_BB_HOST_BANG_EN, 0))
699 goto fail;
700 DELAY(5);
701 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT, o1, 0))
702 goto fail;
703 DELAY(5);
705 for (i = 0; i < (wlen / 2); i++, mask = mask >> 1) {
706 bit = ((d2w & mask) != 0) ? 1 : 0;
708 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
709 bit | o1, 0))
710 goto fail;
711 DELAY(2);
712 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
713 bit | o1 | URTW_BB_HOST_BANG_CLK, 0))
714 goto fail;
715 DELAY(2);
716 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
717 bit | o1 | URTW_BB_HOST_BANG_CLK, 0))
718 goto fail;
719 DELAY(2);
720 mask = mask >> 1;
721 if (i == 2)
722 break;
723 bit = ((d2w & mask) != 0) ? 1 : 0;
724 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
725 bit | o1 | URTW_BB_HOST_BANG_CLK, 0))
726 goto fail;
727 DELAY(2);
728 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
729 bit | o1 | URTW_BB_HOST_BANG_CLK, 0))
730 goto fail;
731 DELAY(2);
732 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
733 bit | o1, 0))
734 goto fail;
735 DELAY(1);
737 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
738 bit | o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK, 0))
739 goto fail;
740 DELAY(2);
741 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
742 bit | o1 | URTW_BB_HOST_BANG_RW, 0))
743 goto fail;
744 DELAY(2);
745 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
746 o1 | URTW_BB_HOST_BANG_RW, 0))
747 goto fail;
748 DELAY(2);
750 mask = 0x800;
751 for (i = 0; i < rlen; i++, mask = mask >> 1) {
752 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
753 o1 | URTW_BB_HOST_BANG_RW, 0))
754 goto fail;
755 DELAY(2);
756 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
757 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK, 0))
758 goto fail;
759 DELAY(2);
760 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
761 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK, 0))
762 goto fail;
763 DELAY(2);
764 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
765 o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK, 0))
766 goto fail;
767 DELAY(2);
769 if (error = urtw_read16_c(sc, URTW_RF_PINS_INPUT, &tmp, 0))
770 goto fail;
771 value |= ((tmp & URTW_BB_HOST_BANG_CLK) ? mask : 0);
772 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
773 o1 | URTW_BB_HOST_BANG_RW, 0))
774 goto fail;
775 DELAY(2);
778 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
779 o1 | URTW_BB_HOST_BANG_EN |
780 URTW_BB_HOST_BANG_RW, 0))
781 goto fail;
782 DELAY(2);
784 if (error = urtw_write16_c(sc, URTW_RF_PINS_ENABLE, o2, 0))
785 goto fail;
786 if (error = urtw_write16_c(sc, URTW_RF_PINS_SELECT, o3, 0))
787 goto fail;
788 error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT, 0x3a0, 0);
790 if (data != NULL)
791 *data = value;
792 fail:
793 return (error);
796 static void
797 urtw_delay_ms(int t)
799 DELAY(t * 1000);
802 static usbd_status
803 urtw_8225_write_c(struct urtw_softc *sc, uint8_t addr, uint16_t data)
805 uint16_t d80, d82, d84;
806 usbd_status error;
808 if (error = urtw_read16_c(sc, URTW_RF_PINS_OUTPUT, &d80, 0))
809 goto fail;
810 d80 &= 0xfff3;
811 if (error = urtw_read16_c(sc, URTW_RF_PINS_ENABLE, &d82, 0))
812 goto fail;
813 if (error = urtw_read16_c(sc, URTW_RF_PINS_SELECT, &d84, 0))
814 goto fail;
815 d84 &= 0xfff0;
816 if (error = urtw_write16_c(sc, URTW_RF_PINS_ENABLE,
817 d82 | 0x0007, 0))
818 goto fail;
819 if (error = urtw_write16_c(sc, URTW_RF_PINS_SELECT,
820 d84 | 0x0007, 0))
821 goto fail;
823 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
824 d80 | URTW_BB_HOST_BANG_EN, 0))
825 goto fail;
826 urtw_delay_ms(2);
827 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT, d80, 0))
828 goto fail;
830 error = urtw_8225_write_s16(sc, addr, 0x8225, &data);
831 if (error != 0)
832 goto fail;
834 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
835 d80 | URTW_BB_HOST_BANG_EN, 0))
836 goto fail;
837 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT,
838 d80 | URTW_BB_HOST_BANG_EN, 0))
839 goto fail;
840 error = urtw_write16_c(sc, URTW_RF_PINS_SELECT, d84, 0);
841 urtw_delay_ms(2);
842 fail:
843 return (error);
846 static usbd_status
847 urtw_8225_isv2(struct urtw_softc *sc, int *ret)
849 uint32_t data;
850 usbd_status error;
852 *ret = 1;
854 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT, 0x0080, 0))
855 goto fail;
856 if (error = urtw_write16_c(sc, URTW_RF_PINS_SELECT, 0x0080, 0))
857 goto fail;
858 if (error = urtw_write16_c(sc, URTW_RF_PINS_ENABLE, 0x0080, 0))
859 goto fail;
860 urtw_delay_ms(300);
862 if (error = urtw_8225_write_c(sc, 0x0, 0x1b7))
863 goto fail;
865 error = urtw_8225_read(sc, 0x8, &data);
866 if (error != 0)
867 goto fail;
868 if (data != 0x588)
869 *ret = 0;
870 else {
871 error = urtw_8225_read(sc, 0x9, &data);
872 if (error != 0)
873 goto fail;
874 if (data != 0x700)
875 *ret = 0;
878 error = urtw_8225_write_c(sc, 0x0, 0xb7);
879 fail:
880 return (error);
883 static usbd_status
884 urtw_get_rfchip(struct urtw_softc *sc)
886 struct urtw_rf *rf = &sc->sc_rf;
887 int ret;
888 uint32_t data;
889 usbd_status error;
891 rf->rf_sc = sc;
893 if (sc->sc_hwrev & URTW_HWREV_8187) {
894 error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data);
895 if (error != 0) {
896 cmn_err(CE_WARN, "RF ID read failed\n");
897 return (-1);
899 switch (data & 0xff) {
900 case URTW_EPROM_RFCHIPID_RTL8225U:
901 error = urtw_8225_isv2(sc, &ret);
902 if (error != 0) {
903 URTW8187_DBG(URTW_DEBUG_HWTYPE,
904 (sc->sc_dev, CE_CONT,
905 "8225 version check failed\n"));
906 goto fail;
908 if (ret == 0) {
909 URTW8187_DBG(URTW_DEBUG_HWTYPE,
910 (sc->sc_dev, CE_CONT,
911 "8225 detected\n"));
912 rf->init = urtw_8225_rf_init;
913 rf->set_chan = urtw_8225_rf_set_chan;
914 rf->set_sens = urtw_8225_rf_set_sens;
915 } else {
916 URTW8187_DBG(URTW_DEBUG_HWTYPE,
917 (sc->sc_dev, CE_CONT,
918 "8225 v2 detected\n"));
919 rf->init = urtw_8225v2_rf_init;
920 rf->set_chan = urtw_8225v2_rf_set_chan;
921 rf->set_sens = NULL;
923 break;
924 default:
925 goto fail;
927 } else {
928 URTW8187_DBG(URTW_DEBUG_HWTYPE,
929 (sc->sc_dev, CE_CONT,
930 "8225 v2 [b] detected\n"));
931 rf->init = urtw_8225v2_b_rf_init;
932 rf->set_chan = urtw_8225v2_b_rf_set_chan;
933 rf->set_sens = NULL;
936 rf->max_sens = URTW_8225_RF_MAX_SENS;
937 rf->sens = URTW_8225_RF_DEF_SENS;
939 return (0);
941 fail:
942 cmn_err(CE_WARN, "unsupported RF chip %d\n", data & 0xff);
943 return (-1);
946 static usbd_status
947 urtw_get_txpwr(struct urtw_softc *sc)
949 int i, j;
950 uint32_t data;
951 usbd_status error;
953 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW_BASE, &data);
954 if (error != 0)
955 goto fail;
956 sc->sc_txpwr_cck_base = data & 0xf;
957 sc->sc_txpwr_ofdm_base = (data >> 4) & 0xf;
959 for (i = 1, j = 0; i < 6; i += 2, j++) {
960 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW0 + j, &data);
961 if (error != 0)
962 goto fail;
963 sc->sc_txpwr_cck[i] = data & 0xf;
964 sc->sc_txpwr_cck[i + 1] = (data & 0xf00) >> 8;
965 sc->sc_txpwr_ofdm[i] = (data & 0xf0) >> 4;
966 sc->sc_txpwr_ofdm[i + 1] = (data & 0xf000) >> 12;
968 for (i = 1, j = 0; i < 4; i += 2, j++) {
969 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW1 + j, &data);
970 if (error != 0)
971 goto fail;
972 sc->sc_txpwr_cck[i + 6] = data & 0xf;
973 sc->sc_txpwr_cck[i + 6 + 1] = (data & 0xf00) >> 8;
974 sc->sc_txpwr_ofdm[i + 6] = (data & 0xf0) >> 4;
975 sc->sc_txpwr_ofdm[i + 6 + 1] = (data & 0xf000) >> 12;
977 if (sc->sc_hwrev & URTW_HWREV_8187) {
978 for (i = 1, j = 0; i < 4; i += 2, j++) {
979 error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2 + j,
980 &data);
981 if (error != 0)
982 goto fail;
983 sc->sc_txpwr_cck[i + 6 + 4] = data & 0xf;
984 sc->sc_txpwr_cck[i + 6 + 4 + 1] = (data & 0xf00) >> 8;
985 sc->sc_txpwr_ofdm[i + 6 + 4] = (data & 0xf0) >> 4;
986 sc->sc_txpwr_ofdm[i + 6 + 4 + 1] =
987 (data & 0xf000) >> 12;
989 } else {
990 /* Channel 11. */
991 error = urtw_eprom_read32(sc, 0x1b, &data);
992 if (error != 0)
993 goto fail;
994 sc->sc_txpwr_cck[11] = data & 0xf;
995 sc->sc_txpwr_ofdm[11] = (data & 0xf0) >> 4;
997 /* Channel 12. */
998 error = urtw_eprom_read32(sc, 0xa, &data);
999 if (error != 0)
1000 goto fail;
1001 sc->sc_txpwr_cck[12] = data & 0xf;
1002 sc->sc_txpwr_ofdm[12] = (data & 0xf0) >> 4;
1004 /* Channel 13, 14. */
1005 error = urtw_eprom_read32(sc, 0x1c, &data);
1006 if (error != 0)
1007 goto fail;
1008 sc->sc_txpwr_cck[13] = data & 0xf;
1009 sc->sc_txpwr_ofdm[13] = (data & 0xf0) >> 4;
1010 sc->sc_txpwr_cck[14] = (data & 0xf00) >> 8;
1011 sc->sc_txpwr_ofdm[14] = (data & 0xf000) >> 12;
1013 fail:
1014 return (error);
1018 static usbd_status
1019 urtw_get_macaddr(struct urtw_softc *sc)
1021 uint32_t data;
1022 usbd_status error;
1023 uint8_t *m = 0;
1025 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
1026 if (error != 0)
1027 goto fail;
1028 sc->sc_bssid[0] = data & 0xff;
1029 sc->sc_bssid[1] = (data & 0xff00) >> 8;
1030 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
1031 if (error != 0)
1032 goto fail;
1033 sc->sc_bssid[2] = data & 0xff;
1034 sc->sc_bssid[3] = (data & 0xff00) >> 8;
1035 error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
1036 if (error != 0)
1037 goto fail;
1038 sc->sc_bssid[4] = data & 0xff;
1039 sc->sc_bssid[5] = (data & 0xff00) >> 8;
1040 bcopy(sc->sc_bssid, sc->sc_ic.ic_macaddr, IEEE80211_ADDR_LEN);
1041 m = sc->sc_bssid;
1042 URTW8187_DBG(URTW_DEBUG_HWTYPE, (sc->sc_dev, CE_CONT,
1043 "MAC: %x:%x:%x:%x:%x:%x\n",
1044 m[0], m[1], m[2], m[3], m[4], m[5]));
1045 fail:
1046 return (error);
1049 static usbd_status
1050 urtw_eprom_read32(struct urtw_softc *sc, uint32_t addr, uint32_t *data)
1052 #define URTW_READCMD_LEN 3
1053 int addrlen, i;
1054 int16_t addrstr[8], data16, readcmd[] = { 1, 1, 0 };
1055 usbd_status error;
1057 /* NB: make sure the buffer is initialized */
1058 *data = 0;
1060 /* enable EPROM programming */
1061 if (error = urtw_write8_c(sc, URTW_EPROM_CMD,
1062 URTW_EPROM_CMD_PROGRAM_MODE, 0))
1063 goto fail;
1064 DELAY(URTW_EPROM_DELAY);
1066 error = urtw_eprom_cs(sc, URTW_EPROM_ENABLE);
1067 if (error != 0)
1068 goto fail;
1069 error = urtw_eprom_ck(sc);
1070 if (error != 0)
1071 goto fail;
1072 error = urtw_eprom_sendbits(sc, readcmd, URTW_READCMD_LEN);
1073 if (error != 0)
1074 goto fail;
1075 if (sc->sc_epromtype == URTW_EEPROM_93C56) {
1076 addrlen = 8;
1077 addrstr[0] = addr & (1 << 7);
1078 addrstr[1] = addr & (1 << 6);
1079 addrstr[2] = addr & (1 << 5);
1080 addrstr[3] = addr & (1 << 4);
1081 addrstr[4] = addr & (1 << 3);
1082 addrstr[5] = addr & (1 << 2);
1083 addrstr[6] = addr & (1 << 1);
1084 addrstr[7] = addr & (1 << 0);
1085 } else {
1086 addrlen = 6;
1087 addrstr[0] = addr & (1 << 5);
1088 addrstr[1] = addr & (1 << 4);
1089 addrstr[2] = addr & (1 << 3);
1090 addrstr[3] = addr & (1 << 2);
1091 addrstr[4] = addr & (1 << 1);
1092 addrstr[5] = addr & (1 << 0);
1094 error = urtw_eprom_sendbits(sc, addrstr, addrlen);
1095 if (error != 0)
1096 goto fail;
1098 error = urtw_eprom_writebit(sc, 0);
1099 if (error != 0)
1100 goto fail;
1102 for (i = 0; i < 16; i++) {
1103 error = urtw_eprom_ck(sc);
1104 if (error != 0)
1105 goto fail;
1106 error = urtw_eprom_readbit(sc, &data16);
1107 if (error != 0)
1108 goto fail;
1110 (*data) |= (data16 << (15 - i));
1113 error = urtw_eprom_cs(sc, URTW_EPROM_DISABLE);
1114 if (error != 0)
1115 goto fail;
1116 error = urtw_eprom_ck(sc);
1117 if (error != 0)
1118 goto fail;
1120 /* now disable EPROM programming */
1121 error = urtw_write8_c(sc, URTW_EPROM_CMD,
1122 URTW_EPROM_CMD_NORMAL_MODE, 0);
1123 fail:
1124 return (error);
1125 #undef URTW_READCMD_LEN
1128 static usbd_status
1129 urtw_eprom_readbit(struct urtw_softc *sc, int16_t *data)
1131 uint8_t data8;
1132 usbd_status error;
1134 error = urtw_read8_c(sc, URTW_EPROM_CMD, &data8, 0);
1135 *data = (data8 & URTW_EPROM_READBIT) ? 1 : 0;
1136 DELAY(URTW_EPROM_DELAY);
1137 return (error);
1140 static usbd_status
1141 urtw_eprom_sendbits(struct urtw_softc *sc, int16_t *buf, int buflen)
1143 int i = 0;
1144 usbd_status error;
1146 for (i = 0; i < buflen; i++) {
1147 error = urtw_eprom_writebit(sc, buf[i]);
1148 if (error != 0)
1149 goto fail;
1150 error = urtw_eprom_ck(sc);
1151 if (error != 0)
1152 goto fail;
1154 fail:
1155 return (error);
1158 static usbd_status
1159 urtw_eprom_writebit(struct urtw_softc *sc, int16_t bit)
1161 uint8_t data;
1162 usbd_status error;
1164 if (error = urtw_read8_c(sc, URTW_EPROM_CMD, &data, 0))
1165 goto fail;
1166 if (bit != 0)
1167 error = urtw_write8_c(sc, URTW_EPROM_CMD,
1168 data | URTW_EPROM_WRITEBIT, 0);
1169 else
1170 error = urtw_write8_c(sc, URTW_EPROM_CMD,
1171 data & ~URTW_EPROM_WRITEBIT, 0);
1172 DELAY(URTW_EPROM_DELAY);
1173 fail:
1174 return (error);
1177 static usbd_status
1178 urtw_eprom_ck(struct urtw_softc *sc)
1180 uint8_t data;
1181 usbd_status error;
1183 /* masking */
1184 if (error = urtw_read8_c(sc, URTW_EPROM_CMD, &data, 0))
1185 goto fail;
1186 if (error = urtw_write8_c(sc, URTW_EPROM_CMD, data | URTW_EPROM_CK, 0))
1187 goto fail;
1188 DELAY(URTW_EPROM_DELAY);
1189 /* unmasking */
1190 if (error = urtw_read8_c(sc, URTW_EPROM_CMD, &data, 0))
1191 goto fail;
1192 error = urtw_write8_c(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CK, 0);
1193 DELAY(URTW_EPROM_DELAY);
1194 fail:
1195 return (error);
1198 static usbd_status
1199 urtw_eprom_cs(struct urtw_softc *sc, int able)
1201 uint8_t data;
1202 usbd_status error;
1204 if (error = urtw_read8_c(sc, URTW_EPROM_CMD, &data, 0))
1205 goto fail;
1206 if (able == URTW_EPROM_ENABLE)
1207 error = urtw_write8_c(sc, URTW_EPROM_CMD,
1208 data | URTW_EPROM_CS, 0);
1209 else
1210 error = urtw_write8_c(sc, URTW_EPROM_CMD,
1211 data & ~URTW_EPROM_CS, 0);
1212 DELAY(URTW_EPROM_DELAY);
1213 fail:
1214 return (error);
1217 static usbd_status
1218 urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data, uint8_t idx)
1220 usb_ctrl_setup_t req;
1221 usb_cr_t cr;
1222 usb_cb_flags_t cf;
1223 mblk_t *mp = NULL;
1224 usbd_status error;
1226 bzero(&req, sizeof (req));
1227 req.bmRequestType = UT_READ_VENDOR_DEVICE;
1228 req.bRequest = URTW_8187_GETREGS_REQ;
1229 req.wValue = val | 0xff00;
1230 req.wIndex = idx & 0x03;
1231 req.wLength = sizeof (uint8_t);
1233 error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
1234 &cr, &cf, 0);
1236 if (error != USB_SUCCESS) {
1237 URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
1238 "urtw_read8_c: get regs req failed :"
1239 " cr:%s(%d), cf:(%x)\n", usb_str_cr(cr), cr, cf));
1240 return (error);
1242 bcopy(mp->b_rptr, data, sizeof (uint8_t));
1243 if (mp)
1244 freemsg(mp);
1245 return (error);
1248 static usbd_status
1249 urtw_read8e(struct urtw_softc *sc, int val, uint8_t *data)
1251 usb_ctrl_setup_t req;
1252 usb_cr_t cr;
1253 usb_cb_flags_t cf;
1254 mblk_t *mp = NULL;
1255 usbd_status error;
1257 bzero(&req, sizeof (req));
1258 req.bmRequestType = UT_READ_VENDOR_DEVICE;
1259 req.bRequest = URTW_8187_GETREGS_REQ;
1260 req.wValue = val | 0xfe00;
1261 req.wIndex = 0;
1262 req.wLength = sizeof (uint8_t);
1263 req.attrs = USB_ATTRS_AUTOCLEARING;
1264 error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
1265 &cr, &cf, 0);
1267 if (error != USB_SUCCESS) {
1268 URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
1269 "urtw_read8e: get regs req failed :"
1270 " cr:%s(%d), cf:(%x)\n", usb_str_cr(cr), cr, cf));
1271 return (error);
1274 if (mp) {
1275 bcopy(mp->b_rptr, data, sizeof (uint8_t));
1276 freemsg(mp);
1278 return (error);
1281 static usbd_status
1282 urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data, uint8_t idx)
1284 usb_ctrl_setup_t req;
1285 usb_cr_t cr;
1286 usb_cb_flags_t cf;
1287 mblk_t *mp = NULL;
1288 usbd_status error;
1290 bzero(&req, sizeof (req));
1291 req.bmRequestType = UT_READ_VENDOR_DEVICE;
1292 req.bRequest = URTW_8187_GETREGS_REQ;
1293 req.wValue = val | 0xff00;
1294 req.wIndex = idx & 0x03;
1295 req.wLength = sizeof (uint16_t);
1296 req.attrs = USB_ATTRS_AUTOCLEARING;
1297 error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
1298 &cr, &cf, 0);
1300 if (error != USB_SUCCESS) {
1301 URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
1302 "urtw_read16_c: get regs req failed :"
1303 " cr:%s(%d), cf:(%x)\n",
1304 usb_str_cr(cr), cr, cf));
1305 return (error);
1307 if (mp) {
1308 bcopy(mp->b_rptr, data, sizeof (uint16_t));
1309 freemsg(mp);
1311 return (error);
1314 static usbd_status
1315 urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data, uint8_t idx)
1317 usb_ctrl_setup_t req;
1318 usb_cr_t cr;
1319 usb_cb_flags_t cf;
1320 mblk_t *mp = NULL;
1321 usbd_status error;
1323 bzero(&req, sizeof (req));
1324 req.bmRequestType = UT_READ_VENDOR_DEVICE;
1325 req.bRequest = URTW_8187_GETREGS_REQ;
1326 req.wValue = val | 0xff00;
1327 req.wIndex = idx & 0x03;
1328 req.wLength = sizeof (uint32_t);
1329 req.attrs = USB_ATTRS_AUTOCLEARING;
1331 error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
1332 &cr, &cf, 0);
1334 if (error != USB_SUCCESS) {
1335 URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
1336 "urtw_read32_c: get regs req failed :"
1337 " cr:%s(%d), cf:(%x)\n", usb_str_cr(cr), cr, cf));
1338 return (error);
1341 if (mp) {
1342 bcopy(mp->b_rptr, data, sizeof (uint32_t));
1343 freemsg(mp);
1345 return (error);
1348 static usbd_status
1349 urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data, uint8_t idx)
1351 usb_ctrl_setup_t req;
1352 usb_cr_t cr;
1353 usb_cb_flags_t cf;
1354 mblk_t *mp = 0;
1355 int error;
1357 bzero(&req, sizeof (req));
1358 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1359 req.bRequest = URTW_8187_SETREGS_REQ;
1360 req.wValue = val | 0xff00;
1361 req.wIndex = idx & 0x03;
1362 req.wLength = sizeof (uint8_t);
1363 req.attrs = USB_ATTRS_NONE;
1365 mp = allocb(sizeof (uint32_t), BPRI_MED);
1366 if (mp == NULL) {
1367 cmn_err(CE_CONT, "urtw_write8_c: failed alloc mblk.");
1368 return (-1);
1370 *(uint8_t *)(mp->b_rptr) = data;
1371 mp->b_wptr += sizeof (uint8_t);
1372 error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
1373 &cr, &cf, 0);
1374 if (error != USB_SUCCESS) {
1375 URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
1376 "urtw_write8_c: could not set regs:"
1377 "cr:%s(%d), cf:(%x)\n", usb_str_cr(cr), cr, cf));
1379 if (mp)
1380 freemsg(mp);
1381 return (error);
1384 static usbd_status
1385 urtw_write8e(struct urtw_softc *sc, int val, uint8_t data)
1387 usb_ctrl_setup_t req;
1388 usb_cr_t cr;
1389 usb_cb_flags_t cf;
1390 mblk_t *mp = 0;
1391 int error;
1393 bzero(&req, sizeof (req));
1394 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1395 req.bRequest = URTW_8187_SETREGS_REQ;
1396 req.wValue = val | 0xfe00;
1397 req.wIndex = 0;
1398 req.wLength = sizeof (uint8_t);
1399 req.attrs = USB_ATTRS_NONE;
1401 mp = allocb(sizeof (uint8_t), BPRI_MED);
1402 if (mp == NULL) {
1403 cmn_err(CE_CONT, "urtw_write8e: failed alloc mblk.");
1404 return (-1);
1406 *(mp->b_rptr) = data;
1407 mp->b_wptr += sizeof (uint8_t);
1409 error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
1410 &cr, &cf, 0);
1411 if (error != USB_SUCCESS) {
1412 URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
1413 "urtw_write8e: could not set regs:"
1414 "cr:%s(%d), cf:(%x)\n",
1415 usb_str_cr(cr), cr, cf));
1417 if (mp)
1418 freemsg(mp);
1419 return (error);
1422 static usbd_status
1423 urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data, uint8_t idx)
1425 usb_ctrl_setup_t req;
1426 usb_cr_t cr;
1427 usb_cb_flags_t cf;
1428 mblk_t *mp = 0;
1429 int error;
1431 bzero(&req, sizeof (req));
1432 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1433 req.bRequest = URTW_8187_SETREGS_REQ;
1434 req.wValue = val | 0xff00;
1435 req.wIndex = idx & 0x03;
1436 req.wLength = sizeof (uint16_t);
1437 req.attrs = USB_ATTRS_NONE;
1439 mp = allocb(sizeof (uint16_t), BPRI_MED);
1440 if (mp == NULL) {
1441 cmn_err(CE_CONT, "urtw_write16_c: failed alloc mblk.");
1442 return (-1);
1444 *(uint16_t *)(uintptr_t)(mp->b_rptr) = data;
1445 mp->b_wptr += sizeof (uint16_t);
1446 error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
1447 &cr, &cf, 0);
1448 if (error != USB_SUCCESS) {
1449 URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
1450 "urtw_write16_c: could not set regs:"
1451 "cr:%s(%d), cf:(%x)\n",
1452 usb_str_cr(cr), cr, cf));
1454 if (mp)
1455 freemsg(mp);
1456 return (error);
1459 static usbd_status
1460 urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data, uint8_t idx)
1462 usb_ctrl_setup_t req;
1463 usb_cr_t cr;
1464 usb_cb_flags_t cf;
1465 mblk_t *mp = 0;
1466 int error;
1468 bzero(&req, sizeof (req));
1469 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1470 req.bRequest = URTW_8187_SETREGS_REQ;
1471 req.wValue = val | 0xff00;
1472 req.wIndex = idx & 0x03;
1473 req.wLength = sizeof (uint32_t);
1474 req.attrs = USB_ATTRS_NONE;
1476 mp = allocb(sizeof (uint32_t), BPRI_MED);
1477 if (mp == NULL) {
1478 cmn_err(CE_CONT, "urtw_write32_c: failed alloc mblk.");
1479 return (-1);
1481 *(uint32_t *)(uintptr_t)(mp->b_rptr) = data;
1482 mp->b_wptr += sizeof (uint32_t);
1483 error = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
1484 &cr, &cf, 0);
1485 if (error != USB_SUCCESS) {
1486 URTW8187_DBG(URTW_DEBUG_DEVREQ, (sc->sc_dev, CE_CONT,
1487 "urtw_write32_c: could not set regs:"
1488 "cr:%s(%d), cf:(%x)\n",
1489 usb_str_cr(cr), cr, cf));
1492 if (mp)
1493 freemsg(mp);
1494 return (error);
1497 static usbd_status
1498 urtw_set_mode(struct urtw_softc *sc, uint32_t mode)
1500 uint8_t data;
1501 usbd_status error;
1503 if (error = urtw_read8_c(sc, URTW_EPROM_CMD, &data, 0))
1504 goto fail;
1505 data = (data & ~URTW_EPROM_CMD_MASK) | (mode << URTW_EPROM_CMD_SHIFT);
1506 data = data & ~(URTW_EPROM_CS | URTW_EPROM_CK);
1507 error = urtw_write8_c(sc, URTW_EPROM_CMD, data, 0);
1508 fail:
1509 return (error);
1512 static usbd_status
1513 urtw_8180_set_anaparam(struct urtw_softc *sc, uint32_t val)
1515 uint8_t data;
1516 usbd_status error;
1518 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1519 if (error)
1520 goto fail;
1522 if (error = urtw_read8_c(sc, URTW_CONFIG3, &data, 0))
1523 goto fail;
1524 if (error = urtw_write8_c(sc, URTW_CONFIG3,
1525 data | URTW_CONFIG3_ANAPARAM_WRITE, 0))
1526 goto fail;
1527 if (error = urtw_write32_c(sc, URTW_ANAPARAM, val, 0))
1528 goto fail;
1529 if (error = urtw_read8_c(sc, URTW_CONFIG3, &data, 0))
1530 goto fail;
1531 if (error = urtw_write8_c(sc, URTW_CONFIG3,
1532 data & ~URTW_CONFIG3_ANAPARAM_WRITE, 0))
1533 goto fail;
1535 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1536 if (error)
1537 goto fail;
1538 fail:
1539 return (error);
1542 static usbd_status
1543 urtw_8185_set_anaparam2(struct urtw_softc *sc, uint32_t val)
1545 uint8_t data;
1546 usbd_status error;
1548 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
1549 if (error)
1550 goto fail;
1552 if (error = urtw_read8_c(sc, URTW_CONFIG3, &data, 0))
1553 goto fail;
1554 if (error = urtw_write8_c(sc, URTW_CONFIG3,
1555 data | URTW_CONFIG3_ANAPARAM_WRITE, 0))
1556 goto fail;
1557 if (error = urtw_write32_c(sc, URTW_ANAPARAM2, val, 0))
1558 goto fail;
1559 if (error = urtw_read8_c(sc, URTW_CONFIG3, &data, 0))
1560 goto fail;
1561 if (error = urtw_write8_c(sc, URTW_CONFIG3,
1562 data & ~URTW_CONFIG3_ANAPARAM_WRITE, 0))
1563 goto fail;
1565 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
1566 if (error)
1567 goto fail;
1568 fail:
1569 return (error);
1572 static usbd_status
1573 urtw_intr_disable(struct urtw_softc *sc)
1575 usbd_status error;
1577 error = urtw_write16_c(sc, URTW_INTR_MASK, 0, 0);
1578 return (error);
1581 static usbd_status
1582 urtw_8187_reset(struct urtw_softc *sc)
1584 uint8_t data;
1585 usbd_status error;
1587 error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON);
1588 if (error)
1589 goto fail;
1590 error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON);
1591 if (error)
1592 goto fail;
1594 error = urtw_intr_disable(sc);
1595 if (error)
1596 goto fail;
1597 urtw_delay_ms(50);
1599 error = urtw_write8e(sc, 0x18, 0x10);
1600 if (error != 0)
1601 goto fail;
1602 error = urtw_write8e(sc, 0x18, 0x11);
1603 if (error != 0)
1604 goto fail;
1605 error = urtw_write8e(sc, 0x18, 0x00);
1606 if (error != 0)
1607 goto fail;
1608 urtw_delay_ms(50);
1610 if (error = urtw_read8_c(sc, URTW_CMD, &data, 0))
1611 goto fail;
1612 data = (data & 2) | URTW_CMD_RST;
1613 if (error = urtw_write8_c(sc, URTW_CMD, data, 0))
1614 goto fail;
1615 urtw_delay_ms(50);
1617 if (error = urtw_read8_c(sc, URTW_CMD, &data, 0))
1618 goto fail;
1619 if (data & URTW_CMD_RST) {
1620 cmn_err(CE_CONT, "urtw reset timeout\n");
1621 goto fail;
1623 error = urtw_set_mode(sc, URTW_EPROM_CMD_LOAD);
1624 if (error)
1625 goto fail;
1626 urtw_delay_ms(50);
1628 error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON);
1629 if (error)
1630 goto fail;
1631 error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON);
1632 if (error)
1633 goto fail;
1634 fail:
1635 return (error);
1638 static usbd_status
1639 urtw_led_on(struct urtw_softc *sc, int type)
1641 if (type == URTW_LED_GPIO) {
1642 switch (sc->sc_gpio_ledpin) {
1643 case URTW_LED_PIN_GPIO0:
1644 (void) urtw_write8_c(sc, URTW_GPIO, 0x01, 0);
1645 (void) urtw_write8_c(sc, URTW_GP_ENABLE, 0x00, 0);
1646 break;
1647 default:
1648 cmn_err(CE_WARN, "unsupported LED PIN type 0x%x",
1649 sc->sc_gpio_ledpin);
1650 /* never reach */
1652 } else {
1653 cmn_err(CE_WARN, "unsupported LED type 0x%x", type);
1654 /* never reach */
1657 sc->sc_gpio_ledon = 1;
1658 return (0);
1661 static usbd_status
1662 urtw_led_off(struct urtw_softc *sc, int type)
1664 if (type == URTW_LED_GPIO) {
1665 switch (sc->sc_gpio_ledpin) {
1666 case URTW_LED_PIN_GPIO0:
1667 (void) urtw_write8_c(sc, URTW_GPIO, 0x01, 0);
1668 (void) urtw_write8_c(sc, URTW_GP_ENABLE, 0x01, 0);
1669 break;
1670 default:
1671 cmn_err(CE_WARN, "unsupported LED PIN type 0x%x",
1672 sc->sc_gpio_ledpin);
1673 /* never reach */
1675 } else {
1676 cmn_err(CE_WARN, "unsupported LED type 0x%x", type);
1677 /* never reach */
1680 sc->sc_gpio_ledon = 0;
1681 return (0);
1684 static usbd_status
1685 urtw_led_mode0(struct urtw_softc *sc, int mode)
1687 URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
1688 "urtw_led_mode0: mode = %d\n", mode));
1689 switch (mode) {
1690 case URTW_LED_CTL_POWER_ON:
1691 sc->sc_gpio_ledstate = URTW_LED_POWER_ON_BLINK;
1692 break;
1693 case URTW_LED_CTL_TX:
1694 if (sc->sc_gpio_ledinprogress == 1)
1695 return (0);
1696 sc->sc_gpio_ledstate = URTW_LED_BLINK_NORMAL;
1697 sc->sc_gpio_blinktime =
1698 (sc->sc_ic.ic_state == IEEE80211_S_RUN ? 4:2);
1699 break;
1700 case URTW_LED_CTL_LINK:
1701 sc->sc_gpio_ledstate = URTW_LED_ON;
1702 break;
1703 default:
1704 cmn_err(CE_CONT, "unsupported LED mode 0x%x", mode);
1705 /* never reach */
1708 switch (sc->sc_gpio_ledstate) {
1709 case URTW_LED_ON:
1710 if (sc->sc_gpio_ledinprogress != 0)
1711 break;
1712 (void) urtw_led_on(sc, URTW_LED_GPIO);
1713 break;
1714 case URTW_LED_BLINK_NORMAL:
1715 if (sc->sc_gpio_ledinprogress != 0)
1716 break;
1717 sc->sc_gpio_ledinprogress = 1;
1718 sc->sc_gpio_blinkstate = (sc->sc_gpio_ledon != 0) ?
1719 URTW_LED_OFF : URTW_LED_ON;
1720 URTW_LEDLOCK(sc);
1721 if (sc->sc_led_ch == 0) {
1722 URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
1723 "urtw_led_mode0: restart led timer\n"));
1724 sc->sc_led_ch = timeout(urtw_led_launch,
1725 (void *)sc,
1726 drv_usectohz((sc->sc_ic.ic_state ==
1727 IEEE80211_S_RUN) ?
1728 URTW_LED_LINKON_BLINK :
1729 URTW_LED_LINKOFF_BLINK));
1730 sc->sc_gpio_ledinprogress = 0;
1732 URTW_LEDUNLOCK(sc);
1733 break;
1734 case URTW_LED_POWER_ON_BLINK:
1735 (void) urtw_led_on(sc, URTW_LED_GPIO);
1736 urtw_delay_ms(100);
1737 (void) urtw_led_off(sc, URTW_LED_GPIO);
1738 break;
1739 default:
1740 URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
1741 "urtw_led_mode0: unknown LED status 0x%x",
1742 sc->sc_gpio_ledstate));
1744 return (0);
1747 static usbd_status
1748 urtw_led_mode1(struct urtw_softc *sc, int mode)
1750 cmn_err(CE_WARN, "urtw sc %p, mode %d not supported", (void *)sc, mode);
1751 return (USBD_INVAL);
1754 static usbd_status
1755 urtw_led_mode2(struct urtw_softc *sc, int mode)
1757 cmn_err(CE_WARN, "urtw sc %p, mode %d not supported", (void *)sc, mode);
1758 return (USBD_INVAL);
1761 static usbd_status
1762 urtw_led_mode3(struct urtw_softc *sc, int mode)
1764 cmn_err(CE_WARN, "urtw sc %p, mode %d not supported", (void *)sc, mode);
1765 return (USBD_INVAL);
1768 static usbd_status
1769 urtw_led_blink(struct urtw_softc *sc)
1771 uint8_t ing = 0;
1773 URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
1774 "urtw_led_blink: gpio_blinkstate %d\n",
1775 sc->sc_gpio_blinkstate));
1776 if (sc->sc_gpio_blinkstate == URTW_LED_ON)
1777 (void) urtw_led_on(sc, URTW_LED_GPIO);
1778 else
1779 (void) urtw_led_off(sc, URTW_LED_GPIO);
1780 sc->sc_gpio_blinktime--;
1781 if (sc->sc_gpio_blinktime == 0)
1782 ing = 1;
1783 else {
1784 if (sc->sc_gpio_ledstate != URTW_LED_BLINK_NORMAL &&
1785 sc->sc_gpio_ledstate != URTW_LED_BLINK_SLOWLY &&
1786 sc->sc_gpio_ledstate != URTW_LED_BLINK_CM3)
1787 ing = 1;
1789 if (ing == 1) {
1790 if (sc->sc_gpio_ledstate == URTW_LED_ON &&
1791 sc->sc_gpio_ledon == 0)
1792 (void) urtw_led_on(sc, URTW_LED_GPIO);
1793 else if (sc->sc_gpio_ledstate == URTW_LED_OFF &&
1794 sc->sc_gpio_ledon == 1)
1795 (void) urtw_led_off(sc, URTW_LED_GPIO);
1797 sc->sc_gpio_blinktime = 0;
1798 sc->sc_gpio_ledinprogress = 0;
1799 return (0);
1802 sc->sc_gpio_blinkstate = (sc->sc_gpio_blinkstate != URTW_LED_ON) ?
1803 URTW_LED_ON : URTW_LED_OFF;
1805 switch (sc->sc_gpio_ledstate) {
1806 case URTW_LED_BLINK_NORMAL:
1807 URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
1808 "URTW_LED_BLINK_NORMAL\n"));
1809 return (1);
1810 default:
1811 URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
1812 "unknown LED status 0x%x", sc->sc_gpio_ledstate));
1814 return (0);
1817 static usbd_status
1818 urtw_led_ctl(struct urtw_softc *sc, int mode)
1820 usbd_status error = 0;
1822 switch (sc->sc_strategy) {
1823 case URTW_SW_LED_MODE0:
1824 error = urtw_led_mode0(sc, mode);
1825 break;
1826 case URTW_SW_LED_MODE1:
1827 error = urtw_led_mode1(sc, mode);
1828 break;
1829 case URTW_SW_LED_MODE2:
1830 error = urtw_led_mode2(sc, mode);
1831 break;
1832 case URTW_SW_LED_MODE3:
1833 error = urtw_led_mode3(sc, mode);
1834 break;
1835 default:
1836 cmn_err(CE_CONT, "unsupported LED mode %d\n", sc->sc_strategy);
1837 /* never reach */
1838 return (-1);
1841 return (error);
1844 static usbd_status
1845 urtw_update_msr(struct urtw_softc *sc, int nstate)
1847 struct ieee80211com *ic = &sc->sc_ic;
1848 uint8_t data;
1849 usbd_status error;
1851 if (error = urtw_read8_c(sc, URTW_MSR, &data, 0))
1852 goto fail;
1853 data &= ~URTW_MSR_LINK_MASK;
1855 /* Should always be set. */
1856 if (sc->sc_hwrev & URTW_HWREV_8187B)
1857 data |= URTW_MSR_LINK_ENEDCA;
1859 if (nstate == IEEE80211_S_RUN) {
1860 switch (ic->ic_opmode) {
1861 case IEEE80211_M_STA:
1862 case IEEE80211_M_MONITOR:
1863 data |= URTW_MSR_LINK_STA;
1864 break;
1865 case IEEE80211_M_IBSS:
1866 data |= URTW_MSR_LINK_ADHOC;
1867 break;
1868 case IEEE80211_M_HOSTAP:
1869 data |= URTW_MSR_LINK_HOSTAP;
1870 break;
1871 default:
1872 cmn_err(CE_CONT, "unsupported operation mode 0x%x\n",
1873 ic->ic_opmode);
1874 return (-1);
1876 } else
1877 data |= URTW_MSR_LINK_NONE;
1879 error = urtw_write8_c(sc, URTW_MSR, data, 0);
1880 fail:
1881 return (error);
1884 static uint16_t
1885 urtw_rate2rtl(int rate)
1887 #define N(a) (sizeof (a) / sizeof ((a)[0]))
1888 int i;
1890 for (i = 0; i < N(urtw_ratetable); i++) {
1891 if (rate == urtw_ratetable[i].reg)
1892 return (urtw_ratetable[i].val);
1894 return (3);
1895 #undef N
1898 static uint16_t
1899 urtw_rtl2rate(int rate)
1901 #define N(a) (sizeof (a) / sizeof ((a)[0]))
1902 int i;
1904 for (i = 0; i < N(urtw_ratetable); i++) {
1905 if (rate == urtw_ratetable[i].val)
1906 return (urtw_ratetable[i].reg);
1909 return (0);
1910 #undef N
1913 static usbd_status
1914 urtw_set_rate(struct urtw_softc *sc)
1916 int i, basic_rate, min_rr_rate, max_rr_rate;
1917 uint16_t data;
1918 usbd_status error;
1920 basic_rate = urtw_rate2rtl(48);
1921 min_rr_rate = urtw_rate2rtl(12);
1922 max_rr_rate = urtw_rate2rtl(48);
1923 if (error = urtw_write8_c(sc, URTW_RESP_RATE,
1924 max_rr_rate << URTW_RESP_MAX_RATE_SHIFT |
1925 min_rr_rate << URTW_RESP_MIN_RATE_SHIFT, 0))
1926 goto fail;
1928 if (error = urtw_read16_c(sc, URTW_BRSR, &data, 0))
1929 goto fail;
1930 data &= ~URTW_BRSR_MBR_8185;
1932 for (i = 0; i <= basic_rate; i++)
1933 data |= (1 << i);
1935 error = urtw_write16_c(sc, URTW_BRSR, data, 0);
1936 fail:
1937 return (error);
1940 static usbd_status
1941 urtw_intr_enable(struct urtw_softc *sc)
1943 usbd_status error;
1945 error = urtw_write16_c(sc, URTW_INTR_MASK, 0xffff, 0);
1946 return (error);
1949 static usbd_status
1950 urtw_rx_setconf(struct urtw_softc *sc)
1952 struct ieee80211com *ic = &sc->sc_ic;
1953 uint32_t data, a, b;
1954 usbd_status error;
1956 if (urtw_read32_c(sc, URTW_RX, &data, 0))
1957 goto fail;
1958 data = data &~ URTW_RX_FILTER_MASK;
1959 data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA;
1960 data = data | URTW_RX_FILTER_BCAST | URTW_RX_FILTER_MCAST;
1962 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
1963 data = data | URTW_RX_FILTER_ICVERR;
1964 data = data | URTW_RX_FILTER_PWR;
1966 if (sc->sc_crcmon == 1 && ic->ic_opmode == IEEE80211_M_MONITOR)
1967 data = data | URTW_RX_FILTER_CRCERR;
1968 data = data | URTW_RX_FILTER_NICMAC;
1969 data = data | URTW_RX_CHECK_BSSID;
1970 data = data &~ URTW_RX_FIFO_THRESHOLD_MASK;
1971 data = data | URTW_RX_FIFO_THRESHOLD_NONE | URTW_RX_AUTORESETPHY;
1972 data = data &~ URTW_MAX_RX_DMA_MASK;
1973 a = URTW_MAX_RX_DMA_2048;
1974 b = 0x80000000;
1975 data = data | a | b;
1977 error = urtw_write32_c(sc, URTW_RX, data, 0);
1978 fail:
1979 return (error);
1982 static usbd_status
1983 urtw_rx_enable(struct urtw_softc *sc)
1985 int i;
1986 usbd_status error;
1987 uint8_t data;
1989 sc->rx_queued = 0;
1990 for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++) {
1991 if (urtw_rx_start(sc) != 0) {
1992 return (USB_FAILURE);
1996 error = urtw_rx_setconf(sc);
1997 if (error != 0)
1998 goto fail;
2000 if (error = urtw_read8_c(sc, URTW_CMD, &data, 0))
2001 goto fail;
2002 error = urtw_write8_c(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE, 0);
2003 fail:
2004 return (error);
2007 void
2008 urtw_tx_enable(struct urtw_softc *sc)
2010 uint8_t data8;
2011 uint32_t data;
2013 if (sc->sc_hwrev & URTW_HWREV_8187) {
2014 (void) urtw_read8_c(sc, URTW_CW_CONF, &data8, 0);
2015 data8 &= ~(URTW_CW_CONF_PERPACKET_CW |
2016 URTW_CW_CONF_PERPACKET_RETRY);
2017 (void) urtw_write8_c(sc, URTW_CW_CONF, data8, 0);
2018 (void) urtw_read8_c(sc, URTW_TX_AGC_CTL, &data8, 0);
2019 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_GAIN;
2020 data8 &= ~URTW_TX_AGC_CTL_PERPACKET_ANTSEL;
2021 data8 &= ~URTW_TX_AGC_CTL_FEEDBACK_ANT;
2022 (void) urtw_write8_c(sc, URTW_TX_AGC_CTL, data8, 0);
2024 (void) urtw_read32_c(sc, URTW_TX_CONF, &data, 0);
2025 data &= ~URTW_TX_LOOPBACK_MASK;
2026 data |= URTW_TX_LOOPBACK_NONE;
2027 data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
2028 data |= sc->sc_tx_retry << URTW_TX_DPRETRY_SHIFT;
2029 data |= sc->sc_rts_retry << URTW_TX_RTSRETRY_SHIFT;
2030 data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
2031 data |= URTW_TX_MXDMA_2048 | URTW_TX_CWMIN | URTW_TX_DISCW;
2032 data &= ~URTW_TX_SWPLCPLEN;
2033 data |= URTW_TX_NOICV;
2034 (void) urtw_write32_c(sc, URTW_TX_CONF, data, 0);
2035 } else {
2036 data = URTW_TX_DURPROCMODE | URTW_TX_DISREQQSIZE |
2037 URTW_TX_MXDMA_2048 | URTW_TX_SHORTRETRY |
2038 URTW_TX_LONGRETRY;
2039 (void) urtw_write32_c(sc, URTW_TX_CONF, data, 0);
2042 (void) urtw_read8_c(sc, URTW_CMD, &data8, 0);
2043 (void) urtw_write8_c(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE, 0);
2046 static int
2047 urtw_8187_init(void *arg)
2049 struct urtw_softc *sc = arg;
2050 usbd_status error;
2051 struct urtw_rf *rf = &sc->sc_rf;
2052 int i;
2054 urtw_stop(sc);
2055 URTW_LOCK(sc);
2056 error = urtw_8187_reset(sc);
2057 if (error)
2058 goto fail;
2060 (void) urtw_write8_c(sc, 0x85, 0, 0);
2061 (void) urtw_write8_c(sc, URTW_GPIO, 0, 0);
2063 /* for led */
2064 (void) urtw_write8_c(sc, 0x85, 4, 0);
2065 error = urtw_led_ctl(sc, URTW_LED_CTL_POWER_ON);
2066 if (error != 0)
2067 goto fail;
2069 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
2070 if (error)
2071 goto fail;
2073 /* applying MAC address again. */
2074 for (i = 0; i < IEEE80211_ADDR_LEN; i++)
2075 (void) urtw_write8_c(sc, URTW_MAC0 + i,
2076 sc->sc_ic.ic_macaddr[i], 0);
2077 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
2078 if (error)
2079 goto fail;
2081 error = urtw_update_msr(sc, IEEE80211_S_INIT);
2082 if (error)
2083 goto fail;
2085 (void) urtw_write32_c(sc, URTW_INT_TIMEOUT, 0, 0);
2086 (void) urtw_write8_c(sc, URTW_WPA_CONFIG, 0, 0);
2087 (void) urtw_write8_c(sc, URTW_RATE_FALLBACK, 0x81, 0);
2088 error = urtw_set_rate(sc);
2089 if (error != 0)
2090 goto fail;
2092 error = rf->init(rf);
2093 if (error != 0)
2094 goto fail;
2095 if (rf->set_sens != NULL)
2096 rf->set_sens(rf);
2098 (void) urtw_write16_c(sc, 0x5e, 1, 0);
2099 (void) urtw_write16_c(sc, 0xfe, 0x10, 0);
2100 (void) urtw_write8_c(sc, URTW_TALLY_SEL, 0x80, 0);
2101 (void) urtw_write8_c(sc, 0xff, 0x60, 0);
2102 (void) urtw_write16_c(sc, 0x5e, 0, 0);
2103 (void) urtw_write8_c(sc, 0x85, 4, 0);
2105 error = urtw_intr_enable(sc);
2106 if (error != 0)
2107 goto fail;
2109 error = urtw_open_pipes(sc);
2110 if (error != 0)
2111 goto fail;
2112 sc->sc_tx_low_queued = 0;
2113 sc->sc_tx_normal_queued = 0;
2114 error = urtw_rx_enable(sc);
2115 if (error != 0)
2116 goto fail;
2117 urtw_tx_enable(sc);
2119 if (error == 0) {
2120 URTW8187_DBG(URTW_DEBUG_ACTIVE, (sc->sc_dev,
2121 CE_CONT, "urtw_8187_init: succesfully done\n"));
2122 sc->sc_flags |= URTW_FLAG_RUNNING;
2123 URTW_UNLOCK(sc);
2124 return (error);
2127 fail:
2128 URTW_UNLOCK(sc);
2129 urtw_stop(sc);
2130 return (EIO);
2134 static usbd_status
2135 urtw_8225_usb_init(struct urtw_softc *sc)
2137 uint8_t data;
2138 usbd_status error;
2140 if (error = urtw_write8_c(sc, URTW_RF_PINS_SELECT + 1, 0, 0))
2141 goto fail;
2142 if (error = urtw_write8_c(sc, URTW_GPIO, 0, 0))
2143 goto fail;
2144 if (error = urtw_read8e(sc, 0x53, &data))
2145 goto fail;
2146 if (error = urtw_write8e(sc, 0x53, data | (1 << 7)))
2147 goto fail;
2148 if (error = urtw_write8_c(sc, URTW_RF_PINS_SELECT + 1, 4, 0))
2149 goto fail;
2150 if (error = urtw_write8_c(sc, URTW_GPIO, 0x20, 0))
2151 goto fail;
2152 if (error = urtw_write8_c(sc, URTW_GP_ENABLE, 0, 0))
2153 goto fail;
2154 if (error = urtw_write16_c(sc, URTW_RF_PINS_OUTPUT, 0x80, 0))
2155 goto fail;
2156 if (error = urtw_write16_c(sc, URTW_RF_PINS_SELECT, 0x80, 0))
2157 goto fail;
2158 error = urtw_write16_c(sc, URTW_RF_PINS_ENABLE, 0x80, 0);
2160 urtw_delay_ms(100);
2161 fail:
2162 return (error);
2165 static usbd_status
2166 urtw_8185_rf_pins_enable(struct urtw_softc *sc)
2168 usbd_status error = 0;
2170 error = urtw_write16_c(sc, URTW_RF_PINS_ENABLE, 0x1ff7, 0);
2171 return (error);
2174 static usbd_status
2175 urtw_8187_write_phy(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2177 uint32_t phyw;
2178 usbd_status error;
2180 phyw = ((data << 8) | (addr | 0x80));
2181 if (error = urtw_write8_c(sc, 0x7f, ((phyw & 0xff000000) >> 24), 0))
2182 goto fail;
2183 if (error = urtw_write8_c(sc, 0x7e, ((phyw & 0x00ff0000) >> 16), 0))
2184 goto fail;
2185 if (error = urtw_write8_c(sc, 0x7d, ((phyw & 0x0000ff00) >> 8), 0))
2186 goto fail;
2187 error = urtw_write8_c(sc, 0x7c, (phyw & 0x000000ff), 0);
2189 * Delay removed from 8185 to 8187.
2190 * usbd_delay_ms(sc->sc_udev, 1);
2192 fail:
2193 return (error);
2196 static usbd_status
2197 urtw_8187_write_phy_ofdm_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2199 data = data & 0xff;
2200 return (urtw_8187_write_phy(sc, addr, data));
2203 static usbd_status
2204 urtw_8187_write_phy_cck_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
2206 data = data & 0xff;
2207 return (urtw_8187_write_phy(sc, addr, (data | 0x10000)));
2210 static usbd_status
2211 urtw_8225_setgain(struct urtw_softc *sc, int16_t gain)
2213 usbd_status error;
2215 if (error = urtw_8187_write_phy_ofdm_c(sc, 0x0d,
2216 urtw_8225_gain[gain * 4]))
2217 goto fail;
2218 if (error = urtw_8187_write_phy_ofdm_c(sc, 0x1b,
2219 urtw_8225_gain[gain * 4 + 2]))
2220 goto fail;
2221 if (error = urtw_8187_write_phy_ofdm_c(sc, 0x1d,
2222 urtw_8225_gain[gain * 4 + 3]))
2223 goto fail;
2224 error = urtw_8187_write_phy_ofdm_c(sc, 0x23,
2225 urtw_8225_gain[gain * 4 + 1]);
2226 fail:
2227 return (error);
2230 static usbd_status
2231 urtw_8225_set_txpwrlvl(struct urtw_softc *sc, int chan)
2233 int i, idx, set;
2234 uint8_t *cck_pwltable;
2235 uint8_t cck_pwrlvl_max, ofdm_pwrlvl_min, ofdm_pwrlvl_max;
2236 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
2237 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
2238 usbd_status error;
2240 cck_pwrlvl_max = 11;
2241 ofdm_pwrlvl_max = 25; /* 12 -> 25 */
2242 ofdm_pwrlvl_min = 10;
2244 /* CCK power setting */
2245 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ?
2246 cck_pwrlvl_max : cck_pwrlvl;
2247 idx = cck_pwrlvl % 6;
2248 set = cck_pwrlvl / 6;
2249 cck_pwltable = (chan == 14) ? urtw_8225_txpwr_cck_ch14 :
2250 urtw_8225_txpwr_cck;
2252 if (error = urtw_write8_c(sc, URTW_TX_GAIN_CCK,
2253 urtw_8225_tx_gain_cck_ofdm[set] >> 1, 0))
2254 goto fail;
2255 for (i = 0; i < 8; i++) {
2256 if (error = urtw_8187_write_phy_cck_c(sc, 0x44 + i,
2257 cck_pwltable[idx * 8 + i]))
2258 goto fail;
2260 urtw_delay_ms(1);
2261 /* OFDM power setting */
2262 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
2263 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
2264 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
2265 idx = ofdm_pwrlvl % 6;
2266 set = ofdm_pwrlvl / 6;
2268 error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON);
2269 if (error)
2270 goto fail;
2271 if (error = urtw_8187_write_phy_ofdm_c(sc, 2, 0x42))
2272 goto fail;
2273 if (error = urtw_8187_write_phy_ofdm_c(sc, 6, 0))
2274 goto fail;
2275 if (error = urtw_8187_write_phy_ofdm_c(sc, 8, 0))
2276 goto fail;
2278 if (error = urtw_write8_c(sc, URTW_TX_GAIN_OFDM,
2279 urtw_8225_tx_gain_cck_ofdm[set] >> 1, 0))
2280 goto fail;
2281 if (error = urtw_8187_write_phy_ofdm_c(sc, 0x5,
2282 urtw_8225_txpwr_ofdm[idx]))
2283 goto fail;
2284 error = urtw_8187_write_phy_ofdm_c(sc, 0x7,
2285 urtw_8225_txpwr_ofdm[idx]);
2286 urtw_delay_ms(1);
2287 fail:
2288 return (error);
2291 static usbd_status
2292 urtw_8185_tx_antenna(struct urtw_softc *sc, uint8_t ant)
2294 usbd_status error;
2296 error = urtw_write8_c(sc, URTW_TX_ANTENNA, ant, 0);
2297 urtw_delay_ms(1);
2298 return (error);
2301 static usbd_status
2302 urtw_8225_rf_init(struct urtw_rf *rf)
2304 #define N(a) (sizeof (a) / sizeof ((a)[0]))
2305 int i;
2306 uint16_t data;
2307 usbd_status error;
2308 struct urtw_softc *sc = rf->rf_sc;
2310 error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON);
2311 if (error)
2312 goto fail;
2314 if (error = urtw_8225_usb_init(sc))
2315 goto fail;
2316 if (error = urtw_write32_c(sc, URTW_RF_TIMING, 0x000a8008, 0))
2317 goto fail;
2318 if (error = urtw_read16_c(sc, URTW_BRSR, &data, 0))
2319 goto fail;
2320 if (error = urtw_write16_c(sc, URTW_BRSR, 0xffff, 0))
2321 goto fail;
2322 if (error = urtw_write32_c(sc, URTW_RF_PARA, 0x100044, 0))
2323 goto fail;
2325 if (error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG))
2326 goto fail;
2327 if (error = urtw_write8_c(sc, URTW_CONFIG3, 0x44, 0))
2328 goto fail;
2329 if (error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL))
2330 goto fail;
2331 if (error = urtw_8185_rf_pins_enable(sc))
2332 goto fail;
2333 urtw_delay_ms(100);
2335 for (i = 0; i < N(urtw_8225_rf_part1); i++) {
2336 if (error = urtw_8225_write_c(sc, urtw_8225_rf_part1[i].reg,
2337 urtw_8225_rf_part1[i].val))
2338 goto fail;
2339 urtw_delay_ms(1);
2341 urtw_delay_ms(50);
2342 if (error = urtw_8225_write_c(sc, 0x2, 0xc4d))
2343 goto fail;
2344 urtw_delay_ms(50);
2345 if (error = urtw_8225_write_c(sc, 0x2, 0x44d))
2346 goto fail;
2347 urtw_delay_ms(50);
2348 if (error = urtw_8225_write_c(sc, 0x0, 0x127))
2349 goto fail;
2351 for (i = 0; i < 95; i++) {
2352 if (error = urtw_8225_write_c(sc, 0x1, (uint8_t)(i + 1)))
2353 goto fail;
2354 if (error = urtw_8225_write_c(sc, 0x2, urtw_8225_rxgain[i]))
2355 goto fail;
2358 if (error = urtw_8225_write_c(sc, 0x0, 0x27))
2359 goto fail;
2360 if (error = urtw_8225_write_c(sc, 0x0, 0x22f))
2361 goto fail;
2363 for (i = 0; i < 128; i++) {
2364 if (error = urtw_8187_write_phy_ofdm_c(sc, 0xb,
2365 urtw_8225_agc[i]))
2366 goto fail;
2367 urtw_delay_ms(1);
2368 if (error = urtw_8187_write_phy_ofdm_c(sc, 0xa,
2369 (uint8_t)i + 0x80))
2370 goto fail;
2371 urtw_delay_ms(1);
2374 for (i = 0; i < N(urtw_8225_rf_part2); i++) {
2375 if (error = urtw_8187_write_phy_ofdm_c(sc,
2376 urtw_8225_rf_part2[i].reg,
2377 urtw_8225_rf_part2[i].val))
2378 goto fail;
2379 urtw_delay_ms(1);
2381 error = urtw_8225_setgain(sc, 4);
2382 if (error)
2383 goto fail;
2385 for (i = 0; i < N(urtw_8225_rf_part3); i++) {
2386 if (error = urtw_8187_write_phy_cck_c(sc,
2387 urtw_8225_rf_part3[i].reg,
2388 urtw_8225_rf_part3[i].val))
2389 goto fail;
2390 urtw_delay_ms(1);
2393 if (error = urtw_write8_c(sc, 0x5b, 0x0d, 0))
2394 goto fail;
2395 if (error = urtw_8225_set_txpwrlvl(sc, 1))
2396 goto fail;
2397 if (error = urtw_8187_write_phy_cck_c(sc, 0x10, 0x9b))
2398 goto fail;
2399 urtw_delay_ms(1);
2400 if (error = urtw_8187_write_phy_ofdm_c(sc, 0x26, 0x90))
2401 goto fail;
2402 urtw_delay_ms(1);
2404 /* TX ant A, 0x0 for B */
2405 if (error = urtw_8185_tx_antenna(sc, 0x3))
2406 goto fail;
2407 if (error = urtw_write32_c(sc, 0x94, 0x3dc00002, 0))
2408 goto fail;
2410 error = urtw_8225_rf_set_chan(rf,
2411 ieee80211_chan2ieee(&sc->sc_ic, sc->sc_ic.ic_curchan));
2412 fail:
2413 return (error);
2414 #undef N
2417 static usbd_status
2418 urtw_8225_rf_set_chan(struct urtw_rf *rf, int chan)
2420 #define IEEE80211_CHAN_G \
2421 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
2422 #define IEEE80211_IS_CHAN_G(_c) \
2423 (((_c)->ich_flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
2425 struct urtw_softc *sc = rf->rf_sc;
2426 struct ieee80211com *ic = &sc->sc_ic;
2427 struct ieee80211_channel *c = ic->ic_curchan;
2428 short gset = (IEEE80211_IS_CHAN_G(c)) ? 1 : 0;
2429 usbd_status error;
2431 if (error = urtw_8225_set_txpwrlvl(sc, chan))
2432 goto fail;
2433 if (urtw_8225_write_c(sc, 0x7, urtw_8225_channel[chan]))
2434 goto fail;
2435 urtw_delay_ms(10);
2437 if (error = urtw_write8_c(sc, URTW_SIFS, 0x22, 0))
2438 goto fail;
2440 if (ic->ic_state == IEEE80211_S_ASSOC &&
2441 ic->ic_flags & IEEE80211_F_SHSLOT)
2442 if (error = urtw_write8_c(sc, URTW_SLOT, 0x9, 0))
2443 goto fail;
2444 else
2445 if (error = urtw_write8_c(sc, URTW_SLOT, 0x14, 0))
2446 goto fail;
2447 if (gset) {
2448 /* for G */
2449 if (error = urtw_write8_c(sc, URTW_DIFS, 0x14, 0))
2450 goto fail;
2451 if (error = urtw_write8_c(sc, URTW_EIFS, 0x5b - 0x14, 0))
2452 goto fail;
2453 error = urtw_write8_c(sc, URTW_CW_VAL, 0x73, 0);
2454 } else {
2455 /* for B */
2456 if (error = urtw_write8_c(sc, URTW_DIFS, 0x24, 0))
2457 goto fail;
2458 if (error = urtw_write8_c(sc, URTW_EIFS, 0x5b - 0x24, 0))
2459 goto fail;
2460 error = urtw_write8_c(sc, URTW_CW_VAL, 0xa5, 0);
2463 fail:
2464 return (error);
2467 static usbd_status
2468 urtw_8225_rf_set_sens(struct urtw_rf *rf)
2470 usbd_status error;
2471 struct urtw_softc *sc = rf->rf_sc;
2473 if (rf->sens < 0 || rf->sens > 6)
2474 return (-1);
2476 if (rf->sens > 4)
2477 if (error = urtw_8225_write_c(sc, 0x0c, 0x850))
2478 goto fail;
2479 else
2480 if (error = urtw_8225_write_c(sc, 0x0c, 0x50))
2481 goto fail;
2483 rf->sens = 6 - rf->sens;
2484 if (error = urtw_8225_setgain(sc, rf->sens))
2485 goto fail;
2486 error = urtw_8187_write_phy_cck_c(sc, 0x41,
2487 urtw_8225_threshold[rf->sens]);
2488 fail:
2489 return (error);
2492 static void
2493 urtw_stop(struct urtw_softc *sc)
2495 URTW_LOCK(sc);
2496 sc->sc_flags &= ~URTW_FLAG_RUNNING;
2497 URTW_UNLOCK(sc);
2498 urtw_close_pipes(sc);
2501 static int
2502 urtw_isbmode(uint16_t rate)
2505 rate = urtw_rtl2rate(rate);
2507 return ((rate <= 22 && rate != 12 && rate != 18)?(1) : (0));
2510 /* ARGSUSED */
2511 static void
2512 urtw_rxeof(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
2514 struct urtw_softc *sc = (struct urtw_softc *)req->bulk_client_private;
2515 struct ieee80211com *ic = &sc->sc_ic;
2516 int actlen, len, flen, rssi;
2517 uint8_t *desc, rate;
2518 struct ieee80211_frame *wh;
2519 struct ieee80211_node *ni = 0;
2520 mblk_t *mp = 0;
2521 uint8_t *rxbuf;
2523 mp = req->bulk_data;
2524 req->bulk_data = NULL;
2525 if (req->bulk_completion_reason != USB_CR_OK ||
2526 mp == NULL) {
2527 sc->sc_rx_err++;
2528 URTW8187_DBG(URTW_DEBUG_RX_PROC, (sc->sc_dev, CE_CONT,
2529 "urtw_rxeof failed! %d, mp %p\n",
2530 req->bulk_completion_reason, mp));
2531 req->bulk_data = mp;
2532 goto fail;
2535 actlen = MBLKL(mp);
2536 rxbuf = (uint8_t *)mp->b_rptr;
2538 if (sc->sc_hwrev & URTW_HWREV_8187)
2539 /* 4 dword and 4 byte CRC */
2540 len = actlen - (4 * 4);
2541 else
2542 /* 5 dword and 4 byte CRC */
2543 len = actlen - (4 * 5);
2545 desc = rxbuf + len;
2546 flen = ((desc[1] & 0x0f) << 8) + (desc[0] & 0xff);
2547 if (flen > actlen) {
2548 cmn_err(CE_CONT, "urtw_rxeof: impossible: flen %d, actlen %d\n",
2549 flen, actlen);
2550 sc->sc_rx_err++;
2551 req->bulk_data = mp;
2552 goto fail;
2555 rate = (desc[2] & 0xf0) >> 4;
2556 if (sc->sc_hwrev & URTW_HWREV_8187) {
2557 rssi = (desc[6] & 0xfe) >> 1;
2559 /* XXX correct? */
2560 if (!urtw_isbmode(rate)) {
2561 rssi = (rssi > 90) ? 90 : ((rssi < 25) ? 25 : rssi);
2562 rssi = ((90 - rssi) * 100) / 65;
2563 } else {
2564 rssi = (rssi > 90) ? 95 : ((rssi < 30) ? 30 : rssi);
2565 rssi = ((95 - rssi) * 100) / 65;
2567 } else {
2568 rssi = 14 + desc[13]/2;
2569 if (rssi >= 95)
2570 rssi = 95;
2571 URTW8187_DBG(URTW_DEBUG_RX_PROC, (sc->sc_dev, CE_CONT,
2572 "urtw_rxeof: rssi %u\n", rssi));
2575 mp->b_wptr = mp->b_rptr + flen - 4;
2576 wh = (struct ieee80211_frame *)mp->b_rptr;
2577 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK)
2578 == IEEE80211_FC0_TYPE_DATA) {
2579 sc->sc_currate = (rate > 0) ? rate : sc->sc_currate;
2580 URTW8187_DBG(URTW_DEBUG_RX_PROC, (sc->sc_dev, CE_CONT,
2581 "urtw_rxeof: update sc_currate to %u\n",
2582 sc->sc_currate));
2584 ni = ieee80211_find_rxnode(ic, wh);
2586 /* send the frame to the 802.11 layer */
2587 (void) ieee80211_input(ic, mp, ni, rssi, 0);
2589 /* node is no longer needed */
2590 ieee80211_free_node(ni);
2591 fail:
2592 mutex_enter(&sc->rx_lock);
2593 sc->rx_queued--;
2594 mutex_exit(&sc->rx_lock);
2595 usb_free_bulk_req(req);
2596 if (URTW_IS_RUNNING(sc) && !URTW_IS_SUSPENDING(sc))
2597 (void) urtw_rx_start(sc);
2600 static usbd_status
2601 urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain)
2603 uint8_t *gainp;
2604 usbd_status error;
2606 /* XXX for A? */
2607 gainp = urtw_8225v2_gain_bg;
2608 if (error = urtw_8187_write_phy_ofdm_c(sc, 0x0d, gainp[gain * 3]))
2609 goto fail;
2610 urtw_delay_ms(1);
2611 if (error = urtw_8187_write_phy_ofdm_c(sc, 0x1b, gainp[gain * 3 + 1]))
2612 urtw_delay_ms(1);
2613 if (error = urtw_8187_write_phy_ofdm_c(sc, 0x1d, gainp[gain * 3 + 2]))
2614 goto fail;
2615 urtw_delay_ms(1);
2616 if (error = urtw_8187_write_phy_ofdm_c(sc, 0x21, 0x17))
2617 goto fail;
2618 urtw_delay_ms(1);
2619 fail:
2620 return (error);
2623 static usbd_status
2624 urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan)
2626 int i;
2627 uint8_t *cck_pwrtable;
2628 uint8_t cck_pwrlvl_max = 15, ofdm_pwrlvl_max = 25, ofdm_pwrlvl_min = 10;
2629 uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
2630 uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
2631 usbd_status error;
2633 /* CCK power setting */
2634 cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ?
2635 cck_pwrlvl_max : cck_pwrlvl;
2636 cck_pwrlvl += sc->sc_txpwr_cck_base;
2637 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
2638 cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
2639 urtw_8225v2_txpwr_cck;
2641 for (i = 0; i < 8; i++) {
2642 if (error = urtw_8187_write_phy_cck_c(sc, 0x44 + i,
2643 cck_pwrtable[i]))
2644 goto fail;
2646 if (error = urtw_write8_c(sc, URTW_TX_GAIN_CCK,
2647 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl], 0))
2648 goto fail;
2649 urtw_delay_ms(1);
2651 /* OFDM power setting */
2652 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
2653 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
2654 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
2655 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
2657 error = urtw_8185_set_anaparam2(sc, URTW_8187_8225_ANAPARAM2_ON);
2658 if (error)
2659 goto fail;
2661 if (error = urtw_8187_write_phy_ofdm_c(sc, 2, 0x42))
2662 goto fail;
2663 if (error = urtw_8187_write_phy_ofdm_c(sc, 5, 0x0))
2664 goto fail;
2665 if (error = urtw_8187_write_phy_ofdm_c(sc, 6, 0x40))
2666 goto fail;
2667 if (error = urtw_8187_write_phy_ofdm_c(sc, 7, 0x0))
2668 goto fail;
2669 if (error = urtw_8187_write_phy_ofdm_c(sc, 8, 0x40))
2670 goto fail;
2672 error = urtw_write8_c(sc, URTW_TX_GAIN_OFDM,
2673 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl], 0);
2674 urtw_delay_ms(1);
2675 fail:
2676 return (error);
2679 static usbd_status
2680 urtw_8225v2_rf_init(struct urtw_rf *rf)
2682 #define N(a) (sizeof (a)/ sizeof ((a)[0]))
2683 int i;
2684 uint16_t data;
2685 uint32_t data32;
2686 usbd_status error;
2687 struct urtw_softc *sc = rf->rf_sc;
2689 if (error = urtw_8180_set_anaparam(sc, URTW_8187_8225_ANAPARAM_ON))
2690 goto fail;
2691 if (error = urtw_8225_usb_init(sc))
2692 goto fail;
2693 if (error = urtw_write32_c(sc, URTW_RF_TIMING, 0x000a8008, 0))
2694 goto fail;
2695 if (error = urtw_read16_c(sc, URTW_BRSR, &data, 0))
2696 goto fail;
2697 if (error = urtw_write16_c(sc, URTW_BRSR, 0xffff, 0))
2698 goto fail;
2699 if (error = urtw_write32_c(sc, URTW_RF_PARA, 0x100044, 0))
2700 goto fail;
2701 if (error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG))
2702 goto fail;
2703 if (error = urtw_write8_c(sc, URTW_CONFIG3, 0x44, 0))
2704 goto fail;
2705 if (error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL))
2706 goto fail;
2707 if (error = urtw_8185_rf_pins_enable(sc))
2708 goto fail;
2710 urtw_delay_ms(500);
2712 for (i = 0; i < N(urtw_8225v2_rf_part1); i++) {
2713 if (error = urtw_8225_write_c(sc, urtw_8225v2_rf_part1[i].reg,
2714 urtw_8225v2_rf_part1[i].val))
2715 goto fail;
2716 urtw_delay_ms(1);
2718 urtw_delay_ms(100);
2720 if (error = urtw_8225_write_c(sc, 0x0, 0x1b7))
2721 goto fail;
2723 for (i = 0; i < 95; i++) {
2724 if (error = urtw_8225_write_c(sc, 0x1, (uint8_t)(i + 1)))
2725 goto fail;
2726 urtw_delay_ms(1);
2727 if (error = urtw_8225_write_c(sc, 0x2, urtw_8225v2_rxgain[i]))
2728 goto fail;
2729 urtw_delay_ms(1);
2732 if (error = urtw_8225_write_c(sc, 0x3, 0x2))
2733 goto fail;
2734 urtw_delay_ms(1);
2735 if (error = urtw_8225_write_c(sc, 0x5, 0x4))
2736 goto fail;
2737 urtw_delay_ms(1);
2738 if (error = urtw_8225_write_c(sc, 0x0, 0xb7))
2739 goto fail;
2740 urtw_delay_ms(1);
2741 if (error = urtw_8225_write_c(sc, 0x2, 0xc4d))
2742 goto fail;
2743 urtw_delay_ms(100);
2744 if (error = urtw_8225_write_c(sc, 0x2, 0x44d))
2745 goto fail;
2746 urtw_delay_ms(100);
2748 if (error = urtw_8225_read(sc, 0x6, &data32))
2749 goto fail;
2750 if (data32 != 0xe6) {
2751 error = (-1);
2752 cmn_err(CE_WARN, "expect 0xe6!! (0x%x)\n", data32);
2753 goto fail;
2755 if (!(data32 & 0x80)) {
2756 if (error = urtw_8225_write_c(sc, 0x02, 0x0c4d))
2757 goto fail;
2758 urtw_delay_ms(200);
2759 if (error = urtw_8225_write_c(sc, 0x02, 0x044d))
2760 goto fail;
2761 urtw_delay_ms(100);
2762 if (error = urtw_8225_read(sc, 0x6, &data32))
2763 goto fail;
2764 if (!(data32 & 0x80))
2765 cmn_err(CE_CONT, "RF calibration failed\n");
2767 urtw_delay_ms(200);
2769 if (error = urtw_8225_write_c(sc, 0x0, 0x2bf))
2770 goto fail;
2771 for (i = 0; i < 128; i++) {
2772 if (error = urtw_8187_write_phy_ofdm_c(sc, 0xb,
2773 urtw_8225_agc[i]))
2774 goto fail;
2775 urtw_delay_ms(1);
2776 if (error = urtw_8187_write_phy_ofdm_c(sc, 0xa,
2777 (uint8_t)i + 0x80))
2778 goto fail;
2779 urtw_delay_ms(1);
2781 urtw_delay_ms(1);
2783 for (i = 0; i < N(urtw_8225v2_rf_part2); i++) {
2784 if (error = urtw_8187_write_phy_ofdm_c(sc,
2785 urtw_8225v2_rf_part2[i].reg,
2786 urtw_8225v2_rf_part2[i].val))
2787 goto fail;
2788 urtw_delay_ms(1);
2790 error = urtw_8225v2_setgain(sc, 4);
2791 if (error)
2792 goto fail;
2794 for (i = 0; i < N(urtw_8225v2_rf_part3); i++) {
2795 if (error = urtw_8187_write_phy_cck_c(sc,
2796 urtw_8225v2_rf_part3[i].reg,
2797 urtw_8225v2_rf_part3[i].val))
2798 goto fail;
2799 urtw_delay_ms(1);
2802 if (error = urtw_write8_c(sc, 0x5b, 0x0d, 0))
2803 goto fail;
2804 if (error = urtw_8225v2_set_txpwrlvl(sc, 1))
2805 goto fail;
2806 if (error = urtw_8187_write_phy_cck_c(sc, 0x10, 0x9b))
2807 goto fail;
2808 urtw_delay_ms(1);
2809 if (error = urtw_8187_write_phy_ofdm_c(sc, 0x26, 0x90))
2810 goto fail;
2811 urtw_delay_ms(1);
2813 /* TX ant A, 0x0 for B */
2814 if (error = urtw_8185_tx_antenna(sc, 0x3))
2815 goto fail;
2816 if (error = urtw_write32_c(sc, 0x94, 0x3dc00002, 0))
2817 goto fail;
2819 error = urtw_8225_rf_set_chan(rf,
2820 ieee80211_chan2ieee(&sc->sc_ic, sc->sc_ic.ic_curchan));
2821 fail:
2822 return (error);
2823 #undef N
2826 static usbd_status
2827 urtw_8225v2_rf_set_chan(struct urtw_rf *rf, int chan)
2829 struct urtw_softc *sc = rf->rf_sc;
2830 struct ieee80211com *ic = &sc->sc_ic;
2831 struct ieee80211_channel *c = ic->ic_curchan;
2832 short gset = (IEEE80211_IS_CHAN_G(c)) ? 1 : 0;
2833 usbd_status error;
2835 if (error = urtw_8225v2_set_txpwrlvl(sc, chan))
2836 goto fail;
2838 if (error = urtw_8225_write_c(sc, 0x7, urtw_8225_channel[chan]))
2839 goto fail;
2841 urtw_delay_ms(10);
2843 if (error = urtw_write8_c(sc, URTW_SIFS, 0x22, 0))
2844 goto fail;
2846 if (ic->ic_state == IEEE80211_S_ASSOC &&
2847 ic->ic_flags & IEEE80211_F_SHSLOT) {
2848 if (error = urtw_write8_c(sc, URTW_SLOT, 0x9, 0))
2849 goto fail;
2850 } else
2851 if (error = urtw_write8_c(sc, URTW_SLOT, 0x14, 0))
2852 goto fail;
2853 if (gset) {
2854 /* for G */
2855 if (error = urtw_write8_c(sc, URTW_DIFS, 0x14, 0))
2856 goto fail;
2857 if (error = urtw_write8_c(sc, URTW_EIFS, 0x5b - 0x14, 0))
2858 goto fail;
2859 if (error = urtw_write8_c(sc, URTW_CW_VAL, 0x73, 0))
2860 goto fail;
2861 } else {
2862 /* for B */
2863 if (error = urtw_write8_c(sc, URTW_DIFS, 0x24, 0))
2864 goto fail;
2865 if (error = urtw_write8_c(sc, URTW_EIFS, 0x5b - 0x24, 0))
2866 goto fail;
2867 if (error = urtw_write8_c(sc, URTW_CW_VAL, 0xa5, 0))
2868 goto fail;
2871 fail:
2872 return (error);
2875 static int
2876 urtw_set_channel(struct urtw_softc *sc)
2878 struct ieee80211com *ic = &sc->sc_ic;
2879 struct urtw_rf *rf = &sc->sc_rf;
2880 uint32_t data;
2881 usbd_status error;
2883 if (error = urtw_read32_c(sc, URTW_TX_CONF, &data, 0))
2884 goto fail;
2885 data &= ~URTW_TX_LOOPBACK_MASK;
2886 if (error = urtw_write32_c(sc, URTW_TX_CONF,
2887 data | URTW_TX_LOOPBACK_MAC, 0))
2888 goto fail;
2889 error = rf->set_chan(rf, ieee80211_chan2ieee(ic, ic->ic_curchan));
2890 if (error)
2891 goto fail;
2892 urtw_delay_ms(20);
2893 error = urtw_write32_c(sc, URTW_TX_CONF,
2894 data | URTW_TX_LOOPBACK_NONE, 0);
2895 fail:
2896 return (error);
2899 /* ARGSUSED */
2900 static void
2901 urtw_txeof_low(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
2903 struct urtw_softc *sc = (struct urtw_softc *)req->bulk_client_private;
2904 struct ieee80211com *ic = &sc->sc_ic;
2906 URTW8187_DBG(URTW_DEBUG_TX_PROC, (sc->sc_dev, CE_CONT,
2907 "urtw_txeof_low(): cr:%s(%d), flags:0x%x, tx_queued:%d",
2908 usb_str_cr(req->bulk_completion_reason),
2909 req->bulk_completion_reason,
2910 req->bulk_cb_flags,
2911 sc->sc_tx_low_queued));
2912 mutex_enter(&sc->tx_lock);
2913 if (req->bulk_completion_reason != USB_CR_OK) {
2914 ic->ic_stats.is_tx_failed++;
2915 goto fail;
2918 if (sc->sc_need_sched) {
2919 sc->sc_need_sched = 0;
2920 mac_tx_update(ic->ic_mach);
2922 fail:
2923 sc->sc_tx_low_queued--;
2924 mutex_exit(&sc->tx_lock);
2925 usb_free_bulk_req(req);
2928 /* ARGSUSED */
2929 static void
2930 urtw_txeof_normal(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
2932 struct urtw_softc *sc = (struct urtw_softc *)req->bulk_client_private;
2933 struct ieee80211com *ic = &sc->sc_ic;
2935 URTW8187_DBG(URTW_DEBUG_ACTIVE, (sc->sc_dev, CE_CONT,
2936 "urtw_txeof_normal(): cr:%s(%d), flags:0x%x, tx_queued:%d",
2937 usb_str_cr(req->bulk_completion_reason),
2938 req->bulk_completion_reason,
2939 req->bulk_cb_flags,
2940 sc->sc_tx_normal_queued));
2942 mutex_enter(&sc->tx_lock);
2943 if (req->bulk_completion_reason != USB_CR_OK) {
2944 ic->ic_stats.is_tx_failed++;
2945 goto fail;
2948 if (sc->sc_need_sched) {
2949 sc->sc_need_sched = 0;
2950 mac_tx_update(ic->ic_mach);
2952 fail:
2953 sc->sc_tx_normal_queued--;
2954 mutex_exit(&sc->tx_lock);
2955 usb_free_bulk_req(req);
2959 static int
2960 urtw_get_rate(struct ieee80211com *ic)
2962 uint8_t (*rates)[IEEE80211_RATE_MAXSIZE];
2963 int rate;
2965 rates = &ic->ic_bss->in_rates.ir_rates;
2967 if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
2968 rate = ic->ic_fixed_rate;
2969 else if (ic->ic_state == IEEE80211_S_RUN)
2970 rate = (*rates)[ic->ic_bss->in_txrate];
2971 else
2972 rate = 0;
2973 return (rate & IEEE80211_RATE_VAL);
2976 void
2977 urtw_8187b_update_wmm(struct urtw_softc *sc)
2979 struct ieee80211com *ic = &sc->sc_ic;
2980 struct ieee80211_channel *c = ic->ic_curchan;
2981 uint32_t data;
2982 uint8_t aifs, sifs, slot, ecwmin, ecwmax;
2984 sifs = 0xa;
2985 if (IEEE80211_IS_CHAN_G(c))
2986 slot = 0x9;
2987 else
2988 slot = 0x14;
2990 aifs = (2 * slot) + sifs;
2991 ecwmin = 3;
2992 ecwmax = 7;
2994 data = ((uint32_t)aifs << 0) | /* AIFS, offset 0 */
2995 ((uint32_t)ecwmin << 8) | /* ECW minimum, offset 8 */
2996 ((uint32_t)ecwmax << 12); /* ECW maximum, offset 16 */
2998 (void) urtw_write32_c(sc, URTW_AC_VO, data, 0);
2999 (void) urtw_write32_c(sc, URTW_AC_VI, data, 0);
3000 (void) urtw_write32_c(sc, URTW_AC_BE, data, 0);
3001 (void) urtw_write32_c(sc, URTW_AC_BK, data, 0);
3004 usbd_status
3005 urtw_8187b_reset(struct urtw_softc *sc)
3007 uint8_t data;
3008 usbd_status error;
3010 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3011 if (error)
3012 goto fail;
3014 (void) urtw_read8_c(sc, URTW_CONFIG3, &data, 0);
3015 (void) urtw_write8_c(sc, URTW_CONFIG3,
3016 data | URTW_CONFIG3_ANAPARAM_WRITE |
3017 URTW_CONFIG3_GNT_SELECT, 0);
3019 (void) urtw_write32_c(sc, URTW_ANAPARAM2,
3020 URTW_8187B_8225_ANAPARAM2_ON, 0);
3021 (void) urtw_write32_c(sc, URTW_ANAPARAM,
3022 URTW_8187B_8225_ANAPARAM_ON, 0);
3023 (void) urtw_write8_c(sc, URTW_ANAPARAM3,
3024 URTW_8187B_8225_ANAPARAM3_ON, 0);
3026 (void) urtw_write8_c(sc, 0x61, 0x10, 0);
3027 (void) urtw_read8_c(sc, 0x62, &data, 0);
3028 (void) urtw_write8_c(sc, 0x62, data & ~(1 << 5), 0);
3029 (void) urtw_write8_c(sc, 0x62, data | (1 << 5), 0);
3031 (void) urtw_read8_c(sc, URTW_CONFIG3, &data, 0);
3032 (void) urtw_write8_c(sc, URTW_CONFIG3,
3033 data & ~URTW_CONFIG3_ANAPARAM_WRITE, 0);
3035 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3036 if (error)
3037 goto fail;
3039 (void) urtw_read8_c(sc, URTW_CMD, &data, 0);
3040 data = (data & 2) | URTW_CMD_RST;
3041 (void) urtw_write8_c(sc, URTW_CMD, data, 0);
3042 urtw_delay_ms(100);
3044 (void) urtw_read8_c(sc, URTW_CMD, &data, 0);
3045 if (data & URTW_CMD_RST) {
3046 cmn_err(CE_WARN, "urtw: 8187b reset timeout\n");
3047 goto fail;
3050 fail:
3051 return (error);
3054 static int
3055 urtw_8187b_init(void *arg)
3057 struct urtw_softc *sc = arg;
3058 struct urtw_rf *rf = &sc->sc_rf;
3059 struct ieee80211com *ic = &sc->sc_ic;
3060 int i;
3061 uint8_t data;
3062 usbd_status error;
3064 urtw_stop(sc);
3065 URTW_LOCK(sc);
3066 urtw_8187b_update_wmm(sc);
3067 error = urtw_8187b_reset(sc);
3068 if (error)
3069 goto fail;
3071 error = urtw_open_pipes(sc);
3072 if (error != 0)
3073 goto fail;
3074 /* Applying MAC address again. */
3075 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3076 if (error)
3077 goto fail;
3078 for (i = 0; i < IEEE80211_ADDR_LEN; i++)
3079 (void) urtw_write8_c(sc, URTW_MAC0 + i,
3080 ic->ic_macaddr[i], 0);
3081 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3082 if (error)
3083 goto fail;
3085 error = urtw_update_msr(sc, IEEE80211_S_INIT);
3086 if (error)
3087 goto fail;
3089 error = rf->init(rf);
3090 if (error != 0)
3091 goto fail;
3092 error = urtw_intr_enable(sc);
3093 if (error != 0)
3094 goto fail;
3096 error = urtw_write8e(sc, 0x41, 0xf4);
3097 if (error != 0)
3098 goto fail;
3099 error = urtw_write8e(sc, 0x40, 0x00);
3100 if (error != 0)
3101 goto fail;
3102 error = urtw_write8e(sc, 0x42, 0x00);
3103 if (error != 0)
3104 goto fail;
3105 error = urtw_write8e(sc, 0x42, 0x01);
3106 if (error != 0)
3107 goto fail;
3108 error = urtw_write8e(sc, 0x40, 0x0f);
3109 if (error != 0)
3110 goto fail;
3111 error = urtw_write8e(sc, 0x42, 0x00);
3112 if (error != 0)
3113 goto fail;
3114 error = urtw_write8e(sc, 0x42, 0x01);
3115 if (error != 0)
3116 goto fail;
3118 (void) urtw_read8_c(sc, 0xdb, &data, 0);
3119 (void) urtw_write8_c(sc, 0xdb, data | (1 << 2), 0);
3120 (void) urtw_write16_c(sc, 0x72, 0x59fa, 3);
3121 (void) urtw_write16_c(sc, 0x74, 0x59d2, 3);
3122 (void) urtw_write16_c(sc, 0x76, 0x59d2, 3);
3123 (void) urtw_write16_c(sc, 0x78, 0x19fa, 3);
3124 (void) urtw_write16_c(sc, 0x7a, 0x19fa, 3);
3125 (void) urtw_write16_c(sc, 0x7c, 0x00d0, 3);
3126 (void) urtw_write8_c(sc, 0x61, 0, 0);
3127 (void) urtw_write8_c(sc, 0x80, 0x0f, 1);
3128 (void) urtw_write8_c(sc, 0x83, 0x03, 1);
3129 (void) urtw_write8_c(sc, 0xda, 0x10, 0);
3130 (void) urtw_write8_c(sc, 0x4d, 0x08, 2);
3132 (void) urtw_write32_c(sc, URTW_HSSI_PARA, 0x0600321b, 0);
3133 (void) urtw_write16_c(sc, 0xec, 0x0800, 1);
3134 (void) urtw_write8_c(sc, URTW_ACM_CONTROL, 0, 0);
3136 sc->sc_tx_low_queued = 0;
3137 sc->sc_tx_normal_queued = 0;
3138 error = urtw_rx_enable(sc);
3139 if (error != 0)
3140 goto fail;
3141 urtw_tx_enable(sc);
3143 if (error == 0) {
3144 URTW8187_DBG(URTW_DEBUG_ACTIVE, (sc->sc_dev,
3145 CE_CONT, "urtw_8187b_init: done\n"));
3146 sc->sc_flags |= URTW_FLAG_RUNNING;
3147 URTW_UNLOCK(sc);
3148 return (error);
3151 fail:
3152 cmn_err(CE_WARN, "urtw_8187b_init failed\n");
3153 URTW_UNLOCK(sc);
3154 urtw_stop(sc);
3155 return (EIO);
3158 void
3159 urtw_8225v2_b_config_mac(struct urtw_softc *sc)
3161 int i;
3162 int nitems = sizeof (urtw_8187b_regtbl)
3163 / sizeof ((urtw_8187b_regtbl)[0]);
3165 for (i = 0; i < nitems; i++) {
3166 (void) urtw_write8_c(sc, urtw_8187b_regtbl[i].reg,
3167 urtw_8187b_regtbl[i].val, urtw_8187b_regtbl[i].idx);
3170 (void) urtw_write16_c(sc, URTW_TID_AC_MAP, 0xfa50, 0);
3171 (void) urtw_write16_c(sc, URTW_INT_MIG, 0, 0);
3173 (void) urtw_write32_c(sc, 0xf0, 0, 1);
3174 (void) urtw_write32_c(sc, 0xf4, 0, 1);
3175 (void) urtw_write8_c(sc, 0xf8, 0, 1);
3177 (void) urtw_write32_c(sc, URTW_RF_TIMING, 0x00004001, 0);
3180 void
3181 urtw_8225v2_b_init_rfe(struct urtw_softc *sc)
3183 (void) urtw_write16_c(sc, URTW_RF_PINS_OUTPUT, 0x0480, 0);
3184 (void) urtw_write16_c(sc, URTW_RF_PINS_SELECT, 0x2488, 0);
3185 (void) urtw_write16_c(sc, URTW_RF_PINS_ENABLE, 0x1fff, 0);
3186 urtw_delay_ms(100);
3189 usbd_status
3190 urtw_8225v2_b_update_chan(struct urtw_softc *sc)
3192 struct ieee80211com *ic = &sc->sc_ic;
3193 struct ieee80211_channel *c = ic->ic_curchan;
3194 uint8_t aifs, difs, eifs, sifs, slot;
3196 (void) urtw_write8_c(sc, URTW_SIFS, 0x22, 0);
3198 sifs = 0xa;
3199 if (IEEE80211_IS_CHAN_G(c)) {
3200 slot = 0x9;
3201 difs = 0x1c;
3202 eifs = 0x5b;
3203 } else {
3204 slot = 0x14;
3205 difs = 0x32;
3206 eifs = 0x5b;
3208 aifs = (2 * slot) + sifs;
3210 (void) urtw_write8_c(sc, URTW_SLOT, slot, 0);
3212 (void) urtw_write8_c(sc, URTW_AC_VO, aifs, 0);
3213 (void) urtw_write8_c(sc, URTW_AC_VI, aifs, 0);
3214 (void) urtw_write8_c(sc, URTW_AC_BE, aifs, 0);
3215 (void) urtw_write8_c(sc, URTW_AC_BK, aifs, 0);
3217 (void) urtw_write8_c(sc, URTW_DIFS, difs, 0);
3218 (void) urtw_write8_c(sc, URTW_8187B_EIFS, eifs, 0);
3219 return (0);
3222 usbd_status
3223 urtw_8225v2_b_rf_init(struct urtw_rf *rf)
3225 struct urtw_softc *sc = rf->rf_sc;
3226 int i, nitems;
3227 uint8_t data;
3228 usbd_status error;
3230 /* Set up ACK rate, retry limit, TX AGC, TX antenna. */
3231 (void) urtw_write16_c(sc, URTW_8187B_BRSR, 0x0fff, 0);
3232 (void) urtw_read8_c(sc, URTW_CW_CONF, &data, 0);
3233 (void) urtw_write8_c(sc, URTW_CW_CONF, data |
3234 URTW_CW_CONF_PERPACKET_RETRY, 0);
3235 (void) urtw_read8_c(sc, URTW_TX_AGC_CTL, &data, 0);
3236 (void) urtw_write8_c(sc, URTW_TX_AGC_CTL, data |
3237 URTW_TX_AGC_CTL_PERPACKET_GAIN |
3238 URTW_TX_AGC_CTL_PERPACKET_ANTSEL, 0);
3240 /* Auto rate fallback control. */
3241 (void) urtw_write16_c(sc, URTW_ARFR, 0x0fff, 1); /* 1M ~ 54M */
3242 (void) urtw_read8_c(sc, URTW_RATE_FALLBACK, &data, 0);
3243 (void) urtw_write8_c(sc, URTW_RATE_FALLBACK, data |
3244 URTW_RATE_FALLBACK_ENABLE, 0);
3246 (void) urtw_write16_c(sc, URTW_BEACON_INTERVAL, 0x3ff, 0);
3247 (void) urtw_write16_c(sc, URTW_ATIM_WND, 2, 0);
3248 (void) urtw_write16_c(sc, URTW_FEMR, 0xffff, 1);
3250 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3251 if (error)
3252 goto fail;
3253 (void) urtw_read8_c(sc, URTW_CONFIG1, &data, 0);
3254 (void) urtw_write8_c(sc, URTW_CONFIG1, (data & 0x3f) | 0x80, 0);
3255 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3256 if (error)
3257 goto fail;
3259 (void) urtw_write8_c(sc, URTW_WPA_CONFIG, 0, 0);
3260 urtw_8225v2_b_config_mac(sc);
3261 (void) urtw_write16_c(sc, URTW_RFSW_CTRL, 0x569a, 2);
3263 error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
3264 if (error)
3265 goto fail;
3266 (void) urtw_read8_c(sc, URTW_CONFIG3, &data, 0);
3267 (void) urtw_write8_c(sc, URTW_CONFIG3,
3268 data | URTW_CONFIG3_ANAPARAM_WRITE, 0);
3269 error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
3270 if (error)
3271 goto fail;
3273 urtw_8225v2_b_init_rfe(sc);
3275 nitems = sizeof (urtw_8225v2_b_rf) / sizeof ((urtw_8225v2_b_rf)[0]);
3276 for (i = 0; i < nitems; i++) {
3277 (void) urtw_8225_write_c(sc, urtw_8225v2_b_rf[i].reg,
3278 urtw_8225v2_b_rf[i].val);
3281 nitems = sizeof (urtw_8225v2_rxgain) / sizeof ((urtw_8225v2_rxgain)[0]);
3282 for (i = 0; i < nitems; i++) {
3283 (void) urtw_8225_write_c(sc, 0x1, (uint8_t)(i + 1));
3284 (void) urtw_8225_write_c(sc, 0x2, urtw_8225v2_rxgain[i]);
3287 (void) urtw_8225_write_c(sc, 0x03, 0x080);
3288 (void) urtw_8225_write_c(sc, 0x05, 0x004);
3289 (void) urtw_8225_write_c(sc, 0x00, 0x0b7);
3290 (void) urtw_8225_write_c(sc, 0x02, 0xc4d);
3291 urtw_delay_ms(10);
3292 (void) urtw_8225_write_c(sc, 0x02, 0x44d);
3293 urtw_delay_ms(10);
3294 (void) urtw_8225_write_c(sc, 0x00, 0x2bf);
3295 urtw_delay_ms(10);
3297 (void) urtw_write8_c(sc, URTW_TX_GAIN_CCK, 0x03, 0);
3298 (void) urtw_write8_c(sc, URTW_TX_GAIN_OFDM, 0x07, 0);
3299 (void) urtw_write8_c(sc, URTW_TX_ANTENNA, 0x03, 0);
3301 (void) urtw_8187_write_phy_ofdm_c(sc, 0x80, 0x12);
3302 nitems = sizeof (urtw_8225v2_agc) / sizeof ((urtw_8225v2_agc)[0]);
3303 for (i = 0; i < nitems; i++) {
3304 (void) urtw_8187_write_phy_ofdm_c(sc, 0x0f, urtw_8225v2_agc[i]);
3305 (void) urtw_8187_write_phy_ofdm_c(sc, 0x0e, (uint8_t)i + 0x80);
3306 (void) urtw_8187_write_phy_ofdm_c(sc, 0x0e, 0);
3308 (void) urtw_8187_write_phy_ofdm_c(sc, 0x80, 0x10);
3310 nitems = sizeof (urtw_8225v2_ofdm) / sizeof ((urtw_8225v2_ofdm)[0]);
3311 for (i = 0; i < nitems; i++) {
3312 (void) urtw_8187_write_phy_ofdm_c(sc, i, urtw_8225v2_ofdm[i]);
3314 (void) urtw_8225v2_b_update_chan(sc);
3316 (void) urtw_8187_write_phy_ofdm_c(sc, 0x97, 0x46);
3317 (void) urtw_8187_write_phy_ofdm_c(sc, 0xa4, 0xb6);
3318 (void) urtw_8187_write_phy_ofdm_c(sc, 0x85, 0xfc);
3319 (void) urtw_8187_write_phy_cck_c(sc, 0xc1, 0x88);
3321 error = urtw_8225v2_b_rf_set_chan(rf,
3322 ieee80211_chan2ieee(&sc->sc_ic, sc->sc_ic.ic_curchan));
3323 fail:
3324 return (error);
3327 static usbd_status
3328 urtw_8225v2_b_rf_set_chan(struct urtw_rf *rf, int chan)
3330 struct urtw_softc *sc = rf->rf_sc;
3331 int error = 0;
3333 urtw_8225v2_b_set_txpwrlvl(sc, chan);
3334 error = urtw_8225_write_c(sc, 0x7, urtw_8225_channel[chan]);
3335 if (error)
3336 goto fail;
3338 * Delay removed from 8185 to 8187.
3339 * usbd_delay_ms(sc->sc_udev, 10);
3342 error = urtw_write16_c(sc, URTW_AC_VO, 0x5114, 0);
3343 if (error)
3344 goto fail;
3345 error = urtw_write16_c(sc, URTW_AC_VI, 0x5114, 0);
3346 if (error)
3347 goto fail;
3348 error = urtw_write16_c(sc, URTW_AC_BE, 0x5114, 0);
3349 if (error)
3350 goto fail;
3351 error = urtw_write16_c(sc, URTW_AC_BK, 0x5114, 0);
3352 fail:
3353 return (error);
3356 void
3357 urtw_8225v2_b_set_txpwrlvl(struct urtw_softc *sc, int chan)
3359 int i;
3360 uint8_t *cck_pwrtable;
3361 uint8_t cck_pwrlvl_min, cck_pwrlvl_max, ofdm_pwrlvl_min,
3362 ofdm_pwrlvl_max;
3363 int8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
3364 int8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
3366 if (sc->sc_hwrev & URTW_HWREV_8187B_B) {
3367 cck_pwrlvl_min = 0;
3368 cck_pwrlvl_max = 15;
3369 ofdm_pwrlvl_min = 2;
3370 ofdm_pwrlvl_max = 17;
3371 } else {
3372 cck_pwrlvl_min = 7;
3373 cck_pwrlvl_max = 22;
3374 ofdm_pwrlvl_min = 10;
3375 ofdm_pwrlvl_max = 25;
3378 /* CCK power setting */
3379 cck_pwrlvl = (cck_pwrlvl > (cck_pwrlvl_max - cck_pwrlvl_min)) ?
3380 cck_pwrlvl_max : (cck_pwrlvl + cck_pwrlvl_min);
3382 cck_pwrlvl += sc->sc_txpwr_cck_base;
3383 cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
3384 cck_pwrlvl = (cck_pwrlvl < 0) ? 0 : cck_pwrlvl;
3386 cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
3387 urtw_8225v2_txpwr_cck;
3389 if (sc->sc_hwrev & URTW_HWREV_8187B_B) {
3390 if (cck_pwrlvl > 7 && cck_pwrlvl <= 11)
3391 cck_pwrtable += 8;
3392 if (cck_pwrlvl > 11)
3393 cck_pwrtable += 16;
3394 } else {
3395 if (cck_pwrlvl > 5 && cck_pwrlvl <= 11)
3396 cck_pwrtable += 8;
3397 if (cck_pwrlvl > 12 && cck_pwrlvl <= 17)
3398 cck_pwrtable += 16;
3399 if (cck_pwrlvl > 17)
3400 cck_pwrtable += 24;
3403 for (i = 0; i < 8; i++) {
3404 (void) urtw_8187_write_phy_cck_c(sc, 0x44 + i, cck_pwrtable[i]);
3407 (void) urtw_write8_c(sc, URTW_TX_GAIN_CCK,
3408 urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl] << 1, 0);
3410 * Delay removed from 8185 to 8187.
3411 * usbd_delay_ms(sc->sc_udev, 1);
3414 /* OFDM power setting */
3415 ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
3416 ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
3418 ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
3419 ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
3420 ofdm_pwrlvl = (ofdm_pwrlvl < 0) ? 0 : ofdm_pwrlvl;
3422 (void) urtw_write8_c(sc, URTW_TX_GAIN_OFDM,
3423 urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl] << 1, 0);
3425 if (sc->sc_hwrev & URTW_HWREV_8187B_B) {
3426 if (ofdm_pwrlvl <= 11) {
3427 (void) urtw_8187_write_phy_ofdm_c(sc, 0x87, 0x60);
3428 (void) urtw_8187_write_phy_ofdm_c(sc, 0x89, 0x60);
3429 } else {
3430 (void) urtw_8187_write_phy_ofdm_c(sc, 0x87, 0x5c);
3431 (void) urtw_8187_write_phy_ofdm_c(sc, 0x89, 0x5c);
3433 } else {
3434 if (ofdm_pwrlvl <= 11) {
3435 (void) urtw_8187_write_phy_ofdm_c(sc, 0x87, 0x5c);
3436 (void) urtw_8187_write_phy_ofdm_c(sc, 0x89, 0x5c);
3437 } else if (ofdm_pwrlvl <= 17) {
3438 (void) urtw_8187_write_phy_ofdm_c(sc, 0x87, 0x54);
3439 (void) urtw_8187_write_phy_ofdm_c(sc, 0x89, 0x54);
3440 } else {
3441 (void) urtw_8187_write_phy_ofdm_c(sc, 0x87, 0x50);
3442 (void) urtw_8187_write_phy_ofdm_c(sc, 0x89, 0x50);
3447 * Delay removed from 8185 to 8187.
3448 * usbd_delay_ms(sc->sc_udev, 1);
3453 static int
3454 urtw_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type)
3456 struct urtw_softc *sc = (struct urtw_softc *)ic;
3457 struct ieee80211_frame *wh;
3458 struct ieee80211_key *k;
3459 struct ieee80211_node *ni = NULL;
3460 uint8_t *buf;
3461 mblk_t *m = 0, *m0, *mtx;
3462 int off, mblen, xferlen, err = 0, priority = 0;
3464 mutex_enter(&sc->tx_lock);
3465 priority = (type == IEEE80211_FC0_TYPE_DATA) ?
3466 LOW_PRIORITY_PIPE: NORMAL_PRIORITY_PIPE;
3468 if (URTW_IS_SUSPENDING(sc)) {
3469 err = 0;
3470 goto failed;
3473 if (((priority)? sc->sc_tx_normal_queued : sc->sc_tx_low_queued) >=
3474 URTW_TX_DATA_LIST_COUNT) {
3475 URTW8187_DBG(URTW_DEBUG_XMIT, (sc->sc_dev, CE_CONT,
3476 "urtw_send(): no TX buffer!\n"));
3477 sc->sc_tx_nobuf++;
3478 err = ENOMEM;
3479 goto failed;
3482 m = allocb(URTW_TXBUF_SIZE, BPRI_MED);
3483 if (m == NULL) {
3484 cmn_err(CE_WARN, "urtw_send(): can't alloc mblk.\n");
3485 err = ENOMEM;
3486 goto failed;
3489 for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) {
3490 mblen = (uintptr_t)m0->b_wptr - (uintptr_t)m0->b_rptr;
3491 (void) bcopy(m0->b_rptr, m->b_rptr + off, mblen);
3492 off += mblen;
3494 m->b_wptr += off;
3496 wh = (struct ieee80211_frame *)m->b_rptr;
3498 ni = ieee80211_find_txnode(ic, wh->i_addr1);
3499 if (ni == NULL) {
3500 err = ENXIO;
3501 ic->ic_stats.is_tx_failed++;
3502 goto failed;
3505 if ((type & IEEE80211_FC0_TYPE_MASK) ==
3506 IEEE80211_FC0_TYPE_DATA) {
3507 (void) ieee80211_encap(ic, m, ni);
3510 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
3511 k = ieee80211_crypto_encap(ic, m);
3512 if (k == NULL) {
3513 ic->ic_stats.is_tx_failed++;
3514 err = ENXIO;
3515 goto failed;
3517 /* packet header may have moved, reset our local pointer */
3518 wh = (struct ieee80211_frame *)m->b_rptr;
3521 if (sc->sc_hwrev & URTW_HWREV_8187)
3522 xferlen = MBLKL(m) + 4 * 3;
3523 else
3524 xferlen = MBLKL(m) + 4 * 8;
3526 if ((0 == xferlen % 64) || (0 == xferlen % 512))
3527 xferlen += 1;
3529 mtx = allocb(xferlen, BPRI_MED);
3530 buf = mtx->b_rptr;
3532 bzero(buf, xferlen);
3533 buf[0] = MBLKL(m) & 0xff;
3534 buf[1] = (MBLKL(m) & 0x0f00) >> 8;
3535 buf[1] |= (1 << 7);
3537 /* XXX sc_preamble_mode is always 2. */
3538 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
3539 buf[2] |= (1 << 1);
3540 /* RTS rate - 10 means we use a basic rate. */
3541 buf[2] |= (urtw_rate2rtl(2) << 3);
3543 * XXX currently TX rate control depends on the rate value of
3544 * RX descriptor because I don't know how to we can control TX rate
3545 * in more smart way. Please fix me you find a thing.
3547 if ((type & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) {
3548 buf[3] = urtw_rate2rtl(MAX(2, urtw_get_rate(ic)));
3549 } else
3550 buf[3] = 0;
3552 if (sc->sc_hwrev & URTW_HWREV_8187) {
3553 buf[8] = 3; /* CW minimum */
3554 buf[8] |= (7 << 4); /* CW maximum */
3555 buf[9] |= 11; /* retry limitation */
3556 bcopy(m->b_rptr, &buf[12], MBLKL(m));
3557 } else {
3558 buf[21] |= 11; /* retry limitation */
3559 bcopy(m->b_rptr, &buf[32], MBLKL(m));
3562 (void) urtw_led_ctl(sc, URTW_LED_CTL_TX);
3563 mtx->b_wptr = mtx->b_rptr + xferlen;
3565 URTW8187_DBG(URTW_DEBUG_XMIT, (sc->sc_dev, CE_CONT,
3566 "sending frame len=%u rate=%u xfer len=%u\n",
3567 MBLKL(m), buf[3], xferlen));
3569 err = urtw_tx_start(sc, mtx, priority);
3570 if (!err) {
3571 ic->ic_stats.is_tx_frags++;
3572 ic->ic_stats.is_tx_bytes += MBLKL(m);
3573 } else {
3574 ic->ic_stats.is_tx_failed++;
3577 failed:
3578 if (ni != NULL)
3579 ieee80211_free_node(ni);
3581 if ((mp) &&
3582 ((type & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA ||
3583 err == DDI_SUCCESS)) {
3584 freemsg(mp);
3586 if (m) freemsg(m);
3588 if (((type & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) &&
3589 (err != 0)) {
3590 sc->sc_need_sched = 1;
3592 mutex_exit(&sc->tx_lock);
3593 return (err);
3596 static void
3597 urtw_next_scan(void *arg)
3599 ieee80211com_t *ic = arg;
3600 struct urtw_softc *sc = (struct urtw_softc *)arg;
3602 if (URTW_IS_NOT_RUNNING(sc)) {
3603 sc->sc_scan_id = 0;
3604 return;
3607 if (ic->ic_state == IEEE80211_S_SCAN) {
3608 (void) ieee80211_next_scan(ic);
3610 sc->sc_scan_id = 0;
3613 static void
3614 urtw_led_launch(void *arg)
3616 struct urtw_softc *sc = arg;
3617 ieee80211com_t *ic = &sc->sc_ic;
3618 int error = 0;
3620 URTW_LEDLOCK(sc);
3621 if ((sc->sc_strategy != URTW_SW_LED_MODE0) ||
3622 URTW_IS_NOT_RUNNING(sc) ||
3623 URTW_IS_SUSPENDING(sc)) {
3624 URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
3625 "failed process LED strategy 0x%x, run?%d",
3626 sc->sc_strategy,
3627 sc->sc_flags));
3628 sc->sc_led_ch = 0;
3629 sc->sc_gpio_ledinprogress = 0;
3630 URTW_LEDUNLOCK(sc);
3631 return;
3633 error = urtw_led_blink(sc);
3634 if (error) {
3635 sc->sc_led_ch = timeout(urtw_led_launch, (void *)sc,
3636 drv_usectohz((ic->ic_state == IEEE80211_S_RUN) ?
3637 URTW_LED_LINKON_BLINK: URTW_LED_LINKOFF_BLINK));
3638 URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
3639 "try again led launch"));
3640 } else {
3641 sc->sc_led_ch = 0;
3642 URTW8187_DBG(URTW_DEBUG_LED, (sc->sc_dev, CE_CONT,
3643 "exit led launch"));
3645 URTW_LEDUNLOCK(sc);
3648 static int
3649 urtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
3651 struct urtw_softc *sc = (struct urtw_softc *)ic;
3652 struct ieee80211_node *ni;
3653 int error = 0;
3655 if (sc->sc_scan_id != 0) {
3656 (void) untimeout(sc->sc_scan_id);
3657 sc->sc_scan_id = 0;
3659 URTW_LOCK(sc);
3660 switch (nstate) {
3661 case IEEE80211_S_INIT:
3662 URTW8187_DBG(URTW_DEBUG_STATE,
3663 (sc->sc_dev, CE_CONT, "-> IEEE80211_S_INIT...arg(%d)\n",
3664 arg));
3665 if (sc->sc_flags & URTW_FLAG_HP)
3666 break;
3667 (void) urtw_update_msr(sc, nstate);
3668 (void) urtw_led_off(sc, URTW_LED_GPIO);
3669 break;
3671 case IEEE80211_S_SCAN:
3672 URTW8187_DBG(URTW_DEBUG_STATE,
3673 (sc->sc_dev, CE_CONT,
3674 "-> IEEE80211_S_SCAN...arg(%d)...[%d]\n",
3675 arg, ieee80211_chan2ieee(ic, ic->ic_curchan)));
3676 error = urtw_set_channel(sc);
3677 if (error) {
3678 URTW8187_DBG(URTW_DEBUG_STATE,
3679 (sc->sc_dev, CE_CONT, "scan setchan failed"));
3680 break;
3682 sc->sc_scan_id = timeout(urtw_next_scan, (void *)sc,
3683 drv_usectohz(sc->dwelltime * 1000));
3684 break;
3686 case IEEE80211_S_AUTH:
3687 URTW8187_DBG(URTW_DEBUG_STATE, (sc->sc_dev, CE_CONT,
3688 "-> IEEE80211_S_AUTH ...arg(%d), chan (%d)\n", arg,
3689 ieee80211_chan2ieee(ic, ic->ic_curchan)));
3690 error = urtw_set_channel(sc);
3691 if (error) {
3692 URTW8187_DBG(URTW_DEBUG_STATE,
3693 (sc->sc_dev, CE_CONT, "auth setchan failed"));
3695 break;
3697 case IEEE80211_S_ASSOC:
3698 URTW8187_DBG(URTW_DEBUG_STATE, (sc->sc_dev, CE_CONT,
3699 "-> IEEE80211_S_ASSOC ...arg(%d), chan (%d)\n", arg,
3700 ieee80211_chan2ieee(ic, ic->ic_curchan)));
3701 error = urtw_set_channel(sc);
3702 if (error) {
3703 URTW8187_DBG(URTW_DEBUG_STATE,
3704 (sc->sc_dev, CE_CONT, "assoc setchan failed"));
3706 break;
3708 case IEEE80211_S_RUN:
3709 URTW8187_DBG(URTW_DEBUG_STATE,
3710 (sc->sc_dev, CE_CONT,
3711 "-> IEEE80211_S_RUN ...arg(%d), chan (%d)\n",
3712 arg, ieee80211_chan2ieee(ic, ic->ic_curchan)));
3713 error = urtw_set_channel(sc);
3714 if (error) {
3715 URTW8187_DBG(URTW_DEBUG_STATE,
3716 (sc->sc_dev, CE_CONT, "run setchan failed"));
3717 goto fail;
3719 ni = ic->ic_bss;
3720 /* setting bssid. */
3721 (void) urtw_write32_c(sc, URTW_BSSID,
3722 ((uint32_t *)(uintptr_t)ni->in_bssid)[0], 0);
3723 (void) urtw_write16_c(sc, URTW_BSSID + 4,
3724 ((uint16_t *)(uintptr_t)ni->in_bssid)[2], 0);
3725 (void) urtw_update_msr(sc, nstate);
3727 ni->in_txrate = ni->in_rates.ir_nrates - 1;
3728 break;
3730 fail:
3731 URTW_UNLOCK(sc);
3733 if (error) {
3734 URTW8187_DBG(URTW_DEBUG_STATE, (sc->sc_dev, CE_CONT,
3735 "-> newstate error...arg(%d)\n", error));
3736 return (EIO);
3738 error = sc->sc_newstate(ic, nstate, arg);
3739 return (error);
3742 static void
3743 urtw_close_pipes(struct urtw_softc *sc)
3745 usb_flags_t flags = USB_FLAGS_SLEEP;
3747 if (sc->sc_rxpipe != NULL) {
3748 usb_pipe_reset(sc->sc_dev,
3749 sc->sc_rxpipe, flags, NULL, 0);
3750 usb_pipe_close(sc->sc_dev,
3751 sc->sc_rxpipe, flags, NULL, 0);
3752 sc->sc_rxpipe = NULL;
3755 if (sc->sc_txpipe_low != NULL) {
3756 usb_pipe_reset(sc->sc_dev,
3757 sc->sc_txpipe_low, flags, NULL, 0);
3758 usb_pipe_close(sc->sc_dev,
3759 sc->sc_txpipe_low, flags, NULL, 0);
3760 sc->sc_txpipe_low = NULL;
3763 if (sc->sc_txpipe_normal != NULL) {
3764 usb_pipe_reset(sc->sc_dev,
3765 sc->sc_txpipe_normal, flags, NULL, 0);
3766 usb_pipe_close(sc->sc_dev,
3767 sc->sc_txpipe_normal, flags, NULL, 0);
3768 sc->sc_txpipe_normal = NULL;
3772 static int
3773 urtw_open_pipes(struct urtw_softc *sc)
3775 usb_ep_data_t *ep_node;
3776 usb_pipe_policy_t policy;
3777 int err;
3778 uint_t skip = 0;
3780 if (sc->sc_rxpipe || sc->sc_txpipe_low || sc->sc_txpipe_normal)
3781 return (USB_SUCCESS);
3783 if ((sc->sc_hwrev & URTW_HWREV_8187) == 0) {
3784 skip = 2;
3786 ep_node = usb_lookup_ep_data(sc->sc_dev, sc->sc_udev, 0, 0,
3787 LOW_PRIORITY_PIPE + skip, USB_EP_ATTR_BULK, USB_EP_DIR_OUT);
3789 bzero(&policy, sizeof (usb_pipe_policy_t));
3790 policy.pp_max_async_reqs = URTW_TX_DATA_LIST_COUNT;
3792 if ((err = usb_pipe_open(sc->sc_dev,
3793 &ep_node->ep_descr, &policy, USB_FLAGS_SLEEP,
3794 &sc->sc_txpipe_low)) != USB_SUCCESS) {
3795 URTW8187_DBG(URTW_DEBUG_ACTIVE, (sc->sc_dev, CE_CONT,
3796 "urtw_open_pipes(): %x low priority pipe open failed\n",
3797 err));
3798 goto fail;
3801 ep_node = usb_lookup_ep_data(sc->sc_dev, sc->sc_udev, 0, 0,
3802 NORMAL_PRIORITY_PIPE + skip, USB_EP_ATTR_BULK, USB_EP_DIR_OUT);
3804 bzero(&policy, sizeof (usb_pipe_policy_t));
3805 policy.pp_max_async_reqs = URTW_TX_DATA_LIST_COUNT;
3807 if ((err = usb_pipe_open(sc->sc_dev,
3808 &ep_node->ep_descr, &policy, USB_FLAGS_SLEEP,
3809 &sc->sc_txpipe_normal)) != USB_SUCCESS) {
3810 URTW8187_DBG(URTW_DEBUG_ACTIVE, (sc->sc_dev, CE_CONT,
3811 "urtw_open_pipes(): %x failed to open high tx pipe\n",
3812 err));
3813 goto fail;
3816 ep_node = usb_lookup_ep_data(sc->sc_dev, sc->sc_udev, 0, 0, 0,
3817 USB_EP_ATTR_BULK, USB_EP_DIR_IN);
3819 bzero(&policy, sizeof (usb_pipe_policy_t));
3820 policy.pp_max_async_reqs = URTW_RX_DATA_LIST_COUNT;
3822 if ((err = usb_pipe_open(sc->sc_dev,
3823 &ep_node->ep_descr, &policy, USB_FLAGS_SLEEP,
3824 &sc->sc_rxpipe)) != USB_SUCCESS) {
3825 URTW8187_DBG(URTW_DEBUG_ACTIVE, (sc->sc_dev, CE_CONT,
3826 "urtw_open_pipes(): %x failed to open rx pipe\n", err));
3827 goto fail;
3830 return (USB_SUCCESS);
3832 fail:
3833 urtw_close_pipes(sc);
3834 return (USB_FAILURE);
3837 static int
3838 urtw_tx_start(struct urtw_softc *sc, mblk_t *mp, int priority)
3840 usb_bulk_req_t *req;
3841 int err;
3843 req = usb_alloc_bulk_req(sc->sc_dev, 0, USB_FLAGS_SLEEP);
3844 if (req == NULL) {
3845 URTW8187_DBG(URTW_DEBUG_TX_PROC, (sc->sc_dev, CE_CONT,
3846 "urtw_tx_start(): failed to allocate req"));
3847 freemsg(mp);
3848 return (-1);
3851 req->bulk_len = MBLKL(mp);
3852 req->bulk_data = mp;
3853 req->bulk_client_private = (usb_opaque_t)sc;
3854 req->bulk_timeout = URTW_TX_TIMEOUT;
3855 req->bulk_attributes = USB_ATTRS_AUTOCLEARING;
3856 req->bulk_cb = (priority)?urtw_txeof_normal : urtw_txeof_low;
3857 req->bulk_exc_cb = (priority)?urtw_txeof_normal: urtw_txeof_low;
3858 req->bulk_completion_reason = 0;
3859 req->bulk_cb_flags = 0;
3861 if ((err = usb_pipe_bulk_xfer(
3862 (priority)?sc->sc_txpipe_normal:sc->sc_txpipe_low, req, 0))
3863 != USB_SUCCESS) {
3864 sc->sc_ic.ic_stats.is_tx_failed++;
3865 URTW8187_DBG(URTW_DEBUG_TX_PROC, (sc->sc_dev, CE_CONT,
3866 "urtw_tx_start: failed to do tx xfer, %d", err));
3867 usb_free_bulk_req(req);
3868 return (EIO);
3871 if (priority) {
3872 sc->sc_tx_normal_queued++;
3873 } else {
3874 sc->sc_tx_low_queued++;
3877 return (0);
3880 static int
3881 urtw_rx_start(struct urtw_softc *sc)
3883 usb_bulk_req_t *req;
3884 int err;
3886 req = usb_alloc_bulk_req(sc->sc_dev, URTW_RXBUF_SIZE, USB_FLAGS_SLEEP);
3887 if (req == NULL) {
3888 URTW8187_DBG(URTW_DEBUG_RECV, (sc->sc_dev, CE_CONT,
3889 "urtw_rx_start(): failed to allocate req"));
3890 return (-1);
3893 req->bulk_len = URTW_RXBUF_SIZE;
3894 req->bulk_client_private = (usb_opaque_t)sc;
3895 req->bulk_timeout = 0;
3896 req->bulk_attributes = USB_ATTRS_SHORT_XFER_OK |
3897 USB_ATTRS_AUTOCLEARING;
3898 req->bulk_cb = urtw_rxeof;
3899 req->bulk_exc_cb = urtw_rxeof;
3900 req->bulk_completion_reason = 0;
3901 req->bulk_cb_flags = 0;
3903 err = usb_pipe_bulk_xfer(sc->sc_rxpipe, req, 0);
3905 if (err != USB_SUCCESS) {
3906 URTW8187_DBG(URTW_DEBUG_RECV, (sc->sc_dev, CE_CONT,
3907 "urtw_rx_start: failed to do rx xfer, %d", err));
3908 usb_free_bulk_req(req);
3909 return (-1);
3912 mutex_enter(&sc->rx_lock);
3913 sc->rx_queued++;
3914 mutex_exit(&sc->rx_lock);
3916 return (0);
3919 static int
3920 urtw_disconnect(dev_info_t *devinfo)
3922 struct urtw_softc *sc;
3924 sc = ddi_get_soft_state(urtw_soft_state_p, ddi_get_instance(devinfo));
3925 URTW8187_DBG(URTW_DEBUG_HOTPLUG,
3926 (sc->sc_dev, CE_CONT, "urtw_offline()\n"));
3928 if (URTW_IS_RUNNING(sc)) {
3929 urtw_stop(sc);
3930 URTW_LOCK(sc);
3931 sc->sc_flags |= URTW_FLAG_PLUGIN_ONLINE;
3932 URTW_UNLOCK(sc);
3934 sc->sc_flags |= URTW_FLAG_HP;
3935 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
3936 ieee80211_stop_watchdog(&sc->sc_ic);
3937 return (DDI_SUCCESS);
3940 static int
3941 urtw_reconnect(dev_info_t *devinfo)
3943 struct urtw_softc *sc;
3944 int error = 0;
3945 sc = ddi_get_soft_state(urtw_soft_state_p, ddi_get_instance(devinfo));
3946 if (usb_check_same_device(sc->sc_dev, NULL, USB_LOG_L2, -1,
3947 USB_CHK_ALL, NULL) != USB_SUCCESS)
3948 return (DDI_FAILURE);
3949 URTW8187_DBG(URTW_DEBUG_HOTPLUG, (sc->sc_dev, CE_CONT,
3950 "urtw_online()\n"));
3951 sc->sc_flags &= ~URTW_FLAG_HP;
3952 if (URTW_IS_PLUGIN_ONLINE(sc)) {
3953 error = sc->urtw_init(sc);
3954 if (!error) {
3955 URTW_LOCK(sc);
3956 sc->sc_flags &= ~URTW_FLAG_PLUGIN_ONLINE;
3957 URTW_UNLOCK(sc);
3960 return (error? DDI_FAILURE: DDI_SUCCESS);
3963 static mblk_t *
3964 urtw_m_tx(void *arg, mblk_t *mp)
3966 struct urtw_softc *sc = (struct urtw_softc *)arg;
3967 struct ieee80211com *ic = &sc->sc_ic;
3968 mblk_t *next;
3970 if ((ic->ic_state != IEEE80211_S_RUN) ||
3971 URTW_IS_SUSPENDING(sc)) {
3972 freemsgchain(mp);
3973 return (NULL);
3976 while (mp != NULL) {
3977 next = mp->b_next;
3978 mp->b_next = NULL;
3979 if (urtw_send(ic, mp, IEEE80211_FC0_TYPE_DATA) != DDI_SUCCESS) {
3980 mp->b_next = next;
3981 break;
3983 mp = next;
3985 return (mp);
3988 static int
3989 urtw_m_start(void *arg)
3991 struct urtw_softc *sc = (struct urtw_softc *)arg;
3992 int error = 0;
3994 URTW8187_DBG(URTW_DEBUG_ACTIVE,
3995 (sc->sc_dev, CE_CONT, "urtw_m_start\n"));
3996 error = sc->urtw_init(sc);
3997 return (error);
4000 static void
4001 urtw_m_stop(void *arg)
4003 struct urtw_softc *sc = (struct urtw_softc *)arg;
4005 URTW8187_DBG(URTW_DEBUG_ACTIVE, (sc->sc_dev, CE_CONT,
4006 "urtw_m_stop()\n"));
4007 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
4008 ieee80211_stop_watchdog(&sc->sc_ic);
4009 (void) urtw_stop(sc);
4012 /*ARGSUSED*/
4013 static int
4014 urtw_m_unicst(void *arg, const uint8_t *macaddr)
4016 return (ENOTSUP);
4019 /*ARGSUSED*/
4020 static int
4021 urtw_m_multicst(void *arg, boolean_t add, const uint8_t *macaddr)
4023 return (ENOTSUP);
4026 /*ARGSUSED*/
4027 static int
4028 urtw_m_promisc(void *arg, boolean_t on)
4030 return (0);
4033 static int
4034 urtw_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
4035 uint_t wldp_length, void *wldp_buf)
4037 struct urtw_softc *sc = (struct urtw_softc *)arg;
4038 int err = 0;
4040 err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_num,
4041 wldp_length, wldp_buf);
4042 return (err);
4045 static void
4046 urtw_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
4047 mac_prop_info_handle_t mph)
4049 struct urtw_softc *sc = (struct urtw_softc *)arg;
4051 ieee80211_propinfo(&sc->sc_ic, pr_name, wldp_pr_num, mph);
4054 static int
4055 urtw_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
4056 uint_t wldp_length, const void *wldp_buf)
4058 struct urtw_softc *sc = (struct urtw_softc *)arg;
4059 struct ieee80211com *ic = &sc->sc_ic;
4060 int err;
4062 err = ieee80211_setprop(ic, pr_name, wldp_pr_num,
4063 wldp_length, wldp_buf);
4064 URTW_LOCK(sc);
4065 if (err == ENETRESET) {
4066 if (URTW_IS_RUNNING(sc) && ic->ic_des_esslen) {
4067 URTW_UNLOCK(sc);
4068 err = sc->urtw_init(sc);
4069 if (err) {
4070 URTW8187_DBG(URTW_DEBUG_ACTIVE,
4071 (sc->sc_dev, CE_CONT,
4072 "urtw: setprop failed\n"));
4073 return (err);
4075 (void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
4076 URTW_LOCK(sc);
4078 err = 0;
4080 URTW_UNLOCK(sc);
4081 return (err);
4084 static void
4085 urtw_m_ioctl(void* arg, queue_t *wq, mblk_t *mp)
4087 struct urtw_softc *sc = (struct urtw_softc *)arg;
4088 struct ieee80211com *ic = &sc->sc_ic;
4089 int err;
4091 err = ieee80211_ioctl(ic, wq, mp);
4092 URTW_LOCK(sc);
4093 if (err == ENETRESET) {
4094 if (URTW_IS_RUNNING(sc) && ic->ic_des_esslen) {
4095 URTW_UNLOCK(sc);
4096 err = sc->urtw_init(sc);
4097 if (err) {
4098 URTW8187_DBG(URTW_DEBUG_ACTIVE,
4099 (sc->sc_dev,
4100 CE_CONT, "urtw: dev init failed\n"));
4101 return;
4103 (void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
4104 URTW_LOCK(sc);
4107 URTW_UNLOCK(sc);
4110 static int
4111 urtw_m_stat(void *arg, uint_t stat, uint64_t *val)
4113 struct urtw_softc *sc = (struct urtw_softc *)arg;
4114 ieee80211com_t *ic = &sc->sc_ic;
4115 ieee80211_node_t *ni = 0;
4116 struct ieee80211_rateset *rs = 0;
4118 URTW_LOCK(sc);
4119 switch (stat) {
4120 case MAC_STAT_IFSPEED:
4121 ni = ic->ic_bss;
4122 rs = &ni->in_rates;
4123 *val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ?
4124 (rs->ir_rates[ni->in_txrate] & IEEE80211_RATE_VAL)
4125 : ic->ic_fixed_rate) / 2 * 1000000;
4126 break;
4127 case MAC_STAT_NOXMTBUF:
4128 *val = sc->sc_tx_nobuf;
4129 break;
4130 case MAC_STAT_NORCVBUF:
4131 *val = sc->sc_rx_nobuf;
4132 break;
4133 case MAC_STAT_IERRORS:
4134 *val = sc->sc_rx_err;
4135 break;
4136 case MAC_STAT_RBYTES:
4137 *val = ic->ic_stats.is_rx_bytes;
4138 break;
4139 case MAC_STAT_IPACKETS:
4140 *val = ic->ic_stats.is_rx_frags;
4141 break;
4142 case MAC_STAT_OBYTES:
4143 *val = ic->ic_stats.is_tx_bytes;
4144 break;
4145 case MAC_STAT_OPACKETS:
4146 *val = ic->ic_stats.is_tx_frags;
4147 break;
4148 case MAC_STAT_OERRORS:
4149 *val = ic->ic_stats.is_tx_failed;
4150 break;
4151 case WIFI_STAT_TX_FRAGS:
4152 case WIFI_STAT_MCAST_TX:
4153 case WIFI_STAT_TX_FAILED:
4154 case WIFI_STAT_TX_RETRANS:
4155 case WIFI_STAT_RTS_SUCCESS:
4156 case WIFI_STAT_RTS_FAILURE:
4157 case WIFI_STAT_ACK_FAILURE:
4158 case WIFI_STAT_RX_FRAGS:
4159 case WIFI_STAT_MCAST_RX:
4160 case WIFI_STAT_FCS_ERRORS:
4161 case WIFI_STAT_WEP_ERRORS:
4162 case WIFI_STAT_RX_DUPS:
4163 URTW_UNLOCK(sc);
4164 return (ieee80211_stat(ic, stat, val));
4165 default:
4166 URTW_UNLOCK(sc);
4167 return (ENOTSUP);
4169 URTW_UNLOCK(sc);
4171 return (0);
4174 static void
4175 urtw_watchdog(void *arg)
4177 struct urtw_softc *sc = arg;
4178 struct ieee80211com *ic = &sc->sc_ic;
4180 ieee80211_stop_watchdog(ic);
4182 URTW_LOCK(sc);
4183 if (URTW_IS_NOT_RUNNING(sc)) {
4184 URTW_UNLOCK(sc);
4185 return;
4188 URTW_UNLOCK(sc);
4189 switch (ic->ic_state) {
4190 case IEEE80211_S_AUTH:
4191 case IEEE80211_S_ASSOC:
4192 if (ic->ic_bss->in_fails > 0) {
4193 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
4194 URTW8187_DBG(URTW_DEBUG_ACTIVE,
4195 (sc->sc_dev, CE_CONT,
4196 "urtw: watchdog begin\n"));
4197 } else
4198 ieee80211_watchdog(ic);
4199 break;
4204 static int
4205 urtw_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
4207 struct urtw_softc *sc;
4208 struct ieee80211com *ic;
4209 int error, i, instance;
4210 uint32_t data = 0;
4211 uint8_t data8 = 0;
4212 char strbuf[32];
4213 wifi_data_t wd = { 0 };
4214 mac_register_t *macp;
4215 struct urtw_type *e = 0;
4216 char *urtw_name = NULL;
4218 switch (cmd) {
4219 case DDI_ATTACH:
4220 break;
4221 case DDI_RESUME:
4222 sc = ddi_get_soft_state(urtw_soft_state_p,
4223 ddi_get_instance(devinfo));
4224 ASSERT(sc != NULL);
4225 URTW8187_DBG(URTW_DEBUG_ACTIVE,
4226 (sc->sc_dev, CE_CONT, "urtw: resume\n"));
4227 URTW_LOCK(sc);
4228 sc->sc_flags &= ~URTW_FLAG_SUSPEND;
4229 URTW_UNLOCK(sc);
4230 if (URTW_IS_PLUGIN_ONLINE(sc)) {
4231 error = sc->urtw_init(sc);
4232 if (error == 0) {
4233 URTW_LOCK(sc);
4234 sc->sc_flags &= ~URTW_FLAG_PLUGIN_ONLINE;
4235 URTW_UNLOCK(sc);
4238 return (DDI_SUCCESS);
4239 default:
4240 return (DDI_FAILURE);
4243 instance = ddi_get_instance(devinfo);
4245 if (ddi_soft_state_zalloc(urtw_soft_state_p, instance) != DDI_SUCCESS) {
4246 cmn_err(CE_WARN, "urtw_attach:unable to alloc soft_state_p\n");
4247 return (DDI_FAILURE);
4250 sc = ddi_get_soft_state(urtw_soft_state_p, instance);
4251 ic = (ieee80211com_t *)&sc->sc_ic;
4252 sc->sc_dev = devinfo;
4254 if (usb_client_attach(devinfo, USBDRV_VERSION, 0) != USB_SUCCESS) {
4255 cmn_err(CE_WARN, "urtw_attach: usb_client_attach failed\n");
4256 goto fail1;
4259 if (usb_get_dev_data(devinfo, &sc->sc_udev,
4260 USB_PARSE_LVL_ALL, 0) != USB_SUCCESS) {
4261 sc->sc_udev = NULL;
4262 goto fail2;
4265 mutex_init(&sc->sc_genlock, NULL, MUTEX_DRIVER, NULL);
4266 mutex_init(&sc->tx_lock, NULL, MUTEX_DRIVER, NULL);
4267 mutex_init(&sc->rx_lock, NULL, MUTEX_DRIVER, NULL);
4268 mutex_init(&sc->sc_ledlock, NULL, MUTEX_DRIVER, NULL);
4270 e = urtw_lookup(sc->sc_udev->dev_descr->idVendor,
4271 sc->sc_udev->dev_descr->idProduct);
4272 if (e == NULL) {
4273 cmn_err(CE_WARN, "(urtw) unknown device\n");
4274 goto fail2;
4276 sc->sc_hwrev = e->rev;
4278 if (sc->sc_hwrev & URTW_HWREV_8187) {
4279 (void) urtw_read32_c(sc, URTW_TX_CONF, &data, 0);
4280 data &= URTW_TX_HWREV_MASK;
4281 switch (data) {
4282 case URTW_TX_HWREV_8187_D:
4283 sc->sc_hwrev |= URTW_HWREV_8187_D;
4284 urtw_name = "RTL8187 rev. D";
4285 break;
4286 case URTW_TX_HWREV_8187B_D:
4288 * Detect Realtek RTL8187B devices that use
4289 * USB IDs of RTL8187.
4291 sc->sc_hwrev = URTW_HWREV_8187B | URTW_HWREV_8187B_B;
4292 urtw_name = "RTL8187B rev. B (early)";
4293 break;
4294 default:
4295 sc->sc_hwrev |= URTW_HWREV_8187_B;
4296 urtw_name = "RTL8187 rev. B (default)";
4297 break;
4299 } else {
4300 /* RTL8187B hwrev register. */
4301 (void) urtw_read8_c(sc, URTW_8187B_HWREV, &data8, 0);
4302 switch (data8) {
4303 case URTW_8187B_HWREV_8187B_B:
4304 sc->sc_hwrev |= URTW_HWREV_8187B_B;
4305 urtw_name = "RTL8187B rev. B";
4306 break;
4307 case URTW_8187B_HWREV_8187B_D:
4308 sc->sc_hwrev |= URTW_HWREV_8187B_D;
4309 urtw_name = "RTL8187B rev. D";
4310 break;
4311 case URTW_8187B_HWREV_8187B_E:
4312 sc->sc_hwrev |= URTW_HWREV_8187B_E;
4313 urtw_name = "RTL8187B rev. E";
4314 break;
4315 default:
4316 sc->sc_hwrev |= URTW_HWREV_8187B_B;
4317 urtw_name = "RTL8187B rev. B (default)";
4318 break;
4322 URTW8187_DBG(URTW_DEBUG_HWTYPE, (sc->sc_dev, CE_CONT,
4323 "urtw_attach: actual device is %s\n", urtw_name));
4324 if (sc->sc_hwrev & URTW_HWREV_8187) {
4325 sc->urtw_init = urtw_8187_init;
4326 } else {
4327 sc->urtw_init = urtw_8187b_init;
4330 if (urtw_read32_c(sc, URTW_RX, &data, 0))
4331 goto fail3;
4332 sc->sc_epromtype = (data & URTW_RX_9356SEL) ? URTW_EEPROM_93C56 :
4333 URTW_EEPROM_93C46;
4334 if (sc->sc_epromtype == URTW_EEPROM_93C56)
4335 URTW8187_DBG(URTW_DEBUG_HWTYPE, (sc->sc_dev, CE_CONT,
4336 "urtw_attach: eprom is 93C56\n"));
4337 else
4338 URTW8187_DBG(URTW_DEBUG_HWTYPE, (sc->sc_dev, CE_CONT,
4339 "urtw_attach: eprom is 93C46\n"));
4340 error = urtw_get_rfchip(sc);
4341 if (error != 0)
4342 goto fail3;
4343 error = urtw_get_macaddr(sc);
4344 if (error != 0)
4345 goto fail3;
4346 error = urtw_get_txpwr(sc);
4347 if (error != 0)
4348 goto fail3;
4349 error = urtw_led_init(sc); /* XXX incompleted */
4350 if (error != 0)
4351 goto fail3;
4353 sc->sc_rts_retry = URTW_DEFAULT_RTS_RETRY;
4354 sc->sc_tx_retry = URTW_DEFAULT_TX_RETRY;
4355 sc->sc_currate = 3;
4356 /* XXX for what? */
4357 sc->sc_preamble_mode = 2;
4359 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
4360 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
4361 ic->ic_state = IEEE80211_S_INIT;
4363 ic->ic_maxrssi = 95;
4364 ic->ic_xmit = urtw_send;
4366 ic->ic_caps |= IEEE80211_C_WPA | /* Support WPA/WPA2 */
4367 IEEE80211_C_TXPMGT | /* tx power management */
4368 IEEE80211_C_SHPREAMBLE | /* short preamble supported */
4369 IEEE80211_C_SHSLOT; /* short slot time supported */
4370 /* set supported .11b and .11g rates */
4371 ic->ic_sup_rates[IEEE80211_MODE_11B] = urtw_rateset_11b;
4372 ic->ic_sup_rates[IEEE80211_MODE_11G] = urtw_rateset_11g;
4374 /* set supported .11b and .11g channels (1 through 11) */
4375 for (i = 1; i <= 11; i++) {
4376 ic->ic_sup_channels[i].ich_freq =
4377 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
4378 ic->ic_sup_channels[i].ich_flags =
4379 IEEE80211_CHAN_CCK | IEEE80211_CHAN_DYN |
4380 IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM;
4383 ieee80211_attach(ic);
4384 ic->ic_ibss_chan = &ic->ic_sup_channels[1];
4385 ic->ic_curchan = ic->ic_ibss_chan;
4387 /* register WPA door */
4388 ieee80211_register_door(ic, ddi_driver_name(devinfo),
4389 ddi_get_instance(devinfo));
4391 /* override state transition machine */
4392 sc->sc_newstate = ic->ic_newstate;
4393 ic->ic_newstate = urtw_newstate;
4394 ic->ic_watchdog = urtw_watchdog;
4395 ieee80211_media_init(ic);
4396 ic->ic_def_txkey = 0;
4398 sc->dwelltime = 250;
4399 sc->sc_flags = 0;
4402 * Provide initial settings for the WiFi plugin; whenever this
4403 * information changes, we need to call mac_plugindata_update()
4405 wd.wd_opmode = ic->ic_opmode;
4406 wd.wd_secalloc = WIFI_SEC_NONE;
4407 IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid);
4409 if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
4410 URTW8187_DBG(URTW_DEBUG_ATTACH, (sc->sc_dev, CE_CONT,
4411 "MAC version alloc failed\n"));
4412 goto fail4;
4415 macp->m_type_ident = MAC_PLUGIN_IDENT_WIFI;
4416 macp->m_driver = sc;
4417 macp->m_dip = devinfo;
4418 macp->m_src_addr = ic->ic_macaddr;
4419 macp->m_callbacks = &urtw_m_callbacks;
4420 macp->m_min_sdu = 0;
4421 macp->m_max_sdu = IEEE80211_MTU;
4422 macp->m_pdata = &wd;
4423 macp->m_pdata_size = sizeof (wd);
4425 error = mac_register(macp, &ic->ic_mach);
4426 mac_free(macp);
4427 if (error != 0) {
4428 cmn_err(CE_WARN, "urtw_attach: mac_register() err %x\n", error);
4429 goto fail4;
4432 if (usb_register_hotplug_cbs(devinfo, urtw_disconnect,
4433 urtw_reconnect) != USB_SUCCESS) {
4434 cmn_err(CE_WARN, "urtw_attach: failed to register events");
4435 goto fail5;
4439 * Create minor node of type DDI_NT_NET_WIFI
4441 (void) snprintf(strbuf, sizeof (strbuf), "%s%d",
4442 "urtw", instance);
4443 error = ddi_create_minor_node(devinfo, strbuf, S_IFCHR,
4444 instance + 1, DDI_NT_NET_WIFI, 0);
4446 if (error != DDI_SUCCESS)
4447 cmn_err(CE_WARN, "urtw: ddi_create_minor_node() failed\n");
4449 * Notify link is down now
4451 mac_link_update(ic->ic_mach, LINK_STATE_DOWN);
4453 URTW8187_DBG(URTW_DEBUG_ATTACH, (sc->sc_dev, CE_CONT,
4454 "urtw_attach: successfully.\n"));
4455 return (DDI_SUCCESS);
4456 fail5:
4457 (void) mac_disable(ic->ic_mach);
4458 (void) mac_unregister(ic->ic_mach);
4459 fail4:
4460 ieee80211_detach(ic);
4461 fail3:
4462 mutex_destroy(&sc->sc_genlock);
4463 mutex_destroy(&sc->tx_lock);
4464 mutex_destroy(&sc->rx_lock);
4465 mutex_destroy(&sc->sc_ledlock);
4466 fail2:
4467 usb_client_detach(sc->sc_dev, sc->sc_udev);
4468 fail1:
4469 ddi_soft_state_free(urtw_soft_state_p, ddi_get_instance(devinfo));
4471 return (DDI_FAILURE);
4474 static int
4475 urtw_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
4477 struct urtw_softc *sc;
4479 sc = ddi_get_soft_state(urtw_soft_state_p, ddi_get_instance(devinfo));
4480 URTW8187_DBG(URTW_DEBUG_ATTACH, (sc->sc_dev,
4481 CE_CONT, "urtw_detach()\n"));
4483 switch (cmd) {
4484 case DDI_DETACH:
4485 break;
4486 case DDI_SUSPEND:
4487 URTW8187_DBG(URTW_DEBUG_ATTACH,
4488 (sc->sc_dev, CE_CONT, "urtw: suspend\n"));
4490 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
4491 ieee80211_stop_watchdog(&sc->sc_ic);
4493 URTW_LOCK(sc);
4494 sc->sc_flags |= URTW_FLAG_SUSPEND;
4495 URTW_UNLOCK(sc);
4496 if (URTW_IS_RUNNING(sc)) {
4497 urtw_stop(sc);
4498 URTW_LOCK(sc);
4499 sc->sc_flags |= URTW_FLAG_PLUGIN_ONLINE;
4500 URTW_UNLOCK(sc);
4502 return (DDI_SUCCESS);
4503 default:
4504 return (DDI_FAILURE);
4507 if (mac_disable(sc->sc_ic.ic_mach) != 0)
4508 return (DDI_FAILURE);
4509 urtw_stop(sc);
4511 * Unregister from the MAC layer subsystem
4513 (void) mac_unregister(sc->sc_ic.ic_mach);
4515 ieee80211_detach(&sc->sc_ic);
4516 usb_unregister_hotplug_cbs(devinfo);
4517 usb_client_detach(devinfo, sc->sc_udev);
4518 mutex_destroy(&sc->sc_genlock);
4519 mutex_destroy(&sc->tx_lock);
4520 mutex_destroy(&sc->rx_lock);
4521 mutex_destroy(&sc->sc_ledlock);
4522 sc->sc_udev = NULL;
4524 ddi_remove_minor_node(devinfo, NULL);
4525 ddi_soft_state_free(urtw_soft_state_p, ddi_get_instance(devinfo));
4527 return (DDI_SUCCESS);
4531 _info(struct modinfo *modinfop)
4533 return (mod_info(&modlinkage, modinfop));
4537 _init(void)
4539 int status;
4541 status = ddi_soft_state_init(&urtw_soft_state_p,
4542 sizeof (struct urtw_softc), 1);
4543 if (status != 0)
4544 return (status);
4546 mac_init_ops(&urtw_dev_ops, "urtw");
4547 status = mod_install(&modlinkage);
4548 if (status != 0) {
4549 mac_fini_ops(&urtw_dev_ops);
4550 ddi_soft_state_fini(&urtw_soft_state_p);
4552 return (status);
4556 _fini(void)
4558 int status;
4560 status = mod_remove(&modlinkage);
4561 if (status == 0) {
4562 mac_fini_ops(&urtw_dev_ops);
4563 ddi_soft_state_fini(&urtw_soft_state_p);
4565 return (status);