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