Do not use ShortGI and STBC with management frames; Atheros cards have problems with...
[ralink_drivers/rt2870_fbsd72.git] / rt2870.c
blob726fa55bef2143b2b2394808f017d3ce66e35366
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_txwi.h"
26 #include "rt2870_txinfo.h"
27 #include "rt2870_read_eeprom.h"
28 #include "rt2870_io.h"
29 #include "rt2870_rf.h"
30 #include "rt2870_led.h"
31 #include "rt2870_debug.h"
34 * Defines and macros
37 #define USB_PRODUCT_LINKSYS4_WUSB600N 0x0071
38 #define USB_PRODUCT_DLINK2_DWA140 0x3c09
39 #define USB_PRODUCT_DLINK2_DWA160AREVB 0x3c11
40 #define USB_PRODUCT_ASUS_RT2770F 0x1742
41 #define USB_PRODUCT_RALINK_RT2770 0x2770
43 #define RT2870_USB_CONFIG_NO 1
44 #define RT2870_USB_IFACE_INDEX 0
46 #define RT2870_USB_REQ_MAC_READ_MULTI 0x07
48 /* packet length + Rx wireless info + Rx info */
49 #define RT2870_RX_DESC_SIZE \
50 (sizeof(uint32_t) + sizeof(struct rt2870_rxwi) + sizeof(struct rt2870_rxinfo))
52 /* Tx info + Tx wireless info + max padding */
53 #define RT2870_TX_DESC_SIZE \
54 (sizeof(struct rt2870_txinfo) + sizeof(struct rt2870_txwi) + 11)
56 #define RT2870_MAX_AGG_SIZE 3840
58 #define RT2870_USB_RX_BULK_BUFLEN (2048 * 12)
60 #define RT2870_NOISE_FLOOR -95
62 #define RT2870_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
64 #define RT2870_ACK_SIZE 14
66 #define IEEE80211_HAS_ADDR4(wh) \
67 (((wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
69 #define RT2870_MS(_v, _f) (((_v) & _f) >> _f##_S)
70 #define RT2870_SM(_v, _f) (((_v) << _f##_S) & _f)
72 #define RT2870_USB_XFER_TIMEOUT 5000
74 #define RT2870_TX_WATCHDOG_TIMEOUT 5
76 #define RT2870_WCID_RESERVED 0xff
77 #define RT2870_WCID_MCAST 0xf7
80 * Data structures and types
83 struct rt2870_cmd_argv_newstate
85 enum ieee80211_state nstate;
86 int arg;
89 struct rt2870_cmd_argv_nodecleanup
91 uint8_t staid;
94 struct rt2870_cmd_argv_newassoc
96 int isnew;
97 uint8_t macaddr[IEEE80211_ADDR_LEN];
100 struct rt2870_cmd_argv_updatebeacon
102 int what;
105 struct rt2870_cmd_argv_keyset
107 enum ieee80211_opmode opmode;
108 struct ieee80211_key key;
109 uint8_t staid;
112 struct rt2870_cmd_argv_keydelete
114 enum ieee80211_opmode opmode;
115 struct ieee80211_key key;
119 * Static function prototypes
122 static int rt2870_find_usb_endpoints(struct rt2870_softc *sc);
124 static void rt2870_init_channels(struct rt2870_softc *sc);
126 static void rt2870_init_channels_ht40(struct rt2870_softc *sc);
128 static void rt2870_init_locked(void *priv);
130 static void rt2870_init(void *priv);
132 static int rt2870_init_bbp(struct rt2870_softc *sc);
134 static void rt2870_stop_locked(void *priv);
136 static void rt2870_stop(void *priv);
138 static void rt2870_start(struct ifnet *ifp);
140 static int rt2870_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
142 static int rt2870_reset(struct ifnet *ifp);
144 static int rt2870_newstate(struct ieee80211com *ic,
145 enum ieee80211_state nstate, int arg);
147 static void rt2870_scan_start(struct ieee80211com *ic);
149 static void rt2870_scan_end(struct ieee80211com *ic);
151 static void rt2870_set_channel(struct ieee80211com *ic);
153 static void rt2870_newassoc(struct ieee80211_node *ni, int isnew);
155 static void rt2870_updateslot(struct ifnet *ifp);
157 static int rt2870_wme_update(struct ieee80211com *ic);
159 static void rt2870_update_beacon(struct ieee80211com *ic, int what);
161 static void rt2870_key_update_begin(struct ieee80211com *ic);
163 static void rt2870_key_update_end(struct ieee80211com *ic);
165 static int rt2870_key_set(struct ieee80211com *ic,
166 const struct ieee80211_key *k, const uint8_t mac[IEEE80211_ADDR_LEN]);
168 static int rt2870_key_delete(struct ieee80211com *ic,
169 const struct ieee80211_key *k);
171 static int rt2870_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
172 const struct ieee80211_bpf_params *params);
174 static int rt2870_media_change(struct ifnet *ifp);
176 static struct ieee80211_node *rt2870_node_alloc(struct ieee80211_node_table *nt);
178 static void rt2870_node_cleanup(struct ieee80211_node *ni);
180 static void rt2870_recv_action(struct ieee80211_node *ni,
181 const uint8_t *frm, const uint8_t *efrm);
183 static int rt2870_send_action(struct ieee80211_node *ni,
184 int category, int action, uint16_t args[4]);
186 static int rt2870_addba_response(struct ieee80211_node *ni,
187 struct ieee80211_tx_ampdu *tap,
188 int status, int baparamset, int batimeout);
190 static void rt2870_addba_stop(struct ieee80211_node *ni,
191 struct ieee80211_tx_ampdu *tap);
193 static int rt2870_send_bar(struct ieee80211_node *ni,
194 struct ieee80211_tx_ampdu *tap, ieee80211_seq seqno);
196 static void rt2870_amrr_update_iter_func(void *arg, struct ieee80211_node *ni);
198 static void rt2870_periodic(void *arg);
200 static void rt2870_tx_watchdog(void *arg);
202 static int rt2870_staid_alloc(struct rt2870_softc *sc, int aid);
204 static void rt2870_staid_delete(struct rt2870_softc *sc, int staid);
206 static int rt2870_do_async(struct rt2870_softc *sc,
207 void (*cb)(struct rt2870_softc *sc, void *priv),
208 void *arg, int len);
210 static void rt2870_newstate_cb(struct rt2870_softc *sc, void *arg);
212 static void rt2870_node_cleanup_cb(struct rt2870_softc *sc, void *arg);
214 static void rt2870_scan_start_cb(struct rt2870_softc *sc, void *arg);
216 static void rt2870_scan_end_cb(struct rt2870_softc *sc, void *arg);
218 static void rt2870_set_channel_cb(struct rt2870_softc *sc, void *arg);
220 static void rt2870_newassoc_cb(struct rt2870_softc *sc, void *arg);
222 static void rt2870_updateslot_cb(struct rt2870_softc *sc, void *arg);
224 static void rt2870_update_beacon_cb(struct rt2870_softc *sc, void *arg);
226 static void rt2870_wme_update_cb(struct rt2870_softc *sc, void *arg);
228 static void rt2870_key_update_begin_cb(struct rt2870_softc *sc, void *arg);
230 static void rt2870_key_update_end_cb(struct rt2870_softc *sc, void *arg);
232 static void rt2870_key_set_cb(struct rt2870_softc *sc, void *arg);
234 static void rt2870_key_delete_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);
266 static void rt2870_asic_clear_keytables(struct rt2870_softc *sc);
268 static void rt2870_asic_add_ba_session(struct rt2870_softc *sc,
269 uint8_t wcid, int tid);
271 static void rt2870_asic_del_ba_session(struct rt2870_softc *sc,
272 uint8_t wcid, int tid);
274 static int rt2870_beacon_alloc(struct rt2870_softc *sc);
276 static uint8_t rt2870_rxrate(struct rt2870_rxwi *rxwi);
278 static uint8_t rt2870_maxrssi_rxpath(struct rt2870_softc *sc,
279 const struct rt2870_rxwi *rxwi);
281 static int8_t rt2870_rssi2dbm(struct rt2870_softc *sc,
282 uint8_t rssi, uint8_t rxpath);
284 static uint8_t rt2870_rate2mcs(uint8_t rate);
286 static int rt2870_ackrate(struct ieee80211com *ic, int rate);
288 static uint16_t rt2870_txtime(int len, int rate, uint32_t flags);
290 static void rt2870_rx_frame(struct rt2870_softc *sc,
291 uint8_t *buf, uint32_t dmalen);
293 static int rt2870_tx_frame(struct rt2870_softc *sc,
294 struct mbuf *m, struct ieee80211_node *ni, int qid);
296 static int rt2870_tx_raw(struct rt2870_softc *sc,
297 struct mbuf *m, struct ieee80211_node *ni,
298 const struct ieee80211_bpf_params *params);
300 static void rt2870_rx_intr(usbd_xfer_handle xfer,
301 usbd_private_handle priv, usbd_status status);
303 static void rt2870_tx_intr(usbd_xfer_handle xfer,
304 usbd_private_handle priv, usbd_status status);
306 static void rt2870_rx_done_task(void *context, int pending);
308 static void rt2870_tx_done_task(void *context, int pending);
310 static void rt2870_periodic_task(void *context, int pending);
312 static void rt2870_cmd_task(void *context, int pending);
314 static int rt2870_rx_eof(struct rt2870_softc *sc, int limit);
316 static void rt2870_tx_eof(struct rt2870_softc *sc,
317 struct rt2870_softc_tx_ring *ring);
319 static void rt2870_update_stats(struct rt2870_softc *sc);
321 static void rt2870_bbp_tuning(struct rt2870_softc *sc);
323 static void rt2870_watchdog(struct rt2870_softc *sc);
325 static void rt2870_drain_fifo_stats(struct rt2870_softc *sc);
327 static void rt2870_update_raw_counters(struct rt2870_softc *sc);
329 static int rt2870_alloc_rx_ring(struct rt2870_softc *sc,
330 struct rt2870_softc_rx_ring *ring);
332 static void rt2870_reset_rx_ring(struct rt2870_softc *sc,
333 struct rt2870_softc_rx_ring *ring);
335 static void rt2870_free_rx_ring(struct rt2870_softc *sc,
336 struct rt2870_softc_rx_ring *ring);
338 static int rt2870_alloc_tx_ring(struct rt2870_softc *sc,
339 struct rt2870_softc_tx_ring *ring, int qid);
341 static void rt2870_reset_tx_ring(struct rt2870_softc *sc,
342 struct rt2870_softc_tx_ring *ring);
344 static void rt2870_free_tx_ring(struct rt2870_softc *sc,
345 struct rt2870_softc_tx_ring *ring);
347 static void rt2870_reset_cmd_ring(struct rt2870_softc *sc,
348 struct rt2870_softc_cmd_ring *ring);
350 static void rt2870_sysctl_attach(struct rt2870_softc *sc);
353 * Static variables
356 static const struct usb_devno rt2870_usb_devno[] =
358 { USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB600N }, /* Linksys WUSB600N */
359 { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA140 }, /* D-Link DWA-140 */
360 { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160AREVB }, /* D-Link DWA-160A Rev. B */
361 { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2770F }, /* Asus RT2770F */
362 { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2770 }, /* Ralink RT2770 */
365 static const struct
367 uint32_t reg;
368 uint32_t val;
369 } rt2870_def_mac[] =
371 { RT2870_REG_PBF_BCN_OFFSET0, 0xf8f0e8e0 },
372 { RT2870_REG_PBF_BCN_OFFSET1, 0x6f77d0c8 },
373 { RT2870_REG_LEGACY_BASIC_RATE, 0x0000013f },
374 { RT2870_REG_HT_BASIC_RATE, 0x00008003 },
375 { RT2870_REG_SYS_CTRL, 0x00000000 },
376 { RT2870_REG_RX_FILTER_CFG, 0x00017f97 },
377 { RT2870_REG_BKOFF_SLOT_CFG, 0x00000209 },
378 { RT2870_REG_TX_SW_CFG0, 0x00000000 },
379 { RT2870_REG_TX_SW_CFG1, 0x00080606 },
380 { RT2870_REG_TX_LINK_CFG, 0x00001020 },
381 { RT2870_REG_TX_TIMEOUT_CFG, 0x000a2090 },
382 { RT2870_REG_MAX_LEN_CFG, (1 << 12) | RT2870_MAX_AGG_SIZE },
383 { RT2870_REG_LED_CFG, 0x7f031e46 },
384 { RT2870_REG_PBF_MAX_PCNT, 0x1f3fbf9f },
385 { RT2870_REG_TX_RTY_CFG, 0x47d01f0f },
386 { RT2870_REG_AUTO_RSP_CFG, 0x00000013 },
387 { RT2870_REG_TX_CCK_PROT_CFG, 0x05740003 },
388 { RT2870_REG_TX_OFDM_PROT_CFG, 0x05740003 },
389 { RT2870_REG_PBF_CFG, 0x00f40006 },
390 { RT2870_REG_TX_MM40_PROT_CFG, 0x03f44084 },
391 { RT2870_REG_SCHDMA_WPDMA_GLO_CFG, 0x00000030 },
392 { RT2870_REG_TX_GF20_PROT_CFG, 0x01744004 },
393 { RT2870_REG_TX_GF40_PROT_CFG, 0x03f44084 },
394 { RT2870_REG_TX_MM20_PROT_CFG, 0x01744004 },
395 { RT2870_REG_TX_TXOP_CTRL_CFG, 0x0000583f },
396 { RT2870_REG_TX_RTS_CFG, 0x00092b20 },
397 { RT2870_REG_TX_EXP_ACK_TIME, 0x002400ca },
398 { RT2870_REG_HCCAPSMP_TXOP_HLDR_ET, 0x00000002 },
399 { RT2870_REG_XIFS_TIME_CFG, 0x33a41010 },
400 { RT2870_REG_PWR_PIN_CFG, 0x00000003 },
401 { RT2870_REG_SCHDMA_WMM_AIFSN_CFG, 0x00002273 },
402 { RT2870_REG_SCHDMA_WMM_CWMIN_CFG, 0x00002344 },
403 { RT2870_REG_SCHDMA_WMM_CWMAX_CFG, 0x000034aa },
406 #define RT2870_DEF_MAC_SIZE (sizeof(rt2870_def_mac) / sizeof(rt2870_def_mac[0]))
408 static const struct
410 uint8_t reg;
411 uint8_t val;
412 } rt2870_def_bbp[] =
414 { 65, 0x2c },
415 { 66, 0x38 },
416 { 69, 0x12 },
417 { 70, 0x0a },
418 { 73, 0x10 },
419 { 81, 0x37 },
420 { 82, 0x62 },
421 { 83, 0x6a },
422 { 84, 0x99 },
423 { 86, 0x00 },
424 { 91, 0x04 },
425 { 92, 0x00 },
426 { 103, 0x00 },
427 { 105, 0x05 },
430 #define RT2870_DEF_BBP_SIZE (sizeof(rt2870_def_bbp) / sizeof(rt2870_def_bbp[0]))
432 SYSCTL_NODE(_hw, OID_AUTO, rt2870, CTLFLAG_RD, 0, "RT2870 driver parameters");
434 static int rt2870_tx_stbc = 1;
435 SYSCTL_INT(_hw_rt2870, OID_AUTO, tx_stbc, CTLFLAG_RW, &rt2870_tx_stbc, 0, "RT2870 Tx STBC");
436 TUNABLE_INT("hw.rt2870.tx_stbc", &rt2870_tx_stbc);
438 #ifdef RT2870_DEBUG
439 static int rt2870_debug = 0;
440 SYSCTL_INT(_hw_rt2870, OID_AUTO, debug, CTLFLAG_RW, &rt2870_debug, 0, "rt2870 debug level");
441 TUNABLE_INT("hw.rt2870.debug", &rt2870_debug);
442 #endif
445 * rt2870_probe
447 static int rt2870_probe(device_t dev)
449 struct usb_attach_arg *uaa;
451 uaa = device_get_ivars(dev);
453 if (uaa->iface != NULL)
454 return UMATCH_NONE;
456 return (usb_lookup(rt2870_usb_devno, uaa->vendor, uaa->product) != NULL) ?
457 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
461 * rt2870_attach
463 static int rt2870_attach(device_t dev)
465 struct rt2870_softc *sc;
466 struct usb_attach_arg *uaa;
467 usbd_status usb_error;
468 struct ieee80211com *ic;
469 struct ifnet *ifp;
470 int error, ntries, i;
472 sc = device_get_softc(dev);
473 uaa = device_get_ivars(dev);
475 sc->dev = dev;
476 sc->usb_dev = uaa->device;
478 sc->tx_stbc = rt2870_tx_stbc;
480 #ifdef RT2870_DEBUG
481 sc->debug = rt2870_debug;
483 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
484 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
485 "debug", CTLFLAG_RW, &sc->debug, 0, "rt2870 debug level");
486 #endif
488 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
489 "%s: attaching\n",
490 device_get_nameunit(sc->dev));
492 if (usbd_set_config_no(sc->usb_dev, RT2870_USB_CONFIG_NO, 0) != 0)
494 printf("%s: could not set USB configuration no\n",
495 device_get_nameunit(sc->dev));
496 return ENXIO;
499 usb_error = usbd_device2interface_handle(sc->usb_dev,
500 RT2870_USB_IFACE_INDEX, &sc->usb_iface);
501 if (usb_error != 0)
503 printf("%s: could not get USB interface handle\n",
504 device_get_nameunit(sc->dev));
505 return ENXIO;
508 error = rt2870_find_usb_endpoints(sc);
509 if (error != 0)
510 return error;
512 for (ntries = 0; ntries < 100; ntries++)
514 sc->mac_rev = rt2870_io_mac_read(sc, RT2870_REG_MAC_CSR0);
515 if (sc->mac_rev != 0x00000000 && sc->mac_rev != 0xffffffff)
516 break;
518 DELAY(10);
521 if (ntries == 100)
523 printf("%s: timeout waiting for NIC to initialize\n",
524 device_get_nameunit(sc->dev));
525 return ENXIO;
528 rt2870_read_eeprom(sc);
530 printf("%s: MAC/BBP RT2870 (rev 0x%08x), RF %s\n",
531 device_get_nameunit(sc->dev), sc->mac_rev,
532 rt2870_rf_name(sc->rf_rev));
534 sc->flags |= RT2870_SOFTC_FLAGS_VALID;
536 /* clear key tables */
538 rt2870_asic_clear_keytables(sc);
540 /* open Tx and Rx USB bulk pipes */
542 for (i = 0; i < sc->usb_endpoints - 1; i++)
544 error = usbd_open_pipe(sc->usb_iface, sc->tx_ring[i].usb_ep,
545 USBD_EXCLUSIVE_USE, &sc->tx_ring[i].usb_pipe);
546 if (error != 0)
548 printf("%s: could not open Tx pipe #%d: %s\n",
549 device_get_nameunit(sc->dev), i, usbd_errstr(error));
550 goto fail;
554 error = usbd_open_pipe(sc->usb_iface, sc->rx_ring.usb_ep,
555 USBD_EXCLUSIVE_USE, &sc->rx_ring.usb_pipe);
556 if (error != 0)
558 printf("%s: could not open Rx pipe: %s\n",
559 device_get_nameunit(sc->dev), usbd_errstr(error));
560 goto fail;
563 /* allocate Tx and Rx rings */
565 for (i = 0; i < sc->usb_endpoints - 1; i++)
567 error = rt2870_alloc_tx_ring(sc, &sc->tx_ring[i], i);
568 if (error != 0)
570 printf("%s: could not allocate Tx ring #%d\n",
571 device_get_nameunit(sc->dev), i);
572 goto fail;
576 if (sc->usb_endpoints == (RT2870_SOFTC_TX_RING_COUNT + 1))
577 sc->tx_ring_mgtqid = 5;
578 else
579 sc->tx_ring_mgtqid = 0;
581 error = rt2870_alloc_rx_ring(sc, &sc->rx_ring);
582 if (error != 0)
584 printf("%s: could not allocate Rx ring\n",
585 device_get_nameunit(sc->dev));
586 goto fail;
589 rt2870_reset_cmd_ring(sc, &sc->cmd_ring);
591 callout_init(&sc->periodic_ch, 0);
592 callout_init(&sc->tx_watchdog_ch, 0);
594 ifp = sc->ifp = if_alloc(IFT_ETHER);
595 if (ifp == NULL)
597 printf("%s: could not if_alloc()\n",
598 device_get_nameunit(sc->dev));
599 error = ENOMEM;
600 goto fail;
603 ifp->if_softc = sc;
605 if_initname(ifp, "rt2870", device_get_unit(sc->dev));
607 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
608 IFF_NEEDSGIANT;
610 ifp->if_init = rt2870_init;
611 ifp->if_ioctl = rt2870_ioctl;
612 ifp->if_start = rt2870_start;
614 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
615 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
616 IFQ_SET_READY(&ifp->if_snd);
618 ic = &sc->ic;
620 ic->ic_ifp = ifp;
622 ic->ic_phytype = IEEE80211_T_HT;
623 ic->ic_opmode = IEEE80211_M_STA;
624 ic->ic_state = IEEE80211_S_INIT;
626 ic->ic_caps = IEEE80211_C_MONITOR |
627 IEEE80211_C_IBSS |
628 IEEE80211_C_AHDEMO |
629 IEEE80211_C_HOSTAP |
630 IEEE80211_C_WDS |
631 IEEE80211_C_BGSCAN |
632 IEEE80211_C_TXPMGT |
633 IEEE80211_C_SHPREAMBLE |
634 IEEE80211_C_SHSLOT |
635 IEEE80211_C_TXFRAG |
636 IEEE80211_C_BURST |
637 IEEE80211_C_WME |
638 IEEE80211_C_WEP |
639 IEEE80211_C_TKIP |
640 IEEE80211_C_AES_CCM |
641 IEEE80211_C_WPA;
643 ic->ic_htcaps = IEEE80211_HTC_HT |
644 IEEE80211_HTC_AMSDU | /* A-MSDU Tx */
645 IEEE80211_HTC_AMPDU | /* A-MPDU Tx */
646 IEEE80211_HTCAP_MAXAMSDU_3839 | /* max. A-MSDU Rx length */
647 IEEE80211_HTCAP_CHWIDTH40 | /* HT 40MHz channel width */
648 IEEE80211_HTCAP_GREENFIELD | /* HT greenfield */
649 IEEE80211_HTCAP_SHORTGI20 | /* HT 20MHz short GI */
650 IEEE80211_HTCAP_SHORTGI40 | /* HT 40MHz short GI */
651 IEEE80211_HTCAP_SMPS_OFF; /* MIMO power save disabled */
653 /* spatial streams */
655 if (sc->nrxpath == 2)
656 ic->ic_htcaps |= IEEE80211_HTCAP_RXSTBC_2STREAM;
657 else if (sc->nrxpath == 3)
658 ic->ic_htcaps |= IEEE80211_HTCAP_RXSTBC_3STREAM;
659 else
660 ic->ic_htcaps |= IEEE80211_HTCAP_RXSTBC_1STREAM;
662 if (sc->ntxpath > 1)
663 ic->ic_htcaps |= IEEE80211_HTCAP_TXSTBC;
665 /* delayed BA */
667 if (sc->mac_rev != 0x28600100)
668 ic->ic_htcaps |= IEEE80211_HTCAP_DELBA;
670 /* init channels */
672 ic->ic_nchans = 0;
673 ic->ic_regdomain = 0;
674 ic->ic_countrycode = CTRY_DEFAULT;
675 ic->ic_location = 0;
677 rt2870_init_channels(sc);
679 rt2870_init_channels_ht40(sc);
681 IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->mac_addr);
683 ieee80211_ifattach(ic);
685 sc->newstate = ic->ic_newstate;
686 ic->ic_newstate = rt2870_newstate;
688 ic->ic_reset = rt2870_reset;
689 ic->ic_node_alloc = rt2870_node_alloc;
691 sc->node_cleanup = ic->ic_node_cleanup;
692 ic->ic_node_cleanup = rt2870_node_cleanup;
694 ic->ic_scan_start = rt2870_scan_start;
695 ic->ic_scan_end = rt2870_scan_end;
696 ic->ic_set_channel = rt2870_set_channel;
697 ic->ic_newassoc = rt2870_newassoc;
698 ic->ic_updateslot = rt2870_updateslot;
699 ic->ic_wme.wme_update = rt2870_wme_update;
700 ic->ic_update_beacon = rt2870_update_beacon;
701 ic->ic_crypto.cs_key_update_begin = rt2870_key_update_begin;
702 ic->ic_crypto.cs_key_update_end = rt2870_key_update_end;
703 ic->ic_crypto.cs_key_set = rt2870_key_set;
704 ic->ic_crypto.cs_key_delete = rt2870_key_delete;
705 ic->ic_raw_xmit = rt2870_raw_xmit;
707 sc->recv_action = ic->ic_recv_action;
708 ic->ic_recv_action = rt2870_recv_action;
710 sc->send_action = ic->ic_send_action;
711 ic->ic_send_action = rt2870_send_action;
713 sc->addba_response = ic->ic_addba_response;
714 ic->ic_addba_response = rt2870_addba_response;
716 sc->addba_stop = ic->ic_addba_stop;
717 ic->ic_addba_stop = rt2870_addba_stop;
719 /* overwrite Rx A-MPDU factor */
721 ic->ic_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_32K;
722 ic->ic_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_NA;
723 ic->ic_ampdu_limit = ic->ic_ampdu_rxmax;
725 /* hardware requires padding between 802.11 frame header and body */
727 ic->ic_flags |= IEEE80211_F_WME | IEEE80211_F_DATAPAD | IEEE80211_F_DOTH;
729 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;
731 ic->ic_max_aid = RT2870_SOFTC_STAID_COUNT;
733 rt2870_amrr_init(&sc->amrr, ic,
734 sc->ntxpath,
735 RT2870_AMRR_MIN_SUCCESS_THRESHOLD,
736 RT2870_AMRR_MAX_SUCCESS_THRESHOLD,
737 500);
739 bpfattach2(ifp, DLT_IEEE802_11_RADIO,
740 sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
741 &sc->drvbpf);
743 sc->rxtap_len = sizeof(sc->rxtapu);
744 sc->rxtap.ihdr.it_len = htole16(sc->rxtap_len);
745 sc->rxtap.ihdr.it_present = htole32(RT2870_SOFTC_RX_RADIOTAP_PRESENT);
747 sc->txtap_len = sizeof(sc->txtapu);
748 sc->txtap.ihdr.it_len = htole16(sc->txtap_len);
749 sc->txtap.ihdr.it_present = htole32(RT2870_SOFTC_TX_RADIOTAP_PRESENT);
751 /* init task queue */
753 TASK_INIT(&sc->rx_done_task, 0, rt2870_rx_done_task, sc);
754 TASK_INIT(&sc->tx_done_task, 0, rt2870_tx_done_task, sc);
755 TASK_INIT(&sc->periodic_task, 0, rt2870_periodic_task, sc);
756 TASK_INIT(&sc->cmd_task, 0, rt2870_cmd_task, sc);
758 sc->rx_process_limit = 100;
760 sc->taskqueue = taskqueue_create("rt2870_taskq", M_NOWAIT,
761 taskqueue_thread_enqueue, &sc->taskqueue);
763 taskqueue_start_threads(&sc->taskqueue, 1, PI_NET, "%s taskq",
764 device_get_nameunit(sc->dev));
766 ieee80211_media_init(ic, rt2870_media_change, ieee80211_media_status);
768 rt2870_sysctl_attach(sc);
770 if (bootverbose)
771 ieee80211_announce(ic);
773 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->usb_dev, sc->dev);
775 return 0;
777 fail:
779 /* close Tx and Rx USB bulk pipes */
781 if (sc->rx_ring.usb_pipe != NULL)
783 usbd_abort_pipe(sc->rx_ring.usb_pipe);
784 usbd_close_pipe(sc->rx_ring.usb_pipe);
785 sc->rx_ring.usb_pipe = NULL;
788 for (i = 0; i < sc->usb_endpoints - 1; i++)
790 if (sc->tx_ring[i].usb_pipe != NULL)
792 usbd_abort_pipe(sc->tx_ring[i].usb_pipe);
793 usbd_close_pipe(sc->tx_ring[i].usb_pipe);
794 sc->tx_ring[i].usb_pipe = NULL;
798 /* free Tx and Rx rings */
800 for (i = 0; i < sc->usb_endpoints - 1; i++)
801 rt2870_free_tx_ring(sc, &sc->tx_ring[i]);
803 rt2870_free_rx_ring(sc, &sc->rx_ring);
805 return error;
809 * rt2870_detach
811 static int rt2870_detach(device_t dev)
813 struct rt2870_softc *sc;
814 struct ieee80211com *ic;
815 struct ifnet *ifp;
816 int i;
818 if (!device_is_attached(dev))
819 return 0;
821 sc = device_get_softc(dev);
822 ic = &sc->ic;
823 ifp = ic->ic_ifp;
825 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
826 "%s: detaching\n",
827 device_get_nameunit(sc->dev));
829 sc->flags &= ~RT2870_SOFTC_FLAGS_VALID;
831 sc->tx_timer = 0;
833 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
835 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
837 callout_stop(&sc->periodic_ch);
838 callout_stop(&sc->tx_watchdog_ch);
840 taskqueue_drain(sc->taskqueue, &sc->rx_done_task);
841 taskqueue_drain(sc->taskqueue, &sc->tx_done_task);
842 taskqueue_drain(sc->taskqueue, &sc->periodic_task);
843 taskqueue_drain(sc->taskqueue, &sc->cmd_task);
845 /* close Tx and Rx USB bulk pipes */
847 if (sc->rx_ring.usb_pipe != NULL)
849 usbd_abort_pipe(sc->rx_ring.usb_pipe);
850 usbd_close_pipe(sc->rx_ring.usb_pipe);
851 sc->rx_ring.usb_pipe = NULL;
854 for (i = 0; i < sc->usb_endpoints - 1; i++)
856 if (sc->tx_ring[i].usb_pipe != NULL)
858 usbd_abort_pipe(sc->tx_ring[i].usb_pipe);
859 usbd_close_pipe(sc->tx_ring[i].usb_pipe);
860 sc->tx_ring[i].usb_pipe = NULL;
864 /* free Tx and Rx rings */
866 for (i = 0; i < sc->usb_endpoints - 1; i++)
867 rt2870_free_tx_ring(sc, &sc->tx_ring[i]);
869 rt2870_free_rx_ring(sc, &sc->rx_ring);
871 bpfdetach(ifp);
873 ieee80211_ifdetach(ic);
875 if_free(ifp);
877 taskqueue_free(sc->taskqueue);
879 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->usb_dev, sc->dev);
881 return 0;
885 * rt2870_find_usb_endpoints
887 static int rt2870_find_usb_endpoints(struct rt2870_softc *sc)
889 usb_interface_descriptor_t *id;
890 usb_endpoint_descriptor_t *ed;
891 int i, j;
893 id = usbd_get_interface_descriptor(sc->usb_iface);
895 sc->usb_endpoints = id->bNumEndpoints;
896 if ((sc->usb_endpoints != (RT2870_SOFTC_TX_RING_COUNT + 1)) &&
897 (sc->usb_endpoints != (RT2870_SOFTC_TX_RING_COUNT - 2 + 1)))
899 printf("%s: wrong number of USB endpoints=%d\n",
900 device_get_nameunit(sc->dev), sc->usb_endpoints);
901 return ENXIO;
904 sc->rx_ring.usb_ep = -1;
906 for (i = 0; i < RT2870_SOFTC_TX_RING_COUNT; i++)
907 sc->tx_ring[i].usb_ep = -1;
909 for (i = 0, j = 0; i < id->bNumEndpoints; i++)
911 ed = usbd_interface2endpoint_descriptor(sc->usb_iface, i);
912 if (ed == NULL)
914 printf("%s: no endpoint descriptor #%d for USB interface\n",
915 device_get_nameunit(sc->dev), i);
916 return ENXIO;
919 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
920 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
922 sc->rx_ring.usb_ep = ed->bEndpointAddress;
924 else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
925 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
927 if (j < RT2870_SOFTC_TX_RING_COUNT)
928 sc->tx_ring[j++].usb_ep = ed->bEndpointAddress;
929 else
930 sc->tx_ring[RT2870_SOFTC_TX_RING_COUNT - 1].usb_ep =
931 ed->bEndpointAddress;
935 if ((sc->rx_ring.usb_ep == -1) ||
936 ((j != RT2870_SOFTC_TX_RING_COUNT) && (j != RT2870_SOFTC_TX_RING_COUNT - 2)))
938 printf("%s: missing USB endpoints\n",
939 device_get_nameunit(sc->dev));
940 return ENXIO;
943 return 0;
947 * rt2870_init_channels
949 static void rt2870_init_channels(struct rt2870_softc *sc)
951 struct ieee80211com *ic;
952 struct ieee80211_channel *c;
953 int i, flags;
955 ic = &sc->ic;
957 /* set supported channels for 2GHz band */
959 for (i = 1; i <= 14; i++)
961 c = &ic->ic_channels[ic->ic_nchans++];
962 flags = IEEE80211_CHAN_B;
964 c->ic_freq = ieee80211_ieee2mhz(i, flags);
965 c->ic_ieee = i;
966 c->ic_flags = flags;
968 c = &ic->ic_channels[ic->ic_nchans++];
969 flags = IEEE80211_CHAN_B | IEEE80211_CHAN_HT20;
971 c->ic_freq = ieee80211_ieee2mhz(i, flags);
972 c->ic_ieee = i;
973 c->ic_flags = flags;
975 c = &ic->ic_channels[ic->ic_nchans++];
976 flags = IEEE80211_CHAN_G;
978 c->ic_freq = ieee80211_ieee2mhz(i, flags);
979 c->ic_ieee = i;
980 c->ic_flags = flags;
982 c = &ic->ic_channels[ic->ic_nchans++];
983 flags = IEEE80211_CHAN_G | IEEE80211_CHAN_HT20;
985 c->ic_freq = ieee80211_ieee2mhz(i, flags);
986 c->ic_ieee = i;
987 c->ic_flags = flags;
990 /* set supported channels for 5GHz band */
992 if (sc->rf_rev == RT2870_EEPROM_RF_2850 ||
993 sc->rf_rev == RT2870_EEPROM_RF_2750)
995 for (i = 36; i <= 64; i += 4)
997 c = &ic->ic_channels[ic->ic_nchans++];
998 flags = IEEE80211_CHAN_A;
1000 c->ic_freq = ieee80211_ieee2mhz(i, flags);
1001 c->ic_ieee = i;
1002 c->ic_flags = flags;
1004 c = &ic->ic_channels[ic->ic_nchans++];
1005 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
1007 c->ic_freq = ieee80211_ieee2mhz(i, flags);
1008 c->ic_ieee = i;
1009 c->ic_flags = flags;
1012 for (i = 100; i <= 140; i += 4)
1014 c = &ic->ic_channels[ic->ic_nchans++];
1015 flags = IEEE80211_CHAN_A;
1017 c->ic_freq = ieee80211_ieee2mhz(i, flags);
1018 c->ic_ieee = i;
1019 c->ic_flags = flags;
1021 c = &ic->ic_channels[ic->ic_nchans++];
1022 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
1024 c->ic_freq = ieee80211_ieee2mhz(i, flags);
1025 c->ic_ieee = i;
1026 c->ic_flags = flags;
1029 for (i = 149; i <= 165; i += 4)
1031 c = &ic->ic_channels[ic->ic_nchans++];
1032 flags = IEEE80211_CHAN_A;
1034 c->ic_freq = ieee80211_ieee2mhz(i, flags);
1035 c->ic_ieee = i;
1036 c->ic_flags = flags;
1038 c = &ic->ic_channels[ic->ic_nchans++];
1039 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
1041 c->ic_freq = ieee80211_ieee2mhz(i, flags);
1042 c->ic_ieee = i;
1043 c->ic_flags = flags;
1049 * rt2870_init_channels_ht40
1051 static void rt2870_init_channels_ht40(struct rt2870_softc *sc)
1053 struct ieee80211com *ic;
1054 struct ieee80211_channel *c, *cent, *ext;
1055 int i, flags;
1057 ic = &sc->ic;
1059 /* set supported channels for 2GHz band */
1061 for (i = 1; i <= 14; i++)
1063 flags = IEEE80211_CHAN_G | IEEE80211_CHAN_HT40;
1065 /* find the center channel */
1067 cent = ieee80211_find_channel_byieee(ic, i,
1068 flags & ~IEEE80211_CHAN_HT);
1069 if (cent == NULL)
1071 printf("%s: skip channel %d, could not find center channel\n",
1072 device_get_nameunit(sc->dev), i);
1073 continue;
1076 /* find the extension channel */
1078 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1079 flags & ~IEEE80211_CHAN_HT);
1080 if (ext == NULL)
1082 printf("%s: skip channel %d, could not find extension channel\n",
1083 device_get_nameunit(sc->dev), i);
1084 continue;
1087 c = &ic->ic_channels[ic->ic_nchans++];
1089 *c = *cent;
1090 c->ic_extieee = ext->ic_ieee;
1091 c->ic_flags &= ~IEEE80211_CHAN_HT;
1092 c->ic_flags |= IEEE80211_CHAN_HT40U;
1094 c = &ic->ic_channels[ic->ic_nchans++];
1096 *c = *ext;
1097 c->ic_extieee = cent->ic_ieee;
1098 c->ic_flags &= ~IEEE80211_CHAN_HT;
1099 c->ic_flags |= IEEE80211_CHAN_HT40D;
1102 /* set supported channels for 5GHz band */
1104 if (sc->rf_rev == RT2870_EEPROM_RF_2850 ||
1105 sc->rf_rev == RT2870_EEPROM_RF_2750)
1107 for (i = 36; i <= 64; i += 4)
1109 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
1111 /* find the center channel */
1113 cent = ieee80211_find_channel_byieee(ic, i,
1114 flags & ~IEEE80211_CHAN_HT);
1115 if (cent == NULL)
1117 printf("%s: skip channel %d, could not find center channel\n",
1118 device_get_nameunit(sc->dev), i);
1119 continue;
1122 /* find the extension channel */
1124 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1125 flags & ~IEEE80211_CHAN_HT);
1126 if (ext == NULL)
1128 printf("%s: skip channel %d, could not find extension channel\n",
1129 device_get_nameunit(sc->dev), i);
1130 continue;
1133 c = &ic->ic_channels[ic->ic_nchans++];
1135 *c = *cent;
1136 c->ic_extieee = ext->ic_ieee;
1137 c->ic_flags &= ~IEEE80211_CHAN_HT;
1138 c->ic_flags |= IEEE80211_CHAN_HT40U;
1140 c = &ic->ic_channels[ic->ic_nchans++];
1142 *c = *ext;
1143 c->ic_extieee = cent->ic_ieee;
1144 c->ic_flags &= ~IEEE80211_CHAN_HT;
1145 c->ic_flags |= IEEE80211_CHAN_HT40D;
1148 for (i = 100; i <= 140; i += 4)
1150 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
1152 /* find the center channel */
1154 cent = ieee80211_find_channel_byieee(ic, i,
1155 flags & ~IEEE80211_CHAN_HT);
1156 if (cent == NULL)
1158 printf("%s: skip channel %d, could not find center channel\n",
1159 device_get_nameunit(sc->dev), i);
1160 continue;
1163 /* find the extension channel */
1165 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1166 flags & ~IEEE80211_CHAN_HT);
1167 if (ext == NULL)
1169 printf("%s: skip channel %d, could not find extension channel\n",
1170 device_get_nameunit(sc->dev), i);
1171 continue;
1174 c = &ic->ic_channels[ic->ic_nchans++];
1176 *c = *cent;
1177 c->ic_extieee = ext->ic_ieee;
1178 c->ic_flags &= ~IEEE80211_CHAN_HT;
1179 c->ic_flags |= IEEE80211_CHAN_HT40U;
1181 c = &ic->ic_channels[ic->ic_nchans++];
1183 *c = *ext;
1184 c->ic_extieee = cent->ic_ieee;
1185 c->ic_flags &= ~IEEE80211_CHAN_HT;
1186 c->ic_flags |= IEEE80211_CHAN_HT40D;
1189 for (i = 149; i <= 165; i += 4)
1191 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
1193 /* find the center channel */
1195 cent = ieee80211_find_channel_byieee(ic, i,
1196 flags & ~IEEE80211_CHAN_HT);
1197 if (cent == NULL)
1199 printf("%s: skip channel %d, could not find center channel\n",
1200 device_get_nameunit(sc->dev), i);
1201 continue;
1204 /* find the extension channel */
1206 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1207 flags & ~IEEE80211_CHAN_HT);
1208 if (ext == NULL)
1210 printf("%s: skip channel %d, could not find extension channel\n",
1211 device_get_nameunit(sc->dev), i);
1212 continue;
1215 c = &ic->ic_channels[ic->ic_nchans++];
1217 *c = *cent;
1218 c->ic_extieee = ext->ic_ieee;
1219 c->ic_flags &= ~IEEE80211_CHAN_HT;
1220 c->ic_flags |= IEEE80211_CHAN_HT40U;
1222 c = &ic->ic_channels[ic->ic_nchans++];
1224 *c = *ext;
1225 c->ic_extieee = cent->ic_ieee;
1226 c->ic_flags &= ~IEEE80211_CHAN_HT;
1227 c->ic_flags |= IEEE80211_CHAN_HT40D;
1233 * rt2870_init_locked
1235 static void rt2870_init_locked(void *priv)
1237 struct rt2870_softc *sc;
1238 struct ieee80211com *ic;
1239 struct ifnet *ifp;
1240 struct rt2870_softc_rx_data *data;
1241 int ntries, error, i;
1242 uint32_t tmp, stacnt[6];
1244 sc = priv;
1245 ic = &sc->ic;
1246 ifp = ic->ic_ifp;
1248 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1249 "%s: initializing\n",
1250 device_get_nameunit(sc->dev));
1252 if (!(sc->flags & RT2870_SOFTC_FLAGS_UCODE_LOADED))
1254 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1255 "%s: loading 8051 microcode\n",
1256 device_get_nameunit(sc->dev));
1258 error = rt2870_io_mcu_load_ucode(sc, rt2870_ucode, sizeof(rt2870_ucode));
1259 if (error != 0)
1261 printf("%s: could not load 8051 microcode\n",
1262 device_get_nameunit(sc->dev));
1263 goto fail;
1266 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1267 "%s: 8051 microcode was successfully loaded\n",
1268 device_get_nameunit(sc->dev));
1270 sc->flags |= RT2870_SOFTC_FLAGS_UCODE_LOADED;
1273 /* wait while DMA engine is busy */
1275 for (ntries = 0; ntries < 100; ntries++)
1277 tmp = rt2870_io_mac_read(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG);
1278 if (!(tmp & (RT2870_REG_TX_DMA_BUSY | RT2870_REG_RX_DMA_BUSY)))
1279 break;
1281 DELAY(1000);
1284 if (ntries == 100)
1286 printf("%s: timeout waiting for DMA engine\n",
1287 device_get_nameunit(sc->dev));
1288 goto fail;
1291 tmp &= 0xff0;
1292 tmp |= RT2870_REG_TX_WB_DDONE;
1294 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
1296 /* PBF hardware reset */
1298 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_SYS_CTRL);
1300 tmp &= ~(1 << 13);
1302 rt2870_io_mac_write(sc, RT2870_REG_PBF_SYS_CTRL, tmp);
1304 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL,
1305 RT2870_REG_MAC_SRST | RT2870_REG_BBP_HRST);
1307 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_DMA_CFG, 0);
1309 rt2870_io_mcu_reset(sc);
1311 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, 0);
1313 /* init Tx power per rate */
1315 for (i = 0; i < RT2870_SOFTC_TXPOW_RATE_COUNT; i++)
1317 if (sc->txpow_rate_20mhz[i] == 0xffffffff)
1318 continue;
1320 rt2870_io_mac_write(sc, RT2870_REG_TX_PWR_CFG(i),
1321 sc->txpow_rate_20mhz[i]);
1324 for (i = 0; i < RT2870_DEF_MAC_SIZE; i++)
1325 rt2870_io_mac_write(sc, rt2870_def_mac[i].reg,
1326 rt2870_def_mac[i].val);
1328 /* wait while MAC is busy */
1330 for (ntries = 0; ntries < 100; ntries++)
1332 if (!(rt2870_io_mac_read(sc, RT2870_REG_STATUS_CFG) &
1333 (RT2870_REG_STATUS_TX_BUSY | RT2870_REG_STATUS_RX_BUSY)))
1334 break;
1336 DELAY(1000);
1339 if (ntries == 100)
1341 printf("%s: timeout waiting for MAC\n",
1342 device_get_nameunit(sc->dev));
1343 goto fail;
1346 /* clear Host to MCU mailbox */
1348 rt2870_io_mac_write(sc, RT2870_REG_H2M_MAILBOX_BBP_AGENT, 0);
1349 rt2870_io_mac_write(sc, RT2870_REG_H2M_MAILBOX, 0);
1351 DELAY(1000);
1353 error = rt2870_init_bbp(sc);
1354 if (error != 0)
1355 goto fail;
1357 /* set up maximum buffer sizes */
1359 tmp = (1 << 12) | RT2870_MAX_AGG_SIZE;
1361 if (sc->mac_rev >= 0x28720200 && sc->mac_rev < 0x30700200)
1363 tmp &= 0xfff;
1364 tmp |= 0x2000;
1367 rt2870_io_mac_write(sc, RT2870_REG_MAX_LEN_CFG, tmp);
1369 /* set mac address */
1371 IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
1373 rt2870_asic_set_macaddr(sc, ic->ic_myaddr);
1375 /* clear statistic registers */
1377 rt2870_io_mac_read_multi(sc, RT2870_REG_RX_STA_CNT0,
1378 stacnt, sizeof(stacnt));
1380 /* send LEDs operating mode to microcontroller */
1382 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_LED1,
1383 RT2870_REG_H2M_TOKEN_NO_INTR, sc->led_off[0]);
1384 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_LED2,
1385 RT2870_REG_H2M_TOKEN_NO_INTR, sc->led_off[1]);
1386 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_LED3,
1387 RT2870_REG_H2M_TOKEN_NO_INTR, sc->led_off[2]);
1389 /* write vendor-specific BBP values (from EEPROM) */
1391 for (i = 0; i < RT2870_SOFTC_BBP_EEPROM_COUNT; i++)
1393 if (sc->bbp_eeprom[i].reg == 0x00 ||
1394 sc->bbp_eeprom[i].reg == 0xff)
1395 continue;
1397 rt2870_io_bbp_write(sc, sc->bbp_eeprom[i].reg,
1398 sc->bbp_eeprom[i].val);
1401 /* disable non-existing Rx chains */
1403 tmp = rt2870_io_bbp_read(sc, 3);
1405 tmp &= ~((1 << 4) | (1 << 3));
1407 if (sc->nrxpath == 3)
1408 tmp |= (1 << 4);
1409 else if (sc->nrxpath == 2)
1410 tmp |= (1 << 3);
1412 rt2870_io_bbp_write(sc, 3, tmp);
1414 /* disable non-existing Tx chains */
1416 tmp = rt2870_io_bbp_read(sc, 1);
1418 tmp &= ~((1 << 4) | (1 << 3));
1420 if (sc->ntxpath == 2)
1421 tmp |= (1 << 4);
1423 rt2870_io_bbp_write(sc, 1, tmp);
1425 /* set current channel */
1427 rt2870_rf_set_chan(sc, ic->ic_curchan);
1429 /* turn radio LED on */
1431 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_ON);
1433 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_BOOT,
1434 RT2870_REG_H2M_TOKEN_NO_INTR, 0);
1436 /* set RTS threshold */
1438 rt2870_asic_update_rtsthreshold(sc);
1440 /* set Tx power */
1442 rt2870_asic_update_txpower(sc);
1444 /* set up protection mode */
1446 sc->tx_ampdu_sessions = 0;
1448 rt2870_asic_updateprot(sc);
1450 /* clear beacon frame space (entries = 8, entry size = 512) */
1452 rt2870_io_mac_set_region_4(sc, RT2870_REG_BEACON_BASE(0), 0, 1024);
1454 /* enable Tx/Rx DMA engine */
1456 tmp = rt2870_io_mac_read(sc, RT2870_REG_SCHDMA_USB_CYC_CFG);
1458 tmp &= 0xffffff00;
1459 tmp |= 0x1e;
1461 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_CYC_CFG, tmp);
1463 if ((sc->mac_rev & 0xffff) != 0x0101)
1464 rt2870_io_mac_write(sc, RT2870_REG_TX_TXOP_CTRL_CFG, 0x583f);
1466 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, RT2870_REG_TX_ENABLE);
1468 for (ntries = 0; ntries < 200; ntries++)
1470 tmp = rt2870_io_mac_read(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG);
1471 if (!(tmp & (RT2870_REG_TX_DMA_BUSY | RT2870_REG_RX_DMA_BUSY)))
1472 break;
1474 DELAY(1000);
1477 if (ntries == 200)
1479 printf("%s: timeout waiting for DMA engine\n",
1480 device_get_nameunit(sc->dev));
1481 goto fail;
1484 DELAY(50);
1486 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP0_CFG, 0);
1487 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP1_CFG,
1488 (48 << 16) | 96);
1490 tmp |= RT2870_REG_TX_WB_DDONE |
1491 RT2870_REG_RX_DMA_ENABLE |
1492 RT2870_REG_TX_DMA_ENABLE;
1494 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
1496 tmp = RT2870_REG_USB_DMA_TX_ENABLE |
1497 RT2870_REG_USB_DMA_RX_ENABLE |
1498 RT2870_REG_USB_DMA_RX_AGG_ENABLE |
1499 /* Rx agg limit in unit of 1024 byte */
1500 ((RT2870_USB_RX_BULK_BUFLEN / 1024 - 3) << RT2870_REG_USB_DMA_RX_AGG_LIMIT_SHIFT) |
1501 /* Rx agg timeout in unit of 33ns */
1502 0x80;
1504 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_DMA_CFG, tmp);
1506 /* set Rx filter */
1508 tmp = RT2870_REG_RX_FILTER_DROP_CRC_ERR |
1509 RT2870_REG_RX_FILTER_DROP_PHY_ERR;
1511 if (ic->ic_opmode != IEEE80211_M_MONITOR)
1513 tmp |= RT2870_REG_RX_FILTER_DROP_DUPL |
1514 RT2870_REG_RX_FILTER_DROP_CTS |
1515 RT2870_REG_RX_FILTER_DROP_BA |
1516 RT2870_REG_RX_FILTER_DROP_ACK |
1517 RT2870_REG_RX_FILTER_DROP_VER_ERR |
1518 RT2870_REG_RX_FILTER_DROP_CTRL_RSV |
1519 RT2870_REG_RX_FILTER_DROP_CFACK |
1520 RT2870_REG_RX_FILTER_DROP_CFEND;
1522 if (ic->ic_opmode == IEEE80211_M_STA)
1523 tmp |= RT2870_REG_RX_FILTER_DROP_RTS |
1524 RT2870_REG_RX_FILTER_DROP_PSPOLL;
1526 if (!(ifp->if_flags & IFF_PROMISC))
1527 tmp |= RT2870_REG_RX_FILTER_DROP_UC_NOME;
1530 rt2870_io_mac_write(sc, RT2870_REG_RX_FILTER_CFG, tmp);
1532 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL,
1533 RT2870_REG_RX_ENABLE | RT2870_REG_TX_ENABLE);
1535 /* clear garbage interrupts */
1537 tmp = rt2870_io_mac_read(sc, 0x1300);
1539 taskqueue_unblock(sc->taskqueue);
1541 /* init Tx and Rx rings */
1543 for(i = 0; i < sc->usb_endpoints - 1; i++)
1544 rt2870_reset_tx_ring(sc, &sc->tx_ring[i]);
1546 rt2870_reset_rx_ring(sc, &sc->rx_ring);
1548 /* start up the receive pipe */
1550 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
1552 data = &sc->rx_ring.data[i];
1554 STAILQ_INSERT_TAIL(&sc->rx_ring.active, data, next);
1556 usbd_setup_xfer(data->xfer, sc->rx_ring.usb_pipe, sc, data->buf,
1557 RT2870_USB_RX_BULK_BUFLEN, USBD_SHORT_XFER_OK | USBD_NO_COPY,
1558 USBD_NO_TIMEOUT, rt2870_rx_intr);
1560 usbd_transfer(data->xfer);
1563 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1564 ifp->if_drv_flags |= IFF_DRV_RUNNING;
1566 if (ic->ic_opmode != IEEE80211_M_MONITOR)
1568 if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
1569 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
1571 else
1573 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
1576 sc->periodic_round = 0;
1578 callout_reset(&sc->periodic_ch, hz / 10, rt2870_periodic, sc);
1580 return;
1582 fail:
1584 rt2870_stop_locked(sc);
1588 * rt2870_init
1590 static void rt2870_init(void *priv)
1592 struct rt2870_softc *sc;
1594 sc = priv;
1596 rt2870_init_locked(sc);
1600 * rt2870_init_bbp
1602 static int rt2870_init_bbp(struct rt2870_softc *sc)
1604 int ntries, i;
1605 uint8_t tmp;
1607 for (ntries = 0; ntries < 20; ntries++)
1609 tmp = rt2870_io_bbp_read(sc, 0);
1610 if (tmp != 0x00 && tmp != 0xff)
1611 break;
1614 if (tmp == 0x00 || tmp == 0xff)
1616 printf("%s: timeout waiting for BBP to wakeup\n",
1617 device_get_nameunit(sc->dev));
1618 return ETIMEDOUT;
1621 for (i = 0; i < RT2870_DEF_BBP_SIZE; i++)
1622 rt2870_io_bbp_write(sc, rt2870_def_bbp[i].reg,
1623 rt2870_def_bbp[i].val);
1625 if ((sc->mac_rev & 0xffff) != 0x0101)
1626 rt2870_io_bbp_write(sc, 84, 0x19);
1628 return 0;
1632 * rt2870_stop
1634 static void rt2870_stop_locked(void *priv)
1636 struct rt2870_softc *sc;
1637 struct ieee80211com *ic;
1638 struct ifnet *ifp;
1639 uint32_t tmp;
1640 int i;
1642 sc = priv;
1643 ic = &sc->ic;
1644 ifp = ic->ic_ifp;
1646 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1647 "%s: stopping\n",
1648 device_get_nameunit(sc->dev));
1650 sc->tx_timer = 0;
1652 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1654 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
1656 callout_stop(&sc->periodic_ch);
1657 callout_stop(&sc->tx_watchdog_ch);
1659 taskqueue_block(sc->taskqueue);
1661 taskqueue_drain(sc->taskqueue, &sc->rx_done_task);
1662 taskqueue_drain(sc->taskqueue, &sc->tx_done_task);
1663 taskqueue_drain(sc->taskqueue, &sc->periodic_task);
1664 taskqueue_drain(sc->taskqueue, &sc->cmd_task);
1666 /* clear key tables */
1668 rt2870_asic_clear_keytables(sc);
1670 /* disable Tx/Rx */
1672 tmp = rt2870_io_mac_read(sc, RT2870_REG_SYS_CTRL);
1674 tmp &= ~(RT2870_REG_RX_ENABLE | RT2870_REG_TX_ENABLE);
1676 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, tmp);
1678 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_DMA_CFG, 0);
1680 /* reset adapter */
1682 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL,
1683 RT2870_REG_MAC_SRST | RT2870_REG_BBP_HRST);
1684 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, 0);
1686 /* abort any pending transfers */
1688 if (sc->rx_ring.usb_pipe != NULL)
1689 usbd_abort_pipe(sc->rx_ring.usb_pipe);
1691 for (i = 0; i < sc->usb_endpoints - 1; i++)
1692 if (sc->tx_ring[i].usb_pipe != NULL)
1693 usbd_abort_pipe(sc->tx_ring[i].usb_pipe);
1695 if (sc->beacon_mbuf != NULL)
1697 m_free(sc->beacon_mbuf);
1698 sc->beacon_mbuf = NULL;
1701 rt2870_reset_cmd_ring(sc, &sc->cmd_ring);
1705 * rt2870_stop
1707 static void rt2870_stop(void *priv)
1709 struct rt2870_softc *sc;
1711 sc = priv;
1713 rt2870_stop_locked(sc);
1717 * rt2870_start
1719 static void rt2870_start(struct ifnet *ifp)
1721 struct rt2870_softc *sc;
1722 struct ieee80211com *ic;
1723 struct ieee80211_node *ni;
1724 struct ether_header *eh;
1725 struct mbuf *m;
1726 int qid;
1728 sc = ifp->if_softc;
1729 ic = &sc->ic;
1731 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1732 return;
1734 for (;;)
1736 IF_POLL(&ic->ic_mgtq, m);
1737 if (m != NULL)
1739 if (sc->tx_ring[sc->tx_ring_mgtqid].queued >= RT2870_SOFTC_TX_RING_DATA_COUNT)
1741 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
1742 "%s: if_start: Tx ring with qid=%d is full\n",
1743 device_get_nameunit(sc->dev), sc->tx_ring_mgtqid);
1745 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1747 sc->tx_data_queue_full[sc->tx_ring_mgtqid]++;
1749 break;
1752 IF_DEQUEUE(&ic->ic_mgtq, m);
1753 if (m == NULL)
1754 break;
1756 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1758 m->m_pkthdr.rcvif = NULL;
1760 if (bpf_peers_present(ic->ic_rawbpf))
1761 bpf_mtap(ic->ic_rawbpf, m);
1763 if (rt2870_tx_frame(sc, m, ni, sc->tx_ring_mgtqid) != 0)
1764 break;
1766 else
1768 if (ic->ic_state != IEEE80211_S_RUN)
1769 break;
1771 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1772 if (m == NULL)
1773 break;
1775 if (ic->ic_flags & IEEE80211_F_SCAN)
1776 ieee80211_cancel_scan(ic);
1778 if (m->m_len < sizeof(struct ether_header) &&
1779 !(m = m_pullup(m, sizeof (struct ether_header))))
1780 continue;
1782 eh = mtod(m, struct ether_header *);
1784 ni = ieee80211_find_txnode(ic, eh->ether_dhost);
1785 if (ni == NULL)
1787 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
1788 "%s: if_start: could not find Tx node\n",
1789 device_get_nameunit(sc->dev));
1791 m_freem(m);
1793 continue;
1796 ieee80211_classify(ic, m, ni);
1798 qid = M_WME_GETAC(m);
1800 if (sc->tx_ring[qid].queued >= RT2870_SOFTC_TX_RING_DATA_COUNT)
1802 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
1803 "%s: if_start: Tx ring with qid=%d is full\n",
1804 device_get_nameunit(sc->dev), qid);
1806 m_freem(m);
1807 ieee80211_free_node(ni);
1809 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1810 ifp->if_oerrors++;
1812 sc->tx_data_queue_full[qid]++;
1814 break;
1817 BPF_MTAP(ifp, m);
1819 m = ieee80211_encap(ic, m, ni);
1820 if (m == NULL)
1822 ieee80211_free_node(ni);
1824 ifp->if_oerrors++;
1826 continue;
1829 if (bpf_peers_present(ic->ic_rawbpf))
1830 bpf_mtap(ic->ic_rawbpf, m);
1832 if (rt2870_tx_frame(sc, m, ni, qid) != 0)
1834 ieee80211_free_node(ni);
1836 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1837 ifp->if_oerrors++;
1839 break;
1843 sc->tx_timer = RT2870_TX_WATCHDOG_TIMEOUT;
1845 ic->ic_lastdata = ticks;
1847 callout_reset(&sc->tx_watchdog_ch, hz, rt2870_tx_watchdog, sc);
1852 * rt2870_ioctl
1854 static int rt2870_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1856 struct rt2870_softc *sc;
1857 struct ieee80211com *ic;
1858 int error;
1860 sc = ifp->if_softc;
1861 ic = &sc->ic;
1863 error = 0;
1865 switch (cmd)
1867 case SIOCSIFFLAGS:
1868 if (ifp->if_flags & IFF_UP)
1870 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1872 if ((ifp->if_flags ^ sc->if_flags) & IFF_PROMISC)
1873 rt2870_asic_update_promisc(sc);
1875 else
1877 rt2870_init_locked(sc);
1880 else
1882 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1883 rt2870_stop_locked(sc);
1886 sc->if_flags = ifp->if_flags;
1887 break;
1889 default:
1890 error = ieee80211_ioctl(ic, cmd, data);
1893 if (error == ENETRESET)
1895 if ((ifp->if_flags & IFF_UP) &&
1896 (ifp->if_drv_flags & IFF_DRV_RUNNING) &&
1897 (ic->ic_roaming != IEEE80211_ROAMING_MANUAL))
1899 rt2870_stop_locked(sc);
1900 rt2870_init_locked(sc);
1903 error = 0;
1906 return error;
1910 * rt2870_reset
1912 static int rt2870_reset(struct ifnet *ifp)
1914 struct rt2870_softc *sc;
1915 struct ieee80211com *ic;
1917 sc = ifp->if_softc;
1918 ic = &sc->ic;
1920 if (ic->ic_opmode != IEEE80211_M_MONITOR)
1921 return ENETRESET;
1923 rt2870_rf_set_chan(sc, ic->ic_curchan);
1925 return 0;
1929 * rt2870_newstate
1931 static int rt2870_newstate(struct ieee80211com *ic,
1932 enum ieee80211_state nstate, int arg)
1934 struct rt2870_softc *sc;
1935 struct ifnet *ifp;
1936 struct rt2870_cmd_argv_newstate cmd_argv;
1938 ifp = ic->ic_ifp;
1939 sc = ifp->if_softc;
1941 cmd_argv.nstate = nstate;
1942 cmd_argv.arg = arg;
1944 rt2870_do_async(sc, rt2870_newstate_cb, &cmd_argv,
1945 sizeof(struct rt2870_cmd_argv_newstate));
1947 return 0;
1951 * rt2870_scan_start
1953 static void rt2870_scan_start(struct ieee80211com *ic)
1955 struct rt2870_softc *sc;
1956 struct ifnet *ifp;
1958 ifp = ic->ic_ifp;
1959 sc = ifp->if_softc;
1961 rt2870_do_async(sc, rt2870_scan_start_cb, NULL, 0);
1965 * rt2870_scan_end
1967 static void rt2870_scan_end(struct ieee80211com *ic)
1969 struct rt2870_softc *sc;
1970 struct ifnet *ifp;
1972 ifp = ic->ic_ifp;
1973 sc = ifp->if_softc;
1975 rt2870_do_async(sc, rt2870_scan_end_cb, NULL, 0);
1979 * rt2870_set_channel
1981 static void rt2870_set_channel(struct ieee80211com *ic)
1983 struct rt2870_softc *sc;
1984 struct ifnet *ifp;
1986 ifp = ic->ic_ifp;
1987 sc = ifp->if_softc;
1989 rt2870_do_async(sc, rt2870_set_channel_cb, NULL, 0);
1993 * rt2870_newassoc
1995 static void rt2870_newassoc(struct ieee80211_node *ni, int isnew)
1997 struct rt2870_softc *sc;
1998 struct ieee80211com *ic;
1999 struct ifnet *ifp;
2000 struct rt2870_cmd_argv_newassoc cmd_argv;
2002 ic = ni->ni_ic;
2003 ifp = ic->ic_ifp;
2004 sc = ifp->if_softc;
2006 cmd_argv.isnew = isnew;
2007 memcpy(cmd_argv.macaddr, ni->ni_macaddr, IEEE80211_ADDR_LEN);
2009 rt2870_do_async(sc, rt2870_newassoc_cb, &cmd_argv,
2010 sizeof(struct rt2870_cmd_argv_newassoc));
2014 * rt2870_updateslot
2016 static void rt2870_updateslot(struct ifnet *ifp)
2018 struct rt2870_softc *sc;
2020 sc = ifp->if_softc;
2022 rt2870_do_async(sc, rt2870_updateslot_cb, NULL, 0);
2026 * rt2870_wme_update
2028 static int rt2870_wme_update(struct ieee80211com *ic)
2030 struct rt2870_softc *sc;
2031 struct ifnet *ifp;
2033 ifp = ic->ic_ifp;
2034 sc = ifp->if_softc;
2036 rt2870_do_async(sc, rt2870_wme_update_cb, NULL, 0);
2038 return 0;
2042 * rt2870_update_beacon
2044 static void rt2870_update_beacon(struct ieee80211com *ic, int what)
2046 struct rt2870_softc *sc;
2047 struct ifnet *ifp;
2048 struct rt2870_cmd_argv_updatebeacon cmd_argv;
2050 ifp = ic->ic_ifp;
2051 sc = ifp->if_softc;
2053 cmd_argv.what = what;
2055 rt2870_do_async(sc, rt2870_update_beacon_cb, &cmd_argv,
2056 sizeof(struct rt2870_cmd_argv_updatebeacon));
2060 * rt2870_key_update_begin
2062 static void rt2870_key_update_begin(struct ieee80211com *ic)
2064 struct rt2870_softc *sc;
2065 struct ifnet *ifp;
2067 ifp = ic->ic_ifp;
2068 sc = ifp->if_softc;
2070 rt2870_do_async(sc, rt2870_key_update_begin_cb, NULL, 0);
2074 * rt2870_key_update_end
2076 static void rt2870_key_update_end(struct ieee80211com *ic)
2078 struct rt2870_softc *sc;
2079 struct ifnet *ifp;
2081 ifp = ic->ic_ifp;
2082 sc = ifp->if_softc;
2084 rt2870_do_async(sc, rt2870_key_update_end_cb, NULL, 0);
2088 * rt2870_key_set
2090 static int rt2870_key_set(struct ieee80211com *ic,
2091 const struct ieee80211_key *k, const uint8_t mac[IEEE80211_ADDR_LEN])
2093 struct rt2870_softc *sc;
2094 struct ifnet *ifp;
2095 struct ieee80211_node *ni;
2096 struct rt2870_softc_node *rni;
2097 struct rt2870_cmd_argv_keyset cmd_argv;
2099 if (k->wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP &&
2100 k->wk_cipher->ic_cipher != IEEE80211_CIPHER_TKIP &&
2101 k->wk_cipher->ic_cipher != IEEE80211_CIPHER_AES_CCM)
2102 return EINVAL;
2104 ifp = ic->ic_ifp;
2105 sc = ifp->if_softc;
2107 cmd_argv.opmode = ic->ic_opmode;
2109 memcpy(&cmd_argv.key, k, sizeof(struct ieee80211_key));
2111 if (!(k->wk_flags & IEEE80211_KEY_GROUP))
2113 ni = ieee80211_find_node(&ic->ic_sta, mac);
2114 rni = (struct rt2870_softc_node *) ni;
2116 cmd_argv.staid = rni->staid;
2118 ieee80211_free_node(ni);
2121 rt2870_do_async(sc, rt2870_key_set_cb, &cmd_argv,
2122 sizeof(struct rt2870_cmd_argv_keyset));
2124 return 1;
2128 * rt2870_key_delete
2130 static int rt2870_key_delete(struct ieee80211com *ic,
2131 const struct ieee80211_key *k)
2133 struct rt2870_softc *sc;
2134 struct ifnet *ifp;
2135 struct rt2870_cmd_argv_keydelete cmd_argv;
2137 ifp = ic->ic_ifp;
2138 sc = ifp->if_softc;
2140 cmd_argv.opmode = ic->ic_opmode;
2142 memcpy(&cmd_argv.key, k, sizeof(struct ieee80211_key));
2144 rt2870_do_async(sc, rt2870_key_delete_cb, &cmd_argv,
2145 sizeof(struct rt2870_cmd_argv_keydelete));
2147 return 1;
2151 * rt2870_raw_xmit
2153 static int rt2870_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2154 const struct ieee80211_bpf_params *params)
2156 struct ieee80211com *ic;
2157 struct ifnet *ifp;
2158 struct rt2870_softc *sc;
2160 ic = ni->ni_ic;
2161 ifp = ic->ic_ifp;
2162 sc = ifp->if_softc;
2164 return 0;
2168 * rt2870_media_change
2170 static int rt2870_media_change(struct ifnet *ifp)
2172 struct rt2870_softc *sc;
2173 int error;
2175 sc = ifp->if_softc;
2177 error = ieee80211_media_change(ifp);
2178 if (error != ENETRESET)
2179 return error;
2181 if ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
2183 rt2870_stop(sc);
2184 rt2870_init(sc);
2187 return 0;
2191 * rt2870_node_alloc
2193 static struct ieee80211_node *rt2870_node_alloc(struct ieee80211_node_table *nt)
2195 return malloc(sizeof(struct rt2870_softc_node),
2196 M_80211_NODE, M_NOWAIT | M_ZERO);
2200 * rt2870_node_cleanup
2202 static void rt2870_node_cleanup(struct ieee80211_node *ni)
2204 struct rt2870_softc *sc;
2205 struct ieee80211com *ic;
2206 struct ifnet *ifp;
2207 struct ieee80211_rx_ampdu *rx_ampdu;
2208 struct rt2870_softc_node *rni;
2209 struct rt2870_cmd_argv_nodecleanup cmd_argv;
2210 int i;
2212 ic = ni->ni_ic;
2213 ifp = ic->ic_ifp;
2214 sc = ifp->if_softc;
2215 rni = (struct rt2870_softc_node *) ni;
2217 RT2870_DPRINTF(sc, RT2870_DEBUG_NODE,
2218 "%s: node cleanup: macaddr=%s, associd=0x%04x, staid=0x%02x\n",
2219 device_get_nameunit(sc->dev), ether_sprintf(ni->ni_macaddr),
2220 ni->ni_associd, rni->staid);
2222 if (rni->staid != 0)
2224 cmd_argv.staid = rni->staid;
2226 rni->staid = 0;
2228 for (i = 0; i < WME_NUM_TID; i++)
2230 rx_ampdu = &ni->ni_rx_ampdu[i];
2232 if (rx_ampdu->rxa_flags & IEEE80211_AGGR_XCHGPEND)
2234 if (sc->rx_ampdu_sessions > 0)
2235 sc->rx_ampdu_sessions--;
2236 else
2237 printf("%s: number of A-MPDU Rx sessions cannot be negative\n",
2238 device_get_nameunit(sc->dev));
2242 rt2870_do_async(sc, rt2870_node_cleanup_cb,
2243 &cmd_argv, sizeof(struct rt2870_cmd_argv_nodecleanup));
2246 sc->node_cleanup(ni);
2250 * rt2870_recv_action
2252 static void rt2870_recv_action(struct ieee80211_node *ni,
2253 const uint8_t *frm, const uint8_t *efrm)
2255 struct rt2870_softc *sc;
2256 struct ieee80211com *ic;
2257 struct ifnet *ifp;
2258 struct ieee80211_rx_ampdu *rx_ampdu;
2259 struct rt2870_softc_node *rni;
2260 const struct ieee80211_action *ia;
2261 uint16_t baparamset;
2262 int tid;
2263 uint8_t wcid;
2265 ic = ni->ni_ic;
2266 ifp = ic->ic_ifp;
2267 sc = ifp->if_softc;
2268 rni = (struct rt2870_softc_node *) ni;
2270 ia = (const struct ieee80211_action *) frm;
2272 if (ia->ia_category == IEEE80211_ACTION_CAT_BA)
2274 switch (ia->ia_action)
2276 /* IEEE80211_ACTION_BA_DELBA */
2277 case IEEE80211_ACTION_BA_DELBA:
2278 baparamset = LE_READ_2(frm + 2);
2279 tid = RT2870_MS(baparamset, IEEE80211_BAPS_TID);
2280 rx_ampdu = &ni->ni_rx_ampdu[tid];
2281 wcid = rni->staid;
2283 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2284 "%s: received DELBA request: associd=0x%04x, staid=0x%02x, tid=%d\n",
2285 device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, tid);
2287 if (rni->staid != 0)
2289 rt2870_asic_del_ba_session(sc, wcid, tid);
2291 if (rx_ampdu->rxa_flags & IEEE80211_AGGR_XCHGPEND)
2293 if (sc->rx_ampdu_sessions > 0)
2294 sc->rx_ampdu_sessions--;
2295 else
2296 printf("%s: number of A-MPDU Rx sessions cannot be negative\n",
2297 device_get_nameunit(sc->dev));
2300 break;
2304 sc->recv_action(ni, frm, efrm);
2308 * rt2870_send_action
2310 static int rt2870_send_action(struct ieee80211_node *ni,
2311 int category, int action, uint16_t args[4])
2313 struct rt2870_softc *sc;
2314 struct ieee80211com *ic;
2315 struct ifnet *ifp;
2316 struct ieee80211_rx_ampdu *rx_ampdu;
2317 struct rt2870_softc_node *rni;
2318 uint16_t status, baparamset;
2319 uint8_t wcid;
2320 int tid, bufsize;
2322 ic = ni->ni_ic;
2323 ifp = ic->ic_ifp;
2324 sc = ifp->if_softc;
2325 rni = (struct rt2870_softc_node *) ni;
2327 wcid = rni->staid;
2329 if (category == IEEE80211_ACTION_CAT_BA)
2331 switch (action)
2333 /* IEEE80211_ACTION_BA_ADDBA_RESPONSE */
2334 case IEEE80211_ACTION_BA_ADDBA_RESPONSE:
2335 status = args[1];
2336 baparamset = args[2];
2337 tid = RT2870_MS(baparamset, IEEE80211_BAPS_TID);
2338 bufsize = RT2870_MS(baparamset, IEEE80211_BAPS_BUFSIZ);
2339 rx_ampdu = &ni->ni_rx_ampdu[tid];
2341 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2342 "%s: sending ADDBA response: associd=0x%04x, staid=0x%02x, status=%d, tid=%d, bufsize=%d\n",
2343 device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, status, tid, bufsize);
2345 if (status == IEEE80211_STATUS_SUCCESS)
2347 rt2870_asic_add_ba_session(sc, wcid, tid);
2349 sc->rx_ampdu_sessions++;
2351 break;
2353 /* IEEE80211_ACTION_BA_DELBA */
2354 case IEEE80211_ACTION_BA_DELBA:
2355 baparamset = RT2870_SM(args[0], IEEE80211_DELBAPS_TID) | args[1];
2356 tid = RT2870_MS(baparamset, IEEE80211_DELBAPS_TID);
2357 rx_ampdu = &ni->ni_rx_ampdu[tid];
2359 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2360 "%s: sending DELBA request: associd=0x%04x, staid=0x%02x, tid=%d\n",
2361 device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, tid);
2363 if (RT2870_MS(baparamset, IEEE80211_DELBAPS_INIT) != IEEE80211_DELBAPS_INIT)
2365 rt2870_asic_del_ba_session(sc, wcid, tid);
2367 if (rx_ampdu->rxa_flags & IEEE80211_AGGR_XCHGPEND)
2369 if (sc->rx_ampdu_sessions > 0)
2370 sc->rx_ampdu_sessions--;
2371 else
2372 printf("%s: number of A-MPDU Rx sessions cannot be negative\n",
2373 device_get_nameunit(sc->dev));
2376 break;
2380 return sc->send_action(ni, category, action, args);
2384 * rt2870_addba_response
2386 static int rt2870_addba_response(struct ieee80211_node *ni,
2387 struct ieee80211_tx_ampdu *tap,
2388 int status, int baparamset, int batimeout)
2390 struct rt2870_softc *sc;
2391 struct ieee80211com *ic;
2392 struct ifnet *ifp;
2393 struct rt2870_softc_node *rni;
2394 ieee80211_seq seqno;
2395 int ret, tid, old_bufsize, new_bufsize;
2397 ic = ni->ni_ic;
2398 ifp = ic->ic_ifp;
2399 sc = ifp->if_softc;
2400 rni = (struct rt2870_softc_node *) ni;
2402 tid = RT2870_MS(baparamset, IEEE80211_BAPS_TID);
2403 old_bufsize = RT2870_MS(baparamset, IEEE80211_BAPS_BUFSIZ);
2404 new_bufsize = old_bufsize;
2406 if (status == IEEE80211_STATUS_SUCCESS)
2408 if (sc->mac_rev >= 0x28830300)
2410 if (sc->mac_rev >= 0x30700200)
2411 new_bufsize = 13;
2412 else
2413 new_bufsize = 31;
2415 else if (sc->mac_rev >= 0x28720200)
2417 new_bufsize = 13;
2419 else
2421 new_bufsize = 7;
2424 if (old_bufsize > new_bufsize)
2426 baparamset &= ~IEEE80211_BAPS_BUFSIZ;
2427 baparamset = RT2870_SM(new_bufsize, IEEE80211_BAPS_BUFSIZ);
2430 if (!(tap->txa_flags & IEEE80211_AGGR_RUNNING))
2432 sc->tx_ampdu_sessions++;
2434 if (sc->tx_ampdu_sessions == 1)
2435 rt2870_asic_updateprot(sc);
2439 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2440 "%s: received ADDBA response: associd=0x%04x, staid=0x%02x, status=%d, tid=%d, "
2441 "old bufsize=%d, new bufsize=%d\n",
2442 device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, status, tid,
2443 old_bufsize, new_bufsize);
2445 ret = sc->addba_response(ni, tap, status, baparamset, batimeout);
2447 if (status == IEEE80211_STATUS_SUCCESS)
2449 seqno = ni->ni_txseqs[tid];
2451 rt2870_send_bar(ni, tap, seqno);
2454 return ret;
2458 * rt2870_addba_stop
2460 static void rt2870_addba_stop(struct ieee80211_node *ni,
2461 struct ieee80211_tx_ampdu *tap)
2463 struct rt2870_softc *sc;
2464 struct ieee80211com *ic;
2465 struct ifnet *ifp;
2466 struct rt2870_softc_node *rni;
2467 int tid;
2469 ic = ni->ni_ic;
2470 ifp = ic->ic_ifp;
2471 sc = ifp->if_softc;
2472 rni = (struct rt2870_softc_node *) ni;
2474 tid = WME_AC_TO_TID(tap->txa_ac);
2476 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2477 "%s: stopping A-MPDU Tx: associd=0x%04x, staid=0x%02x, tid=%d\n",
2478 device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, tid);
2480 if (tap->txa_flags & IEEE80211_AGGR_RUNNING)
2482 if (sc->tx_ampdu_sessions > 0)
2484 sc->tx_ampdu_sessions--;
2486 if (sc->tx_ampdu_sessions == 0)
2487 rt2870_asic_updateprot(sc);
2489 else
2491 printf("%s: number of A-MPDU Tx sessions cannot be negative\n",
2492 device_get_nameunit(sc->dev));
2496 sc->addba_stop(ni, tap);
2500 * rt2870_send_bar
2502 static int rt2870_send_bar(struct ieee80211_node *ni,
2503 struct ieee80211_tx_ampdu *tap, ieee80211_seq seqno)
2505 struct rt2870_softc *sc;
2506 struct ieee80211com *ic;
2507 struct ifnet *ifp;
2508 struct ieee80211_frame_bar *bar;
2509 struct rt2870_softc_node *rni;
2510 struct mbuf *m;
2511 uint16_t barctl, barseqctl;
2512 uint8_t *frm;
2513 int tid;
2515 ic = ni->ni_ic;
2516 ifp = ic->ic_ifp;
2517 sc = ifp->if_softc;
2518 rni = (struct rt2870_softc_node *) ni;
2520 if (!(tap->txa_flags & IEEE80211_AGGR_RUNNING))
2521 return EINVAL;
2523 m = ieee80211_getmgtframe(&frm, ic->ic_headroom, sizeof(struct ieee80211_frame_bar));
2524 if (m == NULL)
2525 return ENOMEM;
2527 bar = mtod(m, struct ieee80211_frame_bar *);
2529 bar->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_BAR;
2530 bar->i_fc[1] = 0;
2532 IEEE80211_ADDR_COPY(bar->i_ra, ni->ni_macaddr);
2533 IEEE80211_ADDR_COPY(bar->i_ta, ic->ic_myaddr);
2535 tid = WME_AC_TO_TID(tap->txa_ac);
2537 barctl = (tap->txa_flags & IEEE80211_AGGR_IMMEDIATE ? 0 : IEEE80211_BAR_NOACK) |
2538 IEEE80211_BAR_COMP |
2539 RT2870_SM(tid, IEEE80211_BAR_TID);
2540 barseqctl = RT2870_SM(seqno, IEEE80211_BASEQ_START);
2542 bar->i_ctl = htole16(barctl);
2543 bar->i_seq = htole16(barseqctl);
2545 m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame_bar);
2546 m->m_pkthdr.rcvif = (void *) ni;
2548 tap->txa_start = seqno;
2550 ieee80211_ref_node(ni);
2552 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2553 "%s: sending BAR: associd=0x%04x, staid=0x%02x, tid=%d, seqno=%d\n",
2554 device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, tid, seqno);
2556 IF_ENQUEUE(&ic->ic_mgtq, m);
2558 if_start(ifp);
2560 return 0;
2564 * rt2870_amrr_update_iter_func
2566 static void rt2870_amrr_update_iter_func(void *arg, struct ieee80211_node *ni)
2568 struct rt2870_softc *sc;
2569 struct ieee80211com *ic;
2570 struct rt2870_softc_node *rni;
2571 uint8_t wcid;
2573 sc = arg;
2574 ic = &sc->ic;
2575 rni = (struct rt2870_softc_node *) ni;
2577 /* only associated stations */
2579 if (rni->staid != 0)
2581 wcid = rni->staid;
2583 RT2870_DPRINTF(sc, RT2870_DEBUG_RATE,
2584 "%s: AMRR node: staid=0x%02x, txcnt=%d, success=%d, retrycnt=%d\n",
2585 device_get_nameunit(sc->dev),
2586 rni->staid, sc->amrr_node[wcid].txcnt, sc->amrr_node[wcid].success, sc->amrr_node[wcid].retrycnt);
2588 rt2870_amrr_choose(ni, &sc->amrr_node[wcid]);
2590 RT2870_DPRINTF(sc, RT2870_DEBUG_RATE,
2591 "%s:%s node Tx rate: associd=0x%04x, staid=0x%02x, rate=0x%02x, max rate=0x%02x\n",
2592 device_get_nameunit(sc->dev),
2593 (ni->ni_flags & IEEE80211_NODE_HT) ? " HT" : "",
2594 ni->ni_associd, rni->staid,
2595 (ni->ni_flags & IEEE80211_NODE_HT) ?
2596 (ni->ni_htrates.rs_rates[ni->ni_txrate] | IEEE80211_RATE_MCS) :
2597 (ni->ni_rates.rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL),
2598 (ni->ni_flags & IEEE80211_NODE_HT) ?
2599 (ni->ni_htrates.rs_rates[ni->ni_htrates.rs_nrates - 1] | IEEE80211_RATE_MCS) :
2600 (ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates - 1] & IEEE80211_RATE_VAL));
2605 * rt2870_periodic
2607 static void rt2870_periodic(void *arg)
2609 struct rt2870_softc *sc;
2610 struct ifnet *ifp;
2612 sc = arg;
2613 ifp = sc->ifp;
2615 RT2870_DPRINTF(sc, RT2870_DEBUG_PERIODIC,
2616 "%s: periodic\n",
2617 device_get_nameunit(sc->dev));
2619 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
2620 return;
2622 taskqueue_enqueue(sc->taskqueue, &sc->periodic_task);
2626 * rt2870_tx_watchdog
2628 static void rt2870_tx_watchdog(void *arg)
2630 struct rt2870_softc *sc;
2631 struct ifnet *ifp;
2633 sc = arg;
2634 ifp = sc->ifp;
2636 if (sc->tx_timer == 0)
2637 return;
2639 if (--sc->tx_timer == 0)
2641 printf("%s: Tx watchdog timeout: resetting\n",
2642 device_get_nameunit(sc->dev));
2644 rt2870_stop_locked(sc);
2645 rt2870_init_locked(sc);
2647 ifp->if_oerrors++;
2649 sc->tx_watchdog_timeouts++;
2652 callout_reset(&sc->tx_watchdog_ch, hz, rt2870_tx_watchdog, sc);
2656 * rt2870_staid_alloc
2658 static int rt2870_staid_alloc(struct rt2870_softc *sc, int aid)
2660 int staid;
2662 if ((aid > 0 && aid < RT2870_SOFTC_STAID_COUNT) && isclr(sc->staid_mask, aid))
2664 staid = aid;
2666 else
2668 for (staid = 1; staid < RT2870_SOFTC_STAID_COUNT; staid++)
2670 if (isclr(sc->staid_mask, staid))
2671 break;
2675 setbit(sc->staid_mask, staid);
2677 return staid;
2681 * rt2870_staid_delete
2683 static void rt2870_staid_delete(struct rt2870_softc *sc, int staid)
2685 clrbit(sc->staid_mask, staid);
2689 * rt2870_do_async
2691 static int rt2870_do_async(struct rt2870_softc *sc,
2692 void (*cb)(struct rt2870_softc *sc, void *arg),
2693 void *arg, int len)
2695 struct ifnet *ifp;
2696 struct rt2870_softc_cmd_ring *ring;
2697 struct rt2870_softc_cmd *cmd;
2698 int run_cmd_task;
2700 ifp = sc->ifp;
2701 ring = &sc->cmd_ring;
2703 if (!(sc->flags & RT2870_SOFTC_FLAGS_VALID))
2704 return -1;
2706 RT2870_SOFTC_LOCK(sc);
2708 if (ring->queued >= RT2870_SOFTC_CMD_RING_CMD_COUNT)
2710 RT2870_SOFTC_UNLOCK(sc);
2711 return -1;
2714 cmd = STAILQ_FIRST(&ring->inactive);
2715 STAILQ_REMOVE_HEAD(&ring->inactive, next);
2717 cmd->cb = cb;
2719 if(arg != NULL)
2720 memcpy(cmd->data, arg, len);
2722 STAILQ_INSERT_TAIL(&ring->active, cmd, next);
2723 ring->queued++;
2725 run_cmd_task = (ring->queued == 1);
2727 RT2870_SOFTC_UNLOCK(sc);
2729 if (run_cmd_task)
2730 taskqueue_enqueue(sc->taskqueue, &sc->cmd_task);
2732 return 0;
2736 * rt2870_newstate_cb
2738 static void rt2870_newstate_cb(struct rt2870_softc *sc, void *arg)
2740 struct ieee80211com *ic;
2741 enum ieee80211_state nstate;
2742 struct ieee80211_node *ni;
2743 struct rt2870_cmd_argv_newstate *cmd_argv;
2744 int error;
2746 ic = &sc->ic;
2747 cmd_argv = arg;
2748 nstate = cmd_argv->nstate;
2750 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
2751 "%s: newstate: %s -> %s\n",
2752 device_get_nameunit(sc->dev),
2753 ieee80211_state_name[ic->ic_state], ieee80211_state_name[nstate]);
2755 error = sc->newstate(ic, nstate, cmd_argv->arg);
2756 if (error != 0)
2757 return;
2759 /* turn link LED off */
2761 if (nstate != IEEE80211_S_RUN)
2762 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_OFF);
2764 switch (nstate)
2766 case IEEE80211_S_INIT:
2767 rt2870_asic_disable_tsf_sync(sc);
2768 break;
2770 case IEEE80211_S_RUN:
2771 ni = ic->ic_bss;
2773 if (ic->ic_opmode != IEEE80211_M_MONITOR)
2774 rt2870_rf_set_chan(sc, ni->ni_chan);
2776 if (ic->ic_opmode != IEEE80211_M_MONITOR)
2778 rt2870_asic_enable_mrr(sc);
2779 rt2870_asic_set_txpreamble(sc);
2780 rt2870_asic_set_basicrates(sc);
2781 rt2870_asic_set_bssid(sc, ni->ni_bssid);
2784 if (ic->ic_opmode == IEEE80211_M_STA)
2785 rt2870_newassoc(ni, 1);
2787 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
2788 ic->ic_opmode == IEEE80211_M_IBSS)
2790 error = rt2870_beacon_alloc(sc);
2791 if (error != 0)
2792 break;
2794 rt2870_asic_update_beacon(sc);
2797 if (ic->ic_opmode != IEEE80211_M_MONITOR)
2798 rt2870_asic_enable_tsf_sync(sc);
2800 /* turn link LED on */
2802 if (ic->ic_opmode != IEEE80211_M_MONITOR)
2804 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_ON |
2805 (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) ?
2806 RT2870_LED_CMD_LINK_2GHZ : RT2870_LED_CMD_LINK_5GHZ));
2808 break;
2810 default:
2811 break;
2816 * rt2870_node_cleanup_cb
2818 static void rt2870_node_cleanup_cb(struct rt2870_softc *sc, void *arg)
2820 struct ieee80211com *ic;
2821 struct rt2870_cmd_argv_nodecleanup *cmd_argv;
2822 uint8_t staid, vapid, wcid;
2823 uint32_t tmp;
2825 ic = &sc->ic;
2826 cmd_argv = arg;
2827 staid = cmd_argv->staid;
2829 vapid = 0;
2830 wcid = staid;
2832 tmp = ((vapid & RT2870_REG_VAP_MASK) << RT2870_REG_VAP_SHIFT) |
2833 (RT2870_REG_CIPHER_MODE_NONE << RT2870_REG_CIPHER_MODE_SHIFT) | RT2870_REG_PKEY_ENABLE;
2835 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
2837 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid), 0x00000000);
2838 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, 0x00000000);
2840 rt2870_staid_delete(sc, staid);
2844 * rt2870_scan_start_cb
2846 static void rt2870_scan_start_cb(struct rt2870_softc *sc, void *arg)
2848 struct ieee80211com *ic;
2849 struct ifnet *ifp;
2851 ic = &sc->ic;
2852 ifp = ic->ic_ifp;
2854 rt2870_asic_disable_tsf_sync(sc);
2858 * rt2870_scan_end_cb
2860 static void rt2870_scan_end_cb(struct rt2870_softc *sc, void *arg)
2862 struct ieee80211com *ic;
2863 struct ieee80211_node *ni;
2865 ic = &sc->ic;
2866 ni = ic->ic_bss;
2868 rt2870_asic_enable_tsf_sync(sc);
2872 * rt2870_set_channel_cb
2874 static void rt2870_set_channel_cb(struct rt2870_softc *sc, void *arg)
2876 struct ieee80211com *ic;
2878 ic = &sc->ic;
2880 RT2870_DPRINTF(sc, RT2870_DEBUG_CHAN,
2881 "%s: set channel: channel=%u, HT%s%s\n",
2882 device_get_nameunit(sc->dev),
2883 ieee80211_chan2ieee(ic, ic->ic_curchan),
2884 !IEEE80211_IS_CHAN_HT(ic->ic_curchan) ? " disabled" :
2885 IEEE80211_IS_CHAN_HT20(ic->ic_curchan) ? "20":
2886 IEEE80211_IS_CHAN_HT40U(ic->ic_curchan) ? "40U" : "40D",
2887 (ic->ic_flags & IEEE80211_F_SCAN) ? ", scanning" : "");
2889 rt2870_rf_set_chan(sc, ic->ic_curchan);
2893 * rt2870_newassoc_cb
2895 static void rt2870_newassoc_cb(struct rt2870_softc *sc, void *arg)
2897 struct ieee80211com *ic;
2898 struct ieee80211_node *ni;
2899 struct rt2870_softc_node *rni;
2900 struct rt2870_cmd_argv_newassoc *cmd_argv;
2901 int isnew;
2902 uint8_t *macaddr, wcid;
2903 uint16_t aid;
2904 uint32_t tmp;
2906 ic = &sc->ic;
2907 cmd_argv = arg;
2908 isnew = cmd_argv->isnew;
2909 macaddr = cmd_argv->macaddr;
2910 ni = ieee80211_find_node(&ic->ic_sta, macaddr);
2911 rni = (struct rt2870_softc_node *) ni;
2913 if (ni == NULL)
2914 return;
2916 if (isnew)
2918 aid = IEEE80211_AID(ni->ni_associd);
2919 rni->staid = rt2870_staid_alloc(sc, aid);
2920 wcid = rni->staid;
2922 tmp = (ni->ni_macaddr[3] << 24) |
2923 (ni->ni_macaddr[2] << 16) |
2924 (ni->ni_macaddr[1] << 8) |
2925 ni->ni_macaddr[0];
2927 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid), tmp);
2929 tmp = (ni->ni_macaddr[5] << 8) |
2930 ni->ni_macaddr[4];
2932 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
2934 rt2870_amrr_node_init(&sc->amrr, &sc->amrr_node[wcid], ni);
2936 RT2870_DPRINTF(sc, RT2870_DEBUG_RATE,
2937 "%s: initial%s node Tx rate: associd=0x%04x, rate=0x%02x, max rate=0x%02x\n",
2938 device_get_nameunit(sc->dev),
2939 (ni->ni_flags & IEEE80211_NODE_HT) ? " HT" : "",
2940 ni->ni_associd, ni->ni_txrate,
2941 (ni->ni_flags & IEEE80211_NODE_HT) ?
2942 (ni->ni_htrates.rs_rates[ni->ni_htrates.rs_nrates - 1] | IEEE80211_RATE_MCS) :
2943 (ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates - 1] & IEEE80211_RATE_VAL));
2945 rt2870_asic_updateprot(sc);
2946 rt2870_asic_updateslot(sc);
2947 rt2870_asic_set_txpreamble(sc);
2950 RT2870_DPRINTF(sc, RT2870_DEBUG_NODE,
2951 "%s: new association: isnew=%d, macaddr=%s, associd=0x%04x, staid=0x%02x, QoS %s, ERP %s, HT %s\n",
2952 device_get_nameunit(sc->dev), isnew, ether_sprintf(ni->ni_macaddr),
2953 ni->ni_associd, rni->staid,
2954 (ni->ni_flags & IEEE80211_NODE_QOS) ? "enabled" : "disabled",
2955 (ni->ni_flags & IEEE80211_NODE_ERP) ? "enabled" : "disabled",
2956 (ni->ni_flags & IEEE80211_NODE_HT) ? "enabled" : "disabled");
2958 ieee80211_free_node(ni);
2962 * rt2870_updateslot_cb
2964 static void rt2870_updateslot_cb(struct rt2870_softc *sc, void *arg)
2966 rt2870_asic_updateslot(sc);
2970 * rt2870_wme_update_cb
2972 static void rt2870_wme_update_cb(struct rt2870_softc *sc, void *arg)
2974 rt2870_asic_wme_update(sc);
2978 * rt2870_update_beacon_cb
2980 static void rt2870_update_beacon_cb(struct rt2870_softc *sc, void *arg)
2982 struct ieee80211com *ic;
2983 struct mbuf *m;
2984 struct ieee80211_beacon_offsets *bo;
2985 struct rt2870_cmd_argv_updatebeacon *cmd_argv;
2987 ic = &sc->ic;
2988 m = sc->beacon_mbuf;
2989 bo = &sc->beacon_offsets;
2990 cmd_argv = arg;
2992 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
2993 "%s: update beacon: what=%d\n",
2994 device_get_nameunit(sc->dev), cmd_argv->what);
2996 setbit(bo->bo_flags, cmd_argv->what);
2998 ieee80211_beacon_update(ic->ic_bss, bo, m, 0);
3000 rt2870_asic_update_beacon(sc);
3004 * rt2870_key_update_begin_cb
3006 static void rt2870_key_update_begin_cb(struct rt2870_softc *sc, void *arg)
3008 struct ifnet *ifp;
3010 ifp = sc->ifp;
3012 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
3013 "%s: key update begin\n",
3014 device_get_nameunit(sc->dev));
3016 taskqueue_block(sc->taskqueue);
3018 IF_LOCK(&ifp->if_snd);
3022 * rt2870_key_update_end_cb
3024 static void rt2870_key_update_end_cb(struct rt2870_softc *sc, void *arg)
3026 struct ifnet *ifp;
3028 ifp = sc->ifp;
3030 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
3031 "%s: key update end\n",
3032 device_get_nameunit(sc->dev));
3034 IF_UNLOCK(&ifp->if_snd);
3036 taskqueue_unblock(sc->taskqueue);
3040 * rt2870_key_set_cb
3042 static void rt2870_key_set_cb(struct rt2870_softc *sc, void *arg)
3044 struct ieee80211com *ic;
3045 struct ieee80211_key *k;
3046 enum ieee80211_opmode opmode;
3047 struct rt2870_cmd_argv_keyset *cmd_argv;
3048 uint16_t key_base, keymode_base;
3049 uint8_t mode, vapid, wcid, iv[8];
3050 uint32_t tmp;
3052 ic = &sc->ic;
3053 cmd_argv = arg;
3054 k = &cmd_argv->key;
3055 opmode = cmd_argv->opmode;
3057 switch (k->wk_cipher->ic_cipher)
3059 case IEEE80211_CIPHER_WEP:
3060 if(k->wk_keylen < 8)
3061 mode = RT2870_REG_CIPHER_MODE_WEP40;
3062 else
3063 mode = RT2870_REG_CIPHER_MODE_WEP104;
3064 break;
3066 case IEEE80211_CIPHER_TKIP:
3067 mode = RT2870_REG_CIPHER_MODE_TKIP;
3068 break;
3070 case IEEE80211_CIPHER_AES_CCM:
3071 mode = RT2870_REG_CIPHER_MODE_AES_CCMP;
3072 break;
3074 default:
3075 return;
3078 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
3079 "%s: key set: keyix=%d, keylen=%d, mode=%d, group=%d\n",
3080 device_get_nameunit(sc->dev), k->wk_keyix, k->wk_keylen,
3081 mode, (k->wk_flags & IEEE80211_KEY_GROUP) ? 1 : 0);
3083 if (!(k->wk_flags & IEEE80211_KEY_GROUP))
3085 /* install pairwise key */
3087 vapid = 0;
3088 wcid = cmd_argv->staid;
3089 key_base = RT2870_REG_PKEY(wcid);
3091 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP)
3093 memset(iv, 0, 8);
3095 iv[3] = (k->wk_keyix << 6);
3097 else
3099 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
3101 iv[0] = (k->wk_keytsc >> 8);
3102 iv[1] = ((iv[0] | 0x20) & 0x7f);
3103 iv[2] = k->wk_keytsc;
3105 else
3107 /* AES CCMP */
3109 iv[0] = k->wk_keytsc;
3110 iv[1] = k->wk_keytsc >> 8;
3111 iv[2] = 0;
3114 iv[3] = ((k->wk_keyix << 6) | IEEE80211_WEP_EXTIV);
3115 iv[4] = (k->wk_keytsc >> 16);
3116 iv[5] = (k->wk_keytsc >> 24);
3117 iv[6] = (k->wk_keytsc >> 32);
3118 iv[7] = (k->wk_keytsc >> 40);
3120 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
3121 "%s: VAP key set: iv=%02x %02x %02x %02x %02x %02x %02x %02x\n",
3122 device_get_nameunit(sc->dev),
3123 iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]);
3126 rt2870_io_mac_write_multi(sc, RT2870_REG_IVEIV(wcid), iv, 8);
3128 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
3130 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, 16);
3132 if (opmode != IEEE80211_M_HOSTAP)
3134 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[16], 8);
3135 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[24], 8);
3137 else
3139 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[24], 8);
3140 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[16], 8);
3143 else
3145 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, k->wk_keylen);
3148 tmp = ((vapid & RT2870_REG_VAP_MASK) << RT2870_REG_VAP_SHIFT) |
3149 (mode << RT2870_REG_CIPHER_MODE_SHIFT) | RT2870_REG_PKEY_ENABLE;
3151 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
3154 if ((k->wk_flags & IEEE80211_KEY_GROUP) ||
3155 (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP))
3157 /* install group key */
3159 vapid = 0;
3160 wcid = RT2870_WCID_MCAST;
3161 key_base = RT2870_REG_SKEY(vapid, k->wk_keyix);
3162 keymode_base = RT2870_REG_SKEY_MODE(vapid);
3164 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
3166 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, 16);
3168 if (opmode != IEEE80211_M_HOSTAP)
3170 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[16], 8);
3171 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[24], 8);
3173 else
3175 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[24], 8);
3176 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[16], 8);
3179 else
3181 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, k->wk_keylen);
3184 tmp = rt2870_io_mac_read(sc, keymode_base);
3186 tmp &= ~(0xf << (k->wk_keyix * 4 + 16 * (vapid % 2)));
3187 tmp |= (mode << (k->wk_keyix * 4 + 16 * (vapid % 2)));
3189 rt2870_io_mac_write(sc, keymode_base, tmp);
3191 if (opmode == IEEE80211_M_HOSTAP)
3193 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP)
3195 memset(iv, 0, 8);
3197 iv[3] = (k->wk_keyix << 6);
3199 else
3201 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
3203 iv[0] = (k->wk_keytsc >> 8);
3204 iv[1] = ((iv[0] | 0x20) & 0x7f);
3205 iv[2] = k->wk_keytsc;
3207 else
3209 /* AES CCMP */
3211 iv[0] = k->wk_keytsc;
3212 iv[1] = k->wk_keytsc >> 8;
3213 iv[2] = 0;
3216 iv[3] = ((k->wk_keyix << 6) | IEEE80211_WEP_EXTIV);
3217 iv[4] = (k->wk_keytsc >> 16);
3218 iv[5] = (k->wk_keytsc >> 24);
3219 iv[6] = (k->wk_keytsc >> 32);
3220 iv[7] = (k->wk_keytsc >> 40);
3222 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
3223 "%s: VAP key set: iv=%02x %02x %02x %02x %02x %02x %02x %02x\n",
3224 device_get_nameunit(sc->dev),
3225 iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]);
3228 rt2870_io_mac_write_multi(sc, RT2870_REG_IVEIV(wcid), iv, 8);
3230 tmp = ((vapid & RT2870_REG_VAP_MASK) << RT2870_REG_VAP_SHIFT) |
3231 (mode << RT2870_REG_CIPHER_MODE_SHIFT);
3233 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
3239 * rt2870_key_delete_cb
3241 static void rt2870_key_delete_cb(struct rt2870_softc *sc, void *arg)
3243 struct ieee80211com *ic;
3244 struct ieee80211_key *k;
3245 enum ieee80211_opmode opmode;
3246 struct rt2870_cmd_argv_keydelete *cmd_argv;
3247 uint8_t vapid, wcid;
3248 uint32_t tmp;
3250 ic = &sc->ic;
3251 cmd_argv = arg;
3252 k = &cmd_argv->key;
3253 opmode = cmd_argv->opmode;
3255 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
3256 "%s: key delete: keyix=%d, keylen=%d, group=%d\n",
3257 device_get_nameunit(sc->dev), k->wk_keyix, k->wk_keylen,
3258 (k->wk_flags & IEEE80211_KEY_GROUP) ? 1 : 0);
3260 if (k->wk_flags & IEEE80211_KEY_GROUP)
3262 /* remove group key */
3264 vapid = 0;
3265 wcid = RT2870_WCID_MCAST;
3267 tmp = rt2870_io_mac_read(sc, RT2870_REG_SKEY_MODE(vapid));
3269 tmp &= ~(0xf << (k->wk_keyix * 4 + 16 * (vapid % 2)));
3270 tmp |= (RT2870_REG_CIPHER_MODE_NONE << (k->wk_keyix * 4 + 16 * (vapid % 2)));
3272 rt2870_io_mac_write(sc, RT2870_REG_SKEY_MODE(vapid), tmp);
3274 if (opmode == IEEE80211_M_HOSTAP)
3276 tmp = ((vapid & RT2870_REG_VAP_MASK) << RT2870_REG_VAP_SHIFT) |
3277 (RT2870_REG_CIPHER_MODE_NONE << RT2870_REG_CIPHER_MODE_SHIFT);
3279 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
3285 * rt2870_asic_set_bssid
3287 static void rt2870_asic_set_bssid(struct rt2870_softc *sc,
3288 const uint8_t *bssid)
3290 uint32_t tmp;
3292 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3293 "%s: set bssid: bssid=%s\n",
3294 device_get_nameunit(sc->dev), ether_sprintf(bssid));
3296 tmp = bssid[0] | (bssid[1]) << 8 | (bssid[2] << 16) | (bssid[3] << 24);
3298 rt2870_io_mac_write(sc, RT2870_REG_BSSID_DW0, tmp);
3300 tmp = bssid[4] | (bssid[5] << 8);
3302 rt2870_io_mac_write(sc, RT2870_REG_BSSID_DW1, tmp);
3306 * rt2870_asic_set_macaddr
3308 static void rt2870_asic_set_macaddr(struct rt2870_softc *sc,
3309 const uint8_t *addr)
3311 uint32_t tmp;
3313 tmp = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
3315 rt2870_io_mac_write(sc, RT2870_REG_ADDR_DW0, tmp);
3317 tmp = addr[4] | (addr[5] << 8) | (0xff << 16);
3319 rt2870_io_mac_write(sc, RT2870_REG_ADDR_DW1, tmp);
3323 * rt2870_asic_enable_tsf_sync
3325 static void rt2870_asic_enable_tsf_sync(struct rt2870_softc *sc)
3327 struct ieee80211com *ic;
3328 uint32_t tmp;
3330 ic = &sc->ic;
3332 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
3333 "%s: enabling TSF\n",
3334 device_get_nameunit(sc->dev));
3336 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
3338 tmp &= ~0x1fffff;
3339 tmp |= ic->ic_bss->ni_intval * 16;
3340 tmp |= (RT2870_REG_TSF_TIMER_ENABLE | RT2870_REG_TBTT_TIMER_ENABLE);
3342 if (ic->ic_opmode == IEEE80211_M_STA)
3344 tmp |= (RT2870_REG_TSF_SYNC_MODE_STA << RT2870_REG_TSF_SYNC_MODE_SHIFT);
3346 else if (ic->ic_opmode == IEEE80211_M_IBSS)
3348 tmp |= RT2870_REG_BCN_TX_ENABLE;
3349 tmp |= (RT2870_REG_TSF_SYNC_MODE_IBSS << RT2870_REG_TSF_SYNC_MODE_SHIFT);
3351 else if (ic->ic_opmode == IEEE80211_M_HOSTAP)
3353 tmp |= RT2870_REG_BCN_TX_ENABLE;
3354 tmp |= (RT2870_REG_TSF_SYNC_MODE_HOSTAP << RT2870_REG_TSF_SYNC_MODE_SHIFT);
3357 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
3361 * rt2870_asic_disable_tsf_sync
3363 static void rt2870_asic_disable_tsf_sync(struct rt2870_softc *sc)
3365 uint32_t tmp;
3367 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
3368 "%s: disabling TSF\n",
3369 device_get_nameunit(sc->dev));
3371 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
3373 tmp &= ~(RT2870_REG_BCN_TX_ENABLE |
3374 RT2870_REG_TSF_TIMER_ENABLE |
3375 RT2870_REG_TBTT_TIMER_ENABLE);
3377 tmp &= ~(RT2870_REG_TSF_SYNC_MODE_MASK << RT2870_REG_TSF_SYNC_MODE_SHIFT);
3378 tmp |= (RT2870_REG_TSF_SYNC_MODE_DISABLE << RT2870_REG_TSF_SYNC_MODE_SHIFT);
3380 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
3384 * rt2870_asic_enable_mrr
3386 static void rt2870_asic_enable_mrr(struct rt2870_softc *sc)
3388 #define CCK(mcs) (mcs)
3389 #define OFDM(mcs) ((1 << 3) | (mcs))
3390 #define HT(mcs) (mcs)
3392 rt2870_io_mac_write(sc, RT2870_REG_TX_LG_FBK_CFG0,
3393 (OFDM(6) << 28) | /* 54 -> 48 */
3394 (OFDM(5) << 24) | /* 48 -> 36 */
3395 (OFDM(4) << 20) | /* 36 -> 24 */
3396 (OFDM(3) << 16) | /* 24 -> 18 */
3397 (OFDM(2) << 12) | /* 18 -> 12 */
3398 (OFDM(1) << 8) | /* 12 -> 9 */
3399 (OFDM(0) << 4) | /* 9 -> 6 */
3400 OFDM(0)); /* 6 -> 6 */
3402 rt2870_io_mac_write(sc, RT2870_REG_TX_LG_FBK_CFG1,
3403 (CCK(2) << 12) | /* 11 -> 5.5 */
3404 (CCK(1) << 8) | /* 5.5 -> 2 */
3405 (CCK(0) << 4) | /* 2 -> 1 */
3406 CCK(0)); /* 1 -> 1 */
3408 rt2870_io_mac_write(sc, RT2870_REG_TX_HT_FBK_CFG0,
3409 (HT(6) << 28) |
3410 (HT(5) << 24) |
3411 (HT(4) << 20) |
3412 (HT(3) << 16) |
3413 (HT(2) << 12) |
3414 (HT(1) << 8) |
3415 (HT(0) << 4) |
3416 HT(0));
3418 rt2870_io_mac_write(sc, RT2870_REG_TX_HT_FBK_CFG1,
3419 (HT(14) << 28) |
3420 (HT(13) << 24) |
3421 (HT(12) << 20) |
3422 (HT(11) << 16) |
3423 (HT(10) << 12) |
3424 (HT(9) << 8) |
3425 (HT(8) << 4) |
3426 HT(7));
3428 #undef HT
3429 #undef OFDM
3430 #undef CCK
3434 * rt2870_asic_set_txpreamble
3436 static void rt2870_asic_set_txpreamble(struct rt2870_softc *sc)
3438 struct ieee80211com *ic;
3439 uint32_t tmp;
3441 ic = &sc->ic;
3443 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3444 "%s: %s short Tx preamble\n",
3445 device_get_nameunit(sc->dev),
3446 (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? "enabling" : "disabling");
3448 tmp = rt2870_io_mac_read(sc, RT2870_REG_AUTO_RSP_CFG);
3450 tmp &= ~RT2870_REG_CCK_SHORT_ENABLE;
3452 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
3453 tmp |= RT2870_REG_CCK_SHORT_ENABLE;
3455 rt2870_io_mac_write(sc, RT2870_REG_AUTO_RSP_CFG, tmp);
3459 * rt2870_asic_set_basicrates
3461 static void rt2870_asic_set_basicrates(struct rt2870_softc *sc)
3463 struct ieee80211com *ic;
3465 ic = &sc->ic;
3467 if (ic->ic_curmode == IEEE80211_MODE_11B)
3468 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0xf);
3469 else if (ic->ic_curmode == IEEE80211_MODE_11A)
3470 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0x150);
3471 else
3472 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0x15f);
3476 * rt2870_asic_update_rtsthreshold
3478 static void rt2870_asic_update_rtsthreshold(struct rt2870_softc *sc)
3480 struct ieee80211com *ic;
3481 uint32_t tmp;
3482 uint16_t threshold;
3484 ic = &sc->ic;
3486 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3487 "%s: updating RTS threshold: %d\n",
3488 device_get_nameunit(sc->dev), ic->ic_rtsthreshold);
3490 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_RTS_CFG);
3492 tmp &= ~(RT2870_REG_TX_RTS_THRESHOLD_MASK << RT2870_REG_TX_RTS_THRESHOLD_SHIFT);
3494 if (ic->ic_flags_ext & IEEE80211_FEXT_AMSDU_TX)
3495 threshold = 0x1000;
3496 else
3497 threshold = ic->ic_rtsthreshold;
3499 tmp |= ((threshold & RT2870_REG_TX_RTS_THRESHOLD_MASK) <<
3500 RT2870_REG_TX_RTS_THRESHOLD_SHIFT);
3502 rt2870_io_mac_write(sc, RT2870_REG_TX_RTS_CFG, tmp);
3506 * rt2870_asic_update_txpower
3508 static void rt2870_asic_update_txpower(struct rt2870_softc *sc)
3510 struct ieee80211com *ic;
3511 uint32_t *txpow_rate;
3512 int8_t delta;
3513 uint8_t val;
3514 uint32_t tmp;
3515 int i;
3517 ic = &sc->ic;
3519 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3520 "%s: updating Tx power: %d\n",
3521 device_get_nameunit(sc->dev), ic->ic_txpowlimit);
3523 if (!IEEE80211_IS_CHAN_HT40(ic->ic_curchan))
3525 txpow_rate = sc->txpow_rate_20mhz;
3527 else
3529 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
3530 txpow_rate = sc->txpow_rate_40mhz_2ghz;
3531 else
3532 txpow_rate = sc->txpow_rate_40mhz_5ghz;
3535 delta = 0;
3537 val = rt2870_io_bbp_read(sc, 1);
3538 val &= 0xfc;
3540 if (ic->ic_txpowlimit > 90)
3542 /* do nothing */
3544 else if (ic->ic_txpowlimit > 60)
3546 delta -= 1;
3548 else if (ic->ic_txpowlimit > 30)
3550 delta -= 3;
3552 else if (ic->ic_txpowlimit > 15)
3554 val |= 0x1;
3556 else if (ic->ic_txpowlimit > 9)
3558 val |= 0x1;
3559 delta -= 3;
3561 else
3563 val |= 0x2;
3566 rt2870_io_bbp_write(sc, 1, val);
3568 for (i = 0; i < RT2870_SOFTC_TXPOW_RATE_COUNT; i++)
3570 if (txpow_rate[i] == 0xffffffff)
3571 continue;
3573 tmp = rt2870_read_eeprom_txpow_rate_add_delta(txpow_rate[i], delta);
3575 rt2870_io_mac_write(sc, RT2870_REG_TX_PWR_CFG(i), tmp);
3580 * rt2870_asic_update_promisc
3582 static void rt2870_asic_update_promisc(struct rt2870_softc *sc)
3584 struct ifnet *ifp;
3585 uint32_t tmp;
3587 ifp = sc->ic.ic_ifp;
3589 printf("%s: %s promiscuous mode\n",
3590 device_get_nameunit(sc->dev),
3591 (ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving");
3593 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_FILTER_CFG);
3595 tmp &= ~RT2870_REG_RX_FILTER_DROP_UC_NOME;
3597 if (!(ifp->if_flags & IFF_PROMISC))
3598 tmp |= RT2870_REG_RX_FILTER_DROP_UC_NOME;
3600 rt2870_io_mac_write(sc, RT2870_REG_RX_FILTER_CFG, tmp);
3604 * rt2870_asic_updateprot
3606 static void rt2870_asic_updateprot(struct rt2870_softc *sc)
3608 struct ieee80211com *ic;
3609 uint32_t cck_prot, ofdm_prot, mm20_prot, mm40_prot, gf20_prot, gf40_prot;
3610 uint8_t htopmode;
3611 enum ieee80211_protmode htprotmode;
3613 ic = &sc->ic;
3615 if (!(sc->flags & RT2870_SOFTC_FLAGS_VALID))
3616 return;
3618 /* CCK frame protection */
3620 cck_prot = RT2870_REG_RTSTH_ENABLE | RT2870_REG_PROT_NAV_SHORT |
3621 RT2870_REG_TXOP_ALLOW_ALL | RT2870_REG_PROT_CTRL_NONE;
3623 /* set up protection frame phy mode and rate (MCS code) */
3625 if (ic->ic_curmode == IEEE80211_MODE_11A)
3626 cck_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3627 (0 << RT2870_REG_PROT_MCS_SHIFT);
3628 else
3629 cck_prot |= ((RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3630 (3 << RT2870_REG_PROT_MCS_SHIFT));
3632 rt2870_io_mac_write(sc, RT2870_REG_TX_CCK_PROT_CFG, cck_prot);
3634 /* OFDM frame protection */
3636 ofdm_prot = RT2870_REG_RTSTH_ENABLE | RT2870_REG_PROT_NAV_SHORT |
3637 RT2870_REG_TXOP_ALLOW_ALL;
3639 if (ic->ic_flags & IEEE80211_F_USEPROT)
3641 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3642 "%s: updating protection mode: b/g protection mode=%s\n",
3643 device_get_nameunit(sc->dev),
3644 (ic->ic_protmode == IEEE80211_PROT_RTSCTS) ? "RTS/CTS" :
3645 ((ic->ic_protmode == IEEE80211_PROT_CTSONLY) ? "CTS-to-self" : "none"));
3647 if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
3648 ofdm_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3649 else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
3650 ofdm_prot |= RT2870_REG_PROT_CTRL_CTS;
3651 else
3652 ofdm_prot |= RT2870_REG_PROT_CTRL_NONE;
3654 else
3656 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3657 "%s: updating protection mode: b/g protection mode=%s\n",
3658 device_get_nameunit(sc->dev), "none");
3660 ofdm_prot |= RT2870_REG_PROT_CTRL_NONE;
3663 rt2870_io_mac_write(sc, RT2870_REG_TX_OFDM_PROT_CFG, ofdm_prot);
3665 /* HT frame protection */
3667 if ((ic->ic_opmode == IEEE80211_M_STA) && (ic->ic_state == IEEE80211_S_RUN))
3668 htopmode = ic->ic_bss->ni_htopmode;
3669 else
3670 htopmode = ic->ic_curhtprotmode;
3672 htprotmode = ic->ic_htprotmode;
3674 /* force HT mixed mode and RTS/CTS protection if A-MPDU Tx aggregation is enabled */
3676 if (sc->tx_ampdu_sessions > 0)
3678 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3679 "%s: updating protection mode: forcing HT mixed mode and RTS/CTS protection\n",
3680 device_get_nameunit(sc->dev));
3682 htopmode = IEEE80211_HTINFO_OPMODE_MIXED;
3683 htprotmode = IEEE80211_PROT_RTSCTS;
3686 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3687 "%s: updating protection mode: HT operation mode=0x%02x, protection mode=%s\n",
3688 device_get_nameunit(sc->dev),
3689 htopmode & IEEE80211_HTINFO_OPMODE,
3690 (htprotmode == IEEE80211_PROT_RTSCTS) ? "RTS/CTS" :
3691 ((htprotmode == IEEE80211_PROT_CTSONLY) ? "CTS-to-self" : "none"));
3693 switch (htopmode & IEEE80211_HTINFO_OPMODE)
3695 /* IEEE80211_HTINFO_OPMODE_HT20PR */
3696 case IEEE80211_HTINFO_OPMODE_HT20PR:
3697 mm20_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3698 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3699 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20 |
3700 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3701 (4 << RT2870_REG_PROT_MCS_SHIFT);
3703 gf20_prot = mm20_prot;
3705 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3706 RT2870_REG_TXOP_ALLOW_ALL |
3707 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3708 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
3710 if (htprotmode == IEEE80211_PROT_RTSCTS)
3711 mm40_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3712 else if (htprotmode == IEEE80211_PROT_CTSONLY)
3713 mm40_prot |= RT2870_REG_PROT_CTRL_CTS;
3714 else
3715 mm40_prot |= RT2870_REG_PROT_CTRL_NONE;
3717 gf40_prot = mm40_prot;
3718 break;
3720 /* IEEE80211_HTINFO_OPMODE_MIXED */
3721 case IEEE80211_HTINFO_OPMODE_MIXED:
3722 mm20_prot = RT2870_REG_PROT_NAV_SHORT |
3723 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3724 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20;
3726 if (ic->ic_flags & IEEE80211_F_USEPROT)
3727 mm20_prot |= (RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3728 (3 << RT2870_REG_PROT_MCS_SHIFT);
3729 else
3730 mm20_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3731 (4 << RT2870_REG_PROT_MCS_SHIFT);
3733 if (htprotmode == IEEE80211_PROT_RTSCTS)
3734 mm20_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3735 else if (htprotmode == IEEE80211_PROT_CTSONLY)
3736 mm20_prot |= RT2870_REG_PROT_CTRL_CTS;
3737 else
3738 mm20_prot |= RT2870_REG_PROT_CTRL_NONE;
3740 gf20_prot = mm20_prot;
3742 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_TXOP_ALLOW_ALL;
3744 if (ic->ic_flags & IEEE80211_F_USEPROT)
3745 mm40_prot |= (RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3746 (3 << RT2870_REG_PROT_MCS_SHIFT);
3747 else
3748 mm40_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3749 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
3751 if (htprotmode == IEEE80211_PROT_RTSCTS)
3752 mm40_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3753 else if (htprotmode == IEEE80211_PROT_CTSONLY)
3754 mm40_prot |= RT2870_REG_PROT_CTRL_CTS;
3755 else
3756 mm40_prot |= RT2870_REG_PROT_CTRL_NONE;
3758 gf40_prot = mm40_prot;
3759 break;
3762 * IEEE80211_HTINFO_OPMODE_PURE
3763 * IEEE80211_HTINFO_OPMODE_PROTOPT
3765 case IEEE80211_HTINFO_OPMODE_PURE:
3766 case IEEE80211_HTINFO_OPMODE_PROTOPT:
3767 default:
3768 mm20_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3769 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3770 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20 |
3771 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3772 (4 << RT2870_REG_PROT_MCS_SHIFT);
3774 gf20_prot = mm20_prot;
3776 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3777 RT2870_REG_TXOP_ALLOW_ALL |
3778 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3779 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
3781 gf40_prot = mm40_prot;
3782 break;
3785 rt2870_io_mac_write(sc, RT2870_REG_TX_MM20_PROT_CFG, mm20_prot);
3786 rt2870_io_mac_write(sc, RT2870_REG_TX_MM40_PROT_CFG, mm40_prot);
3787 rt2870_io_mac_write(sc, RT2870_REG_TX_GF20_PROT_CFG, gf20_prot);
3788 rt2870_io_mac_write(sc, RT2870_REG_TX_GF40_PROT_CFG, gf40_prot);
3792 * rt2870_asic_updateslot
3794 static void rt2870_asic_updateslot(struct rt2870_softc *sc)
3796 struct ieee80211com *ic;
3797 uint32_t tmp;
3799 ic = &sc->ic;
3801 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3802 "%s: %s short slot time\n",
3803 device_get_nameunit(sc->dev),
3804 (ic->ic_flags & (IEEE80211_F_SHSLOT | IEEE80211_F_BURST)) ? "enabling" : "disabling");
3806 tmp = rt2870_io_mac_read(sc, RT2870_REG_BKOFF_SLOT_CFG);
3808 tmp &= ~0xff;
3809 tmp |= (ic->ic_flags & (IEEE80211_F_SHSLOT | IEEE80211_F_BURST)) ? 9 : 20;
3811 rt2870_io_mac_write(sc, RT2870_REG_BKOFF_SLOT_CFG, tmp);
3815 * rt2870_asic_wme_update
3817 static void rt2870_asic_wme_update(struct rt2870_softc *sc)
3819 struct ieee80211com *ic;
3820 struct ieee80211_wme_state *wme;
3821 const struct wmeParams *wmep;
3822 int i;
3824 ic = &sc->ic;
3825 wme = &ic->ic_wme;
3826 wmep = wme->wme_chanParams.cap_wmeParams;
3828 RT2870_DPRINTF(sc, RT2870_DEBUG_WME,
3829 "%s: wme update: WME_AC_VO=%d/%d/%d/%d, WME_AC_VI=%d/%d/%d/%d, "
3830 "WME_AC_BK=%d/%d/%d/%d, WME_AC_BE=%d/%d/%d/%d\n",
3831 device_get_nameunit(sc->dev),
3832 wmep[WME_AC_VO].wmep_aifsn,
3833 wmep[WME_AC_VO].wmep_logcwmin, wmep[WME_AC_VO].wmep_logcwmax,
3834 wmep[WME_AC_VO].wmep_txopLimit,
3835 wmep[WME_AC_VI].wmep_aifsn,
3836 wmep[WME_AC_VI].wmep_logcwmin, wmep[WME_AC_VI].wmep_logcwmax,
3837 wmep[WME_AC_VI].wmep_txopLimit,
3838 wmep[WME_AC_BK].wmep_aifsn,
3839 wmep[WME_AC_BK].wmep_logcwmin, wmep[WME_AC_BK].wmep_logcwmax,
3840 wmep[WME_AC_BK].wmep_txopLimit,
3841 wmep[WME_AC_BE].wmep_aifsn,
3842 wmep[WME_AC_BE].wmep_logcwmin, wmep[WME_AC_BE].wmep_logcwmax,
3843 wmep[WME_AC_BE].wmep_txopLimit);
3845 for (i = 0; i < WME_NUM_AC; i++)
3846 rt2870_io_mac_write(sc, RT2870_REG_TX_EDCA_AC_CFG(i),
3847 (wmep[i].wmep_logcwmax << 16) | (wmep[i].wmep_logcwmin << 12) |
3848 (wmep[i].wmep_aifsn << 8) | wmep[i].wmep_txopLimit);
3850 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_AIFSN_CFG,
3851 (wmep[WME_AC_VO].wmep_aifsn << 12) | (wmep[WME_AC_VI].wmep_aifsn << 8) |
3852 (wmep[WME_AC_BK].wmep_aifsn << 4) | wmep[WME_AC_BE].wmep_aifsn);
3854 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_CWMIN_CFG,
3855 (wmep[WME_AC_VO].wmep_logcwmin << 12) | (wmep[WME_AC_VI].wmep_logcwmin << 8) |
3856 (wmep[WME_AC_BK].wmep_logcwmin << 4) | wmep[WME_AC_BE].wmep_logcwmin);
3858 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_CWMAX_CFG,
3859 (wmep[WME_AC_VO].wmep_logcwmax << 12) | (wmep[WME_AC_VI].wmep_logcwmax << 8) |
3860 (wmep[WME_AC_BK].wmep_logcwmax << 4) | wmep[WME_AC_BE].wmep_logcwmax);
3862 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP0_CFG,
3863 (wmep[WME_AC_BK].wmep_txopLimit << 16) | wmep[WME_AC_BE].wmep_txopLimit);
3865 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP1_CFG,
3866 (wmep[WME_AC_VO].wmep_txopLimit << 16) | wmep[WME_AC_VI].wmep_txopLimit);
3870 * rt2870_asic_update_beacon
3872 static void rt2870_asic_update_beacon(struct rt2870_softc *sc)
3874 struct ieee80211com *ic;
3875 struct mbuf *m;
3876 struct rt2870_txwi *txwi;
3877 uint32_t tmp;
3879 ic = &sc->ic;
3881 m = sc->beacon_mbuf;
3882 txwi = &sc->beacon_txwi;
3884 /* disable temporarily TSF sync */
3886 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
3888 tmp &= ~(RT2870_REG_BCN_TX_ENABLE |
3889 RT2870_REG_TSF_TIMER_ENABLE |
3890 RT2870_REG_TBTT_TIMER_ENABLE);
3892 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
3894 /* write Tx wireless info and beacon frame to on-chip memory */
3896 rt2870_io_mac_write_multi(sc, RT2870_REG_BEACON_BASE(0),
3897 txwi, sizeof(struct rt2870_txwi));
3899 rt2870_io_mac_write_multi(sc, RT2870_REG_BEACON_BASE(0) + sizeof(struct rt2870_txwi),
3900 mtod(m, uint8_t *), m->m_pkthdr.len);
3902 /* enable again TSF sync */
3904 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
3906 tmp |= (RT2870_REG_BCN_TX_ENABLE |
3907 RT2870_REG_TSF_TIMER_ENABLE |
3908 RT2870_REG_TBTT_TIMER_ENABLE);
3910 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
3914 * rt2870_asic_clear_keytables
3916 static void rt2870_asic_clear_keytables(struct rt2870_softc *sc)
3918 int i;
3920 /* clear Rx WCID search table (entries = 256, entry size = 8) */
3922 for (i = 0; i < 256; i++)
3924 rt2870_io_mac_write(sc, RT2870_REG_WCID(i), 0xffffffff);
3925 rt2870_io_mac_write(sc, RT2870_REG_WCID(i) + 4, 0x0000ffff);
3928 /* clear WCID attribute table (entries = 256, entry size = 4) */
3930 rt2870_io_mac_set_region_4(sc, RT2870_REG_WCID_ATTR(0), 0, 256);
3932 /* clear IV/EIV table (entries = 256, entry size = 8) */
3934 rt2870_io_mac_set_region_4(sc, RT2870_REG_IVEIV(0), 0, 2 * 256);
3936 /* clear pairwise key table (entries = 64, entry size = 32) */
3938 rt2870_io_mac_set_region_4(sc, RT2870_REG_PKEY(0), 0, 8 * 64);
3940 /* clear shared key table (entries = 32, entry size = 32) */
3942 rt2870_io_mac_set_region_4(sc, RT2870_REG_SKEY(0, 0), 0, 8 * 32);
3944 /* clear shared key mode (entries = 32, entry size = 2) */
3946 rt2870_io_mac_set_region_4(sc, RT2870_REG_SKEY_MODE(0), 0, 16);
3950 * rt2870_asic_add_ba_session
3952 static void rt2870_asic_add_ba_session(struct rt2870_softc *sc,
3953 uint8_t wcid, int tid)
3955 uint32_t tmp;
3957 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID(wcid) + 4);
3959 tmp |= (0x10000 << tid);
3961 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
3965 * rt2860_asic_del_ba_session
3967 static void rt2870_asic_del_ba_session(struct rt2870_softc *sc,
3968 uint8_t wcid, int tid)
3970 uint32_t tmp;
3972 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID(wcid) + 4);
3974 tmp &= ~(0x10000 << tid);
3976 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
3980 * rt2870_beacon_alloc
3982 static int rt2870_beacon_alloc(struct rt2870_softc *sc)
3984 struct ieee80211com *ic;
3985 struct mbuf *m;
3986 struct rt2870_txwi txwi;
3987 uint8_t rate, mcs;
3989 ic = &sc->ic;
3991 m = ieee80211_beacon_alloc(ic->ic_bss, &sc->beacon_offsets);
3992 if (m == NULL)
3993 return ENOMEM;
3995 rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
3996 mcs = rt2870_rate2mcs(rate);
3998 memset(&txwi, 0, sizeof(struct rt2870_txwi));
4000 txwi.wcid = 0xff;
4001 txwi.pid_mpdu_len = ((htole16(m->m_pkthdr.len) & RT2870_TXWI_MPDU_LEN_MASK) <<
4002 RT2870_TXWI_MPDU_LEN_SHIFT);
4003 txwi.txop = (RT2870_TXWI_TXOP_HT << RT2870_TXWI_TXOP_SHIFT);
4004 txwi.mpdu_density_flags |=
4005 (RT2870_TXWI_FLAGS_TS << RT2870_TXWI_FLAGS_SHIFT);
4006 txwi.bawin_size_xflags |=
4007 (RT2870_TXWI_XFLAGS_NSEQ << RT2870_TXWI_XFLAGS_SHIFT);
4009 if (rate == 2)
4011 txwi.phymode_ifs_stbc_shortgi =
4012 (RT2870_TXWI_PHYMODE_CCK << RT2870_TXWI_PHYMODE_SHIFT);
4014 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
4015 mcs |= RT2870_TXWI_MCS_SHOTPRE;
4017 else
4019 txwi.phymode_ifs_stbc_shortgi =
4020 (RT2870_TXWI_PHYMODE_OFDM << RT2870_TXWI_PHYMODE_SHIFT);
4023 txwi.bw_mcs = (RT2870_TXWI_BW_20 << RT2870_TXWI_BW_SHIFT) |
4024 ((mcs & RT2870_TXWI_MCS_MASK) << RT2870_TXWI_MCS_SHIFT);
4026 if (sc->beacon_mbuf != NULL)
4028 m_free(sc->beacon_mbuf);
4029 sc->beacon_mbuf = NULL;
4032 sc->beacon_mbuf = m;
4033 sc->beacon_txwi = txwi;
4035 return 0;
4039 * rt2870_rxrate
4041 static uint8_t rt2870_rxrate(struct rt2870_rxwi *rxwi)
4043 uint8_t mcs, phymode;
4044 uint8_t rate;
4046 mcs = (rxwi->bw_mcs >> RT2870_RXWI_MCS_SHIFT) & RT2870_RXWI_MCS_MASK;
4047 phymode = (rxwi->phymode_stbc_shortgi >> RT2870_RXWI_PHYMODE_SHIFT) &
4048 RT2870_RXWI_PHYMODE_MASK;
4050 rate = 2;
4052 switch (phymode)
4054 case RT2870_RXWI_PHYMODE_CCK:
4055 switch (mcs & ~RT2870_RXWI_MCS_SHOTPRE)
4057 case 0: rate = 2; break; /* 1 Mbps */
4058 case 1: rate = 4; break; /* 2 MBps */
4059 case 2: rate = 11; break; /* 5.5 Mbps */
4060 case 3: rate = 22; break; /* 11 Mbps */
4062 break;
4064 case RT2870_RXWI_PHYMODE_OFDM:
4065 switch (mcs)
4067 case 0: rate = 12; break; /* 6 Mbps */
4068 case 1: rate = 18; break; /* 9 Mbps */
4069 case 2: rate = 24; break; /* 12 Mbps */
4070 case 3: rate = 36; break; /* 18 Mbps */
4071 case 4: rate = 48; break; /* 24 Mbps */
4072 case 5: rate = 72; break; /* 36 Mbps */
4073 case 6: rate = 96; break; /* 48 Mbps */
4074 case 7: rate = 108; break; /* 54 Mbps */
4076 break;
4078 case RT2870_RXWI_PHYMODE_HT_MIXED:
4079 case RT2870_RXWI_PHYMODE_HT_GF:
4080 break;
4083 return rate;
4087 * rt2870_maxrssi_rxpath
4089 static uint8_t rt2870_maxrssi_rxpath(struct rt2870_softc *sc,
4090 const struct rt2870_rxwi *rxwi)
4092 uint8_t rxpath;
4094 rxpath = 0;
4096 if (sc->nrxpath > 1)
4097 if (rxwi->rssi[1] > rxwi->rssi[rxpath])
4098 rxpath = 1;
4100 if (sc->nrxpath > 2)
4101 if (rxwi->rssi[2] > rxwi->rssi[rxpath])
4102 rxpath = 2;
4104 return rxpath;
4108 * rt2870_rssi2dbm
4110 static int8_t rt2870_rssi2dbm(struct rt2870_softc *sc,
4111 uint8_t rssi, uint8_t rxpath)
4113 struct ieee80211com *ic;
4114 struct ieee80211_channel *c;
4115 int chan;
4116 int8_t rssi_off, lna_gain;
4118 if (rssi == 0)
4119 return -99;
4121 ic = &sc->ic;
4122 c = ic->ic_curchan;
4123 chan = ieee80211_chan2ieee(ic, c);
4125 if (IEEE80211_IS_CHAN_5GHZ(c))
4127 rssi_off = sc->rssi_off_5ghz[rxpath];
4129 if (chan <= 64)
4130 lna_gain = sc->lna_gain[1];
4131 else if (chan <= 128)
4132 lna_gain = sc->lna_gain[2];
4133 else
4134 lna_gain = sc->lna_gain[3];
4136 else
4138 rssi_off = sc->rssi_off_2ghz[rxpath];
4139 lna_gain = sc->lna_gain[0];
4142 return (-12 - rssi_off - lna_gain - rssi);
4146 * rt2870_rate2mcs
4148 static uint8_t rt2870_rate2mcs(uint8_t rate)
4150 switch (rate)
4152 /* CCK rates */
4153 case 2: return 0;
4154 case 4: return 1;
4155 case 11: return 2;
4156 case 22: return 3;
4158 /* OFDM rates */
4159 case 12: return 0;
4160 case 18: return 1;
4161 case 24: return 2;
4162 case 36: return 3;
4163 case 48: return 4;
4164 case 72: return 5;
4165 case 96: return 6;
4166 case 108: return 7;
4169 return 0;
4173 * rt2870_ackrate
4175 static int rt2870_ackrate(struct ieee80211com *ic, int rate)
4177 switch (rate)
4179 /* CCK rates */
4181 case 2:
4182 return 2;
4184 case 4:
4185 case 11:
4186 case 22:
4187 return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate;
4189 /* OFDM rates */
4191 case 12:
4192 case 18:
4193 return 12;
4195 case 24:
4196 case 36:
4197 return 24;
4199 case 48:
4200 case 72:
4201 case 96:
4202 case 108:
4203 return 48;
4206 /* default to 1Mbps */
4207 return 2;
4211 * rt2870_txtime
4213 static uint16_t rt2870_txtime(int len, int rate, uint32_t flags)
4215 uint16_t txtime;
4217 if (RT2870_RATE_IS_OFDM(rate))
4219 txtime = (8 + 4 * len + 3 + rate - 1) / rate;
4220 txtime = 16 + 4 + 4 * txtime + 6;
4222 else
4224 txtime = (16 * len + rate - 1) / rate;
4226 if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE))
4227 txtime += 72 + 24;
4228 else
4229 txtime += 144 + 48;
4232 return txtime;
4236 * rt2870_rx_frame
4238 static void rt2870_rx_frame(struct rt2870_softc *sc,
4239 uint8_t *buf, uint32_t dmalen)
4241 struct ieee80211com *ic;
4242 struct ifnet *ifp;
4243 struct ieee80211_frame *wh;
4244 struct ieee80211_node *ni;
4245 struct rt2870_softc_node *rni;
4246 struct rt2870_softc_rx_radiotap_header *tap;
4247 struct rt2870_rxwi *rxwi;
4248 struct rt2870_rxinfo *rxinfo;
4249 struct mbuf *m;
4250 uint32_t rxinfo_flags;
4251 uint8_t cipher_err, rssi, ant, phymode, bw, shortgi, stbc, mcs, keyidx, tid, frag;
4252 uint16_t seq;
4253 int8_t rssi_dbm;
4254 int len, ampdu, amsdu, rssi_dbm_rel, i;
4256 ic = &sc->ic;
4257 ifp = ic->ic_ifp;
4259 /* get Rx wireless info */
4261 rxwi = (struct rt2870_rxwi *) buf;
4262 len = (le16toh(rxwi->tid_size) >> RT2870_RXWI_SIZE_SHIFT) &
4263 RT2870_RXWI_SIZE_MASK;
4265 if (len > dmalen)
4267 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4268 "%s: bad rxwi len: DMA len=%d, rxwi len=%d\n",
4269 device_get_nameunit(sc->dev), dmalen, len);
4270 return;
4273 /* get Rx info */
4275 rxinfo = (struct rt2870_rxinfo *) ((caddr_t) rxwi + dmalen);
4276 rxinfo_flags = le32toh(rxinfo->flags);
4278 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4279 "%s: Rx frame: DMA len=%d, len=%d, rxinfo flags=0x%08x\n",
4280 device_get_nameunit(sc->dev), dmalen, len, rxinfo_flags);
4282 /* check for crc errors */
4284 if (rxinfo_flags & RT2870_RXINFO_FLAGS_CRC_ERR)
4286 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4287 "%s: rxinfo: crc error\n",
4288 device_get_nameunit(sc->dev));
4290 ifp->if_ierrors++;
4292 if (!(ifp->if_flags & IFF_PROMISC))
4293 return;
4296 wh = (struct ieee80211_frame *) (rxwi + 1);
4298 /* check for L2 padding between IEEE 802.11 frame header and body */
4300 if (rxinfo_flags & RT2870_RXINFO_FLAGS_L2PAD)
4302 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4303 "%s: L2 padding: DMA len=%d, len=%d\n",
4304 device_get_nameunit(sc->dev), dmalen, len);
4306 len += 2;
4309 m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
4310 if (m == NULL)
4312 sc->rx_mbuf_alloc_errors++;
4313 ifp->if_ierrors++;
4314 return;
4317 m->m_pkthdr.rcvif = ifp;
4318 m->m_pkthdr.len = m->m_len = len;
4320 m_copyback(m, 0, len, (caddr_t) wh);
4322 wh = mtod(m, struct ieee80211_frame *);
4324 /* check for cipher errors */
4326 if (rxinfo_flags & RT2870_RXINFO_FLAGS_DECRYPTED)
4328 cipher_err = ((rxinfo_flags >> RT2870_RXINFO_FLAGS_CIPHER_ERR_SHIFT) &
4329 RT2870_RXINFO_FLAGS_CIPHER_ERR_MASK);
4330 if (cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_NONE)
4332 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4333 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
4335 m->m_flags |= M_WEP;
4337 sc->rx_cipher_no_errors++;
4339 else
4341 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4342 "%s: rxinfo: cipher error=0x%02x\n",
4343 device_get_nameunit(sc->dev), cipher_err);
4345 if (cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_ICV)
4346 sc->rx_cipher_icv_errors++;
4347 else if (cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_MIC)
4348 sc->rx_cipher_mic_errors++;
4349 else if (cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_INVALID_KEY)
4350 sc->rx_cipher_invalid_key_errors++;
4352 if ((cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_MIC) &&
4353 (rxinfo_flags & RT2870_RXINFO_FLAGS_MYBSS))
4355 keyidx = (rxwi->udf_bssidx_keyidx >> RT2870_RXWI_KEYIDX_SHIFT) &
4356 RT2870_RXWI_KEYIDX_MASK;
4358 ieee80211_notify_michael_failure(ic, wh, keyidx);
4361 ifp->if_ierrors++;
4363 if (!(ifp->if_flags & IFF_PROMISC))
4365 m_free(m);
4366 return;
4370 else
4372 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4374 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4375 "%s: rxinfo: not decrypted but protected flag set\n",
4376 device_get_nameunit(sc->dev));
4378 ifp->if_ierrors++;
4380 if (!(ifp->if_flags & IFF_PROMISC))
4382 m_free(m);
4383 return;
4388 /* check for A-MPDU */
4390 if (rxinfo_flags & RT2870_RXINFO_FLAGS_BA)
4392 m->m_flags |= M_AMPDU;
4394 sc->rx_ampdu++;
4396 if (wh->i_fc[1] & IEEE80211_FC1_RETRY)
4397 sc->rx_ampdu_retries++;
4399 ampdu = 1;
4401 else
4403 ampdu = 0;
4406 /* check for A-MSDU */
4408 if (rxinfo_flags & RT2870_RXINFO_FLAGS_AMSDU)
4410 sc->rx_amsdu++;
4412 amsdu = 1;
4414 else
4416 amsdu = 0;
4419 ant = rt2870_maxrssi_rxpath(sc, rxwi);
4420 rssi = rxwi->rssi[ant];
4421 rssi_dbm = rt2870_rssi2dbm(sc, rssi, ant);
4422 phymode = ((rxwi->phymode_stbc_shortgi >> RT2870_RXWI_PHYMODE_SHIFT) &
4423 RT2870_RXWI_PHYMODE_MASK);
4424 bw = ((rxwi->bw_mcs >> RT2870_RXWI_BW_SHIFT) & RT2870_RXWI_BW_MASK);
4425 shortgi = ((rxwi->phymode_stbc_shortgi >> RT2870_RXWI_SHORTGI_SHIFT) &
4426 RT2870_RXWI_SHORTGI_MASK);
4427 stbc = ((rxwi->phymode_stbc_shortgi >> RT2870_RXWI_STBC_SHIFT) &
4428 RT2870_RXWI_STBC_MASK);
4429 mcs = ((rxwi->bw_mcs >> RT2870_RXWI_MCS_SHIFT) & RT2870_RXWI_MCS_MASK);
4430 tid = ((rxwi->tid_size >> RT2870_RXWI_TID_SHIFT) & RT2870_RXWI_TID_MASK);
4431 seq = ((rxwi->seq_frag >> RT2870_RXWI_SEQ_SHIFT) & RT2870_RXWI_SEQ_MASK);
4432 frag = ((rxwi->seq_frag >> RT2870_RXWI_FRAG_SHIFT) & RT2870_RXWI_FRAG_MASK);
4434 if (bpf_peers_present(sc->drvbpf))
4436 tap = &sc->rxtap;
4438 tap->flags = IEEE80211_RADIOTAP_F_DATAPAD;
4439 tap->dbm_antsignal = rssi_dbm;
4440 tap->dbm_antnoise = RT2870_NOISE_FLOOR;
4441 tap->antenna = ant;
4442 tap->antsignal = rssi;
4443 tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
4444 tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
4445 tap->chan_ieee = ic->ic_curchan->ic_ieee;
4446 tap->chan_maxpow = 0;
4448 if (phymode == RT2870_RXWI_PHYMODE_CCK || phymode == RT2870_RXWI_PHYMODE_OFDM)
4449 tap->rate = rt2870_rxrate(rxwi);
4450 else
4451 tap->rate = mcs | IEEE80211_RATE_MCS;
4453 if (rxinfo_flags & RT2870_RXINFO_FLAGS_CRC_ERR)
4454 tap->flags |= IEEE80211_RADIOTAP_F_BADFCS;
4456 if (rxinfo_flags & RT2870_RXINFO_FLAGS_FRAG)
4457 tap->flags |= IEEE80211_RADIOTAP_F_FRAG;
4459 if (rxwi->bw_mcs & RT2870_RXWI_MCS_SHOTPRE)
4460 tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
4462 if (shortgi)
4463 tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
4465 /* XXX use temporarily radiotap CFP flag as A-MPDU flag */
4467 if (ampdu)
4468 tap->flags |= IEEE80211_RADIOTAP_F_CFP;
4470 bpf_mtap2(sc->drvbpf, tap, sc->rxtap_len, m);
4474 * net80211 assumes that RSSI data are in the range [-127..127] and
4475 * in .5 dBm units relative to the current noise floor
4478 rssi_dbm_rel = (rssi_dbm - RT2870_NOISE_FLOOR) * 2;
4479 if (rssi_dbm_rel > 127)
4480 rssi_dbm_rel = 127;
4482 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4483 "%s: received frame: len=%d, phymode=%d, bw=%d, shortgi=%d, stbc=0x%02x, mcs=%d, "
4484 "ant=%d, rssi=%d/%d/%d, snr=%d/%d, wcid=0x%02x, ampdu=%d, amsdu=%d, "
4485 "tid=%d, seq=%d, frag=%d, retry=%d, rssi_dbm=%d, rssi_dbm_rel=%d\n",
4486 device_get_nameunit(sc->dev),
4487 len, phymode, bw, shortgi, stbc, mcs,
4488 ant, rxwi->rssi[0], rxwi->rssi[1], rxwi->rssi[2],
4489 rxwi->snr[0], rxwi->snr[1],
4490 rxwi->wcid, ampdu, amsdu, tid, seq, frag, (wh->i_fc[1] & IEEE80211_FC1_RETRY) ? 1 : 0,
4491 rssi_dbm, rssi_dbm_rel);
4493 ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *) wh);
4495 if (ni != NULL)
4497 rni = (struct rt2870_softc_node *) ni;
4499 for (i = 0; i < RT2870_SOFTC_RSSI_DBM_COUNT; i++)
4500 rni->last_rssi_dbm[i] = rt2870_rssi2dbm(sc, rxwi->rssi[i], i);
4503 ieee80211_input(ic, m, ni, rssi_dbm, RT2870_NOISE_FLOOR, 0);
4505 ieee80211_free_node(ni);
4509 * rt2870_tx_frame
4511 static int rt2870_tx_frame(struct rt2870_softc *sc,
4512 struct mbuf *m, struct ieee80211_node *ni, int qid)
4514 struct ieee80211com *ic;
4515 struct rt2870_softc_node *rni;
4516 struct rt2870_softc_tx_ring *ring;
4517 struct rt2870_softc_tx_data *data;
4518 struct rt2870_txinfo *txinfo;
4519 struct rt2870_txwi *txwi;
4520 struct ieee80211_frame *wh;
4521 struct ieee80211_tx_ampdu *tx_ampdu;
4522 struct rt2870_softc_tx_radiotap_header *tap;
4523 u_int hdrsize, hdrspace;
4524 uint8_t type, rate, bw, stbc, shortgi, mcs, pid, wcid, mpdu_density, bawin_size;
4525 uint16_t qos, len, dmalen, mpdu_len, dur;
4526 int hasqos, ac, ampdu, mimops, ackrate;
4528 ic = &sc->ic;
4529 rni = (struct rt2870_softc_node *) ni;
4531 ring = &sc->tx_ring[qid];
4532 data = STAILQ_FIRST(&ring->inactive);
4533 STAILQ_REMOVE_HEAD(&ring->inactive, next);
4534 txinfo = (struct rt2870_txinfo *) data->buf;
4535 txwi = (struct rt2870_txwi *) (txinfo + 1);
4537 wh = mtod(m, struct ieee80211_frame *);
4539 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
4541 hasqos = IEEE80211_QOS_HAS_SEQ(wh);
4542 if (hasqos)
4544 if (IEEE80211_HAS_ADDR4(wh))
4545 qos = le16toh(*(const uint16_t *)
4546 (((struct ieee80211_qosframe_addr4 *) wh)->i_qos));
4547 else
4548 qos = le16toh(*(const uint16_t *)
4549 (((struct ieee80211_qosframe *) wh)->i_qos));
4551 else
4553 qos = 0;
4556 if (ni->ni_flags & IEEE80211_NODE_HT)
4558 if (IEEE80211_IS_MULTICAST(wh->i_addr1) || type != IEEE80211_FC0_TYPE_DATA)
4559 rate = 0;
4560 else if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
4561 rate = ic->ic_fixed_rate;
4562 else
4563 rate = ni->ni_htrates.rs_rates[ni->ni_txrate];
4565 else
4567 if (IEEE80211_IS_MULTICAST(wh->i_addr1) || type != IEEE80211_FC0_TYPE_DATA)
4568 rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
4569 else if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
4570 rate = ic->ic_fixed_rate;
4571 else
4572 rate = ni->ni_rates.rs_rates[ni->ni_txrate];
4575 rate &= IEEE80211_RATE_VAL;
4577 len = sizeof(struct rt2870_txinfo) + sizeof(struct rt2870_txwi) + m->m_pkthdr.len;
4579 /* align end on a 4-bytes boundary */
4581 dmalen = (len + 3) & ~3;
4583 /* fill Tx info */
4585 memset(txinfo, 0, sizeof(struct rt2870_txinfo));
4587 txinfo->len = htole16(dmalen);
4589 txinfo->qsel_flags = (RT2870_TXINFO_QSEL_EDCA << RT2870_TXINFO_QSEL_SHIFT);
4591 /* fill Tx wireless info */
4593 if (ni->ni_flags & IEEE80211_NODE_HT)
4594 mcs = rate;
4595 else
4596 mcs = rt2870_rate2mcs(rate);
4598 if (type == IEEE80211_FC0_TYPE_DATA)
4599 wcid = !IEEE80211_IS_MULTICAST(wh->i_addr1) ? rni->staid : RT2870_WCID_MCAST;
4600 else
4601 wcid = RT2870_WCID_RESERVED;
4603 /* calculate MPDU length without padding */
4605 hdrsize = ieee80211_anyhdrsize(wh);
4606 hdrspace = ieee80211_anyhdrspace(ic, wh);
4607 mpdu_len = m->m_pkthdr.len - hdrspace + hdrsize;
4609 memset(txwi, 0, sizeof(struct rt2870_txwi));
4611 txwi->wcid = wcid;
4613 /* MIMO power save */
4615 if ((ni->ni_flags & IEEE80211_NODE_HT) &&
4616 ((ni->ni_htcap & IEEE80211_HTCAP_SMPS) != IEEE80211_HTCAP_SMPS_OFF))
4618 if (mcs > 7)
4620 if ((ni->ni_htcap & IEEE80211_HTCAP_SMPS) == IEEE80211_HTCAP_SMPS_DYNAMIC)
4622 /* dynamic MIMO power save */
4624 txwi->mpdu_density_flags |=
4625 (RT2870_TXWI_FLAGS_MIMOPS << RT2870_TXWI_FLAGS_SHIFT);
4627 else
4629 /* static MIMO power save */
4631 mcs = 7;
4635 mimops = 1;
4637 else
4639 mimops = 0;
4642 pid = (mcs < 0xf) ? (mcs + 1) : mcs;
4644 txwi->pid_mpdu_len = ((htole16(pid) & RT2870_TXWI_PID_MASK) <<
4645 RT2870_TXWI_PID_SHIFT) | ((htole16(mpdu_len) & RT2870_TXWI_MPDU_LEN_MASK) <<
4646 RT2870_TXWI_MPDU_LEN_SHIFT);
4648 stbc = ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) &&
4649 sc->tx_stbc && (mcs <= 7) && (ic->ic_htcaps & IEEE80211_HTCAP_TXSTBC) &&
4650 (ni->ni_flags & IEEE80211_NODE_HT) && (ni->ni_htcap & IEEE80211_HTCAP_RXSTBC);
4652 shortgi = ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) &&
4653 (((ic->ic_flags_ext & IEEE80211_FEXT_SHORTGI20) &&
4654 (ni->ni_flags & IEEE80211_NODE_HT) && (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) &&
4655 (ni->ni_chw == 20)) ||
4656 ((ic->ic_flags_ext & IEEE80211_FEXT_SHORTGI40) &&
4657 (ni->ni_flags & IEEE80211_NODE_HT) && (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) &&
4658 (ni->ni_chw == 40)));
4660 txwi->phymode_ifs_stbc_shortgi |=
4661 ((stbc & RT2870_TXWI_STBC_MASK) << RT2870_TXWI_STBC_SHIFT) |
4662 ((shortgi & RT2870_TXWI_SHORTGI_MASK) << RT2870_TXWI_SHORTGI_SHIFT);
4664 if (ni->ni_flags & IEEE80211_NODE_HT)
4666 txwi->phymode_ifs_stbc_shortgi |=
4667 (RT2870_TXWI_PHYMODE_HT_MIXED << RT2870_TXWI_PHYMODE_SHIFT);
4669 else
4671 if (!RT2870_RATE_IS_OFDM(rate))
4673 txwi->phymode_ifs_stbc_shortgi |=
4674 (RT2870_TXWI_PHYMODE_CCK << RT2870_TXWI_PHYMODE_SHIFT);
4676 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
4677 mcs |= RT2870_TXWI_MCS_SHOTPRE;
4679 else
4681 txwi->phymode_ifs_stbc_shortgi |=
4682 (RT2870_TXWI_PHYMODE_OFDM << RT2870_TXWI_PHYMODE_SHIFT);
4686 if ((ni->ni_flags & IEEE80211_NODE_HT) && (ni->ni_chw == 40))
4687 bw = RT2870_TXWI_BW_40;
4688 else
4689 bw = RT2870_TXWI_BW_20;
4691 txwi->bw_mcs = ((bw & RT2870_TXWI_BW_MASK) << RT2870_TXWI_BW_SHIFT) |
4692 ((mcs & RT2870_TXWI_MCS_MASK) << RT2870_TXWI_MCS_SHIFT);
4694 if (type != IEEE80211_FC0_TYPE_DATA)
4695 txwi->txop = (RT2870_TXWI_TXOP_BACKOFF << RT2870_TXWI_TXOP_SHIFT);
4696 else
4697 txwi->txop = (RT2870_TXWI_TXOP_HT << RT2870_TXWI_TXOP_SHIFT);
4699 /* skip ACKs for multicast frames */
4701 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
4702 (!hasqos || (qos & IEEE80211_QOS_ACKPOLICY) != IEEE80211_QOS_ACKPOLICY_NOACK))
4704 txwi->bawin_size_xflags |=
4705 (RT2870_TXWI_XFLAGS_ACK << RT2870_TXWI_XFLAGS_SHIFT);
4707 if (ni->ni_flags & IEEE80211_NODE_HT)
4709 /* preamble + plcp + signal extension + SIFS */
4711 dur = 16 + 4 + 6 + 10;
4713 else
4715 ackrate = rt2870_ackrate(ic, rate);
4717 dur = rt2870_txtime(RT2870_ACK_SIZE, ackrate, ic->ic_flags) +
4718 sc->sifs;
4721 *(uint16_t *) wh->i_dur = htole16(dur);
4724 /* check fo A-MPDU */
4726 if ((qos & IEEE80211_QOS_ACKPOLICY) == IEEE80211_QOS_ACKPOLICY_BA)
4728 ac = M_WME_GETAC(m);
4729 tx_ampdu = &ni->ni_tx_ampdu[ac];
4731 mpdu_density = RT2870_MS(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY);
4732 bawin_size = tx_ampdu->txa_wnd;
4734 txwi->mpdu_density_flags |=
4735 ((mpdu_density & RT2870_TXWI_MPDU_DENSITY_MASK) << RT2870_TXWI_MPDU_DENSITY_SHIFT) |
4736 (RT2870_TXWI_FLAGS_AMPDU << RT2870_TXWI_FLAGS_SHIFT);
4738 txwi->bawin_size_xflags |=
4739 ((bawin_size & RT2870_TXWI_BAWIN_SIZE_MASK) << RT2870_TXWI_BAWIN_SIZE_SHIFT);
4741 if (IEEE80211_HAS_ADDR4(wh))
4742 ((struct ieee80211_qosframe_addr4 *) wh)->i_qos[0] &= ~IEEE80211_QOS_ACKPOLICY;
4743 else
4744 ((struct ieee80211_qosframe *) wh)->i_qos[0] &= ~IEEE80211_QOS_ACKPOLICY;
4746 ampdu = 1;
4748 else
4750 mpdu_density = 0;
4751 bawin_size = 0;
4752 ampdu = 0;
4755 /* ask MAC to insert timestamp into probe responses */
4757 if ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
4758 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
4759 txwi->mpdu_density_flags |=
4760 (RT2870_TXWI_FLAGS_TS << RT2870_TXWI_FLAGS_SHIFT);
4762 if (bpf_peers_present(sc->drvbpf))
4764 tap = &sc->txtap;
4766 tap->flags = IEEE80211_RADIOTAP_F_DATAPAD;
4767 tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
4768 tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
4769 tap->chan_ieee = ic->ic_curchan->ic_ieee;
4770 tap->chan_maxpow = 0;
4772 if (ni->ni_flags & IEEE80211_NODE_HT)
4773 tap->rate = mcs | IEEE80211_RATE_MCS;
4774 else
4775 tap->rate = rate;
4777 if (mcs & RT2870_TXWI_MCS_SHOTPRE)
4778 tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
4780 if (shortgi)
4781 tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
4783 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4784 tap->flags |= IEEE80211_RADIOTAP_F_WEP;
4786 /* XXX use temporarily radiotap CFP flag as A-MPDU flag */
4788 if (ampdu)
4789 tap->flags |= IEEE80211_RADIOTAP_F_CFP;
4791 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4793 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
4795 bpf_mtap2(sc->drvbpf, tap, sc->txtap_len, m);
4797 wh->i_fc[1] |= IEEE80211_FC1_WEP;
4799 else
4801 bpf_mtap2(sc->drvbpf, tap, sc->txtap_len, m);
4805 m_copydata(m, 0, m->m_pkthdr.len, (caddr_t) (txwi + 1));
4807 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4808 "%s: sending frame: qid=%d, hdrsize=%d, hdrspace=%d, len=%d, "
4809 "bw=%d, stbc=%d, shortgi=%d, mcs=%d, wcid=0x%02x, ampdu=%d (density=%d, winsize=%d), "
4810 "mimops=%d, DMA len=%d\n",
4811 device_get_nameunit(sc->dev),
4812 qid, hdrsize, hdrspace, m->m_pkthdr.len, bw, stbc, shortgi,
4813 mcs, wcid, ampdu, mpdu_density, bawin_size, mimops, dmalen);
4815 data->m = m;
4816 data->ni = ni;
4818 STAILQ_INSERT_TAIL(&ring->active, data, next);
4819 ring->queued++;
4821 usbd_setup_xfer(data->xfer, ring->usb_pipe, ring, data->buf, len,
4822 USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RT2870_USB_XFER_TIMEOUT, rt2870_tx_intr);
4824 usbd_transfer(data->xfer);
4826 return 0;
4830 * rt2870_tx_raw
4832 static int rt2870_tx_raw(struct rt2870_softc *sc,
4833 struct mbuf *m, struct ieee80211_node *ni,
4834 const struct ieee80211_bpf_params *params)
4836 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4837 "%s: Tx raw\n",
4838 device_get_nameunit(sc->dev));
4840 return 0;
4844 * rt2870_rx_intr
4846 static void rt2870_rx_intr(usbd_xfer_handle xfer,
4847 usbd_private_handle priv, usbd_status status)
4849 struct rt2870_softc *sc;
4850 struct ifnet *ifp;
4851 struct rt2870_softc_rx_ring *ring;
4852 struct rt2870_softc_rx_data *data;
4853 int len;
4855 sc = priv;
4856 ifp = sc->ifp;
4857 ring = &sc->rx_ring;
4859 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
4860 return;
4862 RT2870_DPRINTF(sc, RT2870_DEBUG_INTR,
4863 "%s: Rx interrupt: %s\n",
4864 device_get_nameunit(sc->dev), usbd_errstr(status));
4866 sc->interrupts++;
4867 sc->rx_interrupts++;
4869 switch (status)
4871 case USBD_NORMAL_COMPLETION:
4872 data = STAILQ_FIRST(&ring->active);
4873 if (data == NULL)
4874 break;
4876 STAILQ_REMOVE_HEAD(&ring->active, next);
4878 KASSERT(data->xfer == xfer,
4879 ("%s: Rx interrupt: invalid USB xfer\n",
4880 device_get_nameunit(sc->dev)));
4882 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
4884 data->len = len;
4886 STAILQ_INSERT_TAIL(&ring->done, data, next);
4888 taskqueue_enqueue(sc->taskqueue, &sc->rx_done_task);
4889 break;
4891 case USBD_CANCELLED:
4892 case USBD_NOT_STARTED:
4893 break;
4895 default:
4896 if (status == USBD_STALLED)
4897 usbd_clear_endpoint_stall_async(ring->usb_pipe);
4899 data = STAILQ_FIRST(&ring->active);
4900 if (data != NULL)
4902 STAILQ_REMOVE_HEAD(&ring->active, next);
4904 STAILQ_INSERT_TAIL(&ring->active, data, next);
4906 usbd_setup_xfer(xfer, ring->usb_pipe, sc, data->buf,
4907 RT2870_USB_RX_BULK_BUFLEN, USBD_SHORT_XFER_OK | USBD_NO_COPY,
4908 USBD_NO_TIMEOUT, rt2870_rx_intr);
4910 usbd_transfer(xfer);
4912 break;
4917 * rt2870_tx_intr
4919 static void rt2870_tx_intr(usbd_xfer_handle xfer,
4920 usbd_private_handle priv, usbd_status status)
4922 struct rt2870_softc *sc;
4923 struct ifnet *ifp;
4924 struct rt2870_softc_tx_ring *ring;
4925 struct rt2870_softc_tx_data *data;
4927 ring = priv;
4928 sc = ring->sc;
4929 ifp = sc->ifp;
4931 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
4932 return;
4934 RT2870_DPRINTF(sc, RT2870_DEBUG_INTR,
4935 "%s: Tx interrupt: %s\n",
4936 device_get_nameunit(sc->dev), usbd_errstr(status));
4938 sc->interrupts++;
4939 sc->tx_interrupts[ring->qid]++;
4941 switch (status)
4943 case USBD_NORMAL_COMPLETION:
4944 data = STAILQ_FIRST(&ring->active);
4945 if (data == NULL)
4946 break;
4948 STAILQ_REMOVE_HEAD(&ring->active, next);
4950 STAILQ_INSERT_TAIL(&ring->done, data, next);
4952 sc->tx_qid_pending_mask |= (1 << ring->qid);
4954 taskqueue_enqueue(sc->taskqueue, &sc->tx_done_task);
4955 break;
4957 case USBD_CANCELLED:
4958 case USBD_NOT_STARTED:
4959 break;
4961 default:
4962 data = STAILQ_FIRST(&ring->active);
4963 if (data != NULL)
4965 STAILQ_REMOVE_HEAD(&ring->active, next);
4967 if (data->m != NULL)
4969 m_freem(data->m);
4970 data->m = NULL;
4973 if (data->ni != NULL)
4975 ieee80211_free_node(data->ni);
4976 data->ni = NULL;
4979 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
4981 ring->queued--;
4984 printf("%s: could not transmit buffer: qid=%d, status=%s\n",
4985 device_get_nameunit(sc->dev), ring->qid, usbd_errstr(status));
4987 ifp->if_oerrors++;
4988 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4990 if (status == USBD_STALLED)
4991 usbd_clear_endpoint_stall_async(ring->usb_pipe);
4992 break;
4997 * rt2870_rx_done_task
4999 static void rt2870_rx_done_task(void *context, int pending)
5001 struct rt2870_softc *sc;
5002 struct ifnet *ifp;
5004 sc = context;
5005 ifp = sc->ifp;
5007 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
5008 "%s: Rx done task\n",
5009 device_get_nameunit(sc->dev));
5011 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
5012 return;
5014 if (rt2870_rx_eof(sc, sc->rx_process_limit) != 0)
5016 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
5017 "%s: Rx done task: scheduling again\n",
5018 device_get_nameunit(sc->dev));
5020 taskqueue_enqueue(sc->taskqueue, &sc->rx_done_task);
5025 * rt2870_tx_done_task
5027 static void rt2870_tx_done_task(void *context, int pending)
5029 struct rt2870_softc *sc;
5030 struct ifnet *ifp;
5031 int i;
5033 sc = context;
5034 ifp = sc->ifp;
5036 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
5037 "%s: Tx done task\n",
5038 device_get_nameunit(sc->dev));
5040 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
5041 return;
5043 for (i = sc->usb_endpoints - 2; i >= 0; i--)
5045 if (sc->tx_qid_pending_mask & (1 << i))
5047 sc->tx_qid_pending_mask &= ~(1 << i);
5049 rt2870_tx_eof(sc, &sc->tx_ring[i]);
5053 if (sc->tx_qid_pending_mask != 0)
5055 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
5056 "%s: Tx done task: scheduling again\n",
5057 device_get_nameunit(sc->dev));
5059 taskqueue_enqueue(sc->taskqueue, &sc->tx_done_task);
5062 sc->tx_timer = 0;
5064 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
5068 * rt2870_periodic_task
5070 static void rt2870_periodic_task(void *context, int pending)
5072 struct rt2870_softc *sc;
5073 struct ifnet *ifp;
5074 struct ieee80211com *ic;
5076 sc = context;
5077 ifp = sc->ifp;
5078 ic = &sc->ic;
5080 RT2870_DPRINTF(sc, RT2870_DEBUG_PERIODIC,
5081 "%s: periodic task: round=%lu\n",
5082 device_get_nameunit(sc->dev), sc->periodic_round);
5084 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
5085 return;
5087 sc->periodic_round++;
5089 rt2870_update_stats(sc);
5091 if ((sc->periodic_round % 10) == 0)
5093 rt2870_bbp_tuning(sc);
5095 rt2870_update_raw_counters(sc);
5097 rt2870_watchdog(sc);
5099 if (ic->ic_opmode == IEEE80211_M_STA)
5100 rt2870_amrr_update_iter_func(sc, ic->ic_bss);
5101 else
5102 ieee80211_iterate_nodes(&ic->ic_sta, rt2870_amrr_update_iter_func, sc);
5105 callout_reset(&sc->periodic_ch, hz / 10, rt2870_periodic, sc);
5109 * rt2870_cmd_task
5111 static void rt2870_cmd_task(void *context, int pending)
5113 struct rt2870_softc *sc;
5114 struct rt2870_softc_cmd_ring *ring;
5115 struct rt2870_softc_cmd *cmd;
5117 sc = context;
5118 ring = &sc->cmd_ring;
5120 while (1)
5122 if (!(sc->flags & RT2870_SOFTC_FLAGS_VALID))
5123 break;
5125 RT2870_SOFTC_LOCK(sc);
5127 cmd = STAILQ_FIRST(&ring->active);
5128 if (cmd == NULL)
5130 RT2870_SOFTC_UNLOCK(sc);
5131 break;
5134 STAILQ_REMOVE_HEAD(&ring->active, next);
5136 RT2870_SOFTC_UNLOCK(sc);
5138 cmd->cb(sc, cmd->data);
5140 RT2870_SOFTC_LOCK(sc);
5142 STAILQ_INSERT_TAIL(&ring->inactive, cmd, next);
5143 ring->queued--;
5145 RT2870_SOFTC_UNLOCK(sc);
5150 * rt2870_rx_eof
5152 static int rt2870_rx_eof(struct rt2870_softc *sc, int limit)
5154 struct ifnet *ifp;
5155 struct rt2870_softc_rx_ring *ring;
5156 struct rt2870_softc_rx_data *data;
5157 uint32_t dmalen;
5158 uint8_t *buf;
5159 int nframes, len;
5161 ifp = sc->ifp;
5162 ring = &sc->rx_ring;
5164 nframes = 0;
5166 while (limit != 0)
5168 RT2870_SOFTC_LOCK(sc);
5170 data = STAILQ_FIRST(&ring->done);
5171 if (data == NULL)
5173 RT2870_SOFTC_UNLOCK(sc);
5174 break;
5177 STAILQ_REMOVE_HEAD(&ring->done, next);
5179 RT2870_SOFTC_UNLOCK(sc);
5181 buf = data->buf;
5182 len = data->len;
5184 if (len < RT2870_RX_DESC_SIZE)
5186 ifp->if_ierrors++;
5187 goto skip;
5190 while (len > (sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)))
5192 dmalen = (le32toh(*(uint32_t *) buf) & 0xffff);
5194 if (dmalen == 0 || (dmalen & 3) != 0)
5196 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
5197 "%s: bad DMA len=%u\n",
5198 device_get_nameunit(sc->dev), dmalen);
5199 goto skip;
5202 if ((dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)) > len)
5204 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
5205 "%s: bad DMA len: DMA len=%u, USB len=%d\n",
5206 device_get_nameunit(sc->dev),
5207 (unsigned int) (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)), len);
5208 goto skip;
5211 nframes++;
5213 rt2870_rx_frame(sc, buf + sizeof(uint32_t), dmalen);
5215 buf += (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo));
5216 len -= (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo));
5219 skip:
5221 RT2870_SOFTC_LOCK(sc);
5223 STAILQ_INSERT_TAIL(&ring->active, data, next);
5225 RT2870_SOFTC_UNLOCK(sc);
5227 usbd_setup_xfer(data->xfer, ring->usb_pipe, sc, data->buf,
5228 RT2870_USB_RX_BULK_BUFLEN, USBD_SHORT_XFER_OK | USBD_NO_COPY,
5229 USBD_NO_TIMEOUT, rt2870_rx_intr);
5231 usbd_transfer(data->xfer);
5233 limit--;
5236 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
5237 "%s: Rx eof: nframes=%d\n",
5238 device_get_nameunit(sc->dev), nframes);
5240 sc->rx_packets += nframes;
5242 return (limit == 0);
5246 * rt2870_tx_eof
5248 static void rt2870_tx_eof(struct rt2870_softc *sc,
5249 struct rt2870_softc_tx_ring *ring)
5251 struct ifnet *ifp;
5252 struct rt2870_softc_tx_data *data;
5253 int nframes;
5255 ifp = sc->ifp;
5257 nframes = 0;
5259 while (1)
5261 RT2870_SOFTC_LOCK(sc);
5263 data = STAILQ_FIRST(&ring->done);
5264 if (data == NULL)
5266 RT2870_SOFTC_UNLOCK(sc);
5267 break;
5270 STAILQ_REMOVE_HEAD(&ring->done, next);
5272 RT2870_SOFTC_UNLOCK(sc);
5274 rt2870_drain_fifo_stats(sc);
5276 nframes++;
5278 if (data->m->m_flags & M_TXCB)
5279 ieee80211_process_callback(data->ni, data->m, 0);
5281 m_freem(data->m);
5283 ieee80211_free_node(data->ni);
5285 data->m = NULL;
5286 data->ni = NULL;
5288 RT2870_SOFTC_LOCK(sc);
5290 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5292 ring->queued--;
5294 RT2870_SOFTC_UNLOCK(sc);
5296 ifp->if_opackets++;
5299 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
5300 "%s: Tx eof: qid=%d, nframes=%d\n",
5301 device_get_nameunit(sc->dev), ring->qid, nframes);
5305 * rt2870_update_stats
5307 static void rt2870_update_stats(struct rt2870_softc *sc)
5309 struct ifnet *ifp;
5310 struct ieee80211com *ic;
5311 uint32_t stacnt[3];
5312 int beacons, noretryok, retryok, failed, underflows, zerolen;
5314 ifp = sc->ifp;
5315 ic = &sc->ic;
5317 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
5318 "%s: update statistic\n",
5319 device_get_nameunit(sc->dev));
5321 rt2870_drain_fifo_stats(sc);
5323 /* read and clear Tx statistic registers */
5325 rt2870_io_mac_read_multi(sc, RT2870_REG_TX_STA_CNT0,
5326 stacnt, sizeof(stacnt));
5328 stacnt[0] = le32toh(stacnt[0]);
5329 stacnt[1] = le32toh(stacnt[1]);
5330 stacnt[2] = le32toh(stacnt[2]);
5332 beacons = stacnt[0] >> 16;
5333 noretryok = stacnt[1] & 0xffff;
5334 retryok = stacnt[1] >> 16;
5335 failed = stacnt[0] & 0xffff;
5336 underflows = stacnt[2] >> 16;
5337 zerolen = stacnt[2] & 0xffff;
5339 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
5340 "%s: update statistic: beacons=%d, noretryok=%d, retryok=%d, failed=%d, underflows=%d, zerolen=%d\n",
5341 device_get_nameunit(sc->dev),
5342 beacons, noretryok, retryok, failed, underflows, zerolen);
5344 ifp->if_oerrors += failed;
5346 sc->tx_beacons += beacons;
5347 sc->tx_noretryok += noretryok;
5348 sc->tx_retryok += retryok;
5349 sc->tx_failed += failed;
5350 sc->tx_underflows += underflows;
5351 sc->tx_zerolen += zerolen;
5355 * rt2870_bbp_tuning
5357 static void rt2870_bbp_tuning(struct rt2870_softc *sc)
5359 struct ieee80211com *ic;
5360 struct ieee80211_node *ni;
5361 int chan, group;
5362 int8_t rssi, old, new;
5364 /* RT2860C does not support BBP tuning */
5366 if (sc->mac_rev == 0x28600100)
5367 return;
5369 ic = &sc->ic;
5371 if ((ic->ic_flags & IEEE80211_F_SCAN) ||
5372 ic->ic_opmode != IEEE80211_M_STA || ic->ic_state != IEEE80211_S_RUN)
5373 return;
5375 ni = ic->ic_bss;
5377 chan = ieee80211_chan2ieee(ic, ni->ni_chan);
5379 if (chan <= 14)
5380 group = 0;
5381 else if (chan <= 64)
5382 group = 1;
5383 else if (chan <= 128)
5384 group = 2;
5385 else
5386 group = 3;
5388 rssi = ieee80211_getrssi(ic);
5390 if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
5392 new = 0x2e + sc->lna_gain[group];
5394 else
5396 if (!IEEE80211_IS_CHAN_HT40(ni->ni_chan))
5397 new = 0x32 + sc->lna_gain[group] * 5 / 3;
5398 else
5399 new = 0x3a + sc->lna_gain[group] * 5 / 3;
5402 /* Tune if absolute average RSSI is greater than -80 */
5404 if (rssi > -80)
5405 new += 0x10;
5407 old = rt2870_io_bbp_read(sc, 66);
5409 if (old != new)
5410 rt2870_io_bbp_write(sc, 66, new);
5414 * rt2870_watchdog
5416 static void rt2870_watchdog(struct rt2870_softc *sc)
5418 uint32_t tmp;
5419 int ntries;
5421 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
5423 RT2870_DPRINTF(sc, RT2870_DEBUG_WATCHDOG,
5424 "%s: watchdog: TXRXQ_PCNT=0x%08x\n",
5425 device_get_nameunit(sc->dev), tmp);
5427 if (((tmp >> RT2870_REG_TX0Q_PCNT_SHIFT) & RT2870_REG_TX0Q_PCNT_MASK) != 0)
5429 sc->tx_queue_not_empty[0]++;
5431 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40012);
5433 for (ntries = 0; ntries < 10; ntries++)
5435 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
5436 if (((tmp >> RT2870_REG_TX0Q_PCNT_SHIFT) & RT2870_REG_TX0Q_PCNT_MASK) == 0)
5437 break;
5439 DELAY(1);
5442 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40006);
5445 if (((tmp >> RT2870_REG_TX1Q_PCNT_SHIFT) & RT2870_REG_TX1Q_PCNT_MASK) != 0)
5447 sc->tx_queue_not_empty[1]++;
5449 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf4000a);
5451 for (ntries = 0; ntries < 10; ntries++)
5453 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
5454 if (((tmp >> RT2870_REG_TX1Q_PCNT_SHIFT) & RT2870_REG_TX1Q_PCNT_MASK) == 0)
5455 break;
5457 DELAY(1);
5460 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40006);
5465 * rt2870_drain_fifo_stats
5467 static void rt2870_drain_fifo_stats(struct rt2870_softc *sc)
5469 struct ifnet *ifp;
5470 uint32_t stats;
5471 uint8_t wcid, mcs, pid;
5472 int ok, agg, retrycnt;
5474 ifp = sc->ic.ic_ifp;
5476 /* drain Tx status FIFO (maxsize = 16) */
5478 while ((sc->flags & RT2870_SOFTC_FLAGS_VALID) &&
5479 (stats = rt2870_io_mac_read(sc, RT2870_REG_TX_STA_FIFO)) &
5480 RT2870_REG_TX_STA_FIFO_VALID)
5482 wcid = (stats >> RT2870_REG_TX_STA_FIFO_WCID_SHIFT) &
5483 RT2870_REG_TX_STA_FIFO_WCID_MASK;
5485 /* if no ACK was requested, no feedback is available */
5487 if (!(stats & RT2870_REG_TX_STA_FIFO_ACK_REQ) || wcid == 0xff)
5488 continue;
5490 /* update AMRR statistic */
5492 ok = (stats & RT2870_REG_TX_STA_FIFO_TX_OK) ? 1 : 0;
5493 agg = (stats & RT2870_REG_TX_STA_FIFO_AGG) ? 1 : 0;
5494 mcs = (stats >> RT2870_REG_TX_STA_FIFO_MCS_SHIFT) &
5495 RT2870_REG_TX_STA_FIFO_MCS_MASK;
5496 pid = (stats >> RT2870_REG_TX_STA_FIFO_PID_SHIFT) &
5497 RT2870_REG_TX_STA_FIFO_PID_MASK;
5498 retrycnt = (mcs < 0xf) ? (pid - mcs - 1) : 0;
5500 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
5501 "%s: FIFO statistic: wcid=0x%02x, ok=%d, agg=%d, mcs=0x%02x, pid=0x%02x, retrycnt=%d\n",
5502 device_get_nameunit(sc->dev),
5503 wcid, ok, agg, mcs, pid, retrycnt);
5505 rt2870_amrr_tx_complete(&sc->amrr_node[wcid], ok, retrycnt);
5507 if (!ok)
5508 ifp->if_oerrors++;
5513 * rt2870_update_raw_counters
5515 static void rt2870_update_raw_counters(struct rt2870_softc *sc)
5517 uint32_t tmp;
5519 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT);
5521 sc->tx_nonagg += tmp & 0xffff;
5522 sc->tx_agg += tmp >> 16;
5524 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT0);
5526 sc->tx_ampdu += (tmp & 0xffff) / 1 + (tmp >> 16) / 2;
5528 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT1);
5530 sc->tx_ampdu += (tmp & 0xffff) / 3 + (tmp >> 16) / 4;
5532 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT2);
5534 sc->tx_ampdu += (tmp & 0xffff) / 5 + (tmp >> 16) / 6;
5536 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT3);
5538 sc->tx_ampdu += (tmp & 0xffff) / 7 + (tmp >> 16) / 8;
5540 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT4);
5542 sc->tx_ampdu += (tmp & 0xffff) / 9 + (tmp >> 16) / 10;
5544 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT5);
5546 sc->tx_ampdu += (tmp & 0xffff) / 11 + (tmp >> 16) / 12;
5548 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT6);
5550 sc->tx_ampdu += (tmp & 0xffff) / 13 + (tmp >> 16) / 14;
5552 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT7);
5554 sc->tx_ampdu += (tmp & 0xffff) / 15 + (tmp >> 16) / 16;
5556 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT0);
5558 sc->rx_crc_errors += tmp & 0xffff;
5559 sc->rx_phy_errors += tmp >> 16;
5561 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT1);
5563 sc->rx_false_ccas += tmp & 0xffff;
5564 sc->rx_plcp_errors += tmp >> 16;
5566 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT2);
5568 sc->rx_dup_packets += tmp & 0xffff;
5569 sc->rx_fifo_overflows += tmp >> 16;
5571 tmp = rt2870_io_mac_read(sc, RT2870_REG_TXRX_MPDU_DEN_CNT);
5573 sc->tx_mpdu_zero_density += tmp & 0xffff;
5574 sc->rx_mpdu_zero_density += tmp >> 16;
5578 * rt2870_alloc_rx_ring
5580 static int rt2870_alloc_rx_ring(struct rt2870_softc *sc,
5581 struct rt2870_softc_rx_ring *ring)
5583 struct rt2870_softc_rx_data *data;
5584 int i, error;
5586 STAILQ_INIT(&ring->active);
5587 STAILQ_INIT(&ring->done);
5589 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
5591 data = &ring->data[i];
5593 data->xfer = usbd_alloc_xfer(sc->usb_dev);
5594 if (data->xfer == NULL)
5596 printf("%s: could not allocate Rx xfer\n",
5597 device_get_nameunit(sc->dev));
5598 error = ENOMEM;
5599 goto fail;
5602 data->buf = usbd_alloc_buffer(data->xfer, RT2870_USB_RX_BULK_BUFLEN);
5603 if (data->buf == NULL)
5605 printf("%s: could not allocate Rx buffer\n",
5606 device_get_nameunit(sc->dev));
5607 error = ENOMEM;
5608 goto fail;
5612 return 0;
5614 fail:
5616 rt2870_free_rx_ring(sc, ring);
5618 return error;
5622 * rt2870_reset_rx_ring
5624 static void rt2870_reset_rx_ring(struct rt2870_softc *sc,
5625 struct rt2870_softc_rx_ring *ring)
5627 STAILQ_INIT(&ring->active);
5628 STAILQ_INIT(&ring->done);
5632 * rt2870_free_rx_ring
5634 static void rt2870_free_rx_ring(struct rt2870_softc *sc,
5635 struct rt2870_softc_rx_ring *ring)
5637 struct rt2870_softc_rx_data *data;
5638 int i;
5640 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
5642 data = &ring->data[i];
5644 if ((data->buf != NULL) && (data->xfer != NULL))
5646 usbd_free_buffer(data->xfer);
5647 data->buf = NULL;
5650 if (data->xfer != NULL)
5652 usbd_free_xfer(data->xfer);
5653 data->xfer = NULL;
5659 * rt2870_alloc_tx_ring
5661 static int rt2870_alloc_tx_ring(struct rt2870_softc *sc,
5662 struct rt2870_softc_tx_ring *ring, int qid)
5664 struct rt2870_softc_tx_data *data;
5665 int i, error;
5667 STAILQ_INIT(&ring->inactive);
5668 STAILQ_INIT(&ring->active);
5669 STAILQ_INIT(&ring->done);
5671 ring->sc = sc;
5672 ring->queued = 0;
5673 ring->qid = qid;
5675 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
5677 data = &ring->data[i];
5679 data->xfer = usbd_alloc_xfer(sc->usb_dev);
5680 if (data->xfer == NULL)
5682 printf("%s: could not allocate Tx xfer\n",
5683 device_get_nameunit(sc->dev));
5684 error = ENOMEM;
5685 goto fail;
5688 data->buf = usbd_alloc_buffer(data->xfer,
5689 RT2870_TX_DESC_SIZE + MJUMPAGESIZE);
5690 if (data->buf == NULL)
5692 printf("%s: could not allocate Tx buffer\n",
5693 device_get_nameunit(sc->dev));
5694 error = ENOMEM;
5695 goto fail;
5698 memset(data->buf, 0, RT2870_TX_DESC_SIZE);
5700 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5703 return 0;
5705 fail:
5707 rt2870_free_tx_ring(sc, ring);
5709 return error;
5713 * rt2870_reset_tx_ring
5715 static void rt2870_reset_tx_ring(struct rt2870_softc *sc,
5716 struct rt2870_softc_tx_ring *ring)
5718 struct rt2870_softc_tx_data *data;
5719 int i;
5721 STAILQ_INIT(&ring->inactive);
5722 STAILQ_INIT(&ring->active);
5723 STAILQ_INIT(&ring->done);
5725 ring->queued = 0;
5727 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
5729 data = &ring->data[i];
5731 if (data->m != NULL)
5733 m_free(data->m);
5734 data->m = NULL;
5737 if (data->ni != NULL)
5739 ieee80211_free_node(data->ni);
5740 data->ni = NULL;
5743 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5748 * rt2870_free_tx_ring
5750 static void rt2870_free_tx_ring(struct rt2870_softc *sc,
5751 struct rt2870_softc_tx_ring *ring)
5753 struct rt2870_softc_tx_data *data;
5754 int i;
5756 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
5758 data = &ring->data[i];
5760 if (data->xfer != NULL)
5762 usbd_free_xfer(data->xfer);
5763 data->xfer = NULL;
5766 if (data->m != NULL)
5768 m_free(data->m);
5769 data->m = NULL;
5772 if (data->ni != NULL)
5774 ieee80211_free_node(data->ni);
5775 data->ni = NULL;
5781 * rt2870_reset_cmd_ring
5783 static void rt2870_reset_cmd_ring(struct rt2870_softc *sc,
5784 struct rt2870_softc_cmd_ring *ring)
5786 struct rt2870_softc_cmd *cmd;
5787 int i;
5789 STAILQ_INIT(&ring->inactive);
5790 STAILQ_INIT(&ring->active);
5792 ring->queued = 0;
5794 for (i = 0; i < RT2870_SOFTC_CMD_RING_CMD_COUNT; i++)
5796 cmd = &ring->cmd[i];
5798 STAILQ_INSERT_TAIL(&ring->inactive, cmd, next);
5803 * rt2870_sysctl_attach
5805 static void rt2870_sysctl_attach(struct rt2870_softc *sc)
5807 struct sysctl_ctx_list *ctx;
5808 struct sysctl_oid *tree;
5809 struct sysctl_oid *stats;
5811 ctx = device_get_sysctl_ctx(sc->dev);
5812 tree = device_get_sysctl_tree(sc->dev);
5814 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
5815 "tx_stbc", CTLFLAG_RW, &sc->tx_stbc, 0,
5816 "Tx STBC");
5818 /* statistic counters */
5820 stats = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
5821 "stats", CTLFLAG_RD, 0, "statistic");
5823 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5824 "interrupts", CTLFLAG_RD, &sc->interrupts, 0,
5825 "all interrupts");
5827 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5828 "rx_interrupts", CTLFLAG_RD, &sc->rx_interrupts, 0,
5829 "Rx interrupts");
5831 if (sc->usb_endpoints == (RT2870_SOFTC_TX_RING_COUNT + 1))
5833 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5834 "tx_mgmt_interrupts", CTLFLAG_RD, &sc->tx_interrupts[5], 0,
5835 "Tx MGMT interrupts");
5837 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5838 "tx_hcca_interrupts", CTLFLAG_RD, &sc->tx_interrupts[4], 0,
5839 "Tx HCCA interrupts");
5842 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5843 "tx_ac3_interrupts", CTLFLAG_RD, &sc->tx_interrupts[3], 0,
5844 "Tx AC3 interrupts");
5846 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5847 "tx_ac2_interrupts", CTLFLAG_RD, &sc->tx_interrupts[2], 0,
5848 "Tx AC2 interrupts");
5850 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5851 "tx_ac1_interrupts", CTLFLAG_RD, &sc->tx_interrupts[1], 0,
5852 "Tx AC1 interrupts");
5854 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5855 "tx_ac0_interrupts", CTLFLAG_RD, &sc->tx_interrupts[0], 0,
5856 "Tx AC0 interrupts");
5858 if (sc->usb_endpoints == (RT2870_SOFTC_TX_RING_COUNT + 1))
5860 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5861 "tx_mgmt_data_queued", CTLFLAG_RD, &sc->tx_ring[5].queued, 0,
5862 "Tx MGMT data queued");
5864 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5865 "tx_hcca_data_queued", CTLFLAG_RD, &sc->tx_ring[4].queued, 0,
5866 "Tx HCCA data queued");
5869 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5870 "tx_ac3_data_queued", CTLFLAG_RD, &sc->tx_ring[3].queued, 0,
5871 "Tx AC3 data queued");
5873 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5874 "tx_ac2_data_queued", CTLFLAG_RD, &sc->tx_ring[2].queued, 0,
5875 "Tx AC2 data queued");
5877 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5878 "tx_ac1_data_queued", CTLFLAG_RD, &sc->tx_ring[1].queued, 0,
5879 "Tx AC1 data queued");
5881 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5882 "tx_ac0_data_queued", CTLFLAG_RD, &sc->tx_ring[0].queued, 0,
5883 "Tx AC0 data queued");
5885 if (sc->usb_endpoints == (RT2870_SOFTC_TX_RING_COUNT + 1))
5887 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5888 "tx_mgmt_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[5], 0,
5889 "Tx MGMT data queue full");
5891 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5892 "tx_hcca_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[4], 0,
5893 "Tx HCCA data queue full");
5896 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5897 "tx_ac3_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[3], 0,
5898 "Tx AC3 data queue full");
5900 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5901 "tx_ac2_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[2], 0,
5902 "Tx AC2 data queue full");
5904 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5905 "tx_ac1_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[1], 0,
5906 "Tx AC1 data queue full");
5908 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5909 "tx_ac0_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[0], 0,
5910 "Tx AC0 data queue full");
5912 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5913 "tx_watchdog_timeouts", CTLFLAG_RD, &sc->tx_watchdog_timeouts, 0,
5914 "Tx watchdog timeouts");
5916 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5917 "rx_mbuf_alloc_errors", CTLFLAG_RD, &sc->rx_mbuf_alloc_errors, 0,
5918 "Rx mbuf allocation errors");
5920 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5921 "tx_queue_0_not_empty", CTLFLAG_RD, &sc->tx_queue_not_empty[0], 0,
5922 "Tx queue 0 not empty");
5924 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5925 "tx_queue_1_not_empty", CTLFLAG_RD, &sc->tx_queue_not_empty[1], 0,
5926 "Tx queue 1 not empty");
5928 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5929 "tx_beacons", CTLFLAG_RD, &sc->tx_beacons, 0,
5930 "Tx beacons");
5932 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5933 "tx_noretryok", CTLFLAG_RD, &sc->tx_noretryok, 0,
5934 "Tx successfull without retries");
5936 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5937 "tx_retryok", CTLFLAG_RD, &sc->tx_retryok, 0,
5938 "Tx successfull with retries");
5940 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5941 "tx_failed", CTLFLAG_RD, &sc->tx_failed, 0,
5942 "Tx failed");
5944 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5945 "tx_underflows", CTLFLAG_RD, &sc->tx_underflows, 0,
5946 "Tx underflows");
5948 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5949 "tx_zerolen", CTLFLAG_RD, &sc->tx_zerolen, 0,
5950 "Tx zero length");
5952 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5953 "tx_nonagg", CTLFLAG_RD, &sc->tx_nonagg, 0,
5954 "Tx non-aggregated");
5956 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5957 "tx_agg", CTLFLAG_RD, &sc->tx_agg, 0,
5958 "Tx aggregated");
5960 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5961 "tx_ampdu", CTLFLAG_RD, &sc->tx_ampdu, 0,
5962 "Tx A-MPDU");
5964 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5965 "tx_mpdu_zero_density", CTLFLAG_RD, &sc->tx_mpdu_zero_density, 0,
5966 "Tx MPDU with zero density");
5968 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5969 "tx_ampdu_sessions", CTLFLAG_RD, &sc->tx_ampdu_sessions, 0,
5970 "Tx A-MPDU sessions");
5972 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5973 "rx_packets", CTLFLAG_RD, &sc->rx_packets, 0,
5974 "Rx packets");
5976 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5977 "rx_ampdu", CTLFLAG_RD, &sc->rx_ampdu, 0,
5978 "Rx A-MPDU");
5980 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5981 "rx_ampdu_retries", CTLFLAG_RD, &sc->rx_ampdu_retries, 0,
5982 "Rx A-MPDU retries");
5984 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5985 "rx_mpdu_zero_density", CTLFLAG_RD, &sc->rx_mpdu_zero_density, 0,
5986 "Rx MPDU with zero density");
5988 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5989 "rx_ampdu_sessions", CTLFLAG_RD, &sc->rx_ampdu_sessions, 0,
5990 "Rx A-MPDU sessions");
5992 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5993 "rx_amsdu", CTLFLAG_RD, &sc->rx_amsdu, 0,
5994 "Rx A-MSDU");
5996 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5997 "rx_crc_errors", CTLFLAG_RD, &sc->rx_crc_errors, 0,
5998 "Rx CRC errors");
6000 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6001 "rx_phy_errors", CTLFLAG_RD, &sc->rx_phy_errors, 0,
6002 "Rx PHY errors");
6004 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6005 "rx_false_ccas", CTLFLAG_RD, &sc->rx_false_ccas, 0,
6006 "Rx false CCAs");
6008 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6009 "rx_plcp_errors", CTLFLAG_RD, &sc->rx_plcp_errors, 0,
6010 "Rx PLCP errors");
6012 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6013 "rx_dup_packets", CTLFLAG_RD, &sc->rx_dup_packets, 0,
6014 "Rx duplicate packets");
6016 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6017 "rx_fifo_overflows", CTLFLAG_RD, &sc->rx_fifo_overflows, 0,
6018 "Rx FIFO overflows");
6020 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6021 "rx_cipher_no_errors", CTLFLAG_RD, &sc->rx_cipher_no_errors, 0,
6022 "Rx cipher no errors");
6024 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6025 "rx_cipher_icv_errors", CTLFLAG_RD, &sc->rx_cipher_icv_errors, 0,
6026 "Rx cipher ICV errors");
6028 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6029 "rx_cipher_mic_errors", CTLFLAG_RD, &sc->rx_cipher_mic_errors, 0,
6030 "Rx cipher MIC errors");
6032 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
6033 "rx_cipher_invalid_key_errors", CTLFLAG_RD, &sc->rx_cipher_invalid_key_errors, 0,
6034 "Rx cipher invalid key errors");
6037 static device_method_t rt2870_dev_methods[] =
6039 DEVMETHOD(device_probe, rt2870_probe),
6040 DEVMETHOD(device_attach, rt2870_attach),
6041 DEVMETHOD(device_detach, rt2870_detach),
6042 { 0, 0 }
6045 static driver_t rt2870_driver =
6047 "rt2870",
6048 rt2870_dev_methods,
6049 sizeof(struct rt2870_softc),
6052 static devclass_t rt2870_dev_class;
6054 DRIVER_MODULE(rt2870, uhub, rt2870_driver, rt2870_dev_class,
6055 usbd_driver_load, 0);
6057 MODULE_DEPEND(rt2870, usb, 1, 1, 1);
6058 MODULE_DEPEND(rt2870, wlan, 1, 1, 1);