Fixed bug in rt2870_rssi2dbm; LNA gain should be a signed type
[ralink_drivers/rt2870_fbsd8.git] / rt2870.c
blobf9cf4a69e8aa9ff4a0c5b7bbb4b8908fb1e69e81
2 /*-
3 * Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
4 * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include "rt2870_softc.h"
20 #include "rt2870_reg.h"
21 #include "rt2870_eeprom.h"
22 #include "rt2870_ucode.h"
23 #include "rt2870_rxwi.h"
24 #include "rt2870_rxinfo.h"
25 #include "rt2870_txinfo.h"
26 #include "rt2870_txwi.h"
27 #include "rt2870_read_eeprom.h"
28 #include "rt2870_io.h"
29 #include "rt2870_rf.h"
30 #include "rt2870_led.h"
31 #include "rt2870_debug.h"
34 * Defines and macros
37 #define USB_PRODUCT_LINKSYS4_WUSB600N 0x0071
38 #define USB_PRODUCT_DLINK2_DWA140 0x3c09
39 #define USB_PRODUCT_DLINK2_DWA160AREVB 0x3c11
40 #define USB_PRODUCT_ASUS_RT2770F 0x1742
41 #define USB_PRODUCT_RALINK_RT2770 0x2770
43 #define RT2870_USB_CONFIG_INDEX 0
44 #define RT2870_USB_IFACE_INDEX 0
46 #define RT2870_USB_REQ_MAC_READ_MULTI 0x07
48 /* packet length + Rx wireless info + Rx info */
49 #define RT2870_RX_DESC_SIZE \
50 (sizeof(uint32_t) + sizeof(struct rt2870_rxwi) + sizeof(struct rt2870_rxinfo))
52 /* Tx info + Tx wireless info + max padding */
53 #define RT2870_TX_DESC_SIZE \
54 (sizeof(struct rt2870_txinfo) + sizeof(struct rt2870_txwi) + 11)
56 #define RT2870_MAX_AGG_SIZE 3840
58 #define RT2870_USB_RX_BULK_BUFLEN (2048 * 12)
60 #define RT2870_NOISE_FLOOR -95
62 #define RT2870_AID2WCID(aid) ((aid) & 0xff)
64 #define RT2870_ACK_SIZE 14
66 #define IEEE80211_HAS_ADDR4(wh) \
67 (((wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
69 #define RT2870_MS(_v, _f) (((_v) & _f) >> _f##_S)
70 #define RT2870_SM(_v, _f) (((_v) << _f##_S) & _f)
72 #define RT2870_USB_XFER_TIMEOUT 5000
74 #define RT2870_TX_WATCHDOG_TIMEOUT 5
77 * Data structures and types
80 struct rt2870_cmd_argv_keydelete
82 struct ieee80211_key key;
83 uint16_t associd;
87 * Static function prototypes
90 static void rt2870_init_channels(struct rt2870_softc *sc);
92 static void rt2870_init_channels_ht40(struct rt2870_softc *sc);
94 static void rt2870_init_locked(void *priv);
96 static void rt2870_init(void *priv);
98 static int rt2870_init_bbp(struct rt2870_softc *sc);
100 static void rt2870_stop_locked(void *priv);
102 static void rt2870_stop(void *priv);
104 static void rt2870_start(struct ifnet *ifp);
106 static int rt2870_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
108 static struct ieee80211vap *rt2870_vap_create(struct ieee80211com *ic,
109 const char name[IFNAMSIZ], int unit, int opmode, int flags,
110 const uint8_t bssid[IEEE80211_ADDR_LEN],
111 const uint8_t mac[IEEE80211_ADDR_LEN]);
113 static void rt2870_vap_delete(struct ieee80211vap *vap);
115 static int rt2870_vap_reset(struct ieee80211vap *vap, u_long cmd);
117 static int rt2870_vap_newstate(struct ieee80211vap *vap,
118 enum ieee80211_state nstate, int arg);
120 static void rt2870_vap_key_update_begin(struct ieee80211vap *vap);
122 static void rt2870_vap_key_update_end(struct ieee80211vap *vap);
124 static int rt2870_vap_key_set(struct ieee80211vap *vap,
125 const struct ieee80211_key *k, const uint8_t mac[IEEE80211_ADDR_LEN]);
127 static int rt2870_vap_key_delete(struct ieee80211vap *vap,
128 const struct ieee80211_key *k);
130 static void rt2870_vap_update_beacon(struct ieee80211vap *vap, int what);
132 static struct ieee80211_node *rt2870_node_alloc(struct ieee80211vap *vap,
133 const uint8_t mac[IEEE80211_ADDR_LEN]);
135 static int rt2870_setregdomain(struct ieee80211com *ic,
136 struct ieee80211_regdomain *reg,
137 int nchans, struct ieee80211_channel chans[]);
139 static void rt2870_getradiocaps(struct ieee80211com *ic,
140 int maxchans, int *nchans, struct ieee80211_channel chans[]);
142 static void rt2870_scan_start(struct ieee80211com *ic);
144 static void rt2870_scan_end(struct ieee80211com *ic);
146 static void rt2870_set_channel(struct ieee80211com *ic);
148 static void rt2870_newassoc(struct ieee80211_node *ni, int isnew);
150 static void rt2870_updateslot(struct ifnet *ifp);
152 static void rt2870_update_promisc(struct ifnet *ifp);
154 static void rt2870_update_mcast(struct ifnet *ifp);
156 static int rt2870_wme_update(struct ieee80211com *ic);
158 static int rt2870_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
159 const struct ieee80211_bpf_params *params);
161 static int rt2870_recv_action(struct ieee80211_node *ni,
162 const struct ieee80211_frame *wh,
163 const uint8_t *frm, const uint8_t *efrm);
165 static int rt2870_send_action(struct ieee80211_node *ni,
166 int cat, int act, void *sa);
168 static void rt2870_amrr_update_iter_func(void *arg, struct ieee80211_node *ni);
170 static void rt2870_periodic(void *arg);
172 static void rt2870_tx_watchdog(void *arg);
174 static int rt2870_do_async(struct rt2870_softc *sc,
175 void (*cb)(struct rt2870_softc *sc, void *arg),
176 void *arg, int len);
178 static void rt2870_updateslot_cb(struct rt2870_softc *sc, void *arg);
180 static void rt2870_wme_update_cb(struct rt2870_softc *sc, void *arg);
182 static void rt2870_vap_key_delete_cb(struct rt2870_softc *sc, void *arg);
184 static void rt2870_vap_update_beacon_cb(struct rt2870_softc *sc, void *arg);
186 static void rt2870_asic_set_bssid(struct rt2870_softc *sc,
187 const uint8_t *bssid);
189 static void rt2870_asic_set_macaddr(struct rt2870_softc *sc,
190 const uint8_t *addr);
192 static void rt2870_asic_enable_tsf_sync(struct rt2870_softc *sc);
194 static void rt2870_asic_disable_tsf_sync(struct rt2870_softc *sc);
196 static void rt2870_asic_enable_mrr(struct rt2870_softc *sc);
198 static void rt2870_asic_set_txpreamble(struct rt2870_softc *sc);
200 static void rt2870_asic_set_basicrates(struct rt2870_softc *sc);
202 static void rt2870_asic_update_rtsthreshold(struct rt2870_softc *sc);
204 static void rt2870_asic_update_txpower(struct rt2870_softc *sc);
206 static void rt2870_asic_update_promisc(struct rt2870_softc *sc);
208 static void rt2870_asic_updateprot(struct rt2870_softc *sc);
210 static void rt2870_asic_updateslot(struct rt2870_softc *sc);
212 static void rt2870_asic_wme_update(struct rt2870_softc *sc);
214 static int rt2870_asic_update_beacon(struct rt2870_softc *sc,
215 struct ieee80211vap *vap);
217 static void rt2870_asic_clear_keytables(struct rt2870_softc *sc);
219 static uint8_t rt2870_rxrate(struct rt2870_rxwi *rxwi);
221 static uint8_t rt2870_maxrssi_rxpath(struct rt2870_softc *sc,
222 const struct rt2870_rxwi *rxwi);
224 static int8_t rt2870_rssi2dbm(struct rt2870_softc *sc,
225 uint8_t rssi, uint8_t rxpath);
227 static uint8_t rt2870_rate2mcs(uint8_t rate);
229 static void rt2870_rx_frame(struct rt2870_softc *sc,
230 uint8_t *buf, uint32_t dmalen);
232 static int rt2870_tx_mgmt(struct rt2870_softc *sc,
233 struct mbuf *m, struct ieee80211_node *ni, int qid);
235 static int rt2870_tx_data(struct rt2870_softc *sc,
236 struct mbuf *m, struct ieee80211_node *ni, int qid);
238 static int rt2870_tx_raw(struct rt2870_softc *sc,
239 struct mbuf *m, struct ieee80211_node *ni,
240 const struct ieee80211_bpf_params *params);
242 static void rt2870_rx_intr(struct usb_xfer *xfer, usb_error_t error);
244 static void rt2870_tx_intr(struct usb_xfer *xfer, usb_error_t error);
246 static void rt2870_rx_done_task(void *context, int pending);
248 static void rt2870_tx_done_task(void *context, int pending);
250 static void rt2870_periodic_task(void *context, int pending);
252 static void rt2870_cmd_task(void *context, int pending);
254 static int rt2870_rx_eof(struct rt2870_softc *sc, int limit);
256 static void rt2870_tx_eof(struct rt2870_softc *sc,
257 struct rt2870_softc_tx_ring *ring);
259 static void rt2870_update_stats(struct rt2870_softc *sc);
261 static void rt2870_watchdog(struct rt2870_softc *sc);
263 static void rt2870_drain_fifo_stats(struct rt2870_softc *sc);
265 static void rt2870_update_raw_counters(struct rt2870_softc *sc);
267 static int rt2870_txrx_enable(struct rt2870_softc *sc);
269 static int rt2870_alloc_rx_ring(struct rt2870_softc *sc,
270 struct rt2870_softc_rx_ring *ring);
272 static void rt2870_reset_rx_ring(struct rt2870_softc *sc,
273 struct rt2870_softc_rx_ring *ring);
275 static void rt2870_free_rx_ring(struct rt2870_softc *sc,
276 struct rt2870_softc_rx_ring *ring);
278 static int rt2870_alloc_tx_ring(struct rt2870_softc *sc,
279 struct rt2870_softc_tx_ring *ring, int qid);
281 static void rt2870_reset_tx_ring(struct rt2870_softc *sc,
282 struct rt2870_softc_tx_ring *ring);
284 static void rt2870_free_tx_ring(struct rt2870_softc *sc,
285 struct rt2870_softc_tx_ring *ring);
287 static void rt2870_reset_cmd_ring(struct rt2870_softc *sc,
288 struct rt2870_softc_cmd_ring *ring);
290 static void rt2870_sysctl_attach(struct rt2870_softc *sc);
293 * Static variables
296 static const struct usb_device_id rt2870_usb_devid[] =
298 { USB_VP(USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB600N) }, /* Linksys WUSB600N */
299 { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA140) }, /* D-Link DWA-140 */
300 { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160AREVB) }, /* D-Link DWA-160A Rev. B */
301 { USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2770F) }, /* Asus RT2770F */
302 { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2770) }, /* Ralink RT2770 */
305 static const struct usb_config rt2870_usb_config[RT2870_SOFTC_USB_XFER_COUNT] =
308 .type = UE_BULK,
309 .endpoint = 0x01,
310 .direction = UE_DIR_IN,
311 .bufsize = RT2870_USB_RX_BULK_BUFLEN,
312 .flags = { .ext_buffer = 1, .pipe_bof = 1, .short_xfer_ok = 1, },
313 .callback = rt2870_rx_intr,
316 .type = UE_BULK,
317 .endpoint = 0x01,
318 .direction = UE_DIR_OUT,
319 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
320 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
321 .callback = rt2870_tx_intr,
322 .timeout = RT2870_USB_XFER_TIMEOUT,
325 .type = UE_BULK,
326 .endpoint = 0x02,
327 .direction = UE_DIR_OUT,
328 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
329 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
330 .callback = rt2870_tx_intr,
331 .timeout = RT2870_USB_XFER_TIMEOUT,
334 .type = UE_BULK,
335 .endpoint = 0x03,
336 .direction = UE_DIR_OUT,
337 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
338 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
339 .callback = rt2870_tx_intr,
340 .timeout = RT2870_USB_XFER_TIMEOUT,
343 .type = UE_BULK,
344 .endpoint = 0x04,
345 .direction = UE_DIR_OUT,
346 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
347 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
348 .callback = rt2870_tx_intr,
349 .timeout = RT2870_USB_XFER_TIMEOUT,
352 .type = UE_BULK,
353 .endpoint = 0x05,
354 .direction = UE_DIR_OUT,
355 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
356 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
357 .callback = rt2870_tx_intr,
358 .timeout = RT2870_USB_XFER_TIMEOUT,
361 .type = UE_BULK,
362 .endpoint = 0x06,
363 .direction = UE_DIR_OUT,
364 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
365 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
366 .callback = rt2870_tx_intr,
367 .timeout = RT2870_USB_XFER_TIMEOUT,
371 static const struct
373 uint32_t reg;
374 uint32_t val;
375 } rt2870_def_mac[] =
377 { RT2870_REG_PBF_BCN_OFFSET0, 0xf8f0e8e0 },
378 { RT2870_REG_PBF_BCN_OFFSET1, 0x6f77d0c8 },
379 { RT2870_REG_LEGACY_BASIC_RATE, 0x0000013f },
380 { RT2870_REG_HT_BASIC_RATE, 0x00008003 },
381 { RT2870_REG_SYS_CTRL, 0x00000000 },
382 { RT2870_REG_RX_FILTER_CFG, 0x00017f97 },
383 { RT2870_REG_BKOFF_SLOT_CFG, 0x00000209 },
384 { RT2870_REG_TX_SW_CFG0, 0x00000000 },
385 { RT2870_REG_TX_SW_CFG1, 0x00080606 },
386 { RT2870_REG_TX_LINK_CFG, 0x00001020 },
387 { RT2870_REG_TX_TIMEOUT_CFG, 0x000a2090 },
388 { RT2870_REG_MAX_LEN_CFG, (1 << 12) | RT2870_MAX_AGG_SIZE },
389 { RT2870_REG_LED_CFG, 0x7f031e46 },
390 { RT2870_REG_PBF_MAX_PCNT, 0x1f3fbf9f },
391 { RT2870_REG_TX_RTY_CFG, 0x47d01f0f },
392 { RT2870_REG_AUTO_RSP_CFG, 0x00000013 },
393 { RT2870_REG_TX_CCK_PROT_CFG, 0x05740003 },
394 { RT2870_REG_TX_OFDM_PROT_CFG, 0x05740003 },
395 { RT2870_REG_PBF_CFG, 0x00f40006 },
396 { RT2870_REG_TX_MM40_PROT_CFG, 0x03f44084 },
397 { RT2870_REG_SCHDMA_WPDMA_GLO_CFG, 0x00000030 },
398 { RT2870_REG_TX_GF20_PROT_CFG, 0x01744004 },
399 { RT2870_REG_TX_GF40_PROT_CFG, 0x03f44084 },
400 { RT2870_REG_TX_MM20_PROT_CFG, 0x01744004 },
401 { RT2870_REG_TX_TXOP_CTRL_CFG, 0x0000583f },
402 { RT2870_REG_TX_RTS_CFG, 0x00092b20 },
403 { RT2870_REG_TX_EXP_ACK_TIME, 0x002400ca },
404 { RT2870_REG_HCCAPSMP_TXOP_HLDR_ET, 0x00000002 },
405 { RT2870_REG_XIFS_TIME_CFG, 0x33a41010 },
406 { RT2870_REG_PWR_PIN_CFG, 0x00000003 },
407 { RT2870_REG_SCHDMA_WMM_AIFSN_CFG, 0x00002273 },
408 { RT2870_REG_SCHDMA_WMM_CWMIN_CFG, 0x00002344 },
409 { RT2870_REG_SCHDMA_WMM_CWMAX_CFG, 0x000034aa },
412 #define RT2870_DEF_MAC_SIZE (sizeof(rt2870_def_mac) / sizeof(rt2870_def_mac[0]))
414 static const struct
416 uint8_t reg;
417 uint8_t val;
418 } rt2870_def_bbp[] =
420 { 65, 0x2c },
421 { 66, 0x38 },
422 { 69, 0x12 },
423 { 70, 0x0a },
424 { 73, 0x10 },
425 { 81, 0x37 },
426 { 82, 0x62 },
427 { 83, 0x6a },
428 { 84, 0x99 },
429 { 86, 0x00 },
430 { 91, 0x04 },
431 { 92, 0x00 },
432 { 103, 0x00 },
433 { 105, 0x05 },
434 { 106, 0x35 },
437 #define RT2870_DEF_BBP_SIZE (sizeof(rt2870_def_bbp) / sizeof(rt2870_def_bbp[0]))
439 SYSCTL_DECL(_hw_rt2870);
441 #ifdef RT2870_DEBUG
442 static int rt2870_debug = 0;
443 SYSCTL_INT(_hw_rt2870, OID_AUTO, debug, CTLFLAG_RW, &rt2870_debug, 0, "rt2870 debug level");
444 TUNABLE_INT("hw.rt2870.debug", &rt2870_debug);
445 #endif
448 * rt2870_probe
450 static int rt2870_probe(device_t dev)
452 struct usb_attach_arg *uaa;
454 uaa = device_get_ivars(dev);
456 if (uaa->usb_mode != USB_MODE_HOST)
457 return ENXIO;
459 if (uaa->info.bConfigIndex != RT2870_USB_CONFIG_INDEX)
460 return ENXIO;
462 if (uaa->info.bIfaceIndex != RT2870_USB_IFACE_INDEX)
463 return ENXIO;
465 return (usbd_lookup_id_by_uaa(rt2870_usb_devid,
466 sizeof(rt2870_usb_devid), uaa));
470 * rt2870_attach
472 static int rt2870_attach(device_t dev)
474 struct rt2870_softc *sc;
475 struct usb_attach_arg *uaa;
476 usb_error_t usb_error;
477 struct ieee80211com *ic;
478 struct ifnet *ifp;
479 struct usb_interface *iface;
480 struct usb_interface_descriptor *iface_desc;
481 uint8_t iface_index;
482 int error, ntries, i;
484 sc = device_get_softc(dev);
485 uaa = device_get_ivars(dev);
487 sc->dev = dev;
488 sc->usb_dev = uaa->device;
490 device_set_usb_desc(dev);
492 #ifdef RT2870_DEBUG
493 sc->debug = rt2870_debug;
495 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
496 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
497 "debug", CTLFLAG_RW, &sc->debug, 0, "rt2870 debug level");
498 #endif
500 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
501 "%s: attaching\n",
502 device_get_nameunit(sc->dev));
504 iface_index = RT2870_USB_IFACE_INDEX;
506 iface = usbd_get_iface(uaa->device, iface_index);
507 if (iface == NULL)
509 printf("%s: could not get USB interface\n",
510 device_get_nameunit(sc->dev));
511 return ENXIO;
514 iface_desc = usbd_get_interface_descriptor(iface);
515 if (iface_desc == NULL)
517 printf("%s: could not get USB interface descriptor\n",
518 device_get_nameunit(sc->dev));
519 return ENXIO;
522 sc->usb_endpoints = iface_desc->bNumEndpoints;
523 if ((sc->usb_endpoints != RT2870_SOFTC_USB_XFER_COUNT) &&
524 (sc->usb_endpoints != RT2870_SOFTC_USB_XFER_COUNT - 2))
526 printf("%s: wrong number of USB endpoints=%d\n",
527 device_get_nameunit(sc->dev), sc->usb_endpoints);
528 return ENXIO;
531 mtx_init(&sc->lock, device_get_nameunit(dev),
532 MTX_NETWORK_LOCK, MTX_DEF);
534 usb_error = usbd_transfer_setup(uaa->device, &iface_index,
535 sc->usb_xfer, rt2870_usb_config, sc->usb_endpoints,
536 sc, &sc->lock);
537 if (usb_error != 0)
539 printf("%s: could not allocate USB transfers: error=%s\n",
540 device_get_nameunit(sc->dev), usbd_errstr(usb_error));
541 error = ENXIO;
542 goto fail;
545 RT2870_SOFTC_LOCK(sc);
547 for (ntries = 0; ntries < 100; ntries++)
549 sc->mac_rev = rt2870_io_mac_read(sc, RT2870_REG_MAC_CSR0);
550 if (sc->mac_rev != 0x00000000 && sc->mac_rev != 0xffffffff)
551 break;
553 DELAY(10);
556 if (ntries == 100)
558 printf("%s: timeout waiting for NIC to initialize\n",
559 device_get_nameunit(sc->dev));
560 error = ENXIO;
561 goto fail;
564 rt2870_read_eeprom(sc);
566 RT2870_SOFTC_UNLOCK(sc);
568 printf("%s: MAC/BBP RT2870 (rev 0x%08x), RF %s\n",
569 device_get_nameunit(sc->dev), sc->mac_rev,
570 rt2870_rf_name(sc->rf_rev));
572 /* allocate Tx and Rx rings */
574 for (i = 0; i < sc->usb_endpoints - 1; i++)
576 error = rt2870_alloc_tx_ring(sc, &sc->tx_ring[i], i);
577 if (error != 0)
579 printf("%s: could not allocate Tx ring #%d\n",
580 device_get_nameunit(sc->dev), i);
581 goto fail;
585 if (sc->usb_endpoints == RT2870_SOFTC_USB_XFER_COUNT)
586 sc->tx_ring_mgtqid = 5;
587 else
588 sc->tx_ring_mgtqid = 0;
590 error = rt2870_alloc_rx_ring(sc, &sc->rx_ring);
591 if (error != 0)
593 printf("%s: could not allocate Rx ring\n",
594 device_get_nameunit(sc->dev));
595 goto fail;
598 callout_init(&sc->periodic_ch, 0);
599 callout_init_mtx(&sc->tx_watchdog_ch, &sc->lock, 0);
601 ifp = sc->ifp = if_alloc(IFT_IEEE80211);
602 if (ifp == NULL)
604 printf("%s: could not if_alloc()\n",
605 device_get_nameunit(sc->dev));
606 error = ENOMEM;
607 goto fail;
610 ifp->if_softc = sc;
612 if_initname(ifp, "rt2870", device_get_unit(sc->dev));
614 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
616 ifp->if_init = rt2870_init;
617 ifp->if_ioctl = rt2870_ioctl;
618 ifp->if_start = rt2870_start;
620 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
621 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
622 IFQ_SET_READY(&ifp->if_snd);
624 ic = ifp->if_l2com;
626 ic->ic_ifp = ifp;
628 ic->ic_phytype = IEEE80211_T_HT;
629 ic->ic_opmode = IEEE80211_M_STA;
631 ic->ic_caps = IEEE80211_C_MONITOR |
632 IEEE80211_C_IBSS |
633 IEEE80211_C_STA |
634 IEEE80211_C_AHDEMO |
635 IEEE80211_C_HOSTAP |
636 IEEE80211_C_WDS |
637 IEEE80211_C_MBSS |
638 /* IEEE80211_C_BGSCAN | */
639 IEEE80211_C_TXPMGT |
640 IEEE80211_C_SHPREAMBLE |
641 IEEE80211_C_SHSLOT |
642 IEEE80211_C_TXFRAG |
643 IEEE80211_C_BURST |
644 IEEE80211_C_WME |
645 IEEE80211_C_WPA;
647 ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP |
648 IEEE80211_CRYPTO_TKIP |
649 IEEE80211_CRYPTO_TKIPMIC |
650 IEEE80211_CRYPTO_AES_CCM;
652 ic->ic_htcaps = IEEE80211_HTC_HT |
653 IEEE80211_HTC_AMSDU | /* A-MSDU Tx */
654 IEEE80211_HTCAP_MAXAMSDU_3839 | /* max. A-MSDU Rx length */
655 IEEE80211_HTCAP_CHWIDTH40 | /* HT 40MHz channel width */
656 IEEE80211_HTCAP_GREENFIELD | /* HT greenfield */
657 IEEE80211_HTCAP_SHORTGI20 | /* HT 20MHz short GI */
658 IEEE80211_HTCAP_SHORTGI40 | /* HT 40MHz short GI */
659 IEEE80211_HTCAP_DSSSCCK40; /* HT 40MHz DSSS/CCK modulation */
661 /* spatial streams */
663 if (sc->nrxpath == 2)
664 ic->ic_htcaps |= IEEE80211_HTCAP_RXSTBC_2STREAM;
665 else if (sc->nrxpath == 3)
666 ic->ic_htcaps |= IEEE80211_HTCAP_RXSTBC_3STREAM;
667 else
668 ic->ic_htcaps |= IEEE80211_HTCAP_RXSTBC_1STREAM;
670 if (sc->ntxpath > 1)
671 ic->ic_htcaps |= IEEE80211_HTCAP_TXSTBC;
673 /* delayed BA */
675 if (sc->mac_rev != 0x28600100)
676 ic->ic_htcaps |= IEEE80211_HTCAP_DELBA;
678 /* init channels */
680 ic->ic_nchans = 0;
682 rt2870_init_channels(sc);
684 rt2870_init_channels_ht40(sc);
686 ieee80211_ifattach(ic, sc->mac_addr);
688 ic->ic_vap_create = rt2870_vap_create;
689 ic->ic_vap_delete = rt2870_vap_delete;
691 ic->ic_node_alloc = rt2870_node_alloc;
692 ic->ic_setregdomain = rt2870_setregdomain;
693 ic->ic_getradiocaps = rt2870_getradiocaps;
694 ic->ic_scan_start = rt2870_scan_start;
695 ic->ic_scan_end = rt2870_scan_end;
696 ic->ic_set_channel = rt2870_set_channel;
697 ic->ic_newassoc = rt2870_newassoc;
698 ic->ic_updateslot = rt2870_updateslot;
699 ic->ic_update_promisc = rt2870_update_promisc;
700 ic->ic_update_mcast = rt2870_update_mcast;
701 ic->ic_wme.wme_update = rt2870_wme_update;
702 ic->ic_raw_xmit = rt2870_raw_xmit;
704 sc->recv_action = ic->ic_recv_action;
705 ic->ic_recv_action = rt2870_recv_action;
707 sc->send_action = ic->ic_send_action;
708 ic->ic_send_action = rt2870_send_action;
710 /* hardware requires padding between 802.11 frame header and body */
712 ic->ic_flags |= IEEE80211_F_DATAPAD | IEEE80211_F_DOTH;
714 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;
716 ieee80211_radiotap_attach(ic,
717 &sc->txtap.ihdr, sizeof(sc->txtap),
718 RT2870_SOFTC_TX_RADIOTAP_PRESENT,
719 &sc->rxtap.ihdr, sizeof(sc->rxtap),
720 RT2870_SOFTC_RX_RADIOTAP_PRESENT);
722 /* init task queue */
724 TASK_INIT(&sc->rx_done_task, 0, rt2870_rx_done_task, sc);
725 TASK_INIT(&sc->tx_done_task, 0, rt2870_tx_done_task, sc);
726 TASK_INIT(&sc->periodic_task, 0, rt2870_periodic_task, sc);
727 TASK_INIT(&sc->cmd_task, 0, rt2870_cmd_task, sc);
729 sc->rx_process_limit = 100;
731 sc->taskqueue = taskqueue_create("rt2870_taskq", M_NOWAIT,
732 taskqueue_thread_enqueue, &sc->taskqueue);
734 taskqueue_start_threads(&sc->taskqueue, 1, PI_NET, "%s taskq",
735 device_get_nameunit(sc->dev));
737 rt2870_sysctl_attach(sc);
739 if (bootverbose)
740 ieee80211_announce(ic);
742 return 0;
744 fail:
746 /* stop all USB transfers */
748 usbd_transfer_unsetup(sc->usb_xfer, sc->usb_endpoints);
750 /* free Tx and Rx rings */
752 for (i = 0; i < sc->usb_endpoints - 1; i++)
753 rt2870_free_tx_ring(sc, &sc->tx_ring[i]);
755 rt2870_free_rx_ring(sc, &sc->rx_ring);
757 mtx_destroy(&sc->lock);
759 return error;
763 * rt2870_detach
765 static int rt2870_detach(device_t dev)
767 struct rt2870_softc *sc;
768 struct ieee80211com *ic;
769 struct ifnet *ifp;
770 int i;
772 if (!device_is_attached(dev))
773 return 0;
775 sc = device_get_softc(dev);
776 ifp = sc->ifp;
777 ic = ifp->if_l2com;
779 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
780 "%s: detaching\n",
781 device_get_nameunit(sc->dev));
783 RT2870_SOFTC_LOCK(sc);
785 sc->tx_timer = 0;
787 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
789 callout_stop(&sc->periodic_ch);
790 callout_stop(&sc->tx_watchdog_ch);
792 taskqueue_drain(sc->taskqueue, &sc->rx_done_task);
793 taskqueue_drain(sc->taskqueue, &sc->tx_done_task);
794 taskqueue_drain(sc->taskqueue, &sc->periodic_task);
795 taskqueue_drain(sc->taskqueue, &sc->cmd_task);
797 RT2870_SOFTC_UNLOCK(sc);
799 /* stop all USB transfers */
801 usbd_transfer_unsetup(sc->usb_xfer, sc->usb_endpoints);
803 RT2870_SOFTC_LOCK(sc);
805 /* free Tx and Rx rings */
807 for (i = 0; i < sc->usb_endpoints - 1; i++)
808 rt2870_free_tx_ring(sc, &sc->tx_ring[i]);
810 rt2870_free_rx_ring(sc, &sc->rx_ring);
812 RT2870_SOFTC_UNLOCK(sc);
814 ieee80211_ifdetach(ic);
816 if_free(ifp);
818 taskqueue_free(sc->taskqueue);
820 mtx_destroy(&sc->lock);
822 return 0;
826 * rt2870_init_channels
828 static void rt2870_init_channels(struct rt2870_softc *sc)
830 struct ifnet *ifp;
831 struct ieee80211com *ic;
832 struct ieee80211_channel *c;
833 int i, flags;
835 ifp = sc->ifp;
836 ic = ifp->if_l2com;
838 /* set supported channels for 2GHz band */
840 for (i = 1; i <= 14; i++)
842 c = &ic->ic_channels[ic->ic_nchans++];
843 flags = IEEE80211_CHAN_B;
845 c->ic_freq = ieee80211_ieee2mhz(i, flags);
846 c->ic_ieee = i;
847 c->ic_flags = flags;
849 c = &ic->ic_channels[ic->ic_nchans++];
850 flags = IEEE80211_CHAN_B | IEEE80211_CHAN_HT20;
852 c->ic_freq = ieee80211_ieee2mhz(i, flags);
853 c->ic_ieee = i;
854 c->ic_flags = flags;
856 c = &ic->ic_channels[ic->ic_nchans++];
857 flags = IEEE80211_CHAN_G;
859 c->ic_freq = ieee80211_ieee2mhz(i, flags);
860 c->ic_ieee = i;
861 c->ic_flags = flags;
863 c = &ic->ic_channels[ic->ic_nchans++];
864 flags = IEEE80211_CHAN_G | IEEE80211_CHAN_HT20;
866 c->ic_freq = ieee80211_ieee2mhz(i, flags);
867 c->ic_ieee = i;
868 c->ic_flags = flags;
871 /* set supported channels for 5GHz band */
873 if (sc->rf_rev == RT2870_EEPROM_RF_2850 ||
874 sc->rf_rev == RT2870_EEPROM_RF_2750)
876 for (i = 36; i <= 64; i += 4)
878 c = &ic->ic_channels[ic->ic_nchans++];
879 flags = IEEE80211_CHAN_A;
881 c->ic_freq = ieee80211_ieee2mhz(i, flags);
882 c->ic_ieee = i;
883 c->ic_flags = flags;
885 c = &ic->ic_channels[ic->ic_nchans++];
886 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
888 c->ic_freq = ieee80211_ieee2mhz(i, flags);
889 c->ic_ieee = i;
890 c->ic_flags = flags;
893 for (i = 100; i <= 140; i += 4)
895 c = &ic->ic_channels[ic->ic_nchans++];
896 flags = IEEE80211_CHAN_A;
898 c->ic_freq = ieee80211_ieee2mhz(i, flags);
899 c->ic_ieee = i;
900 c->ic_flags = flags;
902 c = &ic->ic_channels[ic->ic_nchans++];
903 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
905 c->ic_freq = ieee80211_ieee2mhz(i, flags);
906 c->ic_ieee = i;
907 c->ic_flags = flags;
910 for (i = 149; i <= 165; i += 4)
912 c = &ic->ic_channels[ic->ic_nchans++];
913 flags = IEEE80211_CHAN_A;
915 c->ic_freq = ieee80211_ieee2mhz(i, flags);
916 c->ic_ieee = i;
917 c->ic_flags = flags;
919 c = &ic->ic_channels[ic->ic_nchans++];
920 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
922 c->ic_freq = ieee80211_ieee2mhz(i, flags);
923 c->ic_ieee = i;
924 c->ic_flags = flags;
930 * rt2870_init_channels_ht40
932 static void rt2870_init_channels_ht40(struct rt2870_softc *sc)
934 struct ifnet *ifp;
935 struct ieee80211com *ic;
936 struct ieee80211_channel *c, *cent, *ext;
937 int i, flags;
939 ifp = sc->ifp;
940 ic = ifp->if_l2com;
942 /* set supported channels for 2GHz band */
944 for (i = 1; i <= 14; i++)
946 flags = IEEE80211_CHAN_G | IEEE80211_CHAN_HT40;
948 /* find the center channel */
950 cent = ieee80211_find_channel_byieee(ic, i,
951 flags & ~IEEE80211_CHAN_HT);
952 if (cent == NULL)
954 printf("%s: skip channel %d, could not find center channel\n",
955 device_get_nameunit(sc->dev), i);
956 continue;
959 /* find the extension channel */
961 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
962 flags & ~IEEE80211_CHAN_HT);
963 if (ext == NULL)
965 printf("%s: skip channel %d, could not find extension channel\n",
966 device_get_nameunit(sc->dev), i);
967 continue;
970 c = &ic->ic_channels[ic->ic_nchans++];
972 *c = *cent;
973 c->ic_extieee = ext->ic_ieee;
974 c->ic_flags &= ~IEEE80211_CHAN_HT;
975 c->ic_flags |= IEEE80211_CHAN_HT40U;
977 c = &ic->ic_channels[ic->ic_nchans++];
979 *c = *ext;
980 c->ic_extieee = cent->ic_ieee;
981 c->ic_flags &= ~IEEE80211_CHAN_HT;
982 c->ic_flags |= IEEE80211_CHAN_HT40D;
985 /* set supported channels for 5GHz band */
987 if (sc->rf_rev == RT2870_EEPROM_RF_2850 ||
988 sc->rf_rev == RT2870_EEPROM_RF_2750)
990 for (i = 36; i <= 64; i += 4)
992 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
994 /* find the center channel */
996 cent = ieee80211_find_channel_byieee(ic, i,
997 flags & ~IEEE80211_CHAN_HT);
998 if (cent == NULL)
1000 printf("%s: skip channel %d, could not find center channel\n",
1001 device_get_nameunit(sc->dev), i);
1002 continue;
1005 /* find the extension channel */
1007 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1008 flags & ~IEEE80211_CHAN_HT);
1009 if (ext == NULL)
1011 printf("%s: skip channel %d, could not find extension channel\n",
1012 device_get_nameunit(sc->dev), i);
1013 continue;
1016 c = &ic->ic_channels[ic->ic_nchans++];
1018 *c = *cent;
1019 c->ic_extieee = ext->ic_ieee;
1020 c->ic_flags &= ~IEEE80211_CHAN_HT;
1021 c->ic_flags |= IEEE80211_CHAN_HT40U;
1023 c = &ic->ic_channels[ic->ic_nchans++];
1025 *c = *ext;
1026 c->ic_extieee = cent->ic_ieee;
1027 c->ic_flags &= ~IEEE80211_CHAN_HT;
1028 c->ic_flags |= IEEE80211_CHAN_HT40D;
1031 for (i = 100; i <= 140; i += 4)
1033 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
1035 /* find the center channel */
1037 cent = ieee80211_find_channel_byieee(ic, i,
1038 flags & ~IEEE80211_CHAN_HT);
1039 if (cent == NULL)
1041 printf("%s: skip channel %d, could not find center channel\n",
1042 device_get_nameunit(sc->dev), i);
1043 continue;
1046 /* find the extension channel */
1048 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1049 flags & ~IEEE80211_CHAN_HT);
1050 if (ext == NULL)
1052 printf("%s: skip channel %d, could not find extension channel\n",
1053 device_get_nameunit(sc->dev), i);
1054 continue;
1057 c = &ic->ic_channels[ic->ic_nchans++];
1059 *c = *cent;
1060 c->ic_extieee = ext->ic_ieee;
1061 c->ic_flags &= ~IEEE80211_CHAN_HT;
1062 c->ic_flags |= IEEE80211_CHAN_HT40U;
1064 c = &ic->ic_channels[ic->ic_nchans++];
1066 *c = *ext;
1067 c->ic_extieee = cent->ic_ieee;
1068 c->ic_flags &= ~IEEE80211_CHAN_HT;
1069 c->ic_flags |= IEEE80211_CHAN_HT40D;
1072 for (i = 149; i <= 165; i += 4)
1074 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
1076 /* find the center channel */
1078 cent = ieee80211_find_channel_byieee(ic, i,
1079 flags & ~IEEE80211_CHAN_HT);
1080 if (cent == NULL)
1082 printf("%s: skip channel %d, could not find center channel\n",
1083 device_get_nameunit(sc->dev), i);
1084 continue;
1087 /* find the extension channel */
1089 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1090 flags & ~IEEE80211_CHAN_HT);
1091 if (ext == NULL)
1093 printf("%s: skip channel %d, could not find extension channel\n",
1094 device_get_nameunit(sc->dev), i);
1095 continue;
1098 c = &ic->ic_channels[ic->ic_nchans++];
1100 *c = *cent;
1101 c->ic_extieee = ext->ic_ieee;
1102 c->ic_flags &= ~IEEE80211_CHAN_HT;
1103 c->ic_flags |= IEEE80211_CHAN_HT40U;
1105 c = &ic->ic_channels[ic->ic_nchans++];
1107 *c = *ext;
1108 c->ic_extieee = cent->ic_ieee;
1109 c->ic_flags &= ~IEEE80211_CHAN_HT;
1110 c->ic_flags |= IEEE80211_CHAN_HT40D;
1116 * rt2870_init_locked
1118 static void rt2870_init_locked(void *priv)
1120 struct rt2870_softc *sc;
1121 struct ifnet *ifp;
1122 struct ieee80211com *ic;
1123 int ntries, error, i;
1124 uint32_t tmp, stacnt[6];
1126 sc = priv;
1127 ifp = sc->ifp;
1128 ic = ifp->if_l2com;
1130 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1131 "%s: initializing\n",
1132 device_get_nameunit(sc->dev));
1134 RT2870_SOFTC_ASSERT_LOCKED(sc);
1136 if (!(sc->flags & RT2870_SOFTC_FLAGS_UCODE_LOADED))
1138 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1139 "%s: loading 8051 microcode\n",
1140 device_get_nameunit(sc->dev));
1142 error = rt2870_io_mcu_load_ucode(sc, rt2870_ucode, sizeof(rt2870_ucode));
1143 if (error != 0)
1145 printf("%s: could not load 8051 microcode\n",
1146 device_get_nameunit(sc->dev));
1147 goto fail;
1150 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1151 "%s: 8051 microcode was successfully loaded\n",
1152 device_get_nameunit(sc->dev));
1154 sc->flags |= RT2870_SOFTC_FLAGS_UCODE_LOADED;
1157 /* wait while DMA engine is busy */
1159 for (ntries = 0; ntries < 100; ntries++)
1161 tmp = rt2870_io_mac_read(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG);
1162 if (!(tmp & (RT2870_REG_TX_DMA_BUSY | RT2870_REG_RX_DMA_BUSY)))
1163 break;
1165 DELAY(1000);
1168 if (ntries == 100)
1170 printf("%s: timeout waiting for DMA engine\n",
1171 device_get_nameunit(sc->dev));
1172 goto fail;
1175 tmp &= 0xff0;
1176 tmp |= RT2870_REG_TX_WB_DDONE;
1178 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
1180 /* PBF hardware reset */
1182 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_SYS_CTRL);
1184 tmp &= ~(1 << 13);
1186 rt2870_io_mac_write(sc, RT2870_REG_PBF_SYS_CTRL, tmp);
1188 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL,
1189 RT2870_REG_MAC_SRST | RT2870_REG_BBP_HRST);
1191 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_DMA_CFG, 0);
1193 rt2870_io_mcu_reset(sc);
1195 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, 0);
1197 /* init Tx power per rate */
1199 for (i = 0; i < RT2870_SOFTC_TXPOW_RATE_COUNT; i++)
1201 if (sc->txpow_rate_20mhz[i] == 0xffffffff)
1202 continue;
1204 rt2870_io_mac_write(sc, RT2870_REG_TX_PWR_CFG(i),
1205 sc->txpow_rate_20mhz[i]);
1208 for (i = 0; i < RT2870_DEF_MAC_SIZE; i++)
1209 rt2870_io_mac_write(sc, rt2870_def_mac[i].reg,
1210 rt2870_def_mac[i].val);
1212 /* wait while MAC is busy */
1214 for (ntries = 0; ntries < 100; ntries++)
1216 if (!(rt2870_io_mac_read(sc, RT2870_REG_STATUS_CFG) &
1217 (RT2870_REG_STATUS_TX_BUSY | RT2870_REG_STATUS_RX_BUSY)))
1218 break;
1220 DELAY(1000);
1223 if (ntries == 100)
1225 printf("%s: timeout waiting for MAC\n",
1226 device_get_nameunit(sc->dev));
1227 goto fail;
1230 /* clear Host to MCU mailbox */
1232 rt2870_io_mac_write(sc, RT2870_REG_H2M_MAILBOX_BBP_AGENT, 0);
1233 rt2870_io_mac_write(sc, RT2870_REG_H2M_MAILBOX, 0);
1235 DELAY(1000);
1237 error = rt2870_init_bbp(sc);
1238 if (error != 0)
1239 goto fail;
1241 /* set up maximum buffer sizes */
1243 tmp = (1 << 12) | RT2870_MAX_AGG_SIZE;
1245 rt2870_io_mac_write(sc, RT2870_REG_MAX_LEN_CFG, tmp);
1247 if (sc->mac_rev == 0x28720200)
1249 /* set max. PSDU length from 16K to 32K bytes */
1251 tmp = rt2870_io_mac_read(sc, RT2870_REG_MAX_LEN_CFG);
1253 tmp &= ~(3 << 12);
1254 tmp |= (2 << 12);
1256 rt2870_io_mac_write(sc, RT2870_REG_MAX_LEN_CFG, tmp);
1259 if (sc->mac_rev >= 0x28720200 && sc->mac_rev < 0x30700200)
1261 tmp = rt2870_io_mac_read(sc, RT2870_REG_MAX_LEN_CFG);
1263 tmp &= 0xfff;
1264 tmp |= 0x2000;
1266 rt2870_io_mac_write(sc, RT2870_REG_MAX_LEN_CFG, tmp);
1269 /* set mac address */
1271 rt2870_asic_set_macaddr(sc, IF_LLADDR(ifp));
1273 /* clear statistic registers */
1275 rt2870_io_mac_read_multi(sc, RT2870_REG_RX_STA_CNT0,
1276 stacnt, sizeof(stacnt));
1278 /* send LEDs operating mode to microcontroller */
1280 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_LED1,
1281 RT2870_REG_H2M_TOKEN_NO_INTR, sc->led_off[0]);
1282 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_LED2,
1283 RT2870_REG_H2M_TOKEN_NO_INTR, sc->led_off[1]);
1284 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_LED3,
1285 RT2870_REG_H2M_TOKEN_NO_INTR, sc->led_off[2]);
1287 /* write vendor-specific BBP values (from EEPROM) */
1289 for (i = 0; i < RT2870_SOFTC_BBP_EEPROM_COUNT; i++)
1291 if (sc->bbp_eeprom[i].reg == 0x00 ||
1292 sc->bbp_eeprom[i].reg == 0xff)
1293 continue;
1295 rt2870_io_bbp_write(sc, sc->bbp_eeprom[i].reg,
1296 sc->bbp_eeprom[i].val);
1299 /* disable non-existing Rx chains */
1301 tmp = rt2870_io_bbp_read(sc, 3);
1303 tmp &= ~((1 << 4) | (1 << 3));
1305 if (sc->nrxpath == 3)
1306 tmp |= (1 << 4);
1307 else if (sc->nrxpath == 2)
1308 tmp |= (1 << 3);
1310 rt2870_io_bbp_write(sc, 3, tmp);
1312 /* disable non-existing Tx chains */
1314 tmp = rt2870_io_bbp_read(sc, 1);
1316 if (sc->ntxpath == 1)
1317 tmp &= ~((1 << 4) | (1 << 3));
1319 rt2870_io_bbp_write(sc, 1, tmp);
1321 tmp = rt2870_io_bbp_read(sc, 4);
1323 tmp &= ~0x18;
1325 rt2870_io_bbp_write(sc, 4, tmp);
1327 /* set current channel */
1329 rt2870_rf_set_chan(sc, ic->ic_curchan);
1331 /* turn radio LED on */
1333 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_ON);
1335 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_BOOT,
1336 RT2870_REG_H2M_TOKEN_NO_INTR, 0);
1338 /* set RTS threshold */
1340 rt2870_asic_update_rtsthreshold(sc);
1342 /* set Tx power */
1344 rt2870_asic_update_txpower(sc);
1346 /* set up protection mode */
1348 rt2870_asic_updateprot(sc);
1350 /* clear key tables */
1352 rt2870_asic_clear_keytables(sc);
1354 if (rt2870_txrx_enable(sc) != 0)
1355 goto fail;
1357 /* clear garbage interrupts */
1359 tmp = rt2870_io_mac_read(sc, 0x1300);
1361 taskqueue_unblock(sc->taskqueue);
1363 /* init Tx and Rx rings */
1365 for(i = 0; i < sc->usb_endpoints - 1; i++)
1366 rt2870_reset_tx_ring(sc, &sc->tx_ring[i]);
1368 rt2870_reset_rx_ring(sc, &sc->rx_ring);
1370 rt2870_reset_cmd_ring(sc, &sc->cmd_ring);
1372 for(i = 0; i < sc->usb_endpoints - 1; i++)
1374 usbd_xfer_set_priv(sc->usb_xfer[i + 1], &sc->tx_ring[i]);
1375 usbd_xfer_set_stall(sc->usb_xfer[i + 1]);
1378 /* start up the receive pipe */
1380 for(i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
1381 usbd_transfer_start(sc->usb_xfer[0]);
1383 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1384 ifp->if_drv_flags |= IFF_DRV_RUNNING;
1386 sc->periodic_round = 0;
1388 callout_reset(&sc->periodic_ch, hz / 10, rt2870_periodic, sc);
1390 return;
1392 fail:
1394 rt2870_stop_locked(sc);
1398 * rt2870_init
1400 static void rt2870_init(void *priv)
1402 struct rt2870_softc *sc;
1404 sc = priv;
1406 RT2870_SOFTC_LOCK(sc);
1408 rt2870_init_locked(sc);
1410 RT2870_SOFTC_UNLOCK(sc);
1414 * rt2870_init_bbp
1416 static int rt2870_init_bbp(struct rt2870_softc *sc)
1418 int ntries, i;
1419 uint8_t tmp;
1421 for (ntries = 0; ntries < 20; ntries++)
1423 tmp = rt2870_io_bbp_read(sc, 0);
1424 if (tmp != 0x00 && tmp != 0xff)
1425 break;
1428 if (tmp == 0x00 || tmp == 0xff)
1430 printf("%s: timeout waiting for BBP to wakeup\n",
1431 device_get_nameunit(sc->dev));
1432 return ETIMEDOUT;
1435 for (i = 0; i < RT2870_DEF_BBP_SIZE; i++)
1436 rt2870_io_bbp_write(sc, rt2870_def_bbp[i].reg,
1437 rt2870_def_bbp[i].val);
1439 if ((sc->mac_rev & 0xffff) != 0x0101)
1440 rt2870_io_bbp_write(sc, 84, 0x19);
1442 if (sc->mac_rev == 0x28600100)
1444 rt2870_io_bbp_write(sc, 69, 0x16);
1445 rt2870_io_bbp_write(sc, 73, 0x12);
1448 return 0;
1452 * rt2870_stop_locked
1454 static void rt2870_stop_locked(void *priv)
1456 struct rt2870_softc *sc;
1457 struct ifnet *ifp;
1458 struct ieee80211com *ic;
1459 uint32_t tmp;
1460 int i;
1462 sc = priv;
1463 ifp = sc->ifp;
1464 ic = ifp->if_l2com;
1466 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1467 "%s: stopping\n",
1468 device_get_nameunit(sc->dev));
1470 RT2870_SOFTC_ASSERT_LOCKED(sc);
1472 sc->tx_timer = 0;
1474 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1475 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_OFF);
1477 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1479 callout_stop(&sc->periodic_ch);
1480 callout_stop(&sc->tx_watchdog_ch);
1482 RT2870_SOFTC_UNLOCK(sc);
1484 taskqueue_block(sc->taskqueue);
1486 taskqueue_drain(sc->taskqueue, &sc->rx_done_task);
1487 taskqueue_drain(sc->taskqueue, &sc->tx_done_task);
1488 taskqueue_drain(sc->taskqueue, &sc->periodic_task);
1489 taskqueue_drain(sc->taskqueue, &sc->cmd_task);
1491 RT2870_SOFTC_LOCK(sc);
1493 /* clear key tables */
1495 rt2870_asic_clear_keytables(sc);
1497 /* disable Tx/Rx */
1499 tmp = rt2870_io_mac_read(sc, RT2870_REG_SYS_CTRL);
1501 tmp &= ~(RT2870_REG_RX_ENABLE | RT2870_REG_TX_ENABLE);
1503 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, tmp);
1505 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_DMA_CFG, 0);
1507 /* reset adapter */
1509 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL,
1510 RT2870_REG_MAC_SRST | RT2870_REG_BBP_HRST);
1511 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, 0);
1513 /* abort any pending transfers */
1515 for (i = 0; i < sc->usb_endpoints; i++)
1516 usbd_transfer_stop(sc->usb_xfer[i]);
1520 * rt2870_stop
1522 static void rt2870_stop(void *priv)
1524 struct rt2870_softc *sc;
1526 sc = priv;
1528 RT2870_SOFTC_LOCK(sc);
1530 rt2870_stop_locked(sc);
1532 RT2870_SOFTC_UNLOCK(sc);
1536 * rt2870_start
1538 static void rt2870_start(struct ifnet *ifp)
1540 struct rt2870_softc *sc;
1541 struct ieee80211_node *ni;
1542 struct mbuf *m;
1543 int qid;
1545 sc = ifp->if_softc;
1547 RT2870_SOFTC_LOCK(sc);
1549 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1551 RT2870_SOFTC_UNLOCK(sc);
1552 return;
1555 for (;;)
1557 IF_POLL(&ifp->if_snd, m);
1558 if (m == NULL)
1559 break;
1561 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1563 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1565 qid = M_WME_GETAC(m);
1567 if (sc->tx_ring[qid].queued >= RT2870_SOFTC_TX_RING_DATA_COUNT)
1569 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
1570 "%s: if_start: Tx ring with qid=%d is full\n",
1571 device_get_nameunit(sc->dev), qid);
1573 m_freem(m);
1574 ieee80211_free_node(ni);
1575 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1576 ifp->if_oerrors++;
1577 break;
1580 if (rt2870_tx_data(sc, m, ni, qid) != 0)
1582 ieee80211_free_node(ni);
1583 ifp->if_oerrors++;
1584 break;
1587 sc->tx_timer = RT2870_TX_WATCHDOG_TIMEOUT;
1589 callout_reset(&sc->tx_watchdog_ch, hz, rt2870_tx_watchdog, sc);
1592 RT2870_SOFTC_UNLOCK(sc);
1596 * rt2870_ioctl
1598 static int rt2870_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1600 struct rt2870_softc *sc;
1601 struct ieee80211com *ic;
1602 struct ifreq *ifr;
1603 int error, startall;
1605 sc = ifp->if_softc;
1606 ic = ifp->if_l2com;
1607 ifr = (struct ifreq *) data;
1609 error = 0;
1611 switch (cmd)
1613 case SIOCSIFFLAGS:
1614 startall = 0;
1616 RT2870_SOFTC_LOCK(sc);
1618 if (ifp->if_flags & IFF_UP)
1620 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1622 if ((ifp->if_flags ^ sc->if_flags) & IFF_PROMISC)
1623 rt2870_asic_update_promisc(sc);
1625 else
1627 rt2870_init_locked(sc);
1628 startall = 1;
1631 else
1633 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1634 rt2870_stop_locked(sc);
1637 sc->if_flags = ifp->if_flags;
1639 RT2870_SOFTC_UNLOCK(sc);
1641 if (startall)
1642 ieee80211_start_all(ic);
1643 break;
1645 case SIOCGIFMEDIA:
1646 case SIOCSIFMEDIA:
1647 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1648 break;
1650 case SIOCGIFADDR:
1651 error = ether_ioctl(ifp, cmd, data);
1652 break;
1654 default:
1655 error = EINVAL;
1656 break;
1659 return error;
1663 * rt2870_vap_create
1665 static struct ieee80211vap *rt2870_vap_create(struct ieee80211com *ic,
1666 const char name[IFNAMSIZ], int unit, int opmode, int flags,
1667 const uint8_t bssid[IEEE80211_ADDR_LEN],
1668 const uint8_t mac[IEEE80211_ADDR_LEN])
1670 struct rt2870_softc *sc;
1671 struct ifnet *ifp;
1672 struct rt2870_softc_vap *rvap;
1673 struct ieee80211vap *vap;
1675 ifp = ic->ic_ifp;
1676 sc = ifp->if_softc;
1678 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
1679 "%s: VAP create: opmode=%s\n",
1680 device_get_nameunit(sc->dev),
1681 ieee80211_opmode_name[opmode]);
1683 switch (opmode)
1685 case IEEE80211_M_MONITOR:
1686 case IEEE80211_M_IBSS:
1687 case IEEE80211_M_STA:
1688 case IEEE80211_M_AHDEMO:
1689 case IEEE80211_M_HOSTAP:
1690 case IEEE80211_M_MBSS:
1691 if (!TAILQ_EMPTY(&ic->ic_vaps))
1693 if_printf(ifp, "only 1 VAP supported\n");
1694 return NULL;
1697 if (opmode == IEEE80211_M_STA)
1698 flags |= IEEE80211_CLONE_NOBEACONS;
1699 break;
1701 case IEEE80211_M_WDS:
1702 if (TAILQ_EMPTY(&ic->ic_vaps) || ic->ic_opmode != IEEE80211_M_HOSTAP)
1704 if_printf(ifp, "WDS only supported in AP mode\n");
1705 return NULL;
1708 flags &= ~IEEE80211_CLONE_BSSID;
1709 break;
1711 default:
1712 if_printf(ifp, "unknown opmode %d\n", opmode);
1713 return NULL;
1716 rvap = (struct rt2870_softc_vap *) malloc(sizeof(struct rt2870_softc_vap),
1717 M_80211_VAP, M_NOWAIT | M_ZERO);
1718 if (rvap == NULL)
1719 return NULL;
1721 vap = &rvap->vap;
1723 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
1725 rvap->newstate = vap->iv_newstate;
1726 vap->iv_newstate = rt2870_vap_newstate;
1728 vap->iv_reset = rt2870_vap_reset;
1729 vap->iv_key_update_begin = rt2870_vap_key_update_begin;
1730 vap->iv_key_update_end = rt2870_vap_key_update_end;
1731 vap->iv_key_set = rt2870_vap_key_set;
1732 vap->iv_key_delete = rt2870_vap_key_delete;
1733 vap->iv_update_beacon = rt2870_vap_update_beacon;
1735 rt2870_amrr_init(&rvap->amrr, vap,
1736 RT2870_AMRR_MIN_SUCCESS_THRESHOLD,
1737 RT2870_AMRR_MAX_SUCCESS_THRESHOLD,
1738 500);
1740 ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
1742 ic->ic_opmode = opmode;
1744 return vap;
1748 * rt2870_vap_delete
1750 static void rt2870_vap_delete(struct ieee80211vap *vap)
1752 struct rt2870_softc *sc;
1753 struct ieee80211com *ic;
1754 struct ifnet *ifp;
1755 struct rt2870_softc_vap *rvap;
1757 ic = vap->iv_ic;
1758 ifp = ic->ic_ifp;
1759 sc = ifp->if_softc;
1760 rvap = (struct rt2870_softc_vap *) vap;
1762 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
1763 "%s: VAP delete: opmode=%s\n",
1764 device_get_nameunit(sc->dev),
1765 ieee80211_opmode_name[vap->iv_opmode]);
1767 rt2870_amrr_cleanup(&rvap->amrr);
1769 ieee80211_vap_detach(vap);
1771 free(rvap, M_80211_VAP);
1775 * rt2870_reset_vap
1777 static int rt2870_vap_reset(struct ieee80211vap *vap, u_long cmd)
1779 struct rt2870_softc *sc;
1780 struct ieee80211com *ic;
1781 struct ifnet *ifp;
1782 struct rt2870_softc_vap *rvap;
1783 int error;
1785 ic = vap->iv_ic;
1786 ifp = ic->ic_ifp;
1787 sc = ifp->if_softc;
1788 rvap = (struct rt2870_softc_vap *) vap;
1790 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
1791 "%s: VAP reset: cmd=%lu\n",
1792 device_get_nameunit(sc->dev), cmd);
1794 error = 0;
1796 RT2870_SOFTC_LOCK(sc);
1798 switch (cmd)
1800 case IEEE80211_IOC_RTSTHRESHOLD:
1801 rt2870_asic_update_rtsthreshold(sc);
1802 break;
1804 case IEEE80211_IOC_PROTMODE:
1805 case IEEE80211_IOC_HTPROTMODE:
1806 rt2870_asic_updateprot(sc);
1807 break;
1809 case IEEE80211_IOC_TXPOWER:
1810 rt2870_asic_update_txpower(sc);
1811 break;
1813 case IEEE80211_IOC_SHORTGI:
1814 case IEEE80211_IOC_AMPDU_DENSITY:
1815 break;
1817 default:
1818 error = ENETRESET;
1819 break;
1822 RT2870_SOFTC_UNLOCK(sc);
1824 return error;
1828 * rt2870_vap_newstate
1830 static int rt2870_vap_newstate(struct ieee80211vap *vap,
1831 enum ieee80211_state nstate, int arg)
1833 struct rt2870_softc *sc;
1834 struct ieee80211com *ic;
1835 struct ifnet *ifp;
1836 struct rt2870_softc_vap *rvap;
1837 struct ieee80211_node *ni;
1838 int error;
1840 ic = vap->iv_ic;
1841 ifp = ic->ic_ifp;
1842 sc = ifp->if_softc;
1843 rvap = (struct rt2870_softc_vap *) vap;
1845 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
1846 "%s: VAP newstate: %s -> %s\n",
1847 device_get_nameunit(sc->dev),
1848 ieee80211_state_name[vap->iv_state], ieee80211_state_name[nstate]);
1850 error = rvap->newstate(vap, nstate, arg);
1851 if (error != 0)
1852 return error;
1854 IEEE80211_UNLOCK(ic);
1856 RT2870_SOFTC_LOCK(sc);
1858 /* turn link LED off */
1860 if (nstate != IEEE80211_S_RUN)
1861 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_OFF);
1863 switch (nstate)
1865 case IEEE80211_S_INIT:
1866 rt2870_asic_disable_tsf_sync(sc);
1867 break;
1869 case IEEE80211_S_RUN:
1870 ni = vap->iv_bss;
1872 rt2870_rf_set_chan(sc, ni->ni_chan);
1874 if (vap->iv_opmode != IEEE80211_M_MONITOR)
1876 rt2870_asic_enable_mrr(sc);
1877 rt2870_asic_set_txpreamble(sc);
1878 rt2870_asic_set_basicrates(sc);
1879 rt2870_asic_set_bssid(sc, ni->ni_bssid);
1882 if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
1883 vap->iv_opmode == IEEE80211_M_IBSS ||
1884 vap->iv_opmode == IEEE80211_M_MBSS)
1886 error = rt2870_asic_update_beacon(sc, vap);
1887 if (error != 0)
1888 break;
1891 if (vap->iv_opmode != IEEE80211_M_MONITOR)
1892 rt2870_asic_enable_tsf_sync(sc);
1894 /* turn link LED on */
1896 if (ic->ic_opmode != IEEE80211_M_MONITOR)
1898 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_ON |
1899 (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) ?
1900 RT2870_LED_CMD_LINK_2GHZ : RT2870_LED_CMD_LINK_5GHZ));
1902 break;
1904 default:
1905 break;
1908 RT2870_SOFTC_UNLOCK(sc);
1910 IEEE80211_LOCK(ic);
1912 return error;
1916 * rt2870_vap_key_update_begin
1918 static void rt2870_vap_key_update_begin(struct ieee80211vap *vap)
1920 struct rt2870_softc *sc;
1921 struct ieee80211com *ic;
1922 struct ifnet *ifp;
1924 ic = vap->iv_ic;
1925 ifp = ic->ic_ifp;
1926 sc = ifp->if_softc;
1928 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
1929 "%s: VAP key update begin\n",
1930 device_get_nameunit(sc->dev));
1932 taskqueue_block(sc->taskqueue);
1934 IF_LOCK(&ifp->if_snd);
1938 * rt2870_vap_key_update_end
1940 static void rt2870_vap_key_update_end(struct ieee80211vap *vap)
1942 struct rt2870_softc *sc;
1943 struct ieee80211com *ic;
1944 struct ifnet *ifp;
1946 ic = vap->iv_ic;
1947 ifp = ic->ic_ifp;
1948 sc = ifp->if_softc;
1950 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
1951 "%s: VAP key update end\n",
1952 device_get_nameunit(sc->dev));
1954 IF_UNLOCK(&ifp->if_snd);
1956 taskqueue_unblock(sc->taskqueue);
1960 * rt2870_vap_key_set
1962 static int rt2870_vap_key_set(struct ieee80211vap *vap,
1963 const struct ieee80211_key *k, const uint8_t mac[IEEE80211_ADDR_LEN])
1965 struct rt2870_softc *sc;
1966 struct ieee80211com *ic;
1967 struct ifnet *ifp;
1968 struct ieee80211_node *ni;
1969 uint16_t associd, key_base, keymode_base;
1970 uint8_t mode, vapid, wcid, iv[8];
1971 uint32_t tmp;
1973 if (k->wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP &&
1974 k->wk_cipher->ic_cipher != IEEE80211_CIPHER_TKIP &&
1975 k->wk_cipher->ic_cipher != IEEE80211_CIPHER_AES_CCM)
1976 return EINVAL;
1978 ic = vap->iv_ic;
1979 ifp = ic->ic_ifp;
1980 sc = ifp->if_softc;
1982 if (vap->iv_opmode != IEEE80211_M_HOSTAP)
1983 ni = vap->iv_bss;
1984 else
1985 ni = ieee80211_find_vap_node(&ic->ic_sta, vap, mac);
1987 associd = (ni != NULL) ? ni->ni_associd : 0;
1989 if ((vap->iv_opmode == IEEE80211_M_HOSTAP) && (ni != NULL))
1990 ieee80211_free_node(ni);
1992 switch (k->wk_cipher->ic_cipher)
1994 case IEEE80211_CIPHER_WEP:
1995 if(k->wk_keylen < 8)
1996 mode = RT2870_REG_CIPHER_MODE_WEP40;
1997 else
1998 mode = RT2870_REG_CIPHER_MODE_WEP104;
1999 break;
2001 case IEEE80211_CIPHER_TKIP:
2002 mode = RT2870_REG_CIPHER_MODE_TKIP;
2003 break;
2005 case IEEE80211_CIPHER_AES_CCM:
2006 mode = RT2870_REG_CIPHER_MODE_AES_CCMP;
2007 break;
2009 default:
2010 return EINVAL;
2013 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
2014 "%s: VAP key set: keyix=%d, keylen=%d, associd=0x%04x, mode=%d, group=%d\n",
2015 device_get_nameunit(sc->dev), k->wk_keyix, k->wk_keylen, associd, mode,
2016 (k->wk_flags & IEEE80211_KEY_GROUP) ? 1 : 0);
2018 RT2870_SOFTC_LOCK(sc);
2020 if (!(k->wk_flags & IEEE80211_KEY_GROUP))
2022 /* install pairwise key */
2024 vapid = 0;
2025 wcid = RT2870_AID2WCID(associd);
2026 key_base = RT2870_REG_PKEY(wcid);
2028 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP)
2030 memset(iv, 0, 8);
2032 iv[3] = (k->wk_keyix << 6);
2034 else
2036 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
2038 iv[0] = (k->wk_keytsc >> 8);
2039 iv[1] = ((iv[0] | 0x20) & 0x7f);
2040 iv[2] = k->wk_keytsc;
2042 else
2044 /* AES CCMP */
2046 iv[0] = k->wk_keytsc;
2047 iv[1] = k->wk_keytsc >> 8;
2048 iv[2] = 0;
2051 iv[3] = ((k->wk_keyix << 6) | IEEE80211_WEP_EXTIV);
2052 iv[4] = (k->wk_keytsc >> 16);
2053 iv[5] = (k->wk_keytsc >> 24);
2054 iv[6] = (k->wk_keytsc >> 32);
2055 iv[7] = (k->wk_keytsc >> 40);
2057 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
2058 "%s: set key: iv=%02x %02x %02x %02x %02x %02x %02x %02x\n",
2059 device_get_nameunit(sc->dev),
2060 iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]);
2063 rt2870_io_mac_write_multi(sc, RT2870_REG_IVEIV(wcid), iv, 8);
2065 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
2067 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, 16);
2069 if (vap->iv_opmode != IEEE80211_M_HOSTAP)
2071 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[16], 8);
2072 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[24], 8);
2074 else
2076 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[24], 8);
2077 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[16], 8);
2080 else
2082 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, k->wk_keylen);
2085 tmp = ((vapid & RT2870_REG_VAP_MASK) << RT2870_REG_VAP_SHIFT) |
2086 (mode << RT2870_REG_CIPHER_MODE_SHIFT) | RT2870_REG_PKEY_ENABLE;
2088 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
2091 if ((k->wk_flags & IEEE80211_KEY_GROUP) ||
2092 (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP))
2094 /* install group key */
2096 vapid = 0;
2097 key_base = RT2870_REG_SKEY(vapid, k->wk_keyix);
2098 keymode_base = RT2870_REG_SKEY_MODE(vapid);
2100 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
2102 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, 16);
2104 if (vap->iv_opmode != IEEE80211_M_HOSTAP)
2106 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[16], 8);
2107 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[24], 8);
2109 else
2111 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[24], 8);
2112 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[16], 8);
2115 else
2117 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, k->wk_keylen);
2120 tmp = rt2870_io_mac_read(sc, keymode_base);
2122 tmp &= ~(0xf << (k->wk_keyix * 4 + 16 * (vapid % 2)));
2123 tmp |= (mode << (k->wk_keyix * 4 + 16 * (vapid % 2)));
2125 rt2870_io_mac_write(sc, keymode_base, tmp);
2128 RT2870_SOFTC_UNLOCK(sc);
2130 return 1;
2134 * rt2870_vap_key_delete
2136 static int rt2870_vap_key_delete(struct ieee80211vap *vap,
2137 const struct ieee80211_key *k)
2139 struct rt2870_softc *sc;
2140 struct ieee80211com *ic;
2141 struct ifnet *ifp;
2142 struct ieee80211_node *ni;
2143 struct rt2870_cmd_argv_keydelete cmd_argv;
2144 uint16_t associd;
2146 ic = vap->iv_ic;
2147 ifp = ic->ic_ifp;
2148 sc = ifp->if_softc;
2149 ni = vap->iv_bss;
2150 associd = (ni != NULL) ? ni->ni_associd : 0;
2152 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
2153 "%s: VAP key delete: keyix=%d, keylen=%d, associd=0x%04x, group=%d\n",
2154 device_get_nameunit(sc->dev), k->wk_keyix, k->wk_keylen, associd,
2155 (k->wk_flags & IEEE80211_KEY_GROUP) ? 1 : 0);
2157 memcpy(&cmd_argv.key, k, sizeof(struct ieee80211_key));
2158 cmd_argv.associd = associd;
2160 rt2870_do_async(sc, rt2870_vap_key_delete_cb,
2161 &cmd_argv, sizeof(struct rt2870_cmd_argv_keydelete));
2163 return 1;
2167 * rt2870_vap_update_beacon
2169 static void rt2870_vap_update_beacon(struct ieee80211vap *vap, int what)
2171 struct rt2870_softc *sc;
2172 struct ieee80211com *ic;
2173 struct ifnet *ifp;
2175 ic = vap->iv_ic;
2176 ifp = ic->ic_ifp;
2177 sc = ifp->if_softc;
2179 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
2180 "%s: VAP update beacon\n",
2181 device_get_nameunit(sc->dev));
2183 rt2870_do_async(sc, rt2870_vap_update_beacon_cb, NULL, 0);
2187 * rt2870_node_alloc
2189 static struct ieee80211_node *rt2870_node_alloc(struct ieee80211vap *vap,
2190 const uint8_t mac[IEEE80211_ADDR_LEN])
2192 return malloc(sizeof(struct rt2870_softc_node),
2193 M_80211_NODE, M_NOWAIT | M_ZERO);
2197 * rt2870_setregdomain
2199 static int rt2870_setregdomain(struct ieee80211com *ic,
2200 struct ieee80211_regdomain *reg,
2201 int nchans, struct ieee80211_channel chans[])
2203 struct rt2870_softc *sc;
2204 struct ifnet *ifp;
2206 ifp = ic->ic_ifp;
2207 sc = ifp->if_softc;
2209 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
2210 "%s: set regulatory domain: country=%d, country code string=%c%c, location=%c\n",
2211 device_get_nameunit(sc->dev),
2212 reg->country, reg->isocc[0], reg->isocc[1], reg->location);
2214 return 0;
2218 * rt2870_getradiocaps
2220 static void rt2870_getradiocaps(struct ieee80211com *ic,
2221 int maxchans, int *nchans, struct ieee80211_channel chans[])
2223 *nchans = (ic->ic_nchans >= maxchans) ? maxchans : ic->ic_nchans;
2225 memcpy(chans, ic->ic_channels, (*nchans) * sizeof(struct ieee80211_channel));
2229 * rt2870_scan_start
2231 static void rt2870_scan_start(struct ieee80211com *ic)
2233 struct rt2870_softc *sc;
2234 struct ifnet *ifp;
2236 ifp = ic->ic_ifp;
2237 sc = ifp->if_softc;
2239 RT2870_SOFTC_LOCK(sc);
2241 rt2870_asic_disable_tsf_sync(sc);
2243 RT2870_SOFTC_UNLOCK(sc);
2247 * rt2870_scan_end
2249 static void rt2870_scan_end(struct ieee80211com *ic)
2251 struct rt2870_softc *sc;
2252 struct ifnet *ifp;
2254 ifp = ic->ic_ifp;
2255 sc = ifp->if_softc;
2257 RT2870_SOFTC_LOCK(sc);
2259 rt2870_asic_enable_tsf_sync(sc);
2261 RT2870_SOFTC_UNLOCK(sc);
2265 * rt2870_set_channel
2267 static void rt2870_set_channel(struct ieee80211com *ic)
2269 struct rt2870_softc *sc;
2270 struct ifnet *ifp;
2272 ifp = ic->ic_ifp;
2273 sc = ifp->if_softc;
2275 RT2870_DPRINTF(sc, RT2870_DEBUG_CHAN,
2276 "%s: set channel: channel=%u, HT%s%s\n",
2277 device_get_nameunit(sc->dev),
2278 ieee80211_chan2ieee(ic, ic->ic_curchan),
2279 !IEEE80211_IS_CHAN_HT(ic->ic_curchan) ? " disabled" :
2280 IEEE80211_IS_CHAN_HT20(ic->ic_curchan) ? "20":
2281 IEEE80211_IS_CHAN_HT40U(ic->ic_curchan) ? "40U" : "40D",
2282 (ic->ic_flags & IEEE80211_F_SCAN) ? ", scanning" : "");
2284 RT2870_SOFTC_LOCK(sc);
2286 rt2870_rf_set_chan(sc, ic->ic_curchan);
2288 RT2870_SOFTC_UNLOCK(sc);
2292 * rt2870_newassoc
2294 static void rt2870_newassoc(struct ieee80211_node *ni, int isnew)
2296 struct rt2870_softc *sc;
2297 struct ieee80211com *ic;
2298 struct ifnet *ifp;
2299 struct ieee80211vap *vap;
2300 struct rt2870_softc_vap *rvap;
2301 uint16_t associd;
2302 uint8_t wcid;
2304 vap = ni->ni_vap;
2305 ic = vap->iv_ic;
2306 ifp = ic->ic_ifp;
2307 sc = ifp->if_softc;
2308 rvap = (struct rt2870_softc_vap *) vap;
2310 associd = (ni != NULL) ? ni->ni_associd : 0;
2311 wcid = RT2870_AID2WCID(associd);
2313 RT2870_DPRINTF(sc, RT2870_DEBUG_NODE,
2314 "%s: new association: wcid=0x%02x, "
2315 "mac addr=%s, QoS %s, ERP %s, HT %s\n",
2316 device_get_nameunit(sc->dev), wcid,
2317 ether_sprintf(ni->ni_macaddr),
2318 (ni->ni_flags & IEEE80211_NODE_QOS) ? "enabled" : "disabled",
2319 (ni->ni_flags & IEEE80211_NODE_ERP) ? "enabled" : "disabled",
2320 (ni->ni_flags & IEEE80211_NODE_HT) ? "enabled" : "disabled");
2322 RT2870_SOFTC_LOCK(sc);
2324 rt2870_io_mac_write_multi(sc, RT2870_REG_WCID(wcid),
2325 ni->ni_macaddr, IEEE80211_ADDR_LEN);
2327 rt2870_amrr_node_init(&rvap->amrr, &sc->amrr_node[wcid], ni);
2329 RT2870_DPRINTF(sc, RT2870_DEBUG_RATE,
2330 "%s: initial%s node Tx rate: associd=0x%04x, rate=0x%02x, max rate=0x%02x\n",
2331 device_get_nameunit(sc->dev),
2332 (ni->ni_flags & IEEE80211_NODE_HT) ? " HT" : "",
2333 ni->ni_associd, ni->ni_txrate,
2334 (ni->ni_flags & IEEE80211_NODE_HT) ?
2335 (ni->ni_htrates.rs_rates[ni->ni_htrates.rs_nrates - 1] | IEEE80211_RATE_MCS) :
2336 (ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates - 1] & IEEE80211_RATE_VAL));
2338 rt2870_asic_updateprot(sc);
2339 rt2870_asic_updateslot(sc);
2340 rt2870_asic_set_txpreamble(sc);
2342 RT2870_SOFTC_UNLOCK(sc);
2346 * rt2870_updateslot
2348 static void rt2870_updateslot(struct ifnet *ifp)
2350 struct rt2870_softc *sc;
2352 sc = ifp->if_softc;
2354 rt2870_do_async(sc, rt2870_updateslot_cb, NULL, 0);
2358 * rt2870_update_promisc
2360 static void rt2870_update_promisc(struct ifnet *ifp)
2362 struct rt2870_softc *sc;
2364 sc = ifp->if_softc;
2366 RT2870_SOFTC_LOCK(sc);
2368 rt2870_asic_update_promisc(sc);
2370 RT2870_SOFTC_UNLOCK(sc);
2374 * rt2870_update_mcast
2376 static void rt2870_update_mcast(struct ifnet *ifp)
2378 struct rt2870_softc *sc;
2380 sc = ifp->if_softc;
2384 * rt2870_wme_update
2386 static int rt2870_wme_update(struct ieee80211com *ic)
2388 struct rt2870_softc *sc;
2389 struct ifnet *ifp;
2391 ifp = ic->ic_ifp;
2392 sc = ifp->if_softc;
2394 rt2870_do_async(sc, rt2870_wme_update_cb, NULL, 0);
2396 return 0;
2400 * rt2870_raw_xmit
2402 static int rt2870_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2403 const struct ieee80211_bpf_params *params)
2405 struct rt2870_softc *sc;
2406 struct ieee80211com *ic;
2407 struct ifnet *ifp;
2409 ic = ni->ni_ic;
2410 ifp = ic->ic_ifp;
2411 sc = ifp->if_softc;
2413 RT2870_SOFTC_LOCK(sc);
2415 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
2417 RT2870_SOFTC_UNLOCK(sc);
2418 m_freem(m);
2419 ieee80211_free_node(ni);
2420 return ENETDOWN;
2423 if (sc->tx_ring[sc->tx_ring_mgtqid].queued >= RT2870_SOFTC_TX_RING_DATA_COUNT)
2425 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
2426 "%s: raw xmit: Tx ring with qid=%d is full\n",
2427 device_get_nameunit(sc->dev), sc->tx_ring_mgtqid);
2429 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
2430 RT2870_SOFTC_UNLOCK(sc);
2431 m_freem(m);
2432 ieee80211_free_node(ni);
2433 return ENOBUFS;
2436 if (rt2870_tx_mgmt(sc, m, ni, sc->tx_ring_mgtqid) != 0)
2438 ifp->if_oerrors++;
2439 RT2870_SOFTC_UNLOCK(sc);
2440 ieee80211_free_node(ni);
2441 return EIO;
2444 sc->tx_timer = RT2870_TX_WATCHDOG_TIMEOUT;
2446 RT2870_SOFTC_UNLOCK(sc);
2448 return 0;
2452 * rt2870_recv_action
2454 static int rt2870_recv_action(struct ieee80211_node *ni,
2455 const struct ieee80211_frame *wh,
2456 const uint8_t *frm, const uint8_t *efrm)
2458 struct rt2870_softc *sc;
2459 struct ieee80211com *ic;
2460 struct ifnet *ifp;
2461 const struct ieee80211_action *ia;
2462 uint16_t associd, baparamset;
2463 uint8_t wcid;
2464 int ret, tid;
2465 uint32_t tmp;
2467 ic = ni->ni_ic;
2468 ifp = ic->ic_ifp;
2469 sc = ifp->if_softc;
2471 ia = (const struct ieee80211_action *) frm;
2473 ret = sc->recv_action(ni, wh, frm, efrm);
2475 if (ia->ia_category != IEEE80211_ACTION_CAT_BA)
2476 return ret;
2478 associd = (ni != NULL) ? ni->ni_associd : 0;
2479 wcid = RT2870_AID2WCID(associd);
2481 switch (ia->ia_action)
2483 /* IEEE80211_ACTION_BA_ADDBA_REQUEST */
2484 case IEEE80211_ACTION_BA_ADDBA_REQUEST:
2485 baparamset = LE_READ_2(frm + 3);
2486 tid = RT2870_MS(baparamset, IEEE80211_BAPS_TID);
2488 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2489 "%s: adding A-MPDU Rx block ACK: associd=0x%04x, tid=%d\n",
2490 device_get_nameunit(sc->dev), associd, tid);
2492 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID(wcid) + 4);
2494 tmp |= (0x10000 << tid);
2496 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
2497 break;
2499 /* IEEE80211_ACTION_BA_DELBA */
2500 case IEEE80211_ACTION_BA_DELBA:
2501 baparamset = LE_READ_2(frm + 2);
2502 tid = RT2870_MS(baparamset, IEEE80211_BAPS_TID);
2504 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2505 "%s: deleting A-MPDU Rx block ACK: associd=0x%04x, tid=%d\n",
2506 device_get_nameunit(sc->dev), associd, tid);
2508 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID(wcid) + 4);
2510 tmp &= ~(0x10000 << tid);
2512 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
2513 break;
2516 return ret;
2520 * rt2870_send_action
2522 static int rt2870_send_action(struct ieee80211_node *ni,
2523 int cat, int act, void *sa)
2525 struct rt2870_softc *sc;
2526 struct ieee80211com *ic;
2527 struct ifnet *ifp;
2528 uint16_t associd, *args, baparamset;
2529 uint8_t wcid;
2530 int ret, tid;
2531 uint32_t tmp;
2533 ic = ni->ni_ic;
2534 ifp = ic->ic_ifp;
2535 sc = ifp->if_softc;
2537 ret = sc->send_action(ni, cat, act, sa);
2539 if (cat != IEEE80211_ACTION_CAT_BA)
2540 return ret;
2542 associd = (ni != NULL) ? ni->ni_associd : 0;
2543 wcid = RT2870_AID2WCID(associd);
2544 args = sa;
2546 switch (act)
2548 /* IEEE80211_ACTION_BA_DELBA */
2549 case IEEE80211_ACTION_BA_DELBA:
2550 baparamset = RT2870_SM(args[0], IEEE80211_DELBAPS_TID) | args[1];
2552 if (RT2870_MS(baparamset, IEEE80211_DELBAPS_INIT) == IEEE80211_DELBAPS_INIT)
2553 break;
2555 tid = RT2870_MS(baparamset, IEEE80211_DELBAPS_TID);
2557 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2558 "%s: deleting A-MPDU Rx block ACK: associd=0x%04x, tid=%d\n",
2559 device_get_nameunit(sc->dev), associd, tid);
2561 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID(wcid) + 4);
2563 tmp &= ~(0x10000 << tid);
2565 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
2566 break;
2569 return ret;
2573 * rt2870_amrr_update_iter_func
2575 static void rt2870_amrr_update_iter_func(void *arg, struct ieee80211_node *ni)
2577 struct rt2870_softc *sc;
2578 struct ieee80211com *ic;
2579 struct ifnet *ifp;
2580 struct ieee80211vap *vap;
2581 struct rt2870_softc_vap *rvap;
2582 uint8_t wcid;
2584 vap = arg;
2585 ic = vap->iv_ic;
2586 ifp = ic->ic_ifp;
2587 sc = ifp->if_softc;
2588 rvap = (struct rt2870_softc_vap *) vap;
2590 /* only associated stations */
2592 if ((ni->ni_vap == vap) && (ni->ni_associd != 0))
2594 wcid = RT2870_AID2WCID(ni->ni_associd);
2596 rt2870_amrr_choose(ni, &sc->amrr_node[wcid]);
2598 RT2870_DPRINTF(sc, RT2870_DEBUG_RATE,
2599 "%s:%s node Tx rate: associd=0x%04x, rate=0x%02x, max rate=0x%02x\n",
2600 device_get_nameunit(sc->dev),
2601 (ni->ni_flags & IEEE80211_NODE_HT) ? " HT" : "",
2602 ni->ni_associd, ni->ni_txrate,
2603 (ni->ni_flags & IEEE80211_NODE_HT) ?
2604 (ni->ni_htrates.rs_rates[ni->ni_htrates.rs_nrates - 1] | IEEE80211_RATE_MCS) :
2605 (ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates - 1] & IEEE80211_RATE_VAL));
2610 * rt2870_periodic
2612 static void rt2870_periodic(void *arg)
2614 struct rt2870_softc *sc;
2615 struct ifnet *ifp;
2617 sc = arg;
2618 ifp = sc->ifp;
2620 RT2870_DPRINTF(sc, RT2870_DEBUG_PERIODIC,
2621 "%s: periodic\n",
2622 device_get_nameunit(sc->dev));
2624 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
2625 return;
2627 taskqueue_enqueue(sc->taskqueue, &sc->periodic_task);
2631 * rt2870_tx_watchdog
2633 static void rt2870_tx_watchdog(void *arg)
2635 struct rt2870_softc *sc;
2636 struct ifnet *ifp;
2638 sc = arg;
2639 ifp = sc->ifp;
2641 if (sc->tx_timer == 0)
2642 return;
2644 if (--sc->tx_timer == 0)
2646 printf("%s: Tx watchdog timeout: resetting\n",
2647 device_get_nameunit(sc->dev));
2649 rt2870_stop_locked(sc);
2650 rt2870_init_locked(sc);
2652 ifp->if_oerrors++;
2654 sc->tx_watchdog_timeouts++;
2657 callout_reset(&sc->tx_watchdog_ch, hz, rt2870_tx_watchdog, sc);
2661 * rt2870_do_async
2663 static int rt2870_do_async(struct rt2870_softc *sc,
2664 void (*cb)(struct rt2870_softc *sc, void *arg),
2665 void *arg, int len)
2667 struct ifnet *ifp;
2668 struct rt2870_softc_cmd_ring *ring;
2669 struct rt2870_softc_cmd *cmd;
2670 int run_cmd_task;
2672 ifp = sc->ifp;
2673 ring = &sc->cmd_ring;
2675 RT2870_SOFTC_LOCK(sc);
2677 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
2679 RT2870_SOFTC_UNLOCK(sc);
2680 return -1;
2683 if (ring->queued >= RT2870_SOFTC_CMD_RING_CMD_COUNT)
2685 RT2870_SOFTC_UNLOCK(sc);
2686 return -1;
2689 cmd = STAILQ_FIRST(&ring->inactive);
2690 STAILQ_REMOVE_HEAD(&ring->inactive, next);
2692 cmd->cb = cb;
2694 if(arg != NULL)
2695 memcpy(cmd->data, arg, len);
2697 STAILQ_INSERT_TAIL(&ring->active, cmd, next);
2698 ring->queued++;
2700 run_cmd_task = (ring->queued == 1);
2702 RT2870_SOFTC_UNLOCK(sc);
2704 if (run_cmd_task)
2705 taskqueue_enqueue(sc->taskqueue, &sc->cmd_task);
2707 return 0;
2711 * rt2870_updateslot_cb
2713 static void rt2870_updateslot_cb(struct rt2870_softc *sc, void *arg)
2715 RT2870_SOFTC_LOCK(sc);
2717 rt2870_asic_updateslot(sc);
2719 RT2870_SOFTC_UNLOCK(sc);
2723 * rt2870_wme_update_cb
2725 static void rt2870_wme_update_cb(struct rt2870_softc *sc, void *arg)
2727 RT2870_SOFTC_LOCK(sc);
2729 rt2870_asic_wme_update(sc);
2731 RT2870_SOFTC_UNLOCK(sc);
2735 * rt2870_vap_key_delete_cb
2737 static void rt2870_vap_key_delete_cb(struct rt2870_softc *sc, void *arg)
2739 struct ieee80211_key *k;
2740 struct rt2870_cmd_argv_keydelete *cmd_argv;
2741 uint16_t associd;
2742 uint8_t vapid, wcid;
2743 uint32_t tmp;
2745 cmd_argv = arg;
2746 k = &cmd_argv->key;
2747 associd = cmd_argv->associd;
2749 RT2870_SOFTC_LOCK(sc);
2751 if (!(k->wk_flags & IEEE80211_KEY_GROUP))
2753 /* remove pairwise key */
2755 wcid = RT2870_AID2WCID(associd);
2757 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID_ATTR(wcid));
2759 tmp &= ~0xf;
2760 tmp |= (RT2870_REG_CIPHER_MODE_NONE << RT2870_REG_CIPHER_MODE_SHIFT);
2762 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
2764 else
2766 /* remove group key */
2768 vapid = 0;
2770 tmp = rt2870_io_mac_read(sc, RT2870_REG_SKEY_MODE(vapid));
2772 tmp &= ~(0xf << (k->wk_keyix * 4 + 16 * (vapid % 2)));
2773 tmp |= (RT2870_REG_CIPHER_MODE_NONE << (k->wk_keyix * 4 + 16 * (vapid % 2)));
2775 rt2870_io_mac_write(sc, RT2870_REG_SKEY_MODE(vapid), tmp);
2778 RT2870_SOFTC_UNLOCK(sc);
2782 * rt2870_vap_update_beacon_cb
2784 static void rt2870_vap_update_beacon_cb(struct rt2870_softc *sc, void *arg)
2786 struct ifnet *ifp;
2787 struct ieee80211com *ic;
2788 struct ieee80211vap *vap;
2790 ifp = sc->ifp;
2791 ic = ifp->if_l2com;
2792 vap = TAILQ_FIRST(&ic->ic_vaps);
2794 if (vap == NULL)
2795 return;
2797 RT2870_SOFTC_LOCK(sc);
2799 rt2870_asic_update_beacon(sc, vap);
2801 RT2870_SOFTC_UNLOCK(sc);
2805 * rt2870_asic_set_bssid
2807 static void rt2870_asic_set_bssid(struct rt2870_softc *sc,
2808 const uint8_t *bssid)
2810 uint32_t tmp;
2812 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
2813 "%s: set bssid: bssid=%s\n",
2814 device_get_nameunit(sc->dev),
2815 ether_sprintf(bssid));
2817 tmp = bssid[0] | (bssid[1]) << 8 | (bssid[2] << 16) | (bssid[3] << 24);
2819 rt2870_io_mac_write(sc, RT2870_REG_BSSID_DW0, tmp);
2821 tmp = bssid[4] | (bssid[5] << 8);
2823 rt2870_io_mac_write(sc, RT2870_REG_BSSID_DW1, tmp);
2827 * rt2870_asic_set_macaddr
2829 static void rt2870_asic_set_macaddr(struct rt2870_softc *sc,
2830 const uint8_t *addr)
2832 uint32_t tmp;
2834 tmp = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
2836 rt2870_io_mac_write(sc, RT2870_REG_ADDR_DW0, tmp);
2838 tmp = addr[4] | (addr[5] << 8);
2840 rt2870_io_mac_write(sc, RT2870_REG_ADDR_DW1, tmp);
2844 * rt2870_asic_enable_tsf_sync
2846 static void rt2870_asic_enable_tsf_sync(struct rt2870_softc *sc)
2848 struct ifnet *ifp;
2849 struct ieee80211com *ic;
2850 struct ieee80211vap *vap;
2851 uint32_t tmp;
2853 ifp = sc->ifp;
2854 ic = ifp->if_l2com;
2855 vap = TAILQ_FIRST(&ic->ic_vaps);
2857 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
2858 "%s: enabling TSF\n",
2859 device_get_nameunit(sc->dev));
2861 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
2863 tmp &= ~0x1fffff;
2864 tmp |= vap->iv_bss->ni_intval * 16;
2865 tmp |= (RT2870_REG_TSF_TIMER_ENABLE | RT2870_REG_TBTT_TIMER_ENABLE);
2867 if (vap->iv_opmode == IEEE80211_M_STA)
2869 tmp |= (RT2870_REG_TSF_SYNC_MODE_STA << RT2870_REG_TSF_SYNC_MODE_SHIFT);
2871 else if (vap->iv_opmode == IEEE80211_M_IBSS)
2873 tmp |= RT2870_REG_BCN_TX_ENABLE;
2874 tmp |= (RT2870_REG_TSF_SYNC_MODE_IBSS << RT2870_REG_TSF_SYNC_MODE_SHIFT);
2876 else if (vap->iv_opmode == IEEE80211_M_HOSTAP)
2878 tmp |= RT2870_REG_BCN_TX_ENABLE;
2879 tmp |= (RT2870_REG_TSF_SYNC_MODE_HOSTAP << RT2870_REG_TSF_SYNC_MODE_SHIFT);
2882 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
2886 * rt2870_asic_disable_tsf_sync
2888 static void rt2870_asic_disable_tsf_sync(struct rt2870_softc *sc)
2890 uint32_t tmp;
2892 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
2893 "%s: disabling TSF\n",
2894 device_get_nameunit(sc->dev));
2896 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
2898 tmp &= ~(RT2870_REG_BCN_TX_ENABLE |
2899 RT2870_REG_TSF_TIMER_ENABLE |
2900 RT2870_REG_TBTT_TIMER_ENABLE);
2902 tmp &= ~(RT2870_REG_TSF_SYNC_MODE_MASK << RT2870_REG_TSF_SYNC_MODE_SHIFT);
2903 tmp |= (RT2870_REG_TSF_SYNC_MODE_DISABLE << RT2870_REG_TSF_SYNC_MODE_SHIFT);
2905 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
2909 * rt2870_asic_enable_mrr
2911 static void rt2870_asic_enable_mrr(struct rt2870_softc *sc)
2913 #define CCK(mcs) (mcs)
2914 #define OFDM(mcs) ((1 << 3) | (mcs))
2915 #define HT(mcs) (mcs)
2917 rt2870_io_mac_write(sc, RT2870_REG_TX_LG_FBK_CFG0,
2918 (OFDM(6) << 28) | /* 54 -> 48 */
2919 (OFDM(5) << 24) | /* 48 -> 36 */
2920 (OFDM(4) << 20) | /* 36 -> 24 */
2921 (OFDM(3) << 16) | /* 24 -> 18 */
2922 (OFDM(2) << 12) | /* 18 -> 12 */
2923 (OFDM(1) << 8) | /* 12 -> 9 */
2924 (OFDM(0) << 4) | /* 9 -> 6 */
2925 OFDM(0)); /* 6 -> 6 */
2927 rt2870_io_mac_write(sc, RT2870_REG_TX_LG_FBK_CFG1,
2928 (CCK(2) << 12) | /* 11 -> 5.5 */
2929 (CCK(1) << 8) | /* 5.5 -> 2 */
2930 (CCK(0) << 4) | /* 2 -> 1 */
2931 CCK(0)); /* 1 -> 1 */
2933 rt2870_io_mac_write(sc, RT2870_REG_TX_HT_FBK_CFG0,
2934 (HT(6) << 28) |
2935 (HT(5) << 24) |
2936 (HT(4) << 20) |
2937 (HT(3) << 16) |
2938 (HT(2) << 12) |
2939 (HT(1) << 8) |
2940 (HT(0) << 4) |
2941 HT(0));
2943 rt2870_io_mac_write(sc, RT2870_REG_TX_HT_FBK_CFG1,
2944 (HT(14) << 28) |
2945 (HT(13) << 24) |
2946 (HT(12) << 20) |
2947 (HT(11) << 16) |
2948 (HT(10) << 12) |
2949 (HT(9) << 8) |
2950 (HT(8) << 4) |
2951 HT(8));
2953 #undef HT
2954 #undef OFDM
2955 #undef CCK
2959 * rt2870_asic_set_txpreamble
2961 static void rt2870_asic_set_txpreamble(struct rt2870_softc *sc)
2963 struct ifnet *ifp;
2964 struct ieee80211com *ic;
2965 uint32_t tmp;
2967 ifp = sc->ifp;
2968 ic = ifp->if_l2com;
2970 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
2971 "%s: %s short Tx preamble\n",
2972 device_get_nameunit(sc->dev),
2973 (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? "enabling" : "disabling");
2975 tmp = rt2870_io_mac_read(sc, RT2870_REG_AUTO_RSP_CFG);
2977 tmp &= ~RT2870_REG_CCK_SHORT_ENABLE;
2979 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
2980 tmp |= RT2870_REG_CCK_SHORT_ENABLE;
2982 rt2870_io_mac_write(sc, RT2870_REG_AUTO_RSP_CFG, tmp);
2986 * rt2870_asic_set_basicrates
2988 static void rt2870_asic_set_basicrates(struct rt2870_softc *sc)
2990 struct ifnet *ifp;
2991 struct ieee80211com *ic;
2993 ifp = sc->ifp;
2994 ic = ifp->if_l2com;
2996 if (ic->ic_curmode == IEEE80211_MODE_11B)
2997 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0x3);
2998 else if (ic->ic_curmode == IEEE80211_MODE_11A)
2999 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0x150);
3000 else
3001 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0x15f);
3005 * rt2870_asic_update_rtsthreshold
3007 static void rt2870_asic_update_rtsthreshold(struct rt2870_softc *sc)
3009 struct ifnet *ifp;
3010 struct ieee80211com *ic;
3011 struct ieee80211vap *vap;
3012 uint32_t tmp;
3013 uint16_t threshold;
3015 ifp = sc->ifp;
3016 ic = ifp->if_l2com;
3017 vap = TAILQ_FIRST(&ic->ic_vaps);
3019 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3020 "%s: updating RTS threshold: %d\n",
3021 device_get_nameunit(sc->dev), vap->iv_rtsthreshold);
3023 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_RTS_CFG);
3025 tmp &= ~(RT2870_REG_TX_RTS_THRESHOLD_MASK << RT2870_REG_TX_RTS_THRESHOLD_SHIFT);
3027 threshold = (vap->iv_rtsthreshold < IEEE80211_RTS_MAX) ?
3028 vap->iv_rtsthreshold : 0x1000;
3030 tmp |= ((threshold & RT2870_REG_TX_RTS_THRESHOLD_MASK) <<
3031 RT2870_REG_TX_RTS_THRESHOLD_SHIFT);
3033 rt2870_io_mac_write(sc, RT2870_REG_TX_RTS_CFG, tmp);
3037 * rt2870_asic_update_txpower
3039 static void rt2870_asic_update_txpower(struct rt2870_softc *sc)
3041 struct ifnet *ifp;
3042 struct ieee80211com *ic;
3043 uint32_t *txpow_rate;
3044 int8_t delta;
3045 uint8_t val;
3046 uint32_t tmp;
3047 int i;
3049 ifp = sc->ifp;
3050 ic = ifp->if_l2com;
3052 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3053 "%s: updating Tx power: %d\n",
3054 device_get_nameunit(sc->dev), ic->ic_txpowlimit);
3056 if (!IEEE80211_IS_CHAN_HT40(ic->ic_curchan))
3058 txpow_rate = sc->txpow_rate_20mhz;
3060 else
3062 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
3063 txpow_rate = sc->txpow_rate_40mhz_2ghz;
3064 else
3065 txpow_rate = sc->txpow_rate_40mhz_5ghz;
3068 delta = 0;
3070 val = rt2870_io_bbp_read(sc, 1);
3071 val &= 0xfc;
3073 if (ic->ic_txpowlimit > 90)
3075 /* do nothing */
3077 else if (ic->ic_txpowlimit > 60)
3079 delta -= 1;
3081 else if (ic->ic_txpowlimit > 30)
3083 delta -= 3;
3085 else if (ic->ic_txpowlimit > 15)
3087 val |= 0x1;
3089 else if (ic->ic_txpowlimit > 9)
3091 val |= 0x1;
3092 delta -= 3;
3094 else
3096 val |= 0x2;
3099 rt2870_io_bbp_write(sc, 1, val);
3101 for (i = 0; i < RT2870_SOFTC_TXPOW_RATE_COUNT; i++)
3103 if (txpow_rate[i] == 0xffffffff)
3104 continue;
3106 tmp = rt2870_read_eeprom_txpow_rate_add_delta(txpow_rate[i], delta);
3108 rt2870_io_mac_write(sc, RT2870_REG_TX_PWR_CFG(i), tmp);
3113 * rt2870_asic_update_promisc
3115 static void rt2870_asic_update_promisc(struct rt2870_softc *sc)
3117 struct ifnet *ifp;
3118 uint32_t tmp;
3120 ifp = sc->ifp;
3122 printf("%s: %s promiscuous mode\n",
3123 device_get_nameunit(sc->dev),
3124 (ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving");
3126 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_FILTER_CFG);
3128 tmp &= ~RT2870_REG_RX_FILTER_DROP_UC_NOME;
3130 if (!(ifp->if_flags & IFF_PROMISC))
3131 tmp |= RT2870_REG_RX_FILTER_DROP_UC_NOME;
3133 rt2870_io_mac_write(sc, RT2870_REG_RX_FILTER_CFG, tmp);
3137 * rt2870_asic_updateprot
3139 static void rt2870_asic_updateprot(struct rt2870_softc *sc)
3141 struct ifnet *ifp;
3142 struct ieee80211com *ic;
3143 struct ieee80211vap *vap;
3144 uint32_t cck_prot, ofdm_prot, mm20_prot, mm40_prot, gf20_prot, gf40_prot;
3145 uint8_t htopmode;
3147 ifp = sc->ifp;
3148 ic = ifp->if_l2com;
3149 vap = TAILQ_FIRST(&ic->ic_vaps);
3151 /* CCK frame protection */
3153 cck_prot = RT2870_REG_RTSTH_ENABLE | RT2870_REG_PROT_NAV_SHORT |
3154 RT2870_REG_TXOP_ALLOW_ALL | RT2870_REG_PROT_CTRL_NONE;
3156 /* set up protection frame phy mode and rate (MCS code) */
3158 if (ic->ic_curmode == IEEE80211_MODE_11A)
3159 cck_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3160 (0 << RT2870_REG_PROT_MCS_SHIFT);
3161 else
3162 cck_prot |= ((RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3163 (3 << RT2870_REG_PROT_MCS_SHIFT));
3165 rt2870_io_mac_write(sc, RT2870_REG_TX_CCK_PROT_CFG, cck_prot);
3167 /* OFDM frame protection */
3169 ofdm_prot = RT2870_REG_RTSTH_ENABLE | RT2870_REG_PROT_NAV_SHORT |
3170 RT2870_REG_TXOP_ALLOW_ALL;
3172 if (ic->ic_flags & IEEE80211_F_USEPROT)
3174 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3175 "%s: updating protection mode: b/g protection mode=%s\n",
3176 device_get_nameunit(sc->dev),
3177 (ic->ic_protmode == IEEE80211_PROT_RTSCTS) ? "RTS/CTS" :
3178 ((ic->ic_protmode == IEEE80211_PROT_CTSONLY) ? "CTS-to-self" : "none"));
3180 if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
3181 ofdm_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3182 else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
3183 ofdm_prot |= RT2870_REG_PROT_CTRL_CTS;
3184 else
3185 ofdm_prot |= RT2870_REG_PROT_CTRL_NONE;
3187 else
3189 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3190 "%s: updating protection mode: b/g protection mode=%s\n",
3191 device_get_nameunit(sc->dev), "none");
3193 ofdm_prot |= RT2870_REG_PROT_CTRL_NONE;
3196 rt2870_io_mac_write(sc, RT2870_REG_TX_OFDM_PROT_CFG, ofdm_prot);
3198 /* HT frame protection */
3200 if ((vap->iv_opmode == IEEE80211_M_STA) && (vap->iv_state == IEEE80211_S_RUN))
3201 htopmode = vap->iv_bss->ni_htopmode;
3202 else
3203 htopmode = ic->ic_curhtprotmode;
3205 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3206 "%s: updating protection mode: HT operation mode=0x%02x, protection mode=%s\n",
3207 device_get_nameunit(sc->dev),
3208 htopmode & IEEE80211_HTINFO_OPMODE,
3209 (ic->ic_htprotmode == IEEE80211_PROT_RTSCTS) ? "RTS/CTS" :
3210 ((ic->ic_htprotmode == IEEE80211_PROT_CTSONLY) ? "CTS-to-self" : "none"));
3212 switch (htopmode & IEEE80211_HTINFO_OPMODE)
3214 /* IEEE80211_HTINFO_OPMODE_HT20PR */
3215 case IEEE80211_HTINFO_OPMODE_HT20PR:
3216 mm20_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3217 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3218 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20 |
3219 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3220 (4 << RT2870_REG_PROT_MCS_SHIFT);
3222 gf20_prot = mm20_prot;
3224 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3225 RT2870_REG_TXOP_ALLOW_ALL |
3226 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3227 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
3229 if (ic->ic_htprotmode == IEEE80211_PROT_RTSCTS)
3230 mm40_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3231 else if (ic->ic_htprotmode == IEEE80211_PROT_CTSONLY)
3232 mm40_prot |= RT2870_REG_PROT_CTRL_CTS;
3233 else
3234 mm40_prot |= RT2870_REG_PROT_CTRL_NONE;
3236 gf40_prot = mm40_prot;
3237 break;
3239 /* IEEE80211_HTINFO_OPMODE_MIXED */
3240 case IEEE80211_HTINFO_OPMODE_MIXED:
3241 mm20_prot = RT2870_REG_PROT_NAV_SHORT |
3242 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3243 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20;
3245 if (ic->ic_flags & IEEE80211_F_USEPROT)
3246 mm20_prot |= (RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3247 (3 << RT2870_REG_PROT_MCS_SHIFT);
3248 else
3249 mm20_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3250 (4 << RT2870_REG_PROT_MCS_SHIFT);
3252 if (ic->ic_htprotmode == IEEE80211_PROT_RTSCTS)
3253 mm20_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3254 else if (ic->ic_htprotmode == IEEE80211_PROT_CTSONLY)
3255 mm20_prot |= RT2870_REG_PROT_CTRL_CTS;
3256 else
3257 mm20_prot |= RT2870_REG_PROT_CTRL_NONE;
3259 gf20_prot = mm20_prot;
3261 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_TXOP_ALLOW_ALL;
3263 if (ic->ic_flags & IEEE80211_F_USEPROT)
3264 mm40_prot |= (RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3265 (3 << RT2870_REG_PROT_MCS_SHIFT);
3266 else
3267 mm40_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3268 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
3270 if (ic->ic_htprotmode == IEEE80211_PROT_RTSCTS)
3271 mm40_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3272 else if (ic->ic_htprotmode == IEEE80211_PROT_CTSONLY)
3273 mm40_prot |= RT2870_REG_PROT_CTRL_CTS;
3274 else
3275 mm40_prot |= RT2870_REG_PROT_CTRL_NONE;
3277 gf40_prot = mm40_prot;
3278 break;
3281 * IEEE80211_HTINFO_OPMODE_PURE
3282 * IEEE80211_HTINFO_OPMODE_PROTOPT
3284 case IEEE80211_HTINFO_OPMODE_PURE:
3285 case IEEE80211_HTINFO_OPMODE_PROTOPT:
3286 default:
3287 mm20_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3288 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3289 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20 |
3290 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3291 (4 << RT2870_REG_PROT_MCS_SHIFT);
3293 gf20_prot = mm20_prot;
3295 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3296 RT2870_REG_TXOP_ALLOW_ALL |
3297 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3298 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
3300 gf40_prot = mm40_prot;
3301 break;
3304 rt2870_io_mac_write(sc, RT2870_REG_TX_MM20_PROT_CFG, mm20_prot);
3305 rt2870_io_mac_write(sc, RT2870_REG_TX_MM40_PROT_CFG, mm40_prot);
3306 rt2870_io_mac_write(sc, RT2870_REG_TX_GF20_PROT_CFG, gf20_prot);
3307 rt2870_io_mac_write(sc, RT2870_REG_TX_GF40_PROT_CFG, gf40_prot);
3311 * rt2870_asic_updateslot
3313 static void rt2870_asic_updateslot(struct rt2870_softc *sc)
3315 struct ifnet *ifp;
3316 struct ieee80211com *ic;
3317 uint32_t tmp;
3319 ifp = sc->ifp;
3320 ic = ifp->if_l2com;
3322 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3323 "%s: %s short slot time\n",
3324 device_get_nameunit(sc->dev),
3325 (ic->ic_flags & IEEE80211_F_SHSLOT) ? "enabling" : "disabling");
3327 tmp = rt2870_io_mac_read(sc, RT2870_REG_BKOFF_SLOT_CFG);
3329 tmp &= ~0xff;
3330 tmp |= (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
3332 rt2870_io_mac_write(sc, RT2870_REG_BKOFF_SLOT_CFG, tmp);
3336 * rt2870_asic_wme_update
3338 static void rt2870_asic_wme_update(struct rt2870_softc *sc)
3340 struct ifnet *ifp;
3341 struct ieee80211com *ic;
3342 struct ieee80211_wme_state *wme;
3343 const struct wmeParams *wmep;
3344 int i;
3346 ifp = sc->ifp;
3347 ic = ifp->if_l2com;
3348 wme = &ic->ic_wme;
3349 wmep = wme->wme_chanParams.cap_wmeParams;
3351 RT2870_DPRINTF(sc, RT2870_DEBUG_WME,
3352 "%s: wme update: WME_AC_VO=%d/%d/%d/%d, WME_AC_VI=%d/%d/%d/%d, "
3353 "WME_AC_BK=%d/%d/%d/%d, WME_AC_BE=%d/%d/%d/%d\n",
3354 device_get_nameunit(sc->dev),
3355 wmep[WME_AC_VO].wmep_aifsn,
3356 wmep[WME_AC_VO].wmep_logcwmin, wmep[WME_AC_VO].wmep_logcwmax,
3357 wmep[WME_AC_VO].wmep_txopLimit,
3358 wmep[WME_AC_VI].wmep_aifsn,
3359 wmep[WME_AC_VI].wmep_logcwmin, wmep[WME_AC_VI].wmep_logcwmax,
3360 wmep[WME_AC_VI].wmep_txopLimit,
3361 wmep[WME_AC_BK].wmep_aifsn,
3362 wmep[WME_AC_BK].wmep_logcwmin, wmep[WME_AC_BK].wmep_logcwmax,
3363 wmep[WME_AC_BK].wmep_txopLimit,
3364 wmep[WME_AC_BE].wmep_aifsn,
3365 wmep[WME_AC_BE].wmep_logcwmin, wmep[WME_AC_BE].wmep_logcwmax,
3366 wmep[WME_AC_BE].wmep_txopLimit);
3368 for (i = 0; i < WME_NUM_AC; i++)
3369 rt2870_io_mac_write(sc, RT2870_REG_TX_EDCA_AC_CFG(i),
3370 (wmep[i].wmep_logcwmax << 16) | (wmep[i].wmep_logcwmin << 12) |
3371 (wmep[i].wmep_aifsn << 8) | wmep[i].wmep_txopLimit);
3373 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_AIFSN_CFG,
3374 (wmep[WME_AC_VO].wmep_aifsn << 12) | (wmep[WME_AC_VI].wmep_aifsn << 8) |
3375 (wmep[WME_AC_BK].wmep_aifsn << 4) | wmep[WME_AC_BE].wmep_aifsn);
3377 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_CWMIN_CFG,
3378 (wmep[WME_AC_VO].wmep_logcwmin << 12) | (wmep[WME_AC_VI].wmep_logcwmin << 8) |
3379 (wmep[WME_AC_BK].wmep_logcwmin << 4) | wmep[WME_AC_BE].wmep_logcwmin);
3381 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_CWMAX_CFG,
3382 (wmep[WME_AC_VO].wmep_logcwmax << 12) | (wmep[WME_AC_VI].wmep_logcwmax << 8) |
3383 (wmep[WME_AC_BK].wmep_logcwmax << 4) | wmep[WME_AC_BE].wmep_logcwmax);
3385 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP0_CFG,
3386 (wmep[WME_AC_BK].wmep_txopLimit << 16) | wmep[WME_AC_BE].wmep_txopLimit);
3388 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP1_CFG,
3389 (wmep[WME_AC_VO].wmep_txopLimit << 16) | wmep[WME_AC_VI].wmep_txopLimit);
3393 * rt2870_asic_update_beacon
3395 static int rt2870_asic_update_beacon(struct rt2870_softc *sc,
3396 struct ieee80211vap *vap)
3398 struct ifnet *ifp;
3399 struct ieee80211com *ic;
3400 struct rt2870_softc_vap *rvap;
3401 const struct ieee80211_txparam *tp;
3402 struct mbuf *m;
3403 struct rt2870_txwi txwi;
3404 uint8_t rate, mcs;
3405 uint32_t tmp;
3407 ifp = sc->ifp;
3408 ic = ifp->if_l2com;
3409 rvap = (struct rt2870_softc_vap *) vap;
3410 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
3412 m = ieee80211_beacon_alloc(vap->iv_bss, &rvap->beacon_offsets);
3413 if (m == NULL)
3414 return ENOMEM;
3416 rate = tp->mgmtrate;
3417 mcs = rt2870_rate2mcs(rate);
3419 memset(&txwi, 0, sizeof(struct rt2870_txwi));
3421 txwi.wcid = 0xff;
3422 txwi.pid_mpdu_len = ((htole16(m->m_pkthdr.len) & RT2870_TXWI_MPDU_LEN_MASK) <<
3423 RT2870_TXWI_MPDU_LEN_SHIFT);
3424 txwi.txop = (RT2870_TXWI_TXOP_HT << RT2870_TXWI_TXOP_SHIFT);
3425 txwi.mpdu_density_flags |=
3426 (RT2870_TXWI_FLAGS_TS << RT2870_TXWI_FLAGS_SHIFT);
3427 txwi.bawin_size_xflags |=
3428 (RT2870_TXWI_XFLAGS_NSEQ << RT2870_TXWI_XFLAGS_SHIFT);
3430 if (ieee80211_rate2phytype(ic->ic_rt, rate) != IEEE80211_T_OFDM)
3432 txwi.phymode_ifs_stbc_shortgi =
3433 (RT2870_TXWI_PHYMODE_CCK << RT2870_TXWI_PHYMODE_SHIFT);
3435 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
3436 mcs |= RT2870_TXWI_MCS_SHOTPRE;
3438 else
3440 txwi.phymode_ifs_stbc_shortgi =
3441 (RT2870_TXWI_PHYMODE_OFDM << RT2870_TXWI_PHYMODE_SHIFT);
3444 txwi.bw_mcs = (RT2870_TXWI_BW_20 << RT2870_TXWI_BW_SHIFT) |
3445 ((mcs & RT2870_TXWI_MCS_MASK) << RT2870_TXWI_MCS_SHIFT);
3447 /* disable temporarily TSF sync */
3449 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
3451 tmp &= ~(RT2870_REG_BCN_TX_ENABLE |
3452 RT2870_REG_TSF_TIMER_ENABLE |
3453 RT2870_REG_TBTT_TIMER_ENABLE);
3455 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
3457 /* write Tx wireless info and beacon frame to on-chip memory */
3459 rt2870_io_mac_write_multi(sc, RT2870_REG_BEACON_BASE(0),
3460 &txwi, sizeof(struct rt2870_txwi));
3462 rt2870_io_mac_write_multi(sc, RT2870_REG_BEACON_BASE(0) + sizeof(struct rt2870_txwi),
3463 mtod(m, uint8_t *), m->m_pkthdr.len);
3465 /* enable again TSF sync */
3467 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
3469 tmp |= (RT2870_REG_BCN_TX_ENABLE |
3470 RT2870_REG_TSF_TIMER_ENABLE |
3471 RT2870_REG_TBTT_TIMER_ENABLE);
3473 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
3475 m_freem(m);
3477 return 0;
3481 * rt2870_asic_clear_keytables
3483 static void rt2870_asic_clear_keytables(struct rt2870_softc *sc)
3485 /* clear Rx WCID search table (entries = 256, entry size = 8) */
3487 rt2870_io_mac_set_region_4(sc, RT2870_REG_WCID(0), 0, 2 * 256);
3489 /* clear WCID attribute table (entries = 256, entry size = 4) */
3491 rt2870_io_mac_set_region_4(sc, RT2870_REG_WCID_ATTR(0), 0, 256);
3493 /* clear IV/EIV table (entries = 256, entry size = 8) */
3495 rt2870_io_mac_set_region_4(sc, RT2870_REG_IVEIV(0), 0, 2 * 256);
3497 /* clear pairwise key table (entries = 256, entry size = 32) */
3499 rt2870_io_mac_set_region_4(sc, RT2870_REG_PKEY(0), 0, 8 * 256);
3501 /* clear shared key table (entries = 32, entry size = 32) */
3503 rt2870_io_mac_set_region_4(sc, RT2870_REG_SKEY(0, 0), 0, 8 * 32);
3505 /* clear shared key mode (entries = 32, entry size = 2) */
3507 rt2870_io_mac_set_region_4(sc, RT2870_REG_SKEY_MODE(0), 0, 16);
3511 * rt2870_rxrate
3513 static uint8_t rt2870_rxrate(struct rt2870_rxwi *rxwi)
3515 uint8_t mcs, phymode;
3516 uint8_t rate;
3518 mcs = (rxwi->bw_mcs >> RT2870_RXWI_MCS_SHIFT) & RT2870_RXWI_MCS_MASK;
3519 phymode = (rxwi->phymode_stbc_shortgi >> RT2870_RXWI_PHYMODE_SHIFT) &
3520 RT2870_RXWI_PHYMODE_MASK;
3522 rate = 2;
3524 switch (phymode)
3526 case RT2870_RXWI_PHYMODE_CCK:
3527 switch (mcs & ~RT2870_RXWI_MCS_SHOTPRE)
3529 case 0: rate = 2; break; /* 1 Mbps */
3530 case 1: rate = 4; break; /* 2 MBps */
3531 case 2: rate = 11; break; /* 5.5 Mbps */
3532 case 3: rate = 22; break; /* 11 Mbps */
3534 break;
3536 case RT2870_RXWI_PHYMODE_OFDM:
3537 switch (mcs)
3539 case 0: rate = 12; break; /* 6 Mbps */
3540 case 1: rate = 18; break; /* 9 Mbps */
3541 case 2: rate = 24; break; /* 12 Mbps */
3542 case 3: rate = 36; break; /* 18 Mbps */
3543 case 4: rate = 48; break; /* 24 Mbps */
3544 case 5: rate = 72; break; /* 36 Mbps */
3545 case 6: rate = 96; break; /* 48 Mbps */
3546 case 7: rate = 108; break; /* 54 Mbps */
3548 break;
3550 case RT2870_RXWI_PHYMODE_HT_MIXED:
3551 case RT2870_RXWI_PHYMODE_HT_GF:
3552 break;
3555 return rate;
3559 * rt2870_maxrssi_rxpath
3561 static uint8_t rt2870_maxrssi_rxpath(struct rt2870_softc *sc,
3562 const struct rt2870_rxwi *rxwi)
3564 uint8_t rxpath;
3566 rxpath = 0;
3568 if (sc->nrxpath > 1)
3569 if (rxwi->rssi[1] > rxwi->rssi[rxpath])
3570 rxpath = 1;
3572 if (sc->nrxpath > 2)
3573 if (rxwi->rssi[2] > rxwi->rssi[rxpath])
3574 rxpath = 2;
3576 return rxpath;
3580 * rt2870_rssi2dbm
3582 static int8_t rt2870_rssi2dbm(struct rt2870_softc *sc,
3583 uint8_t rssi, uint8_t rxpath)
3585 struct ifnet *ifp;
3586 struct ieee80211com *ic;
3587 struct ieee80211_channel *c;
3588 int chan;
3589 int8_t rssi_off, lna_gain;
3591 if (rssi == 0)
3592 return -99;
3594 ifp = sc->ifp;
3595 ic = ifp->if_l2com;
3596 c = ic->ic_curchan;
3597 chan = ieee80211_chan2ieee(ic, c);
3599 if (IEEE80211_IS_CHAN_5GHZ(c))
3601 rssi_off = sc->rssi_off_5ghz[rxpath];
3603 if (chan <= 64)
3604 lna_gain = sc->lna_gain[1];
3605 else if (chan <= 128)
3606 lna_gain = sc->lna_gain[2];
3607 else
3608 lna_gain = sc->lna_gain[3];
3610 else
3612 rssi_off = sc->rssi_off_2ghz[rxpath];
3613 lna_gain = sc->lna_gain[0];
3616 return (-12 - rssi_off - lna_gain - rssi);
3620 * rt2870_rate2mcs
3622 static uint8_t rt2870_rate2mcs(uint8_t rate)
3624 switch (rate)
3626 /* CCK rates */
3627 case 2: return 0;
3628 case 4: return 1;
3629 case 11: return 2;
3630 case 22: return 3;
3632 /* OFDM rates */
3633 case 12: return 0;
3634 case 18: return 1;
3635 case 24: return 2;
3636 case 36: return 3;
3637 case 48: return 4;
3638 case 72: return 5;
3639 case 96: return 6;
3640 case 108: return 7;
3643 return 0;
3647 * rt2870_rx_frame
3649 static void rt2870_rx_frame(struct rt2870_softc *sc,
3650 uint8_t *buf, uint32_t dmalen)
3652 struct ifnet *ifp;
3653 struct ieee80211com *ic;
3654 struct ieee80211_frame *wh;
3655 struct ieee80211_node *ni;
3656 struct rt2870_softc_rx_radiotap_header *tap;
3657 struct rt2870_rxwi *rxwi;
3658 struct rt2870_rxinfo *rxinfo;
3659 struct mbuf *m;
3660 uint32_t rxinfo_flags;
3661 uint8_t cipher_err, rssi, ant, phymode, bw, shortgi, mcs;
3662 int8_t rssi_dbm;
3663 int len, ampdu, amsdu;
3665 ifp = sc->ifp;
3666 ic = ifp->if_l2com;
3668 /* get Rx wireless info */
3670 rxwi = (struct rt2870_rxwi *) buf;
3671 len = (le16toh(rxwi->tid_size) >> RT2870_RXWI_SIZE_SHIFT) &
3672 RT2870_RXWI_SIZE_MASK;
3674 if (len > dmalen)
3676 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3677 "%s: bad rxwi len: DMA len=%d, rxwi len=%d\n",
3678 device_get_nameunit(sc->dev), dmalen, len);
3679 return;
3682 /* get Rx info */
3684 rxinfo = (struct rt2870_rxinfo *) ((caddr_t) rxwi + dmalen);
3685 rxinfo_flags = le32toh(rxinfo->flags);
3687 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3688 "%s: Rx frame: DMA len=%d, len=%d, rxinfo flags=0x%08x\n",
3689 device_get_nameunit(sc->dev), dmalen, len, rxinfo_flags);
3691 /* check for crc errors */
3693 if (rxinfo_flags & RT2870_RXINFO_FLAGS_CRC_ERR)
3695 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3696 "%s: rxinfo: crc error\n",
3697 device_get_nameunit(sc->dev));
3699 ifp->if_ierrors++;
3701 if (!(ifp->if_flags & IFF_PROMISC))
3702 return;
3705 wh = (struct ieee80211_frame *) (rxwi + 1);
3707 /* check for L2 padding between IEEE 802.11 frame header and body */
3709 if (rxinfo_flags & RT2870_RXINFO_FLAGS_L2PAD)
3711 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3712 "%s: L2 padding: DMA len=%d, len=%d\n",
3713 device_get_nameunit(sc->dev), dmalen, len);
3715 len += 2;
3718 m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
3719 if (m == NULL)
3721 sc->rx_mbuf_alloc_errors++;
3722 ifp->if_ierrors++;
3723 return;
3726 m->m_pkthdr.rcvif = ifp;
3727 m->m_pkthdr.len = m->m_len = len;
3729 m_copyback(m, 0, len, (caddr_t) wh);
3731 wh = mtod(m, struct ieee80211_frame *);
3733 /* check for cipher errors */
3735 if (rxinfo_flags & RT2870_RXINFO_FLAGS_DECRYPTED)
3737 cipher_err = ((rxinfo_flags >> RT2870_RXINFO_FLAGS_CIPHER_ERR_SHIFT) &
3738 RT2870_RXINFO_FLAGS_CIPHER_ERR_MASK);
3739 if (cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_NONE)
3741 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
3742 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
3744 m->m_flags |= M_WEP;
3746 else
3748 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3749 "%s: rxinfo: cipher error=0x%02x\n",
3750 device_get_nameunit(sc->dev), cipher_err);
3752 ifp->if_ierrors++;
3754 if (!(ifp->if_flags & IFF_PROMISC))
3756 m_free(m);
3757 return;
3761 else
3763 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
3765 ifp->if_ierrors++;
3767 if (!(ifp->if_flags & IFF_PROMISC))
3769 m_free(m);
3770 return;
3775 /* check for A-MPDU */
3777 if (rxinfo_flags & RT2870_RXINFO_FLAGS_AMPDU)
3779 m->m_flags |= M_AMPDU;
3780 ampdu = 1;
3782 else
3784 ampdu = 0;
3787 ant = rt2870_maxrssi_rxpath(sc, rxwi);
3788 rssi = rxwi->rssi[ant];
3789 rssi_dbm = rt2870_rssi2dbm(sc, rssi, ant);
3790 phymode = ((rxwi->phymode_stbc_shortgi >> RT2870_RXWI_PHYMODE_SHIFT) &
3791 RT2870_RXWI_PHYMODE_MASK);
3792 bw = ((rxwi->bw_mcs >> RT2870_RXWI_BW_SHIFT) & RT2870_RXWI_BW_MASK);
3793 shortgi = ((rxwi->phymode_stbc_shortgi >> RT2870_RXWI_SHORTGI_SHIFT) &
3794 RT2870_RXWI_SHORTGI_MASK);
3795 mcs = ((rxwi->bw_mcs >> RT2870_RXWI_MCS_SHIFT) & RT2870_RXWI_MCS_MASK);
3796 amsdu = (rxinfo_flags & RT2870_RXINFO_FLAGS_AMSDU);
3798 if (ieee80211_radiotap_active(ic))
3800 tap = &sc->rxtap;
3802 tap->flags = (rxinfo_flags & RT2870_RXINFO_FLAGS_L2PAD) ? IEEE80211_RADIOTAP_F_DATAPAD : 0;
3803 tap->dbm_antsignal = rssi_dbm;
3804 tap->dbm_antnoise = RT2870_NOISE_FLOOR;
3805 tap->antenna = ant;
3806 tap->antsignal = rssi;
3807 tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
3808 tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
3809 tap->chan_ieee = ic->ic_curchan->ic_ieee;
3810 tap->chan_maxpow = 0;
3812 if (phymode == RT2870_RXWI_PHYMODE_CCK || phymode == RT2870_RXWI_PHYMODE_OFDM)
3813 tap->rate = rt2870_rxrate(rxwi);
3814 else
3815 tap->rate = mcs | IEEE80211_RATE_MCS;
3817 if (rxwi->bw_mcs & RT2870_RXWI_MCS_SHOTPRE)
3818 tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
3820 if (shortgi)
3821 tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
3824 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3825 "%s: received frame: len=%d, phymode=%d, bw=%d, shortgi=%d, mcs=%d, "
3826 "ant=%d, rssi=%d/%d/%d, snr=%d/%d, wcid=0x%02x, ampdu=%d, amsdu=%d\n",
3827 device_get_nameunit(sc->dev),
3828 len, phymode, bw, shortgi, mcs,
3829 ant, rxwi->rssi[0], rxwi->rssi[1], rxwi->rssi[2],
3830 rxwi->snr[0], rxwi->snr[1],
3831 rxwi->wcid, ampdu, amsdu);
3833 ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *) wh);
3834 if (ni != NULL)
3836 ieee80211_input(ni, m, rssi_dbm - RT2870_NOISE_FLOOR, RT2870_NOISE_FLOOR);
3837 ieee80211_free_node(ni);
3839 else
3841 ieee80211_input_all(ic, m, rssi_dbm - RT2870_NOISE_FLOOR, RT2870_NOISE_FLOOR);
3846 * rt2870_tx_mgmt
3848 static int rt2870_tx_mgmt(struct rt2870_softc *sc,
3849 struct mbuf *m, struct ieee80211_node *ni, int qid)
3851 struct ifnet *ifp;
3852 struct ieee80211com *ic;
3853 struct ieee80211vap *vap;
3854 const struct ieee80211_txparam *tp;
3855 struct rt2870_softc_node *rni;
3856 struct rt2870_softc_tx_ring *ring;
3857 struct rt2870_softc_tx_data *data;
3858 struct rt2870_txinfo *txinfo;
3859 struct rt2870_txwi *txwi;
3860 struct ieee80211_frame *wh;
3861 struct rt2870_softc_tx_radiotap_header *tap;
3862 u_int hdrsize, hdrspace;
3863 uint8_t rate, stbc, shortgi, mcs, pid;
3864 uint16_t len, dmalen, mpdu_len, dur;
3866 KASSERT(qid >= 0 && qid < (sc->usb_endpoints - 1),
3867 ("%s: Tx MGMT: invalid qid=%d\n",
3868 device_get_nameunit(sc->dev), qid));
3870 ifp = sc->ifp;
3871 ic = ifp->if_l2com;
3872 vap = ni->ni_vap;
3873 rni = (struct rt2870_softc_node *) ni;
3874 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
3876 ring = &sc->tx_ring[qid];
3877 data = STAILQ_FIRST(&ring->inactive);
3878 STAILQ_REMOVE_HEAD(&ring->inactive, next);
3879 txinfo = (struct rt2870_txinfo *) data->buf;
3880 txwi = (struct rt2870_txwi *) (txinfo + 1);
3882 wh = mtod(m, struct ieee80211_frame *);
3884 rate = tp->mgmtrate & IEEE80211_RATE_VAL;
3886 len = sizeof(struct rt2870_txinfo) + sizeof(struct rt2870_txwi) + m->m_pkthdr.len;
3888 /* align end on a 4-bytes boundary */
3890 dmalen = (len + 3) & ~3;
3892 /* fill Tx info */
3894 memset(txinfo, 0, sizeof(struct rt2870_txinfo));
3896 txinfo->len = htole16(dmalen - sizeof(struct rt2870_txinfo));
3898 txinfo->qsel_flags = (RT2870_TXINFO_QSEL_EDCA << RT2870_TXINFO_QSEL_SHIFT);
3900 dmalen += 4;
3902 memset((caddr_t) txinfo + len, 0, dmalen - len);
3904 /* fill Tx wireless info */
3906 if (ni->ni_flags & IEEE80211_NODE_HT)
3907 mcs = rate;
3908 else
3909 mcs = rt2870_rate2mcs(rate);
3911 pid = mcs + 1;
3913 /* calculate MPDU length without padding */
3915 hdrsize = ieee80211_hdrsize(wh);
3916 hdrspace = ieee80211_hdrspace(ic, wh);
3917 mpdu_len = m->m_pkthdr.len - hdrspace + hdrsize;
3919 memset(txwi, 0, sizeof(struct rt2870_txwi));
3921 /* management frames do not need encryption */
3923 txwi->wcid = 0xff;
3925 txwi->pid_mpdu_len = ((htole16(pid) & RT2870_TXWI_PID_MASK) <<
3926 RT2870_TXWI_PID_SHIFT) | ((htole16(mpdu_len) & RT2870_TXWI_MPDU_LEN_MASK) <<
3927 RT2870_TXWI_MPDU_LEN_SHIFT);
3929 stbc = (ni->ni_htcap & IEEE80211_HTCAP_RXSTBC) ? 1 : 0;
3931 shortgi = (vap->iv_flags_ht & (IEEE80211_FHT_SHORTGI20 | IEEE80211_FHT_SHORTGI40)) &&
3932 (ni->ni_flags & IEEE80211_NODE_HT);
3934 txwi->phymode_ifs_stbc_shortgi |=
3935 ((stbc & RT2870_TXWI_STBC_MASK) << RT2870_TXWI_STBC_SHIFT) |
3936 ((shortgi & RT2870_TXWI_SHORTGI_MASK) << RT2870_TXWI_SHORTGI_SHIFT);
3938 txwi->phymode_ifs_stbc_shortgi |=
3939 ((shortgi & RT2870_TXWI_SHORTGI_MASK) << RT2870_TXWI_SHORTGI_SHIFT);
3941 if (ni->ni_flags & IEEE80211_NODE_HT)
3943 txwi->phymode_ifs_stbc_shortgi |=
3944 (RT2870_TXWI_PHYMODE_HT_MIXED << RT2870_TXWI_PHYMODE_SHIFT);
3946 else
3948 if (ieee80211_rate2phytype(ic->ic_rt, rate) != IEEE80211_T_OFDM)
3950 txwi->phymode_ifs_stbc_shortgi |=
3951 (RT2870_TXWI_PHYMODE_CCK << RT2870_TXWI_PHYMODE_SHIFT);
3953 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
3954 mcs |= RT2870_TXWI_MCS_SHOTPRE;
3956 else
3958 txwi->phymode_ifs_stbc_shortgi |=
3959 (RT2870_TXWI_PHYMODE_OFDM << RT2870_TXWI_PHYMODE_SHIFT);
3963 txwi->bw_mcs = (RT2870_TXWI_BW_20 << RT2870_TXWI_BW_SHIFT) |
3964 ((mcs & RT2870_TXWI_MCS_MASK) << RT2870_TXWI_MCS_SHIFT);
3966 txwi->txop = (RT2870_TXWI_TXOP_BACKOFF << RT2870_TXWI_TXOP_SHIFT);
3968 /* skip ACKs for multicast frames and probe responses */
3970 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
3971 ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) !=
3972 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP)))
3974 txwi->bawin_size_xflags |=
3975 (RT2870_TXWI_XFLAGS_ACK << RT2870_TXWI_XFLAGS_SHIFT);
3977 if (ni->ni_flags & IEEE80211_NODE_HT)
3979 /* preamble + plcp + signal extension */
3981 dur = 16 + 4 + 6;
3983 else
3985 dur = ieee80211_ack_duration(ic->ic_rt, rate,
3986 ic->ic_flags & IEEE80211_F_SHPREAMBLE);
3989 *(uint16_t *) wh->i_dur = htole16(dur);
3992 /* ask MAC to insert timestamp into probe responses */
3994 if ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
3995 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
3996 txwi->mpdu_density_flags |=
3997 (RT2870_TXWI_FLAGS_TS << RT2870_TXWI_FLAGS_SHIFT);
3999 if (ieee80211_radiotap_active_vap(vap))
4001 tap = &sc->txtap;
4003 tap->flags = IEEE80211_RADIOTAP_F_DATAPAD;
4004 tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
4005 tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
4006 tap->chan_ieee = ic->ic_curchan->ic_ieee;
4007 tap->chan_maxpow = 0;
4009 if (ni->ni_flags & IEEE80211_NODE_HT)
4010 tap->rate = mcs | IEEE80211_RATE_MCS;
4011 else
4012 tap->rate = rate;
4014 if (mcs & RT2870_TXWI_MCS_SHOTPRE)
4015 tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
4017 if (shortgi)
4018 tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
4020 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4021 tap->flags |= IEEE80211_RADIOTAP_F_WEP;
4023 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4025 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
4027 ieee80211_radiotap_tx(vap, m);
4029 wh->i_fc[1] |= IEEE80211_FC1_WEP;
4031 else
4033 ieee80211_radiotap_tx(vap, m);
4037 m_copydata(m, 0, m->m_pkthdr.len, (caddr_t) (txwi + 1));
4039 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4040 "%s: sending MGMT frame: qid=%d, hdrsize=%d, hdrspace=%d, len=%d, "
4041 "stbc=%d, shortgi=%d, mcs=%d, DMA len=%d\n",
4042 device_get_nameunit(sc->dev),
4043 qid, hdrsize, hdrspace, m->m_pkthdr.len, stbc, shortgi, mcs, dmalen);
4045 data->len = dmalen;
4046 data->m = m;
4047 data->ni = ni;
4049 STAILQ_INSERT_TAIL(&ring->pending, data, next);
4050 ring->queued++;
4052 usbd_transfer_start(sc->usb_xfer[1 + qid]);
4054 return 0;
4058 * rt2870_tx_data
4060 static int rt2870_tx_data(struct rt2870_softc *sc,
4061 struct mbuf *m, struct ieee80211_node *ni, int qid)
4063 struct ifnet *ifp;
4064 struct ieee80211com *ic;
4065 struct ieee80211vap *vap;
4066 const struct ieee80211_txparam *tp;
4067 struct rt2870_softc_node *rni;
4068 struct rt2870_softc_tx_ring *ring;
4069 struct rt2870_softc_tx_data *data;
4070 struct rt2870_txinfo *txinfo;
4071 struct rt2870_txwi *txwi;
4072 struct ieee80211_frame *wh;
4073 struct rt2870_softc_tx_radiotap_header *tap;
4074 u_int hdrsize, hdrspace;
4075 uint8_t type, rate, bw, stbc, shortgi, mcs, pid, wcid;
4076 uint16_t qos, len, dmalen, mpdu_len, dur;
4077 int hasqos;
4079 KASSERT(qid >= 0 && qid < (sc->usb_endpoints - 1),
4080 ("%s: Tx data: invalid qid=%d\n",
4081 device_get_nameunit(sc->dev), qid));
4083 ifp = sc->ifp;
4084 ic = ifp->if_l2com;
4085 vap = ni->ni_vap;
4086 rni = (struct rt2870_softc_node *) ni;
4087 tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
4089 ring = &sc->tx_ring[qid];
4090 data = STAILQ_FIRST(&ring->inactive);
4091 STAILQ_REMOVE_HEAD(&ring->inactive, next);
4092 txinfo = (struct rt2870_txinfo *) data->buf;
4093 txwi = (struct rt2870_txwi *) (txinfo + 1);
4095 wh = mtod(m, struct ieee80211_frame *);
4097 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
4099 hasqos = IEEE80211_QOS_HAS_SEQ(wh);
4100 if (hasqos)
4102 if (IEEE80211_HAS_ADDR4(wh))
4103 qos = le16toh(*(const uint16_t *)
4104 (((struct ieee80211_qosframe_addr4 *) wh)->i_qos));
4105 else
4106 qos = le16toh(*(const uint16_t *)
4107 (((struct ieee80211_qosframe *) wh)->i_qos));
4109 else
4111 qos = 0;
4114 if (IEEE80211_IS_MULTICAST(wh->i_addr1))
4115 rate = tp->mcastrate;
4116 else if (m->m_flags & M_EAPOL)
4117 rate = tp->mgmtrate;
4118 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
4119 rate = tp->ucastrate;
4120 else
4121 rate = ni->ni_txrate;
4123 rate &= IEEE80211_RATE_VAL;
4125 len = sizeof(struct rt2870_txinfo) + sizeof(struct rt2870_txwi) + m->m_pkthdr.len;
4127 /* align end on a 4-bytes boundary */
4129 dmalen = (len + 3) & ~3;
4131 /* fill Tx info */
4133 memset(txinfo, 0, sizeof(struct rt2870_txinfo));
4135 txinfo->len = htole16(dmalen - sizeof(struct rt2870_txinfo));
4137 txinfo->qsel_flags = (RT2870_TXINFO_QSEL_EDCA << RT2870_TXINFO_QSEL_SHIFT);
4139 dmalen += 4;
4141 memset((caddr_t) txinfo + len, 0, dmalen - len);
4143 /* fill Tx wireless info */
4145 if (ni->ni_flags & IEEE80211_NODE_HT)
4146 mcs = rate;
4147 else
4148 mcs = rt2870_rate2mcs(rate);
4150 pid = mcs + 1;
4152 wcid = (type == IEEE80211_FC0_TYPE_DATA) ?
4153 RT2870_AID2WCID(ni->ni_associd) : 0xff;
4155 /* calculate MPDU length without padding */
4157 hdrsize = ieee80211_hdrsize(wh);
4158 hdrspace = ieee80211_hdrspace(ic, wh);
4159 mpdu_len = m->m_pkthdr.len - hdrspace + hdrsize;
4161 memset(txwi, 0, sizeof(struct rt2870_txwi));
4163 txwi->wcid = wcid;
4165 txwi->pid_mpdu_len = ((htole16(pid) & RT2870_TXWI_PID_MASK) <<
4166 RT2870_TXWI_PID_SHIFT) | ((htole16(mpdu_len) & RT2870_TXWI_MPDU_LEN_MASK) <<
4167 RT2870_TXWI_MPDU_LEN_SHIFT);
4169 stbc = (ni->ni_htcap & IEEE80211_HTCAP_RXSTBC) ? 1 : 0;
4171 shortgi = (vap->iv_flags_ht & (IEEE80211_FHT_SHORTGI20 | IEEE80211_FHT_SHORTGI40)) &&
4172 (ni->ni_flags & IEEE80211_NODE_HT);
4174 txwi->phymode_ifs_stbc_shortgi |=
4175 ((stbc & RT2870_TXWI_STBC_MASK) << RT2870_TXWI_STBC_SHIFT) |
4176 ((shortgi & RT2870_TXWI_SHORTGI_MASK) << RT2870_TXWI_SHORTGI_SHIFT);
4178 if (ni->ni_flags & IEEE80211_NODE_HT)
4180 txwi->phymode_ifs_stbc_shortgi |=
4181 (RT2870_TXWI_PHYMODE_HT_MIXED << RT2870_TXWI_PHYMODE_SHIFT);
4183 else
4185 if (ieee80211_rate2phytype(ic->ic_rt, rate) != IEEE80211_T_OFDM)
4187 txwi->phymode_ifs_stbc_shortgi |=
4188 (RT2870_TXWI_PHYMODE_CCK << RT2870_TXWI_PHYMODE_SHIFT);
4190 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
4191 mcs |= RT2870_TXWI_MCS_SHOTPRE;
4193 else
4195 txwi->phymode_ifs_stbc_shortgi |=
4196 (RT2870_TXWI_PHYMODE_OFDM << RT2870_TXWI_PHYMODE_SHIFT);
4200 if ((ni->ni_flags & IEEE80211_NODE_HT) &&
4201 (ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40))
4202 bw = RT2870_TXWI_BW_40;
4203 else
4204 bw = RT2870_TXWI_BW_20;
4206 txwi->bw_mcs = ((bw & RT2870_TXWI_BW_MASK) << RT2870_TXWI_BW_SHIFT) |
4207 ((mcs & RT2870_TXWI_MCS_MASK) << RT2870_TXWI_MCS_SHIFT);
4209 txwi->txop = (RT2870_TXWI_TXOP_HT << RT2870_TXWI_TXOP_SHIFT);
4211 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
4212 (!hasqos || (qos & IEEE80211_QOS_ACKPOLICY) != IEEE80211_QOS_ACKPOLICY_NOACK))
4214 txwi->bawin_size_xflags |=
4215 (RT2870_TXWI_XFLAGS_ACK << RT2870_TXWI_XFLAGS_SHIFT);
4217 if (ni->ni_flags & IEEE80211_NODE_HT)
4219 /* preamble + plcp + signal extension */
4221 dur = 16 + 4 + 6;
4223 else
4225 dur = ieee80211_ack_duration(ic->ic_rt, rate,
4226 ic->ic_flags & IEEE80211_F_SHPREAMBLE);
4229 *(uint16_t *) wh->i_dur = htole16(dur);
4232 /* ask MAC to insert timestamp into probe responses */
4234 if ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
4235 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
4236 txwi->mpdu_density_flags |=
4237 (RT2870_TXWI_FLAGS_TS << RT2870_TXWI_FLAGS_SHIFT);
4239 if (ieee80211_radiotap_active_vap(vap))
4241 tap = &sc->txtap;
4243 tap->flags = IEEE80211_RADIOTAP_F_DATAPAD;
4244 tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
4245 tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
4246 tap->chan_ieee = ic->ic_curchan->ic_ieee;
4247 tap->chan_maxpow = 0;
4249 if (ni->ni_flags & IEEE80211_NODE_HT)
4250 tap->rate = mcs | IEEE80211_RATE_MCS;
4251 else
4252 tap->rate = rate;
4254 if (mcs & RT2870_TXWI_MCS_SHOTPRE)
4255 tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
4257 if (shortgi)
4258 tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
4260 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4261 tap->flags |= IEEE80211_RADIOTAP_F_WEP;
4263 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4265 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
4267 ieee80211_radiotap_tx(vap, m);
4269 wh->i_fc[1] |= IEEE80211_FC1_WEP;
4271 else
4273 ieee80211_radiotap_tx(vap, m);
4277 m_copydata(m, 0, m->m_pkthdr.len, (caddr_t) (txwi + 1));
4279 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4280 "%s: sending data: qid=%d, hdrsize=%d, hdrspace=%d, len=%d, "
4281 "bw=%d, stbc=%d, shortgi=%d, mcs=%d, wcid=0x%02x, DMA len=%d\n",
4282 device_get_nameunit(sc->dev),
4283 qid, hdrsize, hdrspace, m->m_pkthdr.len,
4284 bw, stbc, shortgi, mcs, wcid, dmalen);
4286 data->len = dmalen;
4287 data->m = m;
4288 data->ni = ni;
4290 STAILQ_INSERT_TAIL(&ring->pending, data, next);
4291 ring->queued++;
4293 usbd_transfer_start(sc->usb_xfer[1 + qid]);
4295 return 0;
4299 * rt2870_tx_raw
4301 static int rt2870_tx_raw(struct rt2870_softc *sc,
4302 struct mbuf *m, struct ieee80211_node *ni,
4303 const struct ieee80211_bpf_params *params)
4305 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4306 "%s: Tx raw\n",
4307 device_get_nameunit(sc->dev));
4309 return 0;
4313 * rt2870_rx_intr
4315 static void rt2870_rx_intr(struct usb_xfer *xfer, usb_error_t error)
4317 struct rt2870_softc *sc;
4318 struct ifnet *ifp;
4319 struct rt2870_softc_rx_ring *ring;
4320 struct rt2870_softc_rx_data *data;
4321 int len;
4323 sc = usbd_xfer_softc(xfer);
4324 ifp = sc->ifp;
4325 ring = &sc->rx_ring;
4327 RT2870_DPRINTF(sc, RT2870_DEBUG_INTR,
4328 "%s: Rx interrupt: state=%d, error=%s\n",
4329 device_get_nameunit(sc->dev),
4330 USB_GET_STATE(xfer), usbd_errstr(error));
4332 switch (USB_GET_STATE(xfer))
4334 case USB_ST_TRANSFERRED:
4335 sc->interrupts++;
4336 sc->rx_interrupts++;
4338 data = STAILQ_FIRST(&ring->active);
4339 if (data == NULL)
4340 goto setup;
4342 STAILQ_REMOVE_HEAD(&ring->active, next);
4344 usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
4346 data->len = len;
4348 STAILQ_INSERT_TAIL(&ring->done, data, next);
4350 taskqueue_enqueue(sc->taskqueue, &sc->rx_done_task);
4352 /* FALLTHROUGH */
4354 setup:
4356 case USB_ST_SETUP:
4357 data = STAILQ_FIRST(&ring->inactive);
4358 if (data == NULL)
4359 break;
4361 STAILQ_REMOVE_HEAD(&ring->inactive, next);
4363 STAILQ_INSERT_TAIL(&ring->active, data, next);
4365 usbd_xfer_set_frame_data(xfer, 0, data->buf, usbd_xfer_max_len(xfer));
4366 usbd_transfer_submit(xfer);
4367 break;
4369 default:
4370 sc->interrupts++;
4371 sc->rx_interrupts++;
4373 data = STAILQ_FIRST(&ring->active);
4374 if (data != NULL)
4376 STAILQ_REMOVE_HEAD(&ring->active, next);
4377 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
4380 if (error != USB_ERR_CANCELLED)
4382 ifp->if_ierrors++;
4384 usbd_xfer_set_stall(xfer);
4386 goto setup;
4388 break;
4393 * rt2870_tx_intr
4395 static void rt2870_tx_intr(struct usb_xfer *xfer, usb_error_t error)
4397 struct rt2870_softc *sc;
4398 struct ifnet *ifp;
4399 struct rt2870_softc_tx_ring *ring;
4400 struct rt2870_softc_tx_data *data;
4402 sc = usbd_xfer_softc(xfer);
4403 ifp = sc->ifp;
4404 ring = usbd_xfer_get_priv(xfer);
4406 usbd_xfer_status(xfer, NULL, NULL, NULL, NULL);
4408 RT2870_DPRINTF(sc, RT2870_DEBUG_INTR,
4409 "%s: Tx interrupt: state=%d, error=%s\n",
4410 device_get_nameunit(sc->dev),
4411 USB_GET_STATE(xfer), usbd_errstr(error));
4413 switch (USB_GET_STATE(xfer))
4415 case USB_ST_TRANSFERRED:
4416 sc->interrupts++;
4417 sc->tx_interrupts[ring->qid]++;
4419 data = STAILQ_FIRST(&ring->active);
4420 if (data == NULL)
4421 goto setup;
4423 STAILQ_REMOVE_HEAD(&ring->active, next);
4425 STAILQ_INSERT_TAIL(&ring->done, data, next);
4427 taskqueue_enqueue(sc->taskqueue, &sc->tx_done_task);
4429 /* FALLTHROUGH */
4431 setup:
4433 case USB_ST_SETUP:
4434 data = STAILQ_FIRST(&ring->pending);
4435 if (data == NULL)
4436 break;
4438 STAILQ_REMOVE_HEAD(&ring->pending, next);
4439 STAILQ_INSERT_TAIL(&ring->active, data, next);
4441 usbd_xfer_set_frame_data(xfer, 0, data->buf, data->len);
4442 usbd_transfer_submit(xfer);
4444 RT2870_SOFTC_UNLOCK(sc);
4446 rt2870_start(ifp);
4448 RT2870_SOFTC_LOCK(sc);
4449 break;
4451 default:
4452 sc->interrupts++;
4453 sc->tx_interrupts[ring->qid]++;
4455 data = STAILQ_FIRST(&ring->active);
4456 if (data != NULL)
4458 STAILQ_REMOVE_HEAD(&ring->active, next);
4460 printf("%s: could not transmit buffer: qid=%d, error=%s\n",
4461 device_get_nameunit(sc->dev), ring->qid, usbd_errstr(error));
4463 if (data->m != NULL)
4465 m_freem(data->m);
4466 data->m = NULL;
4469 if (data->ni != NULL)
4471 ieee80211_free_node(data->ni);
4472 data->ni = NULL;
4475 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
4477 ring->queued--;
4480 if (error != USB_ERR_CANCELLED)
4482 ifp->if_oerrors++;
4483 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4485 usbd_xfer_set_stall(xfer);
4487 goto setup;
4489 break;
4494 * rt2870_rx_done_task
4496 static void rt2870_rx_done_task(void *context, int pending)
4498 struct rt2870_softc *sc;
4499 struct ifnet *ifp;
4501 sc = context;
4502 ifp = sc->ifp;
4504 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4505 "%s: Rx done task\n",
4506 device_get_nameunit(sc->dev));
4508 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
4509 return;
4511 if (rt2870_rx_eof(sc, sc->rx_process_limit) != 0)
4512 taskqueue_enqueue(sc->taskqueue, &sc->rx_done_task);
4516 * rt2870_tx_done_task
4518 static void rt2870_tx_done_task(void *context, int pending)
4520 struct rt2870_softc *sc;
4521 struct ifnet *ifp;
4522 int i;
4524 sc = context;
4525 ifp = sc->ifp;
4527 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4528 "%s: Tx done task\n",
4529 device_get_nameunit(sc->dev));
4531 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
4532 return;
4534 for (i = sc->usb_endpoints - 2; i >= 0; i--)
4535 rt2870_tx_eof(sc, &sc->tx_ring[i]);
4537 sc->tx_timer = 0;
4539 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4543 * rt2870_periodic_task
4545 static void rt2870_periodic_task(void *context, int pending)
4547 struct rt2870_softc *sc;
4548 struct ifnet *ifp;
4549 struct ieee80211com *ic;
4550 struct ieee80211vap *vap;
4552 sc = context;
4553 ifp = sc->ifp;
4554 ic = ifp->if_l2com;
4556 RT2870_DPRINTF(sc, RT2870_DEBUG_PERIODIC,
4557 "%s: periodic task: round=%lu\n",
4558 device_get_nameunit(sc->dev), sc->periodic_round);
4560 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
4561 return;
4563 RT2870_SOFTC_LOCK(sc);
4565 sc->periodic_round++;
4567 rt2870_update_stats(sc);
4569 if ((sc->periodic_round % 10) == 0)
4571 rt2870_update_raw_counters(sc);
4573 rt2870_watchdog(sc);
4575 vap = TAILQ_FIRST(&ic->ic_vaps);
4576 if (vap != NULL)
4578 if (vap->iv_opmode == IEEE80211_M_STA)
4579 rt2870_amrr_update_iter_func(vap, vap->iv_bss);
4580 else
4581 ieee80211_iterate_nodes(&ic->ic_sta, rt2870_amrr_update_iter_func, vap);
4585 RT2870_SOFTC_UNLOCK(sc);
4587 callout_reset(&sc->periodic_ch, hz / 10, rt2870_periodic, sc);
4591 * rt2870_cmd_task
4593 static void rt2870_cmd_task(void *context, int pending)
4595 struct rt2870_softc *sc;
4596 struct rt2870_softc_cmd_ring *ring;
4597 struct rt2870_softc_cmd *cmd;
4599 sc = context;
4600 ring = &sc->cmd_ring;
4602 while (1)
4604 RT2870_SOFTC_LOCK(sc);
4606 cmd = STAILQ_FIRST(&ring->active);
4607 if (cmd == NULL)
4609 RT2870_SOFTC_UNLOCK(sc);
4610 break;
4613 STAILQ_REMOVE_HEAD(&ring->active, next);
4615 RT2870_SOFTC_UNLOCK(sc);
4617 cmd->cb(sc, cmd->data);
4619 RT2870_SOFTC_LOCK(sc);
4621 STAILQ_INSERT_TAIL(&ring->inactive, cmd, next);
4622 ring->queued--;
4624 RT2870_SOFTC_UNLOCK(sc);
4629 * rt2870_rx_eof
4631 static int rt2870_rx_eof(struct rt2870_softc *sc, int limit)
4633 struct ifnet *ifp;
4634 struct rt2870_softc_rx_ring *ring;
4635 struct rt2870_softc_rx_data *data;
4636 uint32_t dmalen;
4637 uint8_t *buf;
4638 int nframes, len;
4640 ifp = sc->ifp;
4641 ring = &sc->rx_ring;
4643 nframes = 0;
4645 while (limit != 0)
4647 RT2870_SOFTC_LOCK(sc);
4649 data = STAILQ_FIRST(&ring->done);
4650 if (data == NULL)
4652 RT2870_SOFTC_UNLOCK(sc);
4653 break;
4656 STAILQ_REMOVE_HEAD(&ring->done, next);
4658 RT2870_SOFTC_UNLOCK(sc);
4660 buf = data->buf;
4661 len = data->len;
4663 if (len < RT2870_RX_DESC_SIZE)
4665 ifp->if_ierrors++;
4666 goto skip;
4669 while (len > (sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)))
4671 dmalen = (le32toh(*(uint32_t *) buf) & 0xffff);
4673 if (dmalen == 0 || (dmalen & 3) != 0)
4675 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4676 "%s: bad DMA len=%u\n",
4677 device_get_nameunit(sc->dev), dmalen);
4678 goto skip;
4681 if ((dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)) > len)
4683 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4684 "%s: bad DMA len: DMA len=%u, USB len=%d\n",
4685 device_get_nameunit(sc->dev),
4686 (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)), len);
4687 goto skip;
4690 nframes++;
4692 rt2870_rx_frame(sc, buf + sizeof(uint32_t), dmalen);
4694 buf += (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo));
4695 len -= (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo));
4698 skip:
4700 RT2870_SOFTC_LOCK(sc);
4702 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
4704 usbd_transfer_start(sc->usb_xfer[0]);
4706 RT2870_SOFTC_UNLOCK(sc);
4708 limit--;
4711 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4712 "%s: Rx eof: nframes=%d\n",
4713 device_get_nameunit(sc->dev), nframes);
4715 sc->rx_packets += nframes;
4717 return (limit == 0);
4721 * rt2870_tx_eof
4723 static void rt2870_tx_eof(struct rt2870_softc *sc,
4724 struct rt2870_softc_tx_ring *ring)
4726 struct ifnet *ifp;
4727 struct rt2870_softc_tx_data *data;
4728 int nframes;
4730 ifp = sc->ifp;
4732 nframes = 0;
4734 while (1)
4736 RT2870_SOFTC_LOCK(sc);
4738 data = STAILQ_FIRST(&ring->done);
4739 if (data == NULL)
4741 RT2870_SOFTC_UNLOCK(sc);
4742 break;
4745 STAILQ_REMOVE_HEAD(&ring->done, next);
4747 RT2870_SOFTC_UNLOCK(sc);
4749 nframes++;
4751 if (data->m->m_flags & M_TXCB)
4752 ieee80211_process_callback(data->ni, data->m, 0);
4754 m_freem(data->m);
4756 ieee80211_free_node(data->ni);
4758 data->m = NULL;
4759 data->ni = NULL;
4761 RT2870_SOFTC_LOCK(sc);
4763 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
4765 ring->queued--;
4766 ifp->if_opackets++;
4768 RT2870_SOFTC_UNLOCK(sc);
4771 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4772 "%s: Tx eof: qid=%d, nframes=%d\n",
4773 device_get_nameunit(sc->dev), ring->qid, nframes);
4777 * rt2870_update_stats
4779 static void rt2870_update_stats(struct rt2870_softc *sc)
4781 struct ifnet *ifp;
4782 struct ieee80211com *ic;
4783 struct ieee80211vap *vap;
4784 struct ieee80211_node *ni;
4785 uint16_t associd;
4786 uint8_t wcid;
4787 uint32_t stacnt[3];
4788 int txcnt, retrycnt, failcnt;
4790 ifp = sc->ifp;
4791 ic = ifp->if_l2com;
4793 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
4794 "%s: update statistic\n",
4795 device_get_nameunit(sc->dev));
4797 rt2870_drain_fifo_stats(sc);
4799 if (ic->ic_opmode == IEEE80211_M_STA)
4801 vap = TAILQ_FIRST(&ic->ic_vaps);
4802 ni = vap->iv_bss;
4804 associd = (ni != NULL) ? ni->ni_associd : 0;
4805 wcid = RT2870_AID2WCID(associd);
4807 /* read and clear Tx statistic registers */
4809 rt2870_io_mac_read_multi(sc, RT2870_REG_TX_STA_CNT0,
4810 stacnt, sizeof(stacnt));
4812 txcnt = le32toh(stacnt[1]) & 0xffff;
4813 retrycnt = le32toh(stacnt[1]) >> 16;
4814 failcnt = le32toh(stacnt[0]) & 0xffff;
4816 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
4817 "%s: update statistic: associd=0x%04x, txcnt=%d, retrycnt=%d, failcnt=%d\n",
4818 device_get_nameunit(sc->dev),
4819 associd, txcnt, retrycnt, failcnt);
4821 ifp->if_oerrors += failcnt;
4823 rt2870_amrr_tx_update(&sc->amrr_node[wcid],
4824 txcnt + retrycnt + failcnt, txcnt + retrycnt, retrycnt + failcnt);
4829 * rt2870_watchdog
4831 static void rt2870_watchdog(struct rt2870_softc *sc)
4833 uint32_t tmp;
4834 int ntries;
4836 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
4838 RT2870_DPRINTF(sc, RT2870_DEBUG_WATCHDOG,
4839 "%s: watchdog: TXRXQ_PCNT=0x%08x\n",
4840 device_get_nameunit(sc->dev), tmp);
4842 if (((tmp >> RT2870_REG_TX0Q_PCNT_SHIFT) & RT2870_REG_TX0Q_PCNT_MASK) != 0)
4844 sc->tx_queue_not_empty[0]++;
4846 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40012);
4848 for (ntries = 0; ntries < 10; ntries++)
4850 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
4851 if (((tmp >> RT2870_REG_TX0Q_PCNT_SHIFT) & RT2870_REG_TX0Q_PCNT_MASK) == 0)
4852 break;
4854 DELAY(1);
4857 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40006);
4860 if (((tmp >> RT2870_REG_TX1Q_PCNT_SHIFT) & RT2870_REG_TX1Q_PCNT_MASK) != 0)
4862 sc->tx_queue_not_empty[1]++;
4864 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf4000a);
4866 for (ntries = 0; ntries < 10; ntries++)
4868 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
4869 if (((tmp >> RT2870_REG_TX1Q_PCNT_SHIFT) & RT2870_REG_TX1Q_PCNT_MASK) == 0)
4870 break;
4872 DELAY(1);
4875 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40006);
4880 * rt2870_drain_fifo_stats
4882 static void rt2870_drain_fifo_stats(struct rt2870_softc *sc)
4884 struct ifnet *ifp;
4885 uint32_t stats;
4886 uint8_t wcid, mcs, pid;
4887 int ok, retrycnt;
4889 ifp = sc->ifp;
4891 /* drain Tx status FIFO (maxsize = 16) */
4893 while ((stats = rt2870_io_mac_read(sc, RT2870_REG_TX_STA_FIFO)) &
4894 RT2870_REG_TX_STA_FIFO_VALID)
4896 wcid = (stats >> RT2870_REG_TX_STA_FIFO_WCID_SHIFT) &
4897 RT2870_REG_TX_STA_FIFO_WCID_MASK;
4899 /* if no ACK was requested, no feedback is available */
4901 if (!(stats & RT2870_REG_TX_STA_FIFO_ACK_REQ) || wcid == 0xff)
4902 continue;
4904 /* update AMRR statistic */
4906 ok = (stats & RT2870_REG_TX_STA_FIFO_TX_OK) ? 1 : 0;
4907 mcs = (stats >> RT2870_REG_TX_STA_FIFO_MCS_SHIFT) &
4908 RT2870_REG_TX_STA_FIFO_MCS_MASK;
4909 pid = (stats >> RT2870_REG_TX_STA_FIFO_PID_SHIFT) &
4910 RT2870_REG_TX_STA_FIFO_PID_MASK;
4911 retrycnt = pid - mcs;
4913 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
4914 "%s: FIFO statistic: wcid=0x%02x, ok=%d, mcs=0x%02x, pid=0x%02x, retrycnt=%d\n",
4915 device_get_nameunit(sc->dev),
4916 wcid, ok, mcs, pid, retrycnt);
4918 rt2870_amrr_tx_complete(&sc->amrr_node[wcid], ok, retrycnt);
4920 if (!ok)
4921 ifp->if_oerrors++;
4926 * rt2870_update_raw_counters
4928 static void rt2870_update_raw_counters(struct rt2870_softc *sc)
4930 uint32_t tmp;
4932 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT0);
4934 sc->rx_crc_errors += tmp & 0xffff;
4935 sc->rx_phy_errors += tmp >> 16;
4937 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT1);
4939 sc->rx_false_ccas += tmp & 0xffff;
4940 sc->rx_plcp_errors += tmp >> 16;
4942 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT2);
4944 sc->rx_dup_packets += tmp & 0xffff;
4945 sc->rx_fifo_overflows += tmp >> 16;
4949 * rt2870_txrx_enable
4951 static int rt2870_txrx_enable(struct rt2870_softc *sc)
4953 struct ieee80211com *ic;
4954 struct ifnet *ifp;
4955 uint32_t tmp;
4956 int ntries;
4958 ifp = sc->ifp;
4959 ic = ifp->if_l2com;
4961 /* enable Tx/Rx DMA engine */
4963 tmp = rt2870_io_mac_read(sc, RT2870_REG_SCHDMA_USB_CYC_CFG);
4965 tmp &= 0xffffff00;
4966 tmp |= 0x1e;
4968 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_CYC_CFG, tmp);
4970 if ((sc->mac_rev & 0xffff) != 0x0101)
4971 rt2870_io_mac_write(sc, RT2870_REG_TX_TXOP_CTRL_CFG, 0x583f);
4973 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, RT2870_REG_TX_ENABLE);
4975 for (ntries = 0; ntries < 200; ntries++)
4977 tmp = rt2870_io_mac_read(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG);
4978 if (!(tmp & (RT2870_REG_TX_DMA_BUSY | RT2870_REG_RX_DMA_BUSY)))
4979 break;
4981 DELAY(1000);
4984 if (ntries == 200)
4986 printf("%s: timeout waiting for DMA engine\n",
4987 device_get_nameunit(sc->dev));
4988 return -1;
4991 DELAY(50);
4993 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP0_CFG, 0);
4994 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP1_CFG,
4995 (48 << 16) | 96);
4997 tmp |= RT2870_REG_TX_WB_DDONE |
4998 RT2870_REG_RX_DMA_ENABLE |
4999 RT2870_REG_TX_DMA_ENABLE;
5001 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
5003 tmp = RT2870_REG_USB_DMA_TX_ENABLE |
5004 RT2870_REG_USB_DMA_RX_ENABLE |
5005 RT2870_REG_USB_DMA_RX_AGG_ENABLE |
5006 /* Rx agg limit in unit of 1024 byte */
5007 ((RT2870_USB_RX_BULK_BUFLEN / 1024 - 3) << RT2870_REG_USB_DMA_RX_AGG_LIMIT_SHIFT) |
5008 /* Rx agg timeout in unit of 33ns */
5009 0x80;
5011 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_DMA_CFG, tmp);
5013 /* set Rx filter */
5015 tmp = RT2870_REG_RX_FILTER_DROP_CRC_ERR |
5016 RT2870_REG_RX_FILTER_DROP_PHY_ERR;
5018 if (ic->ic_opmode != IEEE80211_M_MONITOR)
5020 tmp |= RT2870_REG_RX_FILTER_DROP_DUPL |
5021 RT2870_REG_RX_FILTER_DROP_CTS |
5022 RT2870_REG_RX_FILTER_DROP_BA |
5023 RT2870_REG_RX_FILTER_DROP_ACK |
5024 RT2870_REG_RX_FILTER_DROP_VER_ERR |
5025 RT2870_REG_RX_FILTER_DROP_CTRL_RSV |
5026 RT2870_REG_RX_FILTER_DROP_CFACK |
5027 RT2870_REG_RX_FILTER_DROP_CFEND;
5029 if (ic->ic_opmode == IEEE80211_M_STA)
5030 tmp |= RT2870_REG_RX_FILTER_DROP_RTS |
5031 RT2870_REG_RX_FILTER_DROP_PSPOLL;
5033 if (!(ifp->if_flags & IFF_PROMISC))
5034 tmp |= RT2870_REG_RX_FILTER_DROP_UC_NOME;
5037 rt2870_io_mac_write(sc, RT2870_REG_RX_FILTER_CFG, tmp);
5039 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL,
5040 RT2870_REG_RX_ENABLE | RT2870_REG_TX_ENABLE);
5042 return 0;
5046 * rt2870_alloc_rx_ring
5048 static int rt2870_alloc_rx_ring(struct rt2870_softc *sc,
5049 struct rt2870_softc_rx_ring *ring)
5051 struct rt2870_softc_rx_data *data;
5052 int i, error;
5054 STAILQ_INIT(&ring->inactive);
5055 STAILQ_INIT(&ring->active);
5056 STAILQ_INIT(&ring->done);
5058 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
5060 data = &ring->data[i];
5062 data->buf = malloc(RT2870_USB_RX_BULK_BUFLEN, M_USBDEV, M_NOWAIT);
5063 if (data->buf == NULL)
5065 printf("%s: could not allocate Rx buffer\n",
5066 device_get_nameunit(sc->dev));
5067 error = ENOMEM;
5068 goto fail;
5071 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5074 return 0;
5076 fail:
5078 rt2870_free_rx_ring(sc, ring);
5080 return error;
5084 * rt2870_reset_rx_ring
5086 static void rt2870_reset_rx_ring(struct rt2870_softc *sc,
5087 struct rt2870_softc_rx_ring *ring)
5089 struct rt2870_softc_rx_data *data;
5090 int i;
5092 STAILQ_INIT(&ring->inactive);
5093 STAILQ_INIT(&ring->active);
5094 STAILQ_INIT(&ring->done);
5096 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
5098 data = &ring->data[i];
5100 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5105 * rt2870_free_rx_ring
5107 static void rt2870_free_rx_ring(struct rt2870_softc *sc,
5108 struct rt2870_softc_rx_ring *ring)
5110 struct rt2870_softc_rx_data *data;
5111 int i;
5113 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
5115 data = &ring->data[i];
5117 if (data->buf != NULL)
5119 free(data->buf, M_USBDEV);
5120 data->buf = NULL;
5126 * rt2870_alloc_tx_ring
5128 static int rt2870_alloc_tx_ring(struct rt2870_softc *sc,
5129 struct rt2870_softc_tx_ring *ring, int qid)
5131 struct rt2870_softc_tx_data *data;
5132 int i, error;
5134 STAILQ_INIT(&ring->inactive);
5135 STAILQ_INIT(&ring->pending);
5136 STAILQ_INIT(&ring->active);
5137 STAILQ_INIT(&ring->done);
5139 ring->queued = 0;
5140 ring->qid = qid;
5142 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
5144 data = &ring->data[i];
5146 data->buf = malloc(RT2870_TX_DESC_SIZE + MJUMPAGESIZE, M_USBDEV, M_NOWAIT);
5147 if (data->buf == NULL)
5149 printf("%s: could not allocate Tx buffer\n",
5150 device_get_nameunit(sc->dev));
5151 error = ENOMEM;
5152 goto fail;
5155 memset(data->buf, 0, RT2870_TX_DESC_SIZE);
5157 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5160 return 0;
5162 fail:
5164 rt2870_free_tx_ring(sc, ring);
5166 return error;
5170 * rt2870_reset_tx_ring
5172 static void rt2870_reset_tx_ring(struct rt2870_softc *sc,
5173 struct rt2870_softc_tx_ring *ring)
5175 struct rt2870_softc_tx_data *data;
5176 int i;
5178 STAILQ_INIT(&ring->inactive);
5179 STAILQ_INIT(&ring->pending);
5180 STAILQ_INIT(&ring->active);
5181 STAILQ_INIT(&ring->done);
5183 ring->queued = 0;
5185 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
5187 data = &ring->data[i];
5189 if (data->m != NULL)
5191 m_free(data->m);
5192 data->m = NULL;
5195 if (data->ni != NULL)
5197 ieee80211_free_node(data->ni);
5198 data->ni = NULL;
5201 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5206 * rt2870_free_tx_ring
5208 static void rt2870_free_tx_ring(struct rt2870_softc *sc,
5209 struct rt2870_softc_tx_ring *ring)
5211 struct rt2870_softc_tx_data *data;
5212 int i;
5214 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
5216 data = &ring->data[i];
5218 if (data->buf != NULL)
5220 free(data->buf, M_USBDEV);
5221 data->buf = NULL;
5224 if (data->m != NULL)
5226 m_free(data->m);
5227 data->m = NULL;
5230 if (data->ni != NULL)
5232 ieee80211_free_node(data->ni);
5233 data->ni = NULL;
5239 * rt2870_reset_cmd_ring
5241 static void rt2870_reset_cmd_ring(struct rt2870_softc *sc,
5242 struct rt2870_softc_cmd_ring *ring)
5244 struct rt2870_softc_cmd *cmd;
5245 int i;
5247 STAILQ_INIT(&ring->inactive);
5248 STAILQ_INIT(&ring->active);
5250 ring->queued = 0;
5252 for (i = 0; i < RT2870_SOFTC_CMD_RING_CMD_COUNT; i++)
5254 cmd = &ring->cmd[i];
5256 STAILQ_INSERT_TAIL(&ring->inactive, cmd, next);
5261 * rt2870_sysctl_attach
5263 static void rt2870_sysctl_attach(struct rt2870_softc *sc)
5265 struct sysctl_ctx_list *ctx;
5266 struct sysctl_oid *tree;
5267 struct sysctl_oid *stats;
5269 ctx = device_get_sysctl_ctx(sc->dev);
5270 tree = device_get_sysctl_tree(sc->dev);
5272 stats = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
5273 "stats", CTLFLAG_RD, 0, "statistic");
5275 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5276 "interrupts", CTLFLAG_RD, &sc->interrupts, 0,
5277 "all interrupts");
5279 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5280 "rx_interrupts", CTLFLAG_RD, &sc->rx_interrupts, 0,
5281 "Rx interrupts");
5283 if (sc->usb_endpoints == RT2870_SOFTC_USB_XFER_COUNT)
5285 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5286 "tx_mgmt_interrupts", CTLFLAG_RD, &sc->tx_interrupts[5], 0,
5287 "Tx MGMT interrupts");
5289 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5290 "tx_hcca_interrupts", CTLFLAG_RD, &sc->tx_interrupts[4], 0,
5291 "Tx HCCA interrupts");
5294 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5295 "tx_ac3_interrupts", CTLFLAG_RD, &sc->tx_interrupts[3], 0,
5296 "Tx AC3 interrupts");
5298 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5299 "tx_ac2_interrupts", CTLFLAG_RD, &sc->tx_interrupts[2], 0,
5300 "Tx AC2 interrupts");
5302 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5303 "tx_ac1_interrupts", CTLFLAG_RD, &sc->tx_interrupts[1], 0,
5304 "Tx AC1 interrupts");
5306 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5307 "tx_ac0_interrupts", CTLFLAG_RD, &sc->tx_interrupts[0], 0,
5308 "Tx AC0 interrupts");
5310 if (sc->usb_endpoints == RT2870_SOFTC_USB_XFER_COUNT)
5312 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5313 "tx_mgmt_data_queued", CTLFLAG_RD, &sc->tx_ring[5].queued, 0,
5314 "Tx MGMT data queued");
5316 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5317 "tx_hcca_data_queued", CTLFLAG_RD, &sc->tx_ring[4].queued, 0,
5318 "Tx HCCA data queued");
5321 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5322 "tx_ac3_data_queued", CTLFLAG_RD, &sc->tx_ring[3].queued, 0,
5323 "Tx AC3 data queued");
5325 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5326 "tx_ac2_data_queued", CTLFLAG_RD, &sc->tx_ring[2].queued, 0,
5327 "Tx AC2 data queued");
5329 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5330 "tx_ac1_data_queued", CTLFLAG_RD, &sc->tx_ring[1].queued, 0,
5331 "Tx AC1 data queued");
5333 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5334 "tx_ac0_data_queued", CTLFLAG_RD, &sc->tx_ring[0].queued, 0,
5335 "Tx AC0 data queued");
5337 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5338 "tx_watchdog_timeouts", CTLFLAG_RD, &sc->tx_watchdog_timeouts, 0,
5339 "Tx watchdog timeouts");
5341 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5342 "rx_mbuf_alloc_errors", CTLFLAG_RD, &sc->rx_mbuf_alloc_errors, 0,
5343 "Rx mbuf allocation errors");
5345 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5346 "tx_queue_0_not_empty", CTLFLAG_RD, &sc->tx_queue_not_empty[0], 0,
5347 "Tx queue 0 not empty");
5349 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5350 "tx_queue_1_not_empty", CTLFLAG_RD, &sc->tx_queue_not_empty[1], 0,
5351 "Tx queue 1 not empty");
5353 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5354 "rx_packets", CTLFLAG_RD, &sc->rx_packets, 0,
5355 "Rx packets");
5357 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5358 "rx_crc_errors", CTLFLAG_RD, &sc->rx_crc_errors, 0,
5359 "Rx CRC errors");
5361 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5362 "rx_phy_errors", CTLFLAG_RD, &sc->rx_phy_errors, 0,
5363 "Rx PHY errors");
5365 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5366 "rx_false_ccas", CTLFLAG_RD, &sc->rx_false_ccas, 0,
5367 "Rx false CCAs");
5369 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5370 "rx_plcp_errors", CTLFLAG_RD, &sc->rx_plcp_errors, 0,
5371 "Rx PLCP errors");
5373 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5374 "rx_dup_packets", CTLFLAG_RD, &sc->rx_dup_packets, 0,
5375 "Rx duplicate packets");
5377 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5378 "rx_fifo_overflows", CTLFLAG_RD, &sc->rx_fifo_overflows, 0,
5379 "Rx FIFO overflows");
5382 static device_method_t rt2870_dev_methods[] =
5384 DEVMETHOD(device_probe, rt2870_probe),
5385 DEVMETHOD(device_attach, rt2870_attach),
5386 DEVMETHOD(device_detach, rt2870_detach),
5387 { 0, 0 }
5390 static driver_t rt2870_driver =
5392 "rt2870",
5393 rt2870_dev_methods,
5394 sizeof(struct rt2870_softc),
5397 static devclass_t rt2870_dev_class;
5399 DRIVER_MODULE(rt2870, uhub, rt2870_driver, rt2870_dev_class,
5400 NULL, 0);
5402 MODULE_DEPEND(rt2870, usb, 1, 1, 1);
5403 MODULE_DEPEND(rt2870, wlan, 1, 1, 1);