2 * Copyright (c) 2018, Joyent, Inc.
6 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
7 * Use is subject to license terms.
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
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.
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>
52 static void *urtw_soft_state_p
= NULL
;
54 #define URTW_TXBUF_SIZE (IEEE80211_MAX_LEN)
55 #define URTW_RXBUF_SIZE (URTW_TXBUF_SIZE)
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
= {
76 (void *)&urtw_modldrv
,
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
,
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
,
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
157 * Recognized device vendors/products.
159 static struct urtw_type
{
160 struct usb_devno dev
;
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.
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
]);
202 #define usb_lookup(tbl, vendor, product) \
203 usb_match_device(tbl, sizeof (tbl) / sizeof ((tbl)[0]), \
206 #define urtw_lookup(v, p) (usb_lookup(urtw_devs, v, p))
213 struct urtw_pair_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 },
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 },
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 */
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 },
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 },
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
*);
504 urtw_rxeof(usb_pipe_handle_t
, usb_bulk_req_t
*);
506 urtw_newstate(struct ieee80211com
*, enum ieee80211_state
, int);
508 urtw_read8_c(struct urtw_softc
*, int, uint8_t *, uint8_t);
510 urtw_read16_c(struct urtw_softc
*, int, uint16_t *, uint8_t);
512 urtw_read32_c(struct urtw_softc
*, int, uint32_t *, uint8_t);
514 urtw_write8_c(struct urtw_softc
*, int, uint8_t, uint8_t);
516 urtw_write16_c(struct urtw_softc
*, int, uint16_t, uint8_t);
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 *,
523 static usbd_status
urtw_eprom_read32(struct urtw_softc
*, 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
*);
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);
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;
573 urtw8187_dbg(dev_info_t
*dip
, int level
, const char *fmt
, ...)
575 char msg_buffer
[255];
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
);
589 #define URTW8187_DBG(l, x) do {\
590 _NOTE(CONSTANTCONDITION) \
591 if ((l) & urtw8187_dbg_flags) \
593 _NOTE(CONSTANTCONDITION) \
596 #define URTW8187_DBG(l, x)
600 urtw_led_init(struct urtw_softc
*sc
)
605 if (error
= urtw_read8_c(sc
, URTW_PSR
, &sc
->sc_psr
, 0))
607 error
= urtw_eprom_read32(sc
, URTW_EPROM_SWREV
, &rev
);
611 switch (rev
& URTW_EPROM_CID_MASK
) {
612 case URTW_EPROM_CID_ALPHA0
:
613 sc
->sc_strategy
= URTW_SW_LED_MODE1
;
615 case URTW_EPROM_CID_SERCOMM_PS
:
616 sc
->sc_strategy
= URTW_SW_LED_MODE3
;
618 case URTW_EPROM_CID_HW_LED
:
619 sc
->sc_strategy
= URTW_HW_LED
;
621 case URTW_EPROM_CID_RSVD0
:
622 case URTW_EPROM_CID_RSVD1
:
624 sc
->sc_strategy
= URTW_SW_LED_MODE0
;
628 sc
->sc_gpio_ledpin
= URTW_LED_PIN_GPIO0
;
635 urtw_8225_write_s16(struct urtw_softc
*sc
, uint8_t addr
, int index
,
638 usb_ctrl_setup_t req
;
646 bzero(&req
, sizeof (req
));
647 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
648 req
.bRequest
= URTW_8187_SETREGS_REQ
;
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
);
656 cmn_err(CE_WARN
, "urtw_8225_write_s16: allocb failed\n");
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
,
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
));
676 urtw_8225_read(struct urtw_softc
*sc
, uint8_t addr
, uint32_t *data
)
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;
686 if (error
= urtw_read16_c(sc
, URTW_RF_PINS_OUTPUT
, &o1
, 0))
688 if (error
= urtw_read16_c(sc
, URTW_RF_PINS_ENABLE
, &o2
, 0))
690 if (error
= urtw_read16_c(sc
, URTW_RF_PINS_SELECT
, &o3
, 0))
692 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_ENABLE
, o2
| 0xf, 0))
694 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_SELECT
, o3
| 0xf, 0))
697 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
,
698 o1
| URTW_BB_HOST_BANG_EN
, 0))
701 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
, o1
, 0))
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
,
712 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
,
713 bit
| o1
| URTW_BB_HOST_BANG_CLK
, 0))
716 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
,
717 bit
| o1
| URTW_BB_HOST_BANG_CLK
, 0))
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))
728 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
,
729 bit
| o1
| URTW_BB_HOST_BANG_CLK
, 0))
732 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
,
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))
741 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
,
742 bit
| o1
| URTW_BB_HOST_BANG_RW
, 0))
745 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
,
746 o1
| URTW_BB_HOST_BANG_RW
, 0))
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))
756 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
,
757 o1
| URTW_BB_HOST_BANG_RW
| URTW_BB_HOST_BANG_CLK
, 0))
760 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
,
761 o1
| URTW_BB_HOST_BANG_RW
| URTW_BB_HOST_BANG_CLK
, 0))
764 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
,
765 o1
| URTW_BB_HOST_BANG_RW
| URTW_BB_HOST_BANG_CLK
, 0))
769 if (error
= urtw_read16_c(sc
, URTW_RF_PINS_INPUT
, &tmp
, 0))
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))
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))
784 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_ENABLE
, o2
, 0))
786 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_SELECT
, o3
, 0))
788 error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
, 0x3a0, 0);
803 urtw_8225_write_c(struct urtw_softc
*sc
, uint8_t addr
, uint16_t data
)
805 uint16_t d80
, d82
, d84
;
808 if (error
= urtw_read16_c(sc
, URTW_RF_PINS_OUTPUT
, &d80
, 0))
811 if (error
= urtw_read16_c(sc
, URTW_RF_PINS_ENABLE
, &d82
, 0))
813 if (error
= urtw_read16_c(sc
, URTW_RF_PINS_SELECT
, &d84
, 0))
816 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_ENABLE
,
819 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_SELECT
,
823 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
,
824 d80
| URTW_BB_HOST_BANG_EN
, 0))
827 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
, d80
, 0))
830 error
= urtw_8225_write_s16(sc
, addr
, 0x8225, &data
);
834 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
,
835 d80
| URTW_BB_HOST_BANG_EN
, 0))
837 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
,
838 d80
| URTW_BB_HOST_BANG_EN
, 0))
840 error
= urtw_write16_c(sc
, URTW_RF_PINS_SELECT
, d84
, 0);
847 urtw_8225_isv2(struct urtw_softc
*sc
, int *ret
)
854 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
, 0x0080, 0))
856 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_SELECT
, 0x0080, 0))
858 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_ENABLE
, 0x0080, 0))
862 if (error
= urtw_8225_write_c(sc
, 0x0, 0x1b7))
865 error
= urtw_8225_read(sc
, 0x8, &data
);
871 error
= urtw_8225_read(sc
, 0x9, &data
);
878 error
= urtw_8225_write_c(sc
, 0x0, 0xb7);
884 urtw_get_rfchip(struct urtw_softc
*sc
)
886 struct urtw_rf
*rf
= &sc
->sc_rf
;
893 if (sc
->sc_hwrev
& URTW_HWREV_8187
) {
894 error
= urtw_eprom_read32(sc
, URTW_EPROM_RFCHIPID
, &data
);
896 cmn_err(CE_WARN
, "RF ID read failed\n");
899 switch (data
& 0xff) {
900 case URTW_EPROM_RFCHIPID_RTL8225U
:
901 error
= urtw_8225_isv2(sc
, &ret
);
903 URTW8187_DBG(URTW_DEBUG_HWTYPE
,
904 (sc
->sc_dev
, CE_CONT
,
905 "8225 version check failed\n"));
909 URTW8187_DBG(URTW_DEBUG_HWTYPE
,
910 (sc
->sc_dev
, CE_CONT
,
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
;
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
;
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
;
936 rf
->max_sens
= URTW_8225_RF_MAX_SENS
;
937 rf
->sens
= URTW_8225_RF_DEF_SENS
;
942 cmn_err(CE_WARN
, "unsupported RF chip %d\n", data
& 0xff);
947 urtw_get_txpwr(struct urtw_softc
*sc
)
953 error
= urtw_eprom_read32(sc
, URTW_EPROM_TXPW_BASE
, &data
);
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
);
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
);
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
,
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;
991 error
= urtw_eprom_read32(sc
, 0x1b, &data
);
994 sc
->sc_txpwr_cck
[11] = data
& 0xf;
995 sc
->sc_txpwr_ofdm
[11] = (data
& 0xf0) >> 4;
998 error
= urtw_eprom_read32(sc
, 0xa, &data
);
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
);
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;
1019 urtw_get_macaddr(struct urtw_softc
*sc
)
1025 error
= urtw_eprom_read32(sc
, URTW_EPROM_MACADDR
, &data
);
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
);
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
);
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
);
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]));
1050 urtw_eprom_read32(struct urtw_softc
*sc
, uint32_t addr
, uint32_t *data
)
1052 #define URTW_READCMD_LEN 3
1054 int16_t addrstr
[8], data16
, readcmd
[] = { 1, 1, 0 };
1057 /* NB: make sure the buffer is initialized */
1060 /* enable EPROM programming */
1061 if (error
= urtw_write8_c(sc
, URTW_EPROM_CMD
,
1062 URTW_EPROM_CMD_PROGRAM_MODE
, 0))
1064 DELAY(URTW_EPROM_DELAY
);
1066 error
= urtw_eprom_cs(sc
, URTW_EPROM_ENABLE
);
1069 error
= urtw_eprom_ck(sc
);
1072 error
= urtw_eprom_sendbits(sc
, readcmd
, URTW_READCMD_LEN
);
1075 if (sc
->sc_epromtype
== URTW_EEPROM_93C56
) {
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);
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
);
1098 error
= urtw_eprom_writebit(sc
, 0);
1102 for (i
= 0; i
< 16; i
++) {
1103 error
= urtw_eprom_ck(sc
);
1106 error
= urtw_eprom_readbit(sc
, &data16
);
1110 (*data
) |= (data16
<< (15 - i
));
1113 error
= urtw_eprom_cs(sc
, URTW_EPROM_DISABLE
);
1116 error
= urtw_eprom_ck(sc
);
1120 /* now disable EPROM programming */
1121 error
= urtw_write8_c(sc
, URTW_EPROM_CMD
,
1122 URTW_EPROM_CMD_NORMAL_MODE
, 0);
1125 #undef URTW_READCMD_LEN
1129 urtw_eprom_readbit(struct urtw_softc
*sc
, int16_t *data
)
1134 error
= urtw_read8_c(sc
, URTW_EPROM_CMD
, &data8
, 0);
1135 *data
= (data8
& URTW_EPROM_READBIT
) ? 1 : 0;
1136 DELAY(URTW_EPROM_DELAY
);
1141 urtw_eprom_sendbits(struct urtw_softc
*sc
, int16_t *buf
, int buflen
)
1146 for (i
= 0; i
< buflen
; i
++) {
1147 error
= urtw_eprom_writebit(sc
, buf
[i
]);
1150 error
= urtw_eprom_ck(sc
);
1159 urtw_eprom_writebit(struct urtw_softc
*sc
, int16_t bit
)
1164 if (error
= urtw_read8_c(sc
, URTW_EPROM_CMD
, &data
, 0))
1167 error
= urtw_write8_c(sc
, URTW_EPROM_CMD
,
1168 data
| URTW_EPROM_WRITEBIT
, 0);
1170 error
= urtw_write8_c(sc
, URTW_EPROM_CMD
,
1171 data
& ~URTW_EPROM_WRITEBIT
, 0);
1172 DELAY(URTW_EPROM_DELAY
);
1178 urtw_eprom_ck(struct urtw_softc
*sc
)
1184 if (error
= urtw_read8_c(sc
, URTW_EPROM_CMD
, &data
, 0))
1186 if (error
= urtw_write8_c(sc
, URTW_EPROM_CMD
, data
| URTW_EPROM_CK
, 0))
1188 DELAY(URTW_EPROM_DELAY
);
1190 if (error
= urtw_read8_c(sc
, URTW_EPROM_CMD
, &data
, 0))
1192 error
= urtw_write8_c(sc
, URTW_EPROM_CMD
, data
& ~URTW_EPROM_CK
, 0);
1193 DELAY(URTW_EPROM_DELAY
);
1199 urtw_eprom_cs(struct urtw_softc
*sc
, int able
)
1204 if (error
= urtw_read8_c(sc
, URTW_EPROM_CMD
, &data
, 0))
1206 if (able
== URTW_EPROM_ENABLE
)
1207 error
= urtw_write8_c(sc
, URTW_EPROM_CMD
,
1208 data
| URTW_EPROM_CS
, 0);
1210 error
= urtw_write8_c(sc
, URTW_EPROM_CMD
,
1211 data
& ~URTW_EPROM_CS
, 0);
1212 DELAY(URTW_EPROM_DELAY
);
1218 urtw_read8_c(struct urtw_softc
*sc
, int val
, uint8_t *data
, uint8_t idx
)
1220 usb_ctrl_setup_t req
;
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
,
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
));
1242 bcopy(mp
->b_rptr
, data
, sizeof (uint8_t));
1249 urtw_read8e(struct urtw_softc
*sc
, int val
, uint8_t *data
)
1251 usb_ctrl_setup_t req
;
1257 bzero(&req
, sizeof (req
));
1258 req
.bmRequestType
= UT_READ_VENDOR_DEVICE
;
1259 req
.bRequest
= URTW_8187_GETREGS_REQ
;
1260 req
.wValue
= val
| 0xfe00;
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
,
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
));
1275 bcopy(mp
->b_rptr
, data
, sizeof (uint8_t));
1282 urtw_read16_c(struct urtw_softc
*sc
, int val
, uint16_t *data
, uint8_t idx
)
1284 usb_ctrl_setup_t req
;
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
,
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
));
1308 bcopy(mp
->b_rptr
, data
, sizeof (uint16_t));
1315 urtw_read32_c(struct urtw_softc
*sc
, int val
, uint32_t *data
, uint8_t idx
)
1317 usb_ctrl_setup_t req
;
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
,
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
));
1342 bcopy(mp
->b_rptr
, data
, sizeof (uint32_t));
1349 urtw_write8_c(struct urtw_softc
*sc
, int val
, uint8_t data
, uint8_t idx
)
1351 usb_ctrl_setup_t req
;
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
);
1367 cmn_err(CE_CONT
, "urtw_write8_c: failed alloc mblk.");
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
,
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
));
1385 urtw_write8e(struct urtw_softc
*sc
, int val
, uint8_t data
)
1387 usb_ctrl_setup_t req
;
1393 bzero(&req
, sizeof (req
));
1394 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
1395 req
.bRequest
= URTW_8187_SETREGS_REQ
;
1396 req
.wValue
= val
| 0xfe00;
1398 req
.wLength
= sizeof (uint8_t);
1399 req
.attrs
= USB_ATTRS_NONE
;
1401 mp
= allocb(sizeof (uint8_t), BPRI_MED
);
1403 cmn_err(CE_CONT
, "urtw_write8e: failed alloc mblk.");
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
,
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
));
1423 urtw_write16_c(struct urtw_softc
*sc
, int val
, uint16_t data
, uint8_t idx
)
1425 usb_ctrl_setup_t req
;
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
);
1441 cmn_err(CE_CONT
, "urtw_write16_c: failed alloc mblk.");
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
,
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
));
1460 urtw_write32_c(struct urtw_softc
*sc
, int val
, uint32_t data
, uint8_t idx
)
1462 usb_ctrl_setup_t req
;
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
);
1478 cmn_err(CE_CONT
, "urtw_write32_c: failed alloc mblk.");
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
,
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
));
1498 urtw_set_mode(struct urtw_softc
*sc
, uint32_t mode
)
1503 if (error
= urtw_read8_c(sc
, URTW_EPROM_CMD
, &data
, 0))
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);
1513 urtw_8180_set_anaparam(struct urtw_softc
*sc
, uint32_t val
)
1518 error
= urtw_set_mode(sc
, URTW_EPROM_CMD_CONFIG
);
1522 if (error
= urtw_read8_c(sc
, URTW_CONFIG3
, &data
, 0))
1524 if (error
= urtw_write8_c(sc
, URTW_CONFIG3
,
1525 data
| URTW_CONFIG3_ANAPARAM_WRITE
, 0))
1527 if (error
= urtw_write32_c(sc
, URTW_ANAPARAM
, val
, 0))
1529 if (error
= urtw_read8_c(sc
, URTW_CONFIG3
, &data
, 0))
1531 if (error
= urtw_write8_c(sc
, URTW_CONFIG3
,
1532 data
& ~URTW_CONFIG3_ANAPARAM_WRITE
, 0))
1535 error
= urtw_set_mode(sc
, URTW_EPROM_CMD_NORMAL
);
1543 urtw_8185_set_anaparam2(struct urtw_softc
*sc
, uint32_t val
)
1548 error
= urtw_set_mode(sc
, URTW_EPROM_CMD_CONFIG
);
1552 if (error
= urtw_read8_c(sc
, URTW_CONFIG3
, &data
, 0))
1554 if (error
= urtw_write8_c(sc
, URTW_CONFIG3
,
1555 data
| URTW_CONFIG3_ANAPARAM_WRITE
, 0))
1557 if (error
= urtw_write32_c(sc
, URTW_ANAPARAM2
, val
, 0))
1559 if (error
= urtw_read8_c(sc
, URTW_CONFIG3
, &data
, 0))
1561 if (error
= urtw_write8_c(sc
, URTW_CONFIG3
,
1562 data
& ~URTW_CONFIG3_ANAPARAM_WRITE
, 0))
1565 error
= urtw_set_mode(sc
, URTW_EPROM_CMD_NORMAL
);
1573 urtw_intr_disable(struct urtw_softc
*sc
)
1577 error
= urtw_write16_c(sc
, URTW_INTR_MASK
, 0, 0);
1582 urtw_8187_reset(struct urtw_softc
*sc
)
1587 error
= urtw_8180_set_anaparam(sc
, URTW_8187_8225_ANAPARAM_ON
);
1590 error
= urtw_8185_set_anaparam2(sc
, URTW_8187_8225_ANAPARAM2_ON
);
1594 error
= urtw_intr_disable(sc
);
1599 error
= urtw_write8e(sc
, 0x18, 0x10);
1602 error
= urtw_write8e(sc
, 0x18, 0x11);
1605 error
= urtw_write8e(sc
, 0x18, 0x00);
1610 if (error
= urtw_read8_c(sc
, URTW_CMD
, &data
, 0))
1612 data
= (data
& 2) | URTW_CMD_RST
;
1613 if (error
= urtw_write8_c(sc
, URTW_CMD
, data
, 0))
1617 if (error
= urtw_read8_c(sc
, URTW_CMD
, &data
, 0))
1619 if (data
& URTW_CMD_RST
) {
1620 cmn_err(CE_CONT
, "urtw reset timeout\n");
1623 error
= urtw_set_mode(sc
, URTW_EPROM_CMD_LOAD
);
1628 error
= urtw_8180_set_anaparam(sc
, URTW_8187_8225_ANAPARAM_ON
);
1631 error
= urtw_8185_set_anaparam2(sc
, URTW_8187_8225_ANAPARAM2_ON
);
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);
1648 cmn_err(CE_WARN
, "unsupported LED PIN type 0x%x",
1649 sc
->sc_gpio_ledpin
);
1653 cmn_err(CE_WARN
, "unsupported LED type 0x%x", type
);
1657 sc
->sc_gpio_ledon
= 1;
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);
1671 cmn_err(CE_WARN
, "unsupported LED PIN type 0x%x",
1672 sc
->sc_gpio_ledpin
);
1676 cmn_err(CE_WARN
, "unsupported LED type 0x%x", type
);
1680 sc
->sc_gpio_ledon
= 0;
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
));
1690 case URTW_LED_CTL_POWER_ON
:
1691 sc
->sc_gpio_ledstate
= URTW_LED_POWER_ON_BLINK
;
1693 case URTW_LED_CTL_TX
:
1694 if (sc
->sc_gpio_ledinprogress
== 1)
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);
1700 case URTW_LED_CTL_LINK
:
1701 sc
->sc_gpio_ledstate
= URTW_LED_ON
;
1704 cmn_err(CE_CONT
, "unsupported LED mode 0x%x", mode
);
1708 switch (sc
->sc_gpio_ledstate
) {
1710 if (sc
->sc_gpio_ledinprogress
!= 0)
1712 (void) urtw_led_on(sc
, URTW_LED_GPIO
);
1714 case URTW_LED_BLINK_NORMAL
:
1715 if (sc
->sc_gpio_ledinprogress
!= 0)
1717 sc
->sc_gpio_ledinprogress
= 1;
1718 sc
->sc_gpio_blinkstate
= (sc
->sc_gpio_ledon
!= 0) ?
1719 URTW_LED_OFF
: URTW_LED_ON
;
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
,
1726 drv_usectohz((sc
->sc_ic
.ic_state
==
1728 URTW_LED_LINKON_BLINK
:
1729 URTW_LED_LINKOFF_BLINK
));
1730 sc
->sc_gpio_ledinprogress
= 0;
1734 case URTW_LED_POWER_ON_BLINK
:
1735 (void) urtw_led_on(sc
, URTW_LED_GPIO
);
1737 (void) urtw_led_off(sc
, URTW_LED_GPIO
);
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
));
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
);
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
);
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
);
1769 urtw_led_blink(struct urtw_softc
*sc
)
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
);
1779 (void) urtw_led_off(sc
, URTW_LED_GPIO
);
1780 sc
->sc_gpio_blinktime
--;
1781 if (sc
->sc_gpio_blinktime
== 0)
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
)
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;
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"));
1811 URTW8187_DBG(URTW_DEBUG_LED
, (sc
->sc_dev
, CE_CONT
,
1812 "unknown LED status 0x%x", sc
->sc_gpio_ledstate
));
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
);
1826 case URTW_SW_LED_MODE1
:
1827 error
= urtw_led_mode1(sc
, mode
);
1829 case URTW_SW_LED_MODE2
:
1830 error
= urtw_led_mode2(sc
, mode
);
1832 case URTW_SW_LED_MODE3
:
1833 error
= urtw_led_mode3(sc
, mode
);
1836 cmn_err(CE_CONT
, "unsupported LED mode %d\n", sc
->sc_strategy
);
1845 urtw_update_msr(struct urtw_softc
*sc
, int nstate
)
1847 struct ieee80211com
*ic
= &sc
->sc_ic
;
1851 if (error
= urtw_read8_c(sc
, URTW_MSR
, &data
, 0))
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
;
1865 case IEEE80211_M_IBSS
:
1866 data
|= URTW_MSR_LINK_ADHOC
;
1868 case IEEE80211_M_HOSTAP
:
1869 data
|= URTW_MSR_LINK_HOSTAP
;
1872 cmn_err(CE_CONT
, "unsupported operation mode 0x%x\n",
1877 data
|= URTW_MSR_LINK_NONE
;
1879 error
= urtw_write8_c(sc
, URTW_MSR
, data
, 0);
1885 urtw_rate2rtl(int rate
)
1887 #define N(a) (sizeof (a) / sizeof ((a)[0]))
1890 for (i
= 0; i
< N(urtw_ratetable
); i
++) {
1891 if (rate
== urtw_ratetable
[i
].reg
)
1892 return (urtw_ratetable
[i
].val
);
1899 urtw_rtl2rate(int rate
)
1901 #define N(a) (sizeof (a) / sizeof ((a)[0]))
1904 for (i
= 0; i
< N(urtw_ratetable
); i
++) {
1905 if (rate
== urtw_ratetable
[i
].val
)
1906 return (urtw_ratetable
[i
].reg
);
1914 urtw_set_rate(struct urtw_softc
*sc
)
1916 int i
, basic_rate
, min_rr_rate
, max_rr_rate
;
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))
1928 if (error
= urtw_read16_c(sc
, URTW_BRSR
, &data
, 0))
1930 data
&= ~URTW_BRSR_MBR_8185
;
1932 for (i
= 0; i
<= basic_rate
; i
++)
1935 error
= urtw_write16_c(sc
, URTW_BRSR
, data
, 0);
1941 urtw_intr_enable(struct urtw_softc
*sc
)
1945 error
= urtw_write16_c(sc
, URTW_INTR_MASK
, 0xffff, 0);
1950 urtw_rx_setconf(struct urtw_softc
*sc
)
1952 struct ieee80211com
*ic
= &sc
->sc_ic
;
1953 uint32_t data
, a
, b
;
1956 if (urtw_read32_c(sc
, URTW_RX
, &data
, 0))
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
;
1975 data
= data
| a
| b
;
1977 error
= urtw_write32_c(sc
, URTW_RX
, data
, 0);
1983 urtw_rx_enable(struct urtw_softc
*sc
)
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
);
2000 if (error
= urtw_read8_c(sc
, URTW_CMD
, &data
, 0))
2002 error
= urtw_write8_c(sc
, URTW_CMD
, data
| URTW_CMD_RX_ENABLE
, 0);
2008 urtw_tx_enable(struct urtw_softc
*sc
)
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);
2036 data
= URTW_TX_DURPROCMODE
| URTW_TX_DISREQQSIZE
|
2037 URTW_TX_MXDMA_2048
| URTW_TX_SHORTRETRY
|
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);
2047 urtw_8187_init(void *arg
)
2049 struct urtw_softc
*sc
= arg
;
2051 struct urtw_rf
*rf
= &sc
->sc_rf
;
2056 error
= urtw_8187_reset(sc
);
2060 (void) urtw_write8_c(sc
, 0x85, 0, 0);
2061 (void) urtw_write8_c(sc
, URTW_GPIO
, 0, 0);
2064 (void) urtw_write8_c(sc
, 0x85, 4, 0);
2065 error
= urtw_led_ctl(sc
, URTW_LED_CTL_POWER_ON
);
2069 error
= urtw_set_mode(sc
, URTW_EPROM_CMD_CONFIG
);
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
);
2081 error
= urtw_update_msr(sc
, IEEE80211_S_INIT
);
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
);
2092 error
= rf
->init(rf
);
2095 if (rf
->set_sens
!= NULL
)
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
);
2109 error
= urtw_open_pipes(sc
);
2112 sc
->sc_tx_low_queued
= 0;
2113 sc
->sc_tx_normal_queued
= 0;
2114 error
= urtw_rx_enable(sc
);
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
;
2135 urtw_8225_usb_init(struct urtw_softc
*sc
)
2140 if (error
= urtw_write8_c(sc
, URTW_RF_PINS_SELECT
+ 1, 0, 0))
2142 if (error
= urtw_write8_c(sc
, URTW_GPIO
, 0, 0))
2144 if (error
= urtw_read8e(sc
, 0x53, &data
))
2146 if (error
= urtw_write8e(sc
, 0x53, data
| (1 << 7)))
2148 if (error
= urtw_write8_c(sc
, URTW_RF_PINS_SELECT
+ 1, 4, 0))
2150 if (error
= urtw_write8_c(sc
, URTW_GPIO
, 0x20, 0))
2152 if (error
= urtw_write8_c(sc
, URTW_GP_ENABLE
, 0, 0))
2154 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_OUTPUT
, 0x80, 0))
2156 if (error
= urtw_write16_c(sc
, URTW_RF_PINS_SELECT
, 0x80, 0))
2158 error
= urtw_write16_c(sc
, URTW_RF_PINS_ENABLE
, 0x80, 0);
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);
2175 urtw_8187_write_phy(struct urtw_softc
*sc
, uint8_t addr
, uint32_t data
)
2180 phyw
= ((data
<< 8) | (addr
| 0x80));
2181 if (error
= urtw_write8_c(sc
, 0x7f, ((phyw
& 0xff000000) >> 24), 0))
2183 if (error
= urtw_write8_c(sc
, 0x7e, ((phyw
& 0x00ff0000) >> 16), 0))
2185 if (error
= urtw_write8_c(sc
, 0x7d, ((phyw
& 0x0000ff00) >> 8), 0))
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);
2197 urtw_8187_write_phy_ofdm_c(struct urtw_softc
*sc
, uint8_t addr
, uint32_t data
)
2200 return (urtw_8187_write_phy(sc
, addr
, data
));
2204 urtw_8187_write_phy_cck_c(struct urtw_softc
*sc
, uint8_t addr
, uint32_t data
)
2207 return (urtw_8187_write_phy(sc
, addr
, (data
| 0x10000)));
2211 urtw_8225_setgain(struct urtw_softc
*sc
, int16_t gain
)
2215 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 0x0d,
2216 urtw_8225_gain
[gain
* 4]))
2218 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 0x1b,
2219 urtw_8225_gain
[gain
* 4 + 2]))
2221 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 0x1d,
2222 urtw_8225_gain
[gain
* 4 + 3]))
2224 error
= urtw_8187_write_phy_ofdm_c(sc
, 0x23,
2225 urtw_8225_gain
[gain
* 4 + 1]);
2231 urtw_8225_set_txpwrlvl(struct urtw_softc
*sc
, int chan
)
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;
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))
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
]))
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
);
2271 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 2, 0x42))
2273 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 6, 0))
2275 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 8, 0))
2278 if (error
= urtw_write8_c(sc
, URTW_TX_GAIN_OFDM
,
2279 urtw_8225_tx_gain_cck_ofdm
[set
] >> 1, 0))
2281 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 0x5,
2282 urtw_8225_txpwr_ofdm
[idx
]))
2284 error
= urtw_8187_write_phy_ofdm_c(sc
, 0x7,
2285 urtw_8225_txpwr_ofdm
[idx
]);
2292 urtw_8185_tx_antenna(struct urtw_softc
*sc
, uint8_t ant
)
2296 error
= urtw_write8_c(sc
, URTW_TX_ANTENNA
, ant
, 0);
2302 urtw_8225_rf_init(struct urtw_rf
*rf
)
2304 #define N(a) (sizeof (a) / sizeof ((a)[0]))
2308 struct urtw_softc
*sc
= rf
->rf_sc
;
2310 error
= urtw_8180_set_anaparam(sc
, URTW_8187_8225_ANAPARAM_ON
);
2314 if (error
= urtw_8225_usb_init(sc
))
2316 if (error
= urtw_write32_c(sc
, URTW_RF_TIMING
, 0x000a8008, 0))
2318 if (error
= urtw_read16_c(sc
, URTW_BRSR
, &data
, 0))
2320 if (error
= urtw_write16_c(sc
, URTW_BRSR
, 0xffff, 0))
2322 if (error
= urtw_write32_c(sc
, URTW_RF_PARA
, 0x100044, 0))
2325 if (error
= urtw_set_mode(sc
, URTW_EPROM_CMD_CONFIG
))
2327 if (error
= urtw_write8_c(sc
, URTW_CONFIG3
, 0x44, 0))
2329 if (error
= urtw_set_mode(sc
, URTW_EPROM_CMD_NORMAL
))
2331 if (error
= urtw_8185_rf_pins_enable(sc
))
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
))
2342 if (error
= urtw_8225_write_c(sc
, 0x2, 0xc4d))
2345 if (error
= urtw_8225_write_c(sc
, 0x2, 0x44d))
2348 if (error
= urtw_8225_write_c(sc
, 0x0, 0x127))
2351 for (i
= 0; i
< 95; i
++) {
2352 if (error
= urtw_8225_write_c(sc
, 0x1, (uint8_t)(i
+ 1)))
2354 if (error
= urtw_8225_write_c(sc
, 0x2, urtw_8225_rxgain
[i
]))
2358 if (error
= urtw_8225_write_c(sc
, 0x0, 0x27))
2360 if (error
= urtw_8225_write_c(sc
, 0x0, 0x22f))
2363 for (i
= 0; i
< 128; i
++) {
2364 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 0xb,
2368 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 0xa,
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
))
2381 error
= urtw_8225_setgain(sc
, 4);
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
))
2393 if (error
= urtw_write8_c(sc
, 0x5b, 0x0d, 0))
2395 if (error
= urtw_8225_set_txpwrlvl(sc
, 1))
2397 if (error
= urtw_8187_write_phy_cck_c(sc
, 0x10, 0x9b))
2400 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 0x26, 0x90))
2404 /* TX ant A, 0x0 for B */
2405 if (error
= urtw_8185_tx_antenna(sc
, 0x3))
2407 if (error
= urtw_write32_c(sc
, 0x94, 0x3dc00002, 0))
2410 error
= urtw_8225_rf_set_chan(rf
,
2411 ieee80211_chan2ieee(&sc
->sc_ic
, sc
->sc_ic
.ic_curchan
));
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;
2431 if (error
= urtw_8225_set_txpwrlvl(sc
, chan
))
2433 if (urtw_8225_write_c(sc
, 0x7, urtw_8225_channel
[chan
]))
2437 if (error
= urtw_write8_c(sc
, URTW_SIFS
, 0x22, 0))
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))
2445 if (error
= urtw_write8_c(sc
, URTW_SLOT
, 0x14, 0))
2449 if (error
= urtw_write8_c(sc
, URTW_DIFS
, 0x14, 0))
2451 if (error
= urtw_write8_c(sc
, URTW_EIFS
, 0x5b - 0x14, 0))
2453 error
= urtw_write8_c(sc
, URTW_CW_VAL
, 0x73, 0);
2456 if (error
= urtw_write8_c(sc
, URTW_DIFS
, 0x24, 0))
2458 if (error
= urtw_write8_c(sc
, URTW_EIFS
, 0x5b - 0x24, 0))
2460 error
= urtw_write8_c(sc
, URTW_CW_VAL
, 0xa5, 0);
2468 urtw_8225_rf_set_sens(struct urtw_rf
*rf
)
2471 struct urtw_softc
*sc
= rf
->rf_sc
;
2473 if (rf
->sens
< 0 || rf
->sens
> 6)
2477 if (error
= urtw_8225_write_c(sc
, 0x0c, 0x850))
2480 if (error
= urtw_8225_write_c(sc
, 0x0c, 0x50))
2483 rf
->sens
= 6 - rf
->sens
;
2484 if (error
= urtw_8225_setgain(sc
, rf
->sens
))
2486 error
= urtw_8187_write_phy_cck_c(sc
, 0x41,
2487 urtw_8225_threshold
[rf
->sens
]);
2493 urtw_stop(struct urtw_softc
*sc
)
2496 sc
->sc_flags
&= ~URTW_FLAG_RUNNING
;
2498 urtw_close_pipes(sc
);
2502 urtw_isbmode(uint16_t rate
)
2505 rate
= urtw_rtl2rate(rate
);
2507 return ((rate
<= 22 && rate
!= 12 && rate
!= 18)?(1) : (0));
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;
2523 mp
= req
->bulk_data
;
2524 req
->bulk_data
= NULL
;
2525 if (req
->bulk_completion_reason
!= USB_CR_OK
||
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
;
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);
2542 /* 5 dword and 4 byte CRC */
2543 len
= actlen
- (4 * 5);
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",
2551 req
->bulk_data
= mp
;
2555 rate
= (desc
[2] & 0xf0) >> 4;
2556 if (sc
->sc_hwrev
& URTW_HWREV_8187
) {
2557 rssi
= (desc
[6] & 0xfe) >> 1;
2560 if (!urtw_isbmode(rate
)) {
2561 rssi
= (rssi
> 90) ? 90 : ((rssi
< 25) ? 25 : rssi
);
2562 rssi
= ((90 - rssi
) * 100) / 65;
2564 rssi
= (rssi
> 90) ? 95 : ((rssi
< 30) ? 30 : rssi
);
2565 rssi
= ((95 - rssi
) * 100) / 65;
2568 rssi
= 14 + desc
[13]/2;
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",
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
);
2592 mutex_enter(&sc
->rx_lock
);
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
);
2601 urtw_8225v2_setgain(struct urtw_softc
*sc
, int16_t gain
)
2607 gainp
= urtw_8225v2_gain_bg
;
2608 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 0x0d, gainp
[gain
* 3]))
2611 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 0x1b, gainp
[gain
* 3 + 1]))
2613 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 0x1d, gainp
[gain
* 3 + 2]))
2616 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 0x21, 0x17))
2624 urtw_8225v2_set_txpwrlvl(struct urtw_softc
*sc
, int chan
)
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;
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
,
2646 if (error
= urtw_write8_c(sc
, URTW_TX_GAIN_CCK
,
2647 urtw_8225v2_tx_gain_cck_ofdm
[cck_pwrlvl
], 0))
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
);
2661 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 2, 0x42))
2663 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 5, 0x0))
2665 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 6, 0x40))
2667 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 7, 0x0))
2669 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 8, 0x40))
2672 error
= urtw_write8_c(sc
, URTW_TX_GAIN_OFDM
,
2673 urtw_8225v2_tx_gain_cck_ofdm
[ofdm_pwrlvl
], 0);
2680 urtw_8225v2_rf_init(struct urtw_rf
*rf
)
2682 #define N(a) (sizeof (a)/ sizeof ((a)[0]))
2687 struct urtw_softc
*sc
= rf
->rf_sc
;
2689 if (error
= urtw_8180_set_anaparam(sc
, URTW_8187_8225_ANAPARAM_ON
))
2691 if (error
= urtw_8225_usb_init(sc
))
2693 if (error
= urtw_write32_c(sc
, URTW_RF_TIMING
, 0x000a8008, 0))
2695 if (error
= urtw_read16_c(sc
, URTW_BRSR
, &data
, 0))
2697 if (error
= urtw_write16_c(sc
, URTW_BRSR
, 0xffff, 0))
2699 if (error
= urtw_write32_c(sc
, URTW_RF_PARA
, 0x100044, 0))
2701 if (error
= urtw_set_mode(sc
, URTW_EPROM_CMD_CONFIG
))
2703 if (error
= urtw_write8_c(sc
, URTW_CONFIG3
, 0x44, 0))
2705 if (error
= urtw_set_mode(sc
, URTW_EPROM_CMD_NORMAL
))
2707 if (error
= urtw_8185_rf_pins_enable(sc
))
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
))
2720 if (error
= urtw_8225_write_c(sc
, 0x0, 0x1b7))
2723 for (i
= 0; i
< 95; i
++) {
2724 if (error
= urtw_8225_write_c(sc
, 0x1, (uint8_t)(i
+ 1)))
2727 if (error
= urtw_8225_write_c(sc
, 0x2, urtw_8225v2_rxgain
[i
]))
2732 if (error
= urtw_8225_write_c(sc
, 0x3, 0x2))
2735 if (error
= urtw_8225_write_c(sc
, 0x5, 0x4))
2738 if (error
= urtw_8225_write_c(sc
, 0x0, 0xb7))
2741 if (error
= urtw_8225_write_c(sc
, 0x2, 0xc4d))
2744 if (error
= urtw_8225_write_c(sc
, 0x2, 0x44d))
2748 if (error
= urtw_8225_read(sc
, 0x6, &data32
))
2750 if (data32
!= 0xe6) {
2752 cmn_err(CE_WARN
, "expect 0xe6!! (0x%x)\n", data32
);
2755 if (!(data32
& 0x80)) {
2756 if (error
= urtw_8225_write_c(sc
, 0x02, 0x0c4d))
2759 if (error
= urtw_8225_write_c(sc
, 0x02, 0x044d))
2762 if (error
= urtw_8225_read(sc
, 0x6, &data32
))
2764 if (!(data32
& 0x80))
2765 cmn_err(CE_CONT
, "RF calibration failed\n");
2769 if (error
= urtw_8225_write_c(sc
, 0x0, 0x2bf))
2771 for (i
= 0; i
< 128; i
++) {
2772 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 0xb,
2776 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 0xa,
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
))
2790 error
= urtw_8225v2_setgain(sc
, 4);
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
))
2802 if (error
= urtw_write8_c(sc
, 0x5b, 0x0d, 0))
2804 if (error
= urtw_8225v2_set_txpwrlvl(sc
, 1))
2806 if (error
= urtw_8187_write_phy_cck_c(sc
, 0x10, 0x9b))
2809 if (error
= urtw_8187_write_phy_ofdm_c(sc
, 0x26, 0x90))
2813 /* TX ant A, 0x0 for B */
2814 if (error
= urtw_8185_tx_antenna(sc
, 0x3))
2816 if (error
= urtw_write32_c(sc
, 0x94, 0x3dc00002, 0))
2819 error
= urtw_8225_rf_set_chan(rf
,
2820 ieee80211_chan2ieee(&sc
->sc_ic
, sc
->sc_ic
.ic_curchan
));
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;
2835 if (error
= urtw_8225v2_set_txpwrlvl(sc
, chan
))
2838 if (error
= urtw_8225_write_c(sc
, 0x7, urtw_8225_channel
[chan
]))
2843 if (error
= urtw_write8_c(sc
, URTW_SIFS
, 0x22, 0))
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))
2851 if (error
= urtw_write8_c(sc
, URTW_SLOT
, 0x14, 0))
2855 if (error
= urtw_write8_c(sc
, URTW_DIFS
, 0x14, 0))
2857 if (error
= urtw_write8_c(sc
, URTW_EIFS
, 0x5b - 0x14, 0))
2859 if (error
= urtw_write8_c(sc
, URTW_CW_VAL
, 0x73, 0))
2863 if (error
= urtw_write8_c(sc
, URTW_DIFS
, 0x24, 0))
2865 if (error
= urtw_write8_c(sc
, URTW_EIFS
, 0x5b - 0x24, 0))
2867 if (error
= urtw_write8_c(sc
, URTW_CW_VAL
, 0xa5, 0))
2876 urtw_set_channel(struct urtw_softc
*sc
)
2878 struct ieee80211com
*ic
= &sc
->sc_ic
;
2879 struct urtw_rf
*rf
= &sc
->sc_rf
;
2883 if (error
= urtw_read32_c(sc
, URTW_TX_CONF
, &data
, 0))
2885 data
&= ~URTW_TX_LOOPBACK_MASK
;
2886 if (error
= urtw_write32_c(sc
, URTW_TX_CONF
,
2887 data
| URTW_TX_LOOPBACK_MAC
, 0))
2889 error
= rf
->set_chan(rf
, ieee80211_chan2ieee(ic
, ic
->ic_curchan
));
2893 error
= urtw_write32_c(sc
, URTW_TX_CONF
,
2894 data
| URTW_TX_LOOPBACK_NONE
, 0);
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
,
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
++;
2918 if (sc
->sc_need_sched
) {
2919 sc
->sc_need_sched
= 0;
2920 mac_tx_update(ic
->ic_mach
);
2923 sc
->sc_tx_low_queued
--;
2924 mutex_exit(&sc
->tx_lock
);
2925 usb_free_bulk_req(req
);
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
,
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
++;
2948 if (sc
->sc_need_sched
) {
2949 sc
->sc_need_sched
= 0;
2950 mac_tx_update(ic
->ic_mach
);
2953 sc
->sc_tx_normal_queued
--;
2954 mutex_exit(&sc
->tx_lock
);
2955 usb_free_bulk_req(req
);
2960 urtw_get_rate(struct ieee80211com
*ic
)
2962 uint8_t (*rates
)[IEEE80211_RATE_MAXSIZE
];
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
];
2973 return (rate
& IEEE80211_RATE_VAL
);
2977 urtw_8187b_update_wmm(struct urtw_softc
*sc
)
2979 struct ieee80211com
*ic
= &sc
->sc_ic
;
2980 struct ieee80211_channel
*c
= ic
->ic_curchan
;
2982 uint8_t aifs
, sifs
, slot
, ecwmin
, ecwmax
;
2985 if (IEEE80211_IS_CHAN_G(c
))
2990 aifs
= (2 * slot
) + sifs
;
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);
3005 urtw_8187b_reset(struct urtw_softc
*sc
)
3010 error
= urtw_set_mode(sc
, URTW_EPROM_CMD_CONFIG
);
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
);
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);
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");
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
;
3066 urtw_8187b_update_wmm(sc
);
3067 error
= urtw_8187b_reset(sc
);
3071 error
= urtw_open_pipes(sc
);
3074 /* Applying MAC address again. */
3075 error
= urtw_set_mode(sc
, URTW_EPROM_CMD_CONFIG
);
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
);
3085 error
= urtw_update_msr(sc
, IEEE80211_S_INIT
);
3089 error
= rf
->init(rf
);
3092 error
= urtw_intr_enable(sc
);
3096 error
= urtw_write8e(sc
, 0x41, 0xf4);
3099 error
= urtw_write8e(sc
, 0x40, 0x00);
3102 error
= urtw_write8e(sc
, 0x42, 0x00);
3105 error
= urtw_write8e(sc
, 0x42, 0x01);
3108 error
= urtw_write8e(sc
, 0x40, 0x0f);
3111 error
= urtw_write8e(sc
, 0x42, 0x00);
3114 error
= urtw_write8e(sc
, 0x42, 0x01);
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
);
3144 URTW8187_DBG(URTW_DEBUG_ACTIVE
, (sc
->sc_dev
,
3145 CE_CONT
, "urtw_8187b_init: done\n"));
3146 sc
->sc_flags
|= URTW_FLAG_RUNNING
;
3152 cmn_err(CE_WARN
, "urtw_8187b_init failed\n");
3159 urtw_8225v2_b_config_mac(struct urtw_softc
*sc
)
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);
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);
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);
3199 if (IEEE80211_IS_CHAN_G(c
)) {
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);
3223 urtw_8225v2_b_rf_init(struct urtw_rf
*rf
)
3225 struct urtw_softc
*sc
= rf
->rf_sc
;
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
);
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
);
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
);
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
);
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);
3292 (void) urtw_8225_write_c(sc
, 0x02, 0x44d);
3294 (void) urtw_8225_write_c(sc
, 0x00, 0x2bf);
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
));
3328 urtw_8225v2_b_rf_set_chan(struct urtw_rf
*rf
, int chan
)
3330 struct urtw_softc
*sc
= rf
->rf_sc
;
3333 urtw_8225v2_b_set_txpwrlvl(sc
, chan
);
3334 error
= urtw_8225_write_c(sc
, 0x7, urtw_8225_channel
[chan
]);
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);
3345 error
= urtw_write16_c(sc
, URTW_AC_VI
, 0x5114, 0);
3348 error
= urtw_write16_c(sc
, URTW_AC_BE
, 0x5114, 0);
3351 error
= urtw_write16_c(sc
, URTW_AC_BK
, 0x5114, 0);
3357 urtw_8225v2_b_set_txpwrlvl(struct urtw_softc
*sc
, int chan
)
3360 uint8_t *cck_pwrtable
;
3361 uint8_t cck_pwrlvl_min
, cck_pwrlvl_max
, ofdm_pwrlvl_min
,
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
) {
3368 cck_pwrlvl_max
= 15;
3369 ofdm_pwrlvl_min
= 2;
3370 ofdm_pwrlvl_max
= 17;
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)
3392 if (cck_pwrlvl
> 11)
3395 if (cck_pwrlvl
> 5 && cck_pwrlvl
<= 11)
3397 if (cck_pwrlvl
> 12 && cck_pwrlvl
<= 17)
3399 if (cck_pwrlvl
> 17)
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);
3430 (void) urtw_8187_write_phy_ofdm_c(sc
, 0x87, 0x5c);
3431 (void) urtw_8187_write_phy_ofdm_c(sc
, 0x89, 0x5c);
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);
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);
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
;
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
)) {
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"));
3482 m
= allocb(URTW_TXBUF_SIZE
, BPRI_MED
);
3484 cmn_err(CE_WARN
, "urtw_send(): can't alloc mblk.\n");
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
);
3496 wh
= (struct ieee80211_frame
*)m
->b_rptr
;
3498 ni
= ieee80211_find_txnode(ic
, wh
->i_addr1
);
3501 ic
->ic_stats
.is_tx_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
);
3513 ic
->ic_stats
.is_tx_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;
3524 xferlen
= MBLKL(m
) + 4 * 8;
3526 if ((0 == xferlen
% 64) || (0 == xferlen
% 512))
3529 mtx
= allocb(xferlen
, BPRI_MED
);
3532 bzero(buf
, xferlen
);
3533 buf
[0] = MBLKL(m
) & 0xff;
3534 buf
[1] = (MBLKL(m
) & 0x0f00) >> 8;
3537 /* XXX sc_preamble_mode is always 2. */
3538 if (wh
->i_fc
[1] & IEEE80211_FC1_MORE_FRAG
)
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
)));
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
));
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
);
3571 ic
->ic_stats
.is_tx_frags
++;
3572 ic
->ic_stats
.is_tx_bytes
+= MBLKL(m
);
3574 ic
->ic_stats
.is_tx_failed
++;
3579 ieee80211_free_node(ni
);
3582 ((type
& IEEE80211_FC0_TYPE_MASK
) != IEEE80211_FC0_TYPE_DATA
||
3583 err
== DDI_SUCCESS
)) {
3588 if (((type
& IEEE80211_FC0_TYPE_MASK
) == IEEE80211_FC0_TYPE_DATA
) &&
3590 sc
->sc_need_sched
= 1;
3592 mutex_exit(&sc
->tx_lock
);
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
)) {
3607 if (ic
->ic_state
== IEEE80211_S_SCAN
) {
3608 (void) ieee80211_next_scan(ic
);
3614 urtw_led_launch(void *arg
)
3616 struct urtw_softc
*sc
= arg
;
3617 ieee80211com_t
*ic
= &sc
->sc_ic
;
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",
3629 sc
->sc_gpio_ledinprogress
= 0;
3633 error
= urtw_led_blink(sc
);
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"));
3642 URTW8187_DBG(URTW_DEBUG_LED
, (sc
->sc_dev
, CE_CONT
,
3643 "exit led launch"));
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
;
3655 if (sc
->sc_scan_id
!= 0) {
3656 (void) untimeout(sc
->sc_scan_id
);
3661 case IEEE80211_S_INIT
:
3662 URTW8187_DBG(URTW_DEBUG_STATE
,
3663 (sc
->sc_dev
, CE_CONT
, "-> IEEE80211_S_INIT...arg(%d)\n",
3665 if (sc
->sc_flags
& URTW_FLAG_HP
)
3667 (void) urtw_update_msr(sc
, nstate
);
3668 (void) urtw_led_off(sc
, URTW_LED_GPIO
);
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
);
3678 URTW8187_DBG(URTW_DEBUG_STATE
,
3679 (sc
->sc_dev
, CE_CONT
, "scan setchan failed"));
3682 sc
->sc_scan_id
= timeout(urtw_next_scan
, (void *)sc
,
3683 drv_usectohz(sc
->dwelltime
* 1000));
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
);
3692 URTW8187_DBG(URTW_DEBUG_STATE
,
3693 (sc
->sc_dev
, CE_CONT
, "auth setchan failed"));
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
);
3703 URTW8187_DBG(URTW_DEBUG_STATE
,
3704 (sc
->sc_dev
, CE_CONT
, "assoc setchan failed"));
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
);
3715 URTW8187_DBG(URTW_DEBUG_STATE
,
3716 (sc
->sc_dev
, CE_CONT
, "run setchan failed"));
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;
3734 URTW8187_DBG(URTW_DEBUG_STATE
, (sc
->sc_dev
, CE_CONT
,
3735 "-> newstate error...arg(%d)\n", error
));
3738 error
= sc
->sc_newstate(ic
, nstate
, arg
);
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
;
3773 urtw_open_pipes(struct urtw_softc
*sc
)
3775 usb_ep_data_t
*ep_node
;
3776 usb_pipe_policy_t policy
;
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) {
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",
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",
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
));
3830 return (USB_SUCCESS
);
3833 urtw_close_pipes(sc
);
3834 return (USB_FAILURE
);
3838 urtw_tx_start(struct urtw_softc
*sc
, mblk_t
*mp
, int priority
)
3840 usb_bulk_req_t
*req
;
3843 req
= usb_alloc_bulk_req(sc
->sc_dev
, 0, USB_FLAGS_SLEEP
);
3845 URTW8187_DBG(URTW_DEBUG_TX_PROC
, (sc
->sc_dev
, CE_CONT
,
3846 "urtw_tx_start(): failed to allocate req"));
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))
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
);
3872 sc
->sc_tx_normal_queued
++;
3874 sc
->sc_tx_low_queued
++;
3881 urtw_rx_start(struct urtw_softc
*sc
)
3883 usb_bulk_req_t
*req
;
3886 req
= usb_alloc_bulk_req(sc
->sc_dev
, URTW_RXBUF_SIZE
, USB_FLAGS_SLEEP
);
3888 URTW8187_DBG(URTW_DEBUG_RECV
, (sc
->sc_dev
, CE_CONT
,
3889 "urtw_rx_start(): failed to allocate req"));
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
);
3912 mutex_enter(&sc
->rx_lock
);
3914 mutex_exit(&sc
->rx_lock
);
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
)) {
3931 sc
->sc_flags
|= URTW_FLAG_PLUGIN_ONLINE
;
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
);
3941 urtw_reconnect(dev_info_t
*devinfo
)
3943 struct urtw_softc
*sc
;
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
);
3956 sc
->sc_flags
&= ~URTW_FLAG_PLUGIN_ONLINE
;
3960 return (error
? DDI_FAILURE
: DDI_SUCCESS
);
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
;
3970 if ((ic
->ic_state
!= IEEE80211_S_RUN
) ||
3971 URTW_IS_SUSPENDING(sc
)) {
3976 while (mp
!= NULL
) {
3979 if (urtw_send(ic
, mp
, IEEE80211_FC0_TYPE_DATA
) != DDI_SUCCESS
) {
3989 urtw_m_start(void *arg
)
3991 struct urtw_softc
*sc
= (struct urtw_softc
*)arg
;
3994 URTW8187_DBG(URTW_DEBUG_ACTIVE
,
3995 (sc
->sc_dev
, CE_CONT
, "urtw_m_start\n"));
3996 error
= sc
->urtw_init(sc
);
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
);
4014 urtw_m_unicst(void *arg
, const uint8_t *macaddr
)
4021 urtw_m_multicst(void *arg
, boolean_t add
, const uint8_t *macaddr
)
4028 urtw_m_promisc(void *arg
, boolean_t on
)
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
;
4040 err
= ieee80211_getprop(&sc
->sc_ic
, pr_name
, wldp_pr_num
,
4041 wldp_length
, wldp_buf
);
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
);
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
;
4062 err
= ieee80211_setprop(ic
, pr_name
, wldp_pr_num
,
4063 wldp_length
, wldp_buf
);
4065 if (err
== ENETRESET
) {
4066 if (URTW_IS_RUNNING(sc
) && ic
->ic_des_esslen
) {
4068 err
= sc
->urtw_init(sc
);
4070 URTW8187_DBG(URTW_DEBUG_ACTIVE
,
4071 (sc
->sc_dev
, CE_CONT
,
4072 "urtw: setprop failed\n"));
4075 (void) ieee80211_new_state(ic
, IEEE80211_S_SCAN
, -1);
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
;
4091 err
= ieee80211_ioctl(ic
, wq
, mp
);
4093 if (err
== ENETRESET
) {
4094 if (URTW_IS_RUNNING(sc
) && ic
->ic_des_esslen
) {
4096 err
= sc
->urtw_init(sc
);
4098 URTW8187_DBG(URTW_DEBUG_ACTIVE
,
4100 CE_CONT
, "urtw: dev init failed\n"));
4103 (void) ieee80211_new_state(ic
, IEEE80211_S_SCAN
, -1);
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;
4120 case MAC_STAT_IFSPEED
:
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;
4127 case MAC_STAT_NOXMTBUF
:
4128 *val
= sc
->sc_tx_nobuf
;
4130 case MAC_STAT_NORCVBUF
:
4131 *val
= sc
->sc_rx_nobuf
;
4133 case MAC_STAT_IERRORS
:
4134 *val
= sc
->sc_rx_err
;
4136 case MAC_STAT_RBYTES
:
4137 *val
= ic
->ic_stats
.is_rx_bytes
;
4139 case MAC_STAT_IPACKETS
:
4140 *val
= ic
->ic_stats
.is_rx_frags
;
4142 case MAC_STAT_OBYTES
:
4143 *val
= ic
->ic_stats
.is_tx_bytes
;
4145 case MAC_STAT_OPACKETS
:
4146 *val
= ic
->ic_stats
.is_tx_frags
;
4148 case MAC_STAT_OERRORS
:
4149 *val
= ic
->ic_stats
.is_tx_failed
;
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
:
4164 return (ieee80211_stat(ic
, stat
, val
));
4175 urtw_watchdog(void *arg
)
4177 struct urtw_softc
*sc
= arg
;
4178 struct ieee80211com
*ic
= &sc
->sc_ic
;
4180 ieee80211_stop_watchdog(ic
);
4183 if (URTW_IS_NOT_RUNNING(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"));
4198 ieee80211_watchdog(ic
);
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
;
4213 wifi_data_t wd
= { 0 };
4214 mac_register_t
*macp
;
4215 struct urtw_type
*e
= 0;
4216 char *urtw_name
= NULL
;
4222 sc
= ddi_get_soft_state(urtw_soft_state_p
,
4223 ddi_get_instance(devinfo
));
4225 URTW8187_DBG(URTW_DEBUG_ACTIVE
,
4226 (sc
->sc_dev
, CE_CONT
, "urtw: resume\n"));
4228 sc
->sc_flags
&= ~URTW_FLAG_SUSPEND
;
4230 if (URTW_IS_PLUGIN_ONLINE(sc
)) {
4231 error
= sc
->urtw_init(sc
);
4234 sc
->sc_flags
&= ~URTW_FLAG_PLUGIN_ONLINE
;
4238 return (DDI_SUCCESS
);
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");
4259 if (usb_get_dev_data(devinfo
, &sc
->sc_udev
,
4260 USB_PARSE_LVL_ALL
, 0) != USB_SUCCESS
) {
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
);
4273 cmn_err(CE_WARN
, "(urtw) unknown device\n");
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
;
4282 case URTW_TX_HWREV_8187_D
:
4283 sc
->sc_hwrev
|= URTW_HWREV_8187_D
;
4284 urtw_name
= "RTL8187 rev. D";
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)";
4295 sc
->sc_hwrev
|= URTW_HWREV_8187_B
;
4296 urtw_name
= "RTL8187 rev. B (default)";
4300 /* RTL8187B hwrev register. */
4301 (void) urtw_read8_c(sc
, URTW_8187B_HWREV
, &data8
, 0);
4303 case URTW_8187B_HWREV_8187B_B
:
4304 sc
->sc_hwrev
|= URTW_HWREV_8187B_B
;
4305 urtw_name
= "RTL8187B rev. B";
4307 case URTW_8187B_HWREV_8187B_D
:
4308 sc
->sc_hwrev
|= URTW_HWREV_8187B_D
;
4309 urtw_name
= "RTL8187B rev. D";
4311 case URTW_8187B_HWREV_8187B_E
:
4312 sc
->sc_hwrev
|= URTW_HWREV_8187B_E
;
4313 urtw_name
= "RTL8187B rev. E";
4316 sc
->sc_hwrev
|= URTW_HWREV_8187B_B
;
4317 urtw_name
= "RTL8187B rev. B (default)";
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
;
4327 sc
->urtw_init
= urtw_8187b_init
;
4330 if (urtw_read32_c(sc
, URTW_RX
, &data
, 0))
4332 sc
->sc_epromtype
= (data
& URTW_RX_9356SEL
) ? URTW_EEPROM_93C56
:
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"));
4338 URTW8187_DBG(URTW_DEBUG_HWTYPE
, (sc
->sc_dev
, CE_CONT
,
4339 "urtw_attach: eprom is 93C46\n"));
4340 error
= urtw_get_rfchip(sc
);
4343 error
= urtw_get_macaddr(sc
);
4346 error
= urtw_get_txpwr(sc
);
4349 error
= urtw_led_init(sc
); /* XXX incompleted */
4353 sc
->sc_rts_retry
= URTW_DEFAULT_RTS_RETRY
;
4354 sc
->sc_tx_retry
= URTW_DEFAULT_TX_RETRY
;
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;
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"));
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
);
4428 cmn_err(CE_WARN
, "urtw_attach: mac_register() err %x\n", error
);
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");
4439 * Create minor node of type DDI_NT_NET_WIFI
4441 (void) snprintf(strbuf
, sizeof (strbuf
), "%s%d",
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
);
4457 (void) mac_disable(ic
->ic_mach
);
4458 (void) mac_unregister(ic
->ic_mach
);
4460 ieee80211_detach(ic
);
4462 mutex_destroy(&sc
->sc_genlock
);
4463 mutex_destroy(&sc
->tx_lock
);
4464 mutex_destroy(&sc
->rx_lock
);
4465 mutex_destroy(&sc
->sc_ledlock
);
4467 usb_client_detach(sc
->sc_dev
, sc
->sc_udev
);
4469 ddi_soft_state_free(urtw_soft_state_p
, ddi_get_instance(devinfo
));
4471 return (DDI_FAILURE
);
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"));
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
);
4494 sc
->sc_flags
|= URTW_FLAG_SUSPEND
;
4496 if (URTW_IS_RUNNING(sc
)) {
4499 sc
->sc_flags
|= URTW_FLAG_PLUGIN_ONLINE
;
4502 return (DDI_SUCCESS
);
4504 return (DDI_FAILURE
);
4507 if (mac_disable(sc
->sc_ic
.ic_mach
) != 0)
4508 return (DDI_FAILURE
);
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
);
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
));
4541 status
= ddi_soft_state_init(&urtw_soft_state_p
,
4542 sizeof (struct urtw_softc
), 1);
4546 mac_init_ops(&urtw_dev_ops
, "urtw");
4547 status
= mod_install(&modlinkage
);
4549 mac_fini_ops(&urtw_dev_ops
);
4550 ddi_soft_state_fini(&urtw_soft_state_p
);
4560 status
= mod_remove(&modlinkage
);
4562 mac_fini_ops(&urtw_dev_ops
);
4563 ddi_soft_state_fini(&urtw_soft_state_p
);