Introduced Tx QID pending mask in order to improve Tx interrupt handling
[ralink_drivers/rt2870_fbsd8.git] / rt2870.c
blob85a78d2d3059dd0de15f419c33552412a448777f
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_NODE(_hw, OID_AUTO, rt2870, CTLFLAG_RD, 0, "RT2870 driver parameters");
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 RT2870_SOFTC_UNLOCK(sc);
794 taskqueue_block(sc->taskqueue);
796 taskqueue_drain(sc->taskqueue, &sc->rx_done_task);
797 taskqueue_drain(sc->taskqueue, &sc->tx_done_task);
798 taskqueue_drain(sc->taskqueue, &sc->periodic_task);
799 taskqueue_drain(sc->taskqueue, &sc->cmd_task);
801 /* stop all USB transfers */
803 usbd_transfer_unsetup(sc->usb_xfer, sc->usb_endpoints);
805 RT2870_SOFTC_LOCK(sc);
807 /* free Tx and Rx rings */
809 for (i = 0; i < sc->usb_endpoints - 1; i++)
810 rt2870_free_tx_ring(sc, &sc->tx_ring[i]);
812 rt2870_free_rx_ring(sc, &sc->rx_ring);
814 RT2870_SOFTC_UNLOCK(sc);
816 ieee80211_ifdetach(ic);
818 if_free(ifp);
820 taskqueue_free(sc->taskqueue);
822 mtx_destroy(&sc->lock);
824 return 0;
828 * rt2870_init_channels
830 static void rt2870_init_channels(struct rt2870_softc *sc)
832 struct ifnet *ifp;
833 struct ieee80211com *ic;
834 struct ieee80211_channel *c;
835 int i, flags;
837 ifp = sc->ifp;
838 ic = ifp->if_l2com;
840 /* set supported channels for 2GHz band */
842 for (i = 1; i <= 14; i++)
844 c = &ic->ic_channels[ic->ic_nchans++];
845 flags = IEEE80211_CHAN_B;
847 c->ic_freq = ieee80211_ieee2mhz(i, flags);
848 c->ic_ieee = i;
849 c->ic_flags = flags;
851 c = &ic->ic_channels[ic->ic_nchans++];
852 flags = IEEE80211_CHAN_B | IEEE80211_CHAN_HT20;
854 c->ic_freq = ieee80211_ieee2mhz(i, flags);
855 c->ic_ieee = i;
856 c->ic_flags = flags;
858 c = &ic->ic_channels[ic->ic_nchans++];
859 flags = IEEE80211_CHAN_G;
861 c->ic_freq = ieee80211_ieee2mhz(i, flags);
862 c->ic_ieee = i;
863 c->ic_flags = flags;
865 c = &ic->ic_channels[ic->ic_nchans++];
866 flags = IEEE80211_CHAN_G | IEEE80211_CHAN_HT20;
868 c->ic_freq = ieee80211_ieee2mhz(i, flags);
869 c->ic_ieee = i;
870 c->ic_flags = flags;
873 /* set supported channels for 5GHz band */
875 if (sc->rf_rev == RT2870_EEPROM_RF_2850 ||
876 sc->rf_rev == RT2870_EEPROM_RF_2750)
878 for (i = 36; i <= 64; i += 4)
880 c = &ic->ic_channels[ic->ic_nchans++];
881 flags = IEEE80211_CHAN_A;
883 c->ic_freq = ieee80211_ieee2mhz(i, flags);
884 c->ic_ieee = i;
885 c->ic_flags = flags;
887 c = &ic->ic_channels[ic->ic_nchans++];
888 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
890 c->ic_freq = ieee80211_ieee2mhz(i, flags);
891 c->ic_ieee = i;
892 c->ic_flags = flags;
895 for (i = 100; i <= 140; i += 4)
897 c = &ic->ic_channels[ic->ic_nchans++];
898 flags = IEEE80211_CHAN_A;
900 c->ic_freq = ieee80211_ieee2mhz(i, flags);
901 c->ic_ieee = i;
902 c->ic_flags = flags;
904 c = &ic->ic_channels[ic->ic_nchans++];
905 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
907 c->ic_freq = ieee80211_ieee2mhz(i, flags);
908 c->ic_ieee = i;
909 c->ic_flags = flags;
912 for (i = 149; i <= 165; i += 4)
914 c = &ic->ic_channels[ic->ic_nchans++];
915 flags = IEEE80211_CHAN_A;
917 c->ic_freq = ieee80211_ieee2mhz(i, flags);
918 c->ic_ieee = i;
919 c->ic_flags = flags;
921 c = &ic->ic_channels[ic->ic_nchans++];
922 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
924 c->ic_freq = ieee80211_ieee2mhz(i, flags);
925 c->ic_ieee = i;
926 c->ic_flags = flags;
932 * rt2870_init_channels_ht40
934 static void rt2870_init_channels_ht40(struct rt2870_softc *sc)
936 struct ifnet *ifp;
937 struct ieee80211com *ic;
938 struct ieee80211_channel *c, *cent, *ext;
939 int i, flags;
941 ifp = sc->ifp;
942 ic = ifp->if_l2com;
944 /* set supported channels for 2GHz band */
946 for (i = 1; i <= 14; i++)
948 flags = IEEE80211_CHAN_G | IEEE80211_CHAN_HT40;
950 /* find the center channel */
952 cent = ieee80211_find_channel_byieee(ic, i,
953 flags & ~IEEE80211_CHAN_HT);
954 if (cent == NULL)
956 printf("%s: skip channel %d, could not find center channel\n",
957 device_get_nameunit(sc->dev), i);
958 continue;
961 /* find the extension channel */
963 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
964 flags & ~IEEE80211_CHAN_HT);
965 if (ext == NULL)
967 printf("%s: skip channel %d, could not find extension channel\n",
968 device_get_nameunit(sc->dev), i);
969 continue;
972 c = &ic->ic_channels[ic->ic_nchans++];
974 *c = *cent;
975 c->ic_extieee = ext->ic_ieee;
976 c->ic_flags &= ~IEEE80211_CHAN_HT;
977 c->ic_flags |= IEEE80211_CHAN_HT40U;
979 c = &ic->ic_channels[ic->ic_nchans++];
981 *c = *ext;
982 c->ic_extieee = cent->ic_ieee;
983 c->ic_flags &= ~IEEE80211_CHAN_HT;
984 c->ic_flags |= IEEE80211_CHAN_HT40D;
987 /* set supported channels for 5GHz band */
989 if (sc->rf_rev == RT2870_EEPROM_RF_2850 ||
990 sc->rf_rev == RT2870_EEPROM_RF_2750)
992 for (i = 36; i <= 64; i += 4)
994 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
996 /* find the center channel */
998 cent = ieee80211_find_channel_byieee(ic, i,
999 flags & ~IEEE80211_CHAN_HT);
1000 if (cent == NULL)
1002 printf("%s: skip channel %d, could not find center channel\n",
1003 device_get_nameunit(sc->dev), i);
1004 continue;
1007 /* find the extension channel */
1009 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1010 flags & ~IEEE80211_CHAN_HT);
1011 if (ext == NULL)
1013 printf("%s: skip channel %d, could not find extension channel\n",
1014 device_get_nameunit(sc->dev), i);
1015 continue;
1018 c = &ic->ic_channels[ic->ic_nchans++];
1020 *c = *cent;
1021 c->ic_extieee = ext->ic_ieee;
1022 c->ic_flags &= ~IEEE80211_CHAN_HT;
1023 c->ic_flags |= IEEE80211_CHAN_HT40U;
1025 c = &ic->ic_channels[ic->ic_nchans++];
1027 *c = *ext;
1028 c->ic_extieee = cent->ic_ieee;
1029 c->ic_flags &= ~IEEE80211_CHAN_HT;
1030 c->ic_flags |= IEEE80211_CHAN_HT40D;
1033 for (i = 100; i <= 140; i += 4)
1035 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
1037 /* find the center channel */
1039 cent = ieee80211_find_channel_byieee(ic, i,
1040 flags & ~IEEE80211_CHAN_HT);
1041 if (cent == NULL)
1043 printf("%s: skip channel %d, could not find center channel\n",
1044 device_get_nameunit(sc->dev), i);
1045 continue;
1048 /* find the extension channel */
1050 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1051 flags & ~IEEE80211_CHAN_HT);
1052 if (ext == NULL)
1054 printf("%s: skip channel %d, could not find extension channel\n",
1055 device_get_nameunit(sc->dev), i);
1056 continue;
1059 c = &ic->ic_channels[ic->ic_nchans++];
1061 *c = *cent;
1062 c->ic_extieee = ext->ic_ieee;
1063 c->ic_flags &= ~IEEE80211_CHAN_HT;
1064 c->ic_flags |= IEEE80211_CHAN_HT40U;
1066 c = &ic->ic_channels[ic->ic_nchans++];
1068 *c = *ext;
1069 c->ic_extieee = cent->ic_ieee;
1070 c->ic_flags &= ~IEEE80211_CHAN_HT;
1071 c->ic_flags |= IEEE80211_CHAN_HT40D;
1074 for (i = 149; i <= 165; i += 4)
1076 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
1078 /* find the center channel */
1080 cent = ieee80211_find_channel_byieee(ic, i,
1081 flags & ~IEEE80211_CHAN_HT);
1082 if (cent == NULL)
1084 printf("%s: skip channel %d, could not find center channel\n",
1085 device_get_nameunit(sc->dev), i);
1086 continue;
1089 /* find the extension channel */
1091 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1092 flags & ~IEEE80211_CHAN_HT);
1093 if (ext == NULL)
1095 printf("%s: skip channel %d, could not find extension channel\n",
1096 device_get_nameunit(sc->dev), i);
1097 continue;
1100 c = &ic->ic_channels[ic->ic_nchans++];
1102 *c = *cent;
1103 c->ic_extieee = ext->ic_ieee;
1104 c->ic_flags &= ~IEEE80211_CHAN_HT;
1105 c->ic_flags |= IEEE80211_CHAN_HT40U;
1107 c = &ic->ic_channels[ic->ic_nchans++];
1109 *c = *ext;
1110 c->ic_extieee = cent->ic_ieee;
1111 c->ic_flags &= ~IEEE80211_CHAN_HT;
1112 c->ic_flags |= IEEE80211_CHAN_HT40D;
1118 * rt2870_init_locked
1120 static void rt2870_init_locked(void *priv)
1122 struct rt2870_softc *sc;
1123 struct ifnet *ifp;
1124 struct ieee80211com *ic;
1125 int ntries, error, i;
1126 uint32_t tmp, stacnt[6];
1128 sc = priv;
1129 ifp = sc->ifp;
1130 ic = ifp->if_l2com;
1132 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1133 "%s: initializing\n",
1134 device_get_nameunit(sc->dev));
1136 RT2870_SOFTC_ASSERT_LOCKED(sc);
1138 if (!(sc->flags & RT2870_SOFTC_FLAGS_UCODE_LOADED))
1140 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1141 "%s: loading 8051 microcode\n",
1142 device_get_nameunit(sc->dev));
1144 error = rt2870_io_mcu_load_ucode(sc, rt2870_ucode, sizeof(rt2870_ucode));
1145 if (error != 0)
1147 printf("%s: could not load 8051 microcode\n",
1148 device_get_nameunit(sc->dev));
1149 goto fail;
1152 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1153 "%s: 8051 microcode was successfully loaded\n",
1154 device_get_nameunit(sc->dev));
1156 sc->flags |= RT2870_SOFTC_FLAGS_UCODE_LOADED;
1159 /* wait while DMA engine is busy */
1161 for (ntries = 0; ntries < 100; ntries++)
1163 tmp = rt2870_io_mac_read(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG);
1164 if (!(tmp & (RT2870_REG_TX_DMA_BUSY | RT2870_REG_RX_DMA_BUSY)))
1165 break;
1167 DELAY(1000);
1170 if (ntries == 100)
1172 printf("%s: timeout waiting for DMA engine\n",
1173 device_get_nameunit(sc->dev));
1174 goto fail;
1177 tmp &= 0xff0;
1178 tmp |= RT2870_REG_TX_WB_DDONE;
1180 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
1182 /* PBF hardware reset */
1184 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_SYS_CTRL);
1186 tmp &= ~(1 << 13);
1188 rt2870_io_mac_write(sc, RT2870_REG_PBF_SYS_CTRL, tmp);
1190 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL,
1191 RT2870_REG_MAC_SRST | RT2870_REG_BBP_HRST);
1193 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_DMA_CFG, 0);
1195 rt2870_io_mcu_reset(sc);
1197 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, 0);
1199 /* init Tx power per rate */
1201 for (i = 0; i < RT2870_SOFTC_TXPOW_RATE_COUNT; i++)
1203 if (sc->txpow_rate_20mhz[i] == 0xffffffff)
1204 continue;
1206 rt2870_io_mac_write(sc, RT2870_REG_TX_PWR_CFG(i),
1207 sc->txpow_rate_20mhz[i]);
1210 for (i = 0; i < RT2870_DEF_MAC_SIZE; i++)
1211 rt2870_io_mac_write(sc, rt2870_def_mac[i].reg,
1212 rt2870_def_mac[i].val);
1214 /* wait while MAC is busy */
1216 for (ntries = 0; ntries < 100; ntries++)
1218 if (!(rt2870_io_mac_read(sc, RT2870_REG_STATUS_CFG) &
1219 (RT2870_REG_STATUS_TX_BUSY | RT2870_REG_STATUS_RX_BUSY)))
1220 break;
1222 DELAY(1000);
1225 if (ntries == 100)
1227 printf("%s: timeout waiting for MAC\n",
1228 device_get_nameunit(sc->dev));
1229 goto fail;
1232 /* clear Host to MCU mailbox */
1234 rt2870_io_mac_write(sc, RT2870_REG_H2M_MAILBOX_BBP_AGENT, 0);
1235 rt2870_io_mac_write(sc, RT2870_REG_H2M_MAILBOX, 0);
1237 DELAY(1000);
1239 error = rt2870_init_bbp(sc);
1240 if (error != 0)
1241 goto fail;
1243 /* set up maximum buffer sizes */
1245 tmp = (1 << 12) | RT2870_MAX_AGG_SIZE;
1247 rt2870_io_mac_write(sc, RT2870_REG_MAX_LEN_CFG, tmp);
1249 if (sc->mac_rev == 0x28720200)
1251 /* set max. PSDU length from 16K to 32K bytes */
1253 tmp = rt2870_io_mac_read(sc, RT2870_REG_MAX_LEN_CFG);
1255 tmp &= ~(3 << 12);
1256 tmp |= (2 << 12);
1258 rt2870_io_mac_write(sc, RT2870_REG_MAX_LEN_CFG, tmp);
1261 if (sc->mac_rev >= 0x28720200 && sc->mac_rev < 0x30700200)
1263 tmp = rt2870_io_mac_read(sc, RT2870_REG_MAX_LEN_CFG);
1265 tmp &= 0xfff;
1266 tmp |= 0x2000;
1268 rt2870_io_mac_write(sc, RT2870_REG_MAX_LEN_CFG, tmp);
1271 /* set mac address */
1273 rt2870_asic_set_macaddr(sc, IF_LLADDR(ifp));
1275 /* clear statistic registers */
1277 rt2870_io_mac_read_multi(sc, RT2870_REG_RX_STA_CNT0,
1278 stacnt, sizeof(stacnt));
1280 /* send LEDs operating mode to microcontroller */
1282 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_LED1,
1283 RT2870_REG_H2M_TOKEN_NO_INTR, sc->led_off[0]);
1284 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_LED2,
1285 RT2870_REG_H2M_TOKEN_NO_INTR, sc->led_off[1]);
1286 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_LED3,
1287 RT2870_REG_H2M_TOKEN_NO_INTR, sc->led_off[2]);
1289 /* write vendor-specific BBP values (from EEPROM) */
1291 for (i = 0; i < RT2870_SOFTC_BBP_EEPROM_COUNT; i++)
1293 if (sc->bbp_eeprom[i].reg == 0x00 ||
1294 sc->bbp_eeprom[i].reg == 0xff)
1295 continue;
1297 rt2870_io_bbp_write(sc, sc->bbp_eeprom[i].reg,
1298 sc->bbp_eeprom[i].val);
1301 /* disable non-existing Rx chains */
1303 tmp = rt2870_io_bbp_read(sc, 3);
1305 tmp &= ~((1 << 4) | (1 << 3));
1307 if (sc->nrxpath == 3)
1308 tmp |= (1 << 4);
1309 else if (sc->nrxpath == 2)
1310 tmp |= (1 << 3);
1312 rt2870_io_bbp_write(sc, 3, tmp);
1314 /* disable non-existing Tx chains */
1316 tmp = rt2870_io_bbp_read(sc, 1);
1318 tmp &= ~((1 << 4) | (1 << 3));
1320 if (sc->ntxpath == 2)
1321 tmp |= (1 << 4);
1323 rt2870_io_bbp_write(sc, 1, tmp);
1325 /* set current channel */
1327 rt2870_rf_set_chan(sc, ic->ic_curchan);
1329 /* turn radio LED on */
1331 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_ON);
1333 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_BOOT,
1334 RT2870_REG_H2M_TOKEN_NO_INTR, 0);
1336 /* set RTS threshold */
1338 rt2870_asic_update_rtsthreshold(sc);
1340 /* set Tx power */
1342 rt2870_asic_update_txpower(sc);
1344 /* set up protection mode */
1346 rt2870_asic_updateprot(sc);
1348 /* clear key tables */
1350 rt2870_asic_clear_keytables(sc);
1352 if (rt2870_txrx_enable(sc) != 0)
1353 goto fail;
1355 /* clear garbage interrupts */
1357 tmp = rt2870_io_mac_read(sc, 0x1300);
1359 taskqueue_unblock(sc->taskqueue);
1361 /* init Tx and Rx rings */
1363 for(i = 0; i < sc->usb_endpoints - 1; i++)
1364 rt2870_reset_tx_ring(sc, &sc->tx_ring[i]);
1366 rt2870_reset_rx_ring(sc, &sc->rx_ring);
1368 rt2870_reset_cmd_ring(sc, &sc->cmd_ring);
1370 for(i = 0; i < sc->usb_endpoints - 1; i++)
1372 usbd_xfer_set_priv(sc->usb_xfer[i + 1], &sc->tx_ring[i]);
1373 usbd_xfer_set_stall(sc->usb_xfer[i + 1]);
1376 /* start up the receive pipe */
1378 for(i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
1379 usbd_transfer_start(sc->usb_xfer[0]);
1381 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1382 ifp->if_drv_flags |= IFF_DRV_RUNNING;
1384 sc->periodic_round = 0;
1386 callout_reset(&sc->periodic_ch, hz / 10, rt2870_periodic, sc);
1388 return;
1390 fail:
1392 rt2870_stop_locked(sc);
1396 * rt2870_init
1398 static void rt2870_init(void *priv)
1400 struct rt2870_softc *sc;
1402 sc = priv;
1404 RT2870_SOFTC_LOCK(sc);
1406 rt2870_init_locked(sc);
1408 RT2870_SOFTC_UNLOCK(sc);
1412 * rt2870_init_bbp
1414 static int rt2870_init_bbp(struct rt2870_softc *sc)
1416 int ntries, i;
1417 uint8_t tmp;
1419 for (ntries = 0; ntries < 20; ntries++)
1421 tmp = rt2870_io_bbp_read(sc, 0);
1422 if (tmp != 0x00 && tmp != 0xff)
1423 break;
1426 if (tmp == 0x00 || tmp == 0xff)
1428 printf("%s: timeout waiting for BBP to wakeup\n",
1429 device_get_nameunit(sc->dev));
1430 return ETIMEDOUT;
1433 for (i = 0; i < RT2870_DEF_BBP_SIZE; i++)
1434 rt2870_io_bbp_write(sc, rt2870_def_bbp[i].reg,
1435 rt2870_def_bbp[i].val);
1437 if ((sc->mac_rev & 0xffff) != 0x0101)
1438 rt2870_io_bbp_write(sc, 84, 0x19);
1440 if (sc->mac_rev == 0x28600100)
1442 rt2870_io_bbp_write(sc, 69, 0x16);
1443 rt2870_io_bbp_write(sc, 73, 0x12);
1446 return 0;
1450 * rt2870_stop_locked
1452 static void rt2870_stop_locked(void *priv)
1454 struct rt2870_softc *sc;
1455 struct ifnet *ifp;
1456 struct ieee80211com *ic;
1457 uint32_t tmp;
1458 int i;
1460 sc = priv;
1461 ifp = sc->ifp;
1462 ic = ifp->if_l2com;
1464 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1465 "%s: stopping\n",
1466 device_get_nameunit(sc->dev));
1468 RT2870_SOFTC_ASSERT_LOCKED(sc);
1470 sc->tx_timer = 0;
1472 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1473 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_OFF);
1475 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1477 callout_stop(&sc->periodic_ch);
1478 callout_stop(&sc->tx_watchdog_ch);
1480 RT2870_SOFTC_UNLOCK(sc);
1482 taskqueue_block(sc->taskqueue);
1484 taskqueue_drain(sc->taskqueue, &sc->rx_done_task);
1485 taskqueue_drain(sc->taskqueue, &sc->tx_done_task);
1486 taskqueue_drain(sc->taskqueue, &sc->periodic_task);
1487 taskqueue_drain(sc->taskqueue, &sc->cmd_task);
1489 RT2870_SOFTC_LOCK(sc);
1491 /* clear key tables */
1493 rt2870_asic_clear_keytables(sc);
1495 /* disable Tx/Rx */
1497 tmp = rt2870_io_mac_read(sc, RT2870_REG_SYS_CTRL);
1499 tmp &= ~(RT2870_REG_RX_ENABLE | RT2870_REG_TX_ENABLE);
1501 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, tmp);
1503 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_DMA_CFG, 0);
1505 /* reset adapter */
1507 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL,
1508 RT2870_REG_MAC_SRST | RT2870_REG_BBP_HRST);
1509 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, 0);
1511 /* abort any pending transfers */
1513 for (i = 0; i < sc->usb_endpoints; i++)
1514 usbd_transfer_stop(sc->usb_xfer[i]);
1518 * rt2870_stop
1520 static void rt2870_stop(void *priv)
1522 struct rt2870_softc *sc;
1524 sc = priv;
1526 RT2870_SOFTC_LOCK(sc);
1528 rt2870_stop_locked(sc);
1530 RT2870_SOFTC_UNLOCK(sc);
1534 * rt2870_start
1536 static void rt2870_start(struct ifnet *ifp)
1538 struct rt2870_softc *sc;
1539 struct ieee80211_node *ni;
1540 struct mbuf *m;
1541 int qid;
1543 sc = ifp->if_softc;
1545 RT2870_SOFTC_LOCK(sc);
1547 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1549 RT2870_SOFTC_UNLOCK(sc);
1550 return;
1553 for (;;)
1555 IF_POLL(&ifp->if_snd, m);
1556 if (m == NULL)
1557 break;
1559 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1561 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1563 qid = M_WME_GETAC(m);
1565 if (sc->tx_ring[qid].queued >= RT2870_SOFTC_TX_RING_DATA_COUNT)
1567 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
1568 "%s: if_start: Tx ring with qid=%d is full\n",
1569 device_get_nameunit(sc->dev), qid);
1571 m_freem(m);
1572 ieee80211_free_node(ni);
1573 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1574 ifp->if_oerrors++;
1575 break;
1578 if (rt2870_tx_data(sc, m, ni, qid) != 0)
1580 ieee80211_free_node(ni);
1581 ifp->if_oerrors++;
1582 break;
1585 sc->tx_timer = RT2870_TX_WATCHDOG_TIMEOUT;
1587 callout_reset(&sc->tx_watchdog_ch, hz, rt2870_tx_watchdog, sc);
1590 RT2870_SOFTC_UNLOCK(sc);
1594 * rt2870_ioctl
1596 static int rt2870_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1598 struct rt2870_softc *sc;
1599 struct ieee80211com *ic;
1600 struct ifreq *ifr;
1601 int error, startall;
1603 sc = ifp->if_softc;
1604 ic = ifp->if_l2com;
1605 ifr = (struct ifreq *) data;
1607 error = 0;
1609 switch (cmd)
1611 case SIOCSIFFLAGS:
1612 startall = 0;
1614 RT2870_SOFTC_LOCK(sc);
1616 if (ifp->if_flags & IFF_UP)
1618 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1620 if ((ifp->if_flags ^ sc->if_flags) & IFF_PROMISC)
1621 rt2870_asic_update_promisc(sc);
1623 else
1625 rt2870_init_locked(sc);
1626 startall = 1;
1629 else
1631 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1632 rt2870_stop_locked(sc);
1635 sc->if_flags = ifp->if_flags;
1637 RT2870_SOFTC_UNLOCK(sc);
1639 if (startall)
1640 ieee80211_start_all(ic);
1641 break;
1643 case SIOCGIFMEDIA:
1644 case SIOCSIFMEDIA:
1645 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1646 break;
1648 case SIOCGIFADDR:
1649 error = ether_ioctl(ifp, cmd, data);
1650 break;
1652 default:
1653 error = EINVAL;
1654 break;
1657 return error;
1661 * rt2870_vap_create
1663 static struct ieee80211vap *rt2870_vap_create(struct ieee80211com *ic,
1664 const char name[IFNAMSIZ], int unit, int opmode, int flags,
1665 const uint8_t bssid[IEEE80211_ADDR_LEN],
1666 const uint8_t mac[IEEE80211_ADDR_LEN])
1668 struct rt2870_softc *sc;
1669 struct ifnet *ifp;
1670 struct rt2870_softc_vap *rvap;
1671 struct ieee80211vap *vap;
1673 ifp = ic->ic_ifp;
1674 sc = ifp->if_softc;
1676 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
1677 "%s: VAP create: opmode=%s\n",
1678 device_get_nameunit(sc->dev),
1679 ieee80211_opmode_name[opmode]);
1681 switch (opmode)
1683 case IEEE80211_M_MONITOR:
1684 case IEEE80211_M_IBSS:
1685 case IEEE80211_M_STA:
1686 case IEEE80211_M_AHDEMO:
1687 case IEEE80211_M_HOSTAP:
1688 case IEEE80211_M_MBSS:
1689 if (!TAILQ_EMPTY(&ic->ic_vaps))
1691 if_printf(ifp, "only 1 VAP supported\n");
1692 return NULL;
1695 if (opmode == IEEE80211_M_STA)
1696 flags |= IEEE80211_CLONE_NOBEACONS;
1697 break;
1699 case IEEE80211_M_WDS:
1700 if (TAILQ_EMPTY(&ic->ic_vaps) || ic->ic_opmode != IEEE80211_M_HOSTAP)
1702 if_printf(ifp, "WDS only supported in AP mode\n");
1703 return NULL;
1706 flags &= ~IEEE80211_CLONE_BSSID;
1707 break;
1709 default:
1710 if_printf(ifp, "unknown opmode %d\n", opmode);
1711 return NULL;
1714 rvap = (struct rt2870_softc_vap *) malloc(sizeof(struct rt2870_softc_vap),
1715 M_80211_VAP, M_NOWAIT | M_ZERO);
1716 if (rvap == NULL)
1717 return NULL;
1719 vap = &rvap->vap;
1721 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
1723 rvap->newstate = vap->iv_newstate;
1724 vap->iv_newstate = rt2870_vap_newstate;
1726 vap->iv_reset = rt2870_vap_reset;
1727 vap->iv_key_update_begin = rt2870_vap_key_update_begin;
1728 vap->iv_key_update_end = rt2870_vap_key_update_end;
1729 vap->iv_key_set = rt2870_vap_key_set;
1730 vap->iv_key_delete = rt2870_vap_key_delete;
1731 vap->iv_update_beacon = rt2870_vap_update_beacon;
1733 rt2870_amrr_init(&rvap->amrr, vap,
1734 RT2870_AMRR_MIN_SUCCESS_THRESHOLD,
1735 RT2870_AMRR_MAX_SUCCESS_THRESHOLD,
1736 500);
1738 ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
1740 ic->ic_opmode = opmode;
1742 return vap;
1746 * rt2870_vap_delete
1748 static void rt2870_vap_delete(struct ieee80211vap *vap)
1750 struct rt2870_softc *sc;
1751 struct ieee80211com *ic;
1752 struct ifnet *ifp;
1753 struct rt2870_softc_vap *rvap;
1755 ic = vap->iv_ic;
1756 ifp = ic->ic_ifp;
1757 sc = ifp->if_softc;
1758 rvap = (struct rt2870_softc_vap *) vap;
1760 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
1761 "%s: VAP delete: opmode=%s\n",
1762 device_get_nameunit(sc->dev),
1763 ieee80211_opmode_name[vap->iv_opmode]);
1765 rt2870_amrr_cleanup(&rvap->amrr);
1767 ieee80211_vap_detach(vap);
1769 free(rvap, M_80211_VAP);
1773 * rt2870_reset_vap
1775 static int rt2870_vap_reset(struct ieee80211vap *vap, u_long cmd)
1777 struct rt2870_softc *sc;
1778 struct ieee80211com *ic;
1779 struct ifnet *ifp;
1780 struct rt2870_softc_vap *rvap;
1781 int error;
1783 ic = vap->iv_ic;
1784 ifp = ic->ic_ifp;
1785 sc = ifp->if_softc;
1786 rvap = (struct rt2870_softc_vap *) vap;
1788 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
1789 "%s: VAP reset: cmd=%lu\n",
1790 device_get_nameunit(sc->dev), cmd);
1792 error = 0;
1794 RT2870_SOFTC_LOCK(sc);
1796 switch (cmd)
1798 case IEEE80211_IOC_RTSTHRESHOLD:
1799 rt2870_asic_update_rtsthreshold(sc);
1800 break;
1802 case IEEE80211_IOC_PROTMODE:
1803 case IEEE80211_IOC_HTPROTMODE:
1804 rt2870_asic_updateprot(sc);
1805 break;
1807 case IEEE80211_IOC_TXPOWER:
1808 rt2870_asic_update_txpower(sc);
1809 break;
1811 case IEEE80211_IOC_SHORTGI:
1812 case IEEE80211_IOC_AMPDU_DENSITY:
1813 break;
1815 default:
1816 error = ENETRESET;
1817 break;
1820 RT2870_SOFTC_UNLOCK(sc);
1822 return error;
1826 * rt2870_vap_newstate
1828 static int rt2870_vap_newstate(struct ieee80211vap *vap,
1829 enum ieee80211_state nstate, int arg)
1831 struct rt2870_softc *sc;
1832 struct ieee80211com *ic;
1833 struct ifnet *ifp;
1834 struct rt2870_softc_vap *rvap;
1835 struct ieee80211_node *ni;
1836 int error;
1838 ic = vap->iv_ic;
1839 ifp = ic->ic_ifp;
1840 sc = ifp->if_softc;
1841 rvap = (struct rt2870_softc_vap *) vap;
1843 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
1844 "%s: VAP newstate: %s -> %s\n",
1845 device_get_nameunit(sc->dev),
1846 ieee80211_state_name[vap->iv_state], ieee80211_state_name[nstate]);
1848 error = rvap->newstate(vap, nstate, arg);
1849 if (error != 0)
1850 return error;
1852 IEEE80211_UNLOCK(ic);
1854 RT2870_SOFTC_LOCK(sc);
1856 /* turn link LED off */
1858 if (nstate != IEEE80211_S_RUN)
1859 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_OFF);
1861 switch (nstate)
1863 case IEEE80211_S_INIT:
1864 rt2870_asic_disable_tsf_sync(sc);
1865 break;
1867 case IEEE80211_S_RUN:
1868 ni = vap->iv_bss;
1870 rt2870_rf_set_chan(sc, ni->ni_chan);
1872 if (vap->iv_opmode != IEEE80211_M_MONITOR)
1874 rt2870_asic_enable_mrr(sc);
1875 rt2870_asic_set_txpreamble(sc);
1876 rt2870_asic_set_basicrates(sc);
1877 rt2870_asic_update_txpower(sc);
1878 rt2870_asic_set_bssid(sc, ni->ni_bssid);
1881 if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
1882 vap->iv_opmode == IEEE80211_M_IBSS ||
1883 vap->iv_opmode == IEEE80211_M_MBSS)
1885 error = rt2870_asic_update_beacon(sc, vap);
1886 if (error != 0)
1887 break;
1890 if (vap->iv_opmode != IEEE80211_M_MONITOR)
1891 rt2870_asic_enable_tsf_sync(sc);
1893 /* turn link LED on */
1895 if (ic->ic_opmode != IEEE80211_M_MONITOR)
1897 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_ON |
1898 (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) ?
1899 RT2870_LED_CMD_LINK_2GHZ : RT2870_LED_CMD_LINK_5GHZ));
1901 break;
1903 default:
1904 break;
1907 RT2870_SOFTC_UNLOCK(sc);
1909 IEEE80211_LOCK(ic);
1911 return error;
1915 * rt2870_vap_key_update_begin
1917 static void rt2870_vap_key_update_begin(struct ieee80211vap *vap)
1919 struct rt2870_softc *sc;
1920 struct ieee80211com *ic;
1921 struct ifnet *ifp;
1923 ic = vap->iv_ic;
1924 ifp = ic->ic_ifp;
1925 sc = ifp->if_softc;
1927 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
1928 "%s: VAP key update begin\n",
1929 device_get_nameunit(sc->dev));
1931 taskqueue_block(sc->taskqueue);
1933 IF_LOCK(&ifp->if_snd);
1937 * rt2870_vap_key_update_end
1939 static void rt2870_vap_key_update_end(struct ieee80211vap *vap)
1941 struct rt2870_softc *sc;
1942 struct ieee80211com *ic;
1943 struct ifnet *ifp;
1945 ic = vap->iv_ic;
1946 ifp = ic->ic_ifp;
1947 sc = ifp->if_softc;
1949 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
1950 "%s: VAP key update end\n",
1951 device_get_nameunit(sc->dev));
1953 IF_UNLOCK(&ifp->if_snd);
1955 taskqueue_unblock(sc->taskqueue);
1959 * rt2870_vap_key_set
1961 static int rt2870_vap_key_set(struct ieee80211vap *vap,
1962 const struct ieee80211_key *k, const uint8_t mac[IEEE80211_ADDR_LEN])
1964 struct rt2870_softc *sc;
1965 struct ieee80211com *ic;
1966 struct ifnet *ifp;
1967 struct ieee80211_node *ni;
1968 uint16_t associd, key_base, keymode_base;
1969 uint8_t mode, vapid, wcid, iv[8];
1970 uint32_t tmp;
1972 if (k->wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP &&
1973 k->wk_cipher->ic_cipher != IEEE80211_CIPHER_TKIP &&
1974 k->wk_cipher->ic_cipher != IEEE80211_CIPHER_AES_CCM)
1975 return EINVAL;
1977 ic = vap->iv_ic;
1978 ifp = ic->ic_ifp;
1979 sc = ifp->if_softc;
1981 if (vap->iv_opmode != IEEE80211_M_HOSTAP)
1982 ni = vap->iv_bss;
1983 else
1984 ni = ieee80211_find_vap_node(&ic->ic_sta, vap, mac);
1986 associd = (ni != NULL) ? ni->ni_associd : 0;
1988 if ((vap->iv_opmode == IEEE80211_M_HOSTAP) && (ni != NULL))
1989 ieee80211_free_node(ni);
1991 switch (k->wk_cipher->ic_cipher)
1993 case IEEE80211_CIPHER_WEP:
1994 if(k->wk_keylen < 8)
1995 mode = RT2870_REG_CIPHER_MODE_WEP40;
1996 else
1997 mode = RT2870_REG_CIPHER_MODE_WEP104;
1998 break;
2000 case IEEE80211_CIPHER_TKIP:
2001 mode = RT2870_REG_CIPHER_MODE_TKIP;
2002 break;
2004 case IEEE80211_CIPHER_AES_CCM:
2005 mode = RT2870_REG_CIPHER_MODE_AES_CCMP;
2006 break;
2008 default:
2009 return EINVAL;
2012 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
2013 "%s: VAP key set: keyix=%d, keylen=%d, associd=0x%04x, mode=%d, group=%d\n",
2014 device_get_nameunit(sc->dev), k->wk_keyix, k->wk_keylen, associd, mode,
2015 (k->wk_flags & IEEE80211_KEY_GROUP) ? 1 : 0);
2017 RT2870_SOFTC_LOCK(sc);
2019 if (!(k->wk_flags & IEEE80211_KEY_GROUP))
2021 /* install pairwise key */
2023 vapid = 0;
2024 wcid = RT2870_AID2WCID(associd);
2025 key_base = RT2870_REG_PKEY(wcid);
2027 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP)
2029 memset(iv, 0, 8);
2031 iv[3] = (k->wk_keyix << 6);
2033 else
2035 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
2037 iv[0] = (k->wk_keytsc >> 8);
2038 iv[1] = ((iv[0] | 0x20) & 0x7f);
2039 iv[2] = k->wk_keytsc;
2041 else
2043 /* AES CCMP */
2045 iv[0] = k->wk_keytsc;
2046 iv[1] = k->wk_keytsc >> 8;
2047 iv[2] = 0;
2050 iv[3] = ((k->wk_keyix << 6) | IEEE80211_WEP_EXTIV);
2051 iv[4] = (k->wk_keytsc >> 16);
2052 iv[5] = (k->wk_keytsc >> 24);
2053 iv[6] = (k->wk_keytsc >> 32);
2054 iv[7] = (k->wk_keytsc >> 40);
2056 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
2057 "%s: set key: iv=%02x %02x %02x %02x %02x %02x %02x %02x\n",
2058 device_get_nameunit(sc->dev),
2059 iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]);
2062 rt2870_io_mac_write_multi(sc, RT2870_REG_IVEIV(wcid), iv, 8);
2064 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
2066 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, 16);
2068 if (vap->iv_opmode != IEEE80211_M_HOSTAP)
2070 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[16], 8);
2071 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[24], 8);
2073 else
2075 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[24], 8);
2076 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[16], 8);
2079 else
2081 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, k->wk_keylen);
2084 tmp = ((vapid & RT2870_REG_VAP_MASK) << RT2870_REG_VAP_SHIFT) |
2085 (mode << RT2870_REG_CIPHER_MODE_SHIFT) | RT2870_REG_PKEY_ENABLE;
2087 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
2090 if ((k->wk_flags & IEEE80211_KEY_GROUP) ||
2091 (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP))
2093 /* install group key */
2095 vapid = 0;
2096 key_base = RT2870_REG_SKEY(vapid, k->wk_keyix);
2097 keymode_base = RT2870_REG_SKEY_MODE(vapid);
2099 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
2101 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, 16);
2103 if (vap->iv_opmode != IEEE80211_M_HOSTAP)
2105 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[16], 8);
2106 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[24], 8);
2108 else
2110 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[24], 8);
2111 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[16], 8);
2114 else
2116 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, k->wk_keylen);
2119 tmp = rt2870_io_mac_read(sc, keymode_base);
2121 tmp &= ~(0xf << (k->wk_keyix * 4 + 16 * (vapid % 2)));
2122 tmp |= (mode << (k->wk_keyix * 4 + 16 * (vapid % 2)));
2124 rt2870_io_mac_write(sc, keymode_base, tmp);
2127 RT2870_SOFTC_UNLOCK(sc);
2129 return 1;
2133 * rt2870_vap_key_delete
2135 static int rt2870_vap_key_delete(struct ieee80211vap *vap,
2136 const struct ieee80211_key *k)
2138 struct rt2870_softc *sc;
2139 struct ieee80211com *ic;
2140 struct ifnet *ifp;
2141 struct ieee80211_node *ni;
2142 struct rt2870_cmd_argv_keydelete cmd_argv;
2143 uint16_t associd;
2145 ic = vap->iv_ic;
2146 ifp = ic->ic_ifp;
2147 sc = ifp->if_softc;
2148 ni = vap->iv_bss;
2149 associd = (ni != NULL) ? ni->ni_associd : 0;
2151 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
2152 "%s: VAP key delete: keyix=%d, keylen=%d, associd=0x%04x, group=%d\n",
2153 device_get_nameunit(sc->dev), k->wk_keyix, k->wk_keylen, associd,
2154 (k->wk_flags & IEEE80211_KEY_GROUP) ? 1 : 0);
2156 memcpy(&cmd_argv.key, k, sizeof(struct ieee80211_key));
2157 cmd_argv.associd = associd;
2159 rt2870_do_async(sc, rt2870_vap_key_delete_cb,
2160 &cmd_argv, sizeof(struct rt2870_cmd_argv_keydelete));
2162 return 1;
2166 * rt2870_vap_update_beacon
2168 static void rt2870_vap_update_beacon(struct ieee80211vap *vap, int what)
2170 struct rt2870_softc *sc;
2171 struct ieee80211com *ic;
2172 struct ifnet *ifp;
2174 ic = vap->iv_ic;
2175 ifp = ic->ic_ifp;
2176 sc = ifp->if_softc;
2178 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
2179 "%s: VAP update beacon\n",
2180 device_get_nameunit(sc->dev));
2182 rt2870_do_async(sc, rt2870_vap_update_beacon_cb, NULL, 0);
2186 * rt2870_node_alloc
2188 static struct ieee80211_node *rt2870_node_alloc(struct ieee80211vap *vap,
2189 const uint8_t mac[IEEE80211_ADDR_LEN])
2191 return malloc(sizeof(struct rt2870_softc_node),
2192 M_80211_NODE, M_NOWAIT | M_ZERO);
2196 * rt2870_setregdomain
2198 static int rt2870_setregdomain(struct ieee80211com *ic,
2199 struct ieee80211_regdomain *reg,
2200 int nchans, struct ieee80211_channel chans[])
2202 struct rt2870_softc *sc;
2203 struct ifnet *ifp;
2205 ifp = ic->ic_ifp;
2206 sc = ifp->if_softc;
2208 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
2209 "%s: set regulatory domain: country=%d, country code string=%c%c, location=%c\n",
2210 device_get_nameunit(sc->dev),
2211 reg->country, reg->isocc[0], reg->isocc[1], reg->location);
2213 return 0;
2217 * rt2870_getradiocaps
2219 static void rt2870_getradiocaps(struct ieee80211com *ic,
2220 int maxchans, int *nchans, struct ieee80211_channel chans[])
2222 *nchans = (ic->ic_nchans >= maxchans) ? maxchans : ic->ic_nchans;
2224 memcpy(chans, ic->ic_channels, (*nchans) * sizeof(struct ieee80211_channel));
2228 * rt2870_scan_start
2230 static void rt2870_scan_start(struct ieee80211com *ic)
2232 struct rt2870_softc *sc;
2233 struct ifnet *ifp;
2235 ifp = ic->ic_ifp;
2236 sc = ifp->if_softc;
2238 RT2870_SOFTC_LOCK(sc);
2240 rt2870_asic_disable_tsf_sync(sc);
2242 RT2870_SOFTC_UNLOCK(sc);
2246 * rt2870_scan_end
2248 static void rt2870_scan_end(struct ieee80211com *ic)
2250 struct rt2870_softc *sc;
2251 struct ifnet *ifp;
2253 ifp = ic->ic_ifp;
2254 sc = ifp->if_softc;
2256 RT2870_SOFTC_LOCK(sc);
2258 rt2870_asic_enable_tsf_sync(sc);
2260 RT2870_SOFTC_UNLOCK(sc);
2264 * rt2870_set_channel
2266 static void rt2870_set_channel(struct ieee80211com *ic)
2268 struct rt2870_softc *sc;
2269 struct ifnet *ifp;
2271 ifp = ic->ic_ifp;
2272 sc = ifp->if_softc;
2274 RT2870_DPRINTF(sc, RT2870_DEBUG_CHAN,
2275 "%s: set channel: channel=%u, HT%s%s\n",
2276 device_get_nameunit(sc->dev),
2277 ieee80211_chan2ieee(ic, ic->ic_curchan),
2278 !IEEE80211_IS_CHAN_HT(ic->ic_curchan) ? " disabled" :
2279 IEEE80211_IS_CHAN_HT20(ic->ic_curchan) ? "20":
2280 IEEE80211_IS_CHAN_HT40U(ic->ic_curchan) ? "40U" : "40D",
2281 (ic->ic_flags & IEEE80211_F_SCAN) ? ", scanning" : "");
2283 RT2870_SOFTC_LOCK(sc);
2285 rt2870_rf_set_chan(sc, ic->ic_curchan);
2287 RT2870_SOFTC_UNLOCK(sc);
2291 * rt2870_newassoc
2293 static void rt2870_newassoc(struct ieee80211_node *ni, int isnew)
2295 struct rt2870_softc *sc;
2296 struct ieee80211com *ic;
2297 struct ifnet *ifp;
2298 struct ieee80211vap *vap;
2299 struct rt2870_softc_vap *rvap;
2300 uint16_t associd;
2301 uint8_t wcid;
2303 vap = ni->ni_vap;
2304 ic = vap->iv_ic;
2305 ifp = ic->ic_ifp;
2306 sc = ifp->if_softc;
2307 rvap = (struct rt2870_softc_vap *) vap;
2309 associd = (ni != NULL) ? ni->ni_associd : 0;
2310 wcid = RT2870_AID2WCID(associd);
2312 RT2870_DPRINTF(sc, RT2870_DEBUG_NODE,
2313 "%s: new association: wcid=0x%02x, "
2314 "mac addr=%s, QoS %s, ERP %s, HT %s\n",
2315 device_get_nameunit(sc->dev), wcid,
2316 ether_sprintf(ni->ni_macaddr),
2317 (ni->ni_flags & IEEE80211_NODE_QOS) ? "enabled" : "disabled",
2318 (ni->ni_flags & IEEE80211_NODE_ERP) ? "enabled" : "disabled",
2319 (ni->ni_flags & IEEE80211_NODE_HT) ? "enabled" : "disabled");
2321 RT2870_SOFTC_LOCK(sc);
2323 rt2870_io_mac_write_multi(sc, RT2870_REG_WCID(wcid),
2324 ni->ni_macaddr, IEEE80211_ADDR_LEN);
2326 rt2870_amrr_node_init(&rvap->amrr, &sc->amrr_node[wcid], ni);
2328 RT2870_DPRINTF(sc, RT2870_DEBUG_RATE,
2329 "%s: initial%s node Tx rate: associd=0x%04x, rate=0x%02x, max rate=0x%02x\n",
2330 device_get_nameunit(sc->dev),
2331 (ni->ni_flags & IEEE80211_NODE_HT) ? " HT" : "",
2332 ni->ni_associd, ni->ni_txrate,
2333 (ni->ni_flags & IEEE80211_NODE_HT) ?
2334 (ni->ni_htrates.rs_rates[ni->ni_htrates.rs_nrates - 1] | IEEE80211_RATE_MCS) :
2335 (ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates - 1] & IEEE80211_RATE_VAL));
2337 rt2870_asic_updateprot(sc);
2338 rt2870_asic_updateslot(sc);
2339 rt2870_asic_set_txpreamble(sc);
2341 RT2870_SOFTC_UNLOCK(sc);
2345 * rt2870_updateslot
2347 static void rt2870_updateslot(struct ifnet *ifp)
2349 struct rt2870_softc *sc;
2351 sc = ifp->if_softc;
2353 rt2870_do_async(sc, rt2870_updateslot_cb, NULL, 0);
2357 * rt2870_update_promisc
2359 static void rt2870_update_promisc(struct ifnet *ifp)
2361 struct rt2870_softc *sc;
2363 sc = ifp->if_softc;
2365 RT2870_SOFTC_LOCK(sc);
2367 rt2870_asic_update_promisc(sc);
2369 RT2870_SOFTC_UNLOCK(sc);
2373 * rt2870_update_mcast
2375 static void rt2870_update_mcast(struct ifnet *ifp)
2377 struct rt2870_softc *sc;
2379 sc = ifp->if_softc;
2383 * rt2870_wme_update
2385 static int rt2870_wme_update(struct ieee80211com *ic)
2387 struct rt2870_softc *sc;
2388 struct ifnet *ifp;
2390 ifp = ic->ic_ifp;
2391 sc = ifp->if_softc;
2393 rt2870_do_async(sc, rt2870_wme_update_cb, NULL, 0);
2395 return 0;
2399 * rt2870_raw_xmit
2401 static int rt2870_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2402 const struct ieee80211_bpf_params *params)
2404 struct rt2870_softc *sc;
2405 struct ieee80211com *ic;
2406 struct ifnet *ifp;
2408 ic = ni->ni_ic;
2409 ifp = ic->ic_ifp;
2410 sc = ifp->if_softc;
2412 RT2870_SOFTC_LOCK(sc);
2414 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
2416 RT2870_SOFTC_UNLOCK(sc);
2417 m_freem(m);
2418 ieee80211_free_node(ni);
2419 return ENETDOWN;
2422 if (sc->tx_ring[sc->tx_ring_mgtqid].queued >= RT2870_SOFTC_TX_RING_DATA_COUNT)
2424 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
2425 "%s: raw xmit: Tx ring with qid=%d is full\n",
2426 device_get_nameunit(sc->dev), sc->tx_ring_mgtqid);
2428 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
2429 RT2870_SOFTC_UNLOCK(sc);
2430 m_freem(m);
2431 ieee80211_free_node(ni);
2432 return ENOBUFS;
2435 if (rt2870_tx_mgmt(sc, m, ni, sc->tx_ring_mgtqid) != 0)
2437 ifp->if_oerrors++;
2438 RT2870_SOFTC_UNLOCK(sc);
2439 ieee80211_free_node(ni);
2440 return EIO;
2443 sc->tx_timer = RT2870_TX_WATCHDOG_TIMEOUT;
2445 RT2870_SOFTC_UNLOCK(sc);
2447 return 0;
2451 * rt2870_recv_action
2453 static int rt2870_recv_action(struct ieee80211_node *ni,
2454 const struct ieee80211_frame *wh,
2455 const uint8_t *frm, const uint8_t *efrm)
2457 struct rt2870_softc *sc;
2458 struct ieee80211com *ic;
2459 struct ifnet *ifp;
2460 const struct ieee80211_action *ia;
2461 uint16_t associd, baparamset;
2462 uint8_t wcid;
2463 int ret, tid, bufsize;
2464 uint32_t tmp;
2466 ic = ni->ni_ic;
2467 ifp = ic->ic_ifp;
2468 sc = ifp->if_softc;
2470 ia = (const struct ieee80211_action *) frm;
2472 ret = sc->recv_action(ni, wh, frm, efrm);
2474 if (ia->ia_category != IEEE80211_ACTION_CAT_BA)
2475 return ret;
2477 associd = (ni != NULL) ? ni->ni_associd : 0;
2478 wcid = RT2870_AID2WCID(associd);
2480 switch (ia->ia_action)
2482 /* IEEE80211_ACTION_BA_ADDBA_REQUEST */
2483 case IEEE80211_ACTION_BA_ADDBA_REQUEST:
2484 baparamset = LE_READ_2(frm + 3);
2485 tid = RT2870_MS(baparamset, IEEE80211_BAPS_TID);
2486 bufsize = RT2870_MS(baparamset, IEEE80211_BAPS_BUFSIZ);
2488 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2489 "%s: adding A-MPDU Rx block ACK: associd=0x%04x, tid=%d, bufsize=%d\n",
2490 device_get_nameunit(sc->dev), associd, tid, bufsize);
2492 RT2870_SOFTC_LOCK(sc);
2494 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID(wcid) + 4);
2496 tmp |= (0x10000 << tid);
2498 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
2500 RT2870_SOFTC_UNLOCK(sc);
2501 break;
2503 /* IEEE80211_ACTION_BA_DELBA */
2504 case IEEE80211_ACTION_BA_DELBA:
2505 baparamset = LE_READ_2(frm + 2);
2506 tid = RT2870_MS(baparamset, IEEE80211_BAPS_TID);
2508 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2509 "%s: deleting A-MPDU Rx block ACK: associd=0x%04x, tid=%d\n",
2510 device_get_nameunit(sc->dev), associd, tid);
2512 RT2870_SOFTC_LOCK(sc);
2514 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID(wcid) + 4);
2516 tmp &= ~(0x10000 << tid);
2518 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
2520 RT2870_SOFTC_UNLOCK(sc);
2521 break;
2524 return ret;
2528 * rt2870_send_action
2530 static int rt2870_send_action(struct ieee80211_node *ni,
2531 int cat, int act, void *sa)
2533 struct rt2870_softc *sc;
2534 struct ieee80211com *ic;
2535 struct ifnet *ifp;
2536 uint16_t associd, *args, baparamset;
2537 uint8_t wcid;
2538 int ret, tid;
2539 uint32_t tmp;
2541 ic = ni->ni_ic;
2542 ifp = ic->ic_ifp;
2543 sc = ifp->if_softc;
2545 ret = sc->send_action(ni, cat, act, sa);
2547 if (cat != IEEE80211_ACTION_CAT_BA)
2548 return ret;
2550 associd = (ni != NULL) ? ni->ni_associd : 0;
2551 wcid = RT2870_AID2WCID(associd);
2552 args = sa;
2554 switch (act)
2556 /* IEEE80211_ACTION_BA_DELBA */
2557 case IEEE80211_ACTION_BA_DELBA:
2558 baparamset = RT2870_SM(args[0], IEEE80211_DELBAPS_TID) | args[1];
2560 if (RT2870_MS(baparamset, IEEE80211_DELBAPS_INIT) == IEEE80211_DELBAPS_INIT)
2561 break;
2563 tid = RT2870_MS(baparamset, IEEE80211_DELBAPS_TID);
2565 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2566 "%s: deleting A-MPDU Rx block ACK: associd=0x%04x, tid=%d\n",
2567 device_get_nameunit(sc->dev), associd, tid);
2569 RT2870_SOFTC_LOCK(sc);
2571 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID(wcid) + 4);
2573 tmp &= ~(0x10000 << tid);
2575 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
2577 RT2870_SOFTC_UNLOCK(sc);
2578 break;
2581 return ret;
2585 * rt2870_amrr_update_iter_func
2587 static void rt2870_amrr_update_iter_func(void *arg, struct ieee80211_node *ni)
2589 struct rt2870_softc *sc;
2590 struct ieee80211com *ic;
2591 struct ifnet *ifp;
2592 struct ieee80211vap *vap;
2593 struct rt2870_softc_vap *rvap;
2594 uint8_t wcid;
2596 vap = arg;
2597 ic = vap->iv_ic;
2598 ifp = ic->ic_ifp;
2599 sc = ifp->if_softc;
2600 rvap = (struct rt2870_softc_vap *) vap;
2602 /* only associated stations */
2604 if ((ni->ni_vap == vap) && (ni->ni_associd != 0))
2606 wcid = RT2870_AID2WCID(ni->ni_associd);
2608 rt2870_amrr_choose(ni, &sc->amrr_node[wcid]);
2610 RT2870_DPRINTF(sc, RT2870_DEBUG_RATE,
2611 "%s:%s node Tx rate: associd=0x%04x, rate=0x%02x, max rate=0x%02x\n",
2612 device_get_nameunit(sc->dev),
2613 (ni->ni_flags & IEEE80211_NODE_HT) ? " HT" : "",
2614 ni->ni_associd, ni->ni_txrate,
2615 (ni->ni_flags & IEEE80211_NODE_HT) ?
2616 (ni->ni_htrates.rs_rates[ni->ni_htrates.rs_nrates - 1] | IEEE80211_RATE_MCS) :
2617 (ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates - 1] & IEEE80211_RATE_VAL));
2622 * rt2870_periodic
2624 static void rt2870_periodic(void *arg)
2626 struct rt2870_softc *sc;
2627 struct ifnet *ifp;
2629 sc = arg;
2630 ifp = sc->ifp;
2632 RT2870_DPRINTF(sc, RT2870_DEBUG_PERIODIC,
2633 "%s: periodic\n",
2634 device_get_nameunit(sc->dev));
2636 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
2637 return;
2639 taskqueue_enqueue(sc->taskqueue, &sc->periodic_task);
2643 * rt2870_tx_watchdog
2645 static void rt2870_tx_watchdog(void *arg)
2647 struct rt2870_softc *sc;
2648 struct ifnet *ifp;
2650 sc = arg;
2651 ifp = sc->ifp;
2653 if (sc->tx_timer == 0)
2654 return;
2656 if (--sc->tx_timer == 0)
2658 printf("%s: Tx watchdog timeout: resetting\n",
2659 device_get_nameunit(sc->dev));
2661 rt2870_stop_locked(sc);
2662 rt2870_init_locked(sc);
2664 ifp->if_oerrors++;
2666 sc->tx_watchdog_timeouts++;
2669 callout_reset(&sc->tx_watchdog_ch, hz, rt2870_tx_watchdog, sc);
2673 * rt2870_do_async
2675 static int rt2870_do_async(struct rt2870_softc *sc,
2676 void (*cb)(struct rt2870_softc *sc, void *arg),
2677 void *arg, int len)
2679 struct ifnet *ifp;
2680 struct rt2870_softc_cmd_ring *ring;
2681 struct rt2870_softc_cmd *cmd;
2682 int run_cmd_task;
2684 ifp = sc->ifp;
2685 ring = &sc->cmd_ring;
2687 RT2870_SOFTC_LOCK(sc);
2689 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
2691 RT2870_SOFTC_UNLOCK(sc);
2692 return -1;
2695 if (ring->queued >= RT2870_SOFTC_CMD_RING_CMD_COUNT)
2697 RT2870_SOFTC_UNLOCK(sc);
2698 return -1;
2701 cmd = STAILQ_FIRST(&ring->inactive);
2702 STAILQ_REMOVE_HEAD(&ring->inactive, next);
2704 cmd->cb = cb;
2706 if(arg != NULL)
2707 memcpy(cmd->data, arg, len);
2709 STAILQ_INSERT_TAIL(&ring->active, cmd, next);
2710 ring->queued++;
2712 run_cmd_task = (ring->queued == 1);
2714 RT2870_SOFTC_UNLOCK(sc);
2716 if (run_cmd_task)
2717 taskqueue_enqueue(sc->taskqueue, &sc->cmd_task);
2719 return 0;
2723 * rt2870_updateslot_cb
2725 static void rt2870_updateslot_cb(struct rt2870_softc *sc, void *arg)
2727 RT2870_SOFTC_LOCK(sc);
2729 rt2870_asic_updateslot(sc);
2731 RT2870_SOFTC_UNLOCK(sc);
2735 * rt2870_wme_update_cb
2737 static void rt2870_wme_update_cb(struct rt2870_softc *sc, void *arg)
2739 RT2870_SOFTC_LOCK(sc);
2741 rt2870_asic_wme_update(sc);
2743 RT2870_SOFTC_UNLOCK(sc);
2747 * rt2870_vap_key_delete_cb
2749 static void rt2870_vap_key_delete_cb(struct rt2870_softc *sc, void *arg)
2751 struct ieee80211_key *k;
2752 struct rt2870_cmd_argv_keydelete *cmd_argv;
2753 uint16_t associd;
2754 uint8_t vapid, wcid;
2755 uint32_t tmp;
2757 cmd_argv = arg;
2758 k = &cmd_argv->key;
2759 associd = cmd_argv->associd;
2761 RT2870_SOFTC_LOCK(sc);
2763 if (!(k->wk_flags & IEEE80211_KEY_GROUP))
2765 /* remove pairwise key */
2767 wcid = RT2870_AID2WCID(associd);
2769 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID_ATTR(wcid));
2771 tmp &= ~0xf;
2772 tmp |= (RT2870_REG_CIPHER_MODE_NONE << RT2870_REG_CIPHER_MODE_SHIFT);
2774 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
2776 else
2778 /* remove group key */
2780 vapid = 0;
2782 tmp = rt2870_io_mac_read(sc, RT2870_REG_SKEY_MODE(vapid));
2784 tmp &= ~(0xf << (k->wk_keyix * 4 + 16 * (vapid % 2)));
2785 tmp |= (RT2870_REG_CIPHER_MODE_NONE << (k->wk_keyix * 4 + 16 * (vapid % 2)));
2787 rt2870_io_mac_write(sc, RT2870_REG_SKEY_MODE(vapid), tmp);
2790 RT2870_SOFTC_UNLOCK(sc);
2794 * rt2870_vap_update_beacon_cb
2796 static void rt2870_vap_update_beacon_cb(struct rt2870_softc *sc, void *arg)
2798 struct ifnet *ifp;
2799 struct ieee80211com *ic;
2800 struct ieee80211vap *vap;
2802 ifp = sc->ifp;
2803 ic = ifp->if_l2com;
2804 vap = TAILQ_FIRST(&ic->ic_vaps);
2806 if (vap == NULL)
2807 return;
2809 RT2870_SOFTC_LOCK(sc);
2811 rt2870_asic_update_beacon(sc, vap);
2813 RT2870_SOFTC_UNLOCK(sc);
2817 * rt2870_asic_set_bssid
2819 static void rt2870_asic_set_bssid(struct rt2870_softc *sc,
2820 const uint8_t *bssid)
2822 uint32_t tmp;
2824 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
2825 "%s: set bssid: bssid=%s\n",
2826 device_get_nameunit(sc->dev),
2827 ether_sprintf(bssid));
2829 tmp = bssid[0] | (bssid[1]) << 8 | (bssid[2] << 16) | (bssid[3] << 24);
2831 rt2870_io_mac_write(sc, RT2870_REG_BSSID_DW0, tmp);
2833 tmp = bssid[4] | (bssid[5] << 8);
2835 rt2870_io_mac_write(sc, RT2870_REG_BSSID_DW1, tmp);
2839 * rt2870_asic_set_macaddr
2841 static void rt2870_asic_set_macaddr(struct rt2870_softc *sc,
2842 const uint8_t *addr)
2844 uint32_t tmp;
2846 tmp = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
2848 rt2870_io_mac_write(sc, RT2870_REG_ADDR_DW0, tmp);
2850 tmp = addr[4] | (addr[5] << 8);
2852 rt2870_io_mac_write(sc, RT2870_REG_ADDR_DW1, tmp);
2856 * rt2870_asic_enable_tsf_sync
2858 static void rt2870_asic_enable_tsf_sync(struct rt2870_softc *sc)
2860 struct ifnet *ifp;
2861 struct ieee80211com *ic;
2862 struct ieee80211vap *vap;
2863 uint32_t tmp;
2865 ifp = sc->ifp;
2866 ic = ifp->if_l2com;
2867 vap = TAILQ_FIRST(&ic->ic_vaps);
2869 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
2870 "%s: enabling TSF\n",
2871 device_get_nameunit(sc->dev));
2873 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
2875 tmp &= ~0x1fffff;
2876 tmp |= vap->iv_bss->ni_intval * 16;
2877 tmp |= (RT2870_REG_TSF_TIMER_ENABLE | RT2870_REG_TBTT_TIMER_ENABLE);
2879 if (vap->iv_opmode == IEEE80211_M_STA)
2881 tmp |= (RT2870_REG_TSF_SYNC_MODE_STA << RT2870_REG_TSF_SYNC_MODE_SHIFT);
2883 else if (vap->iv_opmode == IEEE80211_M_IBSS)
2885 tmp |= RT2870_REG_BCN_TX_ENABLE;
2886 tmp |= (RT2870_REG_TSF_SYNC_MODE_IBSS << RT2870_REG_TSF_SYNC_MODE_SHIFT);
2888 else if (vap->iv_opmode == IEEE80211_M_HOSTAP)
2890 tmp |= RT2870_REG_BCN_TX_ENABLE;
2891 tmp |= (RT2870_REG_TSF_SYNC_MODE_HOSTAP << RT2870_REG_TSF_SYNC_MODE_SHIFT);
2894 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
2898 * rt2870_asic_disable_tsf_sync
2900 static void rt2870_asic_disable_tsf_sync(struct rt2870_softc *sc)
2902 uint32_t tmp;
2904 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
2905 "%s: disabling TSF\n",
2906 device_get_nameunit(sc->dev));
2908 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
2910 tmp &= ~(RT2870_REG_BCN_TX_ENABLE |
2911 RT2870_REG_TSF_TIMER_ENABLE |
2912 RT2870_REG_TBTT_TIMER_ENABLE);
2914 tmp &= ~(RT2870_REG_TSF_SYNC_MODE_MASK << RT2870_REG_TSF_SYNC_MODE_SHIFT);
2915 tmp |= (RT2870_REG_TSF_SYNC_MODE_DISABLE << RT2870_REG_TSF_SYNC_MODE_SHIFT);
2917 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
2921 * rt2870_asic_enable_mrr
2923 static void rt2870_asic_enable_mrr(struct rt2870_softc *sc)
2925 #define CCK(mcs) (mcs)
2926 #define OFDM(mcs) ((1 << 3) | (mcs))
2927 #define HT(mcs) (mcs)
2929 rt2870_io_mac_write(sc, RT2870_REG_TX_LG_FBK_CFG0,
2930 (OFDM(6) << 28) | /* 54 -> 48 */
2931 (OFDM(5) << 24) | /* 48 -> 36 */
2932 (OFDM(4) << 20) | /* 36 -> 24 */
2933 (OFDM(3) << 16) | /* 24 -> 18 */
2934 (OFDM(2) << 12) | /* 18 -> 12 */
2935 (OFDM(1) << 8) | /* 12 -> 9 */
2936 (OFDM(0) << 4) | /* 9 -> 6 */
2937 OFDM(0)); /* 6 -> 6 */
2939 rt2870_io_mac_write(sc, RT2870_REG_TX_LG_FBK_CFG1,
2940 (CCK(2) << 12) | /* 11 -> 5.5 */
2941 (CCK(1) << 8) | /* 5.5 -> 2 */
2942 (CCK(0) << 4) | /* 2 -> 1 */
2943 CCK(0)); /* 1 -> 1 */
2945 rt2870_io_mac_write(sc, RT2870_REG_TX_HT_FBK_CFG0,
2946 (HT(6) << 28) |
2947 (HT(5) << 24) |
2948 (HT(4) << 20) |
2949 (HT(3) << 16) |
2950 (HT(2) << 12) |
2951 (HT(1) << 8) |
2952 (HT(0) << 4) |
2953 HT(0));
2955 rt2870_io_mac_write(sc, RT2870_REG_TX_HT_FBK_CFG1,
2956 (HT(14) << 28) |
2957 (HT(13) << 24) |
2958 (HT(12) << 20) |
2959 (HT(11) << 16) |
2960 (HT(10) << 12) |
2961 (HT(9) << 8) |
2962 (HT(8) << 4) |
2963 HT(8));
2965 #undef HT
2966 #undef OFDM
2967 #undef CCK
2971 * rt2870_asic_set_txpreamble
2973 static void rt2870_asic_set_txpreamble(struct rt2870_softc *sc)
2975 struct ifnet *ifp;
2976 struct ieee80211com *ic;
2977 uint32_t tmp;
2979 ifp = sc->ifp;
2980 ic = ifp->if_l2com;
2982 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
2983 "%s: %s short Tx preamble\n",
2984 device_get_nameunit(sc->dev),
2985 (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? "enabling" : "disabling");
2987 tmp = rt2870_io_mac_read(sc, RT2870_REG_AUTO_RSP_CFG);
2989 tmp &= ~RT2870_REG_CCK_SHORT_ENABLE;
2991 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
2992 tmp |= RT2870_REG_CCK_SHORT_ENABLE;
2994 rt2870_io_mac_write(sc, RT2870_REG_AUTO_RSP_CFG, tmp);
2998 * rt2870_asic_set_basicrates
3000 static void rt2870_asic_set_basicrates(struct rt2870_softc *sc)
3002 struct ifnet *ifp;
3003 struct ieee80211com *ic;
3005 ifp = sc->ifp;
3006 ic = ifp->if_l2com;
3008 if (ic->ic_curmode == IEEE80211_MODE_11B)
3009 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0x3);
3010 else if (ic->ic_curmode == IEEE80211_MODE_11A)
3011 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0x150);
3012 else
3013 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0x15f);
3017 * rt2870_asic_update_rtsthreshold
3019 static void rt2870_asic_update_rtsthreshold(struct rt2870_softc *sc)
3021 struct ifnet *ifp;
3022 struct ieee80211com *ic;
3023 struct ieee80211vap *vap;
3024 uint32_t tmp;
3025 uint16_t threshold;
3027 ifp = sc->ifp;
3028 ic = ifp->if_l2com;
3029 vap = TAILQ_FIRST(&ic->ic_vaps);
3031 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3032 "%s: updating RTS threshold: %d\n",
3033 device_get_nameunit(sc->dev), vap->iv_rtsthreshold);
3035 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_RTS_CFG);
3037 tmp &= ~(RT2870_REG_TX_RTS_THRESHOLD_MASK << RT2870_REG_TX_RTS_THRESHOLD_SHIFT);
3039 threshold = (vap->iv_rtsthreshold < IEEE80211_RTS_MAX) ?
3040 vap->iv_rtsthreshold : 0x1000;
3042 tmp |= ((threshold & RT2870_REG_TX_RTS_THRESHOLD_MASK) <<
3043 RT2870_REG_TX_RTS_THRESHOLD_SHIFT);
3045 rt2870_io_mac_write(sc, RT2870_REG_TX_RTS_CFG, tmp);
3049 * rt2870_asic_update_txpower
3051 static void rt2870_asic_update_txpower(struct rt2870_softc *sc)
3053 struct ifnet *ifp;
3054 struct ieee80211com *ic;
3055 uint32_t *txpow_rate;
3056 int8_t delta;
3057 uint8_t val;
3058 uint32_t tmp;
3059 int i;
3061 ifp = sc->ifp;
3062 ic = ifp->if_l2com;
3064 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3065 "%s: updating Tx power: %d\n",
3066 device_get_nameunit(sc->dev), ic->ic_txpowlimit);
3068 if (!IEEE80211_IS_CHAN_HT40(ic->ic_curchan))
3070 txpow_rate = sc->txpow_rate_20mhz;
3072 else
3074 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
3075 txpow_rate = sc->txpow_rate_40mhz_2ghz;
3076 else
3077 txpow_rate = sc->txpow_rate_40mhz_5ghz;
3080 delta = 0;
3082 val = rt2870_io_bbp_read(sc, 1);
3083 val &= 0xfc;
3085 if (ic->ic_txpowlimit > 90)
3087 /* do nothing */
3089 else if (ic->ic_txpowlimit > 60)
3091 delta -= 1;
3093 else if (ic->ic_txpowlimit > 30)
3095 delta -= 3;
3097 else if (ic->ic_txpowlimit > 15)
3099 val |= 0x1;
3101 else if (ic->ic_txpowlimit > 9)
3103 val |= 0x1;
3104 delta -= 3;
3106 else
3108 val |= 0x2;
3111 rt2870_io_bbp_write(sc, 1, val);
3113 for (i = 0; i < RT2870_SOFTC_TXPOW_RATE_COUNT; i++)
3115 if (txpow_rate[i] == 0xffffffff)
3116 continue;
3118 tmp = rt2870_read_eeprom_txpow_rate_add_delta(txpow_rate[i], delta);
3120 rt2870_io_mac_write(sc, RT2870_REG_TX_PWR_CFG(i), tmp);
3125 * rt2870_asic_update_promisc
3127 static void rt2870_asic_update_promisc(struct rt2870_softc *sc)
3129 struct ifnet *ifp;
3130 uint32_t tmp;
3132 ifp = sc->ifp;
3134 printf("%s: %s promiscuous mode\n",
3135 device_get_nameunit(sc->dev),
3136 (ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving");
3138 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_FILTER_CFG);
3140 tmp &= ~RT2870_REG_RX_FILTER_DROP_UC_NOME;
3142 if (!(ifp->if_flags & IFF_PROMISC))
3143 tmp |= RT2870_REG_RX_FILTER_DROP_UC_NOME;
3145 rt2870_io_mac_write(sc, RT2870_REG_RX_FILTER_CFG, tmp);
3149 * rt2870_asic_updateprot
3151 static void rt2870_asic_updateprot(struct rt2870_softc *sc)
3153 struct ifnet *ifp;
3154 struct ieee80211com *ic;
3155 struct ieee80211vap *vap;
3156 uint32_t cck_prot, ofdm_prot, mm20_prot, mm40_prot, gf20_prot, gf40_prot;
3157 uint8_t htopmode;
3159 ifp = sc->ifp;
3160 ic = ifp->if_l2com;
3161 vap = TAILQ_FIRST(&ic->ic_vaps);
3163 /* CCK frame protection */
3165 cck_prot = RT2870_REG_RTSTH_ENABLE | RT2870_REG_PROT_NAV_SHORT |
3166 RT2870_REG_TXOP_ALLOW_ALL | RT2870_REG_PROT_CTRL_NONE;
3168 /* set up protection frame phy mode and rate (MCS code) */
3170 if (ic->ic_curmode == IEEE80211_MODE_11A)
3171 cck_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3172 (0 << RT2870_REG_PROT_MCS_SHIFT);
3173 else
3174 cck_prot |= ((RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3175 (3 << RT2870_REG_PROT_MCS_SHIFT));
3177 rt2870_io_mac_write(sc, RT2870_REG_TX_CCK_PROT_CFG, cck_prot);
3179 /* OFDM frame protection */
3181 ofdm_prot = RT2870_REG_RTSTH_ENABLE | RT2870_REG_PROT_NAV_SHORT |
3182 RT2870_REG_TXOP_ALLOW_ALL;
3184 if (ic->ic_flags & IEEE80211_F_USEPROT)
3186 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3187 "%s: updating protection mode: b/g protection mode=%s\n",
3188 device_get_nameunit(sc->dev),
3189 (ic->ic_protmode == IEEE80211_PROT_RTSCTS) ? "RTS/CTS" :
3190 ((ic->ic_protmode == IEEE80211_PROT_CTSONLY) ? "CTS-to-self" : "none"));
3192 if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
3193 ofdm_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3194 else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
3195 ofdm_prot |= RT2870_REG_PROT_CTRL_CTS;
3196 else
3197 ofdm_prot |= RT2870_REG_PROT_CTRL_NONE;
3199 else
3201 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3202 "%s: updating protection mode: b/g protection mode=%s\n",
3203 device_get_nameunit(sc->dev), "none");
3205 ofdm_prot |= RT2870_REG_PROT_CTRL_NONE;
3208 rt2870_io_mac_write(sc, RT2870_REG_TX_OFDM_PROT_CFG, ofdm_prot);
3210 /* HT frame protection */
3212 if ((vap->iv_opmode == IEEE80211_M_STA) && (vap->iv_state == IEEE80211_S_RUN))
3213 htopmode = vap->iv_bss->ni_htopmode;
3214 else
3215 htopmode = ic->ic_curhtprotmode;
3217 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3218 "%s: updating protection mode: HT operation mode=0x%02x, protection mode=%s\n",
3219 device_get_nameunit(sc->dev),
3220 htopmode & IEEE80211_HTINFO_OPMODE,
3221 (ic->ic_htprotmode == IEEE80211_PROT_RTSCTS) ? "RTS/CTS" :
3222 ((ic->ic_htprotmode == IEEE80211_PROT_CTSONLY) ? "CTS-to-self" : "none"));
3224 switch (htopmode & IEEE80211_HTINFO_OPMODE)
3226 /* IEEE80211_HTINFO_OPMODE_HT20PR */
3227 case IEEE80211_HTINFO_OPMODE_HT20PR:
3228 mm20_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3229 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3230 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20 |
3231 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3232 (4 << RT2870_REG_PROT_MCS_SHIFT);
3234 gf20_prot = mm20_prot;
3236 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3237 RT2870_REG_TXOP_ALLOW_ALL |
3238 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3239 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
3241 if (ic->ic_htprotmode == IEEE80211_PROT_RTSCTS)
3242 mm40_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3243 else if (ic->ic_htprotmode == IEEE80211_PROT_CTSONLY)
3244 mm40_prot |= RT2870_REG_PROT_CTRL_CTS;
3245 else
3246 mm40_prot |= RT2870_REG_PROT_CTRL_NONE;
3248 gf40_prot = mm40_prot;
3249 break;
3251 /* IEEE80211_HTINFO_OPMODE_MIXED */
3252 case IEEE80211_HTINFO_OPMODE_MIXED:
3253 mm20_prot = RT2870_REG_PROT_NAV_SHORT |
3254 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3255 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20;
3257 if (ic->ic_flags & IEEE80211_F_USEPROT)
3258 mm20_prot |= (RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3259 (3 << RT2870_REG_PROT_MCS_SHIFT);
3260 else
3261 mm20_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3262 (4 << RT2870_REG_PROT_MCS_SHIFT);
3264 if (ic->ic_htprotmode == IEEE80211_PROT_RTSCTS)
3265 mm20_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3266 else if (ic->ic_htprotmode == IEEE80211_PROT_CTSONLY)
3267 mm20_prot |= RT2870_REG_PROT_CTRL_CTS;
3268 else
3269 mm20_prot |= RT2870_REG_PROT_CTRL_NONE;
3271 gf20_prot = mm20_prot;
3273 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_TXOP_ALLOW_ALL;
3275 if (ic->ic_flags & IEEE80211_F_USEPROT)
3276 mm40_prot |= (RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3277 (3 << RT2870_REG_PROT_MCS_SHIFT);
3278 else
3279 mm40_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3280 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
3282 if (ic->ic_htprotmode == IEEE80211_PROT_RTSCTS)
3283 mm40_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3284 else if (ic->ic_htprotmode == IEEE80211_PROT_CTSONLY)
3285 mm40_prot |= RT2870_REG_PROT_CTRL_CTS;
3286 else
3287 mm40_prot |= RT2870_REG_PROT_CTRL_NONE;
3289 gf40_prot = mm40_prot;
3290 break;
3293 * IEEE80211_HTINFO_OPMODE_PURE
3294 * IEEE80211_HTINFO_OPMODE_PROTOPT
3296 case IEEE80211_HTINFO_OPMODE_PURE:
3297 case IEEE80211_HTINFO_OPMODE_PROTOPT:
3298 default:
3299 mm20_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3300 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3301 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20 |
3302 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3303 (4 << RT2870_REG_PROT_MCS_SHIFT);
3305 gf20_prot = mm20_prot;
3307 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3308 RT2870_REG_TXOP_ALLOW_ALL |
3309 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3310 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
3312 gf40_prot = mm40_prot;
3313 break;
3316 rt2870_io_mac_write(sc, RT2870_REG_TX_MM20_PROT_CFG, mm20_prot);
3317 rt2870_io_mac_write(sc, RT2870_REG_TX_MM40_PROT_CFG, mm40_prot);
3318 rt2870_io_mac_write(sc, RT2870_REG_TX_GF20_PROT_CFG, gf20_prot);
3319 rt2870_io_mac_write(sc, RT2870_REG_TX_GF40_PROT_CFG, gf40_prot);
3323 * rt2870_asic_updateslot
3325 static void rt2870_asic_updateslot(struct rt2870_softc *sc)
3327 struct ifnet *ifp;
3328 struct ieee80211com *ic;
3329 uint32_t tmp;
3331 ifp = sc->ifp;
3332 ic = ifp->if_l2com;
3334 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3335 "%s: %s short slot time\n",
3336 device_get_nameunit(sc->dev),
3337 (ic->ic_flags & IEEE80211_F_SHSLOT) ? "enabling" : "disabling");
3339 tmp = rt2870_io_mac_read(sc, RT2870_REG_BKOFF_SLOT_CFG);
3341 tmp &= ~0xff;
3342 tmp |= (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
3344 rt2870_io_mac_write(sc, RT2870_REG_BKOFF_SLOT_CFG, tmp);
3348 * rt2870_asic_wme_update
3350 static void rt2870_asic_wme_update(struct rt2870_softc *sc)
3352 struct ifnet *ifp;
3353 struct ieee80211com *ic;
3354 struct ieee80211_wme_state *wme;
3355 const struct wmeParams *wmep;
3356 int i;
3358 ifp = sc->ifp;
3359 ic = ifp->if_l2com;
3360 wme = &ic->ic_wme;
3361 wmep = wme->wme_chanParams.cap_wmeParams;
3363 RT2870_DPRINTF(sc, RT2870_DEBUG_WME,
3364 "%s: wme update: WME_AC_VO=%d/%d/%d/%d, WME_AC_VI=%d/%d/%d/%d, "
3365 "WME_AC_BK=%d/%d/%d/%d, WME_AC_BE=%d/%d/%d/%d\n",
3366 device_get_nameunit(sc->dev),
3367 wmep[WME_AC_VO].wmep_aifsn,
3368 wmep[WME_AC_VO].wmep_logcwmin, wmep[WME_AC_VO].wmep_logcwmax,
3369 wmep[WME_AC_VO].wmep_txopLimit,
3370 wmep[WME_AC_VI].wmep_aifsn,
3371 wmep[WME_AC_VI].wmep_logcwmin, wmep[WME_AC_VI].wmep_logcwmax,
3372 wmep[WME_AC_VI].wmep_txopLimit,
3373 wmep[WME_AC_BK].wmep_aifsn,
3374 wmep[WME_AC_BK].wmep_logcwmin, wmep[WME_AC_BK].wmep_logcwmax,
3375 wmep[WME_AC_BK].wmep_txopLimit,
3376 wmep[WME_AC_BE].wmep_aifsn,
3377 wmep[WME_AC_BE].wmep_logcwmin, wmep[WME_AC_BE].wmep_logcwmax,
3378 wmep[WME_AC_BE].wmep_txopLimit);
3380 for (i = 0; i < WME_NUM_AC; i++)
3381 rt2870_io_mac_write(sc, RT2870_REG_TX_EDCA_AC_CFG(i),
3382 (wmep[i].wmep_logcwmax << 16) | (wmep[i].wmep_logcwmin << 12) |
3383 (wmep[i].wmep_aifsn << 8) | wmep[i].wmep_txopLimit);
3385 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_AIFSN_CFG,
3386 (wmep[WME_AC_VO].wmep_aifsn << 12) | (wmep[WME_AC_VI].wmep_aifsn << 8) |
3387 (wmep[WME_AC_BK].wmep_aifsn << 4) | wmep[WME_AC_BE].wmep_aifsn);
3389 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_CWMIN_CFG,
3390 (wmep[WME_AC_VO].wmep_logcwmin << 12) | (wmep[WME_AC_VI].wmep_logcwmin << 8) |
3391 (wmep[WME_AC_BK].wmep_logcwmin << 4) | wmep[WME_AC_BE].wmep_logcwmin);
3393 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_CWMAX_CFG,
3394 (wmep[WME_AC_VO].wmep_logcwmax << 12) | (wmep[WME_AC_VI].wmep_logcwmax << 8) |
3395 (wmep[WME_AC_BK].wmep_logcwmax << 4) | wmep[WME_AC_BE].wmep_logcwmax);
3397 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP0_CFG,
3398 (wmep[WME_AC_BK].wmep_txopLimit << 16) | wmep[WME_AC_BE].wmep_txopLimit);
3400 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP1_CFG,
3401 (wmep[WME_AC_VO].wmep_txopLimit << 16) | wmep[WME_AC_VI].wmep_txopLimit);
3405 * rt2870_asic_update_beacon
3407 static int rt2870_asic_update_beacon(struct rt2870_softc *sc,
3408 struct ieee80211vap *vap)
3410 struct ifnet *ifp;
3411 struct ieee80211com *ic;
3412 struct rt2870_softc_vap *rvap;
3413 const struct ieee80211_txparam *tp;
3414 struct mbuf *m;
3415 struct rt2870_txwi txwi;
3416 uint8_t rate, mcs;
3417 uint32_t tmp;
3419 ifp = sc->ifp;
3420 ic = ifp->if_l2com;
3421 rvap = (struct rt2870_softc_vap *) vap;
3422 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
3424 m = ieee80211_beacon_alloc(vap->iv_bss, &rvap->beacon_offsets);
3425 if (m == NULL)
3426 return ENOMEM;
3428 rate = tp->mgmtrate;
3429 mcs = rt2870_rate2mcs(rate);
3431 memset(&txwi, 0, sizeof(struct rt2870_txwi));
3433 txwi.wcid = 0xff;
3434 txwi.pid_mpdu_len = ((htole16(m->m_pkthdr.len) & RT2870_TXWI_MPDU_LEN_MASK) <<
3435 RT2870_TXWI_MPDU_LEN_SHIFT);
3436 txwi.txop = (RT2870_TXWI_TXOP_HT << RT2870_TXWI_TXOP_SHIFT);
3437 txwi.mpdu_density_flags |=
3438 (RT2870_TXWI_FLAGS_TS << RT2870_TXWI_FLAGS_SHIFT);
3439 txwi.bawin_size_xflags |=
3440 (RT2870_TXWI_XFLAGS_NSEQ << RT2870_TXWI_XFLAGS_SHIFT);
3442 if (ieee80211_rate2phytype(ic->ic_rt, rate) != IEEE80211_T_OFDM)
3444 txwi.phymode_ifs_stbc_shortgi =
3445 (RT2870_TXWI_PHYMODE_CCK << RT2870_TXWI_PHYMODE_SHIFT);
3447 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
3448 mcs |= RT2870_TXWI_MCS_SHOTPRE;
3450 else
3452 txwi.phymode_ifs_stbc_shortgi =
3453 (RT2870_TXWI_PHYMODE_OFDM << RT2870_TXWI_PHYMODE_SHIFT);
3456 txwi.bw_mcs = (RT2870_TXWI_BW_20 << RT2870_TXWI_BW_SHIFT) |
3457 ((mcs & RT2870_TXWI_MCS_MASK) << RT2870_TXWI_MCS_SHIFT);
3459 /* disable temporarily TSF sync */
3461 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
3463 tmp &= ~(RT2870_REG_BCN_TX_ENABLE |
3464 RT2870_REG_TSF_TIMER_ENABLE |
3465 RT2870_REG_TBTT_TIMER_ENABLE);
3467 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
3469 /* write Tx wireless info and beacon frame to on-chip memory */
3471 rt2870_io_mac_write_multi(sc, RT2870_REG_BEACON_BASE(0),
3472 &txwi, sizeof(struct rt2870_txwi));
3474 rt2870_io_mac_write_multi(sc, RT2870_REG_BEACON_BASE(0) + sizeof(struct rt2870_txwi),
3475 mtod(m, uint8_t *), m->m_pkthdr.len);
3477 /* enable again TSF sync */
3479 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
3481 tmp |= (RT2870_REG_BCN_TX_ENABLE |
3482 RT2870_REG_TSF_TIMER_ENABLE |
3483 RT2870_REG_TBTT_TIMER_ENABLE);
3485 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
3487 m_freem(m);
3489 return 0;
3493 * rt2870_asic_clear_keytables
3495 static void rt2870_asic_clear_keytables(struct rt2870_softc *sc)
3497 int i;
3499 /* clear Rx WCID search table (entries = 256, entry size = 8) */
3501 for (i = 0; i < 256; i++)
3503 rt2870_io_mac_write(sc, RT2870_REG_WCID(i), 0xffffffff);
3504 rt2870_io_mac_write(sc, RT2870_REG_WCID(i) + 4, 0x0000ffff);
3507 /* clear WCID attribute table (entries = 256, entry size = 4) */
3509 rt2870_io_mac_set_region_4(sc, RT2870_REG_WCID_ATTR(0), 0, 256);
3511 /* clear IV/EIV table (entries = 256, entry size = 8) */
3513 rt2870_io_mac_set_region_4(sc, RT2870_REG_IVEIV(0), 0, 2 * 256);
3515 /* clear pairwise key table (entries = 256, entry size = 32) */
3517 rt2870_io_mac_set_region_4(sc, RT2870_REG_PKEY(0), 0, 8 * 256);
3519 /* clear shared key table (entries = 32, entry size = 32) */
3521 rt2870_io_mac_set_region_4(sc, RT2870_REG_SKEY(0, 0), 0, 8 * 32);
3523 /* clear shared key mode (entries = 32, entry size = 2) */
3525 rt2870_io_mac_set_region_4(sc, RT2870_REG_SKEY_MODE(0), 0, 16);
3529 * rt2870_rxrate
3531 static uint8_t rt2870_rxrate(struct rt2870_rxwi *rxwi)
3533 uint8_t mcs, phymode;
3534 uint8_t rate;
3536 mcs = (rxwi->bw_mcs >> RT2870_RXWI_MCS_SHIFT) & RT2870_RXWI_MCS_MASK;
3537 phymode = (rxwi->phymode_stbc_shortgi >> RT2870_RXWI_PHYMODE_SHIFT) &
3538 RT2870_RXWI_PHYMODE_MASK;
3540 rate = 2;
3542 switch (phymode)
3544 case RT2870_RXWI_PHYMODE_CCK:
3545 switch (mcs & ~RT2870_RXWI_MCS_SHOTPRE)
3547 case 0: rate = 2; break; /* 1 Mbps */
3548 case 1: rate = 4; break; /* 2 MBps */
3549 case 2: rate = 11; break; /* 5.5 Mbps */
3550 case 3: rate = 22; break; /* 11 Mbps */
3552 break;
3554 case RT2870_RXWI_PHYMODE_OFDM:
3555 switch (mcs)
3557 case 0: rate = 12; break; /* 6 Mbps */
3558 case 1: rate = 18; break; /* 9 Mbps */
3559 case 2: rate = 24; break; /* 12 Mbps */
3560 case 3: rate = 36; break; /* 18 Mbps */
3561 case 4: rate = 48; break; /* 24 Mbps */
3562 case 5: rate = 72; break; /* 36 Mbps */
3563 case 6: rate = 96; break; /* 48 Mbps */
3564 case 7: rate = 108; break; /* 54 Mbps */
3566 break;
3568 case RT2870_RXWI_PHYMODE_HT_MIXED:
3569 case RT2870_RXWI_PHYMODE_HT_GF:
3570 break;
3573 return rate;
3577 * rt2870_maxrssi_rxpath
3579 static uint8_t rt2870_maxrssi_rxpath(struct rt2870_softc *sc,
3580 const struct rt2870_rxwi *rxwi)
3582 uint8_t rxpath;
3584 rxpath = 0;
3586 if (sc->nrxpath > 1)
3587 if (rxwi->rssi[1] > rxwi->rssi[rxpath])
3588 rxpath = 1;
3590 if (sc->nrxpath > 2)
3591 if (rxwi->rssi[2] > rxwi->rssi[rxpath])
3592 rxpath = 2;
3594 return rxpath;
3598 * rt2870_rssi2dbm
3600 static int8_t rt2870_rssi2dbm(struct rt2870_softc *sc,
3601 uint8_t rssi, uint8_t rxpath)
3603 struct ifnet *ifp;
3604 struct ieee80211com *ic;
3605 struct ieee80211_channel *c;
3606 int chan;
3607 int8_t rssi_off, lna_gain;
3609 if (rssi == 0)
3610 return -99;
3612 ifp = sc->ifp;
3613 ic = ifp->if_l2com;
3614 c = ic->ic_curchan;
3615 chan = ieee80211_chan2ieee(ic, c);
3617 if (IEEE80211_IS_CHAN_5GHZ(c))
3619 rssi_off = sc->rssi_off_5ghz[rxpath];
3621 if (chan <= 64)
3622 lna_gain = sc->lna_gain[1];
3623 else if (chan <= 128)
3624 lna_gain = sc->lna_gain[2];
3625 else
3626 lna_gain = sc->lna_gain[3];
3628 else
3630 rssi_off = sc->rssi_off_2ghz[rxpath];
3631 lna_gain = sc->lna_gain[0];
3634 return (-12 - rssi_off - lna_gain - rssi);
3638 * rt2870_rate2mcs
3640 static uint8_t rt2870_rate2mcs(uint8_t rate)
3642 switch (rate)
3644 /* CCK rates */
3645 case 2: return 0;
3646 case 4: return 1;
3647 case 11: return 2;
3648 case 22: return 3;
3650 /* OFDM rates */
3651 case 12: return 0;
3652 case 18: return 1;
3653 case 24: return 2;
3654 case 36: return 3;
3655 case 48: return 4;
3656 case 72: return 5;
3657 case 96: return 6;
3658 case 108: return 7;
3661 return 0;
3665 * rt2870_rx_frame
3667 static void rt2870_rx_frame(struct rt2870_softc *sc,
3668 uint8_t *buf, uint32_t dmalen)
3670 struct ifnet *ifp;
3671 struct ieee80211com *ic;
3672 struct ieee80211_frame *wh;
3673 struct ieee80211_node *ni;
3674 struct rt2870_softc_rx_radiotap_header *tap;
3675 struct rt2870_rxwi *rxwi;
3676 struct rt2870_rxinfo *rxinfo;
3677 struct mbuf *m;
3678 uint32_t rxinfo_flags;
3679 uint8_t cipher_err, rssi, ant, phymode, bw, shortgi, mcs;
3680 int8_t rssi_dbm;
3681 int len, ampdu, amsdu;
3683 ifp = sc->ifp;
3684 ic = ifp->if_l2com;
3686 /* get Rx wireless info */
3688 rxwi = (struct rt2870_rxwi *) buf;
3689 len = (le16toh(rxwi->tid_size) >> RT2870_RXWI_SIZE_SHIFT) &
3690 RT2870_RXWI_SIZE_MASK;
3692 if (len > dmalen)
3694 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3695 "%s: bad rxwi len: DMA len=%d, rxwi len=%d\n",
3696 device_get_nameunit(sc->dev), dmalen, len);
3697 return;
3700 /* get Rx info */
3702 rxinfo = (struct rt2870_rxinfo *) ((caddr_t) rxwi + dmalen);
3703 rxinfo_flags = le32toh(rxinfo->flags);
3705 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3706 "%s: Rx frame: DMA len=%d, len=%d, rxinfo flags=0x%08x\n",
3707 device_get_nameunit(sc->dev), dmalen, len, rxinfo_flags);
3709 /* check for crc errors */
3711 if (rxinfo_flags & RT2870_RXINFO_FLAGS_CRC_ERR)
3713 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3714 "%s: rxinfo: crc error\n",
3715 device_get_nameunit(sc->dev));
3717 ifp->if_ierrors++;
3719 if (!(ifp->if_flags & IFF_PROMISC))
3720 return;
3723 wh = (struct ieee80211_frame *) (rxwi + 1);
3725 /* check for L2 padding between IEEE 802.11 frame header and body */
3727 if (rxinfo_flags & RT2870_RXINFO_FLAGS_L2PAD)
3729 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3730 "%s: L2 padding: DMA len=%d, len=%d\n",
3731 device_get_nameunit(sc->dev), dmalen, len);
3733 len += 2;
3736 m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
3737 if (m == NULL)
3739 sc->rx_mbuf_alloc_errors++;
3740 ifp->if_ierrors++;
3741 return;
3744 m->m_pkthdr.rcvif = ifp;
3745 m->m_pkthdr.len = m->m_len = len;
3747 m_copyback(m, 0, len, (caddr_t) wh);
3749 wh = mtod(m, struct ieee80211_frame *);
3751 /* check for cipher errors */
3753 if (rxinfo_flags & RT2870_RXINFO_FLAGS_DECRYPTED)
3755 cipher_err = ((rxinfo_flags >> RT2870_RXINFO_FLAGS_CIPHER_ERR_SHIFT) &
3756 RT2870_RXINFO_FLAGS_CIPHER_ERR_MASK);
3757 if (cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_NONE)
3759 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
3760 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
3762 m->m_flags |= M_WEP;
3764 else
3766 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3767 "%s: rxinfo: cipher error=0x%02x\n",
3768 device_get_nameunit(sc->dev), cipher_err);
3770 ifp->if_ierrors++;
3772 if (!(ifp->if_flags & IFF_PROMISC))
3774 m_free(m);
3775 return;
3779 else
3781 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
3783 ifp->if_ierrors++;
3785 if (!(ifp->if_flags & IFF_PROMISC))
3787 m_free(m);
3788 return;
3793 /* check for A-MPDU */
3795 if (rxinfo_flags & RT2870_RXINFO_FLAGS_AMPDU)
3797 m->m_flags |= M_AMPDU;
3798 ampdu = 1;
3800 else
3802 ampdu = 0;
3805 ant = rt2870_maxrssi_rxpath(sc, rxwi);
3806 rssi = rxwi->rssi[ant];
3807 rssi_dbm = rt2870_rssi2dbm(sc, rssi, ant);
3808 phymode = ((rxwi->phymode_stbc_shortgi >> RT2870_RXWI_PHYMODE_SHIFT) &
3809 RT2870_RXWI_PHYMODE_MASK);
3810 bw = ((rxwi->bw_mcs >> RT2870_RXWI_BW_SHIFT) & RT2870_RXWI_BW_MASK);
3811 shortgi = ((rxwi->phymode_stbc_shortgi >> RT2870_RXWI_SHORTGI_SHIFT) &
3812 RT2870_RXWI_SHORTGI_MASK);
3813 mcs = ((rxwi->bw_mcs >> RT2870_RXWI_MCS_SHIFT) & RT2870_RXWI_MCS_MASK);
3814 amsdu = (rxinfo_flags & RT2870_RXINFO_FLAGS_AMSDU);
3816 if (ieee80211_radiotap_active(ic))
3818 tap = &sc->rxtap;
3820 tap->flags = (rxinfo_flags & RT2870_RXINFO_FLAGS_L2PAD) ? IEEE80211_RADIOTAP_F_DATAPAD : 0;
3821 tap->dbm_antsignal = rssi_dbm;
3822 tap->dbm_antnoise = RT2870_NOISE_FLOOR;
3823 tap->antenna = ant;
3824 tap->antsignal = rssi;
3825 tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
3826 tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
3827 tap->chan_ieee = ic->ic_curchan->ic_ieee;
3828 tap->chan_maxpow = 0;
3830 if (phymode == RT2870_RXWI_PHYMODE_CCK || phymode == RT2870_RXWI_PHYMODE_OFDM)
3831 tap->rate = rt2870_rxrate(rxwi);
3832 else
3833 tap->rate = mcs | IEEE80211_RATE_MCS;
3835 if (rxwi->bw_mcs & RT2870_RXWI_MCS_SHOTPRE)
3836 tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
3838 if (shortgi)
3839 tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
3842 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3843 "%s: received frame: len=%d, phymode=%d, bw=%d, shortgi=%d, mcs=%d, "
3844 "ant=%d, rssi=%d/%d/%d, snr=%d/%d, wcid=0x%02x, ampdu=%d, amsdu=%d\n",
3845 device_get_nameunit(sc->dev),
3846 len, phymode, bw, shortgi, mcs,
3847 ant, rxwi->rssi[0], rxwi->rssi[1], rxwi->rssi[2],
3848 rxwi->snr[0], rxwi->snr[1],
3849 rxwi->wcid, ampdu, amsdu);
3851 ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *) wh);
3852 if (ni != NULL)
3854 ieee80211_input(ni, m, rssi_dbm - RT2870_NOISE_FLOOR, RT2870_NOISE_FLOOR);
3855 ieee80211_free_node(ni);
3857 else
3859 ieee80211_input_all(ic, m, rssi_dbm - RT2870_NOISE_FLOOR, RT2870_NOISE_FLOOR);
3864 * rt2870_tx_mgmt
3866 static int rt2870_tx_mgmt(struct rt2870_softc *sc,
3867 struct mbuf *m, struct ieee80211_node *ni, int qid)
3869 struct ifnet *ifp;
3870 struct ieee80211com *ic;
3871 struct ieee80211vap *vap;
3872 const struct ieee80211_txparam *tp;
3873 struct rt2870_softc_node *rni;
3874 struct rt2870_softc_tx_ring *ring;
3875 struct rt2870_softc_tx_data *data;
3876 struct rt2870_txinfo *txinfo;
3877 struct rt2870_txwi *txwi;
3878 struct ieee80211_frame *wh;
3879 struct rt2870_softc_tx_radiotap_header *tap;
3880 u_int hdrsize, hdrspace;
3881 uint8_t rate, stbc, shortgi, mcs, pid;
3882 uint16_t len, dmalen, mpdu_len, dur;
3884 KASSERT(qid >= 0 && qid < (sc->usb_endpoints - 1),
3885 ("%s: Tx MGMT: invalid qid=%d\n",
3886 device_get_nameunit(sc->dev), qid));
3888 ifp = sc->ifp;
3889 ic = ifp->if_l2com;
3890 vap = ni->ni_vap;
3891 rni = (struct rt2870_softc_node *) ni;
3892 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
3894 ring = &sc->tx_ring[qid];
3895 data = STAILQ_FIRST(&ring->inactive);
3896 STAILQ_REMOVE_HEAD(&ring->inactive, next);
3897 txinfo = (struct rt2870_txinfo *) data->buf;
3898 txwi = (struct rt2870_txwi *) (txinfo + 1);
3900 wh = mtod(m, struct ieee80211_frame *);
3902 rate = tp->mgmtrate & IEEE80211_RATE_VAL;
3904 len = sizeof(struct rt2870_txinfo) + sizeof(struct rt2870_txwi) + m->m_pkthdr.len;
3906 /* align end on a 4-bytes boundary */
3908 dmalen = (len + 3) & ~3;
3910 /* fill Tx info */
3912 memset(txinfo, 0, sizeof(struct rt2870_txinfo));
3914 txinfo->len = htole16(dmalen - sizeof(struct rt2870_txinfo));
3916 txinfo->qsel_flags = (RT2870_TXINFO_QSEL_EDCA << RT2870_TXINFO_QSEL_SHIFT);
3918 dmalen += 4;
3920 memset((caddr_t) txinfo + len, 0, dmalen - len);
3922 /* fill Tx wireless info */
3924 if (ni->ni_flags & IEEE80211_NODE_HT)
3925 mcs = rate;
3926 else
3927 mcs = rt2870_rate2mcs(rate);
3929 pid = mcs;
3931 /* calculate MPDU length without padding */
3933 hdrsize = ieee80211_hdrsize(wh);
3934 hdrspace = ieee80211_hdrspace(ic, wh);
3935 mpdu_len = m->m_pkthdr.len - hdrspace + hdrsize;
3937 memset(txwi, 0, sizeof(struct rt2870_txwi));
3939 /* management frames do not need encryption */
3941 txwi->wcid = 0xff;
3943 txwi->pid_mpdu_len = ((htole16(pid) & RT2870_TXWI_PID_MASK) <<
3944 RT2870_TXWI_PID_SHIFT) | ((htole16(mpdu_len) & RT2870_TXWI_MPDU_LEN_MASK) <<
3945 RT2870_TXWI_MPDU_LEN_SHIFT);
3947 stbc = (ni->ni_htcap & IEEE80211_HTCAP_RXSTBC) ? 1 : 0;
3949 shortgi = (vap->iv_flags_ht & (IEEE80211_FHT_SHORTGI20 | IEEE80211_FHT_SHORTGI40)) &&
3950 (ni->ni_flags & IEEE80211_NODE_HT);
3952 txwi->phymode_ifs_stbc_shortgi |=
3953 ((stbc & RT2870_TXWI_STBC_MASK) << RT2870_TXWI_STBC_SHIFT) |
3954 ((shortgi & RT2870_TXWI_SHORTGI_MASK) << RT2870_TXWI_SHORTGI_SHIFT);
3956 txwi->phymode_ifs_stbc_shortgi |=
3957 ((shortgi & RT2870_TXWI_SHORTGI_MASK) << RT2870_TXWI_SHORTGI_SHIFT);
3959 if (ni->ni_flags & IEEE80211_NODE_HT)
3961 txwi->phymode_ifs_stbc_shortgi |=
3962 (RT2870_TXWI_PHYMODE_HT_MIXED << RT2870_TXWI_PHYMODE_SHIFT);
3964 else
3966 if (ieee80211_rate2phytype(ic->ic_rt, rate) != IEEE80211_T_OFDM)
3968 txwi->phymode_ifs_stbc_shortgi |=
3969 (RT2870_TXWI_PHYMODE_CCK << RT2870_TXWI_PHYMODE_SHIFT);
3971 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
3972 mcs |= RT2870_TXWI_MCS_SHOTPRE;
3974 else
3976 txwi->phymode_ifs_stbc_shortgi |=
3977 (RT2870_TXWI_PHYMODE_OFDM << RT2870_TXWI_PHYMODE_SHIFT);
3981 txwi->bw_mcs = (RT2870_TXWI_BW_20 << RT2870_TXWI_BW_SHIFT) |
3982 ((mcs & RT2870_TXWI_MCS_MASK) << RT2870_TXWI_MCS_SHIFT);
3984 txwi->txop = (RT2870_TXWI_TXOP_BACKOFF << RT2870_TXWI_TXOP_SHIFT);
3986 /* skip ACKs for multicast frames and probe responses */
3988 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
3989 ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) !=
3990 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP)))
3992 txwi->bawin_size_xflags |=
3993 (RT2870_TXWI_XFLAGS_ACK << RT2870_TXWI_XFLAGS_SHIFT);
3995 if (ni->ni_flags & IEEE80211_NODE_HT)
3997 /* preamble + plcp + signal extension */
3999 dur = 16 + 4 + 6;
4001 else
4003 dur = ieee80211_ack_duration(ic->ic_rt, rate,
4004 ic->ic_flags & IEEE80211_F_SHPREAMBLE);
4007 *(uint16_t *) wh->i_dur = htole16(dur);
4010 /* ask MAC to insert timestamp into probe responses */
4012 if ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
4013 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
4014 txwi->mpdu_density_flags |=
4015 (RT2870_TXWI_FLAGS_TS << RT2870_TXWI_FLAGS_SHIFT);
4017 if (ieee80211_radiotap_active_vap(vap))
4019 tap = &sc->txtap;
4021 tap->flags = IEEE80211_RADIOTAP_F_DATAPAD;
4022 tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
4023 tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
4024 tap->chan_ieee = ic->ic_curchan->ic_ieee;
4025 tap->chan_maxpow = 0;
4027 if (ni->ni_flags & IEEE80211_NODE_HT)
4028 tap->rate = mcs | IEEE80211_RATE_MCS;
4029 else
4030 tap->rate = rate;
4032 if (mcs & RT2870_TXWI_MCS_SHOTPRE)
4033 tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
4035 if (shortgi)
4036 tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
4038 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4039 tap->flags |= IEEE80211_RADIOTAP_F_WEP;
4041 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4043 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
4045 ieee80211_radiotap_tx(vap, m);
4047 wh->i_fc[1] |= IEEE80211_FC1_WEP;
4049 else
4051 ieee80211_radiotap_tx(vap, m);
4055 m_copydata(m, 0, m->m_pkthdr.len, (caddr_t) (txwi + 1));
4057 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4058 "%s: sending MGMT frame: qid=%d, hdrsize=%d, hdrspace=%d, len=%d, "
4059 "stbc=%d, shortgi=%d, mcs=%d, DMA len=%d\n",
4060 device_get_nameunit(sc->dev),
4061 qid, hdrsize, hdrspace, m->m_pkthdr.len, stbc, shortgi, mcs, dmalen);
4063 data->len = dmalen;
4064 data->m = m;
4065 data->ni = ni;
4067 STAILQ_INSERT_TAIL(&ring->pending, data, next);
4068 ring->queued++;
4070 usbd_transfer_start(sc->usb_xfer[1 + qid]);
4072 return 0;
4076 * rt2870_tx_data
4078 static int rt2870_tx_data(struct rt2870_softc *sc,
4079 struct mbuf *m, struct ieee80211_node *ni, int qid)
4081 struct ifnet *ifp;
4082 struct ieee80211com *ic;
4083 struct ieee80211vap *vap;
4084 const struct ieee80211_txparam *tp;
4085 struct rt2870_softc_node *rni;
4086 struct rt2870_softc_tx_ring *ring;
4087 struct rt2870_softc_tx_data *data;
4088 struct rt2870_txinfo *txinfo;
4089 struct rt2870_txwi *txwi;
4090 struct ieee80211_frame *wh;
4091 struct rt2870_softc_tx_radiotap_header *tap;
4092 u_int hdrsize, hdrspace;
4093 uint8_t type, rate, bw, stbc, shortgi, mcs, pid, wcid;
4094 uint16_t qos, len, dmalen, mpdu_len, dur;
4095 int hasqos;
4097 KASSERT(qid >= 0 && qid < (sc->usb_endpoints - 1),
4098 ("%s: Tx data: invalid qid=%d\n",
4099 device_get_nameunit(sc->dev), qid));
4101 ifp = sc->ifp;
4102 ic = ifp->if_l2com;
4103 vap = ni->ni_vap;
4104 rni = (struct rt2870_softc_node *) ni;
4105 tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
4107 ring = &sc->tx_ring[qid];
4108 data = STAILQ_FIRST(&ring->inactive);
4109 STAILQ_REMOVE_HEAD(&ring->inactive, next);
4110 txinfo = (struct rt2870_txinfo *) data->buf;
4111 txwi = (struct rt2870_txwi *) (txinfo + 1);
4113 wh = mtod(m, struct ieee80211_frame *);
4115 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
4117 hasqos = IEEE80211_QOS_HAS_SEQ(wh);
4118 if (hasqos)
4120 if (IEEE80211_HAS_ADDR4(wh))
4121 qos = le16toh(*(const uint16_t *)
4122 (((struct ieee80211_qosframe_addr4 *) wh)->i_qos));
4123 else
4124 qos = le16toh(*(const uint16_t *)
4125 (((struct ieee80211_qosframe *) wh)->i_qos));
4127 else
4129 qos = 0;
4132 if (IEEE80211_IS_MULTICAST(wh->i_addr1))
4133 rate = tp->mcastrate;
4134 else if (m->m_flags & M_EAPOL)
4135 rate = tp->mgmtrate;
4136 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
4137 rate = tp->ucastrate;
4138 else
4139 rate = ni->ni_txrate;
4141 rate &= IEEE80211_RATE_VAL;
4143 len = sizeof(struct rt2870_txinfo) + sizeof(struct rt2870_txwi) + m->m_pkthdr.len;
4145 /* align end on a 4-bytes boundary */
4147 dmalen = (len + 3) & ~3;
4149 /* fill Tx info */
4151 memset(txinfo, 0, sizeof(struct rt2870_txinfo));
4153 txinfo->len = htole16(dmalen - sizeof(struct rt2870_txinfo));
4155 txinfo->qsel_flags = (RT2870_TXINFO_QSEL_EDCA << RT2870_TXINFO_QSEL_SHIFT);
4157 dmalen += 4;
4159 memset((caddr_t) txinfo + len, 0, dmalen - len);
4161 /* fill Tx wireless info */
4163 if (ni->ni_flags & IEEE80211_NODE_HT)
4164 mcs = rate;
4165 else
4166 mcs = rt2870_rate2mcs(rate);
4168 pid = mcs;
4170 wcid = (type == IEEE80211_FC0_TYPE_DATA) ?
4171 RT2870_AID2WCID(ni->ni_associd) : 0xff;
4173 /* calculate MPDU length without padding */
4175 hdrsize = ieee80211_hdrsize(wh);
4176 hdrspace = ieee80211_hdrspace(ic, wh);
4177 mpdu_len = m->m_pkthdr.len - hdrspace + hdrsize;
4179 memset(txwi, 0, sizeof(struct rt2870_txwi));
4181 txwi->wcid = wcid;
4183 txwi->pid_mpdu_len = ((htole16(pid) & RT2870_TXWI_PID_MASK) <<
4184 RT2870_TXWI_PID_SHIFT) | ((htole16(mpdu_len) & RT2870_TXWI_MPDU_LEN_MASK) <<
4185 RT2870_TXWI_MPDU_LEN_SHIFT);
4187 stbc = (ni->ni_htcap & IEEE80211_HTCAP_RXSTBC) ? 1 : 0;
4189 shortgi = (vap->iv_flags_ht & (IEEE80211_FHT_SHORTGI20 | IEEE80211_FHT_SHORTGI40)) &&
4190 (ni->ni_flags & IEEE80211_NODE_HT);
4192 txwi->phymode_ifs_stbc_shortgi |=
4193 ((stbc & RT2870_TXWI_STBC_MASK) << RT2870_TXWI_STBC_SHIFT) |
4194 ((shortgi & RT2870_TXWI_SHORTGI_MASK) << RT2870_TXWI_SHORTGI_SHIFT);
4196 if (ni->ni_flags & IEEE80211_NODE_HT)
4198 txwi->phymode_ifs_stbc_shortgi |=
4199 (RT2870_TXWI_PHYMODE_HT_MIXED << RT2870_TXWI_PHYMODE_SHIFT);
4201 else
4203 if (ieee80211_rate2phytype(ic->ic_rt, rate) != IEEE80211_T_OFDM)
4205 txwi->phymode_ifs_stbc_shortgi |=
4206 (RT2870_TXWI_PHYMODE_CCK << RT2870_TXWI_PHYMODE_SHIFT);
4208 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
4209 mcs |= RT2870_TXWI_MCS_SHOTPRE;
4211 else
4213 txwi->phymode_ifs_stbc_shortgi |=
4214 (RT2870_TXWI_PHYMODE_OFDM << RT2870_TXWI_PHYMODE_SHIFT);
4218 if ((ni->ni_flags & IEEE80211_NODE_HT) &&
4219 (ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40))
4220 bw = RT2870_TXWI_BW_40;
4221 else
4222 bw = RT2870_TXWI_BW_20;
4224 txwi->bw_mcs = ((bw & RT2870_TXWI_BW_MASK) << RT2870_TXWI_BW_SHIFT) |
4225 ((mcs & RT2870_TXWI_MCS_MASK) << RT2870_TXWI_MCS_SHIFT);
4227 txwi->txop = (RT2870_TXWI_TXOP_HT << RT2870_TXWI_TXOP_SHIFT);
4229 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
4230 (!hasqos || (qos & IEEE80211_QOS_ACKPOLICY) != IEEE80211_QOS_ACKPOLICY_NOACK))
4232 txwi->bawin_size_xflags |=
4233 (RT2870_TXWI_XFLAGS_ACK << RT2870_TXWI_XFLAGS_SHIFT);
4235 if (ni->ni_flags & IEEE80211_NODE_HT)
4237 /* preamble + plcp + signal extension */
4239 dur = 16 + 4 + 6;
4241 else
4243 dur = ieee80211_ack_duration(ic->ic_rt, rate,
4244 ic->ic_flags & IEEE80211_F_SHPREAMBLE);
4247 *(uint16_t *) wh->i_dur = htole16(dur);
4250 /* ask MAC to insert timestamp into probe responses */
4252 if ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
4253 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
4254 txwi->mpdu_density_flags |=
4255 (RT2870_TXWI_FLAGS_TS << RT2870_TXWI_FLAGS_SHIFT);
4257 if (ieee80211_radiotap_active_vap(vap))
4259 tap = &sc->txtap;
4261 tap->flags = IEEE80211_RADIOTAP_F_DATAPAD;
4262 tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
4263 tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
4264 tap->chan_ieee = ic->ic_curchan->ic_ieee;
4265 tap->chan_maxpow = 0;
4267 if (ni->ni_flags & IEEE80211_NODE_HT)
4268 tap->rate = mcs | IEEE80211_RATE_MCS;
4269 else
4270 tap->rate = rate;
4272 if (mcs & RT2870_TXWI_MCS_SHOTPRE)
4273 tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
4275 if (shortgi)
4276 tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
4278 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4279 tap->flags |= IEEE80211_RADIOTAP_F_WEP;
4281 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4283 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
4285 ieee80211_radiotap_tx(vap, m);
4287 wh->i_fc[1] |= IEEE80211_FC1_WEP;
4289 else
4291 ieee80211_radiotap_tx(vap, m);
4295 m_copydata(m, 0, m->m_pkthdr.len, (caddr_t) (txwi + 1));
4297 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4298 "%s: sending data: qid=%d, hdrsize=%d, hdrspace=%d, len=%d, "
4299 "bw=%d, stbc=%d, shortgi=%d, mcs=%d, wcid=0x%02x, DMA len=%d\n",
4300 device_get_nameunit(sc->dev),
4301 qid, hdrsize, hdrspace, m->m_pkthdr.len,
4302 bw, stbc, shortgi, mcs, wcid, dmalen);
4304 data->len = dmalen;
4305 data->m = m;
4306 data->ni = ni;
4308 STAILQ_INSERT_TAIL(&ring->pending, data, next);
4309 ring->queued++;
4311 usbd_transfer_start(sc->usb_xfer[1 + qid]);
4313 return 0;
4317 * rt2870_tx_raw
4319 static int rt2870_tx_raw(struct rt2870_softc *sc,
4320 struct mbuf *m, struct ieee80211_node *ni,
4321 const struct ieee80211_bpf_params *params)
4323 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4324 "%s: Tx raw\n",
4325 device_get_nameunit(sc->dev));
4327 return 0;
4331 * rt2870_rx_intr
4333 static void rt2870_rx_intr(struct usb_xfer *xfer, usb_error_t error)
4335 struct rt2870_softc *sc;
4336 struct ifnet *ifp;
4337 struct rt2870_softc_rx_ring *ring;
4338 struct rt2870_softc_rx_data *data;
4339 int len;
4341 sc = usbd_xfer_softc(xfer);
4342 ifp = sc->ifp;
4343 ring = &sc->rx_ring;
4345 RT2870_DPRINTF(sc, RT2870_DEBUG_INTR,
4346 "%s: Rx interrupt: state=%d, error=%s\n",
4347 device_get_nameunit(sc->dev),
4348 USB_GET_STATE(xfer), usbd_errstr(error));
4350 switch (USB_GET_STATE(xfer))
4352 case USB_ST_TRANSFERRED:
4353 sc->interrupts++;
4354 sc->rx_interrupts++;
4356 data = STAILQ_FIRST(&ring->active);
4357 if (data == NULL)
4358 goto setup;
4360 STAILQ_REMOVE_HEAD(&ring->active, next);
4362 usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
4364 data->len = len;
4366 STAILQ_INSERT_TAIL(&ring->done, data, next);
4368 taskqueue_enqueue(sc->taskqueue, &sc->rx_done_task);
4370 /* FALLTHROUGH */
4372 setup:
4374 case USB_ST_SETUP:
4375 data = STAILQ_FIRST(&ring->inactive);
4376 if (data == NULL)
4377 break;
4379 STAILQ_REMOVE_HEAD(&ring->inactive, next);
4381 STAILQ_INSERT_TAIL(&ring->active, data, next);
4383 usbd_xfer_set_frame_data(xfer, 0, data->buf, usbd_xfer_max_len(xfer));
4384 usbd_transfer_submit(xfer);
4385 break;
4387 default:
4388 sc->interrupts++;
4389 sc->rx_interrupts++;
4391 data = STAILQ_FIRST(&ring->active);
4392 if (data != NULL)
4394 STAILQ_REMOVE_HEAD(&ring->active, next);
4395 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
4398 if (error != USB_ERR_CANCELLED)
4400 ifp->if_ierrors++;
4402 usbd_xfer_set_stall(xfer);
4404 goto setup;
4406 break;
4411 * rt2870_tx_intr
4413 static void rt2870_tx_intr(struct usb_xfer *xfer, usb_error_t error)
4415 struct rt2870_softc *sc;
4416 struct ifnet *ifp;
4417 struct rt2870_softc_tx_ring *ring;
4418 struct rt2870_softc_tx_data *data;
4420 sc = usbd_xfer_softc(xfer);
4421 ifp = sc->ifp;
4422 ring = usbd_xfer_get_priv(xfer);
4424 usbd_xfer_status(xfer, NULL, NULL, NULL, NULL);
4426 RT2870_DPRINTF(sc, RT2870_DEBUG_INTR,
4427 "%s: Tx interrupt: state=%d, error=%s\n",
4428 device_get_nameunit(sc->dev),
4429 USB_GET_STATE(xfer), usbd_errstr(error));
4431 switch (USB_GET_STATE(xfer))
4433 case USB_ST_TRANSFERRED:
4434 sc->interrupts++;
4435 sc->tx_interrupts[ring->qid]++;
4437 data = STAILQ_FIRST(&ring->active);
4438 if (data == NULL)
4439 goto setup;
4441 STAILQ_REMOVE_HEAD(&ring->active, next);
4443 STAILQ_INSERT_TAIL(&ring->done, data, next);
4445 sc->tx_qid_pending_mask |= (1 << ring->qid);
4447 taskqueue_enqueue(sc->taskqueue, &sc->tx_done_task);
4449 /* FALLTHROUGH */
4451 setup:
4453 case USB_ST_SETUP:
4454 data = STAILQ_FIRST(&ring->pending);
4455 if (data == NULL)
4456 break;
4458 STAILQ_REMOVE_HEAD(&ring->pending, next);
4459 STAILQ_INSERT_TAIL(&ring->active, data, next);
4461 usbd_xfer_set_frame_data(xfer, 0, data->buf, data->len);
4462 usbd_transfer_submit(xfer);
4464 RT2870_SOFTC_UNLOCK(sc);
4466 rt2870_start(ifp);
4468 RT2870_SOFTC_LOCK(sc);
4469 break;
4471 default:
4472 sc->interrupts++;
4473 sc->tx_interrupts[ring->qid]++;
4475 data = STAILQ_FIRST(&ring->active);
4476 if (data != NULL)
4478 STAILQ_REMOVE_HEAD(&ring->active, next);
4480 printf("%s: could not transmit buffer: qid=%d, error=%s\n",
4481 device_get_nameunit(sc->dev), ring->qid, usbd_errstr(error));
4483 if (data->m != NULL)
4485 m_freem(data->m);
4486 data->m = NULL;
4489 if (data->ni != NULL)
4491 ieee80211_free_node(data->ni);
4492 data->ni = NULL;
4495 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
4497 ring->queued--;
4500 if (error != USB_ERR_CANCELLED)
4502 ifp->if_oerrors++;
4503 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4505 usbd_xfer_set_stall(xfer);
4507 goto setup;
4509 break;
4514 * rt2870_rx_done_task
4516 static void rt2870_rx_done_task(void *context, int pending)
4518 struct rt2870_softc *sc;
4519 struct ifnet *ifp;
4521 sc = context;
4522 ifp = sc->ifp;
4524 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4525 "%s: Rx done task\n",
4526 device_get_nameunit(sc->dev));
4528 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
4529 return;
4531 if (rt2870_rx_eof(sc, sc->rx_process_limit) != 0)
4533 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4534 "%s: Rx done task: scheduling again\n",
4535 device_get_nameunit(sc->dev));
4537 taskqueue_enqueue(sc->taskqueue, &sc->rx_done_task);
4542 * rt2870_tx_done_task
4544 static void rt2870_tx_done_task(void *context, int pending)
4546 struct rt2870_softc *sc;
4547 struct ifnet *ifp;
4548 int i;
4550 sc = context;
4551 ifp = sc->ifp;
4553 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4554 "%s: Tx done task\n",
4555 device_get_nameunit(sc->dev));
4557 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
4558 return;
4560 for (i = sc->usb_endpoints - 2; i >= 0; i--)
4562 if (sc->tx_qid_pending_mask & (1 << i))
4564 sc->tx_qid_pending_mask &= ~(1 << i);
4566 rt2870_tx_eof(sc, &sc->tx_ring[i]);
4570 if (sc->tx_qid_pending_mask != 0)
4572 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4573 "%s: Tx done task: scheduling again\n",
4574 device_get_nameunit(sc->dev));
4576 taskqueue_enqueue(sc->taskqueue, &sc->tx_done_task);
4579 sc->tx_timer = 0;
4581 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4585 * rt2870_periodic_task
4587 static void rt2870_periodic_task(void *context, int pending)
4589 struct rt2870_softc *sc;
4590 struct ifnet *ifp;
4591 struct ieee80211com *ic;
4592 struct ieee80211vap *vap;
4594 sc = context;
4595 ifp = sc->ifp;
4596 ic = ifp->if_l2com;
4598 RT2870_DPRINTF(sc, RT2870_DEBUG_PERIODIC,
4599 "%s: periodic task: round=%lu\n",
4600 device_get_nameunit(sc->dev), sc->periodic_round);
4602 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
4603 return;
4605 RT2870_SOFTC_LOCK(sc);
4607 sc->periodic_round++;
4609 rt2870_update_stats(sc);
4611 if ((sc->periodic_round % 10) == 0)
4613 rt2870_update_raw_counters(sc);
4615 rt2870_watchdog(sc);
4617 vap = TAILQ_FIRST(&ic->ic_vaps);
4618 if (vap != NULL)
4620 if (vap->iv_opmode == IEEE80211_M_STA)
4621 rt2870_amrr_update_iter_func(vap, vap->iv_bss);
4622 else
4623 ieee80211_iterate_nodes(&ic->ic_sta, rt2870_amrr_update_iter_func, vap);
4627 RT2870_SOFTC_UNLOCK(sc);
4629 callout_reset(&sc->periodic_ch, hz / 10, rt2870_periodic, sc);
4633 * rt2870_cmd_task
4635 static void rt2870_cmd_task(void *context, int pending)
4637 struct rt2870_softc *sc;
4638 struct rt2870_softc_cmd_ring *ring;
4639 struct rt2870_softc_cmd *cmd;
4641 sc = context;
4642 ring = &sc->cmd_ring;
4644 while (1)
4646 RT2870_SOFTC_LOCK(sc);
4648 cmd = STAILQ_FIRST(&ring->active);
4649 if (cmd == NULL)
4651 RT2870_SOFTC_UNLOCK(sc);
4652 break;
4655 STAILQ_REMOVE_HEAD(&ring->active, next);
4657 RT2870_SOFTC_UNLOCK(sc);
4659 cmd->cb(sc, cmd->data);
4661 RT2870_SOFTC_LOCK(sc);
4663 STAILQ_INSERT_TAIL(&ring->inactive, cmd, next);
4664 ring->queued--;
4666 RT2870_SOFTC_UNLOCK(sc);
4671 * rt2870_rx_eof
4673 static int rt2870_rx_eof(struct rt2870_softc *sc, int limit)
4675 struct ifnet *ifp;
4676 struct rt2870_softc_rx_ring *ring;
4677 struct rt2870_softc_rx_data *data;
4678 uint32_t dmalen;
4679 uint8_t *buf;
4680 int nframes, len;
4682 ifp = sc->ifp;
4683 ring = &sc->rx_ring;
4685 nframes = 0;
4687 while (limit != 0)
4689 RT2870_SOFTC_LOCK(sc);
4691 data = STAILQ_FIRST(&ring->done);
4692 if (data == NULL)
4694 RT2870_SOFTC_UNLOCK(sc);
4695 break;
4698 STAILQ_REMOVE_HEAD(&ring->done, next);
4700 RT2870_SOFTC_UNLOCK(sc);
4702 buf = data->buf;
4703 len = data->len;
4705 if (len < RT2870_RX_DESC_SIZE)
4707 ifp->if_ierrors++;
4708 goto skip;
4711 while (len > (sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)))
4713 dmalen = (le32toh(*(uint32_t *) buf) & 0xffff);
4715 if (dmalen == 0 || (dmalen & 3) != 0)
4717 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4718 "%s: bad DMA len=%u\n",
4719 device_get_nameunit(sc->dev), dmalen);
4720 goto skip;
4723 if ((dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)) > len)
4725 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4726 "%s: bad DMA len: DMA len=%u, USB len=%d\n",
4727 device_get_nameunit(sc->dev),
4728 (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)), len);
4729 goto skip;
4732 nframes++;
4734 rt2870_rx_frame(sc, buf + sizeof(uint32_t), dmalen);
4736 buf += (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo));
4737 len -= (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo));
4740 skip:
4742 RT2870_SOFTC_LOCK(sc);
4744 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
4746 usbd_transfer_start(sc->usb_xfer[0]);
4748 RT2870_SOFTC_UNLOCK(sc);
4750 limit--;
4753 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4754 "%s: Rx eof: nframes=%d\n",
4755 device_get_nameunit(sc->dev), nframes);
4757 sc->rx_packets += nframes;
4759 return (limit == 0);
4763 * rt2870_tx_eof
4765 static void rt2870_tx_eof(struct rt2870_softc *sc,
4766 struct rt2870_softc_tx_ring *ring)
4768 struct ifnet *ifp;
4769 struct rt2870_softc_tx_data *data;
4770 int nframes;
4772 ifp = sc->ifp;
4774 nframes = 0;
4776 while (1)
4778 RT2870_SOFTC_LOCK(sc);
4780 data = STAILQ_FIRST(&ring->done);
4781 if (data == NULL)
4783 RT2870_SOFTC_UNLOCK(sc);
4784 break;
4787 STAILQ_REMOVE_HEAD(&ring->done, next);
4789 RT2870_SOFTC_UNLOCK(sc);
4791 nframes++;
4793 if (data->m->m_flags & M_TXCB)
4794 ieee80211_process_callback(data->ni, data->m, 0);
4796 m_freem(data->m);
4798 ieee80211_free_node(data->ni);
4800 data->m = NULL;
4801 data->ni = NULL;
4803 RT2870_SOFTC_LOCK(sc);
4805 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
4807 ring->queued--;
4808 ifp->if_opackets++;
4810 RT2870_SOFTC_UNLOCK(sc);
4813 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4814 "%s: Tx eof: qid=%d, nframes=%d\n",
4815 device_get_nameunit(sc->dev), ring->qid, nframes);
4819 * rt2870_update_stats
4821 static void rt2870_update_stats(struct rt2870_softc *sc)
4823 struct ifnet *ifp;
4824 struct ieee80211com *ic;
4825 struct ieee80211vap *vap;
4826 struct ieee80211_node *ni;
4827 uint16_t associd;
4828 uint8_t wcid;
4829 uint32_t stacnt[3];
4830 int txcnt, retrycnt, failcnt;
4832 ifp = sc->ifp;
4833 ic = ifp->if_l2com;
4835 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
4836 "%s: update statistic\n",
4837 device_get_nameunit(sc->dev));
4839 rt2870_drain_fifo_stats(sc);
4841 if (ic->ic_opmode == IEEE80211_M_STA)
4843 vap = TAILQ_FIRST(&ic->ic_vaps);
4844 ni = vap->iv_bss;
4846 associd = (ni != NULL) ? ni->ni_associd : 0;
4847 wcid = RT2870_AID2WCID(associd);
4849 /* read and clear Tx statistic registers */
4851 rt2870_io_mac_read_multi(sc, RT2870_REG_TX_STA_CNT0,
4852 stacnt, sizeof(stacnt));
4854 txcnt = le32toh(stacnt[1]) & 0xffff;
4855 retrycnt = le32toh(stacnt[1]) >> 16;
4856 failcnt = le32toh(stacnt[0]) & 0xffff;
4858 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
4859 "%s: update statistic: associd=0x%04x, txcnt=%d, retrycnt=%d, failcnt=%d\n",
4860 device_get_nameunit(sc->dev),
4861 associd, txcnt, retrycnt, failcnt);
4863 ifp->if_oerrors += failcnt;
4865 rt2870_amrr_tx_update(&sc->amrr_node[wcid],
4866 txcnt + retrycnt + failcnt, txcnt + retrycnt, retrycnt + failcnt);
4871 * rt2870_watchdog
4873 static void rt2870_watchdog(struct rt2870_softc *sc)
4875 uint32_t tmp;
4876 int ntries;
4878 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
4880 RT2870_DPRINTF(sc, RT2870_DEBUG_WATCHDOG,
4881 "%s: watchdog: TXRXQ_PCNT=0x%08x\n",
4882 device_get_nameunit(sc->dev), tmp);
4884 if (((tmp >> RT2870_REG_TX0Q_PCNT_SHIFT) & RT2870_REG_TX0Q_PCNT_MASK) != 0)
4886 sc->tx_queue_not_empty[0]++;
4888 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40012);
4890 for (ntries = 0; ntries < 10; ntries++)
4892 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
4893 if (((tmp >> RT2870_REG_TX0Q_PCNT_SHIFT) & RT2870_REG_TX0Q_PCNT_MASK) == 0)
4894 break;
4896 DELAY(1);
4899 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40006);
4902 if (((tmp >> RT2870_REG_TX1Q_PCNT_SHIFT) & RT2870_REG_TX1Q_PCNT_MASK) != 0)
4904 sc->tx_queue_not_empty[1]++;
4906 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf4000a);
4908 for (ntries = 0; ntries < 10; ntries++)
4910 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
4911 if (((tmp >> RT2870_REG_TX1Q_PCNT_SHIFT) & RT2870_REG_TX1Q_PCNT_MASK) == 0)
4912 break;
4914 DELAY(1);
4917 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40006);
4922 * rt2870_drain_fifo_stats
4924 static void rt2870_drain_fifo_stats(struct rt2870_softc *sc)
4926 struct ifnet *ifp;
4927 uint32_t stats;
4928 uint8_t wcid, mcs, pid;
4929 int ok, retrycnt;
4931 ifp = sc->ifp;
4933 /* drain Tx status FIFO (maxsize = 16) */
4935 while ((stats = rt2870_io_mac_read(sc, RT2870_REG_TX_STA_FIFO)) &
4936 RT2870_REG_TX_STA_FIFO_VALID)
4938 wcid = (stats >> RT2870_REG_TX_STA_FIFO_WCID_SHIFT) &
4939 RT2870_REG_TX_STA_FIFO_WCID_MASK;
4941 /* if no ACK was requested, no feedback is available */
4943 if (!(stats & RT2870_REG_TX_STA_FIFO_ACK_REQ) || wcid == 0xff)
4944 continue;
4946 /* update AMRR statistic */
4948 ok = (stats & RT2870_REG_TX_STA_FIFO_TX_OK) ? 1 : 0;
4949 mcs = (stats >> RT2870_REG_TX_STA_FIFO_MCS_SHIFT) &
4950 RT2870_REG_TX_STA_FIFO_MCS_MASK;
4951 pid = (stats >> RT2870_REG_TX_STA_FIFO_PID_SHIFT) &
4952 RT2870_REG_TX_STA_FIFO_PID_MASK;
4953 retrycnt = pid - mcs;
4955 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
4956 "%s: FIFO statistic: wcid=0x%02x, ok=%d, mcs=0x%02x, pid=0x%02x, retrycnt=%d\n",
4957 device_get_nameunit(sc->dev),
4958 wcid, ok, mcs, pid, retrycnt);
4960 rt2870_amrr_tx_complete(&sc->amrr_node[wcid], ok, retrycnt);
4962 if (!ok)
4963 ifp->if_oerrors++;
4968 * rt2870_update_raw_counters
4970 static void rt2870_update_raw_counters(struct rt2870_softc *sc)
4972 uint32_t tmp;
4974 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT0);
4976 sc->rx_crc_errors += tmp & 0xffff;
4977 sc->rx_phy_errors += tmp >> 16;
4979 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT1);
4981 sc->rx_false_ccas += tmp & 0xffff;
4982 sc->rx_plcp_errors += tmp >> 16;
4984 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT2);
4986 sc->rx_dup_packets += tmp & 0xffff;
4987 sc->rx_fifo_overflows += tmp >> 16;
4991 * rt2870_txrx_enable
4993 static int rt2870_txrx_enable(struct rt2870_softc *sc)
4995 struct ieee80211com *ic;
4996 struct ifnet *ifp;
4997 uint32_t tmp;
4998 int ntries;
5000 ifp = sc->ifp;
5001 ic = ifp->if_l2com;
5003 /* enable Tx/Rx DMA engine */
5005 tmp = rt2870_io_mac_read(sc, RT2870_REG_SCHDMA_USB_CYC_CFG);
5007 tmp &= 0xffffff00;
5008 tmp |= 0x1e;
5010 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_CYC_CFG, tmp);
5012 if ((sc->mac_rev & 0xffff) != 0x0101)
5013 rt2870_io_mac_write(sc, RT2870_REG_TX_TXOP_CTRL_CFG, 0x583f);
5015 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, RT2870_REG_TX_ENABLE);
5017 for (ntries = 0; ntries < 200; ntries++)
5019 tmp = rt2870_io_mac_read(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG);
5020 if (!(tmp & (RT2870_REG_TX_DMA_BUSY | RT2870_REG_RX_DMA_BUSY)))
5021 break;
5023 DELAY(1000);
5026 if (ntries == 200)
5028 printf("%s: timeout waiting for DMA engine\n",
5029 device_get_nameunit(sc->dev));
5030 return -1;
5033 DELAY(50);
5035 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP0_CFG, 0);
5036 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP1_CFG,
5037 (48 << 16) | 96);
5039 tmp |= RT2870_REG_TX_WB_DDONE |
5040 RT2870_REG_RX_DMA_ENABLE |
5041 RT2870_REG_TX_DMA_ENABLE;
5043 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
5045 tmp = RT2870_REG_USB_DMA_TX_ENABLE |
5046 RT2870_REG_USB_DMA_RX_ENABLE |
5047 RT2870_REG_USB_DMA_RX_AGG_ENABLE |
5048 /* Rx agg limit in unit of 1024 byte */
5049 ((RT2870_USB_RX_BULK_BUFLEN / 1024 - 3) << RT2870_REG_USB_DMA_RX_AGG_LIMIT_SHIFT) |
5050 /* Rx agg timeout in unit of 33ns */
5051 0x80;
5053 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_DMA_CFG, tmp);
5055 /* set Rx filter */
5057 tmp = RT2870_REG_RX_FILTER_DROP_CRC_ERR |
5058 RT2870_REG_RX_FILTER_DROP_PHY_ERR;
5060 if (ic->ic_opmode != IEEE80211_M_MONITOR)
5062 tmp |= RT2870_REG_RX_FILTER_DROP_DUPL |
5063 RT2870_REG_RX_FILTER_DROP_CTS |
5064 RT2870_REG_RX_FILTER_DROP_BA |
5065 RT2870_REG_RX_FILTER_DROP_ACK |
5066 RT2870_REG_RX_FILTER_DROP_VER_ERR |
5067 RT2870_REG_RX_FILTER_DROP_CTRL_RSV |
5068 RT2870_REG_RX_FILTER_DROP_CFACK |
5069 RT2870_REG_RX_FILTER_DROP_CFEND;
5071 if (ic->ic_opmode == IEEE80211_M_STA)
5072 tmp |= RT2870_REG_RX_FILTER_DROP_RTS |
5073 RT2870_REG_RX_FILTER_DROP_PSPOLL;
5075 if (!(ifp->if_flags & IFF_PROMISC))
5076 tmp |= RT2870_REG_RX_FILTER_DROP_UC_NOME;
5079 rt2870_io_mac_write(sc, RT2870_REG_RX_FILTER_CFG, tmp);
5081 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL,
5082 RT2870_REG_RX_ENABLE | RT2870_REG_TX_ENABLE);
5084 return 0;
5088 * rt2870_alloc_rx_ring
5090 static int rt2870_alloc_rx_ring(struct rt2870_softc *sc,
5091 struct rt2870_softc_rx_ring *ring)
5093 struct rt2870_softc_rx_data *data;
5094 int i, error;
5096 STAILQ_INIT(&ring->inactive);
5097 STAILQ_INIT(&ring->active);
5098 STAILQ_INIT(&ring->done);
5100 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
5102 data = &ring->data[i];
5104 data->buf = malloc(RT2870_USB_RX_BULK_BUFLEN, M_USBDEV, M_NOWAIT);
5105 if (data->buf == NULL)
5107 printf("%s: could not allocate Rx buffer\n",
5108 device_get_nameunit(sc->dev));
5109 error = ENOMEM;
5110 goto fail;
5113 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5116 return 0;
5118 fail:
5120 rt2870_free_rx_ring(sc, ring);
5122 return error;
5126 * rt2870_reset_rx_ring
5128 static void rt2870_reset_rx_ring(struct rt2870_softc *sc,
5129 struct rt2870_softc_rx_ring *ring)
5131 struct rt2870_softc_rx_data *data;
5132 int i;
5134 STAILQ_INIT(&ring->inactive);
5135 STAILQ_INIT(&ring->active);
5136 STAILQ_INIT(&ring->done);
5138 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
5140 data = &ring->data[i];
5142 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5147 * rt2870_free_rx_ring
5149 static void rt2870_free_rx_ring(struct rt2870_softc *sc,
5150 struct rt2870_softc_rx_ring *ring)
5152 struct rt2870_softc_rx_data *data;
5153 int i;
5155 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
5157 data = &ring->data[i];
5159 if (data->buf != NULL)
5161 free(data->buf, M_USBDEV);
5162 data->buf = NULL;
5168 * rt2870_alloc_tx_ring
5170 static int rt2870_alloc_tx_ring(struct rt2870_softc *sc,
5171 struct rt2870_softc_tx_ring *ring, int qid)
5173 struct rt2870_softc_tx_data *data;
5174 int i, error;
5176 STAILQ_INIT(&ring->inactive);
5177 STAILQ_INIT(&ring->pending);
5178 STAILQ_INIT(&ring->active);
5179 STAILQ_INIT(&ring->done);
5181 ring->queued = 0;
5182 ring->qid = qid;
5184 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
5186 data = &ring->data[i];
5188 data->buf = malloc(RT2870_TX_DESC_SIZE + MJUMPAGESIZE, M_USBDEV, M_NOWAIT);
5189 if (data->buf == NULL)
5191 printf("%s: could not allocate Tx buffer\n",
5192 device_get_nameunit(sc->dev));
5193 error = ENOMEM;
5194 goto fail;
5197 memset(data->buf, 0, RT2870_TX_DESC_SIZE);
5199 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5202 return 0;
5204 fail:
5206 rt2870_free_tx_ring(sc, ring);
5208 return error;
5212 * rt2870_reset_tx_ring
5214 static void rt2870_reset_tx_ring(struct rt2870_softc *sc,
5215 struct rt2870_softc_tx_ring *ring)
5217 struct rt2870_softc_tx_data *data;
5218 int i;
5220 STAILQ_INIT(&ring->inactive);
5221 STAILQ_INIT(&ring->pending);
5222 STAILQ_INIT(&ring->active);
5223 STAILQ_INIT(&ring->done);
5225 ring->queued = 0;
5227 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
5229 data = &ring->data[i];
5231 if (data->m != NULL)
5233 m_free(data->m);
5234 data->m = NULL;
5237 if (data->ni != NULL)
5239 ieee80211_free_node(data->ni);
5240 data->ni = NULL;
5243 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5248 * rt2870_free_tx_ring
5250 static void rt2870_free_tx_ring(struct rt2870_softc *sc,
5251 struct rt2870_softc_tx_ring *ring)
5253 struct rt2870_softc_tx_data *data;
5254 int i;
5256 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
5258 data = &ring->data[i];
5260 if (data->buf != NULL)
5262 free(data->buf, M_USBDEV);
5263 data->buf = NULL;
5266 if (data->m != NULL)
5268 m_free(data->m);
5269 data->m = NULL;
5272 if (data->ni != NULL)
5274 ieee80211_free_node(data->ni);
5275 data->ni = NULL;
5281 * rt2870_reset_cmd_ring
5283 static void rt2870_reset_cmd_ring(struct rt2870_softc *sc,
5284 struct rt2870_softc_cmd_ring *ring)
5286 struct rt2870_softc_cmd *cmd;
5287 int i;
5289 STAILQ_INIT(&ring->inactive);
5290 STAILQ_INIT(&ring->active);
5292 ring->queued = 0;
5294 for (i = 0; i < RT2870_SOFTC_CMD_RING_CMD_COUNT; i++)
5296 cmd = &ring->cmd[i];
5298 STAILQ_INSERT_TAIL(&ring->inactive, cmd, next);
5303 * rt2870_sysctl_attach
5305 static void rt2870_sysctl_attach(struct rt2870_softc *sc)
5307 struct sysctl_ctx_list *ctx;
5308 struct sysctl_oid *tree;
5309 struct sysctl_oid *stats;
5311 ctx = device_get_sysctl_ctx(sc->dev);
5312 tree = device_get_sysctl_tree(sc->dev);
5314 stats = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
5315 "stats", CTLFLAG_RD, 0, "statistic");
5317 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5318 "interrupts", CTLFLAG_RD, &sc->interrupts, 0,
5319 "all interrupts");
5321 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5322 "rx_interrupts", CTLFLAG_RD, &sc->rx_interrupts, 0,
5323 "Rx interrupts");
5325 if (sc->usb_endpoints == RT2870_SOFTC_USB_XFER_COUNT)
5327 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5328 "tx_mgmt_interrupts", CTLFLAG_RD, &sc->tx_interrupts[5], 0,
5329 "Tx MGMT interrupts");
5331 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5332 "tx_hcca_interrupts", CTLFLAG_RD, &sc->tx_interrupts[4], 0,
5333 "Tx HCCA interrupts");
5336 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5337 "tx_ac3_interrupts", CTLFLAG_RD, &sc->tx_interrupts[3], 0,
5338 "Tx AC3 interrupts");
5340 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5341 "tx_ac2_interrupts", CTLFLAG_RD, &sc->tx_interrupts[2], 0,
5342 "Tx AC2 interrupts");
5344 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5345 "tx_ac1_interrupts", CTLFLAG_RD, &sc->tx_interrupts[1], 0,
5346 "Tx AC1 interrupts");
5348 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5349 "tx_ac0_interrupts", CTLFLAG_RD, &sc->tx_interrupts[0], 0,
5350 "Tx AC0 interrupts");
5352 if (sc->usb_endpoints == RT2870_SOFTC_USB_XFER_COUNT)
5354 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5355 "tx_mgmt_data_queued", CTLFLAG_RD, &sc->tx_ring[5].queued, 0,
5356 "Tx MGMT data queued");
5358 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5359 "tx_hcca_data_queued", CTLFLAG_RD, &sc->tx_ring[4].queued, 0,
5360 "Tx HCCA data queued");
5363 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5364 "tx_ac3_data_queued", CTLFLAG_RD, &sc->tx_ring[3].queued, 0,
5365 "Tx AC3 data queued");
5367 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5368 "tx_ac2_data_queued", CTLFLAG_RD, &sc->tx_ring[2].queued, 0,
5369 "Tx AC2 data queued");
5371 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5372 "tx_ac1_data_queued", CTLFLAG_RD, &sc->tx_ring[1].queued, 0,
5373 "Tx AC1 data queued");
5375 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5376 "tx_ac0_data_queued", CTLFLAG_RD, &sc->tx_ring[0].queued, 0,
5377 "Tx AC0 data queued");
5379 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5380 "tx_watchdog_timeouts", CTLFLAG_RD, &sc->tx_watchdog_timeouts, 0,
5381 "Tx watchdog timeouts");
5383 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5384 "rx_mbuf_alloc_errors", CTLFLAG_RD, &sc->rx_mbuf_alloc_errors, 0,
5385 "Rx mbuf allocation errors");
5387 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5388 "tx_queue_0_not_empty", CTLFLAG_RD, &sc->tx_queue_not_empty[0], 0,
5389 "Tx queue 0 not empty");
5391 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5392 "tx_queue_1_not_empty", CTLFLAG_RD, &sc->tx_queue_not_empty[1], 0,
5393 "Tx queue 1 not empty");
5395 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5396 "rx_packets", CTLFLAG_RD, &sc->rx_packets, 0,
5397 "Rx packets");
5399 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5400 "rx_crc_errors", CTLFLAG_RD, &sc->rx_crc_errors, 0,
5401 "Rx CRC errors");
5403 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5404 "rx_phy_errors", CTLFLAG_RD, &sc->rx_phy_errors, 0,
5405 "Rx PHY errors");
5407 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5408 "rx_false_ccas", CTLFLAG_RD, &sc->rx_false_ccas, 0,
5409 "Rx false CCAs");
5411 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5412 "rx_plcp_errors", CTLFLAG_RD, &sc->rx_plcp_errors, 0,
5413 "Rx PLCP errors");
5415 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5416 "rx_dup_packets", CTLFLAG_RD, &sc->rx_dup_packets, 0,
5417 "Rx duplicate packets");
5419 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5420 "rx_fifo_overflows", CTLFLAG_RD, &sc->rx_fifo_overflows, 0,
5421 "Rx FIFO overflows");
5424 static device_method_t rt2870_dev_methods[] =
5426 DEVMETHOD(device_probe, rt2870_probe),
5427 DEVMETHOD(device_attach, rt2870_attach),
5428 DEVMETHOD(device_detach, rt2870_detach),
5429 { 0, 0 }
5432 static driver_t rt2870_driver =
5434 "rt2870",
5435 rt2870_dev_methods,
5436 sizeof(struct rt2870_softc),
5439 static devclass_t rt2870_dev_class;
5441 DRIVER_MODULE(rt2870, uhub, rt2870_driver, rt2870_dev_class,
5442 NULL, 0);
5444 MODULE_DEPEND(rt2870, usb, 1, 1, 1);
5445 MODULE_DEPEND(rt2870, wlan, 1, 1, 1);