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