Fixed problems with 5GHz channels
[ralink_drivers/rt2870_fbsd72.git] / rt2870.c
bloba1a4620a4833d4494a8b12a4bd971acbb72fdbb7
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 /* override 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 (isnew)
2915 aid = IEEE80211_AID(ni->ni_associd);
2916 rni->staid = rt2870_staid_alloc(sc, aid);
2917 wcid = rni->staid;
2919 tmp = (ni->ni_macaddr[3] << 24) |
2920 (ni->ni_macaddr[2] << 16) |
2921 (ni->ni_macaddr[1] << 8) |
2922 ni->ni_macaddr[0];
2924 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid), tmp);
2926 tmp = (ni->ni_macaddr[5] << 8) |
2927 ni->ni_macaddr[4];
2929 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
2931 rt2870_amrr_node_init(&sc->amrr, &sc->amrr_node[wcid], ni);
2933 RT2870_DPRINTF(sc, RT2870_DEBUG_RATE,
2934 "%s: initial%s node Tx rate: associd=0x%04x, rate=0x%02x, max rate=0x%02x\n",
2935 device_get_nameunit(sc->dev),
2936 (ni->ni_flags & IEEE80211_NODE_HT) ? " HT" : "",
2937 ni->ni_associd, ni->ni_txrate,
2938 (ni->ni_flags & IEEE80211_NODE_HT) ?
2939 (ni->ni_htrates.rs_rates[ni->ni_htrates.rs_nrates - 1] | IEEE80211_RATE_MCS) :
2940 (ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates - 1] & IEEE80211_RATE_VAL));
2942 rt2870_asic_updateprot(sc);
2943 rt2870_asic_updateslot(sc);
2944 rt2870_asic_set_txpreamble(sc);
2947 RT2870_DPRINTF(sc, RT2870_DEBUG_NODE,
2948 "%s: new association: isnew=%d, macaddr=%s, associd=0x%04x, staid=0x%02x, QoS %s, ERP %s, HT %s\n",
2949 device_get_nameunit(sc->dev), isnew, ether_sprintf(ni->ni_macaddr),
2950 ni->ni_associd, rni->staid,
2951 (ni->ni_flags & IEEE80211_NODE_QOS) ? "enabled" : "disabled",
2952 (ni->ni_flags & IEEE80211_NODE_ERP) ? "enabled" : "disabled",
2953 (ni->ni_flags & IEEE80211_NODE_HT) ? "enabled" : "disabled");
2957 * rt2870_updateslot_cb
2959 static void rt2870_updateslot_cb(struct rt2870_softc *sc, void *arg)
2961 rt2870_asic_updateslot(sc);
2965 * rt2870_wme_update_cb
2967 static void rt2870_wme_update_cb(struct rt2870_softc *sc, void *arg)
2969 rt2870_asic_wme_update(sc);
2973 * rt2870_update_beacon_cb
2975 static void rt2870_update_beacon_cb(struct rt2870_softc *sc, void *arg)
2977 struct ieee80211com *ic;
2978 struct mbuf *m;
2979 struct ieee80211_beacon_offsets *bo;
2980 struct rt2870_cmd_argv_updatebeacon *cmd_argv;
2982 ic = &sc->ic;
2983 m = sc->beacon_mbuf;
2984 bo = &sc->beacon_offsets;
2985 cmd_argv = arg;
2987 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
2988 "%s: update beacon: what=%d\n",
2989 device_get_nameunit(sc->dev), cmd_argv->what);
2991 setbit(bo->bo_flags, cmd_argv->what);
2993 ieee80211_beacon_update(ic->ic_bss, bo, m, 0);
2995 rt2870_asic_update_beacon(sc);
2999 * rt2870_key_update_begin_cb
3001 static void rt2870_key_update_begin_cb(struct rt2870_softc *sc, void *arg)
3003 struct ifnet *ifp;
3005 ifp = sc->ifp;
3007 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
3008 "%s: key update begin\n",
3009 device_get_nameunit(sc->dev));
3011 taskqueue_block(sc->taskqueue);
3013 IF_LOCK(&ifp->if_snd);
3017 * rt2870_key_update_end_cb
3019 static void rt2870_key_update_end_cb(struct rt2870_softc *sc, void *arg)
3021 struct ifnet *ifp;
3023 ifp = sc->ifp;
3025 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
3026 "%s: key update end\n",
3027 device_get_nameunit(sc->dev));
3029 IF_UNLOCK(&ifp->if_snd);
3031 taskqueue_unblock(sc->taskqueue);
3035 * rt2870_key_set_cb
3037 static void rt2870_key_set_cb(struct rt2870_softc *sc, void *arg)
3039 struct ieee80211com *ic;
3040 struct ieee80211_key *k;
3041 enum ieee80211_opmode opmode;
3042 struct rt2870_cmd_argv_keyset *cmd_argv;
3043 uint16_t key_base, keymode_base;
3044 uint8_t mode, vapid, wcid, iv[8];
3045 uint32_t tmp;
3047 ic = &sc->ic;
3048 cmd_argv = arg;
3049 k = &cmd_argv->key;
3050 opmode = cmd_argv->opmode;
3052 switch (k->wk_cipher->ic_cipher)
3054 case IEEE80211_CIPHER_WEP:
3055 if(k->wk_keylen < 8)
3056 mode = RT2870_REG_CIPHER_MODE_WEP40;
3057 else
3058 mode = RT2870_REG_CIPHER_MODE_WEP104;
3059 break;
3061 case IEEE80211_CIPHER_TKIP:
3062 mode = RT2870_REG_CIPHER_MODE_TKIP;
3063 break;
3065 case IEEE80211_CIPHER_AES_CCM:
3066 mode = RT2870_REG_CIPHER_MODE_AES_CCMP;
3067 break;
3069 default:
3070 return;
3073 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
3074 "%s: key set: keyix=%d, keylen=%d, mode=%d, group=%d\n",
3075 device_get_nameunit(sc->dev), k->wk_keyix, k->wk_keylen,
3076 mode, (k->wk_flags & IEEE80211_KEY_GROUP) ? 1 : 0);
3078 if (!(k->wk_flags & IEEE80211_KEY_GROUP))
3080 /* install pairwise key */
3082 vapid = 0;
3083 wcid = cmd_argv->staid;
3084 key_base = RT2870_REG_PKEY(wcid);
3086 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP)
3088 memset(iv, 0, 8);
3090 iv[3] = (k->wk_keyix << 6);
3092 else
3094 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
3096 iv[0] = (k->wk_keytsc >> 8);
3097 iv[1] = ((iv[0] | 0x20) & 0x7f);
3098 iv[2] = k->wk_keytsc;
3100 else
3102 /* AES CCMP */
3104 iv[0] = k->wk_keytsc;
3105 iv[1] = k->wk_keytsc >> 8;
3106 iv[2] = 0;
3109 iv[3] = ((k->wk_keyix << 6) | IEEE80211_WEP_EXTIV);
3110 iv[4] = (k->wk_keytsc >> 16);
3111 iv[5] = (k->wk_keytsc >> 24);
3112 iv[6] = (k->wk_keytsc >> 32);
3113 iv[7] = (k->wk_keytsc >> 40);
3115 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
3116 "%s: VAP key set: iv=%02x %02x %02x %02x %02x %02x %02x %02x\n",
3117 device_get_nameunit(sc->dev),
3118 iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]);
3121 rt2870_io_mac_write_multi(sc, RT2870_REG_IVEIV(wcid), iv, 8);
3123 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
3125 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, 16);
3127 if (opmode != IEEE80211_M_HOSTAP)
3129 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[16], 8);
3130 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[24], 8);
3132 else
3134 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[24], 8);
3135 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[16], 8);
3138 else
3140 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, k->wk_keylen);
3143 tmp = ((vapid & RT2870_REG_VAP_MASK) << RT2870_REG_VAP_SHIFT) |
3144 (mode << RT2870_REG_CIPHER_MODE_SHIFT) | RT2870_REG_PKEY_ENABLE;
3146 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
3149 if ((k->wk_flags & IEEE80211_KEY_GROUP) ||
3150 (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP))
3152 /* install group key */
3154 vapid = 0;
3155 wcid = RT2870_WCID_MCAST;
3156 key_base = RT2870_REG_SKEY(vapid, k->wk_keyix);
3157 keymode_base = RT2870_REG_SKEY_MODE(vapid);
3159 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
3161 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, 16);
3163 if (opmode != IEEE80211_M_HOSTAP)
3165 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[16], 8);
3166 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[24], 8);
3168 else
3170 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[24], 8);
3171 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[16], 8);
3174 else
3176 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, k->wk_keylen);
3179 tmp = rt2870_io_mac_read(sc, keymode_base);
3181 tmp &= ~(0xf << (k->wk_keyix * 4 + 16 * (vapid % 2)));
3182 tmp |= (mode << (k->wk_keyix * 4 + 16 * (vapid % 2)));
3184 rt2870_io_mac_write(sc, keymode_base, tmp);
3186 if (opmode == IEEE80211_M_HOSTAP)
3188 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP)
3190 memset(iv, 0, 8);
3192 iv[3] = (k->wk_keyix << 6);
3194 else
3196 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
3198 iv[0] = (k->wk_keytsc >> 8);
3199 iv[1] = ((iv[0] | 0x20) & 0x7f);
3200 iv[2] = k->wk_keytsc;
3202 else
3204 /* AES CCMP */
3206 iv[0] = k->wk_keytsc;
3207 iv[1] = k->wk_keytsc >> 8;
3208 iv[2] = 0;
3211 iv[3] = ((k->wk_keyix << 6) | IEEE80211_WEP_EXTIV);
3212 iv[4] = (k->wk_keytsc >> 16);
3213 iv[5] = (k->wk_keytsc >> 24);
3214 iv[6] = (k->wk_keytsc >> 32);
3215 iv[7] = (k->wk_keytsc >> 40);
3217 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
3218 "%s: VAP key set: iv=%02x %02x %02x %02x %02x %02x %02x %02x\n",
3219 device_get_nameunit(sc->dev),
3220 iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]);
3223 rt2870_io_mac_write_multi(sc, RT2870_REG_IVEIV(wcid), iv, 8);
3225 tmp = ((vapid & RT2870_REG_VAP_MASK) << RT2870_REG_VAP_SHIFT) |
3226 (mode << RT2870_REG_CIPHER_MODE_SHIFT);
3228 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
3234 * rt2870_key_delete_cb
3236 static void rt2870_key_delete_cb(struct rt2870_softc *sc, void *arg)
3238 struct ieee80211com *ic;
3239 struct ieee80211_key *k;
3240 enum ieee80211_opmode opmode;
3241 struct rt2870_cmd_argv_keydelete *cmd_argv;
3242 uint8_t vapid, wcid;
3243 uint32_t tmp;
3245 ic = &sc->ic;
3246 cmd_argv = arg;
3247 k = &cmd_argv->key;
3248 opmode = cmd_argv->opmode;
3250 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
3251 "%s: key delete: keyix=%d, keylen=%d, group=%d\n",
3252 device_get_nameunit(sc->dev), k->wk_keyix, k->wk_keylen,
3253 (k->wk_flags & IEEE80211_KEY_GROUP) ? 1 : 0);
3255 if (k->wk_flags & IEEE80211_KEY_GROUP)
3257 /* remove group key */
3259 vapid = 0;
3260 wcid = RT2870_WCID_MCAST;
3262 tmp = rt2870_io_mac_read(sc, RT2870_REG_SKEY_MODE(vapid));
3264 tmp &= ~(0xf << (k->wk_keyix * 4 + 16 * (vapid % 2)));
3265 tmp |= (RT2870_REG_CIPHER_MODE_NONE << (k->wk_keyix * 4 + 16 * (vapid % 2)));
3267 rt2870_io_mac_write(sc, RT2870_REG_SKEY_MODE(vapid), tmp);
3269 if (opmode == IEEE80211_M_HOSTAP)
3271 tmp = ((vapid & RT2870_REG_VAP_MASK) << RT2870_REG_VAP_SHIFT) |
3272 (RT2870_REG_CIPHER_MODE_NONE << RT2870_REG_CIPHER_MODE_SHIFT);
3274 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
3280 * rt2870_asic_set_bssid
3282 static void rt2870_asic_set_bssid(struct rt2870_softc *sc,
3283 const uint8_t *bssid)
3285 uint32_t tmp;
3287 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3288 "%s: set bssid: bssid=%s\n",
3289 device_get_nameunit(sc->dev), ether_sprintf(bssid));
3291 tmp = bssid[0] | (bssid[1]) << 8 | (bssid[2] << 16) | (bssid[3] << 24);
3293 rt2870_io_mac_write(sc, RT2870_REG_BSSID_DW0, tmp);
3295 tmp = bssid[4] | (bssid[5] << 8);
3297 rt2870_io_mac_write(sc, RT2870_REG_BSSID_DW1, tmp);
3301 * rt2870_asic_set_macaddr
3303 static void rt2870_asic_set_macaddr(struct rt2870_softc *sc,
3304 const uint8_t *addr)
3306 uint32_t tmp;
3308 tmp = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
3310 rt2870_io_mac_write(sc, RT2870_REG_ADDR_DW0, tmp);
3312 tmp = addr[4] | (addr[5] << 8) | (0xff << 16);
3314 rt2870_io_mac_write(sc, RT2870_REG_ADDR_DW1, tmp);
3318 * rt2870_asic_enable_tsf_sync
3320 static void rt2870_asic_enable_tsf_sync(struct rt2870_softc *sc)
3322 struct ieee80211com *ic;
3323 uint32_t tmp;
3325 ic = &sc->ic;
3327 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
3328 "%s: enabling TSF\n",
3329 device_get_nameunit(sc->dev));
3331 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
3333 tmp &= ~0x1fffff;
3334 tmp |= ic->ic_bss->ni_intval * 16;
3335 tmp |= (RT2870_REG_TSF_TIMER_ENABLE | RT2870_REG_TBTT_TIMER_ENABLE);
3337 if (ic->ic_opmode == IEEE80211_M_STA)
3339 tmp |= (RT2870_REG_TSF_SYNC_MODE_STA << RT2870_REG_TSF_SYNC_MODE_SHIFT);
3341 else if (ic->ic_opmode == IEEE80211_M_IBSS)
3343 tmp |= RT2870_REG_BCN_TX_ENABLE;
3344 tmp |= (RT2870_REG_TSF_SYNC_MODE_IBSS << RT2870_REG_TSF_SYNC_MODE_SHIFT);
3346 else if (ic->ic_opmode == IEEE80211_M_HOSTAP)
3348 tmp |= RT2870_REG_BCN_TX_ENABLE;
3349 tmp |= (RT2870_REG_TSF_SYNC_MODE_HOSTAP << RT2870_REG_TSF_SYNC_MODE_SHIFT);
3352 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
3356 * rt2870_asic_disable_tsf_sync
3358 static void rt2870_asic_disable_tsf_sync(struct rt2870_softc *sc)
3360 uint32_t tmp;
3362 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
3363 "%s: disabling TSF\n",
3364 device_get_nameunit(sc->dev));
3366 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
3368 tmp &= ~(RT2870_REG_BCN_TX_ENABLE |
3369 RT2870_REG_TSF_TIMER_ENABLE |
3370 RT2870_REG_TBTT_TIMER_ENABLE);
3372 tmp &= ~(RT2870_REG_TSF_SYNC_MODE_MASK << RT2870_REG_TSF_SYNC_MODE_SHIFT);
3373 tmp |= (RT2870_REG_TSF_SYNC_MODE_DISABLE << RT2870_REG_TSF_SYNC_MODE_SHIFT);
3375 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
3379 * rt2870_asic_enable_mrr
3381 static void rt2870_asic_enable_mrr(struct rt2870_softc *sc)
3383 #define CCK(mcs) (mcs)
3384 #define OFDM(mcs) ((1 << 3) | (mcs))
3385 #define HT(mcs) (mcs)
3387 rt2870_io_mac_write(sc, RT2870_REG_TX_LG_FBK_CFG0,
3388 (OFDM(6) << 28) | /* 54 -> 48 */
3389 (OFDM(5) << 24) | /* 48 -> 36 */
3390 (OFDM(4) << 20) | /* 36 -> 24 */
3391 (OFDM(3) << 16) | /* 24 -> 18 */
3392 (OFDM(2) << 12) | /* 18 -> 12 */
3393 (OFDM(1) << 8) | /* 12 -> 9 */
3394 (OFDM(0) << 4) | /* 9 -> 6 */
3395 OFDM(0)); /* 6 -> 6 */
3397 rt2870_io_mac_write(sc, RT2870_REG_TX_LG_FBK_CFG1,
3398 (CCK(2) << 12) | /* 11 -> 5.5 */
3399 (CCK(1) << 8) | /* 5.5 -> 2 */
3400 (CCK(0) << 4) | /* 2 -> 1 */
3401 CCK(0)); /* 1 -> 1 */
3403 rt2870_io_mac_write(sc, RT2870_REG_TX_HT_FBK_CFG0,
3404 (HT(6) << 28) |
3405 (HT(5) << 24) |
3406 (HT(4) << 20) |
3407 (HT(3) << 16) |
3408 (HT(2) << 12) |
3409 (HT(1) << 8) |
3410 (HT(0) << 4) |
3411 HT(0));
3413 rt2870_io_mac_write(sc, RT2870_REG_TX_HT_FBK_CFG1,
3414 (HT(14) << 28) |
3415 (HT(13) << 24) |
3416 (HT(12) << 20) |
3417 (HT(11) << 16) |
3418 (HT(10) << 12) |
3419 (HT(9) << 8) |
3420 (HT(8) << 4) |
3421 HT(7));
3423 #undef HT
3424 #undef OFDM
3425 #undef CCK
3429 * rt2870_asic_set_txpreamble
3431 static void rt2870_asic_set_txpreamble(struct rt2870_softc *sc)
3433 struct ieee80211com *ic;
3434 uint32_t tmp;
3436 ic = &sc->ic;
3438 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3439 "%s: %s short Tx preamble\n",
3440 device_get_nameunit(sc->dev),
3441 (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? "enabling" : "disabling");
3443 tmp = rt2870_io_mac_read(sc, RT2870_REG_AUTO_RSP_CFG);
3445 tmp &= ~RT2870_REG_CCK_SHORT_ENABLE;
3447 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
3448 tmp |= RT2870_REG_CCK_SHORT_ENABLE;
3450 rt2870_io_mac_write(sc, RT2870_REG_AUTO_RSP_CFG, tmp);
3454 * rt2870_asic_set_basicrates
3456 static void rt2870_asic_set_basicrates(struct rt2870_softc *sc)
3458 struct ieee80211com *ic;
3460 ic = &sc->ic;
3462 if (ic->ic_curmode == IEEE80211_MODE_11B)
3463 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0xf);
3464 else if (ic->ic_curmode == IEEE80211_MODE_11A)
3465 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0x150);
3466 else
3467 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0x15f);
3471 * rt2870_asic_update_rtsthreshold
3473 static void rt2870_asic_update_rtsthreshold(struct rt2870_softc *sc)
3475 struct ieee80211com *ic;
3476 uint32_t tmp;
3477 uint16_t threshold;
3479 ic = &sc->ic;
3481 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3482 "%s: updating RTS threshold: %d\n",
3483 device_get_nameunit(sc->dev), ic->ic_rtsthreshold);
3485 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_RTS_CFG);
3487 tmp &= ~(RT2870_REG_TX_RTS_THRESHOLD_MASK << RT2870_REG_TX_RTS_THRESHOLD_SHIFT);
3489 if (ic->ic_flags_ext & IEEE80211_FEXT_AMSDU_TX)
3490 threshold = 0x1000;
3491 else
3492 threshold = ic->ic_rtsthreshold;
3494 tmp |= ((threshold & RT2870_REG_TX_RTS_THRESHOLD_MASK) <<
3495 RT2870_REG_TX_RTS_THRESHOLD_SHIFT);
3497 rt2870_io_mac_write(sc, RT2870_REG_TX_RTS_CFG, tmp);
3501 * rt2870_asic_update_txpower
3503 static void rt2870_asic_update_txpower(struct rt2870_softc *sc)
3505 struct ieee80211com *ic;
3506 uint32_t *txpow_rate;
3507 int8_t delta;
3508 uint8_t val;
3509 uint32_t tmp;
3510 int i;
3512 ic = &sc->ic;
3514 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3515 "%s: updating Tx power: %d\n",
3516 device_get_nameunit(sc->dev), ic->ic_txpowlimit);
3518 if (!IEEE80211_IS_CHAN_HT40(ic->ic_curchan))
3520 txpow_rate = sc->txpow_rate_20mhz;
3522 else
3524 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
3525 txpow_rate = sc->txpow_rate_40mhz_2ghz;
3526 else
3527 txpow_rate = sc->txpow_rate_40mhz_5ghz;
3530 delta = 0;
3532 val = rt2870_io_bbp_read(sc, 1);
3533 val &= 0xfc;
3535 if (ic->ic_txpowlimit > 90)
3537 /* do nothing */
3539 else if (ic->ic_txpowlimit > 60)
3541 delta -= 1;
3543 else if (ic->ic_txpowlimit > 30)
3545 delta -= 3;
3547 else if (ic->ic_txpowlimit > 15)
3549 val |= 0x1;
3551 else if (ic->ic_txpowlimit > 9)
3553 val |= 0x1;
3554 delta -= 3;
3556 else
3558 val |= 0x2;
3561 rt2870_io_bbp_write(sc, 1, val);
3563 for (i = 0; i < RT2870_SOFTC_TXPOW_RATE_COUNT; i++)
3565 if (txpow_rate[i] == 0xffffffff)
3566 continue;
3568 tmp = rt2870_read_eeprom_txpow_rate_add_delta(txpow_rate[i], delta);
3570 rt2870_io_mac_write(sc, RT2870_REG_TX_PWR_CFG(i), tmp);
3575 * rt2870_asic_update_promisc
3577 static void rt2870_asic_update_promisc(struct rt2870_softc *sc)
3579 struct ifnet *ifp;
3580 uint32_t tmp;
3582 ifp = sc->ic.ic_ifp;
3584 printf("%s: %s promiscuous mode\n",
3585 device_get_nameunit(sc->dev),
3586 (ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving");
3588 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_FILTER_CFG);
3590 tmp &= ~RT2870_REG_RX_FILTER_DROP_UC_NOME;
3592 if (!(ifp->if_flags & IFF_PROMISC))
3593 tmp |= RT2870_REG_RX_FILTER_DROP_UC_NOME;
3595 rt2870_io_mac_write(sc, RT2870_REG_RX_FILTER_CFG, tmp);
3599 * rt2870_asic_updateprot
3601 static void rt2870_asic_updateprot(struct rt2870_softc *sc)
3603 struct ieee80211com *ic;
3604 uint32_t cck_prot, ofdm_prot, mm20_prot, mm40_prot, gf20_prot, gf40_prot;
3605 uint8_t htopmode;
3606 enum ieee80211_protmode htprotmode;
3608 ic = &sc->ic;
3610 if (!(sc->flags & RT2870_SOFTC_FLAGS_VALID))
3611 return;
3613 /* CCK frame protection */
3615 cck_prot = RT2870_REG_RTSTH_ENABLE | RT2870_REG_PROT_NAV_SHORT |
3616 RT2870_REG_TXOP_ALLOW_ALL | RT2870_REG_PROT_CTRL_NONE;
3618 /* set up protection frame phy mode and rate (MCS code) */
3620 if (ic->ic_curmode == IEEE80211_MODE_11A)
3621 cck_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3622 (0 << RT2870_REG_PROT_MCS_SHIFT);
3623 else
3624 cck_prot |= ((RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3625 (3 << RT2870_REG_PROT_MCS_SHIFT));
3627 rt2870_io_mac_write(sc, RT2870_REG_TX_CCK_PROT_CFG, cck_prot);
3629 /* OFDM frame protection */
3631 ofdm_prot = RT2870_REG_RTSTH_ENABLE | RT2870_REG_PROT_NAV_SHORT |
3632 RT2870_REG_TXOP_ALLOW_ALL;
3634 if (ic->ic_flags & IEEE80211_F_USEPROT)
3636 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3637 "%s: updating protection mode: b/g protection mode=%s\n",
3638 device_get_nameunit(sc->dev),
3639 (ic->ic_protmode == IEEE80211_PROT_RTSCTS) ? "RTS/CTS" :
3640 ((ic->ic_protmode == IEEE80211_PROT_CTSONLY) ? "CTS-to-self" : "none"));
3642 if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
3643 ofdm_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3644 else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
3645 ofdm_prot |= RT2870_REG_PROT_CTRL_CTS;
3646 else
3647 ofdm_prot |= RT2870_REG_PROT_CTRL_NONE;
3649 else
3651 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3652 "%s: updating protection mode: b/g protection mode=%s\n",
3653 device_get_nameunit(sc->dev), "none");
3655 ofdm_prot |= RT2870_REG_PROT_CTRL_NONE;
3658 rt2870_io_mac_write(sc, RT2870_REG_TX_OFDM_PROT_CFG, ofdm_prot);
3660 /* HT frame protection */
3662 if ((ic->ic_opmode == IEEE80211_M_STA) && (ic->ic_state == IEEE80211_S_RUN))
3663 htopmode = ic->ic_bss->ni_htopmode;
3664 else
3665 htopmode = ic->ic_curhtprotmode;
3667 htprotmode = ic->ic_htprotmode;
3669 /* force HT mixed mode and RTS/CTS protection if A-MPDU Tx aggregation is enabled */
3671 if (sc->tx_ampdu_sessions > 0)
3673 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3674 "%s: updating protection mode: forcing HT mixed mode and RTS/CTS protection\n",
3675 device_get_nameunit(sc->dev));
3677 htopmode = IEEE80211_HTINFO_OPMODE_MIXED;
3678 htprotmode = IEEE80211_PROT_RTSCTS;
3681 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3682 "%s: updating protection mode: HT operation mode=0x%02x, protection mode=%s\n",
3683 device_get_nameunit(sc->dev),
3684 htopmode & IEEE80211_HTINFO_OPMODE,
3685 (htprotmode == IEEE80211_PROT_RTSCTS) ? "RTS/CTS" :
3686 ((htprotmode == IEEE80211_PROT_CTSONLY) ? "CTS-to-self" : "none"));
3688 switch (htopmode & IEEE80211_HTINFO_OPMODE)
3690 /* IEEE80211_HTINFO_OPMODE_HT20PR */
3691 case IEEE80211_HTINFO_OPMODE_HT20PR:
3692 mm20_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3693 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3694 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20 |
3695 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3696 (4 << RT2870_REG_PROT_MCS_SHIFT);
3698 gf20_prot = mm20_prot;
3700 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3701 RT2870_REG_TXOP_ALLOW_ALL |
3702 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3703 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
3705 if (htprotmode == IEEE80211_PROT_RTSCTS)
3706 mm40_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3707 else if (htprotmode == IEEE80211_PROT_CTSONLY)
3708 mm40_prot |= RT2870_REG_PROT_CTRL_CTS;
3709 else
3710 mm40_prot |= RT2870_REG_PROT_CTRL_NONE;
3712 gf40_prot = mm40_prot;
3713 break;
3715 /* IEEE80211_HTINFO_OPMODE_MIXED */
3716 case IEEE80211_HTINFO_OPMODE_MIXED:
3717 mm20_prot = RT2870_REG_PROT_NAV_SHORT |
3718 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3719 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20;
3721 if (ic->ic_flags & IEEE80211_F_USEPROT)
3722 mm20_prot |= (RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3723 (3 << RT2870_REG_PROT_MCS_SHIFT);
3724 else
3725 mm20_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3726 (4 << RT2870_REG_PROT_MCS_SHIFT);
3728 if (htprotmode == IEEE80211_PROT_RTSCTS)
3729 mm20_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3730 else if (htprotmode == IEEE80211_PROT_CTSONLY)
3731 mm20_prot |= RT2870_REG_PROT_CTRL_CTS;
3732 else
3733 mm20_prot |= RT2870_REG_PROT_CTRL_NONE;
3735 gf20_prot = mm20_prot;
3737 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_TXOP_ALLOW_ALL;
3739 if (ic->ic_flags & IEEE80211_F_USEPROT)
3740 mm40_prot |= (RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3741 (3 << RT2870_REG_PROT_MCS_SHIFT);
3742 else
3743 mm40_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3744 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
3746 if (htprotmode == IEEE80211_PROT_RTSCTS)
3747 mm40_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3748 else if (htprotmode == IEEE80211_PROT_CTSONLY)
3749 mm40_prot |= RT2870_REG_PROT_CTRL_CTS;
3750 else
3751 mm40_prot |= RT2870_REG_PROT_CTRL_NONE;
3753 gf40_prot = mm40_prot;
3754 break;
3757 * IEEE80211_HTINFO_OPMODE_PURE
3758 * IEEE80211_HTINFO_OPMODE_PROTOPT
3760 case IEEE80211_HTINFO_OPMODE_PURE:
3761 case IEEE80211_HTINFO_OPMODE_PROTOPT:
3762 default:
3763 mm20_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3764 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3765 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20 |
3766 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3767 (4 << RT2870_REG_PROT_MCS_SHIFT);
3769 gf20_prot = mm20_prot;
3771 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3772 RT2870_REG_TXOP_ALLOW_ALL |
3773 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3774 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
3776 gf40_prot = mm40_prot;
3777 break;
3780 rt2870_io_mac_write(sc, RT2870_REG_TX_MM20_PROT_CFG, mm20_prot);
3781 rt2870_io_mac_write(sc, RT2870_REG_TX_MM40_PROT_CFG, mm40_prot);
3782 rt2870_io_mac_write(sc, RT2870_REG_TX_GF20_PROT_CFG, gf20_prot);
3783 rt2870_io_mac_write(sc, RT2870_REG_TX_GF40_PROT_CFG, gf40_prot);
3787 * rt2870_asic_updateslot
3789 static void rt2870_asic_updateslot(struct rt2870_softc *sc)
3791 struct ieee80211com *ic;
3792 uint32_t tmp;
3794 ic = &sc->ic;
3796 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3797 "%s: %s short slot time\n",
3798 device_get_nameunit(sc->dev),
3799 (ic->ic_flags & (IEEE80211_F_SHSLOT | IEEE80211_F_BURST)) ? "enabling" : "disabling");
3801 tmp = rt2870_io_mac_read(sc, RT2870_REG_BKOFF_SLOT_CFG);
3803 tmp &= ~0xff;
3804 tmp |= (ic->ic_flags & (IEEE80211_F_SHSLOT | IEEE80211_F_BURST)) ? 9 : 20;
3806 rt2870_io_mac_write(sc, RT2870_REG_BKOFF_SLOT_CFG, tmp);
3810 * rt2870_asic_wme_update
3812 static void rt2870_asic_wme_update(struct rt2870_softc *sc)
3814 struct ieee80211com *ic;
3815 struct ieee80211_wme_state *wme;
3816 const struct wmeParams *wmep;
3817 int i;
3819 ic = &sc->ic;
3820 wme = &ic->ic_wme;
3821 wmep = wme->wme_chanParams.cap_wmeParams;
3823 RT2870_DPRINTF(sc, RT2870_DEBUG_WME,
3824 "%s: wme update: WME_AC_VO=%d/%d/%d/%d, WME_AC_VI=%d/%d/%d/%d, "
3825 "WME_AC_BK=%d/%d/%d/%d, WME_AC_BE=%d/%d/%d/%d\n",
3826 device_get_nameunit(sc->dev),
3827 wmep[WME_AC_VO].wmep_aifsn,
3828 wmep[WME_AC_VO].wmep_logcwmin, wmep[WME_AC_VO].wmep_logcwmax,
3829 wmep[WME_AC_VO].wmep_txopLimit,
3830 wmep[WME_AC_VI].wmep_aifsn,
3831 wmep[WME_AC_VI].wmep_logcwmin, wmep[WME_AC_VI].wmep_logcwmax,
3832 wmep[WME_AC_VI].wmep_txopLimit,
3833 wmep[WME_AC_BK].wmep_aifsn,
3834 wmep[WME_AC_BK].wmep_logcwmin, wmep[WME_AC_BK].wmep_logcwmax,
3835 wmep[WME_AC_BK].wmep_txopLimit,
3836 wmep[WME_AC_BE].wmep_aifsn,
3837 wmep[WME_AC_BE].wmep_logcwmin, wmep[WME_AC_BE].wmep_logcwmax,
3838 wmep[WME_AC_BE].wmep_txopLimit);
3840 for (i = 0; i < WME_NUM_AC; i++)
3841 rt2870_io_mac_write(sc, RT2870_REG_TX_EDCA_AC_CFG(i),
3842 (wmep[i].wmep_logcwmax << 16) | (wmep[i].wmep_logcwmin << 12) |
3843 (wmep[i].wmep_aifsn << 8) | wmep[i].wmep_txopLimit);
3845 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_AIFSN_CFG,
3846 (wmep[WME_AC_VO].wmep_aifsn << 12) | (wmep[WME_AC_VI].wmep_aifsn << 8) |
3847 (wmep[WME_AC_BK].wmep_aifsn << 4) | wmep[WME_AC_BE].wmep_aifsn);
3849 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_CWMIN_CFG,
3850 (wmep[WME_AC_VO].wmep_logcwmin << 12) | (wmep[WME_AC_VI].wmep_logcwmin << 8) |
3851 (wmep[WME_AC_BK].wmep_logcwmin << 4) | wmep[WME_AC_BE].wmep_logcwmin);
3853 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_CWMAX_CFG,
3854 (wmep[WME_AC_VO].wmep_logcwmax << 12) | (wmep[WME_AC_VI].wmep_logcwmax << 8) |
3855 (wmep[WME_AC_BK].wmep_logcwmax << 4) | wmep[WME_AC_BE].wmep_logcwmax);
3857 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP0_CFG,
3858 (wmep[WME_AC_BK].wmep_txopLimit << 16) | wmep[WME_AC_BE].wmep_txopLimit);
3860 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP1_CFG,
3861 (wmep[WME_AC_VO].wmep_txopLimit << 16) | wmep[WME_AC_VI].wmep_txopLimit);
3865 * rt2870_asic_update_beacon
3867 static void rt2870_asic_update_beacon(struct rt2870_softc *sc)
3869 struct ieee80211com *ic;
3870 struct mbuf *m;
3871 struct rt2870_txwi *txwi;
3872 uint32_t tmp;
3874 ic = &sc->ic;
3876 m = sc->beacon_mbuf;
3877 txwi = &sc->beacon_txwi;
3879 /* disable temporarily TSF sync */
3881 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
3883 tmp &= ~(RT2870_REG_BCN_TX_ENABLE |
3884 RT2870_REG_TSF_TIMER_ENABLE |
3885 RT2870_REG_TBTT_TIMER_ENABLE);
3887 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
3889 /* write Tx wireless info and beacon frame to on-chip memory */
3891 rt2870_io_mac_write_multi(sc, RT2870_REG_BEACON_BASE(0),
3892 txwi, sizeof(struct rt2870_txwi));
3894 rt2870_io_mac_write_multi(sc, RT2870_REG_BEACON_BASE(0) + sizeof(struct rt2870_txwi),
3895 mtod(m, uint8_t *), m->m_pkthdr.len);
3897 /* enable again TSF sync */
3899 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
3901 tmp |= (RT2870_REG_BCN_TX_ENABLE |
3902 RT2870_REG_TSF_TIMER_ENABLE |
3903 RT2870_REG_TBTT_TIMER_ENABLE);
3905 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
3909 * rt2870_asic_clear_keytables
3911 static void rt2870_asic_clear_keytables(struct rt2870_softc *sc)
3913 int i;
3915 /* clear Rx WCID search table (entries = 256, entry size = 8) */
3917 for (i = 0; i < 256; i++)
3919 rt2870_io_mac_write(sc, RT2870_REG_WCID(i), 0xffffffff);
3920 rt2870_io_mac_write(sc, RT2870_REG_WCID(i) + 4, 0x0000ffff);
3923 /* clear WCID attribute table (entries = 256, entry size = 4) */
3925 rt2870_io_mac_set_region_4(sc, RT2870_REG_WCID_ATTR(0), 0, 256);
3927 /* clear IV/EIV table (entries = 256, entry size = 8) */
3929 rt2870_io_mac_set_region_4(sc, RT2870_REG_IVEIV(0), 0, 2 * 256);
3931 /* clear pairwise key table (entries = 64, entry size = 32) */
3933 rt2870_io_mac_set_region_4(sc, RT2870_REG_PKEY(0), 0, 8 * 64);
3935 /* clear shared key table (entries = 32, entry size = 32) */
3937 rt2870_io_mac_set_region_4(sc, RT2870_REG_SKEY(0, 0), 0, 8 * 32);
3939 /* clear shared key mode (entries = 32, entry size = 2) */
3941 rt2870_io_mac_set_region_4(sc, RT2870_REG_SKEY_MODE(0), 0, 16);
3945 * rt2870_asic_add_ba_session
3947 static void rt2870_asic_add_ba_session(struct rt2870_softc *sc,
3948 uint8_t wcid, int tid)
3950 uint32_t tmp;
3952 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID(wcid) + 4);
3954 tmp |= (0x10000 << tid);
3956 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
3960 * rt2860_asic_del_ba_session
3962 static void rt2870_asic_del_ba_session(struct rt2870_softc *sc,
3963 uint8_t wcid, int tid)
3965 uint32_t tmp;
3967 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID(wcid) + 4);
3969 tmp &= ~(0x10000 << tid);
3971 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
3975 * rt2870_beacon_alloc
3977 static int rt2870_beacon_alloc(struct rt2870_softc *sc)
3979 struct ieee80211com *ic;
3980 struct mbuf *m;
3981 struct rt2870_txwi txwi;
3982 uint8_t rate, mcs;
3984 ic = &sc->ic;
3986 m = ieee80211_beacon_alloc(ic->ic_bss, &sc->beacon_offsets);
3987 if (m == NULL)
3988 return ENOMEM;
3990 rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
3991 mcs = rt2870_rate2mcs(rate);
3993 memset(&txwi, 0, sizeof(struct rt2870_txwi));
3995 txwi.wcid = 0xff;
3996 txwi.pid_mpdu_len = ((htole16(m->m_pkthdr.len) & RT2870_TXWI_MPDU_LEN_MASK) <<
3997 RT2870_TXWI_MPDU_LEN_SHIFT);
3998 txwi.txop = (RT2870_TXWI_TXOP_HT << RT2870_TXWI_TXOP_SHIFT);
3999 txwi.mpdu_density_flags |=
4000 (RT2870_TXWI_FLAGS_TS << RT2870_TXWI_FLAGS_SHIFT);
4001 txwi.bawin_size_xflags |=
4002 (RT2870_TXWI_XFLAGS_NSEQ << RT2870_TXWI_XFLAGS_SHIFT);
4004 if (rate == 2)
4006 txwi.phymode_ifs_stbc_shortgi =
4007 (RT2870_TXWI_PHYMODE_CCK << RT2870_TXWI_PHYMODE_SHIFT);
4009 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
4010 mcs |= RT2870_TXWI_MCS_SHOTPRE;
4012 else
4014 txwi.phymode_ifs_stbc_shortgi =
4015 (RT2870_TXWI_PHYMODE_OFDM << RT2870_TXWI_PHYMODE_SHIFT);
4018 txwi.bw_mcs = (RT2870_TXWI_BW_20 << RT2870_TXWI_BW_SHIFT) |
4019 ((mcs & RT2870_TXWI_MCS_MASK) << RT2870_TXWI_MCS_SHIFT);
4021 if (sc->beacon_mbuf != NULL)
4023 m_free(sc->beacon_mbuf);
4024 sc->beacon_mbuf = NULL;
4027 sc->beacon_mbuf = m;
4028 sc->beacon_txwi = txwi;
4030 return 0;
4034 * rt2870_rxrate
4036 static uint8_t rt2870_rxrate(struct rt2870_rxwi *rxwi)
4038 uint8_t mcs, phymode;
4039 uint8_t rate;
4041 mcs = (rxwi->bw_mcs >> RT2870_RXWI_MCS_SHIFT) & RT2870_RXWI_MCS_MASK;
4042 phymode = (rxwi->phymode_stbc_shortgi >> RT2870_RXWI_PHYMODE_SHIFT) &
4043 RT2870_RXWI_PHYMODE_MASK;
4045 rate = 2;
4047 switch (phymode)
4049 case RT2870_RXWI_PHYMODE_CCK:
4050 switch (mcs & ~RT2870_RXWI_MCS_SHOTPRE)
4052 case 0: rate = 2; break; /* 1 Mbps */
4053 case 1: rate = 4; break; /* 2 MBps */
4054 case 2: rate = 11; break; /* 5.5 Mbps */
4055 case 3: rate = 22; break; /* 11 Mbps */
4057 break;
4059 case RT2870_RXWI_PHYMODE_OFDM:
4060 switch (mcs)
4062 case 0: rate = 12; break; /* 6 Mbps */
4063 case 1: rate = 18; break; /* 9 Mbps */
4064 case 2: rate = 24; break; /* 12 Mbps */
4065 case 3: rate = 36; break; /* 18 Mbps */
4066 case 4: rate = 48; break; /* 24 Mbps */
4067 case 5: rate = 72; break; /* 36 Mbps */
4068 case 6: rate = 96; break; /* 48 Mbps */
4069 case 7: rate = 108; break; /* 54 Mbps */
4071 break;
4073 case RT2870_RXWI_PHYMODE_HT_MIXED:
4074 case RT2870_RXWI_PHYMODE_HT_GF:
4075 break;
4078 return rate;
4082 * rt2870_maxrssi_rxpath
4084 static uint8_t rt2870_maxrssi_rxpath(struct rt2870_softc *sc,
4085 const struct rt2870_rxwi *rxwi)
4087 uint8_t rxpath;
4089 rxpath = 0;
4091 if (sc->nrxpath > 1)
4092 if (rxwi->rssi[1] > rxwi->rssi[rxpath])
4093 rxpath = 1;
4095 if (sc->nrxpath > 2)
4096 if (rxwi->rssi[2] > rxwi->rssi[rxpath])
4097 rxpath = 2;
4099 return rxpath;
4103 * rt2870_rssi2dbm
4105 static int8_t rt2870_rssi2dbm(struct rt2870_softc *sc,
4106 uint8_t rssi, uint8_t rxpath)
4108 struct ieee80211com *ic;
4109 struct ieee80211_channel *c;
4110 int chan;
4111 int8_t rssi_off, lna_gain;
4113 if (rssi == 0)
4114 return -99;
4116 ic = &sc->ic;
4117 c = ic->ic_curchan;
4118 chan = ieee80211_chan2ieee(ic, c);
4120 if (IEEE80211_IS_CHAN_5GHZ(c))
4122 rssi_off = sc->rssi_off_5ghz[rxpath];
4124 if (chan <= 64)
4125 lna_gain = sc->lna_gain[1];
4126 else if (chan <= 128)
4127 lna_gain = sc->lna_gain[2];
4128 else
4129 lna_gain = sc->lna_gain[3];
4131 else
4133 rssi_off = sc->rssi_off_2ghz[rxpath];
4134 lna_gain = sc->lna_gain[0];
4137 return (-12 - rssi_off - lna_gain - rssi);
4141 * rt2870_rate2mcs
4143 static uint8_t rt2870_rate2mcs(uint8_t rate)
4145 switch (rate)
4147 /* CCK rates */
4148 case 2: return 0;
4149 case 4: return 1;
4150 case 11: return 2;
4151 case 22: return 3;
4153 /* OFDM rates */
4154 case 12: return 0;
4155 case 18: return 1;
4156 case 24: return 2;
4157 case 36: return 3;
4158 case 48: return 4;
4159 case 72: return 5;
4160 case 96: return 6;
4161 case 108: return 7;
4164 return 0;
4168 * rt2870_ackrate
4170 static int rt2870_ackrate(struct ieee80211com *ic, int rate)
4172 switch (rate)
4174 /* CCK rates */
4176 case 2:
4177 return 2;
4179 case 4:
4180 case 11:
4181 case 22:
4182 return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate;
4184 /* OFDM rates */
4186 case 12:
4187 case 18:
4188 return 12;
4190 case 24:
4191 case 36:
4192 return 24;
4194 case 48:
4195 case 72:
4196 case 96:
4197 case 108:
4198 return 48;
4201 /* default to 1Mbps */
4202 return 2;
4206 * rt2870_txtime
4208 static uint16_t rt2870_txtime(int len, int rate, uint32_t flags)
4210 uint16_t txtime;
4212 if (RT2870_RATE_IS_OFDM(rate))
4214 txtime = (8 + 4 * len + 3 + rate - 1) / rate;
4215 txtime = 16 + 4 + 4 * txtime + 6;
4217 else
4219 txtime = (16 * len + rate - 1) / rate;
4221 if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE))
4222 txtime += 72 + 24;
4223 else
4224 txtime += 144 + 48;
4227 return txtime;
4231 * rt2870_rx_frame
4233 static void rt2870_rx_frame(struct rt2870_softc *sc,
4234 uint8_t *buf, uint32_t dmalen)
4236 struct ieee80211com *ic;
4237 struct ifnet *ifp;
4238 struct ieee80211_frame *wh;
4239 struct ieee80211_node *ni;
4240 struct rt2870_softc_node *rni;
4241 struct rt2870_softc_rx_radiotap_header *tap;
4242 struct rt2870_rxwi *rxwi;
4243 struct rt2870_rxinfo *rxinfo;
4244 struct mbuf *m;
4245 uint32_t rxinfo_flags;
4246 uint8_t cipher_err, rssi, ant, phymode, bw, shortgi, mcs, keyidx;
4247 int8_t rssi_dbm;
4248 int len, ampdu, amsdu, i;
4250 ic = &sc->ic;
4251 ifp = ic->ic_ifp;
4253 /* get Rx wireless info */
4255 rxwi = (struct rt2870_rxwi *) buf;
4256 len = (le16toh(rxwi->tid_size) >> RT2870_RXWI_SIZE_SHIFT) &
4257 RT2870_RXWI_SIZE_MASK;
4259 if (len > dmalen)
4261 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4262 "%s: bad rxwi len: DMA len=%d, rxwi len=%d\n",
4263 device_get_nameunit(sc->dev), dmalen, len);
4264 return;
4267 /* get Rx info */
4269 rxinfo = (struct rt2870_rxinfo *) ((caddr_t) rxwi + dmalen);
4270 rxinfo_flags = le32toh(rxinfo->flags);
4272 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4273 "%s: Rx frame: DMA len=%d, len=%d, rxinfo flags=0x%08x\n",
4274 device_get_nameunit(sc->dev), dmalen, len, rxinfo_flags);
4276 /* check for crc errors */
4278 if (rxinfo_flags & RT2870_RXINFO_FLAGS_CRC_ERR)
4280 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4281 "%s: rxinfo: crc error\n",
4282 device_get_nameunit(sc->dev));
4284 ifp->if_ierrors++;
4286 if (!(ifp->if_flags & IFF_PROMISC))
4287 return;
4290 wh = (struct ieee80211_frame *) (rxwi + 1);
4292 /* check for L2 padding between IEEE 802.11 frame header and body */
4294 if (rxinfo_flags & RT2870_RXINFO_FLAGS_L2PAD)
4296 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4297 "%s: L2 padding: DMA len=%d, len=%d\n",
4298 device_get_nameunit(sc->dev), dmalen, len);
4300 len += 2;
4303 m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
4304 if (m == NULL)
4306 sc->rx_mbuf_alloc_errors++;
4307 ifp->if_ierrors++;
4308 return;
4311 m->m_pkthdr.rcvif = ifp;
4312 m->m_pkthdr.len = m->m_len = len;
4314 m_copyback(m, 0, len, (caddr_t) wh);
4316 wh = mtod(m, struct ieee80211_frame *);
4318 /* check for cipher errors */
4320 if (rxinfo_flags & RT2870_RXINFO_FLAGS_DECRYPTED)
4322 cipher_err = ((rxinfo_flags >> RT2870_RXINFO_FLAGS_CIPHER_ERR_SHIFT) &
4323 RT2870_RXINFO_FLAGS_CIPHER_ERR_MASK);
4324 if (cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_NONE)
4326 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4327 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
4329 m->m_flags |= M_WEP;
4331 sc->rx_cipher_no_errors++;
4333 else
4335 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4336 "%s: rxinfo: cipher error=0x%02x\n",
4337 device_get_nameunit(sc->dev), cipher_err);
4339 if (cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_ICV)
4340 sc->rx_cipher_icv_errors++;
4341 else if (cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_MIC)
4342 sc->rx_cipher_mic_errors++;
4343 else if (cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_INVALID_KEY)
4344 sc->rx_cipher_invalid_key_errors++;
4346 if ((cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_MIC) &&
4347 (rxinfo_flags & RT2870_RXINFO_FLAGS_MYBSS))
4349 keyidx = (rxwi->udf_bssidx_keyidx >> RT2870_RXWI_KEYIDX_SHIFT) &
4350 RT2870_RXWI_KEYIDX_MASK;
4352 ieee80211_notify_michael_failure(ic, wh, keyidx);
4355 ifp->if_ierrors++;
4357 if (!(ifp->if_flags & IFF_PROMISC))
4359 m_free(m);
4360 return;
4364 else
4366 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4368 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4369 "%s: rxinfo: not decrypted but protected flag set\n",
4370 device_get_nameunit(sc->dev));
4372 ifp->if_ierrors++;
4374 if (!(ifp->if_flags & IFF_PROMISC))
4376 m_free(m);
4377 return;
4382 /* check for A-MPDU */
4384 if (rxinfo_flags & RT2870_RXINFO_FLAGS_BA)
4386 m->m_flags |= M_AMPDU;
4388 sc->rx_ampdu++;
4390 ampdu = 1;
4392 else
4394 ampdu = 0;
4397 /* check for A-MSDU */
4399 if (rxinfo_flags & RT2870_RXINFO_FLAGS_AMSDU)
4401 sc->rx_amsdu++;
4403 amsdu = 1;
4405 else
4407 amsdu = 0;
4410 ant = rt2870_maxrssi_rxpath(sc, rxwi);
4411 rssi = rxwi->rssi[ant];
4412 rssi_dbm = rt2870_rssi2dbm(sc, rssi, ant);
4413 phymode = ((rxwi->phymode_stbc_shortgi >> RT2870_RXWI_PHYMODE_SHIFT) &
4414 RT2870_RXWI_PHYMODE_MASK);
4415 bw = ((rxwi->bw_mcs >> RT2870_RXWI_BW_SHIFT) & RT2870_RXWI_BW_MASK);
4416 shortgi = ((rxwi->phymode_stbc_shortgi >> RT2870_RXWI_SHORTGI_SHIFT) &
4417 RT2870_RXWI_SHORTGI_MASK);
4418 mcs = ((rxwi->bw_mcs >> RT2870_RXWI_MCS_SHIFT) & RT2870_RXWI_MCS_MASK);
4420 if (bpf_peers_present(sc->drvbpf))
4422 tap = &sc->rxtap;
4424 tap->flags = IEEE80211_RADIOTAP_F_DATAPAD;
4425 tap->dbm_antsignal = rssi_dbm;
4426 tap->dbm_antnoise = RT2870_NOISE_FLOOR;
4427 tap->antenna = ant;
4428 tap->antsignal = rssi;
4429 tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
4430 tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
4431 tap->chan_ieee = ic->ic_curchan->ic_ieee;
4432 tap->chan_maxpow = 0;
4434 if (phymode == RT2870_RXWI_PHYMODE_CCK || phymode == RT2870_RXWI_PHYMODE_OFDM)
4435 tap->rate = rt2870_rxrate(rxwi);
4436 else
4437 tap->rate = mcs | IEEE80211_RATE_MCS;
4439 if (rxinfo_flags & RT2870_RXINFO_FLAGS_CRC_ERR)
4440 tap->flags |= IEEE80211_RADIOTAP_F_BADFCS;
4442 if (rxinfo_flags & RT2870_RXINFO_FLAGS_FRAG)
4443 tap->flags |= IEEE80211_RADIOTAP_F_FRAG;
4445 if (rxwi->bw_mcs & RT2870_RXWI_MCS_SHOTPRE)
4446 tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
4448 if (shortgi)
4449 tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
4451 bpf_mtap2(sc->drvbpf, tap, sc->rxtap_len, m);
4454 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4455 "%s: received frame: len=%d, phymode=%d, bw=%d, shortgi=%d, mcs=%d, "
4456 "ant=%d, rssi=%d/%d/%d, snr=%d/%d, wcid=0x%02x, ampdu=%d, amsdu=%d\n",
4457 device_get_nameunit(sc->dev),
4458 len, phymode, bw, shortgi, mcs,
4459 ant, rxwi->rssi[0], rxwi->rssi[1], rxwi->rssi[2],
4460 rxwi->snr[0], rxwi->snr[1],
4461 rxwi->wcid, ampdu, amsdu);
4463 ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *) wh);
4465 if (ni != NULL)
4467 rni = (struct rt2870_softc_node *) ni;
4469 for (i = 0; i < RT2870_SOFTC_RSSI_DBM_COUNT; i++)
4470 rni->last_rssi_dbm[i] = rt2870_rssi2dbm(sc, rxwi->rssi[i], i);
4473 ieee80211_input(ic, m, ni, rssi_dbm, RT2870_NOISE_FLOOR, 0);
4475 ieee80211_free_node(ni);
4479 * rt2870_tx_frame
4481 static int rt2870_tx_frame(struct rt2870_softc *sc,
4482 struct mbuf *m, struct ieee80211_node *ni, int qid)
4484 struct ieee80211com *ic;
4485 struct rt2870_softc_node *rni;
4486 struct rt2870_softc_tx_ring *ring;
4487 struct rt2870_softc_tx_data *data;
4488 struct rt2870_txinfo *txinfo;
4489 struct rt2870_txwi *txwi;
4490 struct ieee80211_frame *wh;
4491 struct ieee80211_tx_ampdu *tx_ampdu;
4492 struct rt2870_softc_tx_radiotap_header *tap;
4493 u_int hdrsize, hdrspace;
4494 uint8_t type, rate, bw, stbc, shortgi, mcs, pid, wcid, mpdu_density, bawin_size;
4495 uint16_t qos, len, dmalen, mpdu_len, dur;
4496 int hasqos, ac, ampdu, mimops, ackrate;
4498 ic = &sc->ic;
4499 rni = (struct rt2870_softc_node *) ni;
4501 ring = &sc->tx_ring[qid];
4502 data = STAILQ_FIRST(&ring->inactive);
4503 STAILQ_REMOVE_HEAD(&ring->inactive, next);
4504 txinfo = (struct rt2870_txinfo *) data->buf;
4505 txwi = (struct rt2870_txwi *) (txinfo + 1);
4507 wh = mtod(m, struct ieee80211_frame *);
4509 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
4511 hasqos = IEEE80211_QOS_HAS_SEQ(wh);
4512 if (hasqos)
4514 if (IEEE80211_HAS_ADDR4(wh))
4515 qos = le16toh(*(const uint16_t *)
4516 (((struct ieee80211_qosframe_addr4 *) wh)->i_qos));
4517 else
4518 qos = le16toh(*(const uint16_t *)
4519 (((struct ieee80211_qosframe *) wh)->i_qos));
4521 else
4523 qos = 0;
4526 if (ni->ni_flags & IEEE80211_NODE_HT)
4528 if (IEEE80211_IS_MULTICAST(wh->i_addr1) || type != IEEE80211_FC0_TYPE_DATA)
4529 rate = 0;
4530 else if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
4531 rate = ic->ic_fixed_rate;
4532 else
4533 rate = ni->ni_htrates.rs_rates[ni->ni_txrate];
4535 else
4537 if (IEEE80211_IS_MULTICAST(wh->i_addr1) || type != IEEE80211_FC0_TYPE_DATA)
4538 rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
4539 else if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
4540 rate = ic->ic_fixed_rate;
4541 else
4542 rate = ni->ni_rates.rs_rates[ni->ni_txrate];
4545 rate &= IEEE80211_RATE_VAL;
4547 len = sizeof(struct rt2870_txinfo) + sizeof(struct rt2870_txwi) + m->m_pkthdr.len;
4549 /* align end on a 4-bytes boundary */
4551 dmalen = (len + 3) & ~3;
4553 /* fill Tx info */
4555 memset(txinfo, 0, sizeof(struct rt2870_txinfo));
4557 txinfo->len = htole16(dmalen);
4559 txinfo->qsel_flags = (RT2870_TXINFO_QSEL_EDCA << RT2870_TXINFO_QSEL_SHIFT);
4561 /* fill Tx wireless info */
4563 if (ni->ni_flags & IEEE80211_NODE_HT)
4564 mcs = rate;
4565 else
4566 mcs = rt2870_rate2mcs(rate);
4568 if (type == IEEE80211_FC0_TYPE_DATA)
4569 wcid = !IEEE80211_IS_MULTICAST(wh->i_addr1) ? rni->staid : RT2870_WCID_MCAST;
4570 else
4571 wcid = RT2870_WCID_RESERVED;
4573 /* calculate MPDU length without padding */
4575 hdrsize = ieee80211_anyhdrsize(wh);
4576 hdrspace = ieee80211_anyhdrspace(ic, wh);
4577 mpdu_len = m->m_pkthdr.len - hdrspace + hdrsize;
4579 memset(txwi, 0, sizeof(struct rt2870_txwi));
4581 txwi->wcid = wcid;
4583 /* MIMO power save */
4585 if ((ni->ni_flags & IEEE80211_NODE_HT) &&
4586 ((ni->ni_htcap & IEEE80211_HTCAP_SMPS) != IEEE80211_HTCAP_SMPS_OFF))
4588 if (mcs > 7)
4590 if ((ni->ni_htcap & IEEE80211_HTCAP_SMPS) == IEEE80211_HTCAP_SMPS_DYNAMIC)
4592 /* dynamic MIMO power save */
4594 txwi->mpdu_density_flags |=
4595 (RT2870_TXWI_FLAGS_MIMOPS << RT2870_TXWI_FLAGS_SHIFT);
4597 else
4599 /* static MIMO power save */
4601 mcs = 7;
4605 mimops = 1;
4607 else
4609 mimops = 0;
4612 pid = (mcs < 0xf) ? (mcs + 1) : mcs;
4614 txwi->pid_mpdu_len = ((htole16(pid) & RT2870_TXWI_PID_MASK) <<
4615 RT2870_TXWI_PID_SHIFT) | ((htole16(mpdu_len) & RT2870_TXWI_MPDU_LEN_MASK) <<
4616 RT2870_TXWI_MPDU_LEN_SHIFT);
4618 stbc = sc->tx_stbc && (mcs <= 7) && (ic->ic_htcaps & IEEE80211_HTCAP_TXSTBC) &&
4619 (ni->ni_flags & IEEE80211_NODE_HT) && (ni->ni_htcap & IEEE80211_HTCAP_RXSTBC);
4621 shortgi = (ic->ic_flags_ext & (IEEE80211_FEXT_SHORTGI20 | IEEE80211_FEXT_SHORTGI40)) &&
4622 (ni->ni_flags & IEEE80211_NODE_HT) && (ni->ni_htcap & (IEEE80211_HTCAP_SHORTGI20 | IEEE80211_HTCAP_SHORTGI40));
4624 txwi->phymode_ifs_stbc_shortgi |=
4625 ((stbc & RT2870_TXWI_STBC_MASK) << RT2870_TXWI_STBC_SHIFT) |
4626 ((shortgi & RT2870_TXWI_SHORTGI_MASK) << RT2870_TXWI_SHORTGI_SHIFT);
4628 if (ni->ni_flags & IEEE80211_NODE_HT)
4630 txwi->phymode_ifs_stbc_shortgi |=
4631 (RT2870_TXWI_PHYMODE_HT_MIXED << RT2870_TXWI_PHYMODE_SHIFT);
4633 else
4635 if (!RT2870_RATE_IS_OFDM(rate))
4637 txwi->phymode_ifs_stbc_shortgi |=
4638 (RT2870_TXWI_PHYMODE_CCK << RT2870_TXWI_PHYMODE_SHIFT);
4640 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
4641 mcs |= RT2870_TXWI_MCS_SHOTPRE;
4643 else
4645 txwi->phymode_ifs_stbc_shortgi |=
4646 (RT2870_TXWI_PHYMODE_OFDM << RT2870_TXWI_PHYMODE_SHIFT);
4650 if ((ni->ni_flags & IEEE80211_NODE_HT) && (ni->ni_chw == 40))
4651 bw = RT2870_TXWI_BW_40;
4652 else
4653 bw = RT2870_TXWI_BW_20;
4655 txwi->bw_mcs = ((bw & RT2870_TXWI_BW_MASK) << RT2870_TXWI_BW_SHIFT) |
4656 ((mcs & RT2870_TXWI_MCS_MASK) << RT2870_TXWI_MCS_SHIFT);
4658 if (type != IEEE80211_FC0_TYPE_DATA)
4659 txwi->txop = (RT2870_TXWI_TXOP_BACKOFF << RT2870_TXWI_TXOP_SHIFT);
4660 else
4661 txwi->txop = (RT2870_TXWI_TXOP_HT << RT2870_TXWI_TXOP_SHIFT);
4663 /* skip ACKs for multicast frames */
4665 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
4666 (!hasqos || (qos & IEEE80211_QOS_ACKPOLICY) != IEEE80211_QOS_ACKPOLICY_NOACK))
4668 txwi->bawin_size_xflags |=
4669 (RT2870_TXWI_XFLAGS_ACK << RT2870_TXWI_XFLAGS_SHIFT);
4671 if (ni->ni_flags & IEEE80211_NODE_HT)
4673 /* preamble + plcp + signal extension + SIFS */
4675 dur = 16 + 4 + 6 + 10;
4677 else
4679 ackrate = rt2870_ackrate(ic, rate);
4681 dur = rt2870_txtime(RT2870_ACK_SIZE, ackrate, ic->ic_flags) +
4682 sc->sifs;
4685 *(uint16_t *) wh->i_dur = htole16(dur);
4688 /* check fo A-MPDU */
4690 if ((qos & IEEE80211_QOS_ACKPOLICY) == IEEE80211_QOS_ACKPOLICY_BA)
4692 ac = M_WME_GETAC(m);
4693 tx_ampdu = &ni->ni_tx_ampdu[ac];
4695 mpdu_density = RT2870_MS(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY);
4696 bawin_size = tx_ampdu->txa_wnd;
4698 txwi->mpdu_density_flags |=
4699 ((mpdu_density & RT2870_TXWI_MPDU_DENSITY_MASK) << RT2870_TXWI_MPDU_DENSITY_SHIFT) |
4700 (RT2870_TXWI_FLAGS_AMPDU << RT2870_TXWI_FLAGS_SHIFT);
4702 txwi->bawin_size_xflags |=
4703 ((bawin_size & RT2870_TXWI_BAWIN_SIZE_MASK) << RT2870_TXWI_BAWIN_SIZE_SHIFT);
4705 if (IEEE80211_HAS_ADDR4(wh))
4706 ((struct ieee80211_qosframe_addr4 *) wh)->i_qos[0] &= ~IEEE80211_QOS_ACKPOLICY;
4707 else
4708 ((struct ieee80211_qosframe *) wh)->i_qos[0] &= ~IEEE80211_QOS_ACKPOLICY;
4710 ampdu = 1;
4712 else
4714 ampdu = 0;
4717 /* ask MAC to insert timestamp into probe responses */
4719 if ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
4720 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
4721 txwi->mpdu_density_flags |=
4722 (RT2870_TXWI_FLAGS_TS << RT2870_TXWI_FLAGS_SHIFT);
4724 if (bpf_peers_present(sc->drvbpf))
4726 tap = &sc->txtap;
4728 tap->flags = IEEE80211_RADIOTAP_F_DATAPAD;
4729 tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
4730 tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
4731 tap->chan_ieee = ic->ic_curchan->ic_ieee;
4732 tap->chan_maxpow = 0;
4734 if (ni->ni_flags & IEEE80211_NODE_HT)
4735 tap->rate = mcs | IEEE80211_RATE_MCS;
4736 else
4737 tap->rate = rate;
4739 if (mcs & RT2870_TXWI_MCS_SHOTPRE)
4740 tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
4742 if (shortgi)
4743 tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
4745 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4746 tap->flags |= IEEE80211_RADIOTAP_F_WEP;
4748 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4750 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
4752 bpf_mtap2(sc->drvbpf, tap, sc->txtap_len, m);
4754 wh->i_fc[1] |= IEEE80211_FC1_WEP;
4756 else
4758 bpf_mtap2(sc->drvbpf, tap, sc->txtap_len, m);
4762 m_copydata(m, 0, m->m_pkthdr.len, (caddr_t) (txwi + 1));
4764 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4765 "%s: sending frame: qid=%d, hdrsize=%d, hdrspace=%d, len=%d, "
4766 "bw=%d, stbc=%d, shortgi=%d, mcs=%d, wcid=0x%02x, ampdu=%d, mimops=%d, DMA len=%d\n",
4767 device_get_nameunit(sc->dev),
4768 qid, hdrsize, hdrspace, m->m_pkthdr.len, bw, stbc, shortgi, mcs, wcid, ampdu, mimops, dmalen);
4770 data->m = m;
4771 data->ni = ni;
4773 STAILQ_INSERT_TAIL(&ring->active, data, next);
4774 ring->queued++;
4776 usbd_setup_xfer(data->xfer, ring->usb_pipe, ring, data->buf, len,
4777 USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RT2870_USB_XFER_TIMEOUT, rt2870_tx_intr);
4779 usbd_transfer(data->xfer);
4781 return 0;
4785 * rt2870_tx_raw
4787 static int rt2870_tx_raw(struct rt2870_softc *sc,
4788 struct mbuf *m, struct ieee80211_node *ni,
4789 const struct ieee80211_bpf_params *params)
4791 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4792 "%s: Tx raw\n",
4793 device_get_nameunit(sc->dev));
4795 return 0;
4799 * rt2870_rx_intr
4801 static void rt2870_rx_intr(usbd_xfer_handle xfer,
4802 usbd_private_handle priv, usbd_status status)
4804 struct rt2870_softc *sc;
4805 struct ifnet *ifp;
4806 struct rt2870_softc_rx_ring *ring;
4807 struct rt2870_softc_rx_data *data;
4808 int len;
4810 sc = priv;
4811 ifp = sc->ifp;
4812 ring = &sc->rx_ring;
4814 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
4815 return;
4817 RT2870_DPRINTF(sc, RT2870_DEBUG_INTR,
4818 "%s: Rx interrupt: %s\n",
4819 device_get_nameunit(sc->dev), usbd_errstr(status));
4821 sc->interrupts++;
4822 sc->rx_interrupts++;
4824 switch (status)
4826 case USBD_NORMAL_COMPLETION:
4827 data = STAILQ_FIRST(&ring->active);
4828 if (data == NULL)
4829 break;
4831 STAILQ_REMOVE_HEAD(&ring->active, next);
4833 KASSERT(data->xfer == xfer,
4834 ("%s: Rx interrupt: invalid USB xfer\n",
4835 device_get_nameunit(sc->dev)));
4837 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
4839 data->len = len;
4841 STAILQ_INSERT_TAIL(&ring->done, data, next);
4843 taskqueue_enqueue(sc->taskqueue, &sc->rx_done_task);
4844 break;
4846 case USBD_CANCELLED:
4847 case USBD_NOT_STARTED:
4848 break;
4850 default:
4851 if (status == USBD_STALLED)
4852 usbd_clear_endpoint_stall_async(ring->usb_pipe);
4854 data = STAILQ_FIRST(&ring->active);
4855 if (data != NULL)
4857 STAILQ_REMOVE_HEAD(&ring->active, next);
4859 STAILQ_INSERT_TAIL(&ring->active, data, next);
4861 usbd_setup_xfer(xfer, ring->usb_pipe, sc, data->buf,
4862 RT2870_USB_RX_BULK_BUFLEN, USBD_SHORT_XFER_OK | USBD_NO_COPY,
4863 USBD_NO_TIMEOUT, rt2870_rx_intr);
4865 usbd_transfer(xfer);
4867 break;
4872 * rt2870_tx_intr
4874 static void rt2870_tx_intr(usbd_xfer_handle xfer,
4875 usbd_private_handle priv, usbd_status status)
4877 struct rt2870_softc *sc;
4878 struct ifnet *ifp;
4879 struct rt2870_softc_tx_ring *ring;
4880 struct rt2870_softc_tx_data *data;
4882 ring = priv;
4883 sc = ring->sc;
4884 ifp = sc->ifp;
4886 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
4887 return;
4889 RT2870_DPRINTF(sc, RT2870_DEBUG_INTR,
4890 "%s: Tx interrupt: %s\n",
4891 device_get_nameunit(sc->dev), usbd_errstr(status));
4893 sc->interrupts++;
4894 sc->tx_interrupts[ring->qid]++;
4896 switch (status)
4898 case USBD_NORMAL_COMPLETION:
4899 data = STAILQ_FIRST(&ring->active);
4900 if (data == NULL)
4901 break;
4903 STAILQ_REMOVE_HEAD(&ring->active, next);
4905 STAILQ_INSERT_TAIL(&ring->done, data, next);
4907 sc->tx_qid_pending_mask |= (1 << ring->qid);
4909 taskqueue_enqueue(sc->taskqueue, &sc->tx_done_task);
4910 break;
4912 case USBD_CANCELLED:
4913 case USBD_NOT_STARTED:
4914 break;
4916 default:
4917 data = STAILQ_FIRST(&ring->active);
4918 if (data != NULL)
4920 STAILQ_REMOVE_HEAD(&ring->active, next);
4922 if (data->m != NULL)
4924 m_freem(data->m);
4925 data->m = NULL;
4928 if (data->ni != NULL)
4930 ieee80211_free_node(data->ni);
4931 data->ni = NULL;
4934 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
4936 ring->queued--;
4939 printf("%s: could not transmit buffer: qid=%d, status=%s\n",
4940 device_get_nameunit(sc->dev), ring->qid, usbd_errstr(status));
4942 ifp->if_oerrors++;
4943 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4945 if (status == USBD_STALLED)
4946 usbd_clear_endpoint_stall_async(ring->usb_pipe);
4947 break;
4952 * rt2870_rx_done_task
4954 static void rt2870_rx_done_task(void *context, int pending)
4956 struct rt2870_softc *sc;
4957 struct ifnet *ifp;
4959 sc = context;
4960 ifp = sc->ifp;
4962 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4963 "%s: Rx done task\n",
4964 device_get_nameunit(sc->dev));
4966 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
4967 return;
4969 if (rt2870_rx_eof(sc, sc->rx_process_limit) != 0)
4971 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4972 "%s: Rx done task: scheduling again\n",
4973 device_get_nameunit(sc->dev));
4975 taskqueue_enqueue(sc->taskqueue, &sc->rx_done_task);
4980 * rt2870_tx_done_task
4982 static void rt2870_tx_done_task(void *context, int pending)
4984 struct rt2870_softc *sc;
4985 struct ifnet *ifp;
4986 int i;
4988 sc = context;
4989 ifp = sc->ifp;
4991 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4992 "%s: Tx done task\n",
4993 device_get_nameunit(sc->dev));
4995 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
4996 return;
4998 for (i = sc->usb_endpoints - 2; i >= 0; i--)
5000 if (sc->tx_qid_pending_mask & (1 << i))
5002 sc->tx_qid_pending_mask &= ~(1 << i);
5004 rt2870_tx_eof(sc, &sc->tx_ring[i]);
5008 if (sc->tx_qid_pending_mask != 0)
5010 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
5011 "%s: Tx done task: scheduling again\n",
5012 device_get_nameunit(sc->dev));
5014 taskqueue_enqueue(sc->taskqueue, &sc->tx_done_task);
5017 sc->tx_timer = 0;
5019 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
5023 * rt2870_periodic_task
5025 static void rt2870_periodic_task(void *context, int pending)
5027 struct rt2870_softc *sc;
5028 struct ifnet *ifp;
5029 struct ieee80211com *ic;
5031 sc = context;
5032 ifp = sc->ifp;
5033 ic = &sc->ic;
5035 RT2870_DPRINTF(sc, RT2870_DEBUG_PERIODIC,
5036 "%s: periodic task: round=%lu\n",
5037 device_get_nameunit(sc->dev), sc->periodic_round);
5039 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
5040 return;
5042 sc->periodic_round++;
5044 rt2870_update_stats(sc);
5046 if ((sc->periodic_round % 10) == 0)
5048 rt2870_bbp_tuning(sc);
5050 rt2870_update_raw_counters(sc);
5052 rt2870_watchdog(sc);
5054 if (ic->ic_opmode == IEEE80211_M_STA)
5055 rt2870_amrr_update_iter_func(sc, ic->ic_bss);
5056 else
5057 ieee80211_iterate_nodes(&ic->ic_sta, rt2870_amrr_update_iter_func, sc);
5060 callout_reset(&sc->periodic_ch, hz / 10, rt2870_periodic, sc);
5064 * rt2870_cmd_task
5066 static void rt2870_cmd_task(void *context, int pending)
5068 struct rt2870_softc *sc;
5069 struct rt2870_softc_cmd_ring *ring;
5070 struct rt2870_softc_cmd *cmd;
5072 sc = context;
5073 ring = &sc->cmd_ring;
5075 while (1)
5077 if (!(sc->flags & RT2870_SOFTC_FLAGS_VALID))
5078 break;
5080 RT2870_SOFTC_LOCK(sc);
5082 cmd = STAILQ_FIRST(&ring->active);
5083 if (cmd == NULL)
5085 RT2870_SOFTC_UNLOCK(sc);
5086 break;
5089 STAILQ_REMOVE_HEAD(&ring->active, next);
5091 RT2870_SOFTC_UNLOCK(sc);
5093 cmd->cb(sc, cmd->data);
5095 RT2870_SOFTC_LOCK(sc);
5097 STAILQ_INSERT_TAIL(&ring->inactive, cmd, next);
5098 ring->queued--;
5100 RT2870_SOFTC_UNLOCK(sc);
5105 * rt2870_rx_eof
5107 static int rt2870_rx_eof(struct rt2870_softc *sc, int limit)
5109 struct ifnet *ifp;
5110 struct rt2870_softc_rx_ring *ring;
5111 struct rt2870_softc_rx_data *data;
5112 uint32_t dmalen;
5113 uint8_t *buf;
5114 int nframes, len;
5116 ifp = sc->ifp;
5117 ring = &sc->rx_ring;
5119 nframes = 0;
5121 while (limit != 0)
5123 RT2870_SOFTC_LOCK(sc);
5125 data = STAILQ_FIRST(&ring->done);
5126 if (data == NULL)
5128 RT2870_SOFTC_UNLOCK(sc);
5129 break;
5132 STAILQ_REMOVE_HEAD(&ring->done, next);
5134 RT2870_SOFTC_UNLOCK(sc);
5136 buf = data->buf;
5137 len = data->len;
5139 if (len < RT2870_RX_DESC_SIZE)
5141 ifp->if_ierrors++;
5142 goto skip;
5145 while (len > (sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)))
5147 dmalen = (le32toh(*(uint32_t *) buf) & 0xffff);
5149 if (dmalen == 0 || (dmalen & 3) != 0)
5151 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
5152 "%s: bad DMA len=%u\n",
5153 device_get_nameunit(sc->dev), dmalen);
5154 goto skip;
5157 if ((dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)) > len)
5159 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
5160 "%s: bad DMA len: DMA len=%u, USB len=%d\n",
5161 device_get_nameunit(sc->dev),
5162 (unsigned int) (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)), len);
5163 goto skip;
5166 nframes++;
5168 rt2870_rx_frame(sc, buf + sizeof(uint32_t), dmalen);
5170 buf += (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo));
5171 len -= (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo));
5174 skip:
5176 RT2870_SOFTC_LOCK(sc);
5178 STAILQ_INSERT_TAIL(&ring->active, data, next);
5180 RT2870_SOFTC_UNLOCK(sc);
5182 usbd_setup_xfer(data->xfer, ring->usb_pipe, sc, data->buf,
5183 RT2870_USB_RX_BULK_BUFLEN, USBD_SHORT_XFER_OK | USBD_NO_COPY,
5184 USBD_NO_TIMEOUT, rt2870_rx_intr);
5186 usbd_transfer(data->xfer);
5188 limit--;
5191 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
5192 "%s: Rx eof: nframes=%d\n",
5193 device_get_nameunit(sc->dev), nframes);
5195 sc->rx_packets += nframes;
5197 return (limit == 0);
5201 * rt2870_tx_eof
5203 static void rt2870_tx_eof(struct rt2870_softc *sc,
5204 struct rt2870_softc_tx_ring *ring)
5206 struct ifnet *ifp;
5207 struct rt2870_softc_tx_data *data;
5208 int nframes;
5210 ifp = sc->ifp;
5212 nframes = 0;
5214 while (1)
5216 RT2870_SOFTC_LOCK(sc);
5218 data = STAILQ_FIRST(&ring->done);
5219 if (data == NULL)
5221 RT2870_SOFTC_UNLOCK(sc);
5222 break;
5225 STAILQ_REMOVE_HEAD(&ring->done, next);
5227 RT2870_SOFTC_UNLOCK(sc);
5229 rt2870_drain_fifo_stats(sc);
5231 nframes++;
5233 if (data->m->m_flags & M_TXCB)
5234 ieee80211_process_callback(data->ni, data->m, 0);
5236 m_freem(data->m);
5238 ieee80211_free_node(data->ni);
5240 data->m = NULL;
5241 data->ni = NULL;
5243 RT2870_SOFTC_LOCK(sc);
5245 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5247 ring->queued--;
5249 RT2870_SOFTC_UNLOCK(sc);
5251 ifp->if_opackets++;
5254 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
5255 "%s: Tx eof: qid=%d, nframes=%d\n",
5256 device_get_nameunit(sc->dev), ring->qid, nframes);
5260 * rt2870_update_stats
5262 static void rt2870_update_stats(struct rt2870_softc *sc)
5264 struct ifnet *ifp;
5265 struct ieee80211com *ic;
5266 uint32_t stacnt[3];
5267 int beacons, noretryok, retryok, failed, underflows, zerolen;
5269 ifp = sc->ifp;
5270 ic = &sc->ic;
5272 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
5273 "%s: update statistic\n",
5274 device_get_nameunit(sc->dev));
5276 rt2870_drain_fifo_stats(sc);
5278 /* read and clear Tx statistic registers */
5280 rt2870_io_mac_read_multi(sc, RT2870_REG_TX_STA_CNT0,
5281 stacnt, sizeof(stacnt));
5283 stacnt[0] = le32toh(stacnt[0]);
5284 stacnt[1] = le32toh(stacnt[1]);
5285 stacnt[2] = le32toh(stacnt[2]);
5287 beacons = stacnt[0] >> 16;
5288 noretryok = stacnt[1] & 0xffff;
5289 retryok = stacnt[1] >> 16;
5290 failed = stacnt[0] & 0xffff;
5291 underflows = stacnt[2] >> 16;
5292 zerolen = stacnt[2] & 0xffff;
5294 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
5295 "%s: update statistic: beacons=%d, noretryok=%d, retryok=%d, failed=%d, underflows=%d, zerolen=%d\n",
5296 device_get_nameunit(sc->dev),
5297 beacons, noretryok, retryok, failed, underflows, zerolen);
5299 ifp->if_oerrors += failed;
5301 sc->tx_beacons += beacons;
5302 sc->tx_noretryok += noretryok;
5303 sc->tx_retryok += retryok;
5304 sc->tx_failed += failed;
5305 sc->tx_underflows += underflows;
5306 sc->tx_zerolen += zerolen;
5310 * rt2870_bbp_tuning
5312 static void rt2870_bbp_tuning(struct rt2870_softc *sc)
5314 struct ieee80211com *ic;
5315 struct ieee80211_node *ni;
5316 int chan, group;
5317 int8_t rssi, old, new;
5319 /* RT2860C does not support BBP tuning */
5321 if (sc->mac_rev == 0x28600100)
5322 return;
5324 ic = &sc->ic;
5326 if ((ic->ic_flags & IEEE80211_F_SCAN) ||
5327 ic->ic_opmode != IEEE80211_M_STA || ic->ic_state != IEEE80211_S_RUN)
5328 return;
5330 ni = ic->ic_bss;
5332 chan = ieee80211_chan2ieee(ic, ni->ni_chan);
5334 if (chan <= 14)
5335 group = 0;
5336 else if (chan <= 64)
5337 group = 1;
5338 else if (chan <= 128)
5339 group = 2;
5340 else
5341 group = 3;
5343 rssi = ieee80211_getrssi(ic);
5345 if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
5347 new = 0x2e + sc->lna_gain[group];
5349 else
5351 if (!IEEE80211_IS_CHAN_HT40(ni->ni_chan))
5352 new = 0x32 + sc->lna_gain[group] * 5 / 3;
5353 else
5354 new = 0x3a + sc->lna_gain[group] * 5 / 3;
5357 /* Tune if absolute average RSSI is greater than -80 */
5359 if (rssi > -80)
5360 new += 0x10;
5362 old = rt2870_io_bbp_read(sc, 66);
5364 if (old != new)
5365 rt2870_io_bbp_write(sc, 66, new);
5369 * rt2870_watchdog
5371 static void rt2870_watchdog(struct rt2870_softc *sc)
5373 uint32_t tmp;
5374 int ntries;
5376 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
5378 RT2870_DPRINTF(sc, RT2870_DEBUG_WATCHDOG,
5379 "%s: watchdog: TXRXQ_PCNT=0x%08x\n",
5380 device_get_nameunit(sc->dev), tmp);
5382 if (((tmp >> RT2870_REG_TX0Q_PCNT_SHIFT) & RT2870_REG_TX0Q_PCNT_MASK) != 0)
5384 sc->tx_queue_not_empty[0]++;
5386 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40012);
5388 for (ntries = 0; ntries < 10; ntries++)
5390 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
5391 if (((tmp >> RT2870_REG_TX0Q_PCNT_SHIFT) & RT2870_REG_TX0Q_PCNT_MASK) == 0)
5392 break;
5394 DELAY(1);
5397 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40006);
5400 if (((tmp >> RT2870_REG_TX1Q_PCNT_SHIFT) & RT2870_REG_TX1Q_PCNT_MASK) != 0)
5402 sc->tx_queue_not_empty[1]++;
5404 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf4000a);
5406 for (ntries = 0; ntries < 10; ntries++)
5408 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
5409 if (((tmp >> RT2870_REG_TX1Q_PCNT_SHIFT) & RT2870_REG_TX1Q_PCNT_MASK) == 0)
5410 break;
5412 DELAY(1);
5415 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40006);
5420 * rt2870_drain_fifo_stats
5422 static void rt2870_drain_fifo_stats(struct rt2870_softc *sc)
5424 struct ifnet *ifp;
5425 uint32_t stats;
5426 uint8_t wcid, mcs, pid;
5427 int ok, agg, retrycnt;
5429 ifp = sc->ic.ic_ifp;
5431 /* drain Tx status FIFO (maxsize = 16) */
5433 while ((sc->flags & RT2870_SOFTC_FLAGS_VALID) &&
5434 (stats = rt2870_io_mac_read(sc, RT2870_REG_TX_STA_FIFO)) &
5435 RT2870_REG_TX_STA_FIFO_VALID)
5437 wcid = (stats >> RT2870_REG_TX_STA_FIFO_WCID_SHIFT) &
5438 RT2870_REG_TX_STA_FIFO_WCID_MASK;
5440 /* if no ACK was requested, no feedback is available */
5442 if (!(stats & RT2870_REG_TX_STA_FIFO_ACK_REQ) || wcid == 0xff)
5443 continue;
5445 /* update AMRR statistic */
5447 ok = (stats & RT2870_REG_TX_STA_FIFO_TX_OK) ? 1 : 0;
5448 agg = (stats & RT2870_REG_TX_STA_FIFO_AGG) ? 1 : 0;
5449 mcs = (stats >> RT2870_REG_TX_STA_FIFO_MCS_SHIFT) &
5450 RT2870_REG_TX_STA_FIFO_MCS_MASK;
5451 pid = (stats >> RT2870_REG_TX_STA_FIFO_PID_SHIFT) &
5452 RT2870_REG_TX_STA_FIFO_PID_MASK;
5453 retrycnt = (mcs < 0xf) ? (pid - mcs - 1) : 0;
5455 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
5456 "%s: FIFO statistic: wcid=0x%02x, ok=%d, agg=%d, mcs=0x%02x, pid=0x%02x, retrycnt=%d\n",
5457 device_get_nameunit(sc->dev),
5458 wcid, ok, agg, mcs, pid, retrycnt);
5460 rt2870_amrr_tx_complete(&sc->amrr_node[wcid], ok, retrycnt);
5462 if (!ok)
5463 ifp->if_oerrors++;
5468 * rt2870_update_raw_counters
5470 static void rt2870_update_raw_counters(struct rt2870_softc *sc)
5472 uint32_t tmp;
5474 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT);
5476 sc->tx_nonagg += tmp & 0xffff;
5477 sc->tx_agg += tmp >> 16;
5479 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT0);
5481 sc->tx_ampdu += (tmp & 0xffff) / 1 + (tmp >> 16) / 2;
5483 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT1);
5485 sc->tx_ampdu += (tmp & 0xffff) / 3 + (tmp >> 16) / 4;
5487 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT2);
5489 sc->tx_ampdu += (tmp & 0xffff) / 5 + (tmp >> 16) / 6;
5491 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT3);
5493 sc->tx_ampdu += (tmp & 0xffff) / 7 + (tmp >> 16) / 8;
5495 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT4);
5497 sc->tx_ampdu += (tmp & 0xffff) / 9 + (tmp >> 16) / 10;
5499 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT5);
5501 sc->tx_ampdu += (tmp & 0xffff) / 11 + (tmp >> 16) / 12;
5503 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT6);
5505 sc->tx_ampdu += (tmp & 0xffff) / 13 + (tmp >> 16) / 14;
5507 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_AGG_CNT7);
5509 sc->tx_ampdu += (tmp & 0xffff) / 15 + (tmp >> 16) / 16;
5511 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT0);
5513 sc->rx_crc_errors += tmp & 0xffff;
5514 sc->rx_phy_errors += tmp >> 16;
5516 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT1);
5518 sc->rx_false_ccas += tmp & 0xffff;
5519 sc->rx_plcp_errors += tmp >> 16;
5521 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT2);
5523 sc->rx_dup_packets += tmp & 0xffff;
5524 sc->rx_fifo_overflows += tmp >> 16;
5526 tmp = rt2870_io_mac_read(sc, RT2870_REG_TXRX_MPDU_DEN_CNT);
5528 sc->tx_mpdu_zero_density += tmp & 0xffff;
5529 sc->rx_mpdu_zero_density += tmp >> 16;
5533 * rt2870_alloc_rx_ring
5535 static int rt2870_alloc_rx_ring(struct rt2870_softc *sc,
5536 struct rt2870_softc_rx_ring *ring)
5538 struct rt2870_softc_rx_data *data;
5539 int i, error;
5541 STAILQ_INIT(&ring->active);
5542 STAILQ_INIT(&ring->done);
5544 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
5546 data = &ring->data[i];
5548 data->xfer = usbd_alloc_xfer(sc->usb_dev);
5549 if (data->xfer == NULL)
5551 printf("%s: could not allocate Rx xfer\n",
5552 device_get_nameunit(sc->dev));
5553 error = ENOMEM;
5554 goto fail;
5557 data->buf = usbd_alloc_buffer(data->xfer, RT2870_USB_RX_BULK_BUFLEN);
5558 if (data->buf == NULL)
5560 printf("%s: could not allocate Rx buffer\n",
5561 device_get_nameunit(sc->dev));
5562 error = ENOMEM;
5563 goto fail;
5567 return 0;
5569 fail:
5571 rt2870_free_rx_ring(sc, ring);
5573 return error;
5577 * rt2870_reset_rx_ring
5579 static void rt2870_reset_rx_ring(struct rt2870_softc *sc,
5580 struct rt2870_softc_rx_ring *ring)
5582 STAILQ_INIT(&ring->active);
5583 STAILQ_INIT(&ring->done);
5587 * rt2870_free_rx_ring
5589 static void rt2870_free_rx_ring(struct rt2870_softc *sc,
5590 struct rt2870_softc_rx_ring *ring)
5592 struct rt2870_softc_rx_data *data;
5593 int i;
5595 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
5597 data = &ring->data[i];
5599 if ((data->buf != NULL) && (data->xfer != NULL))
5601 usbd_free_buffer(data->xfer);
5602 data->buf = NULL;
5605 if (data->xfer != NULL)
5607 usbd_free_xfer(data->xfer);
5608 data->xfer = NULL;
5614 * rt2870_alloc_tx_ring
5616 static int rt2870_alloc_tx_ring(struct rt2870_softc *sc,
5617 struct rt2870_softc_tx_ring *ring, int qid)
5619 struct rt2870_softc_tx_data *data;
5620 int i, error;
5622 STAILQ_INIT(&ring->inactive);
5623 STAILQ_INIT(&ring->active);
5624 STAILQ_INIT(&ring->done);
5626 ring->sc = sc;
5627 ring->queued = 0;
5628 ring->qid = qid;
5630 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
5632 data = &ring->data[i];
5634 data->xfer = usbd_alloc_xfer(sc->usb_dev);
5635 if (data->xfer == NULL)
5637 printf("%s: could not allocate Tx xfer\n",
5638 device_get_nameunit(sc->dev));
5639 error = ENOMEM;
5640 goto fail;
5643 data->buf = usbd_alloc_buffer(data->xfer,
5644 RT2870_TX_DESC_SIZE + MJUMPAGESIZE);
5645 if (data->buf == NULL)
5647 printf("%s: could not allocate Tx buffer\n",
5648 device_get_nameunit(sc->dev));
5649 error = ENOMEM;
5650 goto fail;
5653 memset(data->buf, 0, RT2870_TX_DESC_SIZE);
5655 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5658 return 0;
5660 fail:
5662 rt2870_free_tx_ring(sc, ring);
5664 return error;
5668 * rt2870_reset_tx_ring
5670 static void rt2870_reset_tx_ring(struct rt2870_softc *sc,
5671 struct rt2870_softc_tx_ring *ring)
5673 struct rt2870_softc_tx_data *data;
5674 int i;
5676 STAILQ_INIT(&ring->inactive);
5677 STAILQ_INIT(&ring->active);
5678 STAILQ_INIT(&ring->done);
5680 ring->queued = 0;
5682 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
5684 data = &ring->data[i];
5686 if (data->m != NULL)
5688 m_free(data->m);
5689 data->m = NULL;
5692 if (data->ni != NULL)
5694 ieee80211_free_node(data->ni);
5695 data->ni = NULL;
5698 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5703 * rt2870_free_tx_ring
5705 static void rt2870_free_tx_ring(struct rt2870_softc *sc,
5706 struct rt2870_softc_tx_ring *ring)
5708 struct rt2870_softc_tx_data *data;
5709 int i;
5711 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
5713 data = &ring->data[i];
5715 if (data->xfer != NULL)
5717 usbd_free_xfer(data->xfer);
5718 data->xfer = NULL;
5721 if (data->m != NULL)
5723 m_free(data->m);
5724 data->m = NULL;
5727 if (data->ni != NULL)
5729 ieee80211_free_node(data->ni);
5730 data->ni = NULL;
5736 * rt2870_reset_cmd_ring
5738 static void rt2870_reset_cmd_ring(struct rt2870_softc *sc,
5739 struct rt2870_softc_cmd_ring *ring)
5741 struct rt2870_softc_cmd *cmd;
5742 int i;
5744 STAILQ_INIT(&ring->inactive);
5745 STAILQ_INIT(&ring->active);
5747 ring->queued = 0;
5749 for (i = 0; i < RT2870_SOFTC_CMD_RING_CMD_COUNT; i++)
5751 cmd = &ring->cmd[i];
5753 STAILQ_INSERT_TAIL(&ring->inactive, cmd, next);
5758 * rt2870_sysctl_attach
5760 static void rt2870_sysctl_attach(struct rt2870_softc *sc)
5762 struct sysctl_ctx_list *ctx;
5763 struct sysctl_oid *tree;
5764 struct sysctl_oid *stats;
5766 ctx = device_get_sysctl_ctx(sc->dev);
5767 tree = device_get_sysctl_tree(sc->dev);
5769 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
5770 "tx_stbc", CTLFLAG_RW, &sc->tx_stbc, 0,
5771 "Tx STBC");
5773 /* statistic counters */
5775 stats = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
5776 "stats", CTLFLAG_RD, 0, "statistic");
5778 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5779 "interrupts", CTLFLAG_RD, &sc->interrupts, 0,
5780 "all interrupts");
5782 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5783 "rx_interrupts", CTLFLAG_RD, &sc->rx_interrupts, 0,
5784 "Rx interrupts");
5786 if (sc->usb_endpoints == (RT2870_SOFTC_TX_RING_COUNT + 1))
5788 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5789 "tx_mgmt_interrupts", CTLFLAG_RD, &sc->tx_interrupts[5], 0,
5790 "Tx MGMT interrupts");
5792 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5793 "tx_hcca_interrupts", CTLFLAG_RD, &sc->tx_interrupts[4], 0,
5794 "Tx HCCA interrupts");
5797 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5798 "tx_ac3_interrupts", CTLFLAG_RD, &sc->tx_interrupts[3], 0,
5799 "Tx AC3 interrupts");
5801 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5802 "tx_ac2_interrupts", CTLFLAG_RD, &sc->tx_interrupts[2], 0,
5803 "Tx AC2 interrupts");
5805 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5806 "tx_ac1_interrupts", CTLFLAG_RD, &sc->tx_interrupts[1], 0,
5807 "Tx AC1 interrupts");
5809 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5810 "tx_ac0_interrupts", CTLFLAG_RD, &sc->tx_interrupts[0], 0,
5811 "Tx AC0 interrupts");
5813 if (sc->usb_endpoints == (RT2870_SOFTC_TX_RING_COUNT + 1))
5815 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5816 "tx_mgmt_data_queued", CTLFLAG_RD, &sc->tx_ring[5].queued, 0,
5817 "Tx MGMT data queued");
5819 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5820 "tx_hcca_data_queued", CTLFLAG_RD, &sc->tx_ring[4].queued, 0,
5821 "Tx HCCA data queued");
5824 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5825 "tx_ac3_data_queued", CTLFLAG_RD, &sc->tx_ring[3].queued, 0,
5826 "Tx AC3 data queued");
5828 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5829 "tx_ac2_data_queued", CTLFLAG_RD, &sc->tx_ring[2].queued, 0,
5830 "Tx AC2 data queued");
5832 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5833 "tx_ac1_data_queued", CTLFLAG_RD, &sc->tx_ring[1].queued, 0,
5834 "Tx AC1 data queued");
5836 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5837 "tx_ac0_data_queued", CTLFLAG_RD, &sc->tx_ring[0].queued, 0,
5838 "Tx AC0 data queued");
5840 if (sc->usb_endpoints == (RT2870_SOFTC_TX_RING_COUNT + 1))
5842 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5843 "tx_mgmt_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[5], 0,
5844 "Tx MGMT data queue full");
5846 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5847 "tx_hcca_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[4], 0,
5848 "Tx HCCA data queue full");
5851 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5852 "tx_ac3_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[3], 0,
5853 "Tx AC3 data queue full");
5855 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5856 "tx_ac2_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[2], 0,
5857 "Tx AC2 data queue full");
5859 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5860 "tx_ac1_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[1], 0,
5861 "Tx AC1 data queue full");
5863 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5864 "tx_ac0_data_queue_full", CTLFLAG_RD, &sc->tx_data_queue_full[0], 0,
5865 "Tx AC0 data queue full");
5867 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5868 "tx_watchdog_timeouts", CTLFLAG_RD, &sc->tx_watchdog_timeouts, 0,
5869 "Tx watchdog timeouts");
5871 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5872 "rx_mbuf_alloc_errors", CTLFLAG_RD, &sc->rx_mbuf_alloc_errors, 0,
5873 "Rx mbuf allocation errors");
5875 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5876 "tx_queue_0_not_empty", CTLFLAG_RD, &sc->tx_queue_not_empty[0], 0,
5877 "Tx queue 0 not empty");
5879 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5880 "tx_queue_1_not_empty", CTLFLAG_RD, &sc->tx_queue_not_empty[1], 0,
5881 "Tx queue 1 not empty");
5883 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5884 "tx_beacons", CTLFLAG_RD, &sc->tx_beacons, 0,
5885 "Tx beacons");
5887 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5888 "tx_noretryok", CTLFLAG_RD, &sc->tx_noretryok, 0,
5889 "Tx successfull without retries");
5891 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5892 "tx_retryok", CTLFLAG_RD, &sc->tx_retryok, 0,
5893 "Tx successfull with retries");
5895 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5896 "tx_failed", CTLFLAG_RD, &sc->tx_failed, 0,
5897 "Tx failed");
5899 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5900 "tx_underflows", CTLFLAG_RD, &sc->tx_underflows, 0,
5901 "Tx underflows");
5903 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5904 "tx_zerolen", CTLFLAG_RD, &sc->tx_zerolen, 0,
5905 "Tx zero length");
5907 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5908 "tx_nonagg", CTLFLAG_RD, &sc->tx_nonagg, 0,
5909 "Tx non-aggregated");
5911 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5912 "tx_agg", CTLFLAG_RD, &sc->tx_agg, 0,
5913 "Tx aggregated");
5915 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5916 "tx_ampdu", CTLFLAG_RD, &sc->tx_ampdu, 0,
5917 "Tx A-MPDU");
5919 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5920 "tx_mpdu_zero_density", CTLFLAG_RD, &sc->tx_mpdu_zero_density, 0,
5921 "Tx MPDU with zero density");
5923 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5924 "tx_ampdu_sessions", CTLFLAG_RD, &sc->tx_ampdu_sessions, 0,
5925 "Tx A-MPDU sessions");
5927 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5928 "rx_packets", CTLFLAG_RD, &sc->rx_packets, 0,
5929 "Rx packets");
5931 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5932 "rx_ampdu", CTLFLAG_RD, &sc->rx_ampdu, 0,
5933 "Rx A-MPDU");
5935 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5936 "rx_mpdu_zero_density", CTLFLAG_RD, &sc->rx_mpdu_zero_density, 0,
5937 "Rx MPDU with zero density");
5939 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5940 "rx_ampdu_sessions", CTLFLAG_RD, &sc->rx_ampdu_sessions, 0,
5941 "Rx A-MPDU sessions");
5943 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5944 "rx_amsdu", CTLFLAG_RD, &sc->rx_amsdu, 0,
5945 "Rx A-MSDU");
5947 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5948 "rx_crc_errors", CTLFLAG_RD, &sc->rx_crc_errors, 0,
5949 "Rx CRC errors");
5951 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5952 "rx_phy_errors", CTLFLAG_RD, &sc->rx_phy_errors, 0,
5953 "Rx PHY errors");
5955 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5956 "rx_false_ccas", CTLFLAG_RD, &sc->rx_false_ccas, 0,
5957 "Rx false CCAs");
5959 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5960 "rx_plcp_errors", CTLFLAG_RD, &sc->rx_plcp_errors, 0,
5961 "Rx PLCP errors");
5963 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5964 "rx_dup_packets", CTLFLAG_RD, &sc->rx_dup_packets, 0,
5965 "Rx duplicate packets");
5967 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5968 "rx_fifo_overflows", CTLFLAG_RD, &sc->rx_fifo_overflows, 0,
5969 "Rx FIFO overflows");
5971 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5972 "rx_cipher_no_errors", CTLFLAG_RD, &sc->rx_cipher_no_errors, 0,
5973 "Rx cipher no errors");
5975 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5976 "rx_cipher_icv_errors", CTLFLAG_RD, &sc->rx_cipher_icv_errors, 0,
5977 "Rx cipher ICV errors");
5979 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5980 "rx_cipher_mic_errors", CTLFLAG_RD, &sc->rx_cipher_mic_errors, 0,
5981 "Rx cipher MIC errors");
5983 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5984 "rx_cipher_invalid_key_errors", CTLFLAG_RD, &sc->rx_cipher_invalid_key_errors, 0,
5985 "Rx cipher invalid key errors");
5988 static device_method_t rt2870_dev_methods[] =
5990 DEVMETHOD(device_probe, rt2870_probe),
5991 DEVMETHOD(device_attach, rt2870_attach),
5992 DEVMETHOD(device_detach, rt2870_detach),
5993 { 0, 0 }
5996 static driver_t rt2870_driver =
5998 "rt2870",
5999 rt2870_dev_methods,
6000 sizeof(struct rt2870_softc),
6003 static devclass_t rt2870_dev_class;
6005 DRIVER_MODULE(rt2870, uhub, rt2870_driver, rt2870_dev_class,
6006 usbd_driver_load, 0);
6008 MODULE_DEPEND(rt2870, usb, 1, 1, 1);
6009 MODULE_DEPEND(rt2870, wlan, 1, 1, 1);