Annotation of sys/dev/usb/if_rum.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_rum.c,v 1.64 2007/06/14 10:11:15 mbalmer Exp $ */
2:
3: /*-
4: * Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini@free.fr>
5: * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org>
6: *
7: * Permission to use, copy, modify, and distribute this software for any
8: * purpose with or without fee is hereby granted, provided that the above
9: * copyright notice and this permission notice appear in all copies.
10: *
11: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18: */
19:
20: /*-
21: * Ralink Technology RT2501USB/RT2601USB chipset driver
22: * http://www.ralinktech.com.tw/
23: */
24:
25: #include "bpfilter.h"
26:
27: #include <sys/param.h>
28: #include <sys/sockio.h>
29: #include <sys/sysctl.h>
30: #include <sys/mbuf.h>
31: #include <sys/kernel.h>
32: #include <sys/socket.h>
33: #include <sys/systm.h>
34: #include <sys/malloc.h>
35: #include <sys/timeout.h>
36: #include <sys/conf.h>
37: #include <sys/device.h>
38:
39: #include <machine/bus.h>
40: #include <machine/endian.h>
41: #include <machine/intr.h>
42:
43: #if NBPFILTER > 0
44: #include <net/bpf.h>
45: #endif
46: #include <net/if.h>
47: #include <net/if_arp.h>
48: #include <net/if_dl.h>
49: #include <net/if_media.h>
50: #include <net/if_types.h>
51:
52: #include <netinet/in.h>
53: #include <netinet/in_systm.h>
54: #include <netinet/in_var.h>
55: #include <netinet/if_ether.h>
56: #include <netinet/ip.h>
57:
58: #include <net80211/ieee80211_var.h>
59: #include <net80211/ieee80211_amrr.h>
60: #include <net80211/ieee80211_radiotap.h>
61:
62: #include <dev/usb/usb.h>
63: #include <dev/usb/usbdi.h>
64: #include <dev/usb/usbdi_util.h>
65: #include <dev/usb/usbdevs.h>
66:
67: #include <dev/usb/if_rumreg.h>
68: #include <dev/usb/if_rumvar.h>
69:
70: #ifdef USB_DEBUG
71: #define RUM_DEBUG
72: #endif
73:
74: #ifdef RUM_DEBUG
75: #define DPRINTF(x) do { if (rum_debug) printf x; } while (0)
76: #define DPRINTFN(n, x) do { if (rum_debug >= (n)) printf x; } while (0)
77: int rum_debug = 0;
78: #else
79: #define DPRINTF(x)
80: #define DPRINTFN(n, x)
81: #endif
82:
83: /* various supported device vendors/products */
84: static const struct usb_devno rum_devs[] = {
85: { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_HWU54DM },
86: { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_2 },
87: { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_3 },
88: { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_4 },
89: { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WUG2700 },
90: { USB_VENDOR_AMIT, USB_PRODUCT_AMIT_CGWLUSB2GO },
91: { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_1 },
92: { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_2 },
93: { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050A },
94: { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D9050V3 },
95: { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GC },
96: { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GR },
97: { USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU2 },
98: { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CWD854F },
99: { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_RT2573 },
100: { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWLG122C1 },
101: { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_WUA1340 },
102: { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWB01GS },
103: { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWI05GS },
104: { USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_RT2573 },
105: { USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_RT2573 },
106: { USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254LB },
107: { USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP },
108: { USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_WUB320G },
109: { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_G54HP },
110: { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HP },
111: { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_1 },
112: { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_2 },
113: { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_3 },
114: { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_4 },
115: { USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RT2573 },
116: { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54HP },
117: { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54MINI2 },
118: { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMM },
119: { USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573 },
120: { USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573_2 },
121: { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573 },
122: { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573_2 },
123: { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2671 },
124: { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113R2 },
125: { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL172 },
126: { USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2573 }
127: };
128:
129: void rum_attachhook(void *);
130: int rum_alloc_tx_list(struct rum_softc *);
131: void rum_free_tx_list(struct rum_softc *);
132: int rum_alloc_rx_list(struct rum_softc *);
133: void rum_free_rx_list(struct rum_softc *);
134: int rum_media_change(struct ifnet *);
135: void rum_next_scan(void *);
136: void rum_task(void *);
137: int rum_newstate(struct ieee80211com *, enum ieee80211_state, int);
138: void rum_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
139: void rum_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
140: #if NBPFILTER > 0
141: uint8_t rum_rxrate(const struct rum_rx_desc *);
142: #endif
143: int rum_ack_rate(struct ieee80211com *, int);
144: uint16_t rum_txtime(int, int, uint32_t);
145: uint8_t rum_plcp_signal(int);
146: void rum_setup_tx_desc(struct rum_softc *, struct rum_tx_desc *,
147: uint32_t, uint16_t, int, int);
148: int rum_tx_data(struct rum_softc *, struct mbuf *,
149: struct ieee80211_node *);
150: void rum_start(struct ifnet *);
151: void rum_watchdog(struct ifnet *);
152: int rum_ioctl(struct ifnet *, u_long, caddr_t);
153: void rum_eeprom_read(struct rum_softc *, uint16_t, void *, int);
154: uint32_t rum_read(struct rum_softc *, uint16_t);
155: void rum_read_multi(struct rum_softc *, uint16_t, void *, int);
156: void rum_write(struct rum_softc *, uint16_t, uint32_t);
157: void rum_write_multi(struct rum_softc *, uint16_t, void *, size_t);
158: void rum_bbp_write(struct rum_softc *, uint8_t, uint8_t);
159: uint8_t rum_bbp_read(struct rum_softc *, uint8_t);
160: void rum_rf_write(struct rum_softc *, uint8_t, uint32_t);
161: void rum_select_antenna(struct rum_softc *);
162: void rum_enable_mrr(struct rum_softc *);
163: void rum_set_txpreamble(struct rum_softc *);
164: void rum_set_basicrates(struct rum_softc *);
165: void rum_select_band(struct rum_softc *,
166: struct ieee80211_channel *);
167: void rum_set_chan(struct rum_softc *, struct ieee80211_channel *);
168: void rum_enable_tsf_sync(struct rum_softc *);
169: void rum_update_slot(struct rum_softc *);
170: void rum_set_bssid(struct rum_softc *, const uint8_t *);
171: void rum_set_macaddr(struct rum_softc *, const uint8_t *);
172: void rum_update_promisc(struct rum_softc *);
173: const char *rum_get_rf(int);
174: void rum_read_eeprom(struct rum_softc *);
175: int rum_bbp_init(struct rum_softc *);
176: int rum_init(struct ifnet *);
177: void rum_stop(struct ifnet *, int);
178: int rum_load_microcode(struct rum_softc *, const u_char *, size_t);
179: int rum_prepare_beacon(struct rum_softc *);
180: void rum_newassoc(struct ieee80211com *, struct ieee80211_node *,
181: int);
182: void rum_amrr_start(struct rum_softc *, struct ieee80211_node *);
183: void rum_amrr_timeout(void *);
184: void rum_amrr_update(usbd_xfer_handle, usbd_private_handle,
185: usbd_status status);
186:
187: static const struct {
188: uint32_t reg;
189: uint32_t val;
190: } rum_def_mac[] = {
191: RT2573_DEF_MAC
192: };
193:
194: static const struct {
195: uint8_t reg;
196: uint8_t val;
197: } rum_def_bbp[] = {
198: RT2573_DEF_BBP
199: };
200:
201: static const struct rfprog {
202: uint8_t chan;
203: uint32_t r1, r2, r3, r4;
204: } rum_rf5226[] = {
205: RT2573_RF5226
206: }, rum_rf5225[] = {
207: RT2573_RF5225
208: };
209:
210: int rum_match(struct device *, void *, void *);
211: void rum_attach(struct device *, struct device *, void *);
212: int rum_detach(struct device *, int);
213: int rum_activate(struct device *, enum devact);
214:
215: struct cfdriver rum_cd = {
216: NULL, "rum", DV_IFNET
217: };
218:
219: const struct cfattach rum_ca = {
220: sizeof(struct rum_softc),
221: rum_match,
222: rum_attach,
223: rum_detach,
224: rum_activate,
225: };
226:
227: int
228: rum_match(struct device *parent, void *match, void *aux)
229: {
230: struct usb_attach_arg *uaa = aux;
231:
232: if (uaa->iface != NULL)
233: return UMATCH_NONE;
234:
235: return (usb_lookup(rum_devs, uaa->vendor, uaa->product) != NULL) ?
236: UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
237: }
238:
239: void
240: rum_attachhook(void *xsc)
241: {
242: struct rum_softc *sc = xsc;
243: const char *name = "rum-rt2573";
244: u_char *ucode;
245: size_t size;
246: int error;
247:
248: if ((error = loadfirmware(name, &ucode, &size)) != 0) {
249: printf("%s: failed loadfirmware of file %s (error %d)\n",
250: sc->sc_dev.dv_xname, name, error);
251: return;
252: }
253:
254: if (rum_load_microcode(sc, ucode, size) != 0) {
255: printf("%s: could not load 8051 microcode\n",
256: sc->sc_dev.dv_xname);
257: }
258:
259: free(ucode, M_DEVBUF);
260: }
261:
262: void
263: rum_attach(struct device *parent, struct device *self, void *aux)
264: {
265: struct rum_softc *sc = (struct rum_softc *)self;
266: struct usb_attach_arg *uaa = aux;
267: struct ieee80211com *ic = &sc->sc_ic;
268: struct ifnet *ifp = &ic->ic_if;
269: usb_interface_descriptor_t *id;
270: usb_endpoint_descriptor_t *ed;
271: usbd_status error;
272: char *devinfop;
273: int i, ntries;
274: uint32_t tmp;
275:
276: sc->sc_udev = uaa->device;
277:
278: devinfop = usbd_devinfo_alloc(uaa->device, 0);
279: printf("\n%s: %s\n", sc->sc_dev.dv_xname, devinfop);
280: usbd_devinfo_free(devinfop);
281:
282: if (usbd_set_config_no(sc->sc_udev, RT2573_CONFIG_NO, 0) != 0) {
283: printf("%s: could not set configuration no\n",
284: sc->sc_dev.dv_xname);
285: return;
286: }
287:
288: /* get the first interface handle */
289: error = usbd_device2interface_handle(sc->sc_udev, RT2573_IFACE_INDEX,
290: &sc->sc_iface);
291: if (error != 0) {
292: printf("%s: could not get interface handle\n",
293: sc->sc_dev.dv_xname);
294: return;
295: }
296:
297: /*
298: * Find endpoints.
299: */
300: id = usbd_get_interface_descriptor(sc->sc_iface);
301:
302: sc->sc_rx_no = sc->sc_tx_no = -1;
303: for (i = 0; i < id->bNumEndpoints; i++) {
304: ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
305: if (ed == NULL) {
306: printf("%s: no endpoint descriptor for iface %d\n",
307: sc->sc_dev.dv_xname, i);
308: return;
309: }
310:
311: if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
312: UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
313: sc->sc_rx_no = ed->bEndpointAddress;
314: else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
315: UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
316: sc->sc_tx_no = ed->bEndpointAddress;
317: }
318: if (sc->sc_rx_no == -1 || sc->sc_tx_no == -1) {
319: printf("%s: missing endpoint\n", sc->sc_dev.dv_xname);
320: return;
321: }
322:
323: usb_init_task(&sc->sc_task, rum_task, sc);
324: timeout_set(&sc->scan_to, rum_next_scan, sc);
325:
326: sc->amrr.amrr_min_success_threshold = 1;
327: sc->amrr.amrr_max_success_threshold = 10;
328: timeout_set(&sc->amrr_to, rum_amrr_timeout, sc);
329:
330: /* retrieve RT2573 rev. no */
331: for (ntries = 0; ntries < 1000; ntries++) {
332: if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0)
333: break;
334: DELAY(1000);
335: }
336: if (ntries == 1000) {
337: printf("%s: timeout waiting for chip to settle\n",
338: sc->sc_dev.dv_xname);
339: return;
340: }
341:
342: /* retrieve MAC address and various other things from EEPROM */
343: rum_read_eeprom(sc);
344:
345: printf("%s: MAC/BBP RT%04x (rev 0x%05x), RF %s, address %s\n",
346: sc->sc_dev.dv_xname, sc->macbbp_rev, tmp,
347: rum_get_rf(sc->rf_rev), ether_sprintf(ic->ic_myaddr));
348:
349: if (rootvp == NULL)
350: mountroothook_establish(rum_attachhook, sc);
351: else
352: rum_attachhook(sc);
353:
354: ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
355: ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
356: ic->ic_state = IEEE80211_S_INIT;
357:
358: /* set device capabilities */
359: ic->ic_caps =
360: IEEE80211_C_IBSS | /* IBSS mode supported */
361: IEEE80211_C_MONITOR | /* monitor mode supported */
362: IEEE80211_C_HOSTAP | /* HostAp mode supported */
363: IEEE80211_C_TXPMGT | /* tx power management */
364: IEEE80211_C_SHPREAMBLE | /* short preamble supported */
365: IEEE80211_C_SHSLOT | /* short slot time supported */
366: IEEE80211_C_WEP; /* s/w WEP */
367:
368: if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_5226) {
369: /* set supported .11a rates */
370: ic->ic_sup_rates[IEEE80211_MODE_11A] =
371: ieee80211_std_rateset_11a;
372:
373: /* set supported .11a channels */
374: for (i = 34; i <= 46; i += 4) {
375: ic->ic_channels[i].ic_freq =
376: ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
377: ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
378: }
379: for (i = 36; i <= 64; i += 4) {
380: ic->ic_channels[i].ic_freq =
381: ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
382: ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
383: }
384: for (i = 100; i <= 140; i += 4) {
385: ic->ic_channels[i].ic_freq =
386: ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
387: ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
388: }
389: for (i = 149; i <= 165; i += 4) {
390: ic->ic_channels[i].ic_freq =
391: ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
392: ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
393: }
394: }
395:
396: /* set supported .11b and .11g rates */
397: ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
398: ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
399:
400: /* set supported .11b and .11g channels (1 through 14) */
401: for (i = 1; i <= 14; i++) {
402: ic->ic_channels[i].ic_freq =
403: ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
404: ic->ic_channels[i].ic_flags =
405: IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
406: IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
407: }
408:
409: ifp->if_softc = sc;
410: ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
411: ifp->if_init = rum_init;
412: ifp->if_ioctl = rum_ioctl;
413: ifp->if_start = rum_start;
414: ifp->if_watchdog = rum_watchdog;
415: IFQ_SET_READY(&ifp->if_snd);
416: memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
417:
418: if_attach(ifp);
419: ieee80211_ifattach(ifp);
420: ic->ic_newassoc = rum_newassoc;
421:
422: /* override state transition machine */
423: sc->sc_newstate = ic->ic_newstate;
424: ic->ic_newstate = rum_newstate;
425: ieee80211_media_init(ifp, rum_media_change, ieee80211_media_status);
426:
427: #if NBPFILTER > 0
428: bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
429: sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN);
430:
431: sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
432: sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
433: sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2573_RX_RADIOTAP_PRESENT);
434:
435: sc->sc_txtap_len = sizeof sc->sc_txtapu;
436: sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
437: sc->sc_txtap.wt_ihdr.it_present = htole32(RT2573_TX_RADIOTAP_PRESENT);
438: #endif
439:
440: usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
441: &sc->sc_dev);
442: }
443:
444: int
445: rum_detach(struct device *self, int flags)
446: {
447: struct rum_softc *sc = (struct rum_softc *)self;
448: struct ifnet *ifp = &sc->sc_ic.ic_if;
449: int s;
450:
451: s = splusb();
452:
453: ieee80211_ifdetach(ifp); /* free all nodes */
454: if_detach(ifp);
455:
456: usb_rem_task(sc->sc_udev, &sc->sc_task);
457: timeout_del(&sc->scan_to);
458: timeout_del(&sc->amrr_to);
459:
460: if (sc->amrr_xfer != NULL) {
461: usbd_free_xfer(sc->amrr_xfer);
462: sc->amrr_xfer = NULL;
463: }
464: if (sc->sc_rx_pipeh != NULL) {
465: usbd_abort_pipe(sc->sc_rx_pipeh);
466: usbd_close_pipe(sc->sc_rx_pipeh);
467: }
468: if (sc->sc_tx_pipeh != NULL) {
469: usbd_abort_pipe(sc->sc_tx_pipeh);
470: usbd_close_pipe(sc->sc_tx_pipeh);
471: }
472:
473: rum_free_rx_list(sc);
474: rum_free_tx_list(sc);
475:
476: splx(s);
477:
478: usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
479: &sc->sc_dev);
480:
481: return 0;
482: }
483:
484: int
485: rum_alloc_tx_list(struct rum_softc *sc)
486: {
487: int i, error;
488:
489: sc->tx_cur = sc->tx_queued = 0;
490:
491: for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
492: struct rum_tx_data *data = &sc->tx_data[i];
493:
494: data->sc = sc;
495:
496: data->xfer = usbd_alloc_xfer(sc->sc_udev);
497: if (data->xfer == NULL) {
498: printf("%s: could not allocate tx xfer\n",
499: sc->sc_dev.dv_xname);
500: error = ENOMEM;
501: goto fail;
502: }
503: data->buf = usbd_alloc_buffer(data->xfer,
504: RT2573_TX_DESC_SIZE + IEEE80211_MAX_LEN);
505: if (data->buf == NULL) {
506: printf("%s: could not allocate tx buffer\n",
507: sc->sc_dev.dv_xname);
508: error = ENOMEM;
509: goto fail;
510: }
511: /* clean Tx descriptor */
512: bzero(data->buf, RT2573_TX_DESC_SIZE);
513: }
514:
515: return 0;
516:
517: fail: rum_free_tx_list(sc);
518: return error;
519: }
520:
521: void
522: rum_free_tx_list(struct rum_softc *sc)
523: {
524: int i;
525:
526: for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
527: struct rum_tx_data *data = &sc->tx_data[i];
528:
529: if (data->xfer != NULL) {
530: usbd_free_xfer(data->xfer);
531: data->xfer = NULL;
532: }
533: /*
534: * The node has already been freed at that point so don't call
535: * ieee80211_release_node() here.
536: */
537: data->ni = NULL;
538: }
539: }
540:
541: int
542: rum_alloc_rx_list(struct rum_softc *sc)
543: {
544: int i, error;
545:
546: for (i = 0; i < RUM_RX_LIST_COUNT; i++) {
547: struct rum_rx_data *data = &sc->rx_data[i];
548:
549: data->sc = sc;
550:
551: data->xfer = usbd_alloc_xfer(sc->sc_udev);
552: if (data->xfer == NULL) {
553: printf("%s: could not allocate rx xfer\n",
554: sc->sc_dev.dv_xname);
555: error = ENOMEM;
556: goto fail;
557: }
558: if (usbd_alloc_buffer(data->xfer, MCLBYTES) == NULL) {
559: printf("%s: could not allocate rx buffer\n",
560: sc->sc_dev.dv_xname);
561: error = ENOMEM;
562: goto fail;
563: }
564:
565: MGETHDR(data->m, M_DONTWAIT, MT_DATA);
566: if (data->m == NULL) {
567: printf("%s: could not allocate rx mbuf\n",
568: sc->sc_dev.dv_xname);
569: error = ENOMEM;
570: goto fail;
571: }
572: MCLGET(data->m, M_DONTWAIT);
573: if (!(data->m->m_flags & M_EXT)) {
574: printf("%s: could not allocate rx mbuf cluster\n",
575: sc->sc_dev.dv_xname);
576: error = ENOMEM;
577: goto fail;
578: }
579: data->buf = mtod(data->m, uint8_t *);
580: }
581:
582: return 0;
583:
584: fail: rum_free_tx_list(sc);
585: return error;
586: }
587:
588: void
589: rum_free_rx_list(struct rum_softc *sc)
590: {
591: int i;
592:
593: for (i = 0; i < RUM_RX_LIST_COUNT; i++) {
594: struct rum_rx_data *data = &sc->rx_data[i];
595:
596: if (data->xfer != NULL) {
597: usbd_free_xfer(data->xfer);
598: data->xfer = NULL;
599: }
600: if (data->m != NULL) {
601: m_freem(data->m);
602: data->m = NULL;
603: }
604: }
605: }
606:
607: int
608: rum_media_change(struct ifnet *ifp)
609: {
610: int error;
611:
612: error = ieee80211_media_change(ifp);
613: if (error != ENETRESET)
614: return error;
615:
616: if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
617: rum_init(ifp);
618:
619: return 0;
620: }
621:
622: /*
623: * This function is called periodically (every 200ms) during scanning to
624: * switch from one channel to another.
625: */
626: void
627: rum_next_scan(void *arg)
628: {
629: struct rum_softc *sc = arg;
630: struct ieee80211com *ic = &sc->sc_ic;
631: struct ifnet *ifp = &ic->ic_if;
632:
633: if (ic->ic_state == IEEE80211_S_SCAN)
634: ieee80211_next_scan(ifp);
635: }
636:
637: void
638: rum_task(void *arg)
639: {
640: struct rum_softc *sc = arg;
641: struct ieee80211com *ic = &sc->sc_ic;
642: enum ieee80211_state ostate;
643: struct ieee80211_node *ni;
644: uint32_t tmp;
645:
646: ostate = ic->ic_state;
647:
648: switch (sc->sc_state) {
649: case IEEE80211_S_INIT:
650: if (ostate == IEEE80211_S_RUN) {
651: /* abort TSF synchronization */
652: tmp = rum_read(sc, RT2573_TXRX_CSR9);
653: rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff);
654: }
655: break;
656:
657: case IEEE80211_S_SCAN:
658: rum_set_chan(sc, ic->ic_bss->ni_chan);
659: timeout_add(&sc->scan_to, hz / 5);
660: break;
661:
662: case IEEE80211_S_AUTH:
663: rum_set_chan(sc, ic->ic_bss->ni_chan);
664: break;
665:
666: case IEEE80211_S_ASSOC:
667: rum_set_chan(sc, ic->ic_bss->ni_chan);
668: break;
669:
670: case IEEE80211_S_RUN:
671: rum_set_chan(sc, ic->ic_bss->ni_chan);
672:
673: ni = ic->ic_bss;
674:
675: if (ic->ic_opmode != IEEE80211_M_MONITOR) {
676: rum_update_slot(sc);
677: rum_enable_mrr(sc);
678: rum_set_txpreamble(sc);
679: rum_set_basicrates(sc);
680: rum_set_bssid(sc, ni->ni_bssid);
681: }
682:
683: if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
684: ic->ic_opmode == IEEE80211_M_IBSS)
685: rum_prepare_beacon(sc);
686:
687: if (ic->ic_opmode != IEEE80211_M_MONITOR)
688: rum_enable_tsf_sync(sc);
689:
690: if (ic->ic_opmode == IEEE80211_M_STA) {
691: /* fake a join to init the tx rate */
692: rum_newassoc(ic, ic->ic_bss, 1);
693:
694: /* enable automatic rate control in STA mode */
695: if (ic->ic_fixed_rate == -1)
696: rum_amrr_start(sc, ni);
697: }
698: break;
699: }
700:
701: sc->sc_newstate(ic, sc->sc_state, sc->sc_arg);
702: }
703:
704: int
705: rum_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
706: {
707: struct rum_softc *sc = ic->ic_if.if_softc;
708:
709: usb_rem_task(sc->sc_udev, &sc->sc_task);
710: timeout_del(&sc->scan_to);
711: timeout_del(&sc->amrr_to);
712:
713: /* do it in a process context */
714: sc->sc_state = nstate;
715: sc->sc_arg = arg;
716: usb_add_task(sc->sc_udev, &sc->sc_task);
717: return 0;
718: }
719:
720: /* quickly determine if a given rate is CCK or OFDM */
721: #define RUM_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
722:
723: #define RUM_ACK_SIZE 14 /* 10 + 4(FCS) */
724: #define RUM_CTS_SIZE 14 /* 10 + 4(FCS) */
725:
726: void
727: rum_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
728: {
729: struct rum_tx_data *data = priv;
730: struct rum_softc *sc = data->sc;
731: struct ieee80211com *ic = &sc->sc_ic;
732: struct ifnet *ifp = &ic->ic_if;
733: int s;
734:
735: if (status != USBD_NORMAL_COMPLETION) {
736: if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
737: return;
738:
739: printf("%s: could not transmit buffer: %s\n",
740: sc->sc_dev.dv_xname, usbd_errstr(status));
741:
742: if (status == USBD_STALLED)
743: usbd_clear_endpoint_stall_async(sc->sc_tx_pipeh);
744:
745: ifp->if_oerrors++;
746: return;
747: }
748:
749: s = splnet();
750:
751: ieee80211_release_node(ic, data->ni);
752: data->ni = NULL;
753:
754: sc->tx_queued--;
755: ifp->if_opackets++;
756:
757: DPRINTFN(10, ("tx done\n"));
758:
759: sc->sc_tx_timer = 0;
760: ifp->if_flags &= ~IFF_OACTIVE;
761: rum_start(ifp);
762:
763: splx(s);
764: }
765:
766: void
767: rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
768: {
769: struct rum_rx_data *data = priv;
770: struct rum_softc *sc = data->sc;
771: struct ieee80211com *ic = &sc->sc_ic;
772: struct ifnet *ifp = &ic->ic_if;
773: const struct rum_rx_desc *desc;
774: struct ieee80211_frame *wh;
775: struct ieee80211_node *ni;
776: struct mbuf *mnew, *m;
777: int s, len;
778:
779: if (status != USBD_NORMAL_COMPLETION) {
780: if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
781: return;
782:
783: if (status == USBD_STALLED)
784: usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh);
785: goto skip;
786: }
787:
788: usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
789:
790: if (len < RT2573_RX_DESC_SIZE + sizeof (struct ieee80211_frame_min)) {
791: DPRINTF(("%s: xfer too short %d\n", sc->sc_dev.dv_xname,
792: len));
793: ifp->if_ierrors++;
794: goto skip;
795: }
796:
797: desc = (const struct rum_rx_desc *)data->buf;
798:
799: if (letoh32(desc->flags) & RT2573_RX_CRC_ERROR) {
800: /*
801: * This should not happen since we did not request to receive
802: * those frames when we filled RT2573_TXRX_CSR0.
803: */
804: DPRINTFN(5, ("CRC error\n"));
805: ifp->if_ierrors++;
806: goto skip;
807: }
808:
809: MGETHDR(mnew, M_DONTWAIT, MT_DATA);
810: if (mnew == NULL) {
811: printf("%s: could not allocate rx mbuf\n",
812: sc->sc_dev.dv_xname);
813: ifp->if_ierrors++;
814: goto skip;
815: }
816: MCLGET(mnew, M_DONTWAIT);
817: if (!(mnew->m_flags & M_EXT)) {
818: printf("%s: could not allocate rx mbuf cluster\n",
819: sc->sc_dev.dv_xname);
820: m_freem(mnew);
821: ifp->if_ierrors++;
822: goto skip;
823: }
824: m = data->m;
825: data->m = mnew;
826: data->buf = mtod(data->m, uint8_t *);
827:
828: /* finalize mbuf */
829: m->m_pkthdr.rcvif = ifp;
830: m->m_data = (caddr_t)(desc + 1);
831: m->m_pkthdr.len = m->m_len = (letoh32(desc->flags) >> 16) & 0xfff;
832:
833: s = splnet();
834:
835: #if NBPFILTER > 0
836: if (sc->sc_drvbpf != NULL) {
837: struct mbuf mb;
838: struct rum_rx_radiotap_header *tap = &sc->sc_rxtap;
839:
840: tap->wr_flags = 0;
841: tap->wr_rate = rum_rxrate(desc);
842: tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
843: tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
844: tap->wr_antenna = sc->rx_ant;
845: tap->wr_antsignal = desc->rssi;
846:
847: mb.m_data = (caddr_t)tap;
848: mb.m_len = sc->sc_rxtap_len;
849: mb.m_next = m;
850: mb.m_nextpkt = NULL;
851: mb.m_type = 0;
852: mb.m_flags = 0;
853: bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
854: }
855: #endif
856:
857: wh = mtod(m, struct ieee80211_frame *);
858: ni = ieee80211_find_rxnode(ic, wh);
859:
860: /* send the frame to the 802.11 layer */
861: ieee80211_input(ifp, m, ni, desc->rssi, 0);
862:
863: /* node is no longer needed */
864: ieee80211_release_node(ic, ni);
865:
866: /*
867: * In HostAP mode, ieee80211_input() will enqueue packets in if_snd
868: * without calling if_start().
869: */
870: if (!IFQ_IS_EMPTY(&ifp->if_snd) && !(ifp->if_flags & IFF_OACTIVE))
871: rum_start(ifp);
872:
873: splx(s);
874:
875: DPRINTFN(15, ("rx done\n"));
876:
877: skip: /* setup a new transfer */
878: usbd_setup_xfer(xfer, sc->sc_rx_pipeh, data, data->buf, MCLBYTES,
879: USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rum_rxeof);
880: (void)usbd_transfer(xfer);
881: }
882:
883: /*
884: * This function is only used by the Rx radiotap code. It returns the rate at
885: * which a given frame was received.
886: */
887: #if NBPFILTER > 0
888: uint8_t
889: rum_rxrate(const struct rum_rx_desc *desc)
890: {
891: if (letoh32(desc->flags) & RT2573_RX_OFDM) {
892: /* reverse function of rum_plcp_signal */
893: switch (desc->rate) {
894: case 0xb: return 12;
895: case 0xf: return 18;
896: case 0xa: return 24;
897: case 0xe: return 36;
898: case 0x9: return 48;
899: case 0xd: return 72;
900: case 0x8: return 96;
901: case 0xc: return 108;
902: }
903: } else {
904: if (desc->rate == 10)
905: return 2;
906: if (desc->rate == 20)
907: return 4;
908: if (desc->rate == 55)
909: return 11;
910: if (desc->rate == 110)
911: return 22;
912: }
913: return 2; /* should not get there */
914: }
915: #endif
916:
917: /*
918: * Return the expected ack rate for a frame transmitted at rate `rate'.
919: */
920: int
921: rum_ack_rate(struct ieee80211com *ic, int rate)
922: {
923: switch (rate) {
924: /* CCK rates */
925: case 2:
926: return 2;
927: case 4:
928: case 11:
929: case 22:
930: return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate;
931:
932: /* OFDM rates */
933: case 12:
934: case 18:
935: return 12;
936: case 24:
937: case 36:
938: return 24;
939: case 48:
940: case 72:
941: case 96:
942: case 108:
943: return 48;
944: }
945:
946: /* default to 1Mbps */
947: return 2;
948: }
949:
950: /*
951: * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'.
952: * The function automatically determines the operating mode depending on the
953: * given rate. `flags' indicates whether short preamble is in use or not.
954: */
955: uint16_t
956: rum_txtime(int len, int rate, uint32_t flags)
957: {
958: uint16_t txtime;
959:
960: if (RUM_RATE_IS_OFDM(rate)) {
961: /* IEEE Std 802.11a-1999, pp. 37 */
962: txtime = (8 + 4 * len + 3 + rate - 1) / rate;
963: txtime = 16 + 4 + 4 * txtime + 6;
964: } else {
965: /* IEEE Std 802.11b-1999, pp. 28 */
966: txtime = (16 * len + rate - 1) / rate;
967: if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE))
968: txtime += 72 + 24;
969: else
970: txtime += 144 + 48;
971: }
972: return txtime;
973: }
974:
975: uint8_t
976: rum_plcp_signal(int rate)
977: {
978: switch (rate) {
979: /* CCK rates (returned values are device-dependent) */
980: case 2: return 0x0;
981: case 4: return 0x1;
982: case 11: return 0x2;
983: case 22: return 0x3;
984:
985: /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
986: case 12: return 0xb;
987: case 18: return 0xf;
988: case 24: return 0xa;
989: case 36: return 0xe;
990: case 48: return 0x9;
991: case 72: return 0xd;
992: case 96: return 0x8;
993: case 108: return 0xc;
994:
995: /* unsupported rates (should not get there) */
996: default: return 0xff;
997: }
998: }
999:
1000: void
1001: rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc,
1002: uint32_t flags, uint16_t xflags, int len, int rate)
1003: {
1004: struct ieee80211com *ic = &sc->sc_ic;
1005: uint16_t plcp_length;
1006: int remainder;
1007:
1008: desc->flags = htole32(flags);
1009: desc->flags |= htole32(RT2573_TX_VALID);
1010: desc->flags |= htole32(len << 16);
1011:
1012: desc->xflags = htole16(xflags);
1013:
1014: desc->wme = htole16(
1015: RT2573_QID(0) |
1016: RT2573_AIFSN(2) |
1017: RT2573_LOGCWMIN(4) |
1018: RT2573_LOGCWMAX(10));
1019:
1020: /* setup PLCP fields */
1021: desc->plcp_signal = rum_plcp_signal(rate);
1022: desc->plcp_service = 4;
1023:
1024: len += IEEE80211_CRC_LEN;
1025: if (RUM_RATE_IS_OFDM(rate)) {
1026: desc->flags |= htole32(RT2573_TX_OFDM);
1027:
1028: plcp_length = len & 0xfff;
1029: desc->plcp_length_hi = plcp_length >> 6;
1030: desc->plcp_length_lo = plcp_length & 0x3f;
1031: } else {
1032: plcp_length = (16 * len + rate - 1) / rate;
1033: if (rate == 22) {
1034: remainder = (16 * len) % 22;
1035: if (remainder != 0 && remainder < 7)
1036: desc->plcp_service |= RT2573_PLCP_LENGEXT;
1037: }
1038: desc->plcp_length_hi = plcp_length >> 8;
1039: desc->plcp_length_lo = plcp_length & 0xff;
1040:
1041: if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
1042: desc->plcp_signal |= 0x08;
1043: }
1044: }
1045:
1046: #define RUM_TX_TIMEOUT 5000
1047:
1048: int
1049: rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
1050: {
1051: struct ieee80211com *ic = &sc->sc_ic;
1052: struct ifnet *ifp = &ic->ic_if;
1053: struct rum_tx_desc *desc;
1054: struct rum_tx_data *data;
1055: struct ieee80211_frame *wh;
1056: uint32_t flags = 0;
1057: uint16_t dur;
1058: usbd_status error;
1059: int rate, xferlen, pktlen, needrts = 0, needcts = 0;
1060:
1061: wh = mtod(m0, struct ieee80211_frame *);
1062:
1063: if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1064: m0 = ieee80211_wep_crypt(ifp, m0, 1);
1065: if (m0 == NULL)
1066: return ENOBUFS;
1067:
1068: /* packet header may have moved, reset our local pointer */
1069: wh = mtod(m0, struct ieee80211_frame *);
1070: }
1071:
1072: /* compute actual packet length (including CRC and crypto overhead) */
1073: pktlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
1074:
1075: /* pickup a rate */
1076: if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
1077: ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
1078: IEEE80211_FC0_TYPE_MGT)) {
1079: /* mgmt/multicast frames are sent at the lowest avail. rate */
1080: rate = ni->ni_rates.rs_rates[0];
1081: } else if (ic->ic_fixed_rate != -1) {
1082: rate = ic->ic_sup_rates[ic->ic_curmode].
1083: rs_rates[ic->ic_fixed_rate];
1084: } else
1085: rate = ni->ni_rates.rs_rates[ni->ni_txrate];
1086: if (rate == 0)
1087: rate = 2; /* XXX should not happen */
1088: rate &= IEEE80211_RATE_VAL;
1089:
1090: /* check if RTS/CTS or CTS-to-self protection must be used */
1091: if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1092: /* multicast frames are not sent at OFDM rates in 802.11b/g */
1093: if (pktlen > ic->ic_rtsthreshold) {
1094: needrts = 1; /* RTS/CTS based on frame length */
1095: } else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
1096: RUM_RATE_IS_OFDM(rate)) {
1097: if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
1098: needcts = 1; /* CTS-to-self */
1099: else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
1100: needrts = 1; /* RTS/CTS */
1101: }
1102: }
1103: if (needrts || needcts) {
1104: struct mbuf *mprot;
1105: int protrate, ackrate;
1106: uint16_t dur;
1107:
1108: protrate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2;
1109: ackrate = rum_ack_rate(ic, rate);
1110:
1111: dur = rum_txtime(pktlen, rate, ic->ic_flags) +
1112: rum_txtime(RUM_ACK_SIZE, ackrate, ic->ic_flags) +
1113: 2 * sc->sifs;
1114: if (needrts) {
1115: dur += rum_txtime(RUM_CTS_SIZE, rum_ack_rate(ic,
1116: protrate), ic->ic_flags) + sc->sifs;
1117: mprot = ieee80211_get_rts(ic, wh, dur);
1118: } else {
1119: mprot = ieee80211_get_cts_to_self(ic, dur);
1120: }
1121: if (mprot == NULL) {
1122: printf("%s: could not allocate protection frame\n",
1123: sc->sc_dev.dv_xname);
1124: m_freem(m0);
1125: return ENOBUFS;
1126: }
1127:
1128: data = &sc->tx_data[sc->tx_cur];
1129: desc = (struct rum_tx_desc *)data->buf;
1130:
1131: /* avoid multiple free() of the same node for each fragment */
1132: data->ni = ieee80211_ref_node(ni);
1133:
1134: m_copydata(mprot, 0, mprot->m_pkthdr.len,
1135: data->buf + RT2573_TX_DESC_SIZE);
1136: rum_setup_tx_desc(sc, desc,
1137: (needrts ? RT2573_TX_NEED_ACK : 0) | RT2573_TX_MORE_FRAG,
1138: 0, mprot->m_pkthdr.len, protrate);
1139:
1140: /* no roundup necessary here */
1141: xferlen = RT2573_TX_DESC_SIZE + mprot->m_pkthdr.len;
1142:
1143: /* XXX may want to pass the protection frame to BPF */
1144:
1145: /* mbuf is no longer needed */
1146: m_freem(mprot);
1147:
1148: usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf,
1149: xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
1150: RUM_TX_TIMEOUT, rum_txeof);
1151: error = usbd_transfer(data->xfer);
1152: if (error != 0 && error != USBD_IN_PROGRESS) {
1153: m_freem(m0);
1154: return error;
1155: }
1156:
1157: sc->tx_queued++;
1158: sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT;
1159:
1160: flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
1161: }
1162:
1163: data = &sc->tx_data[sc->tx_cur];
1164: desc = (struct rum_tx_desc *)data->buf;
1165:
1166: data->ni = ni;
1167:
1168: if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1169: flags |= RT2573_TX_NEED_ACK;
1170:
1171: dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate),
1172: ic->ic_flags) + sc->sifs;
1173: *(uint16_t *)wh->i_dur = htole16(dur);
1174:
1175: /* tell hardware to set timestamp in probe responses */
1176: if ((wh->i_fc[0] &
1177: (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
1178: (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
1179: flags |= RT2573_TX_TIMESTAMP;
1180: }
1181:
1182: #if NBPFILTER > 0
1183: if (sc->sc_drvbpf != NULL) {
1184: struct mbuf mb;
1185: struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
1186:
1187: tap->wt_flags = 0;
1188: tap->wt_rate = rate;
1189: tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
1190: tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
1191: tap->wt_antenna = sc->tx_ant;
1192:
1193: mb.m_data = (caddr_t)tap;
1194: mb.m_len = sc->sc_txtap_len;
1195: mb.m_next = m0;
1196: mb.m_nextpkt = NULL;
1197: mb.m_type = 0;
1198: mb.m_flags = 0;
1199: bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
1200: }
1201: #endif
1202:
1203: m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE);
1204: rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate);
1205:
1206: /* align end on a 4-bytes boundary */
1207: xferlen = (RT2573_TX_DESC_SIZE + m0->m_pkthdr.len + 3) & ~3;
1208:
1209: /*
1210: * No space left in the last URB to store the extra 4 bytes, force
1211: * sending of another URB.
1212: */
1213: if ((xferlen % 64) == 0)
1214: xferlen += 4;
1215:
1216: DPRINTFN(10, ("sending frame len=%u rate=%u xfer len=%u\n",
1217: m0->m_pkthdr.len + RT2573_TX_DESC_SIZE, rate, xferlen));
1218:
1219: /* mbuf is no longer needed */
1220: m_freem(m0);
1221:
1222: usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen,
1223: USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof);
1224: error = usbd_transfer(data->xfer);
1225: if (error != 0 && error != USBD_IN_PROGRESS)
1226: return error;
1227:
1228: sc->tx_queued++;
1229: sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT;
1230:
1231: return 0;
1232: }
1233:
1234: void
1235: rum_start(struct ifnet *ifp)
1236: {
1237: struct rum_softc *sc = ifp->if_softc;
1238: struct ieee80211com *ic = &sc->sc_ic;
1239: struct ieee80211_node *ni;
1240: struct mbuf *m0;
1241:
1242: /*
1243: * net80211 may still try to send management frames even if the
1244: * IFF_RUNNING flag is not set...
1245: */
1246: if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
1247: return;
1248:
1249: for (;;) {
1250: IF_POLL(&ic->ic_mgtq, m0);
1251: if (m0 != NULL) {
1252: if (sc->tx_queued >= RUM_TX_LIST_COUNT - 1) {
1253: ifp->if_flags |= IFF_OACTIVE;
1254: break;
1255: }
1256: IF_DEQUEUE(&ic->ic_mgtq, m0);
1257:
1258: ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
1259: m0->m_pkthdr.rcvif = NULL;
1260: #if NBPFILTER > 0
1261: if (ic->ic_rawbpf != NULL)
1262: bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
1263: #endif
1264: if (rum_tx_data(sc, m0, ni) != 0)
1265: break;
1266:
1267: } else {
1268: if (ic->ic_state != IEEE80211_S_RUN)
1269: break;
1270: IFQ_POLL(&ifp->if_snd, m0);
1271: if (m0 == NULL)
1272: break;
1273: if (sc->tx_queued >= RUM_TX_LIST_COUNT - 1) {
1274: ifp->if_flags |= IFF_OACTIVE;
1275: break;
1276: }
1277: IFQ_DEQUEUE(&ifp->if_snd, m0);
1278: #if NBPFILTER > 0
1279: if (ifp->if_bpf != NULL)
1280: bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
1281: #endif
1282: m0 = ieee80211_encap(ifp, m0, &ni);
1283: if (m0 == NULL)
1284: continue;
1285: #if NBPFILTER > 0
1286: if (ic->ic_rawbpf != NULL)
1287: bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
1288: #endif
1289: if (rum_tx_data(sc, m0, ni) != 0) {
1290: if (ni != NULL)
1291: ieee80211_release_node(ic, ni);
1292: ifp->if_oerrors++;
1293: break;
1294: }
1295: }
1296:
1297: sc->sc_tx_timer = 5;
1298: ifp->if_timer = 1;
1299: }
1300: }
1301:
1302: void
1303: rum_watchdog(struct ifnet *ifp)
1304: {
1305: struct rum_softc *sc = ifp->if_softc;
1306:
1307: ifp->if_timer = 0;
1308:
1309: if (sc->sc_tx_timer > 0) {
1310: if (--sc->sc_tx_timer == 0) {
1311: printf("%s: device timeout\n", sc->sc_dev.dv_xname);
1312: /*rum_init(ifp); XXX needs a process context! */
1313: ifp->if_oerrors++;
1314: return;
1315: }
1316: ifp->if_timer = 1;
1317: }
1318:
1319: ieee80211_watchdog(ifp);
1320: }
1321:
1322: int
1323: rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1324: {
1325: struct rum_softc *sc = ifp->if_softc;
1326: struct ieee80211com *ic = &sc->sc_ic;
1327: struct ifaddr *ifa;
1328: struct ifreq *ifr;
1329: int s, error = 0;
1330:
1331: s = splnet();
1332:
1333: switch (cmd) {
1334: case SIOCSIFADDR:
1335: ifa = (struct ifaddr *)data;
1336: ifp->if_flags |= IFF_UP;
1337: #ifdef INET
1338: if (ifa->ifa_addr->sa_family == AF_INET)
1339: arp_ifinit(&ic->ic_ac, ifa);
1340: #endif
1341: /* FALLTHROUGH */
1342: case SIOCSIFFLAGS:
1343: if (ifp->if_flags & IFF_UP) {
1344: if (ifp->if_flags & IFF_RUNNING)
1345: rum_update_promisc(sc);
1346: else
1347: rum_init(ifp);
1348: } else {
1349: if (ifp->if_flags & IFF_RUNNING)
1350: rum_stop(ifp, 1);
1351: }
1352: break;
1353:
1354: case SIOCADDMULTI:
1355: case SIOCDELMULTI:
1356: ifr = (struct ifreq *)data;
1357: error = (cmd == SIOCADDMULTI) ?
1358: ether_addmulti(ifr, &ic->ic_ac) :
1359: ether_delmulti(ifr, &ic->ic_ac);
1360:
1361: if (error == ENETRESET)
1362: error = 0;
1363: break;
1364:
1365: case SIOCS80211CHANNEL:
1366: /*
1367: * This allows for fast channel switching in monitor mode
1368: * (used by kismet). In IBSS mode, we must explicitly reset
1369: * the interface to generate a new beacon frame.
1370: */
1371: error = ieee80211_ioctl(ifp, cmd, data);
1372: if (error == ENETRESET &&
1373: ic->ic_opmode == IEEE80211_M_MONITOR) {
1374: if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
1375: (IFF_UP | IFF_RUNNING))
1376: rum_set_chan(sc, ic->ic_ibss_chan);
1377: error = 0;
1378: }
1379: break;
1380:
1381: default:
1382: error = ieee80211_ioctl(ifp, cmd, data);
1383: }
1384:
1385: if (error == ENETRESET) {
1386: if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
1387: (IFF_UP | IFF_RUNNING))
1388: rum_init(ifp);
1389: error = 0;
1390: }
1391:
1392: splx(s);
1393:
1394: return error;
1395: }
1396:
1397: void
1398: rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len)
1399: {
1400: usb_device_request_t req;
1401: usbd_status error;
1402:
1403: req.bmRequestType = UT_READ_VENDOR_DEVICE;
1404: req.bRequest = RT2573_READ_EEPROM;
1405: USETW(req.wValue, 0);
1406: USETW(req.wIndex, addr);
1407: USETW(req.wLength, len);
1408:
1409: error = usbd_do_request(sc->sc_udev, &req, buf);
1410: if (error != 0) {
1411: printf("%s: could not read EEPROM: %s\n",
1412: sc->sc_dev.dv_xname, usbd_errstr(error));
1413: }
1414: }
1415:
1416: uint32_t
1417: rum_read(struct rum_softc *sc, uint16_t reg)
1418: {
1419: uint32_t val;
1420:
1421: rum_read_multi(sc, reg, &val, sizeof val);
1422:
1423: return letoh32(val);
1424: }
1425:
1426: void
1427: rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len)
1428: {
1429: usb_device_request_t req;
1430: usbd_status error;
1431:
1432: req.bmRequestType = UT_READ_VENDOR_DEVICE;
1433: req.bRequest = RT2573_READ_MULTI_MAC;
1434: USETW(req.wValue, 0);
1435: USETW(req.wIndex, reg);
1436: USETW(req.wLength, len);
1437:
1438: error = usbd_do_request(sc->sc_udev, &req, buf);
1439: if (error != 0) {
1440: printf("%s: could not multi read MAC register: %s\n",
1441: sc->sc_dev.dv_xname, usbd_errstr(error));
1442: }
1443: }
1444:
1445: void
1446: rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val)
1447: {
1448: uint32_t tmp = htole32(val);
1449:
1450: rum_write_multi(sc, reg, &tmp, sizeof tmp);
1451: }
1452:
1453: void
1454: rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len)
1455: {
1456: usb_device_request_t req;
1457: usbd_status error;
1458:
1459: req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1460: req.bRequest = RT2573_WRITE_MULTI_MAC;
1461: USETW(req.wValue, 0);
1462: USETW(req.wIndex, reg);
1463: USETW(req.wLength, len);
1464:
1465: error = usbd_do_request(sc->sc_udev, &req, buf);
1466: if (error != 0) {
1467: printf("%s: could not multi write MAC register: %s\n",
1468: sc->sc_dev.dv_xname, usbd_errstr(error));
1469: }
1470: }
1471:
1472: void
1473: rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val)
1474: {
1475: uint32_t tmp;
1476: int ntries;
1477:
1478: for (ntries = 0; ntries < 5; ntries++) {
1479: if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
1480: break;
1481: }
1482: if (ntries == 5) {
1483: printf("%s: could not write to BBP\n", sc->sc_dev.dv_xname);
1484: return;
1485: }
1486:
1487: tmp = RT2573_BBP_BUSY | (reg & 0x7f) << 8 | val;
1488: rum_write(sc, RT2573_PHY_CSR3, tmp);
1489: }
1490:
1491: uint8_t
1492: rum_bbp_read(struct rum_softc *sc, uint8_t reg)
1493: {
1494: uint32_t val;
1495: int ntries;
1496:
1497: for (ntries = 0; ntries < 5; ntries++) {
1498: if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
1499: break;
1500: }
1501: if (ntries == 5) {
1502: printf("%s: could not read BBP\n", sc->sc_dev.dv_xname);
1503: return 0;
1504: }
1505:
1506: val = RT2573_BBP_BUSY | RT2573_BBP_READ | reg << 8;
1507: rum_write(sc, RT2573_PHY_CSR3, val);
1508:
1509: for (ntries = 0; ntries < 100; ntries++) {
1510: val = rum_read(sc, RT2573_PHY_CSR3);
1511: if (!(val & RT2573_BBP_BUSY))
1512: return val & 0xff;
1513: DELAY(1);
1514: }
1515:
1516: printf("%s: could not read BBP\n", sc->sc_dev.dv_xname);
1517: return 0;
1518: }
1519:
1520: void
1521: rum_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val)
1522: {
1523: uint32_t tmp;
1524: int ntries;
1525:
1526: for (ntries = 0; ntries < 5; ntries++) {
1527: if (!(rum_read(sc, RT2573_PHY_CSR4) & RT2573_RF_BUSY))
1528: break;
1529: }
1530: if (ntries == 5) {
1531: printf("%s: could not write to RF\n", sc->sc_dev.dv_xname);
1532: return;
1533: }
1534:
1535: tmp = RT2573_RF_BUSY | RT2573_RF_20BIT | (val & 0xfffff) << 2 |
1536: (reg & 3);
1537: rum_write(sc, RT2573_PHY_CSR4, tmp);
1538:
1539: /* remember last written value in sc */
1540: sc->rf_regs[reg] = val;
1541:
1542: DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 3, val & 0xfffff));
1543: }
1544:
1545: void
1546: rum_select_antenna(struct rum_softc *sc)
1547: {
1548: uint8_t bbp4, bbp77;
1549: uint32_t tmp;
1550:
1551: bbp4 = rum_bbp_read(sc, 4);
1552: bbp77 = rum_bbp_read(sc, 77);
1553:
1554: /* TBD */
1555:
1556: /* make sure Rx is disabled before switching antenna */
1557: tmp = rum_read(sc, RT2573_TXRX_CSR0);
1558: rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
1559:
1560: rum_bbp_write(sc, 4, bbp4);
1561: rum_bbp_write(sc, 77, bbp77);
1562:
1563: rum_write(sc, RT2573_TXRX_CSR0, tmp);
1564: }
1565:
1566: /*
1567: * Enable multi-rate retries for frames sent at OFDM rates.
1568: * In 802.11b/g mode, allow fallback to CCK rates.
1569: */
1570: void
1571: rum_enable_mrr(struct rum_softc *sc)
1572: {
1573: struct ieee80211com *ic = &sc->sc_ic;
1574: uint32_t tmp;
1575:
1576: tmp = rum_read(sc, RT2573_TXRX_CSR4);
1577:
1578: tmp &= ~RT2573_MRR_CCK_FALLBACK;
1579: if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan))
1580: tmp |= RT2573_MRR_CCK_FALLBACK;
1581: tmp |= RT2573_MRR_ENABLED;
1582:
1583: rum_write(sc, RT2573_TXRX_CSR4, tmp);
1584: }
1585:
1586: void
1587: rum_set_txpreamble(struct rum_softc *sc)
1588: {
1589: uint32_t tmp;
1590:
1591: tmp = rum_read(sc, RT2573_TXRX_CSR4);
1592:
1593: tmp &= ~RT2573_SHORT_PREAMBLE;
1594: if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE)
1595: tmp |= RT2573_SHORT_PREAMBLE;
1596:
1597: rum_write(sc, RT2573_TXRX_CSR4, tmp);
1598: }
1599:
1600: void
1601: rum_set_basicrates(struct rum_softc *sc)
1602: {
1603: struct ieee80211com *ic = &sc->sc_ic;
1604:
1605: /* update basic rate set */
1606: if (ic->ic_curmode == IEEE80211_MODE_11B) {
1607: /* 11b basic rates: 1, 2Mbps */
1608: rum_write(sc, RT2573_TXRX_CSR5, 0x3);
1609: } else if (ic->ic_curmode == IEEE80211_MODE_11A) {
1610: /* 11a basic rates: 6, 12, 24Mbps */
1611: rum_write(sc, RT2573_TXRX_CSR5, 0x150);
1612: } else {
1613: /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
1614: rum_write(sc, RT2573_TXRX_CSR5, 0xf);
1615: }
1616: }
1617:
1618: /*
1619: * Reprogram MAC/BBP to switch to a new band. Values taken from the reference
1620: * driver.
1621: */
1622: void
1623: rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c)
1624: {
1625: uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
1626: uint32_t tmp;
1627:
1628: /* update all BBP registers that depend on the band */
1629: bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c;
1630: bbp35 = 0x50; bbp97 = 0x48; bbp98 = 0x48;
1631: if (IEEE80211_IS_CHAN_5GHZ(c)) {
1632: bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c;
1633: bbp35 += 0x10; bbp97 += 0x10; bbp98 += 0x10;
1634: }
1635: if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
1636: (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
1637: bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10;
1638: }
1639:
1640: sc->bbp17 = bbp17;
1641: rum_bbp_write(sc, 17, bbp17);
1642: rum_bbp_write(sc, 96, bbp96);
1643: rum_bbp_write(sc, 104, bbp104);
1644:
1645: if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
1646: (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
1647: rum_bbp_write(sc, 75, 0x80);
1648: rum_bbp_write(sc, 86, 0x80);
1649: rum_bbp_write(sc, 88, 0x80);
1650: }
1651:
1652: rum_bbp_write(sc, 35, bbp35);
1653: rum_bbp_write(sc, 97, bbp97);
1654: rum_bbp_write(sc, 98, bbp98);
1655:
1656: tmp = rum_read(sc, RT2573_PHY_CSR0);
1657: tmp &= ~(RT2573_PA_PE_2GHZ | RT2573_PA_PE_5GHZ);
1658: if (IEEE80211_IS_CHAN_2GHZ(c))
1659: tmp |= RT2573_PA_PE_2GHZ;
1660: else
1661: tmp |= RT2573_PA_PE_5GHZ;
1662: rum_write(sc, RT2573_PHY_CSR0, tmp);
1663:
1664: /* 802.11a uses a 16 microseconds short interframe space */
1665: sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10;
1666: }
1667:
1668: void
1669: rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c)
1670: {
1671: struct ieee80211com *ic = &sc->sc_ic;
1672: const struct rfprog *rfprog;
1673: uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT;
1674: int8_t power;
1675: u_int i, chan;
1676:
1677: chan = ieee80211_chan2ieee(ic, c);
1678: if (chan == 0 || chan == IEEE80211_CHAN_ANY)
1679: return;
1680:
1681: /* select the appropriate RF settings based on what EEPROM says */
1682: rfprog = (sc->rf_rev == RT2573_RF_5225 ||
1683: sc->rf_rev == RT2573_RF_2527) ? rum_rf5225 : rum_rf5226;
1684:
1685: /* find the settings for this channel (we know it exists) */
1686: for (i = 0; rfprog[i].chan != chan; i++);
1687:
1688: power = sc->txpow[i];
1689: if (power < 0) {
1690: bbp94 += power;
1691: power = 0;
1692: } else if (power > 31) {
1693: bbp94 += power - 31;
1694: power = 31;
1695: }
1696:
1697: /*
1698: * If we are switching from the 2GHz band to the 5GHz band or
1699: * vice-versa, BBP registers need to be reprogrammed.
1700: */
1701: if (c->ic_flags != sc->sc_curchan->ic_flags) {
1702: rum_select_band(sc, c);
1703: rum_select_antenna(sc);
1704: }
1705: sc->sc_curchan = c;
1706:
1707: rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1708: rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1709: rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
1710: rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1711:
1712: rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1713: rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1714: rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7 | 1);
1715: rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1716:
1717: rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1718: rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1719: rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
1720: rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1721:
1722: DELAY(10);
1723:
1724: /* enable smart mode for MIMO-capable RFs */
1725: bbp3 = rum_bbp_read(sc, 3);
1726:
1727: bbp3 &= ~RT2573_SMART_MODE;
1728: if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_2527)
1729: bbp3 |= RT2573_SMART_MODE;
1730:
1731: rum_bbp_write(sc, 3, bbp3);
1732:
1733: if (bbp94 != RT2573_BBPR94_DEFAULT)
1734: rum_bbp_write(sc, 94, bbp94);
1735: }
1736:
1737: /*
1738: * Enable TSF synchronization and tell h/w to start sending beacons for IBSS
1739: * and HostAP operating modes.
1740: */
1741: void
1742: rum_enable_tsf_sync(struct rum_softc *sc)
1743: {
1744: struct ieee80211com *ic = &sc->sc_ic;
1745: uint32_t tmp;
1746:
1747: if (ic->ic_opmode != IEEE80211_M_STA) {
1748: /*
1749: * Change default 16ms TBTT adjustment to 8ms.
1750: * Must be done before enabling beacon generation.
1751: */
1752: rum_write(sc, RT2573_TXRX_CSR10, 1 << 12 | 8);
1753: }
1754:
1755: tmp = rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000;
1756:
1757: /* set beacon interval (in 1/16ms unit) */
1758: tmp |= ic->ic_bss->ni_intval * 16;
1759:
1760: tmp |= RT2573_TSF_TICKING | RT2573_ENABLE_TBTT;
1761: if (ic->ic_opmode == IEEE80211_M_STA)
1762: tmp |= RT2573_TSF_MODE(1);
1763: else
1764: tmp |= RT2573_TSF_MODE(2) | RT2573_GENERATE_BEACON;
1765:
1766: rum_write(sc, RT2573_TXRX_CSR9, tmp);
1767: }
1768:
1769: void
1770: rum_update_slot(struct rum_softc *sc)
1771: {
1772: struct ieee80211com *ic = &sc->sc_ic;
1773: uint8_t slottime;
1774: uint32_t tmp;
1775:
1776: slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
1777:
1778: tmp = rum_read(sc, RT2573_MAC_CSR9);
1779: tmp = (tmp & ~0xff) | slottime;
1780: rum_write(sc, RT2573_MAC_CSR9, tmp);
1781:
1782: DPRINTF(("setting slot time to %uus\n", slottime));
1783: }
1784:
1785: void
1786: rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid)
1787: {
1788: uint32_t tmp;
1789:
1790: tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24;
1791: rum_write(sc, RT2573_MAC_CSR4, tmp);
1792:
1793: tmp = bssid[4] | bssid[5] << 8 | RT2573_ONE_BSSID << 16;
1794: rum_write(sc, RT2573_MAC_CSR5, tmp);
1795: }
1796:
1797: void
1798: rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr)
1799: {
1800: uint32_t tmp;
1801:
1802: tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24;
1803: rum_write(sc, RT2573_MAC_CSR2, tmp);
1804:
1805: tmp = addr[4] | addr[5] << 8 | 0xff << 16;
1806: rum_write(sc, RT2573_MAC_CSR3, tmp);
1807: }
1808:
1809: void
1810: rum_update_promisc(struct rum_softc *sc)
1811: {
1812: struct ifnet *ifp = &sc->sc_ic.ic_if;
1813: uint32_t tmp;
1814:
1815: tmp = rum_read(sc, RT2573_TXRX_CSR0);
1816:
1817: tmp &= ~RT2573_DROP_NOT_TO_ME;
1818: if (!(ifp->if_flags & IFF_PROMISC))
1819: tmp |= RT2573_DROP_NOT_TO_ME;
1820:
1821: rum_write(sc, RT2573_TXRX_CSR0, tmp);
1822:
1823: DPRINTF(("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
1824: "entering" : "leaving"));
1825: }
1826:
1827: const char *
1828: rum_get_rf(int rev)
1829: {
1830: switch (rev) {
1831: case RT2573_RF_2527: return "RT2527 (MIMO XR)";
1832: case RT2573_RF_2528: return "RT2528";
1833: case RT2573_RF_5225: return "RT5225 (MIMO XR)";
1834: case RT2573_RF_5226: return "RT5226";
1835: default: return "unknown";
1836: }
1837: }
1838:
1839: void
1840: rum_read_eeprom(struct rum_softc *sc)
1841: {
1842: struct ieee80211com *ic = &sc->sc_ic;
1843: uint16_t val;
1844: #ifdef RUM_DEBUG
1845: int i;
1846: #endif
1847:
1848: /* read MAC/BBP type */
1849: rum_eeprom_read(sc, RT2573_EEPROM_MACBBP, &val, 2);
1850: sc->macbbp_rev = letoh16(val);
1851:
1852: /* read MAC address */
1853: rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, ic->ic_myaddr, 6);
1854:
1855: rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2);
1856: val = letoh16(val);
1857: sc->rf_rev = (val >> 11) & 0x1f;
1858: sc->hw_radio = (val >> 10) & 0x1;
1859: sc->rx_ant = (val >> 4) & 0x3;
1860: sc->tx_ant = (val >> 2) & 0x3;
1861: sc->nb_ant = val & 0x3;
1862:
1863: DPRINTF(("RF revision=%d\n", sc->rf_rev));
1864:
1865: rum_eeprom_read(sc, RT2573_EEPROM_CONFIG2, &val, 2);
1866: val = letoh16(val);
1867: sc->ext_5ghz_lna = (val >> 6) & 0x1;
1868: sc->ext_2ghz_lna = (val >> 4) & 0x1;
1869:
1870: DPRINTF(("External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n",
1871: sc->ext_2ghz_lna, sc->ext_5ghz_lna));
1872:
1873: rum_eeprom_read(sc, RT2573_EEPROM_RSSI_2GHZ_OFFSET, &val, 2);
1874: val = letoh16(val);
1875: if ((val & 0xff) != 0xff)
1876: sc->rssi_2ghz_corr = (int8_t)(val & 0xff); /* signed */
1877:
1878: rum_eeprom_read(sc, RT2573_EEPROM_RSSI_5GHZ_OFFSET, &val, 2);
1879: val = letoh16(val);
1880: if ((val & 0xff) != 0xff)
1881: sc->rssi_5ghz_corr = (int8_t)(val & 0xff); /* signed */
1882:
1883: DPRINTF(("RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n",
1884: sc->rssi_2ghz_corr, sc->rssi_5ghz_corr));
1885:
1886: rum_eeprom_read(sc, RT2573_EEPROM_FREQ_OFFSET, &val, 2);
1887: val = letoh16(val);
1888: if ((val & 0xff) != 0xff)
1889: sc->rffreq = val & 0xff;
1890:
1891: DPRINTF(("RF freq=%d\n", sc->rffreq));
1892:
1893: /* read Tx power for all a/b/g channels */
1894: rum_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->txpow, 14);
1895: /* XXX default Tx power for 802.11a channels */
1896: memset(sc->txpow + 14, 24, sizeof (sc->txpow) - 14);
1897: #ifdef RUM_DEBUG
1898: for (i = 0; i < 14; i++)
1899: DPRINTF(("Channel=%d Tx power=%d\n", i + 1, sc->txpow[i]));
1900: #endif
1901:
1902: /* read default values for BBP registers */
1903: rum_eeprom_read(sc, RT2573_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16);
1904: #ifdef RUM_DEBUG
1905: for (i = 0; i < 14; i++) {
1906: if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
1907: continue;
1908: DPRINTF(("BBP R%d=%02x\n", sc->bbp_prom[i].reg,
1909: sc->bbp_prom[i].val));
1910: }
1911: #endif
1912: }
1913:
1914: int
1915: rum_bbp_init(struct rum_softc *sc)
1916: {
1917: #define N(a) (sizeof (a) / sizeof ((a)[0]))
1918: int i, ntries;
1919:
1920: /* wait for BBP to be ready */
1921: for (ntries = 0; ntries < 100; ntries++) {
1922: const uint8_t val = rum_bbp_read(sc, 0);
1923: if (val != 0 && val != 0xff)
1924: break;
1925: DELAY(1000);
1926: }
1927: if (ntries == 100) {
1928: printf("%s: timeout waiting for BBP\n",
1929: sc->sc_dev.dv_xname);
1930: return EIO;
1931: }
1932:
1933: /* initialize BBP registers to default values */
1934: for (i = 0; i < N(rum_def_bbp); i++)
1935: rum_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val);
1936:
1937: /* write vendor-specific BBP values (from EEPROM) */
1938: for (i = 0; i < 16; i++) {
1939: if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
1940: continue;
1941: rum_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
1942: }
1943:
1944: return 0;
1945: #undef N
1946: }
1947:
1948: int
1949: rum_init(struct ifnet *ifp)
1950: {
1951: #define N(a) (sizeof (a) / sizeof ((a)[0]))
1952: struct rum_softc *sc = ifp->if_softc;
1953: struct ieee80211com *ic = &sc->sc_ic;
1954: uint32_t tmp;
1955: usbd_status error;
1956: int i, ntries;
1957:
1958: rum_stop(ifp, 0);
1959:
1960: /* initialize MAC registers to default values */
1961: for (i = 0; i < N(rum_def_mac); i++)
1962: rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val);
1963:
1964: /* set host ready */
1965: rum_write(sc, RT2573_MAC_CSR1, 3);
1966: rum_write(sc, RT2573_MAC_CSR1, 0);
1967:
1968: /* wait for BBP/RF to wakeup */
1969: for (ntries = 0; ntries < 1000; ntries++) {
1970: if (rum_read(sc, RT2573_MAC_CSR12) & 8)
1971: break;
1972: rum_write(sc, RT2573_MAC_CSR12, 4); /* force wakeup */
1973: DELAY(1000);
1974: }
1975: if (ntries == 1000) {
1976: printf("%s: timeout waiting for BBP/RF to wakeup\n",
1977: sc->sc_dev.dv_xname);
1978: goto fail;
1979: }
1980:
1981: if ((error = rum_bbp_init(sc)) != 0)
1982: goto fail;
1983:
1984: /* select default channel */
1985: sc->sc_curchan = ic->ic_bss->ni_chan = ic->ic_ibss_chan;
1986: rum_select_band(sc, sc->sc_curchan);
1987: rum_select_antenna(sc);
1988: rum_set_chan(sc, sc->sc_curchan);
1989:
1990: /* clear STA registers */
1991: rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
1992:
1993: IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
1994: rum_set_macaddr(sc, ic->ic_myaddr);
1995:
1996: /* initialize ASIC */
1997: rum_write(sc, RT2573_MAC_CSR1, 4);
1998:
1999: /*
2000: * Allocate xfer for AMRR statistics requests.
2001: */
2002: sc->amrr_xfer = usbd_alloc_xfer(sc->sc_udev);
2003: if (sc->amrr_xfer == NULL) {
2004: printf("%s: could not allocate AMRR xfer\n",
2005: sc->sc_dev.dv_xname);
2006: goto fail;
2007: }
2008:
2009: /*
2010: * Open Tx and Rx USB bulk pipes.
2011: */
2012: error = usbd_open_pipe(sc->sc_iface, sc->sc_tx_no, USBD_EXCLUSIVE_USE,
2013: &sc->sc_tx_pipeh);
2014: if (error != 0) {
2015: printf("%s: could not open Tx pipe: %s\n",
2016: sc->sc_dev.dv_xname, usbd_errstr(error));
2017: goto fail;
2018: }
2019: error = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE,
2020: &sc->sc_rx_pipeh);
2021: if (error != 0) {
2022: printf("%s: could not open Rx pipe: %s\n",
2023: sc->sc_dev.dv_xname, usbd_errstr(error));
2024: goto fail;
2025: }
2026:
2027: /*
2028: * Allocate Tx and Rx xfer queues.
2029: */
2030: error = rum_alloc_tx_list(sc);
2031: if (error != 0) {
2032: printf("%s: could not allocate Tx list\n",
2033: sc->sc_dev.dv_xname);
2034: goto fail;
2035: }
2036: error = rum_alloc_rx_list(sc);
2037: if (error != 0) {
2038: printf("%s: could not allocate Rx list\n",
2039: sc->sc_dev.dv_xname);
2040: goto fail;
2041: }
2042:
2043: /*
2044: * Start up the receive pipe.
2045: */
2046: for (i = 0; i < RUM_RX_LIST_COUNT; i++) {
2047: struct rum_rx_data *data = &sc->rx_data[i];
2048:
2049: usbd_setup_xfer(data->xfer, sc->sc_rx_pipeh, data, data->buf,
2050: MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rum_rxeof);
2051: error = usbd_transfer(data->xfer);
2052: if (error != 0 && error != USBD_IN_PROGRESS) {
2053: printf("%s: could not queue Rx transfer\n",
2054: sc->sc_dev.dv_xname);
2055: goto fail;
2056: }
2057: }
2058:
2059: /* update Rx filter */
2060: tmp = rum_read(sc, RT2573_TXRX_CSR0) & 0xffff;
2061:
2062: tmp |= RT2573_DROP_PHY_ERROR | RT2573_DROP_CRC_ERROR;
2063: if (ic->ic_opmode != IEEE80211_M_MONITOR) {
2064: tmp |= RT2573_DROP_CTL | RT2573_DROP_VER_ERROR |
2065: RT2573_DROP_ACKCTS;
2066: if (ic->ic_opmode != IEEE80211_M_HOSTAP)
2067: tmp |= RT2573_DROP_TODS;
2068: if (!(ifp->if_flags & IFF_PROMISC))
2069: tmp |= RT2573_DROP_NOT_TO_ME;
2070: }
2071: rum_write(sc, RT2573_TXRX_CSR0, tmp);
2072:
2073: ifp->if_flags &= ~IFF_OACTIVE;
2074: ifp->if_flags |= IFF_RUNNING;
2075:
2076: if (ic->ic_opmode == IEEE80211_M_MONITOR)
2077: ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
2078: else
2079: ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2080:
2081: return 0;
2082:
2083: fail: rum_stop(ifp, 1);
2084: return error;
2085: #undef N
2086: }
2087:
2088: void
2089: rum_stop(struct ifnet *ifp, int disable)
2090: {
2091: struct rum_softc *sc = ifp->if_softc;
2092: struct ieee80211com *ic = &sc->sc_ic;
2093: uint32_t tmp;
2094:
2095: sc->sc_tx_timer = 0;
2096: ifp->if_timer = 0;
2097: ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
2098:
2099: ieee80211_new_state(ic, IEEE80211_S_INIT, -1); /* free all nodes */
2100:
2101: /* disable Rx */
2102: tmp = rum_read(sc, RT2573_TXRX_CSR0);
2103: rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
2104:
2105: /* reset ASIC */
2106: rum_write(sc, RT2573_MAC_CSR1, 3);
2107: rum_write(sc, RT2573_MAC_CSR1, 0);
2108:
2109: if (sc->sc_rx_pipeh != NULL) {
2110: usbd_abort_pipe(sc->sc_rx_pipeh);
2111: usbd_close_pipe(sc->sc_rx_pipeh);
2112: sc->sc_rx_pipeh = NULL;
2113: }
2114: if (sc->sc_tx_pipeh != NULL) {
2115: usbd_abort_pipe(sc->sc_tx_pipeh);
2116: usbd_close_pipe(sc->sc_tx_pipeh);
2117: sc->sc_tx_pipeh = NULL;
2118: }
2119:
2120: rum_free_rx_list(sc);
2121: rum_free_tx_list(sc);
2122: }
2123:
2124: int
2125: rum_load_microcode(struct rum_softc *sc, const u_char *ucode, size_t size)
2126: {
2127: usb_device_request_t req;
2128: uint16_t reg = RT2573_MCU_CODE_BASE;
2129: usbd_status error;
2130:
2131: /* copy firmware image into NIC */
2132: for (; size >= 4; reg += 4, ucode += 4, size -= 4)
2133: rum_write(sc, reg, UGETDW(ucode));
2134:
2135: req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2136: req.bRequest = RT2573_MCU_CNTL;
2137: USETW(req.wValue, RT2573_MCU_RUN);
2138: USETW(req.wIndex, 0);
2139: USETW(req.wLength, 0);
2140:
2141: error = usbd_do_request(sc->sc_udev, &req, NULL);
2142: if (error != 0) {
2143: printf("%s: could not run firmware: %s\n",
2144: sc->sc_dev.dv_xname, usbd_errstr(error));
2145: }
2146: return error;
2147: }
2148:
2149: int
2150: rum_prepare_beacon(struct rum_softc *sc)
2151: {
2152: struct ieee80211com *ic = &sc->sc_ic;
2153: struct rum_tx_desc desc;
2154: struct mbuf *m0;
2155: int rate;
2156:
2157: m0 = ieee80211_beacon_alloc(ic, ic->ic_bss);
2158: if (m0 == NULL) {
2159: printf("%s: could not allocate beacon frame\n",
2160: sc->sc_dev.dv_xname);
2161: return ENOBUFS;
2162: }
2163:
2164: /* send beacons at the lowest available rate */
2165: rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan) ? 12 : 2;
2166:
2167: rum_setup_tx_desc(sc, &desc, RT2573_TX_TIMESTAMP, RT2573_TX_HWSEQ,
2168: m0->m_pkthdr.len, rate);
2169:
2170: /* copy the first 24 bytes of Tx descriptor into NIC memory */
2171: rum_write_multi(sc, RT2573_HW_BEACON_BASE0, (uint8_t *)&desc, 24);
2172:
2173: /* copy beacon header and payload into NIC memory */
2174: rum_write_multi(sc, RT2573_HW_BEACON_BASE0 + 24, mtod(m0, uint8_t *),
2175: m0->m_pkthdr.len);
2176:
2177: m_freem(m0);
2178:
2179: return 0;
2180: }
2181:
2182: void
2183: rum_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
2184: {
2185: /* start with lowest Tx rate */
2186: ni->ni_txrate = 0;
2187: }
2188:
2189: void
2190: rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni)
2191: {
2192: int i;
2193:
2194: /* clear statistic registers (STA_CSR0 to STA_CSR5) */
2195: rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
2196:
2197: ieee80211_amrr_node_init(&sc->amrr, &sc->amn);
2198:
2199: /* set rate to some reasonable initial value */
2200: for (i = ni->ni_rates.rs_nrates - 1;
2201: i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72;
2202: i--);
2203: ni->ni_txrate = i;
2204:
2205: timeout_add(&sc->amrr_to, hz);
2206: }
2207:
2208: void
2209: rum_amrr_timeout(void *arg)
2210: {
2211: struct rum_softc *sc = arg;
2212: usb_device_request_t req;
2213:
2214: /*
2215: * Asynchronously read statistic registers (cleared by read).
2216: */
2217: req.bmRequestType = UT_READ_VENDOR_DEVICE;
2218: req.bRequest = RT2573_READ_MULTI_MAC;
2219: USETW(req.wValue, 0);
2220: USETW(req.wIndex, RT2573_STA_CSR0);
2221: USETW(req.wLength, sizeof sc->sta);
2222:
2223: usbd_setup_default_xfer(sc->amrr_xfer, sc->sc_udev, sc,
2224: USBD_DEFAULT_TIMEOUT, &req, sc->sta, sizeof sc->sta, 0,
2225: rum_amrr_update);
2226: (void)usbd_transfer(sc->amrr_xfer);
2227: }
2228:
2229: void
2230: rum_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv,
2231: usbd_status status)
2232: {
2233: struct rum_softc *sc = (struct rum_softc *)priv;
2234: struct ifnet *ifp = &sc->sc_ic.ic_if;
2235:
2236: if (status != USBD_NORMAL_COMPLETION) {
2237: printf("%s: could not retrieve Tx statistics - cancelling "
2238: "automatic rate control\n", sc->sc_dev.dv_xname);
2239: return;
2240: }
2241:
2242: /* count TX retry-fail as Tx errors */
2243: ifp->if_oerrors += letoh32(sc->sta[5]) >> 16;
2244:
2245: sc->amn.amn_retrycnt =
2246: (letoh32(sc->sta[4]) >> 16) + /* TX one-retry ok count */
2247: (letoh32(sc->sta[5]) & 0xffff) + /* TX more-retry ok count */
2248: (letoh32(sc->sta[5]) >> 16); /* TX retry-fail count */
2249:
2250: sc->amn.amn_txcnt =
2251: sc->amn.amn_retrycnt +
2252: (letoh32(sc->sta[4]) & 0xffff); /* TX no-retry ok count */
2253:
2254: ieee80211_amrr_choose(&sc->amrr, sc->sc_ic.ic_bss, &sc->amn);
2255:
2256: timeout_add(&sc->amrr_to, hz);
2257: }
2258:
2259: int
2260: rum_activate(struct device *self, enum devact act)
2261: {
2262: switch (act) {
2263: case DVACT_ACTIVATE:
2264: return EOPNOTSUPP;
2265:
2266: case DVACT_DEACTIVATE:
2267: break;
2268: }
2269:
2270: return 0;
2271: }
CVSweb