net80211's newassoc should be called from process context
[ralink_drivers/rt2870_fbsd8.git] / rt2870.c
blob92b741bdf7142a7113230c1fcfc0b4a8da175a55
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
42 #define USB_PRODUCT_RALINK_RT2870 0x2870
44 #define RT2870_USB_CONFIG_INDEX 0
45 #define RT2870_USB_IFACE_INDEX 0
47 #define RT2870_USB_REQ_MAC_READ_MULTI 0x07
49 /* packet length + Rx wireless info + Rx info */
50 #define RT2870_RX_DESC_SIZE \
51 (sizeof(uint32_t) + sizeof(struct rt2870_rxwi) + sizeof(struct rt2870_rxinfo))
53 /* Tx info + Tx wireless info + max padding */
54 #define RT2870_TX_DESC_SIZE \
55 (sizeof(struct rt2870_txinfo) + sizeof(struct rt2870_txwi) + 11)
57 #define RT2870_MAX_AGG_SIZE 3840
59 #define RT2870_USB_RX_BULK_BUFLEN (2048 * 12)
61 #define RT2870_NOISE_FLOOR -95
63 #define IEEE80211_HAS_ADDR4(wh) \
64 (((wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
66 #define RT2870_MS(_v, _f) (((_v) & _f) >> _f##_S)
67 #define RT2870_SM(_v, _f) (((_v) << _f##_S) & _f)
69 #define RT2870_USB_XFER_TIMEOUT 5000
71 #define RT2870_TX_WATCHDOG_TIMEOUT 5
73 #define RT2870_WCID_RESERVED 0xff
74 #define RT2870_WCID_MCAST 0xf7
77 * Data structures and types
80 struct rt2870_cmd_argv_newassoc
82 uint8_t macaddr[IEEE80211_ADDR_LEN];
83 int isnew;
86 struct rt2870_cmd_argv_nodecleanup
88 uint8_t staid;
91 struct rt2870_cmd_argv_keyset
93 enum ieee80211_opmode opmode;
94 struct ieee80211_key key;
95 uint8_t staid;
98 struct rt2870_cmd_argv_keydelete
100 enum ieee80211_opmode opmode;
101 struct ieee80211_key key;
105 * Static function prototypes
108 static void rt2870_init_channels(struct rt2870_softc *sc);
110 static void rt2870_init_channels_ht40(struct rt2870_softc *sc);
112 static void rt2870_init_locked(void *priv);
114 static void rt2870_init(void *priv);
116 static int rt2870_init_bbp(struct rt2870_softc *sc);
118 static void rt2870_stop_locked(void *priv);
120 static void rt2870_stop(void *priv);
122 static void rt2870_start(struct ifnet *ifp);
124 static int rt2870_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
126 static struct ieee80211vap *rt2870_vap_create(struct ieee80211com *ic,
127 const char name[IFNAMSIZ], int unit, int opmode, int flags,
128 const uint8_t bssid[IEEE80211_ADDR_LEN],
129 const uint8_t mac[IEEE80211_ADDR_LEN]);
131 static void rt2870_vap_delete(struct ieee80211vap *vap);
133 static int rt2870_vap_reset(struct ieee80211vap *vap, u_long cmd);
135 static int rt2870_vap_newstate(struct ieee80211vap *vap,
136 enum ieee80211_state nstate, int arg);
138 static void rt2870_vap_key_update_begin(struct ieee80211vap *vap);
140 static void rt2870_vap_key_update_end(struct ieee80211vap *vap);
142 static int rt2870_vap_key_set(struct ieee80211vap *vap,
143 const struct ieee80211_key *k, const uint8_t mac[IEEE80211_ADDR_LEN]);
145 static int rt2870_vap_key_delete(struct ieee80211vap *vap,
146 const struct ieee80211_key *k);
148 static void rt2870_vap_update_beacon(struct ieee80211vap *vap, int what);
150 static struct ieee80211_node *rt2870_node_alloc(struct ieee80211vap *vap,
151 const uint8_t mac[IEEE80211_ADDR_LEN]);
153 static void rt2870_node_cleanup(struct ieee80211_node *ni);
155 static void rt2870_node_getmimoinfo(const struct ieee80211_node *ni,
156 struct ieee80211_mimo_info *mi);
158 static int rt2870_setregdomain(struct ieee80211com *ic,
159 struct ieee80211_regdomain *reg,
160 int nchans, struct ieee80211_channel chans[]);
162 static void rt2870_getradiocaps(struct ieee80211com *ic,
163 int maxchans, int *nchans, struct ieee80211_channel chans[]);
165 static void rt2870_scan_start(struct ieee80211com *ic);
167 static void rt2870_scan_end(struct ieee80211com *ic);
169 static void rt2870_set_channel(struct ieee80211com *ic);
171 static void rt2870_newassoc(struct ieee80211_node *ni, int isnew);
173 static void rt2870_updateslot(struct ifnet *ifp);
175 static void rt2870_update_promisc(struct ifnet *ifp);
177 static void rt2870_update_mcast(struct ifnet *ifp);
179 static int rt2870_wme_update(struct ieee80211com *ic);
181 static int rt2870_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
182 const struct ieee80211_bpf_params *params);
184 static int rt2870_recv_action(struct ieee80211_node *ni,
185 const struct ieee80211_frame *wh,
186 const uint8_t *frm, const uint8_t *efrm);
188 static int rt2870_send_action(struct ieee80211_node *ni,
189 int cat, int act, void *sa);
191 static int rt2870_addba_response(struct ieee80211_node *ni,
192 struct ieee80211_tx_ampdu *tap,
193 int status, int baparamset, int batimeout);
195 static void rt2870_addba_stop(struct ieee80211_node *ni,
196 struct ieee80211_tx_ampdu *tap);
198 static int rt2870_ampdu_rx_start(struct ieee80211_node *ni,
199 struct ieee80211_rx_ampdu *rap,
200 int baparamset, int batimeout, int baseqctl);
202 static void rt2870_ampdu_rx_stop(struct ieee80211_node *ni,
203 struct ieee80211_rx_ampdu *rap);
205 static int rt2870_send_bar(struct ieee80211_node *ni,
206 struct ieee80211_tx_ampdu *tap, ieee80211_seq seqno);
208 static void rt2870_amrr_update_iter_func(void *arg, struct ieee80211_node *ni);
210 static void rt2870_periodic(void *arg);
212 static void rt2870_tx_watchdog(void *arg);
214 static int rt2870_staid_alloc(struct rt2870_softc *sc, int aid);
216 static void rt2870_staid_delete(struct rt2870_softc *sc, int staid);
218 static int rt2870_do_async(struct rt2870_softc *sc,
219 void (*cb)(struct rt2870_softc *sc, void *arg),
220 void *arg, int len);
222 static void rt2870_newassoc_cb(struct rt2870_softc *sc, void *arg);
224 static void rt2870_node_cleanup_cb(struct rt2870_softc *sc, void *arg);
226 static void rt2870_updateslot_cb(struct rt2870_softc *sc, void *arg);
228 static void rt2870_wme_update_cb(struct rt2870_softc *sc, void *arg);
230 static void rt2870_vap_key_set_cb(struct rt2870_softc *sc, void *arg);
232 static void rt2870_vap_key_delete_cb(struct rt2870_softc *sc, void *arg);
234 static void rt2870_vap_update_beacon_cb(struct rt2870_softc *sc, void *arg);
236 static void rt2870_asic_set_bssid(struct rt2870_softc *sc,
237 const uint8_t *bssid);
239 static void rt2870_asic_set_macaddr(struct rt2870_softc *sc,
240 const uint8_t *addr);
242 static void rt2870_asic_enable_tsf_sync(struct rt2870_softc *sc);
244 static void rt2870_asic_disable_tsf_sync(struct rt2870_softc *sc);
246 static void rt2870_asic_enable_mrr(struct rt2870_softc *sc);
248 static void rt2870_asic_set_txpreamble(struct rt2870_softc *sc);
250 static void rt2870_asic_set_basicrates(struct rt2870_softc *sc);
252 static void rt2870_asic_update_rtsthreshold(struct rt2870_softc *sc);
254 static void rt2870_asic_update_txpower(struct rt2870_softc *sc);
256 static void rt2870_asic_update_promisc(struct rt2870_softc *sc);
258 static void rt2870_asic_updateprot(struct rt2870_softc *sc);
260 static void rt2870_asic_updateslot(struct rt2870_softc *sc);
262 static void rt2870_asic_wme_update(struct rt2870_softc *sc);
264 static void rt2870_asic_update_beacon(struct rt2870_softc *sc,
265 struct ieee80211vap *vap);
267 static void rt2870_asic_clear_keytables(struct rt2870_softc *sc);
269 static void rt2870_asic_add_ba_session(struct rt2870_softc *sc,
270 uint8_t wcid, int tid);
272 static void rt2870_asic_del_ba_session(struct rt2870_softc *sc,
273 uint8_t wcid, int tid);
275 static int rt2870_beacon_alloc(struct rt2870_softc *sc,
276 struct ieee80211vap *vap);
278 static uint8_t rt2870_rxrate(struct rt2870_rxwi *rxwi);
280 static uint8_t rt2870_maxrssi_rxpath(struct rt2870_softc *sc,
281 const struct rt2870_rxwi *rxwi);
283 static int8_t rt2870_rssi2dbm(struct rt2870_softc *sc,
284 uint8_t rssi, uint8_t rxpath);
286 static uint8_t rt2870_rate2mcs(uint8_t rate);
288 static void rt2870_rx_frame(struct rt2870_softc *sc,
289 uint8_t *buf, uint32_t dmalen);
291 static int rt2870_tx_mgmt(struct rt2870_softc *sc,
292 struct mbuf *m, struct ieee80211_node *ni, int qid);
294 static int rt2870_tx_data(struct rt2870_softc *sc,
295 struct mbuf *m, struct ieee80211_node *ni, int qid);
297 static int rt2870_tx_raw(struct rt2870_softc *sc,
298 struct mbuf *m, struct ieee80211_node *ni,
299 const struct ieee80211_bpf_params *params);
301 static void rt2870_rx_intr(struct usb_xfer *xfer, usb_error_t error);
303 static void rt2870_tx_intr(struct usb_xfer *xfer, usb_error_t error);
305 static void rt2870_rx_done_task(void *context, int pending);
307 static void rt2870_tx_done_task(void *context, int pending);
309 static void rt2870_periodic_task(void *context, int pending);
311 static void rt2870_cmd_task(void *context, int pending);
313 static int rt2870_rx_eof(struct rt2870_softc *sc, int limit);
315 static void rt2870_tx_eof(struct rt2870_softc *sc,
316 struct rt2870_softc_tx_ring *ring);
318 static void rt2870_update_stats(struct rt2870_softc *sc);
320 static void rt2870_bbp_tuning(struct rt2870_softc *sc);
322 static void rt2870_watchdog(struct rt2870_softc *sc);
324 static void rt2870_drain_fifo_stats(struct rt2870_softc *sc);
326 static void rt2870_update_raw_counters(struct rt2870_softc *sc);
328 static int rt2870_txrx_enable(struct rt2870_softc *sc);
330 static int rt2870_alloc_rx_ring(struct rt2870_softc *sc,
331 struct rt2870_softc_rx_ring *ring);
333 static void rt2870_reset_rx_ring(struct rt2870_softc *sc,
334 struct rt2870_softc_rx_ring *ring);
336 static void rt2870_free_rx_ring(struct rt2870_softc *sc,
337 struct rt2870_softc_rx_ring *ring);
339 static int rt2870_alloc_tx_ring(struct rt2870_softc *sc,
340 struct rt2870_softc_tx_ring *ring, int qid);
342 static void rt2870_reset_tx_ring(struct rt2870_softc *sc,
343 struct rt2870_softc_tx_ring *ring);
345 static void rt2870_free_tx_ring(struct rt2870_softc *sc,
346 struct rt2870_softc_tx_ring *ring);
348 static void rt2870_reset_cmd_ring(struct rt2870_softc *sc,
349 struct rt2870_softc_cmd_ring *ring);
351 static void rt2870_sysctl_attach(struct rt2870_softc *sc);
354 * Static variables
357 static const struct usb_device_id rt2870_usb_devid[] =
359 { USB_VP(USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB600N) }, /* Linksys WUSB600N */
360 { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA140) }, /* D-Link DWA-140 */
361 { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160AREVB) }, /* D-Link DWA-160A Rev. B */
362 { USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2770F) }, /* Asus RT2770F */
363 { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2770) }, /* Ralink RT2770 */
364 { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2870) }, /* Ralink RT2870 */
367 static const struct usb_config rt2870_usb_config[RT2870_SOFTC_USB_XFER_COUNT] =
370 .type = UE_BULK,
371 .endpoint = 0x01,
372 .direction = UE_DIR_IN,
373 .bufsize = RT2870_USB_RX_BULK_BUFLEN,
374 .flags = { .ext_buffer = 1, .pipe_bof = 1, .short_xfer_ok = 1, },
375 .callback = rt2870_rx_intr,
378 .type = UE_BULK,
379 .endpoint = 0x01,
380 .direction = UE_DIR_OUT,
381 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
382 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
383 .callback = rt2870_tx_intr,
384 .timeout = RT2870_USB_XFER_TIMEOUT,
387 .type = UE_BULK,
388 .endpoint = 0x02,
389 .direction = UE_DIR_OUT,
390 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
391 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
392 .callback = rt2870_tx_intr,
393 .timeout = RT2870_USB_XFER_TIMEOUT,
396 .type = UE_BULK,
397 .endpoint = 0x03,
398 .direction = UE_DIR_OUT,
399 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
400 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
401 .callback = rt2870_tx_intr,
402 .timeout = RT2870_USB_XFER_TIMEOUT,
405 .type = UE_BULK,
406 .endpoint = 0x04,
407 .direction = UE_DIR_OUT,
408 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
409 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
410 .callback = rt2870_tx_intr,
411 .timeout = RT2870_USB_XFER_TIMEOUT,
414 .type = UE_BULK,
415 .endpoint = 0x05,
416 .direction = UE_DIR_OUT,
417 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
418 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
419 .callback = rt2870_tx_intr,
420 .timeout = RT2870_USB_XFER_TIMEOUT,
423 .type = UE_BULK,
424 .endpoint = 0x06,
425 .direction = UE_DIR_OUT,
426 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
427 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
428 .callback = rt2870_tx_intr,
429 .timeout = RT2870_USB_XFER_TIMEOUT,
433 static const struct
435 uint32_t reg;
436 uint32_t val;
437 } rt2870_def_mac[] =
439 { RT2870_REG_PBF_BCN_OFFSET0, 0xf8f0e8e0 },
440 { RT2870_REG_PBF_BCN_OFFSET1, 0x6f77d0c8 },
441 { RT2870_REG_LEGACY_BASIC_RATE, 0x0000013f },
442 { RT2870_REG_HT_BASIC_RATE, 0x00008003 },
443 { RT2870_REG_SYS_CTRL, 0x00000000 },
444 { RT2870_REG_RX_FILTER_CFG, 0x00017f97 },
445 { RT2870_REG_BKOFF_SLOT_CFG, 0x00000209 },
446 { RT2870_REG_TX_SW_CFG0, 0x00000000 },
447 { RT2870_REG_TX_SW_CFG1, 0x00080606 },
448 { RT2870_REG_TX_LINK_CFG, 0x00001020 },
449 { RT2870_REG_TX_TIMEOUT_CFG, 0x000a2090 },
450 { RT2870_REG_MAX_LEN_CFG, (1 << 12) | RT2870_MAX_AGG_SIZE },
451 { RT2870_REG_LED_CFG, 0x7f031e46 },
452 { RT2870_REG_PBF_MAX_PCNT, 0x1f3fbf9f },
453 { RT2870_REG_TX_RTY_CFG, 0x47d01f0f },
454 { RT2870_REG_AUTO_RSP_CFG, 0x00000013 },
455 { RT2870_REG_TX_CCK_PROT_CFG, 0x05740003 },
456 { RT2870_REG_TX_OFDM_PROT_CFG, 0x05740003 },
457 { RT2870_REG_PBF_CFG, 0x00f40006 },
458 { RT2870_REG_TX_MM40_PROT_CFG, 0x03f44084 },
459 { RT2870_REG_SCHDMA_WPDMA_GLO_CFG, 0x00000030 },
460 { RT2870_REG_TX_GF20_PROT_CFG, 0x01744004 },
461 { RT2870_REG_TX_GF40_PROT_CFG, 0x03f44084 },
462 { RT2870_REG_TX_MM20_PROT_CFG, 0x01744004 },
463 { RT2870_REG_TX_TXOP_CTRL_CFG, 0x0000583f },
464 { RT2870_REG_TX_RTS_CFG, 0x00092b20 },
465 { RT2870_REG_TX_EXP_ACK_TIME, 0x002400ca },
466 { RT2870_REG_HCCAPSMP_TXOP_HLDR_ET, 0x00000002 },
467 { RT2870_REG_XIFS_TIME_CFG, 0x33a41010 },
468 { RT2870_REG_PWR_PIN_CFG, 0x00000003 },
469 { RT2870_REG_SCHDMA_WMM_AIFSN_CFG, 0x00002273 },
470 { RT2870_REG_SCHDMA_WMM_CWMIN_CFG, 0x00002344 },
471 { RT2870_REG_SCHDMA_WMM_CWMAX_CFG, 0x000034aa },
474 #define RT2870_DEF_MAC_SIZE (sizeof(rt2870_def_mac) / sizeof(rt2870_def_mac[0]))
476 static const struct
478 uint8_t reg;
479 uint8_t val;
480 } rt2870_def_bbp[] =
482 { 65, 0x2c },
483 { 66, 0x38 },
484 { 69, 0x12 },
485 { 70, 0x0a },
486 { 73, 0x10 },
487 { 81, 0x37 },
488 { 82, 0x62 },
489 { 83, 0x6a },
490 { 84, 0x99 },
491 { 86, 0x00 },
492 { 91, 0x04 },
493 { 92, 0x00 },
494 { 103, 0x00 },
495 { 105, 0x05 },
496 { 106, 0x35 },
499 #define RT2870_DEF_BBP_SIZE (sizeof(rt2870_def_bbp) / sizeof(rt2870_def_bbp[0]))
501 SYSCTL_NODE(_hw, OID_AUTO, rt2870, CTLFLAG_RD, 0, "RT2870 driver parameters");
503 static int rt2870_tx_stbc = 1;
504 SYSCTL_INT(_hw_rt2870, OID_AUTO, tx_stbc, CTLFLAG_RW, &rt2870_tx_stbc, 0, "RT2870 Tx STBC");
505 TUNABLE_INT("hw.rt2870.tx_stbc", &rt2870_tx_stbc);
507 #ifdef RT2870_DEBUG
508 static int rt2870_debug = 0;
509 SYSCTL_INT(_hw_rt2870, OID_AUTO, debug, CTLFLAG_RW, &rt2870_debug, 0, "RT2870 debug level");
510 TUNABLE_INT("hw.rt2870.debug", &rt2870_debug);
511 #endif
514 * rt2870_probe
516 static int rt2870_probe(device_t dev)
518 struct usb_attach_arg *uaa;
520 uaa = device_get_ivars(dev);
522 if (uaa->usb_mode != USB_MODE_HOST)
523 return ENXIO;
525 if (uaa->info.bConfigIndex != RT2870_USB_CONFIG_INDEX)
526 return ENXIO;
528 if (uaa->info.bIfaceIndex != RT2870_USB_IFACE_INDEX)
529 return ENXIO;
531 return (usbd_lookup_id_by_uaa(rt2870_usb_devid,
532 sizeof(rt2870_usb_devid), uaa));
536 * rt2870_attach
538 static int rt2870_attach(device_t dev)
540 struct rt2870_softc *sc;
541 struct usb_attach_arg *uaa;
542 usb_error_t usb_error;
543 struct ieee80211com *ic;
544 struct ifnet *ifp;
545 struct usb_interface *iface;
546 struct usb_interface_descriptor *iface_desc;
547 uint8_t iface_index;
548 int error, ntries, i;
550 sc = device_get_softc(dev);
551 uaa = device_get_ivars(dev);
553 sc->dev = dev;
554 sc->usb_dev = uaa->device;
556 device_set_usb_desc(dev);
558 sc->tx_stbc = rt2870_tx_stbc;
560 #ifdef RT2870_DEBUG
561 sc->debug = rt2870_debug;
563 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
564 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
565 "debug", CTLFLAG_RW, &sc->debug, 0, "rt2870 debug level");
566 #endif
568 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
569 "%s: attaching\n",
570 device_get_nameunit(sc->dev));
572 iface_index = RT2870_USB_IFACE_INDEX;
574 iface = usbd_get_iface(uaa->device, iface_index);
575 if (iface == NULL)
577 printf("%s: could not get USB interface\n",
578 device_get_nameunit(sc->dev));
579 return ENXIO;
582 iface_desc = usbd_get_interface_descriptor(iface);
583 if (iface_desc == NULL)
585 printf("%s: could not get USB interface descriptor\n",
586 device_get_nameunit(sc->dev));
587 return ENXIO;
590 sc->usb_endpoints = iface_desc->bNumEndpoints;
591 if ((sc->usb_endpoints != RT2870_SOFTC_USB_XFER_COUNT) &&
592 (sc->usb_endpoints != RT2870_SOFTC_USB_XFER_COUNT - 2))
594 printf("%s: wrong number of USB endpoints=%d\n",
595 device_get_nameunit(sc->dev), sc->usb_endpoints);
596 return ENXIO;
599 mtx_init(&sc->lock, device_get_nameunit(dev),
600 MTX_NETWORK_LOCK, MTX_DEF);
602 usb_error = usbd_transfer_setup(uaa->device, &iface_index,
603 sc->usb_xfer, rt2870_usb_config, sc->usb_endpoints,
604 sc, &sc->lock);
605 if (usb_error != 0)
607 printf("%s: could not allocate USB transfers: error=%s\n",
608 device_get_nameunit(sc->dev), usbd_errstr(usb_error));
609 error = ENXIO;
610 goto fail;
613 sc->flags |= RT2870_SOFTC_FLAGS_VALID;
615 RT2870_SOFTC_LOCK(sc);
617 for (ntries = 0; ntries < 100; ntries++)
619 sc->mac_rev = rt2870_io_mac_read(sc, RT2870_REG_MAC_CSR0);
620 if (sc->mac_rev != 0x00000000 && sc->mac_rev != 0xffffffff)
621 break;
623 DELAY(10);
626 if (ntries == 100)
628 printf("%s: timeout waiting for NIC to initialize\n",
629 device_get_nameunit(sc->dev));
630 error = ENXIO;
631 goto fail;
634 rt2870_read_eeprom(sc);
636 RT2870_SOFTC_UNLOCK(sc);
638 printf("%s: MAC/BBP RT2870 (rev 0x%08x), RF %s\n",
639 device_get_nameunit(sc->dev), sc->mac_rev,
640 rt2870_rf_name(sc->rf_rev));
642 RT2870_SOFTC_LOCK(sc);
644 /* clear key tables */
646 rt2870_asic_clear_keytables(sc);
648 RT2870_SOFTC_UNLOCK(sc);
650 /* allocate Tx and Rx rings */
652 for (i = 0; i < sc->usb_endpoints - 1; i++)
654 error = rt2870_alloc_tx_ring(sc, &sc->tx_ring[i], i);
655 if (error != 0)
657 printf("%s: could not allocate Tx ring #%d\n",
658 device_get_nameunit(sc->dev), i);
659 goto fail;
663 if (sc->usb_endpoints == RT2870_SOFTC_USB_XFER_COUNT)
664 sc->tx_ring_mgtqid = 5;
665 else
666 sc->tx_ring_mgtqid = 0;
668 error = rt2870_alloc_rx_ring(sc, &sc->rx_ring);
669 if (error != 0)
671 printf("%s: could not allocate Rx ring\n",
672 device_get_nameunit(sc->dev));
673 goto fail;
676 callout_init(&sc->periodic_ch, 0);
677 callout_init_mtx(&sc->tx_watchdog_ch, &sc->lock, 0);
679 ifp = sc->ifp = if_alloc(IFT_IEEE80211);
680 if (ifp == NULL)
682 printf("%s: could not if_alloc()\n",
683 device_get_nameunit(sc->dev));
684 error = ENOMEM;
685 goto fail;
688 ifp->if_softc = sc;
690 if_initname(ifp, "rt2870", device_get_unit(sc->dev));
692 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
694 ifp->if_init = rt2870_init;
695 ifp->if_ioctl = rt2870_ioctl;
696 ifp->if_start = rt2870_start;
698 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
699 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
700 IFQ_SET_READY(&ifp->if_snd);
702 ic = ifp->if_l2com;
704 ic->ic_ifp = ifp;
706 ic->ic_phytype = IEEE80211_T_HT;
707 ic->ic_opmode = IEEE80211_M_STA;
709 ic->ic_caps = IEEE80211_C_MONITOR |
710 IEEE80211_C_IBSS |
711 IEEE80211_C_STA |
712 IEEE80211_C_AHDEMO |
713 IEEE80211_C_HOSTAP |
714 IEEE80211_C_WDS |
715 IEEE80211_C_MBSS |
716 IEEE80211_C_BGSCAN |
717 IEEE80211_C_TXPMGT |
718 IEEE80211_C_SHPREAMBLE |
719 IEEE80211_C_SHSLOT |
720 IEEE80211_C_TXFRAG |
721 IEEE80211_C_BURST |
722 IEEE80211_C_WME |
723 IEEE80211_C_WPA;
725 ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP |
726 IEEE80211_CRYPTO_TKIP |
727 IEEE80211_CRYPTO_TKIPMIC |
728 IEEE80211_CRYPTO_AES_CCM;
730 ic->ic_htcaps = IEEE80211_HTC_HT |
731 IEEE80211_HTC_AMSDU | /* A-MSDU Tx */
732 IEEE80211_HTC_AMPDU | /* A-MPDU Tx */
733 IEEE80211_HTC_SMPS | /* MIMO power save */
734 IEEE80211_HTCAP_MAXAMSDU_3839 | /* max. A-MSDU Rx length */
735 IEEE80211_HTCAP_CHWIDTH40 | /* HT 40MHz channel width */
736 IEEE80211_HTCAP_GREENFIELD | /* HT greenfield */
737 IEEE80211_HTCAP_SHORTGI20 | /* HT 20MHz short GI */
738 IEEE80211_HTCAP_SHORTGI40 | /* HT 40MHz short GI */
739 IEEE80211_HTCAP_SMPS_OFF; /* MIMO power save disabled */
741 /* spatial streams */
743 if (sc->nrxpath == 2)
744 ic->ic_htcaps |= IEEE80211_HTCAP_RXSTBC_2STREAM;
745 else if (sc->nrxpath == 3)
746 ic->ic_htcaps |= IEEE80211_HTCAP_RXSTBC_3STREAM;
747 else
748 ic->ic_htcaps |= IEEE80211_HTCAP_RXSTBC_1STREAM;
750 if (sc->ntxpath > 1)
751 ic->ic_htcaps |= IEEE80211_HTCAP_TXSTBC;
753 /* delayed BA */
755 if (sc->mac_rev != 0x28600100)
756 ic->ic_htcaps |= IEEE80211_HTCAP_DELBA;
758 /* init channels */
760 ic->ic_nchans = 0;
762 rt2870_init_channels(sc);
764 rt2870_init_channels_ht40(sc);
766 ieee80211_ifattach(ic, sc->mac_addr);
768 ic->ic_vap_create = rt2870_vap_create;
769 ic->ic_vap_delete = rt2870_vap_delete;
771 ic->ic_node_alloc = rt2870_node_alloc;
773 sc->node_cleanup = ic->ic_node_cleanup;
774 ic->ic_node_cleanup = rt2870_node_cleanup;
776 ic->ic_node_getmimoinfo = rt2870_node_getmimoinfo;
777 ic->ic_setregdomain = rt2870_setregdomain;
778 ic->ic_getradiocaps = rt2870_getradiocaps;
779 ic->ic_scan_start = rt2870_scan_start;
780 ic->ic_scan_end = rt2870_scan_end;
781 ic->ic_set_channel = rt2870_set_channel;
782 ic->ic_newassoc = rt2870_newassoc;
783 ic->ic_updateslot = rt2870_updateslot;
784 ic->ic_update_promisc = rt2870_update_promisc;
785 ic->ic_update_mcast = rt2870_update_mcast;
786 ic->ic_wme.wme_update = rt2870_wme_update;
787 ic->ic_raw_xmit = rt2870_raw_xmit;
789 sc->recv_action = ic->ic_recv_action;
790 ic->ic_recv_action = rt2870_recv_action;
792 sc->send_action = ic->ic_send_action;
793 ic->ic_send_action = rt2870_send_action;
795 sc->addba_response = ic->ic_addba_response;
796 ic->ic_addba_response = rt2870_addba_response;
798 sc->addba_stop = ic->ic_addba_stop;
799 ic->ic_addba_stop = rt2870_addba_stop;
801 sc->ampdu_rx_start = ic->ic_ampdu_rx_start;
802 ic->ic_ampdu_rx_start = rt2870_ampdu_rx_start;
804 sc->ampdu_rx_stop = ic->ic_ampdu_rx_stop;
805 ic->ic_ampdu_rx_stop = rt2870_ampdu_rx_stop;
807 /* hardware requires padding between 802.11 frame header and body */
809 ic->ic_flags |= IEEE80211_F_DATAPAD | IEEE80211_F_DOTH;
811 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;
813 ieee80211_radiotap_attach(ic,
814 &sc->txtap.ihdr, sizeof(sc->txtap),
815 RT2870_SOFTC_TX_RADIOTAP_PRESENT,
816 &sc->rxtap.ihdr, sizeof(sc->rxtap),
817 RT2870_SOFTC_RX_RADIOTAP_PRESENT);
819 /* init task queue */
821 TASK_INIT(&sc->rx_done_task, 0, rt2870_rx_done_task, sc);
822 TASK_INIT(&sc->tx_done_task, 0, rt2870_tx_done_task, sc);
823 TASK_INIT(&sc->periodic_task, 0, rt2870_periodic_task, sc);
824 TASK_INIT(&sc->cmd_task, 0, rt2870_cmd_task, sc);
826 sc->rx_process_limit = 100;
828 sc->taskqueue = taskqueue_create("rt2870_taskq", M_NOWAIT,
829 taskqueue_thread_enqueue, &sc->taskqueue);
831 taskqueue_start_threads(&sc->taskqueue, 1, PI_NET, "%s taskq",
832 device_get_nameunit(sc->dev));
834 rt2870_reset_cmd_ring(sc, &sc->cmd_ring);
836 rt2870_sysctl_attach(sc);
838 if (bootverbose)
839 ieee80211_announce(ic);
841 return 0;
843 fail:
845 /* stop all USB transfers */
847 usbd_transfer_unsetup(sc->usb_xfer, sc->usb_endpoints);
849 /* free Tx and Rx rings */
851 for (i = 0; i < sc->usb_endpoints - 1; i++)
852 rt2870_free_tx_ring(sc, &sc->tx_ring[i]);
854 rt2870_free_rx_ring(sc, &sc->rx_ring);
856 mtx_destroy(&sc->lock);
858 return error;
862 * rt2870_detach
864 static int rt2870_detach(device_t dev)
866 struct rt2870_softc *sc;
867 struct ieee80211com *ic;
868 struct ifnet *ifp;
869 int i;
871 if (!device_is_attached(dev))
872 return 0;
874 sc = device_get_softc(dev);
875 ifp = sc->ifp;
876 ic = ifp->if_l2com;
878 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
879 "%s: detaching\n",
880 device_get_nameunit(sc->dev));
882 RT2870_SOFTC_LOCK(sc);
884 sc->flags &= ~RT2870_SOFTC_FLAGS_VALID;
886 sc->tx_timer = 0;
888 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
890 callout_stop(&sc->periodic_ch);
891 callout_stop(&sc->tx_watchdog_ch);
893 RT2870_SOFTC_UNLOCK(sc);
895 taskqueue_block(sc->taskqueue);
897 taskqueue_drain(sc->taskqueue, &sc->rx_done_task);
898 taskqueue_drain(sc->taskqueue, &sc->tx_done_task);
899 taskqueue_drain(sc->taskqueue, &sc->periodic_task);
900 taskqueue_drain(sc->taskqueue, &sc->cmd_task);
902 /* stop all USB transfers */
904 usbd_transfer_unsetup(sc->usb_xfer, sc->usb_endpoints);
906 RT2870_SOFTC_LOCK(sc);
908 /* free Tx and Rx rings */
910 for (i = 0; i < sc->usb_endpoints - 1; i++)
911 rt2870_free_tx_ring(sc, &sc->tx_ring[i]);
913 rt2870_free_rx_ring(sc, &sc->rx_ring);
915 RT2870_SOFTC_UNLOCK(sc);
917 ieee80211_ifdetach(ic);
919 if_free(ifp);
921 taskqueue_free(sc->taskqueue);
923 mtx_destroy(&sc->lock);
925 return 0;
929 * rt2870_init_channels
931 static void rt2870_init_channels(struct rt2870_softc *sc)
933 struct ifnet *ifp;
934 struct ieee80211com *ic;
935 struct ieee80211_channel *c;
936 int i, flags;
938 ifp = sc->ifp;
939 ic = ifp->if_l2com;
941 /* set supported channels for 2GHz band */
943 for (i = 1; i <= 14; i++)
945 c = &ic->ic_channels[ic->ic_nchans++];
946 flags = IEEE80211_CHAN_B;
948 c->ic_freq = ieee80211_ieee2mhz(i, flags);
949 c->ic_ieee = i;
950 c->ic_flags = flags;
952 c = &ic->ic_channels[ic->ic_nchans++];
953 flags = IEEE80211_CHAN_B | IEEE80211_CHAN_HT20;
955 c->ic_freq = ieee80211_ieee2mhz(i, flags);
956 c->ic_ieee = i;
957 c->ic_flags = flags;
959 c = &ic->ic_channels[ic->ic_nchans++];
960 flags = IEEE80211_CHAN_G;
962 c->ic_freq = ieee80211_ieee2mhz(i, flags);
963 c->ic_ieee = i;
964 c->ic_flags = flags;
966 c = &ic->ic_channels[ic->ic_nchans++];
967 flags = IEEE80211_CHAN_G | IEEE80211_CHAN_HT20;
969 c->ic_freq = ieee80211_ieee2mhz(i, flags);
970 c->ic_ieee = i;
971 c->ic_flags = flags;
974 /* set supported channels for 5GHz band */
976 if (sc->rf_rev == RT2870_EEPROM_RF_2850 ||
977 sc->rf_rev == RT2870_EEPROM_RF_2750)
979 for (i = 36; i <= 64; i += 4)
981 c = &ic->ic_channels[ic->ic_nchans++];
982 flags = IEEE80211_CHAN_A;
984 c->ic_freq = ieee80211_ieee2mhz(i, flags);
985 c->ic_ieee = i;
986 c->ic_flags = flags;
988 c = &ic->ic_channels[ic->ic_nchans++];
989 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
991 c->ic_freq = ieee80211_ieee2mhz(i, flags);
992 c->ic_ieee = i;
993 c->ic_flags = flags;
996 for (i = 100; i <= 140; i += 4)
998 c = &ic->ic_channels[ic->ic_nchans++];
999 flags = IEEE80211_CHAN_A;
1001 c->ic_freq = ieee80211_ieee2mhz(i, flags);
1002 c->ic_ieee = i;
1003 c->ic_flags = flags;
1005 c = &ic->ic_channels[ic->ic_nchans++];
1006 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
1008 c->ic_freq = ieee80211_ieee2mhz(i, flags);
1009 c->ic_ieee = i;
1010 c->ic_flags = flags;
1013 for (i = 149; i <= 165; i += 4)
1015 c = &ic->ic_channels[ic->ic_nchans++];
1016 flags = IEEE80211_CHAN_A;
1018 c->ic_freq = ieee80211_ieee2mhz(i, flags);
1019 c->ic_ieee = i;
1020 c->ic_flags = flags;
1022 c = &ic->ic_channels[ic->ic_nchans++];
1023 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
1025 c->ic_freq = ieee80211_ieee2mhz(i, flags);
1026 c->ic_ieee = i;
1027 c->ic_flags = flags;
1033 * rt2870_init_channels_ht40
1035 static void rt2870_init_channels_ht40(struct rt2870_softc *sc)
1037 struct ifnet *ifp;
1038 struct ieee80211com *ic;
1039 struct ieee80211_channel *c, *cent, *ext;
1040 int i, flags;
1042 ifp = sc->ifp;
1043 ic = ifp->if_l2com;
1045 /* set supported channels for 2GHz band */
1047 for (i = 1; i <= 14; i++)
1049 flags = IEEE80211_CHAN_G | IEEE80211_CHAN_HT40;
1051 /* find the center channel */
1053 cent = ieee80211_find_channel_byieee(ic, i,
1054 flags & ~IEEE80211_CHAN_HT);
1055 if (cent == NULL)
1057 printf("%s: skip channel %d, could not find center channel\n",
1058 device_get_nameunit(sc->dev), i);
1059 continue;
1062 /* find the extension channel */
1064 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1065 flags & ~IEEE80211_CHAN_HT);
1066 if (ext == NULL)
1068 printf("%s: skip channel %d, could not find extension channel\n",
1069 device_get_nameunit(sc->dev), i);
1070 continue;
1073 c = &ic->ic_channels[ic->ic_nchans++];
1075 *c = *cent;
1076 c->ic_extieee = ext->ic_ieee;
1077 c->ic_flags &= ~IEEE80211_CHAN_HT;
1078 c->ic_flags |= IEEE80211_CHAN_HT40U;
1080 c = &ic->ic_channels[ic->ic_nchans++];
1082 *c = *ext;
1083 c->ic_extieee = cent->ic_ieee;
1084 c->ic_flags &= ~IEEE80211_CHAN_HT;
1085 c->ic_flags |= IEEE80211_CHAN_HT40D;
1088 /* set supported channels for 5GHz band */
1090 if (sc->rf_rev == RT2870_EEPROM_RF_2850 ||
1091 sc->rf_rev == RT2870_EEPROM_RF_2750)
1093 for (i = 36; i <= 64; i += 4)
1095 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
1097 /* find the center channel */
1099 cent = ieee80211_find_channel_byieee(ic, i,
1100 flags & ~IEEE80211_CHAN_HT);
1101 if (cent == NULL)
1103 printf("%s: skip channel %d, could not find center channel\n",
1104 device_get_nameunit(sc->dev), i);
1105 continue;
1108 /* find the extension channel */
1110 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1111 flags & ~IEEE80211_CHAN_HT);
1112 if (ext == NULL)
1114 printf("%s: skip channel %d, could not find extension channel\n",
1115 device_get_nameunit(sc->dev), i);
1116 continue;
1119 c = &ic->ic_channels[ic->ic_nchans++];
1121 *c = *cent;
1122 c->ic_extieee = ext->ic_ieee;
1123 c->ic_flags &= ~IEEE80211_CHAN_HT;
1124 c->ic_flags |= IEEE80211_CHAN_HT40U;
1126 c = &ic->ic_channels[ic->ic_nchans++];
1128 *c = *ext;
1129 c->ic_extieee = cent->ic_ieee;
1130 c->ic_flags &= ~IEEE80211_CHAN_HT;
1131 c->ic_flags |= IEEE80211_CHAN_HT40D;
1134 for (i = 100; i <= 140; i += 4)
1136 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
1138 /* find the center channel */
1140 cent = ieee80211_find_channel_byieee(ic, i,
1141 flags & ~IEEE80211_CHAN_HT);
1142 if (cent == NULL)
1144 printf("%s: skip channel %d, could not find center channel\n",
1145 device_get_nameunit(sc->dev), i);
1146 continue;
1149 /* find the extension channel */
1151 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1152 flags & ~IEEE80211_CHAN_HT);
1153 if (ext == NULL)
1155 printf("%s: skip channel %d, could not find extension channel\n",
1156 device_get_nameunit(sc->dev), i);
1157 continue;
1160 c = &ic->ic_channels[ic->ic_nchans++];
1162 *c = *cent;
1163 c->ic_extieee = ext->ic_ieee;
1164 c->ic_flags &= ~IEEE80211_CHAN_HT;
1165 c->ic_flags |= IEEE80211_CHAN_HT40U;
1167 c = &ic->ic_channels[ic->ic_nchans++];
1169 *c = *ext;
1170 c->ic_extieee = cent->ic_ieee;
1171 c->ic_flags &= ~IEEE80211_CHAN_HT;
1172 c->ic_flags |= IEEE80211_CHAN_HT40D;
1175 for (i = 149; i <= 165; i += 4)
1177 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
1179 /* find the center channel */
1181 cent = ieee80211_find_channel_byieee(ic, i,
1182 flags & ~IEEE80211_CHAN_HT);
1183 if (cent == NULL)
1185 printf("%s: skip channel %d, could not find center channel\n",
1186 device_get_nameunit(sc->dev), i);
1187 continue;
1190 /* find the extension channel */
1192 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1193 flags & ~IEEE80211_CHAN_HT);
1194 if (ext == NULL)
1196 printf("%s: skip channel %d, could not find extension channel\n",
1197 device_get_nameunit(sc->dev), i);
1198 continue;
1201 c = &ic->ic_channels[ic->ic_nchans++];
1203 *c = *cent;
1204 c->ic_extieee = ext->ic_ieee;
1205 c->ic_flags &= ~IEEE80211_CHAN_HT;
1206 c->ic_flags |= IEEE80211_CHAN_HT40U;
1208 c = &ic->ic_channels[ic->ic_nchans++];
1210 *c = *ext;
1211 c->ic_extieee = cent->ic_ieee;
1212 c->ic_flags &= ~IEEE80211_CHAN_HT;
1213 c->ic_flags |= IEEE80211_CHAN_HT40D;
1219 * rt2870_init_locked
1221 static void rt2870_init_locked(void *priv)
1223 struct rt2870_softc *sc;
1224 struct ifnet *ifp;
1225 struct ieee80211com *ic;
1226 int ntries, error, i;
1227 uint32_t tmp, stacnt[6];
1229 sc = priv;
1230 ifp = sc->ifp;
1231 ic = ifp->if_l2com;
1233 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1234 "%s: initializing\n",
1235 device_get_nameunit(sc->dev));
1237 RT2870_SOFTC_ASSERT_LOCKED(sc);
1239 if (!(sc->flags & RT2870_SOFTC_FLAGS_UCODE_LOADED))
1241 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1242 "%s: loading 8051 microcode\n",
1243 device_get_nameunit(sc->dev));
1245 error = rt2870_io_mcu_load_ucode(sc, rt2870_ucode, sizeof(rt2870_ucode));
1246 if (error != 0)
1248 printf("%s: could not load 8051 microcode\n",
1249 device_get_nameunit(sc->dev));
1250 goto fail;
1253 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1254 "%s: 8051 microcode was successfully loaded\n",
1255 device_get_nameunit(sc->dev));
1257 sc->flags |= RT2870_SOFTC_FLAGS_UCODE_LOADED;
1260 /* wait while DMA engine is busy */
1262 for (ntries = 0; ntries < 100; ntries++)
1264 tmp = rt2870_io_mac_read(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG);
1265 if (!(tmp & (RT2870_REG_TX_DMA_BUSY | RT2870_REG_RX_DMA_BUSY)))
1266 break;
1268 DELAY(1000);
1271 if (ntries == 100)
1273 printf("%s: timeout waiting for DMA engine\n",
1274 device_get_nameunit(sc->dev));
1275 goto fail;
1278 tmp &= 0xff0;
1279 tmp |= RT2870_REG_TX_WB_DDONE;
1281 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
1283 /* PBF hardware reset */
1285 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_SYS_CTRL);
1287 tmp &= ~(1 << 13);
1289 rt2870_io_mac_write(sc, RT2870_REG_PBF_SYS_CTRL, tmp);
1291 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL,
1292 RT2870_REG_MAC_SRST | RT2870_REG_BBP_HRST);
1294 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_DMA_CFG, 0);
1296 rt2870_io_mcu_reset(sc);
1298 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, 0);
1300 /* init Tx power per rate */
1302 for (i = 0; i < RT2870_SOFTC_TXPOW_RATE_COUNT; i++)
1304 if (sc->txpow_rate_20mhz[i] == 0xffffffff)
1305 continue;
1307 rt2870_io_mac_write(sc, RT2870_REG_TX_PWR_CFG(i),
1308 sc->txpow_rate_20mhz[i]);
1311 for (i = 0; i < RT2870_DEF_MAC_SIZE; i++)
1312 rt2870_io_mac_write(sc, rt2870_def_mac[i].reg,
1313 rt2870_def_mac[i].val);
1315 /* wait while MAC is busy */
1317 for (ntries = 0; ntries < 100; ntries++)
1319 if (!(rt2870_io_mac_read(sc, RT2870_REG_STATUS_CFG) &
1320 (RT2870_REG_STATUS_TX_BUSY | RT2870_REG_STATUS_RX_BUSY)))
1321 break;
1323 DELAY(1000);
1326 if (ntries == 100)
1328 printf("%s: timeout waiting for MAC\n",
1329 device_get_nameunit(sc->dev));
1330 goto fail;
1333 /* clear Host to MCU mailbox */
1335 rt2870_io_mac_write(sc, RT2870_REG_H2M_MAILBOX_BBP_AGENT, 0);
1336 rt2870_io_mac_write(sc, RT2870_REG_H2M_MAILBOX, 0);
1338 DELAY(1000);
1340 error = rt2870_init_bbp(sc);
1341 if (error != 0)
1342 goto fail;
1344 /* set up maximum buffer sizes */
1346 tmp = (1 << 12) | RT2870_MAX_AGG_SIZE;
1348 rt2870_io_mac_write(sc, RT2870_REG_MAX_LEN_CFG, tmp);
1350 if (sc->mac_rev == 0x28720200)
1352 /* set max. PSDU length from 16K to 32K bytes */
1354 tmp = rt2870_io_mac_read(sc, RT2870_REG_MAX_LEN_CFG);
1356 tmp &= ~(3 << 12);
1357 tmp |= (2 << 12);
1359 rt2870_io_mac_write(sc, RT2870_REG_MAX_LEN_CFG, tmp);
1362 if (sc->mac_rev >= 0x28720200 && sc->mac_rev < 0x30700200)
1364 tmp = rt2870_io_mac_read(sc, RT2870_REG_MAX_LEN_CFG);
1366 tmp &= 0xfff;
1367 tmp |= 0x2000;
1369 rt2870_io_mac_write(sc, RT2870_REG_MAX_LEN_CFG, tmp);
1372 /* set mac address */
1374 rt2870_asic_set_macaddr(sc, IF_LLADDR(ifp));
1376 /* clear statistic registers */
1378 rt2870_io_mac_read_multi(sc, RT2870_REG_RX_STA_CNT0,
1379 stacnt, sizeof(stacnt));
1381 /* send LEDs operating mode to microcontroller */
1383 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_LED1,
1384 RT2870_REG_H2M_TOKEN_NO_INTR, sc->led_off[0]);
1385 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_LED2,
1386 RT2870_REG_H2M_TOKEN_NO_INTR, sc->led_off[1]);
1387 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_LED3,
1388 RT2870_REG_H2M_TOKEN_NO_INTR, sc->led_off[2]);
1390 /* write vendor-specific BBP values (from EEPROM) */
1392 for (i = 0; i < RT2870_SOFTC_BBP_EEPROM_COUNT; i++)
1394 if (sc->bbp_eeprom[i].reg == 0x00 ||
1395 sc->bbp_eeprom[i].reg == 0xff)
1396 continue;
1398 rt2870_io_bbp_write(sc, sc->bbp_eeprom[i].reg,
1399 sc->bbp_eeprom[i].val);
1402 /* disable non-existing Rx chains */
1404 tmp = rt2870_io_bbp_read(sc, 3);
1406 tmp &= ~((1 << 4) | (1 << 3));
1408 if (sc->nrxpath == 3)
1409 tmp |= (1 << 4);
1410 else if (sc->nrxpath == 2)
1411 tmp |= (1 << 3);
1413 rt2870_io_bbp_write(sc, 3, tmp);
1415 /* disable non-existing Tx chains */
1417 tmp = rt2870_io_bbp_read(sc, 1);
1419 tmp &= ~((1 << 4) | (1 << 3));
1421 if (sc->ntxpath == 2)
1422 tmp |= (1 << 4);
1424 rt2870_io_bbp_write(sc, 1, tmp);
1426 /* set current channel */
1428 rt2870_rf_set_chan(sc, ic->ic_curchan);
1430 /* turn radio LED on */
1432 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_ON);
1434 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_BOOT,
1435 RT2870_REG_H2M_TOKEN_NO_INTR, 0);
1437 /* set RTS threshold */
1439 rt2870_asic_update_rtsthreshold(sc);
1441 /* set Tx power */
1443 rt2870_asic_update_txpower(sc);
1445 /* set up protection mode */
1447 sc->tx_ampdu_sessions = 0;
1449 rt2870_asic_updateprot(sc);
1451 /* clear beacon frame space (entries = 8, entry size = 512) */
1453 rt2870_io_mac_set_region_4(sc, RT2870_REG_BEACON_BASE(0), 0, 1024);
1455 if (rt2870_txrx_enable(sc) != 0)
1456 goto fail;
1458 /* clear garbage interrupts */
1460 tmp = rt2870_io_mac_read(sc, 0x1300);
1462 taskqueue_unblock(sc->taskqueue);
1464 /* init Tx and Rx rings */
1466 for(i = 0; i < sc->usb_endpoints - 1; i++)
1467 rt2870_reset_tx_ring(sc, &sc->tx_ring[i]);
1469 rt2870_reset_rx_ring(sc, &sc->rx_ring);
1471 for(i = 0; i < sc->usb_endpoints - 1; i++)
1473 usbd_xfer_set_priv(sc->usb_xfer[i + 1], &sc->tx_ring[i]);
1474 usbd_xfer_set_stall(sc->usb_xfer[i + 1]);
1477 /* start up the receive pipe */
1479 for(i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
1480 usbd_transfer_start(sc->usb_xfer[0]);
1482 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1483 ifp->if_drv_flags |= IFF_DRV_RUNNING;
1485 sc->periodic_round = 0;
1487 callout_reset(&sc->periodic_ch, hz / 10, rt2870_periodic, sc);
1489 return;
1491 fail:
1493 rt2870_stop_locked(sc);
1497 * rt2870_init
1499 static void rt2870_init(void *priv)
1501 struct rt2870_softc *sc;
1503 sc = priv;
1505 RT2870_SOFTC_LOCK(sc);
1507 rt2870_init_locked(sc);
1509 RT2870_SOFTC_UNLOCK(sc);
1513 * rt2870_init_bbp
1515 static int rt2870_init_bbp(struct rt2870_softc *sc)
1517 int ntries, i;
1518 uint8_t tmp;
1520 for (ntries = 0; ntries < 20; ntries++)
1522 tmp = rt2870_io_bbp_read(sc, 0);
1523 if (tmp != 0x00 && tmp != 0xff)
1524 break;
1527 if (tmp == 0x00 || tmp == 0xff)
1529 printf("%s: timeout waiting for BBP to wakeup\n",
1530 device_get_nameunit(sc->dev));
1531 return ETIMEDOUT;
1534 for (i = 0; i < RT2870_DEF_BBP_SIZE; i++)
1535 rt2870_io_bbp_write(sc, rt2870_def_bbp[i].reg,
1536 rt2870_def_bbp[i].val);
1538 if ((sc->mac_rev & 0xffff) != 0x0101)
1539 rt2870_io_bbp_write(sc, 84, 0x19);
1541 if (sc->mac_rev == 0x28600100)
1543 rt2870_io_bbp_write(sc, 69, 0x16);
1544 rt2870_io_bbp_write(sc, 73, 0x12);
1547 return 0;
1551 * rt2870_stop_locked
1553 static void rt2870_stop_locked(void *priv)
1555 struct rt2870_softc *sc;
1556 struct ifnet *ifp;
1557 struct ieee80211com *ic;
1558 uint32_t tmp;
1559 int i;
1561 sc = priv;
1562 ifp = sc->ifp;
1563 ic = ifp->if_l2com;
1565 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1566 "%s: stopping\n",
1567 device_get_nameunit(sc->dev));
1569 RT2870_SOFTC_ASSERT_LOCKED(sc);
1571 sc->tx_timer = 0;
1573 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1574 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_OFF);
1576 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1578 callout_stop(&sc->periodic_ch);
1579 callout_stop(&sc->tx_watchdog_ch);
1581 RT2870_SOFTC_UNLOCK(sc);
1583 taskqueue_block(sc->taskqueue);
1585 taskqueue_drain(sc->taskqueue, &sc->rx_done_task);
1586 taskqueue_drain(sc->taskqueue, &sc->tx_done_task);
1587 taskqueue_drain(sc->taskqueue, &sc->periodic_task);
1588 taskqueue_drain(sc->taskqueue, &sc->cmd_task);
1590 RT2870_SOFTC_LOCK(sc);
1592 /* clear key tables */
1594 rt2870_asic_clear_keytables(sc);
1596 /* disable Tx/Rx */
1598 tmp = rt2870_io_mac_read(sc, RT2870_REG_SYS_CTRL);
1600 tmp &= ~(RT2870_REG_RX_ENABLE | RT2870_REG_TX_ENABLE);
1602 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, tmp);
1604 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_DMA_CFG, 0);
1606 /* reset adapter */
1608 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL,
1609 RT2870_REG_MAC_SRST | RT2870_REG_BBP_HRST);
1610 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, 0);
1612 /* abort any pending transfers */
1614 for (i = 0; i < sc->usb_endpoints; i++)
1615 usbd_transfer_stop(sc->usb_xfer[i]);
1617 rt2870_reset_cmd_ring(sc, &sc->cmd_ring);
1621 * rt2870_stop
1623 static void rt2870_stop(void *priv)
1625 struct rt2870_softc *sc;
1627 sc = priv;
1629 RT2870_SOFTC_LOCK(sc);
1631 rt2870_stop_locked(sc);
1633 RT2870_SOFTC_UNLOCK(sc);
1637 * rt2870_start
1639 static void rt2870_start(struct ifnet *ifp)
1641 struct rt2870_softc *sc;
1642 struct ieee80211_node *ni;
1643 struct mbuf *m;
1644 int qid;
1646 sc = ifp->if_softc;
1648 RT2870_SOFTC_LOCK(sc);
1650 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1652 RT2870_SOFTC_UNLOCK(sc);
1653 return;
1656 for (;;)
1658 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1659 if (m == NULL)
1660 break;
1662 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1664 m->m_pkthdr.rcvif = NULL;
1666 qid = M_WME_GETAC(m);
1668 if (sc->tx_ring[qid].queued >= RT2870_SOFTC_TX_RING_DATA_COUNT)
1670 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
1671 "%s: if_start: Tx ring with qid=%d is full\n",
1672 device_get_nameunit(sc->dev), qid);
1674 m_freem(m);
1675 ieee80211_free_node(ni);
1677 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1678 ifp->if_oerrors++;
1680 sc->tx_data_queue_full[qid]++;
1682 break;
1685 if (rt2870_tx_data(sc, m, ni, qid) != 0)
1687 ieee80211_free_node(ni);
1688 ifp->if_oerrors++;
1689 break;
1692 sc->tx_timer = RT2870_TX_WATCHDOG_TIMEOUT;
1694 callout_reset(&sc->tx_watchdog_ch, hz, rt2870_tx_watchdog, sc);
1697 RT2870_SOFTC_UNLOCK(sc);
1701 * rt2870_ioctl
1703 static int rt2870_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1705 struct rt2870_softc *sc;
1706 struct ieee80211com *ic;
1707 struct ifreq *ifr;
1708 int error, startall;
1710 sc = ifp->if_softc;
1711 ic = ifp->if_l2com;
1712 ifr = (struct ifreq *) data;
1714 error = 0;
1716 switch (cmd)
1718 case SIOCSIFFLAGS:
1719 startall = 0;
1721 RT2870_SOFTC_LOCK(sc);
1723 if (ifp->if_flags & IFF_UP)
1725 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1727 if ((ifp->if_flags ^ sc->if_flags) & IFF_PROMISC)
1728 rt2870_asic_update_promisc(sc);
1730 else
1732 rt2870_init_locked(sc);
1733 startall = 1;
1736 else
1738 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1739 rt2870_stop_locked(sc);
1742 sc->if_flags = ifp->if_flags;
1744 RT2870_SOFTC_UNLOCK(sc);
1746 if (startall)
1747 ieee80211_start_all(ic);
1748 break;
1750 case SIOCGIFMEDIA:
1751 case SIOCSIFMEDIA:
1752 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1753 break;
1755 case SIOCGIFADDR:
1756 error = ether_ioctl(ifp, cmd, data);
1757 break;
1759 default:
1760 error = EINVAL;
1761 break;
1764 return error;
1768 * rt2870_vap_create
1770 static struct ieee80211vap *rt2870_vap_create(struct ieee80211com *ic,
1771 const char name[IFNAMSIZ], int unit, int opmode, int flags,
1772 const uint8_t bssid[IEEE80211_ADDR_LEN],
1773 const uint8_t mac[IEEE80211_ADDR_LEN])
1775 struct rt2870_softc *sc;
1776 struct ifnet *ifp;
1777 struct rt2870_softc_vap *rvap;
1778 struct ieee80211vap *vap;
1780 ifp = ic->ic_ifp;
1781 sc = ifp->if_softc;
1783 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
1784 "%s: VAP create: opmode=%s\n",
1785 device_get_nameunit(sc->dev),
1786 ieee80211_opmode_name[opmode]);
1788 switch (opmode)
1790 case IEEE80211_M_IBSS:
1791 case IEEE80211_M_STA:
1792 case IEEE80211_M_AHDEMO:
1793 case IEEE80211_M_HOSTAP:
1794 case IEEE80211_M_MBSS:
1795 if ((sc->napvaps + sc->nadhocvaps + sc->nstavaps) != 0)
1797 if_printf(ifp, "only 1 VAP supported\n");
1798 return NULL;
1801 if (opmode == IEEE80211_M_STA)
1802 flags |= IEEE80211_CLONE_NOBEACONS;
1803 break;
1805 case IEEE80211_M_WDS:
1806 if (sc->napvaps == 0)
1808 if_printf(ifp, "WDS only supported in AP mode\n");
1809 return NULL;
1811 break;
1813 case IEEE80211_M_MONITOR:
1814 break;
1816 default:
1817 if_printf(ifp, "unknown opmode %d\n", opmode);
1818 return NULL;
1821 rvap = (struct rt2870_softc_vap *) malloc(sizeof(struct rt2870_softc_vap),
1822 M_80211_VAP, M_NOWAIT | M_ZERO);
1823 if (rvap == NULL)
1824 return NULL;
1826 vap = &rvap->vap;
1828 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
1830 rvap->newstate = vap->iv_newstate;
1831 vap->iv_newstate = rt2870_vap_newstate;
1833 vap->iv_reset = rt2870_vap_reset;
1834 vap->iv_key_update_begin = rt2870_vap_key_update_begin;
1835 vap->iv_key_update_end = rt2870_vap_key_update_end;
1836 vap->iv_key_set = rt2870_vap_key_set;
1837 vap->iv_key_delete = rt2870_vap_key_delete;
1838 vap->iv_update_beacon = rt2870_vap_update_beacon;
1840 rt2870_amrr_init(&rvap->amrr, vap,
1841 sc->ntxpath,
1842 RT2870_AMRR_MIN_SUCCESS_THRESHOLD,
1843 RT2870_AMRR_MAX_SUCCESS_THRESHOLD,
1844 500);
1846 vap->iv_max_aid = RT2870_SOFTC_STAID_COUNT;
1848 /* overwrite default Rx A-MPDU factor */
1850 vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_32K;
1851 vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_NA;
1852 vap->iv_ampdu_limit = vap->iv_ampdu_rxmax;
1854 ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
1856 switch (vap->iv_opmode)
1858 case IEEE80211_M_HOSTAP:
1859 case IEEE80211_M_MBSS:
1860 case IEEE80211_M_AHDEMO:
1861 sc->napvaps++;
1862 break;
1864 case IEEE80211_M_IBSS:
1865 sc->nadhocvaps++;
1866 break;
1868 case IEEE80211_M_STA:
1869 sc->nstavaps++;
1870 break;
1872 case IEEE80211_M_WDS:
1873 sc->nwdsvaps++;
1874 break;
1876 default:
1877 break;
1880 sc->nvaps++;
1882 if (sc->napvaps > 0)
1883 ic->ic_opmode = IEEE80211_M_HOSTAP;
1884 else if (sc->nadhocvaps > 0)
1885 ic->ic_opmode = IEEE80211_M_IBSS;
1886 else if (sc->nstavaps > 0)
1887 ic->ic_opmode = IEEE80211_M_STA;
1888 else
1889 ic->ic_opmode = opmode;
1891 return vap;
1895 * rt2870_vap_delete
1897 static void rt2870_vap_delete(struct ieee80211vap *vap)
1899 struct rt2870_softc *sc;
1900 struct ieee80211com *ic;
1901 struct ifnet *ifp;
1902 struct rt2870_softc_vap *rvap;
1903 enum ieee80211_opmode opmode;
1905 ic = vap->iv_ic;
1906 ifp = ic->ic_ifp;
1907 sc = ifp->if_softc;
1908 rvap = (struct rt2870_softc_vap *) vap;
1909 opmode = vap->iv_opmode;
1911 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
1912 "%s: VAP delete: opmode=%s\n",
1913 device_get_nameunit(sc->dev),
1914 ieee80211_opmode_name[opmode]);
1916 rt2870_amrr_cleanup(&rvap->amrr);
1918 ieee80211_vap_detach(vap);
1920 if (rvap->beacon_mbuf != NULL)
1922 m_free(rvap->beacon_mbuf);
1923 rvap->beacon_mbuf = NULL;
1926 switch (opmode)
1928 case IEEE80211_M_HOSTAP:
1929 case IEEE80211_M_MBSS:
1930 case IEEE80211_M_AHDEMO:
1931 sc->napvaps--;
1932 break;
1934 case IEEE80211_M_IBSS:
1935 sc->nadhocvaps--;
1936 break;
1938 case IEEE80211_M_STA:
1939 sc->nstavaps--;
1940 break;
1942 case IEEE80211_M_WDS:
1943 sc->nwdsvaps--;
1944 break;
1946 default:
1947 break;
1950 sc->nvaps--;
1952 if (sc->napvaps > 0)
1953 ic->ic_opmode = IEEE80211_M_HOSTAP;
1954 else if (sc->nadhocvaps > 0)
1955 ic->ic_opmode = IEEE80211_M_IBSS;
1956 else if (sc->nstavaps > 0)
1957 ic->ic_opmode = IEEE80211_M_STA;
1959 free(rvap, M_80211_VAP);
1963 * rt2870_reset_vap
1965 static int rt2870_vap_reset(struct ieee80211vap *vap, u_long cmd)
1967 struct rt2870_softc *sc;
1968 struct ieee80211com *ic;
1969 struct ifnet *ifp;
1970 struct rt2870_softc_vap *rvap;
1971 int error;
1973 ic = vap->iv_ic;
1974 ifp = ic->ic_ifp;
1975 sc = ifp->if_softc;
1976 rvap = (struct rt2870_softc_vap *) vap;
1978 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
1979 "%s: VAP reset: cmd=%lu\n",
1980 device_get_nameunit(sc->dev), cmd);
1982 error = 0;
1984 RT2870_SOFTC_LOCK(sc);
1986 switch (cmd)
1988 case IEEE80211_IOC_RTSTHRESHOLD:
1989 case IEEE80211_IOC_AMSDU:
1990 rt2870_asic_update_rtsthreshold(sc);
1991 break;
1993 case IEEE80211_IOC_PROTMODE:
1994 case IEEE80211_IOC_HTPROTMODE:
1995 rt2870_asic_updateprot(sc);
1996 break;
1998 case IEEE80211_IOC_TXPOWER:
1999 rt2870_asic_update_txpower(sc);
2000 break;
2002 case IEEE80211_IOC_BURST:
2003 rt2870_asic_updateslot(sc);
2004 break;
2006 case IEEE80211_IOC_SHORTGI:
2007 case IEEE80211_IOC_AMPDU_DENSITY:
2008 case IEEE80211_IOC_SMPS:
2009 break;
2011 default:
2012 error = ENETRESET;
2013 break;
2016 RT2870_SOFTC_UNLOCK(sc);
2018 return error;
2022 * rt2870_vap_newstate
2024 static int rt2870_vap_newstate(struct ieee80211vap *vap,
2025 enum ieee80211_state nstate, int arg)
2027 struct rt2870_softc *sc;
2028 struct ieee80211com *ic;
2029 struct ifnet *ifp;
2030 struct rt2870_softc_vap *rvap;
2031 struct ieee80211_node *ni;
2032 int error;
2034 ic = vap->iv_ic;
2035 ifp = ic->ic_ifp;
2036 sc = ifp->if_softc;
2037 rvap = (struct rt2870_softc_vap *) vap;
2039 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
2040 "%s: VAP newstate: %s -> %s\n",
2041 device_get_nameunit(sc->dev),
2042 ieee80211_state_name[vap->iv_state], ieee80211_state_name[nstate]);
2044 error = rvap->newstate(vap, nstate, arg);
2045 if (error != 0)
2046 return error;
2048 IEEE80211_UNLOCK(ic);
2050 RT2870_SOFTC_LOCK(sc);
2052 /* turn link LED off */
2054 if (nstate != IEEE80211_S_RUN)
2055 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_OFF);
2057 switch (nstate)
2059 case IEEE80211_S_INIT:
2060 rt2870_asic_disable_tsf_sync(sc);
2061 break;
2063 case IEEE80211_S_RUN:
2064 ni = vap->iv_bss;
2066 rt2870_rf_set_chan(sc, ni->ni_chan);
2068 if (vap->iv_opmode != IEEE80211_M_MONITOR)
2070 rt2870_asic_enable_mrr(sc);
2071 rt2870_asic_set_txpreamble(sc);
2072 rt2870_asic_set_basicrates(sc);
2073 rt2870_asic_update_txpower(sc);
2074 rt2870_asic_set_bssid(sc, ni->ni_bssid);
2077 if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
2078 vap->iv_opmode == IEEE80211_M_IBSS ||
2079 vap->iv_opmode == IEEE80211_M_MBSS)
2081 error = rt2870_beacon_alloc(sc, vap);
2082 if (error != 0)
2083 break;
2085 rt2870_asic_update_beacon(sc, vap);
2088 if (vap->iv_opmode != IEEE80211_M_MONITOR)
2089 rt2870_asic_enable_tsf_sync(sc);
2091 /* turn link LED on */
2093 if (vap->iv_opmode != IEEE80211_M_MONITOR)
2095 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_ON |
2096 (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) ?
2097 RT2870_LED_CMD_LINK_2GHZ : RT2870_LED_CMD_LINK_5GHZ));
2099 break;
2101 default:
2102 break;
2105 RT2870_SOFTC_UNLOCK(sc);
2107 IEEE80211_LOCK(ic);
2109 return error;
2113 * rt2870_vap_key_update_begin
2115 static void rt2870_vap_key_update_begin(struct ieee80211vap *vap)
2117 struct rt2870_softc *sc;
2118 struct ieee80211com *ic;
2119 struct ifnet *ifp;
2121 ic = vap->iv_ic;
2122 ifp = ic->ic_ifp;
2123 sc = ifp->if_softc;
2125 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
2126 "%s: VAP key update begin\n",
2127 device_get_nameunit(sc->dev));
2129 taskqueue_block(sc->taskqueue);
2131 IF_LOCK(&ifp->if_snd);
2135 * rt2870_vap_key_update_end
2137 static void rt2870_vap_key_update_end(struct ieee80211vap *vap)
2139 struct rt2870_softc *sc;
2140 struct ieee80211com *ic;
2141 struct ifnet *ifp;
2143 ic = vap->iv_ic;
2144 ifp = ic->ic_ifp;
2145 sc = ifp->if_softc;
2147 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
2148 "%s: VAP key update end\n",
2149 device_get_nameunit(sc->dev));
2151 IF_UNLOCK(&ifp->if_snd);
2153 taskqueue_unblock(sc->taskqueue);
2157 * rt2870_vap_key_set
2159 static int rt2870_vap_key_set(struct ieee80211vap *vap,
2160 const struct ieee80211_key *k, const uint8_t mac[IEEE80211_ADDR_LEN])
2162 struct rt2870_softc *sc;
2163 struct ieee80211com *ic;
2164 struct ifnet *ifp;
2165 struct ieee80211_node *ni;
2166 struct rt2870_softc_node *rni;
2167 struct rt2870_cmd_argv_keyset cmd_argv;
2169 if (k->wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP &&
2170 k->wk_cipher->ic_cipher != IEEE80211_CIPHER_TKIP &&
2171 k->wk_cipher->ic_cipher != IEEE80211_CIPHER_AES_CCM)
2172 return 0;
2174 ic = vap->iv_ic;
2175 ifp = ic->ic_ifp;
2176 sc = ifp->if_softc;
2178 cmd_argv.opmode = vap->iv_opmode;
2180 memcpy(&cmd_argv.key, k, sizeof(struct ieee80211_key));
2182 if (!(k->wk_flags & IEEE80211_KEY_GROUP))
2184 ni = ieee80211_find_vap_node(&ic->ic_sta, vap, mac);
2185 rni = (struct rt2870_softc_node *) ni;
2187 cmd_argv.staid = rni->staid;
2189 ieee80211_free_node(ni);
2192 rt2870_do_async(sc, rt2870_vap_key_set_cb,
2193 &cmd_argv, sizeof(struct rt2870_cmd_argv_keyset));
2195 return 1;
2199 * rt2870_vap_key_delete
2201 static int rt2870_vap_key_delete(struct ieee80211vap *vap,
2202 const struct ieee80211_key *k)
2204 struct rt2870_softc *sc;
2205 struct ieee80211com *ic;
2206 struct ifnet *ifp;
2207 struct rt2870_cmd_argv_keydelete cmd_argv;
2209 ic = vap->iv_ic;
2210 ifp = ic->ic_ifp;
2211 sc = ifp->if_softc;
2213 cmd_argv.opmode = vap->iv_opmode;
2215 memcpy(&cmd_argv.key, k, sizeof(struct ieee80211_key));
2217 rt2870_do_async(sc, rt2870_vap_key_delete_cb,
2218 &cmd_argv, sizeof(struct rt2870_cmd_argv_keydelete));
2220 return 1;
2224 * rt2870_vap_update_beacon
2226 static void rt2870_vap_update_beacon(struct ieee80211vap *vap, int what)
2228 struct rt2870_softc *sc;
2229 struct ieee80211com *ic;
2230 struct ifnet *ifp;
2231 struct rt2870_softc_vap *rvap;
2232 struct mbuf *m;
2233 struct ieee80211_beacon_offsets *bo;
2235 ic = vap->iv_ic;
2236 ifp = ic->ic_ifp;
2237 sc = ifp->if_softc;
2238 rvap = (struct rt2870_softc_vap *) vap;
2239 m = rvap->beacon_mbuf;
2240 bo = &rvap->beacon_offsets;
2242 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
2243 "%s: VAP update beacon: what=%d\n",
2244 device_get_nameunit(sc->dev), what);
2246 setbit(bo->bo_flags, what);
2248 ieee80211_beacon_update(vap->iv_bss, bo, m, 0);
2250 rt2870_do_async(sc, rt2870_vap_update_beacon_cb, NULL, 0);
2254 * rt2870_node_alloc
2256 static struct ieee80211_node *rt2870_node_alloc(struct ieee80211vap *vap,
2257 const uint8_t mac[IEEE80211_ADDR_LEN])
2259 return malloc(sizeof(struct rt2870_softc_node),
2260 M_80211_NODE, M_NOWAIT | M_ZERO);
2264 * rt2870_node_cleanup
2266 static void rt2870_node_cleanup(struct ieee80211_node *ni)
2268 struct rt2870_softc *sc;
2269 struct ieee80211com *ic;
2270 struct ifnet *ifp;
2271 struct rt2870_softc_node *rni;
2272 struct rt2870_cmd_argv_nodecleanup cmd_argv;
2274 ic = ni->ni_ic;
2275 ifp = ic->ic_ifp;
2276 sc = ifp->if_softc;
2277 rni = (struct rt2870_softc_node *) ni;
2279 RT2870_DPRINTF(sc, RT2870_DEBUG_NODE,
2280 "%s: node cleanup: macaddr=%s, associd=0x%04x, staid=0x%02x\n",
2281 device_get_nameunit(sc->dev), ether_sprintf(ni->ni_macaddr),
2282 ni->ni_associd, rni->staid);
2284 if (rni->staid != 0)
2286 cmd_argv.staid = rni->staid;
2288 rni->staid = 0;
2290 rt2870_do_async(sc, rt2870_node_cleanup_cb,
2291 &cmd_argv, sizeof(struct rt2870_cmd_argv_nodecleanup));
2294 sc->node_cleanup(ni);
2298 * rt2870_node_getmimoinfo
2300 static void rt2870_node_getmimoinfo(const struct ieee80211_node *ni,
2301 struct ieee80211_mimo_info *mi)
2303 const struct rt2870_softc_node *rni;
2304 int i;
2306 rni = (const struct rt2870_softc_node *) ni;
2308 for (i = 0; i < RT2870_SOFTC_RSSI_COUNT; i++)
2310 mi->rssi[i] = rni->last_rssi_dbm[i];
2311 mi->noise[i] = RT2870_NOISE_FLOOR;
2316 * rt2870_setregdomain
2318 static int rt2870_setregdomain(struct ieee80211com *ic,
2319 struct ieee80211_regdomain *reg,
2320 int nchans, struct ieee80211_channel chans[])
2322 struct rt2870_softc *sc;
2323 struct ifnet *ifp;
2325 ifp = ic->ic_ifp;
2326 sc = ifp->if_softc;
2328 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
2329 "%s: set regulatory domain: country=%d, country code string=%c%c, location=%c\n",
2330 device_get_nameunit(sc->dev),
2331 reg->country, reg->isocc[0], reg->isocc[1], reg->location);
2333 return 0;
2337 * rt2870_getradiocaps
2339 static void rt2870_getradiocaps(struct ieee80211com *ic,
2340 int maxchans, int *nchans, struct ieee80211_channel chans[])
2342 *nchans = (ic->ic_nchans >= maxchans) ? maxchans : ic->ic_nchans;
2344 memcpy(chans, ic->ic_channels, (*nchans) * sizeof(struct ieee80211_channel));
2348 * rt2870_scan_start
2350 static void rt2870_scan_start(struct ieee80211com *ic)
2352 struct rt2870_softc *sc;
2353 struct ifnet *ifp;
2355 ifp = ic->ic_ifp;
2356 sc = ifp->if_softc;
2358 if (!(sc->flags & RT2870_SOFTC_FLAGS_VALID))
2359 return;
2361 RT2870_SOFTC_LOCK(sc);
2363 rt2870_asic_disable_tsf_sync(sc);
2365 RT2870_SOFTC_UNLOCK(sc);
2369 * rt2870_scan_end
2371 static void rt2870_scan_end(struct ieee80211com *ic)
2373 struct rt2870_softc *sc;
2374 struct ifnet *ifp;
2376 ifp = ic->ic_ifp;
2377 sc = ifp->if_softc;
2379 if (!(sc->flags & RT2870_SOFTC_FLAGS_VALID))
2380 return;
2382 RT2870_SOFTC_LOCK(sc);
2384 rt2870_asic_enable_tsf_sync(sc);
2386 RT2870_SOFTC_UNLOCK(sc);
2390 * rt2870_set_channel
2392 static void rt2870_set_channel(struct ieee80211com *ic)
2394 struct rt2870_softc *sc;
2395 struct ifnet *ifp;
2397 ifp = ic->ic_ifp;
2398 sc = ifp->if_softc;
2400 if (!(sc->flags & RT2870_SOFTC_FLAGS_VALID))
2401 return;
2403 RT2870_DPRINTF(sc, RT2870_DEBUG_CHAN,
2404 "%s: set channel: channel=%u, HT%s%s\n",
2405 device_get_nameunit(sc->dev),
2406 ieee80211_chan2ieee(ic, ic->ic_curchan),
2407 !IEEE80211_IS_CHAN_HT(ic->ic_curchan) ? " disabled" :
2408 IEEE80211_IS_CHAN_HT20(ic->ic_curchan) ? "20":
2409 IEEE80211_IS_CHAN_HT40U(ic->ic_curchan) ? "40U" : "40D",
2410 (ic->ic_flags & IEEE80211_F_SCAN) ? ", scanning" : "");
2412 RT2870_SOFTC_LOCK(sc);
2414 rt2870_rf_set_chan(sc, ic->ic_curchan);
2416 RT2870_SOFTC_UNLOCK(sc);
2420 * rt2870_newassoc
2422 static void rt2870_newassoc(struct ieee80211_node *ni, int isnew)
2424 struct rt2870_softc *sc;
2425 struct ieee80211com *ic;
2426 struct ifnet *ifp;
2427 struct rt2870_cmd_argv_newassoc cmd_argv;
2429 ic = ni->ni_ic;
2430 ifp = ic->ic_ifp;
2431 sc = ifp->if_softc;
2433 memcpy(cmd_argv.macaddr, ni->ni_macaddr, IEEE80211_ADDR_LEN);
2434 cmd_argv.isnew = isnew;
2436 rt2870_do_async(sc, rt2870_newassoc_cb, &cmd_argv,
2437 sizeof(struct rt2870_cmd_argv_newassoc));
2441 * rt2870_updateslot
2443 static void rt2870_updateslot(struct ifnet *ifp)
2445 struct rt2870_softc *sc;
2447 sc = ifp->if_softc;
2449 rt2870_do_async(sc, rt2870_updateslot_cb, NULL, 0);
2453 * rt2870_update_promisc
2455 static void rt2870_update_promisc(struct ifnet *ifp)
2457 struct rt2870_softc *sc;
2459 sc = ifp->if_softc;
2461 RT2870_SOFTC_LOCK(sc);
2463 rt2870_asic_update_promisc(sc);
2465 RT2870_SOFTC_UNLOCK(sc);
2469 * rt2870_update_mcast
2471 static void rt2870_update_mcast(struct ifnet *ifp)
2473 struct rt2870_softc *sc;
2475 sc = ifp->if_softc;
2479 * rt2870_wme_update
2481 static int rt2870_wme_update(struct ieee80211com *ic)
2483 struct rt2870_softc *sc;
2484 struct ifnet *ifp;
2486 ifp = ic->ic_ifp;
2487 sc = ifp->if_softc;
2489 rt2870_do_async(sc, rt2870_wme_update_cb, NULL, 0);
2491 return 0;
2495 * rt2870_raw_xmit
2497 static int rt2870_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2498 const struct ieee80211_bpf_params *params)
2500 struct rt2870_softc *sc;
2501 struct ieee80211com *ic;
2502 struct ifnet *ifp;
2504 ic = ni->ni_ic;
2505 ifp = ic->ic_ifp;
2506 sc = ifp->if_softc;
2508 RT2870_SOFTC_LOCK(sc);
2510 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
2512 RT2870_SOFTC_UNLOCK(sc);
2514 m_freem(m);
2515 ieee80211_free_node(ni);
2517 return ENETDOWN;
2520 if (sc->tx_ring[sc->tx_ring_mgtqid].queued >= RT2870_SOFTC_TX_RING_DATA_COUNT)
2522 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
2523 "%s: raw xmit: Tx ring with qid=%d is full\n",
2524 device_get_nameunit(sc->dev), sc->tx_ring_mgtqid);
2526 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
2528 RT2870_SOFTC_UNLOCK(sc);
2530 m_freem(m);
2531 ieee80211_free_node(ni);
2533 sc->tx_data_queue_full[sc->tx_ring_mgtqid]++;
2535 return ENOBUFS;
2538 if (rt2870_tx_mgmt(sc, m, ni, sc->tx_ring_mgtqid) != 0)
2540 ifp->if_oerrors++;
2542 RT2870_SOFTC_UNLOCK(sc);
2544 ieee80211_free_node(ni);
2546 return EIO;
2549 sc->tx_timer = RT2870_TX_WATCHDOG_TIMEOUT;
2551 RT2870_SOFTC_UNLOCK(sc);
2553 return 0;
2557 * rt2870_recv_action
2559 static int rt2870_recv_action(struct ieee80211_node *ni,
2560 const struct ieee80211_frame *wh,
2561 const uint8_t *frm, const uint8_t *efrm)
2563 struct rt2870_softc *sc;
2564 struct ieee80211com *ic;
2565 struct ifnet *ifp;
2566 struct rt2870_softc_node *rni;
2567 const struct ieee80211_action *ia;
2568 uint16_t baparamset;
2569 uint8_t wcid;
2570 int tid;
2572 ic = ni->ni_ic;
2573 ifp = ic->ic_ifp;
2574 sc = ifp->if_softc;
2575 rni = (struct rt2870_softc_node *) ni;
2577 ia = (const struct ieee80211_action *) frm;
2579 if (ia->ia_category == IEEE80211_ACTION_CAT_BA)
2581 switch (ia->ia_action)
2583 /* IEEE80211_ACTION_BA_DELBA */
2584 case IEEE80211_ACTION_BA_DELBA:
2585 baparamset = LE_READ_2(frm + 2);
2586 tid = RT2870_MS(baparamset, IEEE80211_BAPS_TID);
2587 wcid = rni->staid;
2589 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2590 "%s: received DELBA request: associd=0x%04x, staid=0x%02x, tid=%d\n",
2591 device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, tid);
2593 if (rni->staid != 0)
2595 RT2870_SOFTC_LOCK(sc);
2597 rt2870_asic_del_ba_session(sc, wcid, tid);
2599 RT2870_SOFTC_UNLOCK(sc);
2601 break;
2605 return sc->recv_action(ni, wh, frm, efrm);
2609 * rt2870_send_action
2611 static int rt2870_send_action(struct ieee80211_node *ni,
2612 int cat, int act, void *sa)
2614 struct rt2870_softc *sc;
2615 struct ieee80211com *ic;
2616 struct ifnet *ifp;
2617 struct rt2870_softc_node *rni;
2618 uint16_t *args, status, baparamset;
2619 uint8_t wcid;
2620 int tid, bufsize;
2622 ic = ni->ni_ic;
2623 ifp = ic->ic_ifp;
2624 sc = ifp->if_softc;
2625 rni = (struct rt2870_softc_node *) ni;
2627 wcid = rni->staid;
2628 args = sa;
2630 if (cat == IEEE80211_ACTION_CAT_BA)
2632 switch (act)
2634 /* IEEE80211_ACTION_BA_ADDBA_RESPONSE */
2635 case IEEE80211_ACTION_BA_ADDBA_RESPONSE:
2636 status = args[1];
2637 baparamset = args[2];
2638 tid = RT2870_MS(baparamset, IEEE80211_BAPS_TID);
2639 bufsize = RT2870_MS(baparamset, IEEE80211_BAPS_BUFSIZ);
2641 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2642 "%s: sending ADDBA response: associd=0x%04x, staid=0x%02x, status=%d, tid=%d, bufsize=%d\n",
2643 device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, status, tid, bufsize);
2645 if (status == IEEE80211_STATUS_SUCCESS)
2647 RT2870_SOFTC_LOCK(sc);
2649 rt2870_asic_add_ba_session(sc, wcid, tid);
2651 RT2870_SOFTC_UNLOCK(sc);
2653 break;
2655 /* IEEE80211_ACTION_BA_DELBA */
2656 case IEEE80211_ACTION_BA_DELBA:
2657 baparamset = RT2870_SM(args[0], IEEE80211_DELBAPS_TID) | args[1];
2658 tid = RT2870_MS(baparamset, IEEE80211_DELBAPS_TID);
2660 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2661 "%s: sending DELBA request: associd=0x%04x, staid=0x%02x, tid=%d\n",
2662 device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, tid);
2664 if (RT2870_MS(baparamset, IEEE80211_DELBAPS_INIT) != IEEE80211_DELBAPS_INIT)
2666 RT2870_SOFTC_LOCK(sc);
2668 rt2870_asic_del_ba_session(sc, wcid, tid);
2670 RT2870_SOFTC_UNLOCK(sc);
2672 break;
2676 return sc->send_action(ni, cat, act, sa);
2681 * rt2870_addba_response
2683 static int rt2870_addba_response(struct ieee80211_node *ni,
2684 struct ieee80211_tx_ampdu *tap,
2685 int status, int baparamset, int batimeout)
2687 struct rt2870_softc *sc;
2688 struct ieee80211com *ic;
2689 struct ifnet *ifp;
2690 struct rt2870_softc_node *rni;
2691 ieee80211_seq seqno;
2692 int ret, tid, old_bufsize, new_bufsize;
2694 ic = ni->ni_ic;
2695 ifp = ic->ic_ifp;
2696 sc = ifp->if_softc;
2697 rni = (struct rt2870_softc_node *) ni;
2699 tid = RT2870_MS(baparamset, IEEE80211_BAPS_TID);
2700 old_bufsize = RT2870_MS(baparamset, IEEE80211_BAPS_BUFSIZ);
2701 new_bufsize = old_bufsize;
2703 if (status == IEEE80211_STATUS_SUCCESS)
2705 if (sc->mac_rev >= 0x28830300)
2707 if (sc->mac_rev >= 0x30700200)
2708 new_bufsize = 13;
2709 else
2710 new_bufsize = 31;
2712 else if (sc->mac_rev >= 0x28720200)
2714 new_bufsize = 13;
2716 else
2718 new_bufsize = 7;
2721 if (old_bufsize > new_bufsize)
2723 baparamset &= ~IEEE80211_BAPS_BUFSIZ;
2724 baparamset = RT2870_SM(new_bufsize, IEEE80211_BAPS_BUFSIZ);
2727 if (!(tap->txa_flags & IEEE80211_AGGR_RUNNING))
2729 sc->tx_ampdu_sessions++;
2731 if (sc->tx_ampdu_sessions == 1)
2733 RT2870_SOFTC_LOCK(sc);
2735 rt2870_asic_updateprot(sc);
2737 RT2870_SOFTC_UNLOCK(sc);
2742 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2743 "%s: received ADDBA response: associd=0x%04x, staid=0x%02x, status=%d, tid=%d, "
2744 "old bufsize=%d, new bufsize=%d\n",
2745 device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, status, tid,
2746 old_bufsize, new_bufsize);
2748 ret = sc->addba_response(ni, tap, status, baparamset, batimeout);
2750 if (status == IEEE80211_STATUS_SUCCESS)
2752 seqno = ni->ni_txseqs[tid];
2754 rt2870_send_bar(ni, tap, seqno);
2757 return ret;
2761 * rt2870_addba_stop
2763 static void rt2870_addba_stop(struct ieee80211_node *ni,
2764 struct ieee80211_tx_ampdu *tap)
2766 struct rt2870_softc *sc;
2767 struct ieee80211com *ic;
2768 struct ifnet *ifp;
2769 struct rt2870_softc_node *rni;
2770 int tid;
2772 ic = ni->ni_ic;
2773 ifp = ic->ic_ifp;
2774 sc = ifp->if_softc;
2775 rni = (struct rt2870_softc_node *) ni;
2777 tid = WME_AC_TO_TID(tap->txa_ac);
2779 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2780 "%s: stopping A-MPDU Tx: associd=0x%04x, staid=0x%02x, tid=%d\n",
2781 device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, tid);
2783 if (tap->txa_flags & IEEE80211_AGGR_RUNNING)
2785 if (sc->tx_ampdu_sessions > 0)
2787 sc->tx_ampdu_sessions--;
2789 if (sc->tx_ampdu_sessions == 0)
2791 RT2870_SOFTC_LOCK(sc);
2793 rt2870_asic_updateprot(sc);
2795 RT2870_SOFTC_UNLOCK(sc);
2798 else
2800 printf("%s: number of A-MPDU Tx sessions cannot be negative\n",
2801 device_get_nameunit(sc->dev));
2805 sc->addba_stop(ni, tap);
2809 * rt2870_ampdu_rx_start
2811 static int rt2870_ampdu_rx_start(struct ieee80211_node *ni,
2812 struct ieee80211_rx_ampdu *rap,
2813 int baparamset, int batimeout, int baseqctl)
2815 struct rt2870_softc *sc;
2816 struct ieee80211com *ic;
2817 struct ifnet *ifp;
2818 struct rt2870_softc_node *rni;
2819 int tid;
2821 ic = ni->ni_ic;
2822 ifp = ic->ic_ifp;
2823 sc = ifp->if_softc;
2824 rni = (struct rt2870_softc_node *) ni;
2826 tid = RT2870_MS(baparamset, IEEE80211_BAPS_TID);
2828 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2829 "%s: starting A-MPDU Rx: associd=0x%04x, staid=0x%02x, tid=%d\n",
2830 device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, tid);
2832 if (!(rap->rxa_flags & IEEE80211_AGGR_RUNNING))
2833 sc->rx_ampdu_sessions++;
2835 return sc->ampdu_rx_start(ni, rap, baparamset, batimeout, baseqctl);
2839 * rt2870_ampdu_rx_stop
2841 static void rt2870_ampdu_rx_stop(struct ieee80211_node *ni,
2842 struct ieee80211_rx_ampdu *rap)
2844 struct rt2870_softc *sc;
2845 struct ieee80211com *ic;
2846 struct ifnet *ifp;
2847 struct rt2870_softc_node *rni;
2849 ic = ni->ni_ic;
2850 ifp = ic->ic_ifp;
2851 sc = ifp->if_softc;
2852 rni = (struct rt2870_softc_node *) ni;
2854 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2855 "%s: stopping A-MPDU Rx: associd=0x%04x, staid=0x%02x\n",
2856 device_get_nameunit(sc->dev), ni->ni_associd, rni->staid);
2858 if (rap->rxa_flags & IEEE80211_AGGR_RUNNING)
2860 if (sc->rx_ampdu_sessions > 0)
2861 sc->rx_ampdu_sessions--;
2862 else
2863 printf("%s: number of A-MPDU Rx sessions cannot be negative\n",
2864 device_get_nameunit(sc->dev));
2867 sc->ampdu_rx_stop(ni, rap);
2871 * rt2870_send_bar
2873 static int rt2870_send_bar(struct ieee80211_node *ni,
2874 struct ieee80211_tx_ampdu *tap, ieee80211_seq seqno)
2876 struct rt2870_softc *sc;
2877 struct ieee80211com *ic;
2878 struct ifnet *ifp;
2879 struct ieee80211vap *vap;
2880 struct ieee80211_frame_bar *bar;
2881 struct rt2870_softc_node *rni;
2882 struct mbuf *m;
2883 uint16_t barctl, barseqctl;
2884 uint8_t *frm;
2885 int ret, tid;
2887 ic = ni->ni_ic;
2888 ifp = ic->ic_ifp;
2889 sc = ifp->if_softc;
2890 vap = ni->ni_vap;
2891 rni = (struct rt2870_softc_node *) ni;
2893 if (!(tap->txa_flags & IEEE80211_AGGR_RUNNING))
2894 return EINVAL;
2896 m = ieee80211_getmgtframe(&frm, ic->ic_headroom, sizeof(struct ieee80211_frame_bar));
2897 if (m == NULL)
2898 return ENOMEM;
2900 bar = mtod(m, struct ieee80211_frame_bar *);
2902 bar->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_BAR;
2903 bar->i_fc[1] = 0;
2905 IEEE80211_ADDR_COPY(bar->i_ra, ni->ni_macaddr);
2906 IEEE80211_ADDR_COPY(bar->i_ta, vap->iv_myaddr);
2908 tid = WME_AC_TO_TID(tap->txa_ac);
2910 barctl = (tap->txa_flags & IEEE80211_AGGR_IMMEDIATE ? 0 : IEEE80211_BAR_NOACK) |
2911 IEEE80211_BAR_COMP |
2912 RT2870_SM(tid, IEEE80211_BAR_TID);
2913 barseqctl = RT2870_SM(seqno, IEEE80211_BAR_SEQ_START);
2915 bar->i_ctl = htole16(barctl);
2916 bar->i_seq = htole16(barseqctl);
2918 m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame_bar);
2920 tap->txa_start = seqno;
2922 ieee80211_ref_node(ni);
2924 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2925 "%s: sending BAR: associd=0x%04x, staid=0x%02x, tid=%d, seqno=%d\n",
2926 device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, tid, seqno);
2928 ret = ic->ic_raw_xmit(ni, m, NULL);
2929 if (ret != 0)
2930 ieee80211_free_node(ni);
2932 return ret;
2936 * rt2870_amrr_update_iter_func
2938 static void rt2870_amrr_update_iter_func(void *arg, struct ieee80211_node *ni)
2940 struct rt2870_softc *sc;
2941 struct ieee80211com *ic;
2942 struct ifnet *ifp;
2943 struct ieee80211vap *vap;
2944 struct rt2870_softc_vap *rvap;
2945 struct rt2870_softc_node *rni;
2946 uint8_t wcid;
2948 vap = arg;
2949 ic = vap->iv_ic;
2950 ifp = ic->ic_ifp;
2951 sc = ifp->if_softc;
2952 rvap = (struct rt2870_softc_vap *) vap;
2953 rni = (struct rt2870_softc_node *) ni;
2955 /* only associated stations */
2957 if ((ni->ni_vap == vap) && (rni->staid != 0))
2959 wcid = rni->staid;
2961 RT2870_DPRINTF(sc, RT2870_DEBUG_RATE,
2962 "%s: AMRR node: staid=0x%02x, txcnt=%d, success=%d, retrycnt=%d\n",
2963 device_get_nameunit(sc->dev),
2964 rni->staid, sc->amrr_node[wcid].txcnt, sc->amrr_node[wcid].success, sc->amrr_node[wcid].retrycnt);
2966 rt2870_amrr_choose(ni, &sc->amrr_node[wcid]);
2968 RT2870_DPRINTF(sc, RT2870_DEBUG_RATE,
2969 "%s:%s node Tx rate: associd=0x%04x, staid=0x%02x, rate=0x%02x, max rate=0x%02x\n",
2970 device_get_nameunit(sc->dev),
2971 (ni->ni_flags & IEEE80211_NODE_HT) ? " HT" : "",
2972 ni->ni_associd, rni->staid, ni->ni_txrate,
2973 (ni->ni_flags & IEEE80211_NODE_HT) ?
2974 (ni->ni_htrates.rs_rates[ni->ni_htrates.rs_nrates - 1] | IEEE80211_RATE_MCS) :
2975 (ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates - 1] & IEEE80211_RATE_VAL));
2980 * rt2870_periodic
2982 static void rt2870_periodic(void *arg)
2984 struct rt2870_softc *sc;
2985 struct ifnet *ifp;
2987 sc = arg;
2988 ifp = sc->ifp;
2990 RT2870_DPRINTF(sc, RT2870_DEBUG_PERIODIC,
2991 "%s: periodic\n",
2992 device_get_nameunit(sc->dev));
2994 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
2995 return;
2997 taskqueue_enqueue(sc->taskqueue, &sc->periodic_task);
3001 * rt2870_tx_watchdog
3003 static void rt2870_tx_watchdog(void *arg)
3005 struct rt2870_softc *sc;
3006 struct ifnet *ifp;
3008 sc = arg;
3009 ifp = sc->ifp;
3011 if (sc->tx_timer == 0)
3012 return;
3014 if (--sc->tx_timer == 0)
3016 printf("%s: Tx watchdog timeout: resetting\n",
3017 device_get_nameunit(sc->dev));
3019 rt2870_stop_locked(sc);
3020 rt2870_init_locked(sc);
3022 ifp->if_oerrors++;
3024 sc->tx_watchdog_timeouts++;
3027 callout_reset(&sc->tx_watchdog_ch, hz, rt2870_tx_watchdog, sc);
3031 * rt2870_staid_alloc
3033 static int rt2870_staid_alloc(struct rt2870_softc *sc, int aid)
3035 int staid;
3037 if ((aid > 0 && aid < RT2870_SOFTC_STAID_COUNT) && isclr(sc->staid_mask, aid))
3039 staid = aid;
3041 else
3043 for (staid = 1; staid < RT2870_SOFTC_STAID_COUNT; staid++)
3045 if (isclr(sc->staid_mask, staid))
3046 break;
3050 setbit(sc->staid_mask, staid);
3052 return staid;
3056 * rt2870_staid_delete
3058 static void rt2870_staid_delete(struct rt2870_softc *sc, int staid)
3060 clrbit(sc->staid_mask, staid);
3065 * rt2870_do_async
3067 static int rt2870_do_async(struct rt2870_softc *sc,
3068 void (*cb)(struct rt2870_softc *sc, void *arg),
3069 void *arg, int len)
3071 struct ifnet *ifp;
3072 struct rt2870_softc_cmd_ring *ring;
3073 struct rt2870_softc_cmd *cmd;
3074 int run_cmd_task;
3076 ifp = sc->ifp;
3077 ring = &sc->cmd_ring;
3079 if (!(sc->flags & RT2870_SOFTC_FLAGS_VALID))
3080 return -1;
3082 RT2870_SOFTC_LOCK(sc);
3084 if (ring->queued >= RT2870_SOFTC_CMD_RING_CMD_COUNT)
3086 RT2870_SOFTC_UNLOCK(sc);
3087 return -1;
3090 cmd = STAILQ_FIRST(&ring->inactive);
3091 STAILQ_REMOVE_HEAD(&ring->inactive, next);
3093 cmd->cb = cb;
3095 if(arg != NULL)
3096 memcpy(cmd->data, arg, len);
3098 STAILQ_INSERT_TAIL(&ring->active, cmd, next);
3099 ring->queued++;
3101 run_cmd_task = (ring->queued == 1);
3103 RT2870_SOFTC_UNLOCK(sc);
3105 if (run_cmd_task)
3106 taskqueue_enqueue(sc->taskqueue, &sc->cmd_task);
3108 return 0;
3112 * rt2870_newassoc_cb
3114 static void rt2870_newassoc_cb(struct rt2870_softc *sc, void *arg)
3116 struct ieee80211com *ic;
3117 struct ifnet *ifp;
3118 struct ieee80211vap *vap;
3119 struct ieee80211_node *ni;
3120 struct rt2870_softc_vap *rvap;
3121 struct rt2870_softc_node *rni;
3122 struct rt2870_cmd_argv_newassoc *cmd_argv;
3123 uint16_t aid;
3124 uint8_t *macaddr, wcid;
3125 int isnew;
3126 uint32_t tmp;
3128 cmd_argv = arg;
3129 macaddr = cmd_argv->macaddr;
3130 isnew = cmd_argv->isnew;
3131 ifp = sc->ifp;
3132 ic = ifp->if_l2com;
3133 ni = ieee80211_find_node(&ic->ic_sta, macaddr);
3134 vap = ni->ni_vap;
3135 rvap = (struct rt2870_softc_vap *) vap;
3136 rni = (struct rt2870_softc_node *) ni;
3138 if (isnew)
3140 aid = IEEE80211_AID(ni->ni_associd);
3141 rni->staid = rt2870_staid_alloc(sc, aid);
3142 wcid = rni->staid;
3144 RT2870_SOFTC_LOCK(sc);
3146 tmp = (ni->ni_macaddr[3] << 24) |
3147 (ni->ni_macaddr[2] << 16) |
3148 (ni->ni_macaddr[1] << 8) |
3149 ni->ni_macaddr[0];
3151 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid), tmp);
3153 tmp = (ni->ni_macaddr[5] << 8) |
3154 ni->ni_macaddr[4];
3156 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
3158 rt2870_amrr_node_init(&rvap->amrr, &sc->amrr_node[wcid], ni);
3160 RT2870_DPRINTF(sc, RT2870_DEBUG_RATE,
3161 "%s: initial%s node Tx rate: associd=0x%04x, rate=0x%02x, max rate=0x%02x\n",
3162 device_get_nameunit(sc->dev),
3163 (ni->ni_flags & IEEE80211_NODE_HT) ? " HT" : "",
3164 ni->ni_associd, ni->ni_txrate,
3165 (ni->ni_flags & IEEE80211_NODE_HT) ?
3166 (ni->ni_htrates.rs_rates[ni->ni_htrates.rs_nrates - 1] | IEEE80211_RATE_MCS) :
3167 (ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates - 1] & IEEE80211_RATE_VAL));
3169 rt2870_asic_updateprot(sc);
3170 rt2870_asic_updateslot(sc);
3171 rt2870_asic_set_txpreamble(sc);
3173 RT2870_SOFTC_UNLOCK(sc);
3176 RT2870_DPRINTF(sc, RT2870_DEBUG_NODE,
3177 "%s: new association: isnew=%d, macaddr=%s, associd=0x%04x, staid=0x%02x, QoS %s, ERP %s, HT %s\n",
3178 device_get_nameunit(sc->dev), isnew, ether_sprintf(ni->ni_macaddr),
3179 ni->ni_associd, rni->staid,
3180 (ni->ni_flags & IEEE80211_NODE_QOS) ? "enabled" : "disabled",
3181 (ni->ni_flags & IEEE80211_NODE_ERP) ? "enabled" : "disabled",
3182 (ni->ni_flags & IEEE80211_NODE_HT) ? "enabled" : "disabled");
3186 * rt2870_node_cleanup_cb
3188 static void rt2870_node_cleanup_cb(struct rt2870_softc *sc, void *arg)
3190 struct ifnet *ifp;
3191 struct ieee80211com *ic;
3192 struct rt2870_cmd_argv_nodecleanup *cmd_argv;
3193 uint8_t staid, vapid, wcid;
3194 uint32_t tmp;
3196 ifp = sc->ifp;
3197 ic = ifp->if_l2com;
3198 cmd_argv = arg;
3199 staid = cmd_argv->staid;
3201 vapid = 0;
3202 wcid = staid;
3204 tmp = ((vapid & RT2870_REG_VAP_MASK) << RT2870_REG_VAP_SHIFT) |
3205 (RT2870_REG_CIPHER_MODE_NONE << RT2870_REG_CIPHER_MODE_SHIFT) | RT2870_REG_PKEY_ENABLE;
3207 RT2870_SOFTC_LOCK(sc);
3209 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
3211 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid), 0x00000000);
3212 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, 0x00000000);
3214 rt2870_staid_delete(sc, staid);
3216 RT2870_SOFTC_UNLOCK(sc);
3220 * rt2870_updateslot_cb
3222 static void rt2870_updateslot_cb(struct rt2870_softc *sc, void *arg)
3224 RT2870_SOFTC_LOCK(sc);
3226 rt2870_asic_updateslot(sc);
3228 RT2870_SOFTC_UNLOCK(sc);
3232 * rt2870_wme_update_cb
3234 static void rt2870_wme_update_cb(struct rt2870_softc *sc, void *arg)
3236 RT2870_SOFTC_LOCK(sc);
3238 rt2870_asic_wme_update(sc);
3240 RT2870_SOFTC_UNLOCK(sc);
3244 * rt2870_vap_key_set_cb
3246 static void rt2870_vap_key_set_cb(struct rt2870_softc *sc, void *arg)
3248 struct ieee80211com *ic;
3249 struct ifnet *ifp;
3250 struct ieee80211_key *k;
3251 enum ieee80211_opmode opmode;
3252 struct rt2870_cmd_argv_keyset *cmd_argv;
3253 uint16_t key_base, keymode_base;
3254 uint8_t mode, vapid, wcid, iv[8];
3255 uint32_t tmp;
3257 ifp = sc->ifp;
3258 ic = ifp->if_l2com;
3259 cmd_argv = arg;
3260 k = &cmd_argv->key;
3261 opmode = cmd_argv->opmode;
3263 switch (k->wk_cipher->ic_cipher)
3265 case IEEE80211_CIPHER_WEP:
3266 if(k->wk_keylen < 8)
3267 mode = RT2870_REG_CIPHER_MODE_WEP40;
3268 else
3269 mode = RT2870_REG_CIPHER_MODE_WEP104;
3270 break;
3272 case IEEE80211_CIPHER_TKIP:
3273 mode = RT2870_REG_CIPHER_MODE_TKIP;
3274 break;
3276 case IEEE80211_CIPHER_AES_CCM:
3277 mode = RT2870_REG_CIPHER_MODE_AES_CCMP;
3278 break;
3280 default:
3281 return;
3284 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
3285 "%s: VAP key set: keyix=%d, keylen=%d, macaddr=%s, mode=%d, group=%d\n",
3286 device_get_nameunit(sc->dev), k->wk_keyix, k->wk_keylen, ether_sprintf(k->wk_macaddr),
3287 mode, (k->wk_flags & IEEE80211_KEY_GROUP) ? 1 : 0);
3289 RT2870_SOFTC_LOCK(sc);
3291 if (!(k->wk_flags & IEEE80211_KEY_GROUP))
3293 /* install pairwise key */
3295 vapid = 0;
3296 wcid = cmd_argv->staid;
3297 key_base = RT2870_REG_PKEY(wcid);
3299 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP)
3301 memset(iv, 0, 8);
3303 iv[3] = (k->wk_keyix << 6);
3305 else
3307 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
3309 iv[0] = (k->wk_keytsc >> 8);
3310 iv[1] = ((iv[0] | 0x20) & 0x7f);
3311 iv[2] = k->wk_keytsc;
3313 else
3315 /* AES CCMP */
3317 iv[0] = k->wk_keytsc;
3318 iv[1] = k->wk_keytsc >> 8;
3319 iv[2] = 0;
3322 iv[3] = ((k->wk_keyix << 6) | IEEE80211_WEP_EXTIV);
3323 iv[4] = (k->wk_keytsc >> 16);
3324 iv[5] = (k->wk_keytsc >> 24);
3325 iv[6] = (k->wk_keytsc >> 32);
3326 iv[7] = (k->wk_keytsc >> 40);
3328 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
3329 "%s: VAP key set: iv=%02x %02x %02x %02x %02x %02x %02x %02x\n",
3330 device_get_nameunit(sc->dev),
3331 iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]);
3334 rt2870_io_mac_write_multi(sc, RT2870_REG_IVEIV(wcid), iv, 8);
3336 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
3338 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, 16);
3340 if (opmode != IEEE80211_M_HOSTAP)
3342 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[16], 8);
3343 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[24], 8);
3345 else
3347 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[24], 8);
3348 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[16], 8);
3351 else
3353 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, k->wk_keylen);
3356 tmp = ((vapid & RT2870_REG_VAP_MASK) << RT2870_REG_VAP_SHIFT) |
3357 (mode << RT2870_REG_CIPHER_MODE_SHIFT) | RT2870_REG_PKEY_ENABLE;
3359 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
3362 if ((k->wk_flags & IEEE80211_KEY_GROUP) ||
3363 (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP))
3365 /* install group key */
3367 vapid = 0;
3368 wcid = RT2870_WCID_MCAST;
3369 key_base = RT2870_REG_SKEY(vapid, k->wk_keyix);
3370 keymode_base = RT2870_REG_SKEY_MODE(vapid);
3372 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
3374 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, 16);
3376 if (opmode != IEEE80211_M_HOSTAP)
3378 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[16], 8);
3379 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[24], 8);
3381 else
3383 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[24], 8);
3384 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[16], 8);
3387 else
3389 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, k->wk_keylen);
3392 tmp = rt2870_io_mac_read(sc, keymode_base);
3394 tmp &= ~(0xf << (k->wk_keyix * 4 + 16 * (vapid % 2)));
3395 tmp |= (mode << (k->wk_keyix * 4 + 16 * (vapid % 2)));
3397 rt2870_io_mac_write(sc, keymode_base, tmp);
3399 if (opmode == IEEE80211_M_HOSTAP)
3401 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP)
3403 memset(iv, 0, 8);
3405 iv[3] = (k->wk_keyix << 6);
3407 else
3409 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
3411 iv[0] = (k->wk_keytsc >> 8);
3412 iv[1] = ((iv[0] | 0x20) & 0x7f);
3413 iv[2] = k->wk_keytsc;
3415 else
3417 /* AES CCMP */
3419 iv[0] = k->wk_keytsc;
3420 iv[1] = k->wk_keytsc >> 8;
3421 iv[2] = 0;
3424 iv[3] = ((k->wk_keyix << 6) | IEEE80211_WEP_EXTIV);
3425 iv[4] = (k->wk_keytsc >> 16);
3426 iv[5] = (k->wk_keytsc >> 24);
3427 iv[6] = (k->wk_keytsc >> 32);
3428 iv[7] = (k->wk_keytsc >> 40);
3430 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
3431 "%s: VAP key set: iv=%02x %02x %02x %02x %02x %02x %02x %02x\n",
3432 device_get_nameunit(sc->dev),
3433 iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]);
3436 rt2870_io_mac_write_multi(sc, RT2870_REG_IVEIV(wcid), iv, 8);
3438 tmp = ((vapid & RT2870_REG_VAP_MASK) << RT2870_REG_VAP_SHIFT) |
3439 (mode << RT2870_REG_CIPHER_MODE_SHIFT);
3441 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
3445 RT2870_SOFTC_UNLOCK(sc);
3449 * rt2870_vap_key_delete_cb
3451 static void rt2870_vap_key_delete_cb(struct rt2870_softc *sc, void *arg)
3453 struct ieee80211com *ic;
3454 struct ifnet *ifp;
3455 struct ieee80211_key *k;
3456 enum ieee80211_opmode opmode;
3457 struct rt2870_cmd_argv_keydelete *cmd_argv;
3458 uint8_t vapid, wcid;
3459 uint32_t tmp;
3461 ifp = sc->ifp;
3462 ic = ifp->if_l2com;
3463 cmd_argv = arg;
3464 k = &cmd_argv->key;
3465 opmode = cmd_argv->opmode;
3467 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
3468 "%s: VAP key delete: keyix=%d, keylen=%d, macaddr=%s, group=%d\n",
3469 device_get_nameunit(sc->dev), k->wk_keyix, k->wk_keylen, ether_sprintf(k->wk_macaddr),
3470 (k->wk_flags & IEEE80211_KEY_GROUP) ? 1 : 0);
3472 RT2870_SOFTC_LOCK(sc);
3474 if (k->wk_flags & IEEE80211_KEY_GROUP)
3476 /* remove group key */
3478 vapid = 0;
3479 wcid = RT2870_WCID_MCAST;
3481 tmp = rt2870_io_mac_read(sc, RT2870_REG_SKEY_MODE(vapid));
3483 tmp &= ~(0xf << (k->wk_keyix * 4 + 16 * (vapid % 2)));
3484 tmp |= (RT2870_REG_CIPHER_MODE_NONE << (k->wk_keyix * 4 + 16 * (vapid % 2)));
3486 rt2870_io_mac_write(sc, RT2870_REG_SKEY_MODE(vapid), tmp);
3488 if (opmode == IEEE80211_M_HOSTAP)
3490 tmp = ((vapid & RT2870_REG_VAP_MASK) << RT2870_REG_VAP_SHIFT) |
3491 (RT2870_REG_CIPHER_MODE_NONE << RT2870_REG_CIPHER_MODE_SHIFT);
3493 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
3497 RT2870_SOFTC_UNLOCK(sc);
3501 * rt2870_vap_update_beacon_cb
3503 static void rt2870_vap_update_beacon_cb(struct rt2870_softc *sc, void *arg)
3505 struct ifnet *ifp;
3506 struct ieee80211com *ic;
3507 struct ieee80211vap *vap;
3509 ifp = sc->ifp;
3510 ic = ifp->if_l2com;
3511 vap = TAILQ_FIRST(&ic->ic_vaps);
3513 if (vap == NULL)
3514 return;
3516 RT2870_SOFTC_LOCK(sc);
3518 rt2870_asic_update_beacon(sc, vap);
3520 RT2870_SOFTC_UNLOCK(sc);
3524 * rt2870_asic_set_bssid
3526 static void rt2870_asic_set_bssid(struct rt2870_softc *sc,
3527 const uint8_t *bssid)
3529 uint32_t tmp;
3531 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3532 "%s: set bssid: bssid=%s\n",
3533 device_get_nameunit(sc->dev),
3534 ether_sprintf(bssid));
3536 tmp = bssid[0] | (bssid[1]) << 8 | (bssid[2] << 16) | (bssid[3] << 24);
3538 rt2870_io_mac_write(sc, RT2870_REG_BSSID_DW0, tmp);
3540 tmp = bssid[4] | (bssid[5] << 8);
3542 rt2870_io_mac_write(sc, RT2870_REG_BSSID_DW1, tmp);
3546 * rt2870_asic_set_macaddr
3548 static void rt2870_asic_set_macaddr(struct rt2870_softc *sc,
3549 const uint8_t *addr)
3551 uint32_t tmp;
3553 tmp = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
3555 rt2870_io_mac_write(sc, RT2870_REG_ADDR_DW0, tmp);
3557 tmp = addr[4] | (addr[5] << 8) | (0xff << 16);
3559 rt2870_io_mac_write(sc, RT2870_REG_ADDR_DW1, tmp);
3563 * rt2870_asic_enable_tsf_sync
3565 static void rt2870_asic_enable_tsf_sync(struct rt2870_softc *sc)
3567 struct ifnet *ifp;
3568 struct ieee80211com *ic;
3569 struct ieee80211vap *vap;
3570 uint32_t tmp;
3572 ifp = sc->ifp;
3573 ic = ifp->if_l2com;
3574 vap = TAILQ_FIRST(&ic->ic_vaps);
3576 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
3577 "%s: enabling TSF\n",
3578 device_get_nameunit(sc->dev));
3580 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
3582 tmp &= ~0x1fffff;
3583 tmp |= vap->iv_bss->ni_intval * 16;
3584 tmp |= (RT2870_REG_TSF_TIMER_ENABLE | RT2870_REG_TBTT_TIMER_ENABLE);
3586 if (vap->iv_opmode == IEEE80211_M_STA)
3588 tmp |= (RT2870_REG_TSF_SYNC_MODE_STA << RT2870_REG_TSF_SYNC_MODE_SHIFT);
3590 else if (vap->iv_opmode == IEEE80211_M_IBSS)
3592 tmp |= RT2870_REG_BCN_TX_ENABLE;
3593 tmp |= (RT2870_REG_TSF_SYNC_MODE_IBSS << RT2870_REG_TSF_SYNC_MODE_SHIFT);
3595 else if (vap->iv_opmode == IEEE80211_M_HOSTAP)
3597 tmp |= RT2870_REG_BCN_TX_ENABLE;
3598 tmp |= (RT2870_REG_TSF_SYNC_MODE_HOSTAP << RT2870_REG_TSF_SYNC_MODE_SHIFT);
3601 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
3605 * rt2870_asic_disable_tsf_sync
3607 static void rt2870_asic_disable_tsf_sync(struct rt2870_softc *sc)
3609 uint32_t tmp;
3611 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
3612 "%s: disabling TSF\n",
3613 device_get_nameunit(sc->dev));
3615 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
3617 tmp &= ~(RT2870_REG_BCN_TX_ENABLE |
3618 RT2870_REG_TSF_TIMER_ENABLE |
3619 RT2870_REG_TBTT_TIMER_ENABLE);
3621 tmp &= ~(RT2870_REG_TSF_SYNC_MODE_MASK << RT2870_REG_TSF_SYNC_MODE_SHIFT);
3622 tmp |= (RT2870_REG_TSF_SYNC_MODE_DISABLE << RT2870_REG_TSF_SYNC_MODE_SHIFT);
3624 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
3628 * rt2870_asic_enable_mrr
3630 static void rt2870_asic_enable_mrr(struct rt2870_softc *sc)
3632 #define CCK(mcs) (mcs)
3633 #define OFDM(mcs) ((1 << 3) | (mcs))
3634 #define HT(mcs) (mcs)
3636 rt2870_io_mac_write(sc, RT2870_REG_TX_LG_FBK_CFG0,
3637 (OFDM(6) << 28) | /* 54 -> 48 */
3638 (OFDM(5) << 24) | /* 48 -> 36 */
3639 (OFDM(4) << 20) | /* 36 -> 24 */
3640 (OFDM(3) << 16) | /* 24 -> 18 */
3641 (OFDM(2) << 12) | /* 18 -> 12 */
3642 (OFDM(1) << 8) | /* 12 -> 9 */
3643 (OFDM(0) << 4) | /* 9 -> 6 */
3644 OFDM(0)); /* 6 -> 6 */
3646 rt2870_io_mac_write(sc, RT2870_REG_TX_LG_FBK_CFG1,
3647 (CCK(2) << 12) | /* 11 -> 5.5 */
3648 (CCK(1) << 8) | /* 5.5 -> 2 */
3649 (CCK(0) << 4) | /* 2 -> 1 */
3650 CCK(0)); /* 1 -> 1 */
3652 rt2870_io_mac_write(sc, RT2870_REG_TX_HT_FBK_CFG0,
3653 (HT(6) << 28) |
3654 (HT(5) << 24) |
3655 (HT(4) << 20) |
3656 (HT(3) << 16) |
3657 (HT(2) << 12) |
3658 (HT(1) << 8) |
3659 (HT(0) << 4) |
3660 HT(0));
3662 rt2870_io_mac_write(sc, RT2870_REG_TX_HT_FBK_CFG1,
3663 (HT(14) << 28) |
3664 (HT(13) << 24) |
3665 (HT(12) << 20) |
3666 (HT(11) << 16) |
3667 (HT(10) << 12) |
3668 (HT(9) << 8) |
3669 (HT(8) << 4) |
3670 HT(7));
3672 #undef HT
3673 #undef OFDM
3674 #undef CCK
3678 * rt2870_asic_set_txpreamble
3680 static void rt2870_asic_set_txpreamble(struct rt2870_softc *sc)
3682 struct ifnet *ifp;
3683 struct ieee80211com *ic;
3684 uint32_t tmp;
3686 ifp = sc->ifp;
3687 ic = ifp->if_l2com;
3689 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3690 "%s: %s short Tx preamble\n",
3691 device_get_nameunit(sc->dev),
3692 (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? "enabling" : "disabling");
3694 tmp = rt2870_io_mac_read(sc, RT2870_REG_AUTO_RSP_CFG);
3696 tmp &= ~RT2870_REG_CCK_SHORT_ENABLE;
3698 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
3699 tmp |= RT2870_REG_CCK_SHORT_ENABLE;
3701 rt2870_io_mac_write(sc, RT2870_REG_AUTO_RSP_CFG, tmp);
3705 * rt2870_asic_set_basicrates
3707 static void rt2870_asic_set_basicrates(struct rt2870_softc *sc)
3709 struct ifnet *ifp;
3710 struct ieee80211com *ic;
3712 ifp = sc->ifp;
3713 ic = ifp->if_l2com;
3715 if (ic->ic_curmode == IEEE80211_MODE_11B)
3716 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0xf);
3717 else if (ic->ic_curmode == IEEE80211_MODE_11A)
3718 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0x150);
3719 else
3720 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0x15f);
3724 * rt2870_asic_update_rtsthreshold
3726 static void rt2870_asic_update_rtsthreshold(struct rt2870_softc *sc)
3728 struct ifnet *ifp;
3729 struct ieee80211com *ic;
3730 struct ieee80211vap *vap;
3731 uint32_t tmp;
3732 uint16_t threshold;
3734 ifp = sc->ifp;
3735 ic = ifp->if_l2com;
3736 vap = TAILQ_FIRST(&ic->ic_vaps);
3738 if (vap == NULL)
3739 threshold = IEEE80211_RTS_MAX;
3740 else if (vap->iv_flags_ht & IEEE80211_FHT_AMSDU_TX)
3741 threshold = 0x1000;
3742 else
3743 threshold = vap->iv_rtsthreshold;
3745 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3746 "%s: updating RTS threshold: %d\n",
3747 device_get_nameunit(sc->dev), threshold);
3749 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_RTS_CFG);
3751 tmp &= ~(RT2870_REG_TX_RTS_THRESHOLD_MASK << RT2870_REG_TX_RTS_THRESHOLD_SHIFT);
3753 tmp |= ((threshold & RT2870_REG_TX_RTS_THRESHOLD_MASK) <<
3754 RT2870_REG_TX_RTS_THRESHOLD_SHIFT);
3756 rt2870_io_mac_write(sc, RT2870_REG_TX_RTS_CFG, tmp);
3760 * rt2870_asic_update_txpower
3762 static void rt2870_asic_update_txpower(struct rt2870_softc *sc)
3764 struct ifnet *ifp;
3765 struct ieee80211com *ic;
3766 uint32_t *txpow_rate;
3767 int8_t delta;
3768 uint8_t val;
3769 uint32_t tmp;
3770 int i;
3772 ifp = sc->ifp;
3773 ic = ifp->if_l2com;
3775 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3776 "%s: updating Tx power: %d\n",
3777 device_get_nameunit(sc->dev), ic->ic_txpowlimit);
3779 if (!IEEE80211_IS_CHAN_HT40(ic->ic_curchan))
3781 txpow_rate = sc->txpow_rate_20mhz;
3783 else
3785 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
3786 txpow_rate = sc->txpow_rate_40mhz_2ghz;
3787 else
3788 txpow_rate = sc->txpow_rate_40mhz_5ghz;
3791 delta = 0;
3793 val = rt2870_io_bbp_read(sc, 1);
3794 val &= 0xfc;
3796 if (ic->ic_txpowlimit > 90)
3798 /* do nothing */
3800 else if (ic->ic_txpowlimit > 60)
3802 delta -= 1;
3804 else if (ic->ic_txpowlimit > 30)
3806 delta -= 3;
3808 else if (ic->ic_txpowlimit > 15)
3810 val |= 0x1;
3812 else if (ic->ic_txpowlimit > 9)
3814 val |= 0x1;
3815 delta -= 3;
3817 else
3819 val |= 0x2;
3822 rt2870_io_bbp_write(sc, 1, val);
3824 for (i = 0; i < RT2870_SOFTC_TXPOW_RATE_COUNT; i++)
3826 if (txpow_rate[i] == 0xffffffff)
3827 continue;
3829 tmp = rt2870_read_eeprom_txpow_rate_add_delta(txpow_rate[i], delta);
3831 rt2870_io_mac_write(sc, RT2870_REG_TX_PWR_CFG(i), tmp);
3836 * rt2870_asic_update_promisc
3838 static void rt2870_asic_update_promisc(struct rt2870_softc *sc)
3840 struct ifnet *ifp;
3841 uint32_t tmp;
3843 ifp = sc->ifp;
3845 printf("%s: %s promiscuous mode\n",
3846 device_get_nameunit(sc->dev),
3847 (ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving");
3849 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_FILTER_CFG);
3851 tmp &= ~RT2870_REG_RX_FILTER_DROP_UC_NOME;
3853 if (!(ifp->if_flags & IFF_PROMISC))
3854 tmp |= RT2870_REG_RX_FILTER_DROP_UC_NOME;
3856 rt2870_io_mac_write(sc, RT2870_REG_RX_FILTER_CFG, tmp);
3860 * rt2870_asic_updateprot
3862 static void rt2870_asic_updateprot(struct rt2870_softc *sc)
3864 struct ifnet *ifp;
3865 struct ieee80211com *ic;
3866 struct ieee80211vap *vap;
3867 uint32_t cck_prot, ofdm_prot, mm20_prot, mm40_prot, gf20_prot, gf40_prot;
3868 uint8_t htopmode;
3869 enum ieee80211_protmode htprotmode;
3871 ifp = sc->ifp;
3872 ic = ifp->if_l2com;
3873 vap = TAILQ_FIRST(&ic->ic_vaps);
3875 if (!(sc->flags & RT2870_SOFTC_FLAGS_VALID))
3876 return;
3878 /* CCK frame protection */
3880 cck_prot = RT2870_REG_RTSTH_ENABLE | RT2870_REG_PROT_NAV_SHORT |
3881 RT2870_REG_TXOP_ALLOW_ALL | RT2870_REG_PROT_CTRL_NONE;
3883 /* set up protection frame phy mode and rate (MCS code) */
3885 if (ic->ic_curmode == IEEE80211_MODE_11A)
3886 cck_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3887 (0 << RT2870_REG_PROT_MCS_SHIFT);
3888 else
3889 cck_prot |= ((RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3890 (3 << RT2870_REG_PROT_MCS_SHIFT));
3892 rt2870_io_mac_write(sc, RT2870_REG_TX_CCK_PROT_CFG, cck_prot);
3894 /* OFDM frame protection */
3896 ofdm_prot = RT2870_REG_RTSTH_ENABLE | RT2870_REG_PROT_NAV_SHORT |
3897 RT2870_REG_TXOP_ALLOW_ALL;
3899 if (ic->ic_flags & IEEE80211_F_USEPROT)
3901 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3902 "%s: updating protection mode: b/g protection mode=%s\n",
3903 device_get_nameunit(sc->dev),
3904 (ic->ic_protmode == IEEE80211_PROT_RTSCTS) ? "RTS/CTS" :
3905 ((ic->ic_protmode == IEEE80211_PROT_CTSONLY) ? "CTS-to-self" : "none"));
3907 if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
3908 ofdm_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3909 else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
3910 ofdm_prot |= RT2870_REG_PROT_CTRL_CTS;
3911 else
3912 ofdm_prot |= RT2870_REG_PROT_CTRL_NONE;
3914 else
3916 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3917 "%s: updating protection mode: b/g protection mode=%s\n",
3918 device_get_nameunit(sc->dev), "none");
3920 ofdm_prot |= RT2870_REG_PROT_CTRL_NONE;
3923 rt2870_io_mac_write(sc, RT2870_REG_TX_OFDM_PROT_CFG, ofdm_prot);
3925 /* HT frame protection */
3927 if ((vap != NULL) && (vap->iv_opmode == IEEE80211_M_STA) && (vap->iv_state == IEEE80211_S_RUN))
3928 htopmode = vap->iv_bss->ni_htopmode;
3929 else
3930 htopmode = ic->ic_curhtprotmode;
3932 htprotmode = ic->ic_htprotmode;
3934 /* force HT mixed mode and RTS/CTS protection if A-MPDU Tx aggregation is enabled */
3936 if (sc->tx_ampdu_sessions > 0)
3938 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3939 "%s: updating protection mode: forcing HT mixed mode and RTS/CTS protection\n",
3940 device_get_nameunit(sc->dev));
3942 htopmode = IEEE80211_HTINFO_OPMODE_MIXED;
3943 htprotmode = IEEE80211_PROT_RTSCTS;
3946 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3947 "%s: updating protection mode: HT operation mode=0x%02x, protection mode=%s\n",
3948 device_get_nameunit(sc->dev),
3949 htopmode & IEEE80211_HTINFO_OPMODE,
3950 (htprotmode == IEEE80211_PROT_RTSCTS) ? "RTS/CTS" :
3951 ((htprotmode == IEEE80211_PROT_CTSONLY) ? "CTS-to-self" : "none"));
3953 switch (htopmode & IEEE80211_HTINFO_OPMODE)
3955 /* IEEE80211_HTINFO_OPMODE_HT20PR */
3956 case IEEE80211_HTINFO_OPMODE_HT20PR:
3957 mm20_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3958 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3959 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20 |
3960 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3961 (4 << RT2870_REG_PROT_MCS_SHIFT);
3963 gf20_prot = mm20_prot;
3965 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3966 RT2870_REG_TXOP_ALLOW_ALL |
3967 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3968 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
3970 if (htprotmode == IEEE80211_PROT_RTSCTS)
3971 mm40_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3972 else if (htprotmode == IEEE80211_PROT_CTSONLY)
3973 mm40_prot |= RT2870_REG_PROT_CTRL_CTS;
3974 else
3975 mm40_prot |= RT2870_REG_PROT_CTRL_NONE;
3977 gf40_prot = mm40_prot;
3978 break;
3980 /* IEEE80211_HTINFO_OPMODE_MIXED */
3981 case IEEE80211_HTINFO_OPMODE_MIXED:
3982 mm20_prot = RT2870_REG_PROT_NAV_SHORT |
3983 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3984 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20;
3986 if (ic->ic_flags & IEEE80211_F_USEPROT)
3987 mm20_prot |= (RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3988 (3 << RT2870_REG_PROT_MCS_SHIFT);
3989 else
3990 mm20_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3991 (4 << RT2870_REG_PROT_MCS_SHIFT);
3993 if (htprotmode == IEEE80211_PROT_RTSCTS)
3994 mm20_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3995 else if (htprotmode == IEEE80211_PROT_CTSONLY)
3996 mm20_prot |= RT2870_REG_PROT_CTRL_CTS;
3997 else
3998 mm20_prot |= RT2870_REG_PROT_CTRL_NONE;
4000 gf20_prot = mm20_prot;
4002 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_TXOP_ALLOW_ALL;
4004 if (ic->ic_flags & IEEE80211_F_USEPROT)
4005 mm40_prot |= (RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
4006 (3 << RT2870_REG_PROT_MCS_SHIFT);
4007 else
4008 mm40_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
4009 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
4011 if (htprotmode == IEEE80211_PROT_RTSCTS)
4012 mm40_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
4013 else if (htprotmode == IEEE80211_PROT_CTSONLY)
4014 mm40_prot |= RT2870_REG_PROT_CTRL_CTS;
4015 else
4016 mm40_prot |= RT2870_REG_PROT_CTRL_NONE;
4018 gf40_prot = mm40_prot;
4019 break;
4022 * IEEE80211_HTINFO_OPMODE_PURE
4023 * IEEE80211_HTINFO_OPMODE_PROTOPT
4025 case IEEE80211_HTINFO_OPMODE_PURE:
4026 case IEEE80211_HTINFO_OPMODE_PROTOPT:
4027 default:
4028 mm20_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
4029 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
4030 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20 |
4031 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
4032 (4 << RT2870_REG_PROT_MCS_SHIFT);
4034 gf20_prot = mm20_prot;
4036 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
4037 RT2870_REG_TXOP_ALLOW_ALL |
4038 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
4039 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
4041 gf40_prot = mm40_prot;
4042 break;
4045 rt2870_io_mac_write(sc, RT2870_REG_TX_MM20_PROT_CFG, mm20_prot);
4046 rt2870_io_mac_write(sc, RT2870_REG_TX_MM40_PROT_CFG, mm40_prot);
4047 rt2870_io_mac_write(sc, RT2870_REG_TX_GF20_PROT_CFG, gf20_prot);
4048 rt2870_io_mac_write(sc, RT2870_REG_TX_GF40_PROT_CFG, gf40_prot);
4052 * rt2870_asic_updateslot
4054 static void rt2870_asic_updateslot(struct rt2870_softc *sc)
4056 struct ifnet *ifp;
4057 struct ieee80211com *ic;
4058 struct ieee80211vap *vap;
4059 uint32_t tmp;
4061 ifp = sc->ifp;
4062 ic = ifp->if_l2com;
4063 vap = TAILQ_FIRST(&ic->ic_vaps);
4065 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
4066 "%s: %s short slot time\n",
4067 device_get_nameunit(sc->dev),
4068 ((ic->ic_flags & IEEE80211_F_SHSLOT) ||
4069 ((vap != NULL) && (vap->iv_flags & IEEE80211_F_BURST))) ? "enabling" : "disabling");
4071 tmp = rt2870_io_mac_read(sc, RT2870_REG_BKOFF_SLOT_CFG);
4073 tmp &= ~0xff;
4075 if ((ic->ic_flags & IEEE80211_F_SHSLOT) ||
4076 ((vap != NULL) && (vap->iv_flags & IEEE80211_F_BURST)))
4077 tmp |= IEEE80211_DUR_SHSLOT;
4078 else
4079 tmp |= IEEE80211_DUR_SLOT;
4081 rt2870_io_mac_write(sc, RT2870_REG_BKOFF_SLOT_CFG, tmp);
4085 * rt2870_asic_wme_update
4087 static void rt2870_asic_wme_update(struct rt2870_softc *sc)
4089 struct ifnet *ifp;
4090 struct ieee80211com *ic;
4091 struct ieee80211_wme_state *wme;
4092 const struct wmeParams *wmep;
4093 int i;
4095 ifp = sc->ifp;
4096 ic = ifp->if_l2com;
4097 wme = &ic->ic_wme;
4098 wmep = wme->wme_chanParams.cap_wmeParams;
4100 RT2870_DPRINTF(sc, RT2870_DEBUG_WME,
4101 "%s: wme update: WME_AC_VO=%d/%d/%d/%d, WME_AC_VI=%d/%d/%d/%d, "
4102 "WME_AC_BK=%d/%d/%d/%d, WME_AC_BE=%d/%d/%d/%d\n",
4103 device_get_nameunit(sc->dev),
4104 wmep[WME_AC_VO].wmep_aifsn,
4105 wmep[WME_AC_VO].wmep_logcwmin, wmep[WME_AC_VO].wmep_logcwmax,
4106 wmep[WME_AC_VO].wmep_txopLimit,
4107 wmep[WME_AC_VI].wmep_aifsn,
4108 wmep[WME_AC_VI].wmep_logcwmin, wmep[WME_AC_VI].wmep_logcwmax,
4109 wmep[WME_AC_VI].wmep_txopLimit,
4110 wmep[WME_AC_BK].wmep_aifsn,
4111 wmep[WME_AC_BK].wmep_logcwmin, wmep[WME_AC_BK].wmep_logcwmax,
4112 wmep[WME_AC_BK].wmep_txopLimit,
4113 wmep[WME_AC_BE].wmep_aifsn,
4114 wmep[WME_AC_BE].wmep_logcwmin, wmep[WME_AC_BE].wmep_logcwmax,
4115 wmep[WME_AC_BE].wmep_txopLimit);
4117 for (i = 0; i < WME_NUM_AC; i++)
4118 rt2870_io_mac_write(sc, RT2870_REG_TX_EDCA_AC_CFG(i),
4119 (wmep[i].wmep_logcwmax << 16) | (wmep[i].wmep_logcwmin << 12) |
4120 (wmep[i].wmep_aifsn << 8) | wmep[i].wmep_txopLimit);
4122 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_AIFSN_CFG,
4123 (wmep[WME_AC_VO].wmep_aifsn << 12) | (wmep[WME_AC_VI].wmep_aifsn << 8) |
4124 (wmep[WME_AC_BK].wmep_aifsn << 4) | wmep[WME_AC_BE].wmep_aifsn);
4126 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_CWMIN_CFG,
4127 (wmep[WME_AC_VO].wmep_logcwmin << 12) | (wmep[WME_AC_VI].wmep_logcwmin << 8) |
4128 (wmep[WME_AC_BK].wmep_logcwmin << 4) | wmep[WME_AC_BE].wmep_logcwmin);
4130 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_CWMAX_CFG,
4131 (wmep[WME_AC_VO].wmep_logcwmax << 12) | (wmep[WME_AC_VI].wmep_logcwmax << 8) |
4132 (wmep[WME_AC_BK].wmep_logcwmax << 4) | wmep[WME_AC_BE].wmep_logcwmax);
4134 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP0_CFG,
4135 (wmep[WME_AC_BK].wmep_txopLimit << 16) | wmep[WME_AC_BE].wmep_txopLimit);
4137 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP1_CFG,
4138 (wmep[WME_AC_VO].wmep_txopLimit << 16) | wmep[WME_AC_VI].wmep_txopLimit);
4142 * rt2870_asic_update_beacon
4144 static void rt2870_asic_update_beacon(struct rt2870_softc *sc,
4145 struct ieee80211vap *vap)
4147 struct rt2870_softc_vap *rvap;
4148 struct mbuf *m;
4149 struct rt2870_txwi *txwi;
4150 uint32_t tmp;
4152 rvap = (struct rt2870_softc_vap *) vap;
4154 m = rvap->beacon_mbuf;
4155 txwi = &rvap->beacon_txwi;
4157 /* disable temporarily TSF sync */
4159 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
4161 tmp &= ~(RT2870_REG_BCN_TX_ENABLE |
4162 RT2870_REG_TSF_TIMER_ENABLE |
4163 RT2870_REG_TBTT_TIMER_ENABLE);
4165 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
4167 /* write Tx wireless info and beacon frame to on-chip memory */
4169 rt2870_io_mac_write_multi(sc, RT2870_REG_BEACON_BASE(0),
4170 txwi, sizeof(struct rt2870_txwi));
4172 rt2870_io_mac_write_multi(sc, RT2870_REG_BEACON_BASE(0) + sizeof(struct rt2870_txwi),
4173 mtod(m, uint8_t *), m->m_pkthdr.len);
4175 /* enable again TSF sync */
4177 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
4179 tmp |= (RT2870_REG_BCN_TX_ENABLE |
4180 RT2870_REG_TSF_TIMER_ENABLE |
4181 RT2870_REG_TBTT_TIMER_ENABLE);
4183 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
4187 * rt2870_asic_clear_keytables
4189 static void rt2870_asic_clear_keytables(struct rt2870_softc *sc)
4191 int i;
4193 /* clear Rx WCID search table (entries = 256, entry size = 8) */
4195 for (i = 0; i < 256; i++)
4197 rt2870_io_mac_write(sc, RT2870_REG_WCID(i), 0xffffffff);
4198 rt2870_io_mac_write(sc, RT2870_REG_WCID(i) + 4, 0x0000ffff);
4201 /* clear WCID attribute table (entries = 256, entry size = 4) */
4203 rt2870_io_mac_set_region_4(sc, RT2870_REG_WCID_ATTR(0), 0, 256);
4205 /* clear IV/EIV table (entries = 256, entry size = 8) */
4207 rt2870_io_mac_set_region_4(sc, RT2870_REG_IVEIV(0), 0, 2 * 256);
4209 /* clear pairwise key table (entries = 256, entry size = 32) */
4211 rt2870_io_mac_set_region_4(sc, RT2870_REG_PKEY(0), 0, 8 * 256);
4213 /* clear shared key table (entries = 32, entry size = 32) */
4215 rt2870_io_mac_set_region_4(sc, RT2870_REG_SKEY(0, 0), 0, 8 * 32);
4217 /* clear shared key mode (entries = 32, entry size = 2) */
4219 rt2870_io_mac_set_region_4(sc, RT2870_REG_SKEY_MODE(0), 0, 16);
4223 * rt2870_asic_add_ba_session
4225 static void rt2870_asic_add_ba_session(struct rt2870_softc *sc,
4226 uint8_t wcid, int tid)
4228 uint32_t tmp;
4230 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID(wcid) + 4);
4232 tmp |= (0x10000 << tid);
4234 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
4238 * rt2860_asic_del_ba_session
4240 static void rt2870_asic_del_ba_session(struct rt2870_softc *sc,
4241 uint8_t wcid, int tid)
4243 uint32_t tmp;
4245 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID(wcid) + 4);
4247 tmp &= ~(0x10000 << tid);
4249 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
4253 * rt2870_beacon_alloc
4255 static int rt2870_beacon_alloc(struct rt2870_softc *sc,
4256 struct ieee80211vap *vap)
4258 struct ieee80211com *ic;
4259 struct rt2870_softc_vap *rvap;
4260 struct mbuf *m;
4261 struct rt2870_txwi txwi;
4262 uint8_t rate, mcs;
4264 ic = vap->iv_ic;
4265 rvap = (struct rt2870_softc_vap *) vap;
4267 m = ieee80211_beacon_alloc(vap->iv_bss, &rvap->beacon_offsets);
4268 if (m == NULL)
4269 return ENOMEM;
4271 rate = IEEE80211_IS_CHAN_5GHZ(vap->iv_bss->ni_chan) ? 12 : 2;
4272 mcs = rt2870_rate2mcs(rate);
4274 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
4275 "%s: beacon allocate: mcs=0x%02x\n",
4276 device_get_nameunit(sc->dev), mcs);
4278 memset(&txwi, 0, sizeof(struct rt2870_txwi));
4280 txwi.wcid = RT2870_WCID_RESERVED;
4281 txwi.pid_mpdu_len = ((htole16(m->m_pkthdr.len) & RT2870_TXWI_MPDU_LEN_MASK) <<
4282 RT2870_TXWI_MPDU_LEN_SHIFT);
4283 txwi.txop = (RT2870_TXWI_TXOP_HT << RT2870_TXWI_TXOP_SHIFT);
4284 txwi.mpdu_density_flags |=
4285 (RT2870_TXWI_FLAGS_TS << RT2870_TXWI_FLAGS_SHIFT);
4286 txwi.bawin_size_xflags |=
4287 (RT2870_TXWI_XFLAGS_NSEQ << RT2870_TXWI_XFLAGS_SHIFT);
4289 if (rate == 2)
4291 txwi.phymode_ifs_stbc_shortgi =
4292 (RT2870_TXWI_PHYMODE_CCK << RT2870_TXWI_PHYMODE_SHIFT);
4294 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
4295 mcs |= RT2870_TXWI_MCS_SHOTPRE;
4297 else
4299 txwi.phymode_ifs_stbc_shortgi =
4300 (RT2870_TXWI_PHYMODE_OFDM << RT2870_TXWI_PHYMODE_SHIFT);
4303 txwi.bw_mcs = (RT2870_TXWI_BW_20 << RT2870_TXWI_BW_SHIFT) |
4304 ((mcs & RT2870_TXWI_MCS_MASK) << RT2870_TXWI_MCS_SHIFT);
4306 if (rvap->beacon_mbuf != NULL)
4308 m_free(rvap->beacon_mbuf);
4309 rvap->beacon_mbuf = NULL;
4312 rvap->beacon_mbuf = m;
4313 rvap->beacon_txwi = txwi;
4315 return 0;
4319 * rt2870_rxrate
4321 static uint8_t rt2870_rxrate(struct rt2870_rxwi *rxwi)
4323 uint8_t mcs, phymode;
4324 uint8_t rate;
4326 mcs = (rxwi->bw_mcs >> RT2870_RXWI_MCS_SHIFT) & RT2870_RXWI_MCS_MASK;
4327 phymode = (rxwi->phymode_stbc_shortgi >> RT2870_RXWI_PHYMODE_SHIFT) &
4328 RT2870_RXWI_PHYMODE_MASK;
4330 rate = 2;
4332 switch (phymode)
4334 case RT2870_RXWI_PHYMODE_CCK:
4335 switch (mcs & ~RT2870_RXWI_MCS_SHOTPRE)
4337 case 0: rate = 2; break; /* 1 Mbps */
4338 case 1: rate = 4; break; /* 2 MBps */
4339 case 2: rate = 11; break; /* 5.5 Mbps */
4340 case 3: rate = 22; break; /* 11 Mbps */
4342 break;
4344 case RT2870_RXWI_PHYMODE_OFDM:
4345 switch (mcs)
4347 case 0: rate = 12; break; /* 6 Mbps */
4348 case 1: rate = 18; break; /* 9 Mbps */
4349 case 2: rate = 24; break; /* 12 Mbps */
4350 case 3: rate = 36; break; /* 18 Mbps */
4351 case 4: rate = 48; break; /* 24 Mbps */
4352 case 5: rate = 72; break; /* 36 Mbps */
4353 case 6: rate = 96; break; /* 48 Mbps */
4354 case 7: rate = 108; break; /* 54 Mbps */
4356 break;
4358 case RT2870_RXWI_PHYMODE_HT_MIXED:
4359 case RT2870_RXWI_PHYMODE_HT_GF:
4360 break;
4363 return rate;
4367 * rt2870_maxrssi_rxpath
4369 static uint8_t rt2870_maxrssi_rxpath(struct rt2870_softc *sc,
4370 const struct rt2870_rxwi *rxwi)
4372 uint8_t rxpath;
4374 rxpath = 0;
4376 if (sc->nrxpath > 1)
4377 if (rxwi->rssi[1] > rxwi->rssi[rxpath])
4378 rxpath = 1;
4380 if (sc->nrxpath > 2)
4381 if (rxwi->rssi[2] > rxwi->rssi[rxpath])
4382 rxpath = 2;
4384 return rxpath;
4388 * rt2870_rssi2dbm
4390 static int8_t rt2870_rssi2dbm(struct rt2870_softc *sc,
4391 uint8_t rssi, uint8_t rxpath)
4393 struct ifnet *ifp;
4394 struct ieee80211com *ic;
4395 struct ieee80211_channel *c;
4396 int chan;
4397 int8_t rssi_off, lna_gain;
4399 if (rssi == 0)
4400 return -99;
4402 ifp = sc->ifp;
4403 ic = ifp->if_l2com;
4404 c = ic->ic_curchan;
4405 chan = ieee80211_chan2ieee(ic, c);
4407 if (IEEE80211_IS_CHAN_5GHZ(c))
4409 rssi_off = sc->rssi_off_5ghz[rxpath];
4411 if (chan <= 64)
4412 lna_gain = sc->lna_gain[1];
4413 else if (chan <= 128)
4414 lna_gain = sc->lna_gain[2];
4415 else
4416 lna_gain = sc->lna_gain[3];
4418 else
4420 rssi_off = sc->rssi_off_2ghz[rxpath];
4421 lna_gain = sc->lna_gain[0];
4424 return (-12 - rssi_off - lna_gain - rssi);
4428 * rt2870_rate2mcs
4430 static uint8_t rt2870_rate2mcs(uint8_t rate)
4432 switch (rate)
4434 /* CCK rates */
4435 case 2: return 0;
4436 case 4: return 1;
4437 case 11: return 2;
4438 case 22: return 3;
4440 /* OFDM rates */
4441 case 12: return 0;
4442 case 18: return 1;
4443 case 24: return 2;
4444 case 36: return 3;
4445 case 48: return 4;
4446 case 72: return 5;
4447 case 96: return 6;
4448 case 108: return 7;
4451 return 0;
4455 * rt2870_rx_frame
4457 static void rt2870_rx_frame(struct rt2870_softc *sc,
4458 uint8_t *buf, uint32_t dmalen)
4460 struct ifnet *ifp;
4461 struct ieee80211com *ic;
4462 struct ieee80211_frame *wh;
4463 struct ieee80211_node *ni;
4464 struct rt2870_softc_node *rni;
4465 struct rt2870_softc_rx_radiotap_header *tap;
4466 struct rt2870_rxwi *rxwi;
4467 struct rt2870_rxinfo *rxinfo;
4468 struct mbuf *m;
4469 uint32_t rxinfo_flags;
4470 uint8_t cipher_err, rssi, ant, phymode, bw, shortgi, stbc, mcs, keyidx, tid, frag;
4471 uint16_t seq;
4472 int8_t rssi_dbm;
4473 int len, ampdu, amsdu, rssi_dbm_rel, i;
4475 ifp = sc->ifp;
4476 ic = ifp->if_l2com;
4478 /* get Rx wireless info */
4480 rxwi = (struct rt2870_rxwi *) buf;
4481 len = (le16toh(rxwi->tid_size) >> RT2870_RXWI_SIZE_SHIFT) &
4482 RT2870_RXWI_SIZE_MASK;
4484 if (len > dmalen)
4486 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4487 "%s: bad rxwi len: DMA len=%d, rxwi len=%d\n",
4488 device_get_nameunit(sc->dev), dmalen, len);
4489 return;
4492 /* get Rx info */
4494 rxinfo = (struct rt2870_rxinfo *) ((caddr_t) rxwi + dmalen);
4495 rxinfo_flags = le32toh(rxinfo->flags);
4497 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4498 "%s: Rx frame: DMA len=%d, len=%d, rxinfo flags=0x%08x\n",
4499 device_get_nameunit(sc->dev), dmalen, len, rxinfo_flags);
4501 /* check for crc errors */
4503 if (rxinfo_flags & RT2870_RXINFO_FLAGS_CRC_ERR)
4505 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4506 "%s: rxinfo: crc error\n",
4507 device_get_nameunit(sc->dev));
4509 ifp->if_ierrors++;
4511 if (!(ifp->if_flags & IFF_PROMISC))
4512 return;
4515 wh = (struct ieee80211_frame *) (rxwi + 1);
4517 /* check for L2 padding between IEEE 802.11 frame header and body */
4519 if (rxinfo_flags & RT2870_RXINFO_FLAGS_L2PAD)
4521 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4522 "%s: L2 padding: DMA len=%d, len=%d\n",
4523 device_get_nameunit(sc->dev), dmalen, len);
4525 len += 2;
4528 m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
4529 if (m == NULL)
4531 sc->rx_mbuf_alloc_errors++;
4532 ifp->if_ierrors++;
4533 return;
4536 m->m_pkthdr.rcvif = ifp;
4537 m->m_pkthdr.len = m->m_len = len;
4539 m_copyback(m, 0, len, (caddr_t) wh);
4541 wh = mtod(m, struct ieee80211_frame *);
4543 /* check for cipher errors */
4545 if (rxinfo_flags & RT2870_RXINFO_FLAGS_DECRYPTED)
4547 cipher_err = ((rxinfo_flags >> RT2870_RXINFO_FLAGS_CIPHER_ERR_SHIFT) &
4548 RT2870_RXINFO_FLAGS_CIPHER_ERR_MASK);
4549 if (cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_NONE)
4551 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4552 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
4554 m->m_flags |= M_WEP;
4556 sc->rx_cipher_no_errors++;
4558 else
4560 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4561 "%s: rxinfo: cipher error=0x%02x\n",
4562 device_get_nameunit(sc->dev), cipher_err);
4564 if (cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_ICV)
4565 sc->rx_cipher_icv_errors++;
4566 else if (cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_MIC)
4567 sc->rx_cipher_mic_errors++;
4568 else if (cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_INVALID_KEY)
4569 sc->rx_cipher_invalid_key_errors++;
4571 if ((cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_MIC) &&
4572 (rxinfo_flags & RT2870_RXINFO_FLAGS_MYBSS))
4574 ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) wh);
4575 if (ni != NULL)
4577 keyidx = (rxwi->udf_bssidx_keyidx >> RT2870_RXWI_KEYIDX_SHIFT) &
4578 RT2870_RXWI_KEYIDX_MASK;
4580 ieee80211_notify_michael_failure(ni->ni_vap, wh, keyidx);
4582 ieee80211_free_node(ni);
4586 ifp->if_ierrors++;
4588 if (!(ifp->if_flags & IFF_PROMISC))
4590 m_free(m);
4591 return;
4595 else
4597 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4599 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4600 "%s: rxinfo: not decrypted but protected flag set\n",
4601 device_get_nameunit(sc->dev));
4603 ifp->if_ierrors++;
4605 if (!(ifp->if_flags & IFF_PROMISC))
4607 m_free(m);
4608 return;
4613 /* check for A-MPDU */
4615 if (rxinfo_flags & RT2870_RXINFO_FLAGS_BA)
4617 m->m_flags |= M_AMPDU;
4619 sc->rx_ampdu++;
4621 if (wh->i_fc[1] & IEEE80211_FC1_RETRY)
4622 sc->rx_ampdu_retries++;
4624 ampdu = 1;
4626 else
4628 ampdu = 0;
4631 /* check for A-MSDU */
4633 if (rxinfo_flags & RT2870_RXINFO_FLAGS_AMSDU)
4635 sc->rx_amsdu++;
4637 amsdu = 1;
4639 else
4641 amsdu = 0;
4644 ant = rt2870_maxrssi_rxpath(sc, rxwi);
4645 rssi = rxwi->rssi[ant];
4646 rssi_dbm = rt2870_rssi2dbm(sc, rssi, ant);
4647 phymode = ((rxwi->phymode_stbc_shortgi >> RT2870_RXWI_PHYMODE_SHIFT) &
4648 RT2870_RXWI_PHYMODE_MASK);
4649 bw = ((rxwi->bw_mcs >> RT2870_RXWI_BW_SHIFT) & RT2870_RXWI_BW_MASK);
4650 shortgi = ((rxwi->phymode_stbc_shortgi >> RT2870_RXWI_SHORTGI_SHIFT) &
4651 RT2870_RXWI_SHORTGI_MASK);
4652 stbc = ((rxwi->phymode_stbc_shortgi >> RT2870_RXWI_STBC_SHIFT) &
4653 RT2870_RXWI_STBC_MASK);
4654 mcs = ((rxwi->bw_mcs >> RT2870_RXWI_MCS_SHIFT) & RT2870_RXWI_MCS_MASK);
4655 tid = ((rxwi->tid_size >> RT2870_RXWI_TID_SHIFT) & RT2870_RXWI_TID_MASK);
4656 seq = ((rxwi->seq_frag >> RT2870_RXWI_SEQ_SHIFT) & RT2870_RXWI_SEQ_MASK);
4657 frag = ((rxwi->seq_frag >> RT2870_RXWI_FRAG_SHIFT) & RT2870_RXWI_FRAG_MASK);
4659 if (ieee80211_radiotap_active(ic))
4661 tap = &sc->rxtap;
4663 tap->flags = (rxinfo_flags & RT2870_RXINFO_FLAGS_L2PAD) ? IEEE80211_RADIOTAP_F_DATAPAD : 0;
4664 tap->dbm_antsignal = rssi_dbm;
4665 tap->dbm_antnoise = RT2870_NOISE_FLOOR;
4666 tap->antenna = ant;
4667 tap->antsignal = rssi;
4668 tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
4669 tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
4670 tap->chan_ieee = ic->ic_curchan->ic_ieee;
4671 tap->chan_maxpow = 0;
4673 if (phymode == RT2870_RXWI_PHYMODE_CCK || phymode == RT2870_RXWI_PHYMODE_OFDM)
4674 tap->rate = rt2870_rxrate(rxwi);
4675 else
4676 tap->rate = mcs | IEEE80211_RATE_MCS;
4678 if (rxinfo_flags & RT2870_RXINFO_FLAGS_CRC_ERR)
4679 tap->flags |= IEEE80211_RADIOTAP_F_BADFCS;
4681 if (rxinfo_flags & RT2870_RXINFO_FLAGS_FRAG)
4682 tap->flags |= IEEE80211_RADIOTAP_F_FRAG;
4684 if (rxwi->bw_mcs & RT2870_RXWI_MCS_SHOTPRE)
4685 tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
4687 if ((rxinfo_flags & RT2870_RXINFO_FLAGS_DECRYPTED) ||
4688 (wh->i_fc[1] & IEEE80211_FC1_WEP))
4689 tap->flags |= IEEE80211_RADIOTAP_F_WEP;
4691 if (shortgi)
4692 tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
4694 /* XXX use temporarily radiotap CFP flag as A-MPDU flag */
4696 if (ampdu)
4697 tap->flags |= IEEE80211_RADIOTAP_F_CFP;
4701 * net80211 assumes that RSSI data are in the range [-127..127] and
4702 * in .5 dBm units relative to the current noise floor
4705 rssi_dbm_rel = (rssi_dbm - RT2870_NOISE_FLOOR) * 2;
4706 if (rssi_dbm_rel > 127)
4707 rssi_dbm_rel = 127;
4709 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4710 "%s: received frame: len=%d, phymode=%d, bw=%d, shortgi=%d, stbc=0x%02x, mcs=%d, "
4711 "ant=%d, rssi=%d/%d/%d, snr=%d/%d, wcid=0x%02x, ampdu=%d, amsdu=%d, tid=%d, seq=%d, frag=%d, "
4712 "retry=%d, rssi_dbm=%d, rssi_dbm_rel=%d\n",
4713 device_get_nameunit(sc->dev),
4714 len, phymode, bw, shortgi, stbc, mcs,
4715 ant, rxwi->rssi[0], rxwi->rssi[1], rxwi->rssi[2],
4716 rxwi->snr[0], rxwi->snr[1],
4717 rxwi->wcid, ampdu, amsdu, tid, seq, frag, (wh->i_fc[1] & IEEE80211_FC1_RETRY) ? 1 : 0,
4718 rssi_dbm, rssi_dbm_rel);
4720 ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *) wh);
4721 if (ni != NULL)
4723 rni = (struct rt2870_softc_node *) ni;
4725 for (i = 0; i < RT2870_SOFTC_RSSI_COUNT; i++)
4727 rni->last_rssi[i] = rxwi->rssi[i];
4728 rni->last_rssi_dbm[i] = rt2870_rssi2dbm(sc, rxwi->rssi[i], i);
4731 ieee80211_input(ni, m, rssi_dbm_rel, RT2870_NOISE_FLOOR);
4732 ieee80211_free_node(ni);
4734 else
4736 ieee80211_input_all(ic, m, rssi_dbm_rel, RT2870_NOISE_FLOOR);
4741 * rt2870_tx_mgmt
4743 static int rt2870_tx_mgmt(struct rt2870_softc *sc,
4744 struct mbuf *m, struct ieee80211_node *ni, int qid)
4746 struct ifnet *ifp;
4747 struct ieee80211com *ic;
4748 struct ieee80211vap *vap;
4749 const struct ieee80211_txparam *tp;
4750 struct rt2870_softc_node *rni;
4751 struct rt2870_softc_tx_ring *ring;
4752 struct rt2870_softc_tx_data *data;
4753 struct rt2870_txinfo *txinfo;
4754 struct rt2870_txwi *txwi;
4755 struct ieee80211_frame *wh;
4756 struct rt2870_softc_tx_radiotap_header *tap;
4757 u_int hdrsize, hdrspace;
4758 uint8_t rate, mcs, pid;
4759 uint16_t len, dmalen, mpdu_len, dur;
4760 int mimops;
4762 KASSERT(qid >= 0 && qid < (sc->usb_endpoints - 1),
4763 ("%s: Tx MGMT: invalid qid=%d\n",
4764 device_get_nameunit(sc->dev), qid));
4766 ifp = sc->ifp;
4767 ic = ifp->if_l2com;
4768 vap = ni->ni_vap;
4769 rni = (struct rt2870_softc_node *) ni;
4770 tp = ni->ni_txparms;
4772 ring = &sc->tx_ring[qid];
4773 data = STAILQ_FIRST(&ring->inactive);
4774 STAILQ_REMOVE_HEAD(&ring->inactive, next);
4775 txinfo = (struct rt2870_txinfo *) data->buf;
4776 txwi = (struct rt2870_txwi *) (txinfo + 1);
4778 wh = mtod(m, struct ieee80211_frame *);
4780 rate = tp->mgmtrate & IEEE80211_RATE_VAL;
4782 len = sizeof(struct rt2870_txinfo) + sizeof(struct rt2870_txwi) + m->m_pkthdr.len;
4784 /* align end on a 4-bytes boundary */
4786 dmalen = (len + 3) & ~3;
4788 /* fill Tx info */
4790 memset(txinfo, 0, sizeof(struct rt2870_txinfo));
4792 txinfo->len = htole16(dmalen - sizeof(struct rt2870_txinfo));
4794 txinfo->qsel_flags = (RT2870_TXINFO_QSEL_EDCA << RT2870_TXINFO_QSEL_SHIFT);
4796 dmalen += 4;
4798 memset((caddr_t) txinfo + len, 0, dmalen - len);
4800 /* fill Tx wireless info */
4802 if (ni->ni_flags & IEEE80211_NODE_HT)
4803 mcs = rate;
4804 else
4805 mcs = rt2870_rate2mcs(rate);
4807 /* calculate MPDU length without padding */
4809 hdrsize = ieee80211_anyhdrsize(wh);
4810 hdrspace = ieee80211_anyhdrspace(ic, wh);
4811 mpdu_len = m->m_pkthdr.len - hdrspace + hdrsize;
4813 memset(txwi, 0, sizeof(struct rt2870_txwi));
4815 /* management frames do not need encryption */
4817 txwi->wcid = 0xff;
4819 /* MIMO power save */
4821 if ((ni->ni_flags & IEEE80211_NODE_HT) && (ni->ni_flags & IEEE80211_NODE_MIMO_PS))
4823 if (mcs > 7)
4825 if (ni->ni_flags & IEEE80211_NODE_MIMO_RTS)
4827 /* dynamic MIMO power save */
4829 txwi->mpdu_density_flags |=
4830 (RT2870_TXWI_FLAGS_MIMOPS << RT2870_TXWI_FLAGS_SHIFT);
4832 else
4834 /* static MIMO power save */
4836 mcs = 7;
4840 mimops = 1;
4842 else
4844 mimops = 0;
4847 pid = (mcs < 0xf) ? (mcs + 1) : mcs;
4849 txwi->pid_mpdu_len = ((htole16(pid) & RT2870_TXWI_PID_MASK) <<
4850 RT2870_TXWI_PID_SHIFT) | ((htole16(mpdu_len) & RT2870_TXWI_MPDU_LEN_MASK) <<
4851 RT2870_TXWI_MPDU_LEN_SHIFT);
4853 if (ni->ni_flags & IEEE80211_NODE_HT)
4855 txwi->phymode_ifs_stbc_shortgi |=
4856 (RT2870_TXWI_PHYMODE_HT_MIXED << RT2870_TXWI_PHYMODE_SHIFT);
4858 else
4860 if (ieee80211_rate2phytype(ic->ic_rt, rate) != IEEE80211_T_OFDM)
4862 txwi->phymode_ifs_stbc_shortgi |=
4863 (RT2870_TXWI_PHYMODE_CCK << RT2870_TXWI_PHYMODE_SHIFT);
4865 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
4866 mcs |= RT2870_TXWI_MCS_SHOTPRE;
4868 else
4870 txwi->phymode_ifs_stbc_shortgi |=
4871 (RT2870_TXWI_PHYMODE_OFDM << RT2870_TXWI_PHYMODE_SHIFT);
4875 txwi->bw_mcs = (RT2870_TXWI_BW_20 << RT2870_TXWI_BW_SHIFT) |
4876 ((mcs & RT2870_TXWI_MCS_MASK) << RT2870_TXWI_MCS_SHIFT);
4878 txwi->txop = (RT2870_TXWI_TXOP_BACKOFF << RT2870_TXWI_TXOP_SHIFT);
4880 /* skip ACKs for multicast frames */
4882 if (!IEEE80211_IS_MULTICAST(wh->i_addr1))
4884 txwi->bawin_size_xflags |=
4885 (RT2870_TXWI_XFLAGS_ACK << RT2870_TXWI_XFLAGS_SHIFT);
4887 if (ni->ni_flags & IEEE80211_NODE_HT)
4889 /* preamble + plcp + signal extension + SIFS */
4891 dur = 16 + 4 + 6 + 10;
4893 else
4895 dur = ieee80211_ack_duration(ic->ic_rt, rate,
4896 ic->ic_flags & IEEE80211_F_SHPREAMBLE);
4899 *(uint16_t *) wh->i_dur = htole16(dur);
4902 /* ask MAC to insert timestamp into probe responses */
4904 if ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
4905 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
4906 txwi->mpdu_density_flags |=
4907 (RT2870_TXWI_FLAGS_TS << RT2870_TXWI_FLAGS_SHIFT);
4909 if (ieee80211_radiotap_active_vap(vap))
4911 tap = &sc->txtap;
4913 tap->flags = IEEE80211_RADIOTAP_F_DATAPAD;
4914 tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
4915 tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
4916 tap->chan_ieee = ic->ic_curchan->ic_ieee;
4917 tap->chan_maxpow = 0;
4919 if (ni->ni_flags & IEEE80211_NODE_HT)
4920 tap->rate = mcs | IEEE80211_RATE_MCS;
4921 else
4922 tap->rate = rate;
4924 if (mcs & RT2870_TXWI_MCS_SHOTPRE)
4925 tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
4927 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4928 tap->flags |= IEEE80211_RADIOTAP_F_WEP;
4930 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4932 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
4934 ieee80211_radiotap_tx(vap, m);
4936 wh->i_fc[1] |= IEEE80211_FC1_WEP;
4938 else
4940 ieee80211_radiotap_tx(vap, m);
4944 m_copydata(m, 0, m->m_pkthdr.len, (caddr_t) (txwi + 1));
4946 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4947 "%s: sending MGMT frame: qid=%d, hdrsize=%d, hdrspace=%d, len=%d, "
4948 "mcs=%d, mimops=%d, DMA len=%d\n",
4949 device_get_nameunit(sc->dev),
4950 qid, hdrsize, hdrspace, m->m_pkthdr.len, mcs, mimops, dmalen);
4952 data->len = dmalen;
4953 data->m = m;
4954 data->ni = ni;
4956 STAILQ_INSERT_TAIL(&ring->pending, data, next);
4957 ring->queued++;
4959 usbd_transfer_start(sc->usb_xfer[1 + qid]);
4961 return 0;
4965 * rt2870_tx_data
4967 static int rt2870_tx_data(struct rt2870_softc *sc,
4968 struct mbuf *m, struct ieee80211_node *ni, int qid)
4970 struct ifnet *ifp;
4971 struct ieee80211com *ic;
4972 struct ieee80211vap *vap;
4973 const struct ieee80211_txparam *tp;
4974 struct rt2870_softc_node *rni;
4975 struct rt2870_softc_tx_ring *ring;
4976 struct rt2870_softc_tx_data *data;
4977 struct rt2870_txinfo *txinfo;
4978 struct rt2870_txwi *txwi;
4979 struct ieee80211_frame *wh;
4980 struct ieee80211_tx_ampdu *tx_ampdu;
4981 ieee80211_seq seqno;
4982 struct rt2870_softc_tx_radiotap_header *tap;
4983 u_int hdrsize, hdrspace;
4984 uint8_t type, rate, bw, stbc, shortgi, mcs, pid, wcid, mpdu_density, bawin_size;
4985 uint16_t qos, len, dmalen, mpdu_len, dur;
4986 int hasqos, ac, tid, ampdu, mimops;
4988 KASSERT(qid >= 0 && qid < (sc->usb_endpoints - 1),
4989 ("%s: Tx data: invalid qid=%d\n",
4990 device_get_nameunit(sc->dev), qid));
4992 ifp = sc->ifp;
4993 ic = ifp->if_l2com;
4994 vap = ni->ni_vap;
4995 rni = (struct rt2870_softc_node *) ni;
4996 tp = ni->ni_txparms;
4998 ring = &sc->tx_ring[qid];
4999 data = STAILQ_FIRST(&ring->inactive);
5000 STAILQ_REMOVE_HEAD(&ring->inactive, next);
5001 txinfo = (struct rt2870_txinfo *) data->buf;
5002 txwi = (struct rt2870_txwi *) (txinfo + 1);
5004 wh = mtod(m, struct ieee80211_frame *);
5006 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
5008 hasqos = IEEE80211_QOS_HAS_SEQ(wh);
5009 if (hasqos)
5011 if (IEEE80211_HAS_ADDR4(wh))
5012 qos = le16toh(*(const uint16_t *)
5013 (((struct ieee80211_qosframe_addr4 *) wh)->i_qos));
5014 else
5015 qos = le16toh(*(const uint16_t *)
5016 (((struct ieee80211_qosframe *) wh)->i_qos));
5018 else
5020 qos = 0;
5023 if (IEEE80211_IS_MULTICAST(wh->i_addr1))
5024 rate = tp->mcastrate;
5025 else if (m->m_flags & M_EAPOL)
5026 rate = tp->mgmtrate;
5027 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
5028 rate = tp->ucastrate;
5029 else
5030 rate = ni->ni_txrate;
5032 rate &= IEEE80211_RATE_VAL;
5034 len = sizeof(struct rt2870_txinfo) + sizeof(struct rt2870_txwi) + m->m_pkthdr.len;
5036 /* align end on a 4-bytes boundary */
5038 dmalen = (len + 3) & ~3;
5040 /* fill Tx info */
5042 memset(txinfo, 0, sizeof(struct rt2870_txinfo));
5044 txinfo->len = htole16(dmalen - sizeof(struct rt2870_txinfo));
5046 txinfo->qsel_flags = (RT2870_TXINFO_QSEL_EDCA << RT2870_TXINFO_QSEL_SHIFT);
5048 dmalen += 4;
5050 memset((caddr_t) txinfo + len, 0, dmalen - len);
5052 /* fill Tx wireless info */
5054 if (ni->ni_flags & IEEE80211_NODE_HT)
5055 mcs = rate;
5056 else
5057 mcs = rt2870_rate2mcs(rate);
5059 if (type == IEEE80211_FC0_TYPE_DATA)
5060 wcid = !IEEE80211_IS_MULTICAST(wh->i_addr1) ? rni->staid : RT2870_WCID_MCAST;
5061 else
5062 wcid = RT2870_WCID_RESERVED;
5064 /* calculate MPDU length without padding */
5066 hdrsize = ieee80211_anyhdrsize(wh);
5067 hdrspace = ieee80211_anyhdrspace(ic, wh);
5068 mpdu_len = m->m_pkthdr.len - hdrspace + hdrsize;
5070 memset(txwi, 0, sizeof(struct rt2870_txwi));
5072 txwi->wcid = wcid;
5074 /* MIMO power save */
5076 if ((ni->ni_flags & IEEE80211_NODE_HT) && (ni->ni_flags & IEEE80211_NODE_MIMO_PS))
5078 if (mcs > 7)
5080 if (ni->ni_flags & IEEE80211_NODE_MIMO_RTS)
5082 /* dynamic MIMO power save */
5084 txwi->mpdu_density_flags |=
5085 (RT2870_TXWI_FLAGS_MIMOPS << RT2870_TXWI_FLAGS_SHIFT);
5087 else
5089 /* static MIMO power save */
5091 mcs = 7;
5095 mimops = 1;
5097 else
5099 mimops = 0;
5102 pid = (mcs < 0xf) ? (mcs + 1) : mcs;
5104 txwi->pid_mpdu_len = ((htole16(pid) & RT2870_TXWI_PID_MASK) <<
5105 RT2870_TXWI_PID_SHIFT) | ((htole16(mpdu_len) & RT2870_TXWI_MPDU_LEN_MASK) <<
5106 RT2870_TXWI_MPDU_LEN_SHIFT);
5108 stbc = sc->tx_stbc && (mcs <= 7) && (vap->iv_htcaps & IEEE80211_HTCAP_TXSTBC) &&
5109 (ni->ni_flags & IEEE80211_NODE_HT) && (ni->ni_htcap & IEEE80211_HTCAP_RXSTBC);
5111 shortgi = ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) && (ni->ni_flags & IEEE80211_NODE_SGI20) && (ni->ni_chw == 20)) ||
5112 ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) && (ni->ni_flags & IEEE80211_NODE_SGI40) && (ni->ni_chw == 40));
5114 txwi->phymode_ifs_stbc_shortgi |=
5115 ((stbc & RT2870_TXWI_STBC_MASK) << RT2870_TXWI_STBC_SHIFT) |
5116 ((shortgi & RT2870_TXWI_SHORTGI_MASK) << RT2870_TXWI_SHORTGI_SHIFT);
5118 if (ni->ni_flags & IEEE80211_NODE_HT)
5120 txwi->phymode_ifs_stbc_shortgi |=
5121 (RT2870_TXWI_PHYMODE_HT_MIXED << RT2870_TXWI_PHYMODE_SHIFT);
5123 else
5125 if (ieee80211_rate2phytype(ic->ic_rt, rate) != IEEE80211_T_OFDM)
5127 txwi->phymode_ifs_stbc_shortgi |=
5128 (RT2870_TXWI_PHYMODE_CCK << RT2870_TXWI_PHYMODE_SHIFT);
5130 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
5131 mcs |= RT2870_TXWI_MCS_SHOTPRE;
5133 else
5135 txwi->phymode_ifs_stbc_shortgi |=
5136 (RT2870_TXWI_PHYMODE_OFDM << RT2870_TXWI_PHYMODE_SHIFT);
5140 if ((ni->ni_flags & IEEE80211_NODE_HT) && (ni->ni_chw == 40))
5141 bw = RT2870_TXWI_BW_40;
5142 else
5143 bw = RT2870_TXWI_BW_20;
5145 txwi->bw_mcs = ((bw & RT2870_TXWI_BW_MASK) << RT2870_TXWI_BW_SHIFT) |
5146 ((mcs & RT2870_TXWI_MCS_MASK) << RT2870_TXWI_MCS_SHIFT);
5148 txwi->txop = (RT2870_TXWI_TXOP_HT << RT2870_TXWI_TXOP_SHIFT);
5150 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
5151 (!hasqos || (qos & IEEE80211_QOS_ACKPOLICY) != IEEE80211_QOS_ACKPOLICY_NOACK))
5153 txwi->bawin_size_xflags |=
5154 (RT2870_TXWI_XFLAGS_ACK << RT2870_TXWI_XFLAGS_SHIFT);
5156 if (ni->ni_flags & IEEE80211_NODE_HT)
5158 /* preamble + plcp + signal extension + SIFS */
5160 dur = 16 + 4 + 6 + 10;
5162 else
5164 dur = ieee80211_ack_duration(ic->ic_rt, rate,
5165 ic->ic_flags & IEEE80211_F_SHPREAMBLE);
5168 *(uint16_t *) wh->i_dur = htole16(dur);
5171 /* check fo A-MPDU */
5173 if (m->m_flags & M_AMPDU_MPDU)
5175 ac = M_WME_GETAC(m);
5176 tid = WME_AC_TO_TID(ac);
5177 tx_ampdu = &ni->ni_tx_ampdu[ac];
5179 mpdu_density = RT2870_MS(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY);
5180 bawin_size = tx_ampdu->txa_wnd;
5182 txwi->mpdu_density_flags |=
5183 ((mpdu_density & RT2870_TXWI_MPDU_DENSITY_MASK) << RT2870_TXWI_MPDU_DENSITY_SHIFT) |
5184 (RT2870_TXWI_FLAGS_AMPDU << RT2870_TXWI_FLAGS_SHIFT);
5186 txwi->bawin_size_xflags |=
5187 ((bawin_size & RT2870_TXWI_BAWIN_SIZE_MASK) << RT2870_TXWI_BAWIN_SIZE_SHIFT);
5189 seqno = ni->ni_txseqs[tid]++;
5191 *(uint16_t *) &wh->i_seq[0] = htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
5193 ampdu = 1;
5195 else
5197 mpdu_density = 0;
5198 bawin_size = 0;
5199 ampdu = 0;
5202 /* ask MAC to insert timestamp into probe responses */
5204 if ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
5205 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
5206 txwi->mpdu_density_flags |=
5207 (RT2870_TXWI_FLAGS_TS << RT2870_TXWI_FLAGS_SHIFT);
5209 if (ieee80211_radiotap_active_vap(vap))
5211 tap = &sc->txtap;
5213 tap->flags = IEEE80211_RADIOTAP_F_DATAPAD;
5214 tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
5215 tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
5216 tap->chan_ieee = ic->ic_curchan->ic_ieee;
5217 tap->chan_maxpow = 0;
5219 if (ni->ni_flags & IEEE80211_NODE_HT)
5220 tap->rate = mcs | IEEE80211_RATE_MCS;
5221 else
5222 tap->rate = rate;
5224 if (mcs & RT2870_TXWI_MCS_SHOTPRE)
5225 tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
5227 if (shortgi)
5228 tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
5230 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
5231 tap->flags |= IEEE80211_RADIOTAP_F_WEP;
5233 /* XXX use temporarily radiotap CFP flag as A-MPDU flag */
5235 if (ampdu)
5236 tap->flags |= IEEE80211_RADIOTAP_F_CFP;
5238 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
5240 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
5242 ieee80211_radiotap_tx(vap, m);
5244 wh->i_fc[1] |= IEEE80211_FC1_WEP;
5246 else
5248 ieee80211_radiotap_tx(vap, m);
5252 m_copydata(m, 0, m->m_pkthdr.len, (caddr_t) (txwi + 1));
5254 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
5255 "%s: sending data: qid=%d, hdrsize=%d, hdrspace=%d, len=%d, "
5256 "bw=%d, stbc=%d, shortgi=%d, mcs=%d, wcid=0x%02x, "
5257 "ampdu=%d (density=%d, winsize=%d), mimops=%d, DMA len=%d\n",
5258 device_get_nameunit(sc->dev),
5259 qid, hdrsize, hdrspace, m->m_pkthdr.len,
5260 bw, stbc, shortgi, mcs, wcid,
5261 ampdu, mpdu_density, bawin_size, mimops, dmalen);
5263 data->len = dmalen;
5264 data->m = m;
5265 data->ni = ni;
5267 STAILQ_INSERT_TAIL(&ring->pending, data, next);
5268 ring->queued++;
5270 usbd_transfer_start(sc->usb_xfer[1 + qid]);
5272 return 0;
5276 * rt2870_tx_raw
5278 static int rt2870_tx_raw(struct rt2870_softc *sc,
5279 struct mbuf *m, struct ieee80211_node *ni,
5280 const struct ieee80211_bpf_params *params)
5282 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
5283 "%s: Tx raw\n",
5284 device_get_nameunit(sc->dev));
5286 return 0;
5290 * rt2870_rx_intr
5292 static void rt2870_rx_intr(struct usb_xfer *xfer, usb_error_t error)
5294 struct rt2870_softc *sc;
5295 struct ifnet *ifp;
5296 struct rt2870_softc_rx_ring *ring;
5297 struct rt2870_softc_rx_data *data;
5298 int len;
5300 sc = usbd_xfer_softc(xfer);
5301 ifp = sc->ifp;
5302 ring = &sc->rx_ring;
5304 RT2870_DPRINTF(sc, RT2870_DEBUG_INTR,
5305 "%s: Rx interrupt: state=%d, error=%s\n",
5306 device_get_nameunit(sc->dev),
5307 USB_GET_STATE(xfer), usbd_errstr(error));
5309 switch (USB_GET_STATE(xfer))
5311 case USB_ST_TRANSFERRED:
5312 sc->interrupts++;
5313 sc->rx_interrupts++;
5315 data = STAILQ_FIRST(&ring->active);
5316 if (data == NULL)
5317 goto setup;
5319 STAILQ_REMOVE_HEAD(&ring->active, next);
5321 usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
5323 data->len = len;
5325 STAILQ_INSERT_TAIL(&ring->done, data, next);
5327 taskqueue_enqueue(sc->taskqueue, &sc->rx_done_task);
5329 /* FALLTHROUGH */
5331 setup:
5333 case USB_ST_SETUP:
5334 data = STAILQ_FIRST(&ring->inactive);
5335 if (data == NULL)
5336 break;
5338 STAILQ_REMOVE_HEAD(&ring->inactive, next);
5340 STAILQ_INSERT_TAIL(&ring->active, data, next);
5342 usbd_xfer_set_frame_data(xfer, 0, data->buf, usbd_xfer_max_len(xfer));
5343 usbd_transfer_submit(xfer);
5344 break;
5346 default:
5347 sc->interrupts++;
5348 sc->rx_interrupts++;
5350 data = STAILQ_FIRST(&ring->active);
5351 if (data != NULL)
5353 STAILQ_REMOVE_HEAD(&ring->active, next);
5354 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5357 if (error != USB_ERR_CANCELLED)
5359 ifp->if_ierrors++;
5361 usbd_xfer_set_stall(xfer);
5363 goto setup;
5365 break;
5370 * rt2870_tx_intr
5372 static void rt2870_tx_intr(struct usb_xfer *xfer, usb_error_t error)
5374 struct rt2870_softc *sc;
5375 struct ifnet *ifp;
5376 struct rt2870_softc_tx_ring *ring;
5377 struct rt2870_softc_tx_data *data;
5379 sc = usbd_xfer_softc(xfer);
5380 ifp = sc->ifp;
5381 ring = usbd_xfer_get_priv(xfer);
5383 usbd_xfer_status(xfer, NULL, NULL, NULL, NULL);
5385 RT2870_DPRINTF(sc, RT2870_DEBUG_INTR,
5386 "%s: Tx interrupt: state=%d, error=%s\n",
5387 device_get_nameunit(sc->dev),
5388 USB_GET_STATE(xfer), usbd_errstr(error));
5390 switch (USB_GET_STATE(xfer))
5392 case USB_ST_TRANSFERRED:
5393 sc->interrupts++;
5394 sc->tx_interrupts[ring->qid]++;
5396 data = STAILQ_FIRST(&ring->active);
5397 if (data == NULL)
5398 goto setup;
5400 STAILQ_REMOVE_HEAD(&ring->active, next);
5402 STAILQ_INSERT_TAIL(&ring->done, data, next);
5404 sc->tx_qid_pending_mask |= (1 << ring->qid);
5406 taskqueue_enqueue(sc->taskqueue, &sc->tx_done_task);
5408 /* FALLTHROUGH */
5410 setup:
5412 case USB_ST_SETUP:
5413 data = STAILQ_FIRST(&ring->pending);
5414 if (data == NULL)
5415 break;
5417 STAILQ_REMOVE_HEAD(&ring->pending, next);
5418 STAILQ_INSERT_TAIL(&ring->active, data, next);
5420 usbd_xfer_set_frame_data(xfer, 0, data->buf, data->len);
5421 usbd_transfer_submit(xfer);
5423 RT2870_SOFTC_UNLOCK(sc);
5425 rt2870_start(ifp);
5427 RT2870_SOFTC_LOCK(sc);
5428 break;
5430 default:
5431 sc->interrupts++;
5432 sc->tx_interrupts[ring->qid]++;
5434 data = STAILQ_FIRST(&ring->active);
5435 if (data != NULL)
5437 STAILQ_REMOVE_HEAD(&ring->active, next);
5439 printf("%s: could not transmit buffer: qid=%d, error=%s\n",
5440 device_get_nameunit(sc->dev), ring->qid, usbd_errstr(error));
5442 if (data->m != NULL)
5444 m_freem(data->m);
5445 data->m = NULL;
5448 if (data->ni != NULL)
5450 ieee80211_free_node(data->ni);
5451 data->ni = NULL;
5454 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5456 ring->queued--;
5459 if (error != USB_ERR_CANCELLED)
5461 ifp->if_oerrors++;
5462 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
5464 usbd_xfer_set_stall(xfer);
5466 goto setup;
5468 break;
5473 * rt2870_rx_done_task
5475 static void rt2870_rx_done_task(void *context, int pending)
5477 struct rt2870_softc *sc;
5478 struct ifnet *ifp;
5480 sc = context;
5481 ifp = sc->ifp;
5483 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
5484 "%s: Rx done task\n",
5485 device_get_nameunit(sc->dev));
5487 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
5488 return;
5490 if (rt2870_rx_eof(sc, sc->rx_process_limit) != 0)
5492 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
5493 "%s: Rx done task: scheduling again\n",
5494 device_get_nameunit(sc->dev));
5496 taskqueue_enqueue(sc->taskqueue, &sc->rx_done_task);
5501 * rt2870_tx_done_task
5503 static void rt2870_tx_done_task(void *context, int pending)
5505 struct rt2870_softc *sc;
5506 struct ifnet *ifp;
5507 int i;
5509 sc = context;
5510 ifp = sc->ifp;
5512 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
5513 "%s: Tx done task\n",
5514 device_get_nameunit(sc->dev));
5516 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
5517 return;
5519 for (i = sc->usb_endpoints - 2; i >= 0; i--)
5521 if (sc->tx_qid_pending_mask & (1 << i))
5523 sc->tx_qid_pending_mask &= ~(1 << i);
5525 rt2870_tx_eof(sc, &sc->tx_ring[i]);
5529 if (sc->tx_qid_pending_mask != 0)
5531 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
5532 "%s: Tx done task: scheduling again\n",
5533 device_get_nameunit(sc->dev));
5535 taskqueue_enqueue(sc->taskqueue, &sc->tx_done_task);
5538 sc->tx_timer = 0;
5540 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
5544 * rt2870_periodic_task
5546 static void rt2870_periodic_task(void *context, int pending)
5548 struct rt2870_softc *sc;
5549 struct ifnet *ifp;
5550 struct ieee80211com *ic;
5551 struct ieee80211vap *vap;
5553 sc = context;
5554 ifp = sc->ifp;
5555 ic = ifp->if_l2com;
5556 vap = TAILQ_FIRST(&ic->ic_vaps);
5558 RT2870_DPRINTF(sc, RT2870_DEBUG_PERIODIC,
5559 "%s: periodic task: round=%lu\n",
5560 device_get_nameunit(sc->dev), sc->periodic_round);
5562 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
5563 return;
5565 RT2870_SOFTC_LOCK(sc);
5567 sc->periodic_round++;
5569 rt2870_update_stats(sc);
5571 if ((sc->periodic_round % 10) == 0)
5573 rt2870_bbp_tuning(sc);
5575 rt2870_update_raw_counters(sc);
5577 rt2870_watchdog(sc);
5579 if (vap != NULL && vap->iv_opmode != IEEE80211_M_MONITOR && vap->iv_state == IEEE80211_S_RUN)
5581 if (vap->iv_opmode == IEEE80211_M_STA)
5582 rt2870_amrr_update_iter_func(vap, vap->iv_bss);
5583 else
5584 ieee80211_iterate_nodes(&ic->ic_sta, rt2870_amrr_update_iter_func, vap);
5588 RT2870_SOFTC_UNLOCK(sc);
5590 callout_reset(&sc->periodic_ch, hz / 10, rt2870_periodic, sc);
5594 * rt2870_cmd_task
5596 static void rt2870_cmd_task(void *context, int pending)
5598 struct rt2870_softc *sc;
5599 struct rt2870_softc_cmd_ring *ring;
5600 struct rt2870_softc_cmd *cmd;
5602 sc = context;
5603 ring = &sc->cmd_ring;
5605 while (1)
5607 if (!(sc->flags & RT2870_SOFTC_FLAGS_VALID))
5608 break;
5610 RT2870_SOFTC_LOCK(sc);
5612 cmd = STAILQ_FIRST(&ring->active);
5613 if (cmd == NULL)
5615 RT2870_SOFTC_UNLOCK(sc);
5616 break;
5619 STAILQ_REMOVE_HEAD(&ring->active, next);
5621 RT2870_SOFTC_UNLOCK(sc);
5623 cmd->cb(sc, cmd->data);
5625 RT2870_SOFTC_LOCK(sc);
5627 STAILQ_INSERT_TAIL(&ring->inactive, cmd, next);
5628 ring->queued--;
5630 RT2870_SOFTC_UNLOCK(sc);
5635 * rt2870_rx_eof
5637 static int rt2870_rx_eof(struct rt2870_softc *sc, int limit)
5639 struct ifnet *ifp;
5640 struct rt2870_softc_rx_ring *ring;
5641 struct rt2870_softc_rx_data *data;
5642 uint32_t dmalen;
5643 uint8_t *buf;
5644 int nframes, len;
5646 ifp = sc->ifp;
5647 ring = &sc->rx_ring;
5649 nframes = 0;
5651 while (limit != 0)
5653 RT2870_SOFTC_LOCK(sc);
5655 data = STAILQ_FIRST(&ring->done);
5656 if (data == NULL)
5658 RT2870_SOFTC_UNLOCK(sc);
5659 break;
5662 STAILQ_REMOVE_HEAD(&ring->done, next);
5664 RT2870_SOFTC_UNLOCK(sc);
5666 buf = data->buf;
5667 len = data->len;
5669 if (len < RT2870_RX_DESC_SIZE)
5671 ifp->if_ierrors++;
5672 goto skip;
5675 while (len > (sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)))
5677 dmalen = (le32toh(*(uint32_t *) buf) & 0xffff);
5679 if (dmalen == 0 || (dmalen & 3) != 0)
5681 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
5682 "%s: bad DMA len=%u\n",
5683 device_get_nameunit(sc->dev), dmalen);
5684 goto skip;
5687 if ((dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)) > len)
5689 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
5690 "%s: bad DMA len: DMA len=%u, USB len=%d\n",
5691 device_get_nameunit(sc->dev),
5692 (unsigned int) (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)), len);
5693 goto skip;
5696 nframes++;
5698 rt2870_rx_frame(sc, buf + sizeof(uint32_t), dmalen);
5700 buf += (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo));
5701 len -= (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo));
5704 skip:
5706 RT2870_SOFTC_LOCK(sc);
5708 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5710 usbd_transfer_start(sc->usb_xfer[0]);
5712 RT2870_SOFTC_UNLOCK(sc);
5714 limit--;
5717 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
5718 "%s: Rx eof: nframes=%d\n",
5719 device_get_nameunit(sc->dev), nframes);
5721 sc->rx_packets += nframes;
5723 return (limit == 0);
5727 * rt2870_tx_eof
5729 static void rt2870_tx_eof(struct rt2870_softc *sc,
5730 struct rt2870_softc_tx_ring *ring)
5732 struct ifnet *ifp;
5733 struct rt2870_softc_tx_data *data;
5734 int nframes;
5736 ifp = sc->ifp;
5738 nframes = 0;
5740 while (1)
5742 RT2870_SOFTC_LOCK(sc);
5744 data = STAILQ_FIRST(&ring->done);
5745 if (data == NULL)
5747 RT2870_SOFTC_UNLOCK(sc);
5748 break;
5751 STAILQ_REMOVE_HEAD(&ring->done, next);
5753 rt2870_drain_fifo_stats(sc);
5755 RT2870_SOFTC_UNLOCK(sc);
5757 nframes++;
5759 if (data->m->m_flags & M_TXCB)
5760 ieee80211_process_callback(data->ni, data->m, 0);
5762 m_freem(data->m);
5764 ieee80211_free_node(data->ni);
5766 data->m = NULL;
5767 data->ni = NULL;
5769 RT2870_SOFTC_LOCK(sc);
5771 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5773 ring->queued--;
5774 ifp->if_opackets++;
5776 RT2870_SOFTC_UNLOCK(sc);
5779 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
5780 "%s: Tx eof: qid=%d, nframes=%d\n",
5781 device_get_nameunit(sc->dev), ring->qid, nframes);
5785 * rt2870_update_stats
5787 static void rt2870_update_stats(struct rt2870_softc *sc)
5789 struct ifnet *ifp;
5790 struct ieee80211com *ic;
5791 uint32_t stacnt[3];
5792 int beacons, noretryok, retryok, failed, underflows, zerolen;
5794 ifp = sc->ifp;
5795 ic = ifp->if_l2com;
5797 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
5798 "%s: update statistic\n",
5799 device_get_nameunit(sc->dev));
5801 rt2870_drain_fifo_stats(sc);
5803 /* read and clear Tx statistic registers */
5805 rt2870_io_mac_read_multi(sc, RT2870_REG_TX_STA_CNT0,
5806 stacnt, sizeof(stacnt));
5808 stacnt[0] = le32toh(stacnt[0]);
5809 stacnt[1] = le32toh(stacnt[1]);
5810 stacnt[2] = le32toh(stacnt[2]);
5812 beacons = stacnt[0] >> 16;
5813 noretryok = stacnt[1] & 0xffff;
5814 retryok = stacnt[1] >> 16;
5815 failed = stacnt[0] & 0xffff;
5816 underflows = stacnt[2] >> 16;
5817 zerolen = stacnt[2] & 0xffff;
5819 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
5820 "%s: update statistic: beacons=%d, noretryok=%d, retryok=%d, failed=%d, underflows=%d, zerolen=%d\n",
5821 device_get_nameunit(sc->dev),
5822 beacons, noretryok, retryok, failed, underflows, zerolen);
5824 ifp->if_oerrors += failed;
5826 sc->tx_beacons += beacons;
5827 sc->tx_noretryok += noretryok;
5828 sc->tx_retryok += retryok;
5829 sc->tx_failed += failed;
5830 sc->tx_underflows += underflows;
5831 sc->tx_zerolen += zerolen;
5835 * rt2870_bbp_tuning
5837 static void rt2870_bbp_tuning(struct rt2870_softc *sc)
5839 struct ifnet *ifp;
5840 struct ieee80211com *ic;
5841 struct ieee80211vap *vap;
5842 struct ieee80211_node *ni;
5843 int chan, group;
5844 int8_t rssi, old, new;
5846 /* RT2860C does not support BBP tuning */
5848 if (sc->mac_rev == 0x28600100)
5849 return;
5851 ifp = sc->ifp;
5852 ic = ifp->if_l2com;
5853 vap = TAILQ_FIRST(&ic->ic_vaps);
5855 if ((ic->ic_flags & IEEE80211_F_SCAN) || vap == NULL ||
5856 vap->iv_opmode != IEEE80211_M_STA || vap->iv_state != IEEE80211_S_RUN)
5857 return;
5859 ni = vap->iv_bss;
5861 chan = ieee80211_chan2ieee(ic, ni->ni_chan);
5863 if (chan <= 14)
5864 group = 0;
5865 else if (chan <= 64)
5866 group = 1;
5867 else if (chan <= 128)
5868 group = 2;
5869 else
5870 group = 3;
5872 rssi = ieee80211_getrssi(vap);
5874 if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
5876 new = 0x2e + sc->lna_gain[group];
5878 else
5880 if (!IEEE80211_IS_CHAN_HT40(ni->ni_chan))
5881 new = 0x32 + sc->lna_gain[group] * 5 / 3;
5882 else
5883 new = 0x3a + sc->lna_gain[group] * 5 / 3;
5886 /* Tune if absolute average RSSI is greater than -80 */
5888 if (rssi > 30)
5889 new += 0x10;
5891 old = rt2870_io_bbp_read(sc, 66);
5893 if (old != new)
5894 rt2870_io_bbp_write(sc, 66, new);
5898 * rt2870_watchdog
5900 static void rt2870_watchdog(struct rt2870_softc *sc)
5902 uint32_t tmp;
5903 int ntries;
5905 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
5907 RT2870_DPRINTF(sc, RT2870_DEBUG_WATCHDOG,
5908 "%s: watchdog: TXRXQ_PCNT=0x%08x\n",
5909 device_get_nameunit(sc->dev), tmp);
5911 if (((tmp >> RT2870_REG_TX0Q_PCNT_SHIFT) & RT2870_REG_TX0Q_PCNT_MASK) != 0)
5913 sc->tx_queue_not_empty[0]++;
5915 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40012);
5917 for (ntries = 0; ntries < 10; ntries++)
5919 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
5920 if (((tmp >> RT2870_REG_TX0Q_PCNT_SHIFT) & RT2870_REG_TX0Q_PCNT_MASK) == 0)
5921 break;
5923 DELAY(1);
5926 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40006);
5929 if (((tmp >> RT2870_REG_TX1Q_PCNT_SHIFT) & RT2870_REG_TX1Q_PCNT_MASK) != 0)
5931 sc->tx_queue_not_empty[1]++;
5933 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf4000a);
5935 for (ntries = 0; ntries < 10; ntries++)
5937 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
5938 if (((tmp >> RT2870_REG_TX1Q_PCNT_SHIFT) & RT2870_REG_TX1Q_PCNT_MASK) == 0)
5939 break;
5941 DELAY(1);
5944 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40006);
5949 * rt2870_drain_fifo_stats
5951 static void rt2870_drain_fifo_stats(struct rt2870_softc *sc)
5953 struct ifnet *ifp;
5954 uint32_t stats;
5955 uint8_t wcid, mcs, pid;
5956 int ok, agg, retrycnt;
5958 ifp = sc->ifp;
5960 /* drain Tx status FIFO (maxsize = 16) */
5962 while ((sc->flags & RT2870_SOFTC_FLAGS_VALID) &&
5963 ((stats = rt2870_io_mac_read(sc, RT2870_REG_TX_STA_FIFO)) &
5964 RT2870_REG_TX_STA_FIFO_VALID))
5966 wcid = (stats >> RT2870_REG_TX_STA_FIFO_WCID_SHIFT) &
5967 RT2870_REG_TX_STA_FIFO_WCID_MASK;
5969 /* if no ACK was requested, no feedback is available */
5971 if (!(stats & RT2870_REG_TX_STA_FIFO_ACK_REQ) || wcid == RT2870_WCID_RESERVED)
5972 continue;
5974 /* update AMRR statistic */
5976 ok = (stats & RT2870_REG_TX_STA_FIFO_TX_OK) ? 1 : 0;
5977 agg = (stats & RT2870_REG_TX_STA_FIFO_AGG) ? 1 : 0;
5978 mcs = (stats >> RT2870_REG_TX_STA_FIFO_MCS_SHIFT) &
5979 RT2870_REG_TX_STA_FIFO_MCS_MASK;
5980 pid = (stats >> RT2870_REG_TX_STA_FIFO_PID_SHIFT) &
5981 RT2870_REG_TX_STA_FIFO_PID_MASK;
5982 retrycnt = (mcs < 0xf) ? (pid - mcs - 1) : 0;
5984 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
5985 "%s: FIFO statistic: wcid=0x%02x, ok=%d, agg=%d, mcs=0x%02x, pid=0x%02x, retrycnt=%d\n",
5986 device_get_nameunit(sc->dev),
5987 wcid, ok, agg, mcs, pid, retrycnt);
5989 rt2870_amrr_tx_complete(&sc->amrr_node[wcid], ok, retrycnt);
5991 if (!ok)
5992 ifp->if_oerrors++;
5997 * rt2870_update_raw_counters
5999 static void rt2870_update_raw_counters(struct rt2870_softc *sc)
6001 uint32_t tmp;
6003 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT);
6005 sc->tx_nonagg += tmp & 0xffff;
6006 sc->tx_agg += tmp >> 16;
6008 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT0);
6010 sc->tx_ampdu += (tmp & 0xffff) / 1 + (tmp >> 16) / 2;
6012 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT1);
6014 sc->tx_ampdu += (tmp & 0xffff) / 3 + (tmp >> 16) / 4;
6016 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT2);
6018 sc->tx_ampdu += (tmp & 0xffff) / 5 + (tmp >> 16) / 6;
6020 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT3);
6022 sc->tx_ampdu += (tmp & 0xffff) / 7 + (tmp >> 16) / 8;
6024 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT4);
6026 sc->tx_ampdu += (tmp & 0xffff) / 9 + (tmp >> 16) / 10;
6028 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT5);
6030 sc->tx_ampdu += (tmp & 0xffff) / 11 + (tmp >> 16) / 12;
6032 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT6);
6034 sc->tx_ampdu += (tmp & 0xffff) / 13 + (tmp >> 16) / 14;
6036 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT7);
6038 sc->tx_ampdu += (tmp & 0xffff) / 15 + (tmp >> 16) / 16;
6040 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT0);
6042 sc->rx_crc_errors += tmp & 0xffff;
6043 sc->rx_phy_errors += tmp >> 16;
6045 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT1);
6047 sc->rx_false_ccas += tmp & 0xffff;
6048 sc->rx_plcp_errors += tmp >> 16;
6050 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT2);
6052 sc->rx_dup_packets += tmp & 0xffff;
6053 sc->rx_fifo_overflows += tmp >> 16;
6055 tmp = rt2870_io_mac_read(sc, RT2870_REG_TXRX_MPDU_DEN_CNT);
6057 sc->tx_mpdu_zero_density += tmp & 0xffff;
6058 sc->rx_mpdu_zero_density += tmp >> 16;
6062 * rt2870_txrx_enable
6064 static int rt2870_txrx_enable(struct rt2870_softc *sc)
6066 struct ieee80211com *ic;
6067 struct ifnet *ifp;
6068 uint32_t tmp;
6069 int ntries;
6071 ifp = sc->ifp;
6072 ic = ifp->if_l2com;
6074 /* enable Tx/Rx DMA engine */
6076 tmp = rt2870_io_mac_read(sc, RT2870_REG_SCHDMA_USB_CYC_CFG);
6078 tmp &= 0xffffff00;
6079 tmp |= 0x1e;
6081 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_CYC_CFG, tmp);
6083 if ((sc->mac_rev & 0xffff) != 0x0101)
6084 rt2870_io_mac_write(sc, RT2870_REG_TX_TXOP_CTRL_CFG, 0x583f);
6086 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, RT2870_REG_TX_ENABLE);
6088 for (ntries = 0; ntries < 200; ntries++)
6090 tmp = rt2870_io_mac_read(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG);
6091 if (!(tmp & (RT2870_REG_TX_DMA_BUSY | RT2870_REG_RX_DMA_BUSY)))
6092 break;
6094 DELAY(1000);
6097 if (ntries == 200)
6099 printf("%s: timeout waiting for DMA engine\n",
6100 device_get_nameunit(sc->dev));
6101 return -1;
6104 DELAY(50);
6106 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP0_CFG, 0);
6107 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP1_CFG,
6108 (48 << 16) | 96);
6110 tmp |= RT2870_REG_TX_WB_DDONE |
6111 RT2870_REG_RX_DMA_ENABLE |
6112 RT2870_REG_TX_DMA_ENABLE;
6114 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
6116 tmp = RT2870_REG_USB_DMA_TX_ENABLE |
6117 RT2870_REG_USB_DMA_RX_ENABLE |
6118 RT2870_REG_USB_DMA_RX_AGG_ENABLE |
6119 /* Rx agg limit in unit of 1024 byte */
6120 ((RT2870_USB_RX_BULK_BUFLEN / 1024 - 3) << RT2870_REG_USB_DMA_RX_AGG_LIMIT_SHIFT) |
6121 /* Rx agg timeout in unit of 33ns */
6122 0x80;
6124 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_DMA_CFG, tmp);
6126 /* set Rx filter */
6128 tmp = RT2870_REG_RX_FILTER_DROP_CRC_ERR |
6129 RT2870_REG_RX_FILTER_DROP_PHY_ERR;
6131 if (ic->ic_opmode != IEEE80211_M_MONITOR)
6133 tmp |= RT2870_REG_RX_FILTER_DROP_DUPL |
6134 RT2870_REG_RX_FILTER_DROP_CTS |
6135 RT2870_REG_RX_FILTER_DROP_BA |
6136 RT2870_REG_RX_FILTER_DROP_ACK |
6137 RT2870_REG_RX_FILTER_DROP_VER_ERR |
6138 RT2870_REG_RX_FILTER_DROP_CTRL_RSV |
6139 RT2870_REG_RX_FILTER_DROP_CFACK |
6140 RT2870_REG_RX_FILTER_DROP_CFEND;
6142 if (ic->ic_opmode == IEEE80211_M_STA)
6143 tmp |= RT2870_REG_RX_FILTER_DROP_RTS |
6144 RT2870_REG_RX_FILTER_DROP_PSPOLL;
6146 if (!(ifp->if_flags & IFF_PROMISC))
6147 tmp |= RT2870_REG_RX_FILTER_DROP_UC_NOME;
6150 rt2870_io_mac_write(sc, RT2870_REG_RX_FILTER_CFG, tmp);
6152 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL,
6153 RT2870_REG_RX_ENABLE | RT2870_REG_TX_ENABLE);
6155 return 0;
6159 * rt2870_alloc_rx_ring
6161 static int rt2870_alloc_rx_ring(struct rt2870_softc *sc,
6162 struct rt2870_softc_rx_ring *ring)
6164 struct rt2870_softc_rx_data *data;
6165 int i, error;
6167 STAILQ_INIT(&ring->inactive);
6168 STAILQ_INIT(&ring->active);
6169 STAILQ_INIT(&ring->done);
6171 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
6173 data = &ring->data[i];
6175 data->buf = malloc(RT2870_USB_RX_BULK_BUFLEN, M_USBDEV, M_NOWAIT);
6176 if (data->buf == NULL)
6178 printf("%s: could not allocate Rx buffer\n",
6179 device_get_nameunit(sc->dev));
6180 error = ENOMEM;
6181 goto fail;
6184 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
6187 return 0;
6189 fail:
6191 rt2870_free_rx_ring(sc, ring);
6193 return error;
6197 * rt2870_reset_rx_ring
6199 static void rt2870_reset_rx_ring(struct rt2870_softc *sc,
6200 struct rt2870_softc_rx_ring *ring)
6202 struct rt2870_softc_rx_data *data;
6203 int i;
6205 STAILQ_INIT(&ring->inactive);
6206 STAILQ_INIT(&ring->active);
6207 STAILQ_INIT(&ring->done);
6209 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
6211 data = &ring->data[i];
6213 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
6218 * rt2870_free_rx_ring
6220 static void rt2870_free_rx_ring(struct rt2870_softc *sc,
6221 struct rt2870_softc_rx_ring *ring)
6223 struct rt2870_softc_rx_data *data;
6224 int i;
6226 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
6228 data = &ring->data[i];
6230 if (data->buf != NULL)
6232 free(data->buf, M_USBDEV);
6233 data->buf = NULL;
6239 * rt2870_alloc_tx_ring
6241 static int rt2870_alloc_tx_ring(struct rt2870_softc *sc,
6242 struct rt2870_softc_tx_ring *ring, int qid)
6244 struct rt2870_softc_tx_data *data;
6245 int i, error;
6247 STAILQ_INIT(&ring->inactive);
6248 STAILQ_INIT(&ring->pending);
6249 STAILQ_INIT(&ring->active);
6250 STAILQ_INIT(&ring->done);
6252 ring->queued = 0;
6253 ring->qid = qid;
6255 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
6257 data = &ring->data[i];
6259 data->buf = malloc(RT2870_TX_DESC_SIZE + MJUMPAGESIZE, M_USBDEV, M_NOWAIT);
6260 if (data->buf == NULL)
6262 printf("%s: could not allocate Tx buffer\n",
6263 device_get_nameunit(sc->dev));
6264 error = ENOMEM;
6265 goto fail;
6268 memset(data->buf, 0, RT2870_TX_DESC_SIZE);
6270 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
6273 return 0;
6275 fail:
6277 rt2870_free_tx_ring(sc, ring);
6279 return error;
6283 * rt2870_reset_tx_ring
6285 static void rt2870_reset_tx_ring(struct rt2870_softc *sc,
6286 struct rt2870_softc_tx_ring *ring)
6288 struct rt2870_softc_tx_data *data;
6289 int i;
6291 STAILQ_INIT(&ring->inactive);
6292 STAILQ_INIT(&ring->pending);
6293 STAILQ_INIT(&ring->active);
6294 STAILQ_INIT(&ring->done);
6296 ring->queued = 0;
6298 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
6300 data = &ring->data[i];
6302 if (data->m != NULL)
6304 m_free(data->m);
6305 data->m = NULL;
6308 if (data->ni != NULL)
6310 ieee80211_free_node(data->ni);
6311 data->ni = NULL;
6314 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
6319 * rt2870_free_tx_ring
6321 static void rt2870_free_tx_ring(struct rt2870_softc *sc,
6322 struct rt2870_softc_tx_ring *ring)
6324 struct rt2870_softc_tx_data *data;
6325 int i;
6327 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
6329 data = &ring->data[i];
6331 if (data->buf != NULL)
6333 free(data->buf, M_USBDEV);
6334 data->buf = NULL;
6337 if (data->m != NULL)
6339 m_free(data->m);
6340 data->m = NULL;
6343 if (data->ni != NULL)
6345 ieee80211_free_node(data->ni);
6346 data->ni = NULL;
6352 * rt2870_reset_cmd_ring
6354 static void rt2870_reset_cmd_ring(struct rt2870_softc *sc,
6355 struct rt2870_softc_cmd_ring *ring)
6357 struct rt2870_softc_cmd *cmd;
6358 int i;
6360 STAILQ_INIT(&ring->inactive);
6361 STAILQ_INIT(&ring->active);
6363 ring->queued = 0;
6365 for (i = 0; i < RT2870_SOFTC_CMD_RING_CMD_COUNT; i++)
6367 cmd = &ring->cmd[i];
6369 STAILQ_INSERT_TAIL(&ring->inactive, cmd, next);
6374 * rt2870_sysctl_attach
6376 static void rt2870_sysctl_attach(struct rt2870_softc *sc)
6378 struct sysctl_ctx_list *ctx;
6379 struct sysctl_oid *tree;
6380 struct sysctl_oid *stats;
6382 ctx = device_get_sysctl_ctx(sc->dev);
6383 tree = device_get_sysctl_tree(sc->dev);
6385 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
6386 "tx_stbc", CTLFLAG_RW, &sc->tx_stbc, 0,
6387 "Tx STBC");
6389 /* statistic counters */
6391 stats = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
6392 "stats", CTLFLAG_RD, 0, "statistic");
6394 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6395 "interrupts", CTLFLAG_RD, &sc->interrupts, 0,
6396 "all interrupts");
6398 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6399 "rx_interrupts", CTLFLAG_RD, &sc->rx_interrupts, 0,
6400 "Rx interrupts");
6402 if (sc->usb_endpoints == RT2870_SOFTC_USB_XFER_COUNT)
6404 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6405 "tx_mgmt_interrupts", CTLFLAG_RD, &sc->tx_interrupts[5], 0,
6406 "Tx MGMT interrupts");
6408 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6409 "tx_hcca_interrupts", CTLFLAG_RD, &sc->tx_interrupts[4], 0,
6410 "Tx HCCA interrupts");
6413 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6414 "tx_ac3_interrupts", CTLFLAG_RD, &sc->tx_interrupts[3], 0,
6415 "Tx AC3 interrupts");
6417 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6418 "tx_ac2_interrupts", CTLFLAG_RD, &sc->tx_interrupts[2], 0,
6419 "Tx AC2 interrupts");
6421 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6422 "tx_ac1_interrupts", CTLFLAG_RD, &sc->tx_interrupts[1], 0,
6423 "Tx AC1 interrupts");
6425 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6426 "tx_ac0_interrupts", CTLFLAG_RD, &sc->tx_interrupts[0], 0,
6427 "Tx AC0 interrupts");
6429 if (sc->usb_endpoints == RT2870_SOFTC_USB_XFER_COUNT)
6431 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6432 "tx_mgmt_data_queued", CTLFLAG_RD, &sc->tx_ring[5].queued, 0,
6433 "Tx MGMT data queued");
6435 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6436 "tx_hcca_data_queued", CTLFLAG_RD, &sc->tx_ring[4].queued, 0,
6437 "Tx HCCA data queued");
6440 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6441 "tx_ac3_data_queued", CTLFLAG_RD, &sc->tx_ring[3].queued, 0,
6442 "Tx AC3 data queued");
6444 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6445 "tx_ac2_data_queued", CTLFLAG_RD, &sc->tx_ring[2].queued, 0,
6446 "Tx AC2 data queued");
6448 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6449 "tx_ac1_data_queued", CTLFLAG_RD, &sc->tx_ring[1].queued, 0,
6450 "Tx AC1 data queued");
6452 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6453 "tx_ac0_data_queued", CTLFLAG_RD, &sc->tx_ring[0].queued, 0,
6454 "Tx AC0 data queued");
6456 if (sc->usb_endpoints == RT2870_SOFTC_USB_XFER_COUNT)
6458 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6459 "tx_mgmt_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[5], 0,
6460 "Tx MGMT data queue full");
6462 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6463 "tx_hcca_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[4], 0,
6464 "Tx HCCA data queue full");
6467 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6468 "tx_ac3_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[3], 0,
6469 "Tx AC3 data queue full");
6471 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6472 "tx_ac2_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[2], 0,
6473 "Tx AC2 data queue full");
6475 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6476 "tx_ac1_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[1], 0,
6477 "Tx AC1 data queue full");
6479 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6480 "tx_ac0_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[0], 0,
6481 "Tx AC0 data queue full");
6483 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6484 "tx_watchdog_timeouts", CTLFLAG_RD, &sc->tx_watchdog_timeouts, 0,
6485 "Tx watchdog timeouts");
6487 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6488 "rx_mbuf_alloc_errors", CTLFLAG_RD, &sc->rx_mbuf_alloc_errors, 0,
6489 "Rx mbuf allocation errors");
6491 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6492 "tx_queue_0_not_empty", CTLFLAG_RD, &sc->tx_queue_not_empty[0], 0,
6493 "Tx queue 0 not empty");
6495 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6496 "tx_queue_1_not_empty", CTLFLAG_RD, &sc->tx_queue_not_empty[1], 0,
6497 "Tx queue 1 not empty");
6499 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6500 "tx_beacons", CTLFLAG_RD, &sc->tx_beacons, 0,
6501 "Tx beacons");
6503 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6504 "tx_noretryok", CTLFLAG_RD, &sc->tx_noretryok, 0,
6505 "Tx successfull without retries");
6507 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6508 "tx_retryok", CTLFLAG_RD, &sc->tx_retryok, 0,
6509 "Tx successfull with retries");
6511 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6512 "tx_failed", CTLFLAG_RD, &sc->tx_failed, 0,
6513 "Tx failed");
6515 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6516 "tx_underflows", CTLFLAG_RD, &sc->tx_underflows, 0,
6517 "Tx underflows");
6519 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6520 "tx_zerolen", CTLFLAG_RD, &sc->tx_zerolen, 0,
6521 "Tx zero length");
6523 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6524 "tx_nonagg", CTLFLAG_RD, &sc->tx_nonagg, 0,
6525 "Tx non-aggregated");
6527 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6528 "tx_agg", CTLFLAG_RD, &sc->tx_agg, 0,
6529 "Tx aggregated");
6531 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6532 "tx_ampdu", CTLFLAG_RD, &sc->tx_ampdu, 0,
6533 "Tx A-MPDU");
6535 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6536 "tx_mpdu_zero_density", CTLFLAG_RD, &sc->tx_mpdu_zero_density, 0,
6537 "Tx MPDU with zero density");
6539 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6540 "tx_ampdu_sessions", CTLFLAG_RD, &sc->tx_ampdu_sessions, 0,
6541 "Tx A-MPDU sessions");
6543 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6544 "rx_packets", CTLFLAG_RD, &sc->rx_packets, 0,
6545 "Rx packets");
6547 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6548 "rx_ampdu", CTLFLAG_RD, &sc->rx_ampdu, 0,
6549 "Rx A-MPDU");
6551 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6552 "rx_ampdu_retries", CTLFLAG_RD, &sc->rx_ampdu_retries, 0,
6553 "Rx A-MPDU retries");
6555 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6556 "rx_mpdu_zero_density", CTLFLAG_RD, &sc->rx_mpdu_zero_density, 0,
6557 "Rx MPDU with zero density");
6559 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6560 "rx_ampdu_sessions", CTLFLAG_RD, &sc->rx_ampdu_sessions, 0,
6561 "Rx A-MPDU sessions");
6563 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6564 "rx_amsdu", CTLFLAG_RD, &sc->rx_amsdu, 0,
6565 "Rx A-MSDU");
6567 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6568 "rx_crc_errors", CTLFLAG_RD, &sc->rx_crc_errors, 0,
6569 "Rx CRC errors");
6571 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6572 "rx_phy_errors", CTLFLAG_RD, &sc->rx_phy_errors, 0,
6573 "Rx PHY errors");
6575 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6576 "rx_false_ccas", CTLFLAG_RD, &sc->rx_false_ccas, 0,
6577 "Rx false CCAs");
6579 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6580 "rx_plcp_errors", CTLFLAG_RD, &sc->rx_plcp_errors, 0,
6581 "Rx PLCP errors");
6583 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6584 "rx_dup_packets", CTLFLAG_RD, &sc->rx_dup_packets, 0,
6585 "Rx duplicate packets");
6587 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6588 "rx_fifo_overflows", CTLFLAG_RD, &sc->rx_fifo_overflows, 0,
6589 "Rx FIFO overflows");
6591 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6592 "rx_cipher_no_errors", CTLFLAG_RD, &sc->rx_cipher_no_errors, 0,
6593 "Rx cipher no errors");
6595 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6596 "rx_cipher_icv_errors", CTLFLAG_RD, &sc->rx_cipher_icv_errors, 0,
6597 "Rx cipher ICV errors");
6599 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6600 "rx_cipher_mic_errors", CTLFLAG_RD, &sc->rx_cipher_mic_errors, 0,
6601 "Rx cipher MIC errors");
6603 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6604 "rx_cipher_invalid_key_errors", CTLFLAG_RD, &sc->rx_cipher_invalid_key_errors, 0,
6605 "Rx cipher invalid key errors");
6608 static device_method_t rt2870_dev_methods[] =
6610 DEVMETHOD(device_probe, rt2870_probe),
6611 DEVMETHOD(device_attach, rt2870_attach),
6612 DEVMETHOD(device_detach, rt2870_detach),
6613 { 0, 0 }
6616 static driver_t rt2870_driver =
6618 "rt2870",
6619 rt2870_dev_methods,
6620 sizeof(struct rt2870_softc),
6623 static devclass_t rt2870_dev_class;
6625 DRIVER_MODULE(rt2870, uhub, rt2870_driver, rt2870_dev_class,
6626 NULL, 0);
6628 MODULE_DEPEND(rt2870, usb, 1, 1, 1);
6629 MODULE_DEPEND(rt2870, wlan, 1, 1, 1);