Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/rum/rum.c
+++ new/usr/src/uts/common/io/rum/rum.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) 2005-2007 Damien Bergamini <damien.bergamini@free.fr>
8 8 * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org>
9 9 *
10 10 * Permission to use, copy, modify, and distribute this software for any
11 11 * purpose with or without fee is hereby granted, provided that the above
12 12 * copyright notice and this permission notice appear in all copies.
13 13 *
14 14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 21 */
22 22
23 23 /*
24 24 * Ralink Technology RT2501USB/RT2601USB chipset driver
25 25 * http://www.ralinktech.com.tw/
26 26 */
27 27 #include <sys/types.h>
28 28 #include <sys/cmn_err.h>
29 29 #include <sys/strsubr.h>
30 30 #include <sys/modctl.h>
31 31 #include <sys/devops.h>
32 32 #include <sys/mac_provider.h>
33 33 #include <sys/mac_wifi.h>
34 34 #include <sys/net80211.h>
35 35 #include <sys/byteorder.h>
36 36
37 37 #define USBDRV_MAJOR_VER 2
38 38 #define USBDRV_MINOR_VER 0
39 39 #include <sys/usb/usba.h>
40 40 #include <sys/usb/usba/usba_types.h>
41 41
42 42 #include "rum_reg.h"
43 43 #include "rum_var.h"
44 44 #include "rt2573_ucode.h"
45 45
46 46 static void *rum_soft_state_p = NULL;
47 47
48 48 #define RAL_TXBUF_SIZE (IEEE80211_MAX_LEN)
49 49 #define RAL_RXBUF_SIZE (IEEE80211_MAX_LEN)
50 50
51 51 /* quickly determine if a given rate is CCK or OFDM */
52 52 #define RUM_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
53 53 #define RUM_ACK_SIZE 14 /* 10 + 4(FCS) */
54 54 #define RUM_CTS_SIZE 14 /* 10 + 4(FCS) */
55 55
56 56 #define RUM_N(a) (sizeof (a) / sizeof ((a)[0]))
57 57
58 58 /*
59 59 * Supported rates for 802.11a/b/g modes (in 500Kbps unit).
60 60 */
61 61 static const struct ieee80211_rateset rum_rateset_11a =
62 62 { 8, { 12, 18, 24, 36, 48, 72, 96, 108 } };
63 63
64 64 static const struct ieee80211_rateset rum_rateset_11b =
65 65 { 4, { 2, 4, 11, 22 } };
66 66
67 67 static const struct ieee80211_rateset rum_rateset_11g =
68 68 { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
69 69
70 70 static const struct {
71 71 uint32_t reg;
72 72 uint32_t val;
73 73 } rum_def_mac[] = {
74 74 { RT2573_TXRX_CSR0, 0x025fb032 },
75 75 { RT2573_TXRX_CSR1, 0x9eaa9eaf },
76 76 { RT2573_TXRX_CSR2, 0x8a8b8c8d },
77 77 { RT2573_TXRX_CSR3, 0x00858687 },
78 78 { RT2573_TXRX_CSR7, 0x2e31353b },
79 79 { RT2573_TXRX_CSR8, 0x2a2a2a2c },
80 80 { RT2573_TXRX_CSR15, 0x0000000f },
81 81 { RT2573_MAC_CSR6, 0x00000fff },
82 82 { RT2573_MAC_CSR8, 0x016c030a },
83 83 { RT2573_MAC_CSR10, 0x00000718 },
84 84 { RT2573_MAC_CSR12, 0x00000004 },
85 85 { RT2573_MAC_CSR13, 0x00007f00 },
86 86 { RT2573_SEC_CSR0, 0x00000000 },
87 87 { RT2573_SEC_CSR1, 0x00000000 },
88 88 { RT2573_SEC_CSR5, 0x00000000 },
89 89 { RT2573_PHY_CSR1, 0x000023b0 },
90 90 { RT2573_PHY_CSR5, 0x00040a06 },
91 91 { RT2573_PHY_CSR6, 0x00080606 },
92 92 { RT2573_PHY_CSR7, 0x00000408 },
93 93 { RT2573_AIFSN_CSR, 0x00002273 },
94 94 { RT2573_CWMIN_CSR, 0x00002344 },
95 95 { RT2573_CWMAX_CSR, 0x000034aa }
96 96 };
97 97
98 98 static const struct {
99 99 uint8_t reg;
100 100 uint8_t val;
101 101 } rum_def_bbp[] = {
102 102 { 3, 0x80 },
103 103 { 15, 0x30 },
104 104 { 17, 0x20 },
105 105 { 21, 0xc8 },
106 106 { 22, 0x38 },
107 107 { 23, 0x06 },
108 108 { 24, 0xfe },
109 109 { 25, 0x0a },
110 110 { 26, 0x0d },
111 111 { 32, 0x0b },
112 112 { 34, 0x12 },
113 113 { 37, 0x07 },
114 114 { 39, 0xf8 },
115 115 { 41, 0x60 },
116 116 { 53, 0x10 },
117 117 { 54, 0x18 },
118 118 { 60, 0x10 },
119 119 { 61, 0x04 },
120 120 { 62, 0x04 },
121 121 { 75, 0xfe },
122 122 { 86, 0xfe },
123 123 { 88, 0xfe },
124 124 { 90, 0x0f },
125 125 { 99, 0x00 },
126 126 { 102, 0x16 },
127 127 { 107, 0x04 }
128 128 };
129 129
130 130 static const struct rfprog {
131 131 uint8_t chan;
132 132 uint32_t r1, r2, r3, r4;
133 133 } rum_rf5226[] = {
134 134 { 1, 0x00b03, 0x001e1, 0x1a014, 0x30282 },
135 135 { 2, 0x00b03, 0x001e1, 0x1a014, 0x30287 },
136 136 { 3, 0x00b03, 0x001e2, 0x1a014, 0x30282 },
137 137 { 4, 0x00b03, 0x001e2, 0x1a014, 0x30287 },
138 138 { 5, 0x00b03, 0x001e3, 0x1a014, 0x30282 },
139 139 { 6, 0x00b03, 0x001e3, 0x1a014, 0x30287 },
140 140 { 7, 0x00b03, 0x001e4, 0x1a014, 0x30282 },
141 141 { 8, 0x00b03, 0x001e4, 0x1a014, 0x30287 },
142 142 { 9, 0x00b03, 0x001e5, 0x1a014, 0x30282 },
143 143 { 10, 0x00b03, 0x001e5, 0x1a014, 0x30287 },
144 144 { 11, 0x00b03, 0x001e6, 0x1a014, 0x30282 },
145 145 { 12, 0x00b03, 0x001e6, 0x1a014, 0x30287 },
146 146 { 13, 0x00b03, 0x001e7, 0x1a014, 0x30282 },
147 147 { 14, 0x00b03, 0x001e8, 0x1a014, 0x30284 },
148 148
149 149 { 34, 0x00b03, 0x20266, 0x36014, 0x30282 },
150 150 { 38, 0x00b03, 0x20267, 0x36014, 0x30284 },
151 151 { 42, 0x00b03, 0x20268, 0x36014, 0x30286 },
152 152 { 46, 0x00b03, 0x20269, 0x36014, 0x30288 },
153 153
154 154 { 36, 0x00b03, 0x00266, 0x26014, 0x30288 },
155 155 { 40, 0x00b03, 0x00268, 0x26014, 0x30280 },
156 156 { 44, 0x00b03, 0x00269, 0x26014, 0x30282 },
157 157 { 48, 0x00b03, 0x0026a, 0x26014, 0x30284 },
158 158 { 52, 0x00b03, 0x0026b, 0x26014, 0x30286 },
159 159 { 56, 0x00b03, 0x0026c, 0x26014, 0x30288 },
160 160 { 60, 0x00b03, 0x0026e, 0x26014, 0x30280 },
161 161 { 64, 0x00b03, 0x0026f, 0x26014, 0x30282 },
162 162
163 163 { 100, 0x00b03, 0x0028a, 0x2e014, 0x30280 },
164 164 { 104, 0x00b03, 0x0028b, 0x2e014, 0x30282 },
165 165 { 108, 0x00b03, 0x0028c, 0x2e014, 0x30284 },
166 166 { 112, 0x00b03, 0x0028d, 0x2e014, 0x30286 },
167 167 { 116, 0x00b03, 0x0028e, 0x2e014, 0x30288 },
168 168 { 120, 0x00b03, 0x002a0, 0x2e014, 0x30280 },
169 169 { 124, 0x00b03, 0x002a1, 0x2e014, 0x30282 },
170 170 { 128, 0x00b03, 0x002a2, 0x2e014, 0x30284 },
171 171 { 132, 0x00b03, 0x002a3, 0x2e014, 0x30286 },
172 172 { 136, 0x00b03, 0x002a4, 0x2e014, 0x30288 },
173 173 { 140, 0x00b03, 0x002a6, 0x2e014, 0x30280 },
174 174
175 175 { 149, 0x00b03, 0x002a8, 0x2e014, 0x30287 },
176 176 { 153, 0x00b03, 0x002a9, 0x2e014, 0x30289 },
177 177 { 157, 0x00b03, 0x002ab, 0x2e014, 0x30281 },
178 178 { 161, 0x00b03, 0x002ac, 0x2e014, 0x30283 },
179 179 { 165, 0x00b03, 0x002ad, 0x2e014, 0x30285 }
180 180 }, rum_rf5225[] = {
181 181 { 1, 0x00b33, 0x011e1, 0x1a014, 0x30282 },
182 182 { 2, 0x00b33, 0x011e1, 0x1a014, 0x30287 },
183 183 { 3, 0x00b33, 0x011e2, 0x1a014, 0x30282 },
184 184 { 4, 0x00b33, 0x011e2, 0x1a014, 0x30287 },
185 185 { 5, 0x00b33, 0x011e3, 0x1a014, 0x30282 },
186 186 { 6, 0x00b33, 0x011e3, 0x1a014, 0x30287 },
187 187 { 7, 0x00b33, 0x011e4, 0x1a014, 0x30282 },
188 188 { 8, 0x00b33, 0x011e4, 0x1a014, 0x30287 },
189 189 { 9, 0x00b33, 0x011e5, 0x1a014, 0x30282 },
190 190 { 10, 0x00b33, 0x011e5, 0x1a014, 0x30287 },
191 191 { 11, 0x00b33, 0x011e6, 0x1a014, 0x30282 },
192 192 { 12, 0x00b33, 0x011e6, 0x1a014, 0x30287 },
193 193 { 13, 0x00b33, 0x011e7, 0x1a014, 0x30282 },
194 194 { 14, 0x00b33, 0x011e8, 0x1a014, 0x30284 },
195 195
196 196 { 34, 0x00b33, 0x01266, 0x26014, 0x30282 },
197 197 { 38, 0x00b33, 0x01267, 0x26014, 0x30284 },
198 198 { 42, 0x00b33, 0x01268, 0x26014, 0x30286 },
199 199 { 46, 0x00b33, 0x01269, 0x26014, 0x30288 },
200 200
201 201 { 36, 0x00b33, 0x01266, 0x26014, 0x30288 },
202 202 { 40, 0x00b33, 0x01268, 0x26014, 0x30280 },
203 203 { 44, 0x00b33, 0x01269, 0x26014, 0x30282 },
204 204 { 48, 0x00b33, 0x0126a, 0x26014, 0x30284 },
205 205 { 52, 0x00b33, 0x0126b, 0x26014, 0x30286 },
206 206 { 56, 0x00b33, 0x0126c, 0x26014, 0x30288 },
207 207 { 60, 0x00b33, 0x0126e, 0x26014, 0x30280 },
208 208 { 64, 0x00b33, 0x0126f, 0x26014, 0x30282 },
209 209
210 210 { 100, 0x00b33, 0x0128a, 0x2e014, 0x30280 },
211 211 { 104, 0x00b33, 0x0128b, 0x2e014, 0x30282 },
212 212 { 108, 0x00b33, 0x0128c, 0x2e014, 0x30284 },
213 213 { 112, 0x00b33, 0x0128d, 0x2e014, 0x30286 },
214 214 { 116, 0x00b33, 0x0128e, 0x2e014, 0x30288 },
215 215 { 120, 0x00b33, 0x012a0, 0x2e014, 0x30280 },
216 216 { 124, 0x00b33, 0x012a1, 0x2e014, 0x30282 },
217 217 { 128, 0x00b33, 0x012a2, 0x2e014, 0x30284 },
218 218 { 132, 0x00b33, 0x012a3, 0x2e014, 0x30286 },
219 219 { 136, 0x00b33, 0x012a4, 0x2e014, 0x30288 },
220 220 { 140, 0x00b33, 0x012a6, 0x2e014, 0x30280 },
221 221
222 222 { 149, 0x00b33, 0x012a8, 0x2e014, 0x30287 },
223 223 { 153, 0x00b33, 0x012a9, 0x2e014, 0x30289 },
224 224 { 157, 0x00b33, 0x012ab, 0x2e014, 0x30281 },
225 225 { 161, 0x00b33, 0x012ac, 0x2e014, 0x30283 },
226 226 { 165, 0x00b33, 0x012ad, 0x2e014, 0x30285 }
227 227 };
228 228
229 229 /*
230 230 * device operations
231 231 */
232 232 static int rum_attach(dev_info_t *, ddi_attach_cmd_t);
233 233 static int rum_detach(dev_info_t *, ddi_detach_cmd_t);
234 234
235 235 /*
236 236 * Module Loading Data & Entry Points
237 237 */
238 238 DDI_DEFINE_STREAM_OPS(rum_dev_ops, nulldev, nulldev, rum_attach,
↓ open down ↓ |
238 lines elided |
↑ open up ↑ |
239 239 rum_detach, nodev, NULL, D_MP, NULL, ddi_quiesce_not_needed);
240 240
241 241 static struct modldrv rum_modldrv = {
242 242 &mod_driverops, /* Type of module. This one is a driver */
243 243 "rum driver v1.2", /* short description */
244 244 &rum_dev_ops /* driver specific ops */
245 245 };
246 246
247 247 static struct modlinkage modlinkage = {
248 248 MODREV_1,
249 - (void *)&rum_modldrv,
250 - NULL
249 + { (void *)&rum_modldrv, NULL }
251 250 };
252 251
253 252 static int rum_m_stat(void *, uint_t, uint64_t *);
254 253 static int rum_m_start(void *);
255 254 static void rum_m_stop(void *);
256 255 static int rum_m_promisc(void *, boolean_t);
257 256 static int rum_m_multicst(void *, boolean_t, const uint8_t *);
258 257 static int rum_m_unicst(void *, const uint8_t *);
259 258 static mblk_t *rum_m_tx(void *, mblk_t *);
260 259 static void rum_m_ioctl(void *, queue_t *, mblk_t *);
261 260 static int rum_m_setprop(void *, const char *, mac_prop_id_t,
262 261 uint_t, const void *);
263 262 static int rum_m_getprop(void *, const char *, mac_prop_id_t,
264 263 uint_t, void *);
265 264 static void rum_m_propinfo(void *, const char *, mac_prop_id_t,
266 265 mac_prop_info_handle_t);
267 266
268 267 static mac_callbacks_t rum_m_callbacks = {
269 268 MC_IOCTL | MC_SETPROP | MC_GETPROP | MC_PROPINFO,
270 269 rum_m_stat,
271 270 rum_m_start,
272 271 rum_m_stop,
273 272 rum_m_promisc,
274 273 rum_m_multicst,
275 274 rum_m_unicst,
276 275 rum_m_tx,
277 276 NULL,
278 277 rum_m_ioctl,
279 278 NULL, /* mc_getcapab */
280 279 NULL,
281 280 NULL,
282 281 rum_m_setprop,
283 282 rum_m_getprop,
284 283 rum_m_propinfo
285 284 };
286 285
287 286 static void rum_amrr_start(struct rum_softc *, struct ieee80211_node *);
288 287 static int rum_tx_trigger(struct rum_softc *, mblk_t *);
289 288 static int rum_rx_trigger(struct rum_softc *);
290 289
291 290 uint32_t rum_dbg_flags = 0;
292 291
293 292 void
294 293 ral_debug(uint32_t dbg_flags, const int8_t *fmt, ...)
295 294 {
296 295 va_list args;
297 296
298 297 if (dbg_flags & rum_dbg_flags) {
299 298 va_start(args, fmt);
300 299 vcmn_err(CE_CONT, fmt, args);
301 300 va_end(args);
302 301 }
303 302 }
304 303
305 304 static void
306 305 rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len)
307 306 {
308 307 usb_ctrl_setup_t req;
309 308 usb_cr_t cr;
310 309 usb_cb_flags_t cf;
311 310 mblk_t *mp;
312 311 int err;
313 312
314 313 bzero(&req, sizeof (req));
315 314 req.bmRequestType = USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_DEV_TO_HOST;
316 315 req.bRequest = RT2573_READ_MULTI_MAC;
317 316 req.wValue = 0;
318 317 req.wIndex = reg;
319 318 req.wLength = (uint16_t)len;
320 319 req.attrs = USB_ATTRS_AUTOCLEARING;
321 320
322 321 mp = NULL;
323 322 err = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
324 323 &cr, &cf, 0);
325 324
326 325 if (err != USB_SUCCESS) {
327 326 ral_debug(RAL_DBG_ERR,
328 327 "rum_read_multi(): could not read MAC register:"
329 328 "cr:%s(%d), cf:(%x)\n",
330 329 usb_str_cr(cr), cr, cf);
331 330 return;
332 331 }
333 332
334 333 bcopy(mp->b_rptr, buf, len);
335 334 freemsg(mp);
336 335 }
337 336
338 337 static uint32_t
339 338 rum_read(struct rum_softc *sc, uint16_t reg)
340 339 {
341 340 uint32_t val;
342 341
343 342 rum_read_multi(sc, reg, &val, sizeof (val));
344 343
345 344 return (LE_32(val));
346 345 }
347 346
348 347 static void
349 348 rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len)
350 349 {
351 350 usb_ctrl_setup_t req;
352 351 usb_cr_t cr;
353 352 usb_cb_flags_t cf;
354 353 mblk_t *mp;
355 354 int err;
356 355
357 356 bzero(&req, sizeof (req));
358 357 req.bmRequestType = USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_HOST_TO_DEV;
359 358 req.bRequest = RT2573_WRITE_MULTI_MAC;
360 359 req.wValue = 0;
361 360 req.wIndex = reg;
362 361 req.wLength = (uint16_t)len;
363 362 req.attrs = USB_ATTRS_NONE;
364 363
365 364 if ((mp = allocb(len, BPRI_HI)) == NULL) {
366 365 ral_debug(RAL_DBG_ERR, "rum_write_multi(): failed alloc mblk.");
367 366 return;
368 367 }
369 368
370 369 bcopy(buf, mp->b_wptr, len);
371 370 mp->b_wptr += len;
372 371
373 372 err = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
374 373 &cr, &cf, 0);
375 374
376 375 if (err != USB_SUCCESS) {
377 376 ral_debug(RAL_DBG_USB,
378 377 "rum_write_multi(): could not write MAC register:"
379 378 "cr:%s(%d), cf:(%x)\n",
380 379 usb_str_cr(cr), cr, cf);
381 380 }
382 381
383 382 freemsg(mp);
384 383 }
385 384
386 385 static void
387 386 rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val)
388 387 {
389 388 uint32_t tmp = LE_32(val);
390 389
391 390 rum_write_multi(sc, reg, &tmp, sizeof (tmp));
392 391 }
393 392
394 393 #define UGETDW(w) ((w)[0] | ((w)[1] << 8) | ((w)[2] << 16) | ((w)[3] << 24))
395 394
396 395 static int
397 396 rum_load_microcode(struct rum_softc *sc)
398 397 {
399 398 usb_ctrl_setup_t req;
400 399 usb_cr_t cr;
401 400 usb_cb_flags_t cf;
402 401 int err;
403 402
404 403 const uint8_t *ucode;
405 404 int size;
406 405 uint16_t reg = RT2573_MCU_CODE_BASE;
407 406
408 407 ucode = rt2573_ucode;
409 408 size = sizeof (rt2573_ucode);
410 409
411 410 /* copy firmware image into NIC */
412 411 for (; size >= 4; reg += 4, ucode += 4, size -= 4) {
413 412 rum_write(sc, reg, UGETDW(ucode));
414 413 /* rum_write(sc, reg, *(uint32_t *)(ucode)); */
415 414 }
416 415
417 416 bzero(&req, sizeof (req));
418 417 req.bmRequestType = USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_HOST_TO_DEV;
419 418 req.bRequest = RT2573_MCU_CNTL;
420 419 req.wValue = RT2573_MCU_RUN;
421 420 req.wIndex = 0;
422 421 req.wLength = 0;
423 422 req.attrs = USB_ATTRS_NONE;
424 423
425 424 err = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, NULL,
426 425 &cr, &cf, 0);
427 426
428 427 if (err != USB_SUCCESS) {
429 428 ral_debug(RAL_DBG_ERR,
430 429 "rum_load_microcode(): could not run firmware: "
431 430 "cr:%s(%d), cf:(%x)\n",
432 431 usb_str_cr(cr), cr, cf);
433 432 }
434 433
435 434 ral_debug(RAL_DBG_MSG,
436 435 "rum_load_microcode(%d): done\n", sizeof (rt2573_ucode));
437 436
438 437 return (err);
439 438 }
440 439
441 440 static void
442 441 rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len)
443 442 {
444 443 usb_ctrl_setup_t req;
445 444 usb_cr_t cr;
446 445 usb_cb_flags_t cf;
447 446 mblk_t *mp;
448 447 int err;
449 448
450 449 bzero(&req, sizeof (req));
451 450 req.bmRequestType = USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_DEV_TO_HOST;
452 451 req.bRequest = RT2573_READ_EEPROM;
453 452 req.wValue = 0;
454 453 req.wIndex = addr;
455 454 req.wLength = (uint16_t)len;
456 455
457 456 mp = NULL;
458 457 err = usb_pipe_ctrl_xfer_wait(sc->sc_udev->dev_default_ph, &req, &mp,
459 458 &cr, &cf, 0);
460 459
461 460 if (err != USB_SUCCESS) {
462 461 ral_debug(RAL_DBG_USB,
463 462 "rum_eeprom_read(): could not read EEPROM:"
464 463 "cr:%s(%d), cf:(%x)\n",
465 464 usb_str_cr(cr), cr, cf);
466 465 return;
467 466 }
468 467
469 468 bcopy(mp->b_rptr, buf, len);
470 469 freemsg(mp);
471 470 }
472 471
473 472 /* ARGSUSED */
474 473 static void
475 474 rum_txeof(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
476 475 {
477 476 struct rum_softc *sc = (struct rum_softc *)req->bulk_client_private;
478 477 struct ieee80211com *ic = &sc->sc_ic;
479 478
480 479 ral_debug(RAL_DBG_TX,
481 480 "rum_txeof(): cr:%s(%d), flags:0x%x, tx_queued:%d",
482 481 usb_str_cr(req->bulk_completion_reason),
483 482 req->bulk_completion_reason,
484 483 req->bulk_cb_flags,
485 484 sc->tx_queued);
486 485
487 486 if (req->bulk_completion_reason != USB_CR_OK)
488 487 sc->sc_tx_err++;
489 488
490 489 mutex_enter(&sc->tx_lock);
491 490
492 491 sc->tx_queued--;
493 492 sc->sc_tx_timer = 0;
494 493
495 494 if (sc->sc_need_sched) {
496 495 sc->sc_need_sched = 0;
497 496 mac_tx_update(ic->ic_mach);
498 497 }
499 498
500 499 mutex_exit(&sc->tx_lock);
501 500 usb_free_bulk_req(req);
502 501 }
503 502
504 503 /* ARGSUSED */
505 504 static void
506 505 rum_rxeof(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
507 506 {
508 507 struct rum_softc *sc = (struct rum_softc *)req->bulk_client_private;
509 508 struct ieee80211com *ic = &sc->sc_ic;
510 509
511 510 struct rum_rx_desc *desc;
512 511 struct ieee80211_frame *wh;
513 512 struct ieee80211_node *ni;
514 513
515 514 mblk_t *m, *mp;
516 515 int len, pktlen;
517 516 char *rxbuf;
518 517
519 518 mp = req->bulk_data;
520 519 req->bulk_data = NULL;
521 520
522 521 ral_debug(RAL_DBG_RX,
523 522 "rum_rxeof(): cr:%s(%d), flags:0x%x, rx_queued:%d",
524 523 usb_str_cr(req->bulk_completion_reason),
525 524 req->bulk_completion_reason,
526 525 req->bulk_cb_flags,
527 526 sc->rx_queued);
528 527
529 528 if (req->bulk_completion_reason != USB_CR_OK) {
530 529 sc->sc_rx_err++;
531 530 goto fail;
532 531 }
533 532
534 533 len = msgdsize(mp);
535 534 rxbuf = (char *)mp->b_rptr;
536 535
537 536
538 537 if (len < RT2573_RX_DESC_SIZE + sizeof (struct ieee80211_frame_min)) {
539 538 ral_debug(RAL_DBG_ERR,
540 539 "rum_rxeof(): xfer too short %d\n", len);
541 540 sc->sc_rx_err++;
542 541 goto fail;
543 542 }
544 543
545 544 /* rx descriptor is located at the head, different from RT2500USB */
546 545 desc = (struct rum_rx_desc *)rxbuf;
547 546
548 547 if (LE_32(desc->flags) & RT2573_RX_CRC_ERROR) {
549 548 /*
550 549 * This should not happen since we did not request to receive
551 550 * those frames when we filled RT2573_TXRX_CSR0.
552 551 */
553 552 ral_debug(RAL_DBG_ERR, "CRC error\n");
554 553 sc->sc_rx_err++;
555 554 goto fail;
556 555 }
557 556
558 557 pktlen = (LE_32(desc->flags) >> 16) & 0xfff;
559 558
560 559 if (pktlen > (len - RT2573_RX_DESC_SIZE)) {
561 560 ral_debug(RAL_DBG_ERR,
562 561 "rum_rxeof(): pktlen mismatch <%d, %d>.\n", pktlen, len);
563 562 goto fail;
564 563 }
565 564
566 565 if ((m = allocb(pktlen, BPRI_MED)) == NULL) {
567 566 ral_debug(RAL_DBG_ERR,
568 567 "rum_rxeof(): allocate mblk failed.\n");
569 568 sc->sc_rx_nobuf++;
570 569 goto fail;
571 570 }
572 571
573 572 bcopy(rxbuf + RT2573_RX_DESC_SIZE, m->b_rptr, pktlen);
574 573 m->b_wptr += pktlen;
575 574
576 575 wh = (struct ieee80211_frame *)m->b_rptr;
577 576 ni = ieee80211_find_rxnode(ic, wh);
578 577
579 578 /* send the frame to the 802.11 layer */
580 579 (void) ieee80211_input(ic, m, ni, desc->rssi, 0);
581 580
582 581 /* node is no longer needed */
583 582 ieee80211_free_node(ni);
584 583
585 584 fail:
586 585 mutex_enter(&sc->rx_lock);
587 586 sc->rx_queued--;
588 587 mutex_exit(&sc->rx_lock);
589 588
590 589 freemsg(mp);
591 590 usb_free_bulk_req(req);
592 591
593 592 if (RAL_IS_RUNNING(sc))
594 593 (void) rum_rx_trigger(sc);
595 594 }
596 595
597 596 /*
598 597 * Return the expected ack rate for a frame transmitted at rate `rate'.
599 598 */
600 599 static int
601 600 rum_ack_rate(struct ieee80211com *ic, int rate)
602 601 {
603 602 switch (rate) {
604 603 /* CCK rates */
605 604 case 2:
606 605 return (2);
607 606 case 4:
608 607 case 11:
609 608 case 22:
610 609 return ((ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate);
611 610
612 611 /* OFDM rates */
613 612 case 12:
614 613 case 18:
615 614 return (12);
616 615 case 24:
617 616 case 36:
618 617 return (24);
619 618 case 48:
620 619 case 72:
621 620 case 96:
622 621 case 108:
623 622 return (48);
624 623 }
625 624
626 625 /* default to 1Mbps */
627 626 return (2);
628 627 }
629 628
630 629 /*
631 630 * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'.
632 631 * The function automatically determines the operating mode depending on the
633 632 * given rate. `flags' indicates whether short preamble is in use or not.
634 633 */
635 634 static uint16_t
636 635 rum_txtime(int len, int rate, uint32_t flags)
637 636 {
638 637 uint16_t txtime;
639 638
640 639 if (RUM_RATE_IS_OFDM(rate)) {
641 640 /* IEEE Std 802.11a-1999, pp. 37 */
642 641 txtime = (8 + 4 * len + 3 + rate - 1) / rate;
643 642 txtime = 16 + 4 + 4 * txtime + 6;
644 643 } else {
645 644 /* IEEE Std 802.11b-1999, pp. 28 */
646 645 txtime = (16 * len + rate - 1) / rate;
647 646 if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE))
648 647 txtime += 72 + 24;
649 648 else
650 649 txtime += 144 + 48;
651 650 }
652 651 return (txtime);
653 652 }
654 653
655 654 static uint8_t
656 655 rum_plcp_signal(int rate)
657 656 {
658 657 switch (rate) {
659 658 /* CCK rates (returned values are device-dependent) */
660 659 case 2: return (0x0);
661 660 case 4: return (0x1);
662 661 case 11: return (0x2);
663 662 case 22: return (0x3);
664 663
665 664 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
666 665 case 12: return (0xb);
667 666 case 18: return (0xf);
668 667 case 24: return (0xa);
669 668 case 36: return (0xe);
670 669 case 48: return (0x9);
671 670 case 72: return (0xd);
672 671 case 96: return (0x8);
673 672 case 108: return (0xc);
674 673
675 674 /* unsupported rates (should not get there) */
676 675 default: return (0xff);
677 676 }
678 677 }
679 678
680 679 static void
681 680 rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc,
682 681 uint32_t flags, uint16_t xflags, int len, int rate)
683 682 {
684 683 struct ieee80211com *ic = &sc->sc_ic;
685 684 uint16_t plcp_length;
686 685 int remainder;
687 686
688 687 desc->flags = LE_32(flags);
689 688 desc->flags |= LE_32(RT2573_TX_VALID);
690 689 desc->flags |= LE_32(len << 16);
691 690
692 691 desc->xflags = LE_16(xflags);
693 692
694 693 desc->wme = LE_16(RT2573_QID(0) | RT2573_AIFSN(2) |
695 694 RT2573_LOGCWMIN(4) | RT2573_LOGCWMAX(10));
696 695
697 696 /* setup PLCP fields */
698 697 desc->plcp_signal = rum_plcp_signal(rate);
699 698 desc->plcp_service = 4;
700 699
701 700 len += IEEE80211_CRC_LEN;
702 701 if (RUM_RATE_IS_OFDM(rate)) {
703 702 desc->flags |= LE_32(RT2573_TX_OFDM);
704 703
705 704 plcp_length = len & 0xfff;
706 705 desc->plcp_length_hi = plcp_length >> 6;
707 706 desc->plcp_length_lo = plcp_length & 0x3f;
708 707 } else {
709 708 plcp_length = (16 * len + rate - 1) / rate;
710 709 if (rate == 22) {
711 710 remainder = (16 * len) % 22;
712 711 if (remainder != 0 && remainder < 7)
713 712 desc->plcp_service |= RT2573_PLCP_LENGEXT;
714 713 }
715 714 desc->plcp_length_hi = plcp_length >> 8;
716 715 desc->plcp_length_lo = plcp_length & 0xff;
717 716
718 717 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
719 718 desc->plcp_signal |= 0x08;
720 719 }
721 720 }
722 721
723 722 #define RUM_TX_TIMEOUT 5
724 723
725 724 static int
726 725 rum_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type)
727 726 {
728 727 struct rum_softc *sc = (struct rum_softc *)ic;
729 728 struct rum_tx_desc *desc;
730 729
731 730 struct ieee80211_frame *wh;
732 731 struct ieee80211_key *k;
733 732
734 733 uint16_t dur;
735 734 uint32_t flags = 0;
736 735 int rate, err = DDI_SUCCESS, rv;
737 736
738 737 struct ieee80211_node *ni = NULL;
739 738 mblk_t *m, *m0;
740 739 int off, mblen, pktlen, xferlen;
741 740
742 741 /* discard packets while suspending or not inited */
743 742 if (!RAL_IS_RUNNING(sc)) {
744 743 freemsg(mp);
745 744 return (ENXIO);
746 745 }
747 746
748 747 mutex_enter(&sc->tx_lock);
749 748
750 749 if (sc->tx_queued > RAL_TX_LIST_COUNT) {
751 750 ral_debug(RAL_DBG_TX, "rum_send(): "
752 751 "no TX buffer available!\n");
753 752 if ((type & IEEE80211_FC0_TYPE_MASK) ==
754 753 IEEE80211_FC0_TYPE_DATA) {
755 754 sc->sc_need_sched = 1;
756 755 }
757 756 sc->sc_tx_nobuf++;
758 757 err = ENOMEM;
759 758 goto fail;
760 759 }
761 760
762 761 m = allocb(RAL_TXBUF_SIZE + RT2573_TX_DESC_SIZE, BPRI_MED);
763 762 if (m == NULL) {
764 763 ral_debug(RAL_DBG_ERR, "rum_send(): can't alloc mblk.\n");
765 764 err = DDI_FAILURE;
766 765 goto fail;
767 766 }
768 767
769 768 m->b_rptr += RT2573_TX_DESC_SIZE; /* skip TX descriptor */
770 769 m->b_wptr += RT2573_TX_DESC_SIZE;
771 770
772 771 for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) {
773 772 mblen = (uintptr_t)m0->b_wptr - (uintptr_t)m0->b_rptr;
774 773 (void) memcpy(m->b_rptr + off, m0->b_rptr, mblen);
775 774 off += mblen;
776 775 }
777 776 m->b_wptr += off;
778 777
779 778 wh = (struct ieee80211_frame *)m->b_rptr;
780 779
781 780 ni = ieee80211_find_txnode(ic, wh->i_addr1);
782 781 if (ni == NULL) {
783 782 err = DDI_FAILURE;
784 783 sc->sc_tx_err++;
785 784 freemsg(m);
786 785 goto fail;
787 786 }
788 787
789 788 if ((type & IEEE80211_FC0_TYPE_MASK) ==
790 789 IEEE80211_FC0_TYPE_DATA) {
791 790 (void) ieee80211_encap(ic, m, ni);
792 791 }
793 792
794 793 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
795 794 k = ieee80211_crypto_encap(ic, m);
796 795 if (k == NULL) {
797 796 sc->sc_tx_err++;
798 797 err = DDI_FAILURE;
799 798 freemsg(m);
800 799 goto fail;
801 800 }
802 801 /* packet header may have moved, reset our local pointer */
803 802 wh = (struct ieee80211_frame *)m->b_rptr;
804 803 }
805 804
806 805 m->b_rptr -= RT2573_TX_DESC_SIZE; /* restore */
807 806 desc = (struct rum_tx_desc *)m->b_rptr;
808 807
809 808 if ((type & IEEE80211_FC0_TYPE_MASK) ==
810 809 IEEE80211_FC0_TYPE_DATA) { /* DATA */
811 810 if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
812 811 rate = ic->ic_bss->in_rates.ir_rates[ic->ic_fixed_rate];
813 812 else
814 813 rate = ni->in_rates.ir_rates[ni->in_txrate];
815 814
816 815 rate &= IEEE80211_RATE_VAL;
817 816 if (rate <= 0) {
818 817 rate = 2; /* basic rate */
819 818 }
820 819
821 820
822 821 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
823 822 flags |= RT2573_TX_NEED_ACK;
824 823 flags |= RT2573_TX_MORE_FRAG;
825 824
826 825 dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate),
827 826 ic->ic_flags) + sc->sifs;
828 827 *(uint16_t *)(uintptr_t)wh->i_dur = LE_16(dur);
829 828 }
830 829 } else { /* MGMT */
831 830 rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
832 831
833 832 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
834 833 flags |= RT2573_TX_NEED_ACK;
835 834
836 835 dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate),
837 836 ic->ic_flags) + sc->sifs;
838 837 *(uint16_t *)(uintptr_t)wh->i_dur = LE_16(dur);
839 838
840 839 /* tell hardware to add timestamp for probe responses */
841 840 if ((wh->i_fc[0] &
842 841 (IEEE80211_FC0_TYPE_MASK |
843 842 IEEE80211_FC0_SUBTYPE_MASK)) ==
844 843 (IEEE80211_FC0_TYPE_MGT |
845 844 IEEE80211_FC0_SUBTYPE_PROBE_RESP))
846 845 flags |= RT2573_TX_TIMESTAMP;
847 846 }
848 847 }
849 848
850 849 pktlen = msgdsize(m) - RT2573_TX_DESC_SIZE;
851 850 rum_setup_tx_desc(sc, desc, flags, 0, pktlen, rate);
852 851
853 852 /* align end on a 4-bytes boundary */
854 853 xferlen = (RT2573_TX_DESC_SIZE + pktlen + 3) & ~3;
855 854
856 855 /*
857 856 * No space left in the last URB to store the extra 4 bytes, force
858 857 * sending of another URB.
859 858 */
860 859 if ((xferlen % 64) == 0)
861 860 xferlen += 4;
862 861
863 862 m->b_wptr = m->b_rptr + xferlen;
864 863
865 864 ral_debug(RAL_DBG_TX, "sending data frame len=%u rate=%u xfer len=%u\n",
866 865 pktlen, rate, xferlen);
867 866
868 867 rv = rum_tx_trigger(sc, m);
869 868
870 869 if (rv == 0) {
871 870 ic->ic_stats.is_tx_frags++;
872 871 ic->ic_stats.is_tx_bytes += pktlen;
873 872 }
874 873
875 874 fail:
876 875 if (ni != NULL)
877 876 ieee80211_free_node(ni);
878 877
879 878 if ((type & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA ||
880 879 err == 0) {
881 880 freemsg(mp);
882 881 }
883 882
884 883 mutex_exit(&sc->tx_lock);
885 884
886 885 return (err);
887 886 }
888 887
889 888 static mblk_t *
890 889 rum_m_tx(void *arg, mblk_t *mp)
891 890 {
892 891 struct rum_softc *sc = (struct rum_softc *)arg;
893 892 struct ieee80211com *ic = &sc->sc_ic;
894 893 mblk_t *next;
895 894
896 895 /*
897 896 * No data frames go out unless we're associated; this
898 897 * should not happen as the 802.11 layer does not enable
899 898 * the xmit queue until we enter the RUN state.
900 899 */
901 900 if (ic->ic_state != IEEE80211_S_RUN) {
902 901 ral_debug(RAL_DBG_ERR, "rum_m_tx(): "
903 902 "discard, state %u\n", ic->ic_state);
904 903 freemsgchain(mp);
905 904 return (NULL);
906 905 }
907 906
908 907 while (mp != NULL) {
909 908 next = mp->b_next;
910 909 mp->b_next = NULL;
911 910 if (rum_send(ic, mp, IEEE80211_FC0_TYPE_DATA) != DDI_SUCCESS) {
912 911 mp->b_next = next;
913 912 freemsgchain(mp);
914 913 return (NULL);
915 914 }
916 915 mp = next;
917 916 }
918 917 return (mp);
919 918 }
920 919
921 920 static void
922 921 rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val)
923 922 {
924 923 uint32_t tmp;
925 924 int ntries;
926 925
927 926 for (ntries = 0; ntries < 5; ntries++) {
928 927 if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
929 928 break;
930 929 }
931 930 if (ntries == 5) {
932 931 ral_debug(RAL_DBG_ERR,
933 932 "rum_bbp_write(): could not write to BBP\n");
934 933 return;
935 934 }
936 935
937 936 tmp = RT2573_BBP_BUSY | (reg & 0x7f) << 8 | val;
938 937 rum_write(sc, RT2573_PHY_CSR3, tmp);
939 938 }
940 939
941 940 static uint8_t
942 941 rum_bbp_read(struct rum_softc *sc, uint8_t reg)
943 942 {
944 943 uint32_t val;
945 944 int ntries;
946 945
947 946 for (ntries = 0; ntries < 5; ntries++) {
948 947 if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
949 948 break;
950 949 }
951 950 if (ntries == 5) {
952 951 ral_debug(RAL_DBG_ERR, "rum_bbp_read(): could not read BBP\n");
953 952 return (0);
954 953 }
955 954
956 955 val = RT2573_BBP_BUSY | RT2573_BBP_READ | reg << 8;
957 956 rum_write(sc, RT2573_PHY_CSR3, val);
958 957
959 958 for (ntries = 0; ntries < 100; ntries++) {
960 959 val = rum_read(sc, RT2573_PHY_CSR3);
961 960 if (!(val & RT2573_BBP_BUSY))
962 961 return (val & 0xff);
963 962 drv_usecwait(1);
964 963 }
965 964
966 965 ral_debug(RAL_DBG_ERR, "rum_bbp_read(): could not read BBP\n");
967 966 return (0);
968 967 }
969 968
970 969 static void
971 970 rum_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val)
972 971 {
973 972 uint32_t tmp;
974 973 int ntries;
975 974
976 975 for (ntries = 0; ntries < 5; ntries++) {
977 976 if (!(rum_read(sc, RT2573_PHY_CSR4) & RT2573_RF_BUSY))
978 977 break;
979 978 }
980 979 if (ntries == 5) {
981 980 ral_debug(RAL_DBG_ERR,
982 981 "rum_rf_write(): could not write to RF\n");
983 982 return;
984 983 }
985 984
986 985 tmp = RT2573_RF_BUSY | RT2573_RF_20BIT | (val & 0xfffff) << 2 |
987 986 (reg & 3);
988 987 rum_write(sc, RT2573_PHY_CSR4, tmp);
989 988
990 989 /* remember last written value in sc */
991 990 sc->rf_regs[reg] = val;
992 991
993 992 ral_debug(RAL_DBG_HW, "RF R[%u] <- 0x%05x\n", reg & 3, val & 0xfffff);
994 993 }
995 994
996 995 static void
997 996 rum_select_antenna(struct rum_softc *sc)
998 997 {
999 998 uint8_t bbp4, bbp77;
1000 999 uint32_t tmp;
1001 1000
1002 1001 bbp4 = rum_bbp_read(sc, 4);
1003 1002 bbp77 = rum_bbp_read(sc, 77);
1004 1003
1005 1004 /* make sure Rx is disabled before switching antenna */
1006 1005 tmp = rum_read(sc, RT2573_TXRX_CSR0);
1007 1006 rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
1008 1007
1009 1008 rum_bbp_write(sc, 4, bbp4);
1010 1009 rum_bbp_write(sc, 77, bbp77);
1011 1010
1012 1011 rum_write(sc, RT2573_TXRX_CSR0, tmp);
1013 1012 }
1014 1013
1015 1014 /*
1016 1015 * Enable multi-rate retries for frames sent at OFDM rates.
1017 1016 * In 802.11b/g mode, allow fallback to CCK rates.
1018 1017 */
1019 1018 static void
1020 1019 rum_enable_mrr(struct rum_softc *sc)
1021 1020 {
1022 1021 struct ieee80211com *ic = &sc->sc_ic;
1023 1022 uint32_t tmp;
1024 1023
1025 1024 tmp = rum_read(sc, RT2573_TXRX_CSR4);
1026 1025
1027 1026 tmp &= ~RT2573_MRR_CCK_FALLBACK;
1028 1027 if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
1029 1028 tmp |= RT2573_MRR_CCK_FALLBACK;
1030 1029 tmp |= RT2573_MRR_ENABLED;
1031 1030
1032 1031 rum_write(sc, RT2573_TXRX_CSR4, tmp);
1033 1032 }
1034 1033
1035 1034 static void
1036 1035 rum_set_txpreamble(struct rum_softc *sc)
1037 1036 {
1038 1037 uint32_t tmp;
1039 1038
1040 1039 tmp = rum_read(sc, RT2573_TXRX_CSR4);
1041 1040
1042 1041 tmp &= ~RT2573_SHORT_PREAMBLE;
1043 1042 if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE)
1044 1043 tmp |= RT2573_SHORT_PREAMBLE;
1045 1044
1046 1045 rum_write(sc, RT2573_TXRX_CSR4, tmp);
1047 1046 }
1048 1047
1049 1048 static void
1050 1049 rum_set_basicrates(struct rum_softc *sc)
1051 1050 {
1052 1051 struct ieee80211com *ic = &sc->sc_ic;
1053 1052
1054 1053 /* update basic rate set */
1055 1054 if (ic->ic_curmode == IEEE80211_MODE_11B) {
1056 1055 /* 11b basic rates: 1, 2Mbps */
1057 1056 rum_write(sc, RT2573_TXRX_CSR5, 0x3);
1058 1057 } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->in_chan)) {
1059 1058 /* 11a basic rates: 6, 12, 24Mbps */
1060 1059 rum_write(sc, RT2573_TXRX_CSR5, 0x150);
1061 1060 } else {
1062 1061 /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
1063 1062 rum_write(sc, RT2573_TXRX_CSR5, 0xf);
1064 1063 }
1065 1064 }
1066 1065
1067 1066 /*
1068 1067 * Reprogram MAC/BBP to switch to a new band. Values taken from the reference
1069 1068 * driver.
1070 1069 */
1071 1070 static void
1072 1071 rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c)
1073 1072 {
1074 1073 uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
1075 1074 uint32_t tmp;
1076 1075
1077 1076 /* update all BBP registers that depend on the band */
1078 1077 bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c;
1079 1078 bbp35 = 0x50; bbp97 = 0x48; bbp98 = 0x48;
1080 1079 if (IEEE80211_IS_CHAN_5GHZ(c)) {
1081 1080 bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c;
1082 1081 bbp35 += 0x10; bbp97 += 0x10; bbp98 += 0x10;
1083 1082 }
1084 1083 if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
1085 1084 (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
1086 1085 bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10;
1087 1086 }
1088 1087
1089 1088 sc->bbp17 = bbp17;
1090 1089 rum_bbp_write(sc, 17, bbp17);
1091 1090 rum_bbp_write(sc, 96, bbp96);
1092 1091 rum_bbp_write(sc, 104, bbp104);
1093 1092
1094 1093 if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
1095 1094 (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
1096 1095 rum_bbp_write(sc, 75, 0x80);
1097 1096 rum_bbp_write(sc, 86, 0x80);
1098 1097 rum_bbp_write(sc, 88, 0x80);
1099 1098 }
1100 1099
1101 1100 rum_bbp_write(sc, 35, bbp35);
1102 1101 rum_bbp_write(sc, 97, bbp97);
1103 1102 rum_bbp_write(sc, 98, bbp98);
1104 1103
1105 1104 tmp = rum_read(sc, RT2573_PHY_CSR0);
1106 1105 tmp &= ~(RT2573_PA_PE_2GHZ | RT2573_PA_PE_5GHZ);
1107 1106 if (IEEE80211_IS_CHAN_2GHZ(c))
1108 1107 tmp |= RT2573_PA_PE_2GHZ;
1109 1108 else
1110 1109 tmp |= RT2573_PA_PE_5GHZ;
1111 1110 rum_write(sc, RT2573_PHY_CSR0, tmp);
1112 1111
1113 1112 /* 802.11a uses a 16 microseconds short interframe space */
1114 1113 sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10;
1115 1114 }
1116 1115
1117 1116 static void
1118 1117 rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c)
1119 1118 {
1120 1119 struct ieee80211com *ic = &sc->sc_ic;
1121 1120 const struct rfprog *rfprog;
1122 1121 uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT;
1123 1122 int8_t power;
1124 1123 uint_t i, chan;
1125 1124
1126 1125 chan = ieee80211_chan2ieee(ic, c);
1127 1126 if (chan == 0 || chan == IEEE80211_CHAN_ANY)
1128 1127 return;
1129 1128
1130 1129 /* select the appropriate RF settings based on what EEPROM says */
1131 1130 rfprog = (sc->rf_rev == RT2573_RF_5225 ||
1132 1131 sc->rf_rev == RT2573_RF_2527) ? rum_rf5225 : rum_rf5226;
1133 1132
1134 1133 /* find the settings for this channel (we know it exists) */
1135 1134 for (i = 0; rfprog[i].chan != chan; i++) {
1136 1135 }
1137 1136
1138 1137 power = sc->txpow[i];
1139 1138 if (power < 0) {
1140 1139 bbp94 += power;
1141 1140 power = 0;
1142 1141 } else if (power > 31) {
1143 1142 bbp94 += power - 31;
1144 1143 power = 31;
1145 1144 }
1146 1145
1147 1146 /*
1148 1147 * If we are switching from the 2GHz band to the 5GHz band or
1149 1148 * vice-versa, BBP registers need to be reprogrammed.
1150 1149 */
1151 1150 if (c->ich_flags != ic->ic_curchan->ich_flags) {
1152 1151 rum_select_band(sc, c);
1153 1152 rum_select_antenna(sc);
1154 1153 }
1155 1154 ic->ic_curchan = c;
1156 1155
1157 1156 rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1158 1157 rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1159 1158 rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
1160 1159 rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1161 1160
1162 1161 rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1163 1162 rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1164 1163 rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7 | 1);
1165 1164 rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1166 1165
1167 1166 rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1168 1167 rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1169 1168 rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
1170 1169 rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1171 1170
1172 1171 drv_usecwait(10);
1173 1172
1174 1173 /* enable smart mode for MIMO-capable RFs */
1175 1174 bbp3 = rum_bbp_read(sc, 3);
1176 1175
1177 1176 bbp3 &= ~RT2573_SMART_MODE;
1178 1177 if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_2527)
1179 1178 bbp3 |= RT2573_SMART_MODE;
1180 1179
1181 1180 rum_bbp_write(sc, 3, bbp3);
1182 1181
1183 1182 if (bbp94 != RT2573_BBPR94_DEFAULT)
1184 1183 rum_bbp_write(sc, 94, bbp94);
1185 1184 }
1186 1185
1187 1186 /*
1188 1187 * Enable TSF synchronization and tell h/w to start sending beacons for IBSS
1189 1188 * and HostAP operating modes.
1190 1189 */
1191 1190 static void
1192 1191 rum_enable_tsf_sync(struct rum_softc *sc)
1193 1192 {
1194 1193 struct ieee80211com *ic = &sc->sc_ic;
1195 1194 uint32_t tmp;
1196 1195
1197 1196 if (ic->ic_opmode != IEEE80211_M_STA) {
1198 1197 /*
1199 1198 * Change default 16ms TBTT adjustment to 8ms.
1200 1199 * Must be done before enabling beacon generation.
1201 1200 */
1202 1201 rum_write(sc, RT2573_TXRX_CSR10, 1 << 12 | 8);
1203 1202 }
1204 1203
1205 1204 tmp = rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000;
1206 1205
1207 1206 /* set beacon interval (in 1/16ms unit) */
1208 1207 tmp |= ic->ic_bss->in_intval * 16;
1209 1208
1210 1209 tmp |= RT2573_TSF_TICKING | RT2573_ENABLE_TBTT;
1211 1210 if (ic->ic_opmode == IEEE80211_M_STA)
1212 1211 tmp |= RT2573_TSF_MODE(1);
1213 1212 else
1214 1213 tmp |= RT2573_TSF_MODE(2) | RT2573_GENERATE_BEACON;
1215 1214
1216 1215 rum_write(sc, RT2573_TXRX_CSR9, tmp);
1217 1216 }
1218 1217
1219 1218 /* ARGSUSED */
1220 1219 static void
1221 1220 rum_update_slot(struct ieee80211com *ic, int onoff)
1222 1221 {
1223 1222 struct rum_softc *sc = (struct rum_softc *)ic;
1224 1223 uint8_t slottime;
1225 1224 uint32_t tmp;
1226 1225
1227 1226 slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
1228 1227
1229 1228 tmp = rum_read(sc, RT2573_MAC_CSR9);
1230 1229 tmp = (tmp & ~0xff) | slottime;
1231 1230 rum_write(sc, RT2573_MAC_CSR9, tmp);
1232 1231
1233 1232 ral_debug(RAL_DBG_HW, "setting slot time to %uus\n", slottime);
1234 1233 }
1235 1234
1236 1235 static void
1237 1236 rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid)
1238 1237 {
1239 1238 uint32_t tmp;
1240 1239
1241 1240 tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24;
1242 1241 rum_write(sc, RT2573_MAC_CSR4, tmp);
1243 1242
1244 1243 tmp = bssid[4] | bssid[5] << 8 | RT2573_ONE_BSSID << 16;
1245 1244 rum_write(sc, RT2573_MAC_CSR5, tmp);
1246 1245 }
1247 1246
1248 1247 static void
1249 1248 rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr)
1250 1249 {
1251 1250 uint32_t tmp;
1252 1251
1253 1252 tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24;
1254 1253 rum_write(sc, RT2573_MAC_CSR2, tmp);
1255 1254
1256 1255 tmp = addr[4] | addr[5] << 8 | 0xff << 16;
1257 1256 rum_write(sc, RT2573_MAC_CSR3, tmp);
1258 1257
1259 1258 ral_debug(RAL_DBG_HW,
1260 1259 "setting MAC address to " MACSTR "\n", MAC2STR(addr));
1261 1260 }
1262 1261
1263 1262 static void
1264 1263 rum_update_promisc(struct rum_softc *sc)
1265 1264 {
1266 1265 uint32_t tmp;
1267 1266
1268 1267 tmp = rum_read(sc, RT2573_TXRX_CSR0);
1269 1268
1270 1269 tmp &= ~RT2573_DROP_NOT_TO_ME;
1271 1270 if (!(sc->sc_rcr & RAL_RCR_PROMISC))
1272 1271 tmp |= RT2573_DROP_NOT_TO_ME;
1273 1272
1274 1273 rum_write(sc, RT2573_TXRX_CSR0, tmp);
1275 1274
1276 1275 ral_debug(RAL_DBG_HW, "%s promiscuous mode\n",
1277 1276 (sc->sc_rcr & RAL_RCR_PROMISC) ? "entering" : "leaving");
1278 1277 }
1279 1278
1280 1279 static const char *
1281 1280 rum_get_rf(int rev)
1282 1281 {
1283 1282 switch (rev) {
1284 1283 case RT2573_RF_2527: return ("RT2527 (MIMO XR)");
1285 1284 case RT2573_RF_2528: return ("RT2528");
1286 1285 case RT2573_RF_5225: return ("RT5225 (MIMO XR)");
1287 1286 case RT2573_RF_5226: return ("RT5226");
1288 1287 default: return ("unknown");
1289 1288 }
1290 1289 }
1291 1290
1292 1291 static void
1293 1292 rum_read_eeprom(struct rum_softc *sc)
1294 1293 {
1295 1294 struct ieee80211com *ic = &sc->sc_ic;
1296 1295 uint16_t val;
1297 1296
1298 1297 /* read MAC address */
1299 1298 rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, ic->ic_macaddr, 6);
1300 1299
1301 1300 rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2);
1302 1301 val = LE_16(val);
1303 1302 sc->rf_rev = (val >> 11) & 0x1f;
1304 1303 sc->hw_radio = (val >> 10) & 0x1;
1305 1304 sc->rx_ant = (val >> 4) & 0x3;
1306 1305 sc->tx_ant = (val >> 2) & 0x3;
1307 1306 sc->nb_ant = val & 0x3;
1308 1307
1309 1308 ral_debug(RAL_DBG_HW, "RF revision=%d\n", sc->rf_rev);
1310 1309
1311 1310 rum_eeprom_read(sc, RT2573_EEPROM_CONFIG2, &val, 2);
1312 1311 val = LE_16(val);
1313 1312 sc->ext_5ghz_lna = (val >> 6) & 0x1;
1314 1313 sc->ext_2ghz_lna = (val >> 4) & 0x1;
1315 1314
1316 1315 ral_debug(RAL_DBG_HW, "External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n",
1317 1316 sc->ext_2ghz_lna, sc->ext_5ghz_lna);
1318 1317
1319 1318 rum_eeprom_read(sc, RT2573_EEPROM_RSSI_2GHZ_OFFSET, &val, 2);
1320 1319 val = LE_16(val);
1321 1320 if ((val & 0xff) != 0xff)
1322 1321 sc->rssi_2ghz_corr = (int8_t)(val & 0xff); /* signed */
1323 1322
1324 1323 rum_eeprom_read(sc, RT2573_EEPROM_RSSI_5GHZ_OFFSET, &val, 2);
1325 1324 val = LE_16(val);
1326 1325 if ((val & 0xff) != 0xff)
1327 1326 sc->rssi_5ghz_corr = (int8_t)(val & 0xff); /* signed */
1328 1327
1329 1328 ral_debug(RAL_DBG_HW, "RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n",
1330 1329 sc->rssi_2ghz_corr, sc->rssi_5ghz_corr);
1331 1330
1332 1331 rum_eeprom_read(sc, RT2573_EEPROM_FREQ_OFFSET, &val, 2);
1333 1332 val = LE_16(val);
1334 1333 if ((val & 0xff) != 0xff)
1335 1334 sc->rffreq = val & 0xff;
1336 1335
1337 1336 ral_debug(RAL_DBG_HW, "RF freq=%d\n", sc->rffreq);
1338 1337
1339 1338 /* read Tx power for all a/b/g channels */
1340 1339 rum_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->txpow, 14);
1341 1340 /* default Tx power for 802.11a channels */
1342 1341 (void) memset(sc->txpow + 14, 24, sizeof (sc->txpow) - 14);
1343 1342
1344 1343 /* read default values for BBP registers */
1345 1344 rum_eeprom_read(sc, RT2573_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16);
1346 1345 }
1347 1346
1348 1347 static int
1349 1348 rum_bbp_init(struct rum_softc *sc)
1350 1349 {
1351 1350 int i, ntries;
1352 1351
1353 1352 /* wait for BBP to be ready */
1354 1353 for (ntries = 0; ntries < 100; ntries++) {
1355 1354 const uint8_t val = rum_bbp_read(sc, 0);
1356 1355 if (val != 0 && val != 0xff)
1357 1356 break;
1358 1357 drv_usecwait(1000);
1359 1358 }
1360 1359 if (ntries == 100) {
1361 1360 ral_debug(RAL_DBG_ERR, "timeout waiting for BBP\n");
1362 1361 return (EIO);
1363 1362 }
1364 1363
1365 1364 /* initialize BBP registers to default values */
1366 1365 for (i = 0; i < RUM_N(rum_def_bbp); i++)
1367 1366 rum_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val);
1368 1367
1369 1368 /* write vendor-specific BBP values (from EEPROM) */
1370 1369 for (i = 0; i < 16; i++) {
1371 1370 if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
1372 1371 continue;
1373 1372 rum_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
1374 1373 }
1375 1374
1376 1375 return (0);
1377 1376 }
1378 1377
1379 1378 /*
1380 1379 * This function is called periodically (every 200ms) during scanning to
1381 1380 * switch from one channel to another.
1382 1381 */
1383 1382 static void
1384 1383 rum_next_scan(void *arg)
1385 1384 {
1386 1385 struct rum_softc *sc = arg;
1387 1386 struct ieee80211com *ic = &sc->sc_ic;
1388 1387
1389 1388 if (ic->ic_state == IEEE80211_S_SCAN)
1390 1389 ieee80211_next_scan(ic);
1391 1390 }
1392 1391
1393 1392 static int
1394 1393 rum_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1395 1394 {
1396 1395 struct rum_softc *sc = (struct rum_softc *)ic;
1397 1396 enum ieee80211_state ostate;
1398 1397 struct ieee80211_node *ni;
1399 1398 int err;
1400 1399 uint32_t tmp;
1401 1400
1402 1401 RAL_LOCK(sc);
1403 1402
1404 1403 ostate = ic->ic_state;
1405 1404
1406 1405 if (sc->sc_scan_id != 0) {
1407 1406 (void) untimeout(sc->sc_scan_id);
1408 1407 sc->sc_scan_id = 0;
1409 1408 }
1410 1409
1411 1410 if (sc->sc_amrr_id != 0) {
1412 1411 (void) untimeout(sc->sc_amrr_id);
1413 1412 sc->sc_amrr_id = 0;
1414 1413 }
1415 1414
1416 1415 switch (nstate) {
1417 1416 case IEEE80211_S_INIT:
1418 1417 if (ostate == IEEE80211_S_RUN) {
1419 1418 /* abort TSF synchronization */
1420 1419 tmp = rum_read(sc, RT2573_TXRX_CSR9);
1421 1420 rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff);
1422 1421 }
1423 1422 break;
1424 1423
1425 1424 case IEEE80211_S_SCAN:
1426 1425 rum_set_chan(sc, ic->ic_curchan);
1427 1426 sc->sc_scan_id = timeout(rum_next_scan, (void *)sc,
1428 1427 drv_usectohz(sc->dwelltime * 1000));
1429 1428 break;
1430 1429
1431 1430 case IEEE80211_S_AUTH:
1432 1431 rum_set_chan(sc, ic->ic_curchan);
1433 1432 break;
1434 1433
1435 1434 case IEEE80211_S_ASSOC:
1436 1435 rum_set_chan(sc, ic->ic_curchan);
1437 1436 break;
1438 1437
1439 1438 case IEEE80211_S_RUN:
1440 1439 rum_set_chan(sc, ic->ic_curchan);
1441 1440
1442 1441 ni = ic->ic_bss;
1443 1442
1444 1443 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
1445 1444 rum_update_slot(ic, 1);
1446 1445 rum_enable_mrr(sc);
1447 1446 rum_set_txpreamble(sc);
1448 1447 rum_set_basicrates(sc);
1449 1448 rum_set_bssid(sc, ni->in_bssid);
1450 1449 }
1451 1450
1452 1451 if (ic->ic_opmode != IEEE80211_M_MONITOR)
1453 1452 rum_enable_tsf_sync(sc);
1454 1453
1455 1454 /* enable automatic rate adaptation in STA mode */
1456 1455 if (ic->ic_opmode == IEEE80211_M_STA &&
1457 1456 ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE)
1458 1457 rum_amrr_start(sc, ni);
1459 1458 break;
1460 1459 }
1461 1460
1462 1461 RAL_UNLOCK(sc);
1463 1462
1464 1463 err = sc->sc_newstate(ic, nstate, arg);
1465 1464 /*
1466 1465 * Finally, start any timers.
1467 1466 */
1468 1467 if (nstate == IEEE80211_S_RUN)
1469 1468 ieee80211_start_watchdog(ic, 1);
1470 1469
1471 1470 return (err);
1472 1471 }
1473 1472
1474 1473 static void
1475 1474 rum_close_pipes(struct rum_softc *sc)
1476 1475 {
1477 1476 usb_flags_t flags = USB_FLAGS_SLEEP;
1478 1477
1479 1478 if (sc->sc_rx_pipeh != NULL) {
1480 1479 usb_pipe_reset(sc->sc_dev, sc->sc_rx_pipeh, flags, NULL, 0);
1481 1480 usb_pipe_close(sc->sc_dev, sc->sc_rx_pipeh, flags, NULL, 0);
1482 1481 sc->sc_rx_pipeh = NULL;
1483 1482 }
1484 1483
1485 1484 if (sc->sc_tx_pipeh != NULL) {
1486 1485 usb_pipe_reset(sc->sc_dev, sc->sc_tx_pipeh, flags, NULL, 0);
1487 1486 usb_pipe_close(sc->sc_dev, sc->sc_tx_pipeh, flags, NULL, 0);
1488 1487 sc->sc_tx_pipeh = NULL;
1489 1488 }
1490 1489 }
1491 1490
1492 1491 static int
1493 1492 rum_open_pipes(struct rum_softc *sc)
1494 1493 {
1495 1494 usb_ep_data_t *ep_node;
1496 1495 usb_pipe_policy_t policy;
1497 1496 int err;
1498 1497
1499 1498 ep_node = usb_lookup_ep_data(sc->sc_dev, sc->sc_udev, 0, 0, 0,
1500 1499 USB_EP_ATTR_BULK, USB_EP_DIR_OUT);
1501 1500
1502 1501 bzero(&policy, sizeof (usb_pipe_policy_t));
1503 1502 policy.pp_max_async_reqs = RAL_TX_LIST_COUNT;
1504 1503
1505 1504 if ((err = usb_pipe_open(sc->sc_dev,
1506 1505 &ep_node->ep_descr, &policy, USB_FLAGS_SLEEP,
1507 1506 &sc->sc_tx_pipeh)) != USB_SUCCESS) {
1508 1507 ral_debug(RAL_DBG_ERR,
1509 1508 "rum_open_pipes(): %x failed to open tx pipe\n", err);
1510 1509 goto fail;
1511 1510 }
1512 1511
1513 1512 ep_node = usb_lookup_ep_data(sc->sc_dev, sc->sc_udev, 0, 0, 0,
1514 1513 USB_EP_ATTR_BULK, USB_EP_DIR_IN);
1515 1514
1516 1515 bzero(&policy, sizeof (usb_pipe_policy_t));
1517 1516 policy.pp_max_async_reqs = RAL_RX_LIST_COUNT + 32;
1518 1517
1519 1518 if ((err = usb_pipe_open(sc->sc_dev,
1520 1519 &ep_node->ep_descr, &policy, USB_FLAGS_SLEEP,
1521 1520 &sc->sc_rx_pipeh)) != USB_SUCCESS) {
1522 1521 ral_debug(RAL_DBG_ERR,
1523 1522 "rum_open_pipes(): %x failed to open rx pipe\n", err);
1524 1523 goto fail;
1525 1524 }
1526 1525
1527 1526 return (USB_SUCCESS);
1528 1527
1529 1528 fail:
1530 1529 if (sc->sc_rx_pipeh != NULL) {
1531 1530 usb_pipe_close(sc->sc_dev, sc->sc_rx_pipeh,
1532 1531 USB_FLAGS_SLEEP, NULL, 0);
1533 1532 sc->sc_rx_pipeh = NULL;
1534 1533 }
1535 1534
1536 1535 if (sc->sc_tx_pipeh != NULL) {
1537 1536 usb_pipe_close(sc->sc_dev, sc->sc_tx_pipeh,
1538 1537 USB_FLAGS_SLEEP, NULL, 0);
1539 1538 sc->sc_tx_pipeh = NULL;
1540 1539 }
1541 1540
1542 1541 return (USB_FAILURE);
1543 1542 }
1544 1543
1545 1544 static int
1546 1545 rum_tx_trigger(struct rum_softc *sc, mblk_t *mp)
1547 1546 {
1548 1547 usb_bulk_req_t *req;
1549 1548 int err;
1550 1549
1551 1550 sc->sc_tx_timer = RUM_TX_TIMEOUT;
1552 1551
1553 1552 req = usb_alloc_bulk_req(sc->sc_dev, 0, USB_FLAGS_SLEEP);
1554 1553 if (req == NULL) {
1555 1554 ral_debug(RAL_DBG_ERR,
1556 1555 "rum_tx_trigger(): failed to allocate req");
1557 1556 freemsg(mp);
1558 1557 return (-1);
1559 1558 }
1560 1559
1561 1560 req->bulk_len = msgdsize(mp);
1562 1561 req->bulk_data = mp;
1563 1562 req->bulk_client_private = (usb_opaque_t)sc;
1564 1563 req->bulk_timeout = RUM_TX_TIMEOUT;
1565 1564 req->bulk_attributes = USB_ATTRS_AUTOCLEARING;
1566 1565 req->bulk_cb = rum_txeof;
1567 1566 req->bulk_exc_cb = rum_txeof;
1568 1567 req->bulk_completion_reason = 0;
1569 1568 req->bulk_cb_flags = 0;
1570 1569
1571 1570 if ((err = usb_pipe_bulk_xfer(sc->sc_tx_pipeh, req, 0))
1572 1571 != USB_SUCCESS) {
1573 1572
1574 1573 ral_debug(RAL_DBG_ERR, "rum_tx_trigger(): "
1575 1574 "failed to do tx xfer, %d", err);
1576 1575 usb_free_bulk_req(req);
1577 1576 return (-1);
1578 1577 }
1579 1578
1580 1579 sc->tx_queued++;
1581 1580
1582 1581 return (0);
1583 1582 }
1584 1583
1585 1584 static int
1586 1585 rum_rx_trigger(struct rum_softc *sc)
1587 1586 {
1588 1587 usb_bulk_req_t *req;
1589 1588 int err;
1590 1589
1591 1590 req = usb_alloc_bulk_req(sc->sc_dev, RAL_RXBUF_SIZE, USB_FLAGS_SLEEP);
1592 1591 if (req == NULL) {
1593 1592 ral_debug(RAL_DBG_ERR,
1594 1593 "rum_rx_trigger(): failed to allocate req");
1595 1594 return (-1);
1596 1595 }
1597 1596
1598 1597 req->bulk_len = RAL_RXBUF_SIZE;
1599 1598 req->bulk_client_private = (usb_opaque_t)sc;
1600 1599 req->bulk_timeout = 0;
1601 1600 req->bulk_attributes = USB_ATTRS_SHORT_XFER_OK
1602 1601 | USB_ATTRS_AUTOCLEARING;
1603 1602 req->bulk_cb = rum_rxeof;
1604 1603 req->bulk_exc_cb = rum_rxeof;
1605 1604 req->bulk_completion_reason = 0;
1606 1605 req->bulk_cb_flags = 0;
1607 1606
1608 1607 err = usb_pipe_bulk_xfer(sc->sc_rx_pipeh, req, 0);
1609 1608
1610 1609 if (err != USB_SUCCESS) {
1611 1610 ral_debug(RAL_DBG_ERR, "rum_rx_trigger(): "
1612 1611 "failed to do rx xfer, %d", err);
1613 1612 usb_free_bulk_req(req);
1614 1613
1615 1614 return (-1);
1616 1615 }
1617 1616
1618 1617 mutex_enter(&sc->rx_lock);
1619 1618 sc->rx_queued++;
1620 1619 mutex_exit(&sc->rx_lock);
1621 1620
1622 1621 return (0);
1623 1622 }
1624 1623
1625 1624 static void
1626 1625 rum_init_tx_queue(struct rum_softc *sc)
1627 1626 {
1628 1627 sc->tx_queued = 0;
1629 1628 }
1630 1629
1631 1630 static int
1632 1631 rum_init_rx_queue(struct rum_softc *sc)
1633 1632 {
1634 1633 int i;
1635 1634
1636 1635 sc->rx_queued = 0;
1637 1636
1638 1637 for (i = 0; i < RAL_RX_LIST_COUNT; i++) {
1639 1638 if (rum_rx_trigger(sc) != 0) {
1640 1639 return (USB_FAILURE);
1641 1640 }
1642 1641 }
1643 1642
1644 1643 return (USB_SUCCESS);
1645 1644 }
1646 1645
1647 1646 static void
1648 1647 rum_stop(struct rum_softc *sc)
1649 1648 {
1650 1649 struct ieee80211com *ic = &sc->sc_ic;
1651 1650 uint32_t tmp;
1652 1651
1653 1652 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
1654 1653 ieee80211_stop_watchdog(ic); /* stop the watchdog */
1655 1654
1656 1655 RAL_LOCK(sc);
1657 1656
1658 1657 sc->sc_tx_timer = 0;
1659 1658 sc->sc_flags &= ~RAL_FLAG_RUNNING; /* STOP */
1660 1659
1661 1660 /* disable Rx */
1662 1661 tmp = rum_read(sc, RT2573_TXRX_CSR0);
1663 1662 rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
1664 1663
1665 1664 /* reset ASIC */
1666 1665 rum_write(sc, RT2573_MAC_CSR1, 3);
1667 1666 rum_write(sc, RT2573_MAC_CSR1, 0);
1668 1667
1669 1668 rum_close_pipes(sc);
1670 1669
1671 1670 RAL_UNLOCK(sc);
1672 1671 }
1673 1672
1674 1673 static int
1675 1674 rum_init(struct rum_softc *sc)
1676 1675 {
1677 1676 struct ieee80211com *ic = &sc->sc_ic;
1678 1677 uint32_t tmp;
1679 1678 int i, ntries;
1680 1679
1681 1680 rum_stop(sc);
1682 1681
1683 1682 /* initialize MAC registers to default values */
1684 1683 for (i = 0; i < RUM_N(rum_def_mac); i++)
1685 1684 rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val);
1686 1685
1687 1686 /* set host ready */
1688 1687 rum_write(sc, RT2573_MAC_CSR1, 3);
1689 1688 rum_write(sc, RT2573_MAC_CSR1, 0);
1690 1689
1691 1690 /* wait for BBP/RF to wakeup */
1692 1691 for (ntries = 0; ntries < 1000; ntries++) {
1693 1692 if (rum_read(sc, RT2573_MAC_CSR12) & 8)
1694 1693 break;
1695 1694 rum_write(sc, RT2573_MAC_CSR12, 4); /* force wakeup */
1696 1695 drv_usecwait(1000);
1697 1696 }
1698 1697 if (ntries == 1000) {
1699 1698 ral_debug(RAL_DBG_ERR,
1700 1699 "rum_init(): timeout waiting for BBP/RF to wakeup\n");
1701 1700 goto fail;
1702 1701 }
1703 1702
1704 1703 if (rum_bbp_init(sc) != 0)
1705 1704 goto fail;
1706 1705
1707 1706 /* select default channel */
1708 1707 rum_select_band(sc, ic->ic_curchan);
1709 1708 rum_select_antenna(sc);
1710 1709 rum_set_chan(sc, ic->ic_curchan);
1711 1710
1712 1711 /* clear STA registers */
1713 1712 rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof (sc->sta));
1714 1713
1715 1714 rum_set_macaddr(sc, ic->ic_macaddr);
1716 1715
1717 1716 /* initialize ASIC */
1718 1717 rum_write(sc, RT2573_MAC_CSR1, 4);
1719 1718
1720 1719 if (rum_open_pipes(sc) != USB_SUCCESS) {
1721 1720 ral_debug(RAL_DBG_ERR, "rum_init(): "
1722 1721 "could not open pipes.\n");
1723 1722 goto fail;
1724 1723 }
1725 1724
1726 1725 rum_init_tx_queue(sc);
1727 1726
1728 1727 if (rum_init_rx_queue(sc) != USB_SUCCESS)
1729 1728 goto fail;
1730 1729
1731 1730 /* update Rx filter */
1732 1731 tmp = rum_read(sc, RT2573_TXRX_CSR0) & 0xffff;
1733 1732 tmp |= RT2573_DROP_PHY_ERROR | RT2573_DROP_CRC_ERROR;
1734 1733 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
1735 1734 tmp |= RT2573_DROP_CTL | RT2573_DROP_VER_ERROR |
1736 1735 RT2573_DROP_ACKCTS;
1737 1736 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
1738 1737 tmp |= RT2573_DROP_TODS;
1739 1738 if (!(sc->sc_rcr & RAL_RCR_PROMISC))
1740 1739 tmp |= RT2573_DROP_NOT_TO_ME;
1741 1740 }
1742 1741
1743 1742 rum_write(sc, RT2573_TXRX_CSR0, tmp);
1744 1743 sc->sc_flags |= RAL_FLAG_RUNNING; /* RUNNING */
1745 1744
1746 1745 return (DDI_SUCCESS);
1747 1746 fail:
1748 1747 rum_stop(sc);
1749 1748 return (DDI_FAILURE);
1750 1749 }
1751 1750
1752 1751 static int
1753 1752 rum_disconnect(dev_info_t *devinfo)
1754 1753 {
1755 1754 struct rum_softc *sc;
1756 1755 struct ieee80211com *ic;
1757 1756
1758 1757 /*
1759 1758 * We can't call rum_stop() here, since the hardware is removed,
1760 1759 * we can't access the register anymore.
1761 1760 */
1762 1761 sc = ddi_get_soft_state(rum_soft_state_p, ddi_get_instance(devinfo));
1763 1762 ASSERT(sc != NULL);
1764 1763
1765 1764 if (!RAL_IS_RUNNING(sc)) /* different device or not inited */
1766 1765 return (DDI_SUCCESS);
1767 1766
1768 1767 ic = &sc->sc_ic;
1769 1768 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
1770 1769 ieee80211_stop_watchdog(ic); /* stop the watchdog */
1771 1770
1772 1771 RAL_LOCK(sc);
1773 1772
1774 1773 sc->sc_tx_timer = 0;
1775 1774 sc->sc_flags &= ~RAL_FLAG_RUNNING; /* STOP */
1776 1775
1777 1776 rum_close_pipes(sc);
1778 1777
1779 1778 RAL_UNLOCK(sc);
1780 1779
1781 1780 return (DDI_SUCCESS);
1782 1781 }
1783 1782
1784 1783 static int
1785 1784 rum_reconnect(dev_info_t *devinfo)
1786 1785 {
1787 1786 struct rum_softc *sc;
1788 1787 int err;
1789 1788
1790 1789 sc = ddi_get_soft_state(rum_soft_state_p, ddi_get_instance(devinfo));
1791 1790 ASSERT(sc != NULL);
1792 1791
1793 1792 /* check device changes after disconnect */
1794 1793 if (usb_check_same_device(sc->sc_dev, NULL, USB_LOG_L2, -1,
1795 1794 USB_CHK_BASIC | USB_CHK_CFG, NULL) != USB_SUCCESS) {
1796 1795 ral_debug(RAL_DBG_ERR, "different device connected\n");
1797 1796 return (DDI_FAILURE);
1798 1797 }
1799 1798
1800 1799 err = rum_load_microcode(sc);
1801 1800 if (err != USB_SUCCESS) {
1802 1801 ral_debug(RAL_DBG_ERR, "could not load 8051 microcode\n");
1803 1802 goto fail;
1804 1803 }
1805 1804
1806 1805 err = rum_init(sc);
1807 1806 fail:
1808 1807 return (err);
1809 1808 }
1810 1809
1811 1810 static void
1812 1811 rum_resume(struct rum_softc *sc)
1813 1812 {
1814 1813 int err;
1815 1814
1816 1815 /* check device changes after suspend */
1817 1816 if (usb_check_same_device(sc->sc_dev, NULL, USB_LOG_L2, -1,
1818 1817 USB_CHK_BASIC | USB_CHK_CFG, NULL) != USB_SUCCESS) {
1819 1818 ral_debug(RAL_DBG_ERR, "no or different device connected\n");
1820 1819 return;
1821 1820 }
1822 1821
1823 1822 err = rum_load_microcode(sc);
1824 1823 if (err != USB_SUCCESS) {
1825 1824 ral_debug(RAL_DBG_ERR, "could not load 8051 microcode\n");
1826 1825 return;
1827 1826 }
1828 1827
1829 1828 (void) rum_init(sc);
1830 1829 }
1831 1830
1832 1831 #define RUM_AMRR_MIN_SUCCESS_THRESHOLD 1
1833 1832 #define RUM_AMRR_MAX_SUCCESS_THRESHOLD 10
1834 1833
1835 1834 /*
1836 1835 * Naive implementation of the Adaptive Multi Rate Retry algorithm:
1837 1836 * "IEEE 802.11 Rate Adaptation: A Practical Approach"
1838 1837 * Mathieu Lacage, Hossein Manshaei, Thierry Turletti
1839 1838 * INRIA Sophia - Projet Planete
1840 1839 * http://www-sop.inria.fr/rapports/sophia/RR-5208.html
1841 1840 *
1842 1841 * This algorithm is particularly well suited for rum since it does not
1843 1842 * require per-frame retry statistics. Note however that since h/w does
1844 1843 * not provide per-frame stats, we can't do per-node rate adaptation and
1845 1844 * thus automatic rate adaptation is only enabled in STA operating mode.
1846 1845 */
1847 1846 #define is_success(amrr) \
1848 1847 ((amrr)->retrycnt < (amrr)->txcnt / 10)
1849 1848 #define is_failure(amrr) \
1850 1849 ((amrr)->retrycnt > (amrr)->txcnt / 3)
1851 1850 #define is_enough(amrr) \
1852 1851 ((amrr)->txcnt > 10)
1853 1852 #define is_min_rate(ni) \
1854 1853 ((ni)->in_txrate == 0)
1855 1854 #define is_max_rate(ni) \
1856 1855 ((ni)->in_txrate == (ni)->in_rates.ir_nrates - 1)
1857 1856 #define increase_rate(ni) \
1858 1857 ((ni)->in_txrate++)
1859 1858 #define decrease_rate(ni) \
1860 1859 ((ni)->in_txrate--)
1861 1860 #define reset_cnt(amrr) do { \
1862 1861 (amrr)->txcnt = (amrr)->retrycnt = 0; \
1863 1862 _NOTE(CONSTCOND) \
1864 1863 } while (/* CONSTCOND */0)
1865 1864
1866 1865 static void
1867 1866 rum_ratectl(struct rum_amrr *amrr, struct ieee80211_node *ni)
1868 1867 {
1869 1868 int need_change = 0;
1870 1869
1871 1870 if (is_success(amrr) && is_enough(amrr)) {
1872 1871 amrr->success++;
1873 1872 if (amrr->success >= amrr->success_threshold &&
1874 1873 !is_max_rate(ni)) {
1875 1874 amrr->recovery = 1;
1876 1875 amrr->success = 0;
1877 1876 increase_rate(ni);
1878 1877 need_change = 1;
1879 1878 } else {
1880 1879 amrr->recovery = 0;
1881 1880 }
1882 1881 } else if (is_failure(amrr)) {
1883 1882 amrr->success = 0;
1884 1883 if (!is_min_rate(ni)) {
1885 1884 if (amrr->recovery) {
1886 1885 amrr->success_threshold *= 2;
1887 1886 if (amrr->success_threshold >
1888 1887 RUM_AMRR_MAX_SUCCESS_THRESHOLD)
1889 1888 amrr->success_threshold =
1890 1889 RUM_AMRR_MAX_SUCCESS_THRESHOLD;
1891 1890 } else {
1892 1891 amrr->success_threshold =
1893 1892 RUM_AMRR_MIN_SUCCESS_THRESHOLD;
1894 1893 }
1895 1894 decrease_rate(ni);
1896 1895 need_change = 1;
1897 1896 }
1898 1897 amrr->recovery = 0; /* original paper was incorrect */
1899 1898 }
1900 1899
1901 1900 if (is_enough(amrr) || need_change)
1902 1901 reset_cnt(amrr);
1903 1902 }
1904 1903
1905 1904 static void
1906 1905 rum_amrr_timeout(void *arg)
1907 1906 {
1908 1907 struct rum_softc *sc = (struct rum_softc *)arg;
1909 1908 struct rum_amrr *amrr = &sc->amrr;
1910 1909
1911 1910 rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof (sc->sta));
1912 1911
1913 1912 /* count TX retry-fail as Tx errors */
1914 1913 sc->sc_tx_err += LE_32(sc->sta[5]) >> 16;
1915 1914 sc->sc_tx_retries += ((LE_32(sc->sta[4]) >> 16) +
1916 1915 (LE_32(sc->sta[5]) & 0xffff));
1917 1916
1918 1917 amrr->retrycnt =
1919 1918 (LE_32(sc->sta[4]) >> 16) + /* TX one-retry ok count */
1920 1919 (LE_32(sc->sta[5]) & 0xffff) + /* TX more-retry ok count */
1921 1920 (LE_32(sc->sta[5]) >> 16); /* TX retry-fail count */
1922 1921
1923 1922 amrr->txcnt =
1924 1923 amrr->retrycnt +
1925 1924 (LE_32(sc->sta[4]) & 0xffff); /* TX no-retry ok count */
1926 1925
1927 1926 rum_ratectl(amrr, sc->sc_ic.ic_bss);
1928 1927
1929 1928 sc->sc_amrr_id = timeout(rum_amrr_timeout, (void *)sc,
1930 1929 drv_usectohz(1000 * 1000)); /* 1 second */
1931 1930 }
1932 1931
1933 1932 static void
1934 1933 rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni)
1935 1934 {
1936 1935 struct rum_amrr *amrr = &sc->amrr;
1937 1936 int i;
1938 1937
1939 1938 /* clear statistic registers (STA_CSR0 to STA_CSR5) */
1940 1939 rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof (sc->sta));
1941 1940
1942 1941 amrr->success = 0;
1943 1942 amrr->recovery = 0;
1944 1943 amrr->txcnt = amrr->retrycnt = 0;
1945 1944 amrr->success_threshold = RUM_AMRR_MIN_SUCCESS_THRESHOLD;
1946 1945
1947 1946 /* set rate to some reasonable initial value */
1948 1947 for (i = ni->in_rates.ir_nrates - 1;
1949 1948 i > 0 && (ni->in_rates.ir_rates[i] & IEEE80211_RATE_VAL) > 72;
1950 1949 i--) {
1951 1950 }
1952 1951
1953 1952 ni->in_txrate = i;
1954 1953
1955 1954 sc->sc_amrr_id = timeout(rum_amrr_timeout, (void *)sc,
1956 1955 drv_usectohz(1000 * 1000)); /* 1 second */
1957 1956 }
1958 1957
1959 1958 void
1960 1959 rum_watchdog(void *arg)
1961 1960 {
1962 1961 struct rum_softc *sc = arg;
1963 1962 struct ieee80211com *ic = &sc->sc_ic;
1964 1963 int ntimer = 0;
1965 1964
1966 1965 RAL_LOCK(sc);
1967 1966 ic->ic_watchdog_timer = 0;
1968 1967
1969 1968 if (!RAL_IS_RUNNING(sc)) {
1970 1969 RAL_UNLOCK(sc);
1971 1970 return;
1972 1971 }
1973 1972
1974 1973 if (sc->sc_tx_timer > 0) {
1975 1974 if (--sc->sc_tx_timer == 0) {
1976 1975 ral_debug(RAL_DBG_ERR, "tx timer timeout\n");
1977 1976 RAL_UNLOCK(sc);
1978 1977 (void) rum_init(sc);
1979 1978 (void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
1980 1979 return;
1981 1980 }
1982 1981 }
1983 1982
1984 1983 if (ic->ic_state == IEEE80211_S_RUN)
1985 1984 ntimer = 1;
1986 1985
1987 1986 RAL_UNLOCK(sc);
1988 1987
1989 1988 ieee80211_watchdog(ic);
1990 1989
1991 1990 if (ntimer)
1992 1991 ieee80211_start_watchdog(ic, ntimer);
1993 1992 }
1994 1993
1995 1994 static int
1996 1995 rum_m_start(void *arg)
1997 1996 {
1998 1997 struct rum_softc *sc = (struct rum_softc *)arg;
1999 1998 int err;
2000 1999
2001 2000 /*
2002 2001 * initialize RT2501USB hardware
2003 2002 */
2004 2003 err = rum_init(sc);
2005 2004 if (err != DDI_SUCCESS) {
2006 2005 ral_debug(RAL_DBG_ERR, "device configuration failed\n");
2007 2006 goto fail;
2008 2007 }
2009 2008 sc->sc_flags |= RAL_FLAG_RUNNING; /* RUNNING */
2010 2009 return (err);
2011 2010
2012 2011 fail:
2013 2012 rum_stop(sc);
2014 2013 return (err);
2015 2014 }
2016 2015
2017 2016 static void
2018 2017 rum_m_stop(void *arg)
2019 2018 {
2020 2019 struct rum_softc *sc = (struct rum_softc *)arg;
2021 2020
2022 2021 (void) rum_stop(sc);
2023 2022 sc->sc_flags &= ~RAL_FLAG_RUNNING; /* STOP */
2024 2023 }
2025 2024
2026 2025 static int
2027 2026 rum_m_unicst(void *arg, const uint8_t *macaddr)
2028 2027 {
2029 2028 struct rum_softc *sc = (struct rum_softc *)arg;
2030 2029 struct ieee80211com *ic = &sc->sc_ic;
2031 2030
2032 2031 ral_debug(RAL_DBG_MSG, "rum_m_unicst(): " MACSTR "\n",
2033 2032 MAC2STR(macaddr));
2034 2033
2035 2034 IEEE80211_ADDR_COPY(ic->ic_macaddr, macaddr);
2036 2035 (void) rum_set_macaddr(sc, (uint8_t *)macaddr);
2037 2036 (void) rum_init(sc);
2038 2037
2039 2038 return (0);
2040 2039 }
2041 2040
2042 2041 /*ARGSUSED*/
2043 2042 static int
2044 2043 rum_m_multicst(void *arg, boolean_t add, const uint8_t *mca)
2045 2044 {
2046 2045 return (0);
2047 2046 }
2048 2047
2049 2048 static int
2050 2049 rum_m_promisc(void *arg, boolean_t on)
2051 2050 {
2052 2051 struct rum_softc *sc = (struct rum_softc *)arg;
2053 2052
2054 2053 if (on) {
2055 2054 sc->sc_rcr |= RAL_RCR_PROMISC;
2056 2055 sc->sc_rcr |= RAL_RCR_MULTI;
2057 2056 } else {
2058 2057 sc->sc_rcr &= ~RAL_RCR_PROMISC;
2059 2058 sc->sc_rcr &= ~RAL_RCR_MULTI;
2060 2059 }
2061 2060
2062 2061 rum_update_promisc(sc);
2063 2062 return (0);
2064 2063 }
2065 2064
2066 2065 /*
2067 2066 * callback functions for /get/set properties
2068 2067 */
2069 2068 static int
2070 2069 rum_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2071 2070 uint_t wldp_length, const void *wldp_buf)
2072 2071 {
2073 2072 struct rum_softc *sc = (struct rum_softc *)arg;
2074 2073 struct ieee80211com *ic = &sc->sc_ic;
2075 2074 int err;
2076 2075
2077 2076 err = ieee80211_setprop(ic, pr_name, wldp_pr_num,
2078 2077 wldp_length, wldp_buf);
2079 2078 RAL_LOCK(sc);
2080 2079 if (err == ENETRESET) {
2081 2080 if (RAL_IS_RUNNING(sc)) {
2082 2081 RAL_UNLOCK(sc);
2083 2082 (void) rum_init(sc);
2084 2083 (void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2085 2084 RAL_LOCK(sc);
2086 2085 }
2087 2086 err = 0;
2088 2087 }
2089 2088 RAL_UNLOCK(sc);
2090 2089
2091 2090 return (err);
2092 2091 }
2093 2092
2094 2093 static int
2095 2094 rum_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2096 2095 uint_t wldp_length, void *wldp_buf)
2097 2096 {
2098 2097 struct rum_softc *sc = (struct rum_softc *)arg;
2099 2098 int err;
2100 2099
2101 2100 err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_num,
2102 2101 wldp_length, wldp_buf);
2103 2102
2104 2103 return (err);
2105 2104 }
2106 2105
2107 2106 static void
2108 2107 rum_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
2109 2108 mac_prop_info_handle_t prh)
2110 2109 {
2111 2110 struct rum_softc *sc = (struct rum_softc *)arg;
2112 2111
2113 2112 ieee80211_propinfo(&sc->sc_ic, pr_name, wldp_pr_num, prh);
2114 2113 }
2115 2114
2116 2115 static void
2117 2116 rum_m_ioctl(void* arg, queue_t *wq, mblk_t *mp)
2118 2117 {
2119 2118 struct rum_softc *sc = (struct rum_softc *)arg;
2120 2119 struct ieee80211com *ic = &sc->sc_ic;
2121 2120 int err;
2122 2121
2123 2122 err = ieee80211_ioctl(ic, wq, mp);
2124 2123 RAL_LOCK(sc);
2125 2124 if (err == ENETRESET) {
2126 2125 if (RAL_IS_RUNNING(sc)) {
2127 2126 RAL_UNLOCK(sc);
2128 2127 (void) rum_init(sc);
2129 2128 (void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2130 2129 RAL_LOCK(sc);
2131 2130 }
2132 2131 }
2133 2132 RAL_UNLOCK(sc);
2134 2133 }
2135 2134
2136 2135 static int
2137 2136 rum_m_stat(void *arg, uint_t stat, uint64_t *val)
2138 2137 {
2139 2138 struct rum_softc *sc = (struct rum_softc *)arg;
2140 2139 ieee80211com_t *ic = &sc->sc_ic;
2141 2140 ieee80211_node_t *ni;
2142 2141 struct ieee80211_rateset *rs;
2143 2142
2144 2143 RAL_LOCK(sc);
2145 2144
2146 2145 ni = ic->ic_bss;
2147 2146 rs = &ni->in_rates;
2148 2147
2149 2148 switch (stat) {
2150 2149 case MAC_STAT_IFSPEED:
2151 2150 *val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ?
2152 2151 (rs->ir_rates[ni->in_txrate] & IEEE80211_RATE_VAL)
2153 2152 : ic->ic_fixed_rate) * 500000ull;
2154 2153 break;
2155 2154 case MAC_STAT_NOXMTBUF:
2156 2155 *val = sc->sc_tx_nobuf;
2157 2156 break;
2158 2157 case MAC_STAT_NORCVBUF:
2159 2158 *val = sc->sc_rx_nobuf;
2160 2159 break;
2161 2160 case MAC_STAT_IERRORS:
2162 2161 *val = sc->sc_rx_err;
2163 2162 break;
2164 2163 case MAC_STAT_RBYTES:
2165 2164 *val = ic->ic_stats.is_rx_bytes;
2166 2165 break;
2167 2166 case MAC_STAT_IPACKETS:
2168 2167 *val = ic->ic_stats.is_rx_frags;
2169 2168 break;
2170 2169 case MAC_STAT_OBYTES:
2171 2170 *val = ic->ic_stats.is_tx_bytes;
2172 2171 break;
2173 2172 case MAC_STAT_OPACKETS:
2174 2173 *val = ic->ic_stats.is_tx_frags;
2175 2174 break;
2176 2175 case MAC_STAT_OERRORS:
2177 2176 case WIFI_STAT_TX_FAILED:
2178 2177 *val = sc->sc_tx_err;
2179 2178 break;
2180 2179 case WIFI_STAT_TX_RETRANS:
2181 2180 *val = sc->sc_tx_retries;
2182 2181 break;
2183 2182 case WIFI_STAT_FCS_ERRORS:
2184 2183 case WIFI_STAT_WEP_ERRORS:
2185 2184 case WIFI_STAT_TX_FRAGS:
2186 2185 case WIFI_STAT_MCAST_TX:
2187 2186 case WIFI_STAT_RTS_SUCCESS:
2188 2187 case WIFI_STAT_RTS_FAILURE:
2189 2188 case WIFI_STAT_ACK_FAILURE:
2190 2189 case WIFI_STAT_RX_FRAGS:
2191 2190 case WIFI_STAT_MCAST_RX:
2192 2191 case WIFI_STAT_RX_DUPS:
2193 2192 RAL_UNLOCK(sc);
2194 2193 return (ieee80211_stat(ic, stat, val));
2195 2194 default:
2196 2195 RAL_UNLOCK(sc);
2197 2196 return (ENOTSUP);
2198 2197 }
2199 2198 RAL_UNLOCK(sc);
2200 2199
2201 2200 return (0);
2202 2201 }
2203 2202
2204 2203 static int
2205 2204 rum_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
2206 2205 {
2207 2206 struct rum_softc *sc;
2208 2207 struct ieee80211com *ic;
2209 2208 int err, i, ntries;
2210 2209 uint32_t tmp;
2211 2210 int instance;
2212 2211
2213 2212 char strbuf[32];
2214 2213
2215 2214 wifi_data_t wd = { 0 };
2216 2215 mac_register_t *macp;
2217 2216
2218 2217 switch (cmd) {
2219 2218 case DDI_ATTACH:
2220 2219 break;
2221 2220 case DDI_RESUME:
2222 2221 sc = ddi_get_soft_state(rum_soft_state_p,
2223 2222 ddi_get_instance(devinfo));
2224 2223 ASSERT(sc != NULL);
2225 2224 rum_resume(sc);
2226 2225 return (DDI_SUCCESS);
2227 2226 default:
2228 2227 return (DDI_FAILURE);
2229 2228 }
2230 2229
2231 2230 instance = ddi_get_instance(devinfo);
2232 2231
2233 2232 if (ddi_soft_state_zalloc(rum_soft_state_p, instance) != DDI_SUCCESS) {
2234 2233 ral_debug(RAL_DBG_MSG, "rum_attach(): "
2235 2234 "unable to alloc soft_state_p\n");
2236 2235 return (DDI_FAILURE);
2237 2236 }
2238 2237
2239 2238 sc = ddi_get_soft_state(rum_soft_state_p, instance);
2240 2239 ic = (ieee80211com_t *)&sc->sc_ic;
2241 2240 sc->sc_dev = devinfo;
2242 2241
2243 2242 if (usb_client_attach(devinfo, USBDRV_VERSION, 0) != USB_SUCCESS) {
2244 2243 ral_debug(RAL_DBG_ERR,
2245 2244 "rum_attach(): usb_client_attach failed\n");
2246 2245 goto fail1;
2247 2246 }
2248 2247
2249 2248 if (usb_get_dev_data(devinfo, &sc->sc_udev,
2250 2249 USB_PARSE_LVL_ALL, 0) != USB_SUCCESS) {
2251 2250 sc->sc_udev = NULL;
2252 2251 goto fail2;
2253 2252 }
2254 2253
2255 2254 mutex_init(&sc->sc_genlock, NULL, MUTEX_DRIVER, NULL);
2256 2255 mutex_init(&sc->tx_lock, NULL, MUTEX_DRIVER, NULL);
2257 2256 mutex_init(&sc->rx_lock, NULL, MUTEX_DRIVER, NULL);
2258 2257
2259 2258 /* retrieve RT2573 rev. no */
2260 2259 for (ntries = 0; ntries < 1000; ntries++) {
2261 2260 if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0)
2262 2261 break;
2263 2262 drv_usecwait(1000);
2264 2263 }
2265 2264 if (ntries == 1000) {
2266 2265 ral_debug(RAL_DBG_ERR,
2267 2266 "rum_attach(): timeout waiting for chip to settle\n");
2268 2267 goto fail3;
2269 2268 }
2270 2269
2271 2270 /* retrieve MAC address and various other things from EEPROM */
2272 2271 rum_read_eeprom(sc);
2273 2272
2274 2273 ral_debug(RAL_DBG_MSG, "rum: MAC/BBP RT2573 (rev 0x%05x), RF %s\n",
2275 2274 tmp, rum_get_rf(sc->rf_rev));
2276 2275
2277 2276 err = rum_load_microcode(sc);
2278 2277 if (err != USB_SUCCESS) {
2279 2278 ral_debug(RAL_DBG_ERR, "could not load 8051 microcode\n");
2280 2279 goto fail3;
2281 2280 }
2282 2281
2283 2282 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
2284 2283 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
2285 2284 ic->ic_state = IEEE80211_S_INIT;
2286 2285
2287 2286 ic->ic_maxrssi = 63;
2288 2287 ic->ic_set_shortslot = rum_update_slot;
2289 2288 ic->ic_xmit = rum_send;
2290 2289
2291 2290 /* set device capabilities */
2292 2291 ic->ic_caps =
2293 2292 IEEE80211_C_TXPMGT | /* tx power management */
2294 2293 IEEE80211_C_SHPREAMBLE | /* short preamble supported */
2295 2294 IEEE80211_C_SHSLOT; /* short slot time supported */
2296 2295
2297 2296 ic->ic_caps |= IEEE80211_C_WPA; /* Support WPA/WPA2 */
2298 2297
2299 2298 #define IEEE80211_CHAN_A \
2300 2299 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
2301 2300
2302 2301 if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_5226) {
2303 2302 /* set supported .11a rates */
2304 2303 ic->ic_sup_rates[IEEE80211_MODE_11A] = rum_rateset_11a;
2305 2304
2306 2305 /* set supported .11a channels */
2307 2306 for (i = 34; i <= 46; i += 4) {
2308 2307 ic->ic_sup_channels[i].ich_freq =
2309 2308 ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
2310 2309 ic->ic_sup_channels[i].ich_flags = IEEE80211_CHAN_A;
2311 2310 }
2312 2311 for (i = 36; i <= 64; i += 4) {
2313 2312 ic->ic_sup_channels[i].ich_freq =
2314 2313 ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
2315 2314 ic->ic_sup_channels[i].ich_flags = IEEE80211_CHAN_A;
2316 2315 }
2317 2316 for (i = 100; i <= 140; i += 4) {
2318 2317 ic->ic_sup_channels[i].ich_freq =
2319 2318 ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
2320 2319 ic->ic_sup_channels[i].ich_flags = IEEE80211_CHAN_A;
2321 2320 }
2322 2321 for (i = 149; i <= 165; i += 4) {
2323 2322 ic->ic_sup_channels[i].ich_freq =
2324 2323 ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
2325 2324 ic->ic_sup_channels[i].ich_flags = IEEE80211_CHAN_A;
2326 2325 }
2327 2326 }
2328 2327
2329 2328 /* set supported .11b and .11g rates */
2330 2329 ic->ic_sup_rates[IEEE80211_MODE_11B] = rum_rateset_11b;
2331 2330 ic->ic_sup_rates[IEEE80211_MODE_11G] = rum_rateset_11g;
2332 2331
2333 2332 /* set supported .11b and .11g channels (1 through 14) */
2334 2333 for (i = 1; i <= 14; i++) {
2335 2334 ic->ic_sup_channels[i].ich_freq =
2336 2335 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
2337 2336 ic->ic_sup_channels[i].ich_flags =
2338 2337 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
2339 2338 IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
2340 2339 }
2341 2340
2342 2341 ieee80211_attach(ic);
2343 2342
2344 2343 /* register WPA door */
2345 2344 ieee80211_register_door(ic, ddi_driver_name(devinfo),
2346 2345 ddi_get_instance(devinfo));
2347 2346
2348 2347 /* override state transition machine */
2349 2348 sc->sc_newstate = ic->ic_newstate;
2350 2349 ic->ic_newstate = rum_newstate;
2351 2350 ic->ic_watchdog = rum_watchdog;
2352 2351 ieee80211_media_init(ic);
2353 2352 ic->ic_def_txkey = 0;
2354 2353
2355 2354 sc->sc_rcr = 0;
2356 2355 sc->dwelltime = 300;
2357 2356 sc->sc_flags = 0;
2358 2357
2359 2358 /*
2360 2359 * Provide initial settings for the WiFi plugin; whenever this
2361 2360 * information changes, we need to call mac_plugindata_update()
2362 2361 */
2363 2362 wd.wd_opmode = ic->ic_opmode;
2364 2363 wd.wd_secalloc = WIFI_SEC_NONE;
2365 2364 IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid);
2366 2365
2367 2366 if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
2368 2367 ral_debug(RAL_DBG_ERR, "rum_attach(): "
2369 2368 "MAC version mismatch\n");
2370 2369 goto fail3;
2371 2370 }
2372 2371
2373 2372 macp->m_type_ident = MAC_PLUGIN_IDENT_WIFI;
2374 2373 macp->m_driver = sc;
2375 2374 macp->m_dip = devinfo;
2376 2375 macp->m_src_addr = ic->ic_macaddr;
2377 2376 macp->m_callbacks = &rum_m_callbacks;
2378 2377 macp->m_min_sdu = 0;
2379 2378 macp->m_max_sdu = IEEE80211_MTU;
2380 2379 macp->m_pdata = &wd;
2381 2380 macp->m_pdata_size = sizeof (wd);
2382 2381
2383 2382 err = mac_register(macp, &ic->ic_mach);
2384 2383 mac_free(macp);
2385 2384 if (err != 0) {
2386 2385 ral_debug(RAL_DBG_ERR, "rum_attach(): "
2387 2386 "mac_register() err %x\n", err);
2388 2387 goto fail3;
2389 2388 }
2390 2389
2391 2390 if (usb_register_hotplug_cbs(devinfo, rum_disconnect,
2392 2391 rum_reconnect) != USB_SUCCESS) {
2393 2392 ral_debug(RAL_DBG_ERR,
2394 2393 "rum_attach() failed to register events");
2395 2394 goto fail4;
2396 2395 }
2397 2396
2398 2397 /*
2399 2398 * Create minor node of type DDI_NT_NET_WIFI
2400 2399 */
2401 2400 (void) snprintf(strbuf, sizeof (strbuf), "%s%d",
2402 2401 "rum", instance);
2403 2402 err = ddi_create_minor_node(devinfo, strbuf, S_IFCHR,
2404 2403 instance + 1, DDI_NT_NET_WIFI, 0);
2405 2404
2406 2405 if (err != DDI_SUCCESS)
2407 2406 ral_debug(RAL_DBG_ERR, "ddi_create_minor_node() failed\n");
2408 2407
2409 2408 /*
2410 2409 * Notify link is down now
2411 2410 */
2412 2411 mac_link_update(ic->ic_mach, LINK_STATE_DOWN);
2413 2412 return (DDI_SUCCESS);
2414 2413
2415 2414 fail4:
2416 2415 (void) mac_unregister(ic->ic_mach);
2417 2416 fail3:
2418 2417 mutex_destroy(&sc->sc_genlock);
2419 2418 mutex_destroy(&sc->tx_lock);
2420 2419 mutex_destroy(&sc->rx_lock);
2421 2420 fail2:
2422 2421 usb_client_detach(sc->sc_dev, sc->sc_udev);
2423 2422 fail1:
2424 2423 ddi_soft_state_free(rum_soft_state_p, ddi_get_instance(devinfo));
2425 2424
2426 2425 return (DDI_FAILURE);
2427 2426 }
2428 2427
2429 2428 static int
2430 2429 rum_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
2431 2430 {
2432 2431 struct rum_softc *sc;
2433 2432
2434 2433 sc = ddi_get_soft_state(rum_soft_state_p, ddi_get_instance(devinfo));
2435 2434 ASSERT(sc != NULL);
2436 2435
2437 2436 switch (cmd) {
2438 2437 case DDI_DETACH:
2439 2438 break;
2440 2439 case DDI_SUSPEND:
2441 2440 if (RAL_IS_RUNNING(sc))
2442 2441 (void) rum_stop(sc);
2443 2442 return (DDI_SUCCESS);
2444 2443 default:
2445 2444 return (DDI_FAILURE);
2446 2445 }
2447 2446
2448 2447 rum_stop(sc);
2449 2448 usb_unregister_hotplug_cbs(devinfo);
2450 2449
2451 2450 /*
2452 2451 * Unregister from the MAC layer subsystem
2453 2452 */
2454 2453 if (mac_unregister(sc->sc_ic.ic_mach) != 0)
2455 2454 return (DDI_FAILURE);
2456 2455
2457 2456 /*
2458 2457 * detach ieee80211 layer
2459 2458 */
2460 2459 ieee80211_detach(&sc->sc_ic);
2461 2460
2462 2461 mutex_destroy(&sc->sc_genlock);
2463 2462 mutex_destroy(&sc->tx_lock);
2464 2463 mutex_destroy(&sc->rx_lock);
2465 2464
2466 2465 /* pipes will be closed in rum_stop() */
2467 2466 usb_client_detach(devinfo, sc->sc_udev);
2468 2467 sc->sc_udev = NULL;
2469 2468
2470 2469 ddi_remove_minor_node(devinfo, NULL);
2471 2470 ddi_soft_state_free(rum_soft_state_p, ddi_get_instance(devinfo));
2472 2471
2473 2472 return (DDI_SUCCESS);
2474 2473 }
2475 2474
2476 2475 int
2477 2476 _info(struct modinfo *modinfop)
2478 2477 {
2479 2478 return (mod_info(&modlinkage, modinfop));
2480 2479 }
2481 2480
2482 2481 int
2483 2482 _init(void)
2484 2483 {
2485 2484 int status;
2486 2485
2487 2486 status = ddi_soft_state_init(&rum_soft_state_p,
2488 2487 sizeof (struct rum_softc), 1);
2489 2488 if (status != 0)
2490 2489 return (status);
2491 2490
2492 2491 mac_init_ops(&rum_dev_ops, "rum");
2493 2492 status = mod_install(&modlinkage);
2494 2493 if (status != 0) {
2495 2494 mac_fini_ops(&rum_dev_ops);
2496 2495 ddi_soft_state_fini(&rum_soft_state_p);
2497 2496 }
2498 2497 return (status);
2499 2498 }
2500 2499
2501 2500 int
2502 2501 _fini(void)
2503 2502 {
2504 2503 int status;
2505 2504
2506 2505 status = mod_remove(&modlinkage);
2507 2506 if (status == 0) {
2508 2507 mac_fini_ops(&rum_dev_ops);
2509 2508 ddi_soft_state_fini(&rum_soft_state_p);
2510 2509 }
2511 2510 return (status);
2512 2511 }
↓ open down ↓ |
2252 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX