WCID table entries should be set to { 0xffffffff, 0x0000ffff } at initialization
[ralink_drivers/rt2870_fbsd8.git] / rt2870.c
blobf78dacba2e885bc98c3aab0cabc203aefb7282cf
2 /*-
3 * Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
4 * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include "rt2870_softc.h"
20 #include "rt2870_reg.h"
21 #include "rt2870_eeprom.h"
22 #include "rt2870_ucode.h"
23 #include "rt2870_rxwi.h"
24 #include "rt2870_rxinfo.h"
25 #include "rt2870_txinfo.h"
26 #include "rt2870_txwi.h"
27 #include "rt2870_read_eeprom.h"
28 #include "rt2870_io.h"
29 #include "rt2870_rf.h"
30 #include "rt2870_led.h"
31 #include "rt2870_debug.h"
34 * Defines and macros
37 #define USB_PRODUCT_LINKSYS4_WUSB600N 0x0071
38 #define USB_PRODUCT_DLINK2_DWA140 0x3c09
39 #define USB_PRODUCT_DLINK2_DWA160AREVB 0x3c11
40 #define USB_PRODUCT_ASUS_RT2770F 0x1742
41 #define USB_PRODUCT_RALINK_RT2770 0x2770
43 #define RT2870_USB_CONFIG_INDEX 0
44 #define RT2870_USB_IFACE_INDEX 0
46 #define RT2870_USB_REQ_MAC_READ_MULTI 0x07
48 /* packet length + Rx wireless info + Rx info */
49 #define RT2870_RX_DESC_SIZE \
50 (sizeof(uint32_t) + sizeof(struct rt2870_rxwi) + sizeof(struct rt2870_rxinfo))
52 /* Tx info + Tx wireless info + max padding */
53 #define RT2870_TX_DESC_SIZE \
54 (sizeof(struct rt2870_txinfo) + sizeof(struct rt2870_txwi) + 11)
56 #define RT2870_MAX_AGG_SIZE 3840
58 #define RT2870_USB_RX_BULK_BUFLEN (2048 * 12)
60 #define RT2870_NOISE_FLOOR -95
62 #define RT2870_AID2WCID(aid) ((aid) & 0xff)
64 #define RT2870_ACK_SIZE 14
66 #define IEEE80211_HAS_ADDR4(wh) \
67 (((wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
69 #define RT2870_MS(_v, _f) (((_v) & _f) >> _f##_S)
70 #define RT2870_SM(_v, _f) (((_v) << _f##_S) & _f)
72 #define RT2870_USB_XFER_TIMEOUT 5000
74 #define RT2870_TX_WATCHDOG_TIMEOUT 5
77 * Data structures and types
80 struct rt2870_cmd_argv_keydelete
82 struct ieee80211_key key;
83 uint16_t associd;
87 * Static function prototypes
90 static void rt2870_init_channels(struct rt2870_softc *sc);
92 static void rt2870_init_channels_ht40(struct rt2870_softc *sc);
94 static void rt2870_init_locked(void *priv);
96 static void rt2870_init(void *priv);
98 static int rt2870_init_bbp(struct rt2870_softc *sc);
100 static void rt2870_stop_locked(void *priv);
102 static void rt2870_stop(void *priv);
104 static void rt2870_start(struct ifnet *ifp);
106 static int rt2870_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
108 static struct ieee80211vap *rt2870_vap_create(struct ieee80211com *ic,
109 const char name[IFNAMSIZ], int unit, int opmode, int flags,
110 const uint8_t bssid[IEEE80211_ADDR_LEN],
111 const uint8_t mac[IEEE80211_ADDR_LEN]);
113 static void rt2870_vap_delete(struct ieee80211vap *vap);
115 static int rt2870_vap_reset(struct ieee80211vap *vap, u_long cmd);
117 static int rt2870_vap_newstate(struct ieee80211vap *vap,
118 enum ieee80211_state nstate, int arg);
120 static void rt2870_vap_key_update_begin(struct ieee80211vap *vap);
122 static void rt2870_vap_key_update_end(struct ieee80211vap *vap);
124 static int rt2870_vap_key_set(struct ieee80211vap *vap,
125 const struct ieee80211_key *k, const uint8_t mac[IEEE80211_ADDR_LEN]);
127 static int rt2870_vap_key_delete(struct ieee80211vap *vap,
128 const struct ieee80211_key *k);
130 static void rt2870_vap_update_beacon(struct ieee80211vap *vap, int what);
132 static struct ieee80211_node *rt2870_node_alloc(struct ieee80211vap *vap,
133 const uint8_t mac[IEEE80211_ADDR_LEN]);
135 static int rt2870_setregdomain(struct ieee80211com *ic,
136 struct ieee80211_regdomain *reg,
137 int nchans, struct ieee80211_channel chans[]);
139 static void rt2870_getradiocaps(struct ieee80211com *ic,
140 int maxchans, int *nchans, struct ieee80211_channel chans[]);
142 static void rt2870_scan_start(struct ieee80211com *ic);
144 static void rt2870_scan_end(struct ieee80211com *ic);
146 static void rt2870_set_channel(struct ieee80211com *ic);
148 static void rt2870_newassoc(struct ieee80211_node *ni, int isnew);
150 static void rt2870_updateslot(struct ifnet *ifp);
152 static void rt2870_update_promisc(struct ifnet *ifp);
154 static void rt2870_update_mcast(struct ifnet *ifp);
156 static int rt2870_wme_update(struct ieee80211com *ic);
158 static int rt2870_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
159 const struct ieee80211_bpf_params *params);
161 static int rt2870_recv_action(struct ieee80211_node *ni,
162 const struct ieee80211_frame *wh,
163 const uint8_t *frm, const uint8_t *efrm);
165 static int rt2870_send_action(struct ieee80211_node *ni,
166 int cat, int act, void *sa);
168 static void rt2870_amrr_update_iter_func(void *arg, struct ieee80211_node *ni);
170 static void rt2870_periodic(void *arg);
172 static void rt2870_tx_watchdog(void *arg);
174 static int rt2870_do_async(struct rt2870_softc *sc,
175 void (*cb)(struct rt2870_softc *sc, void *arg),
176 void *arg, int len);
178 static void rt2870_updateslot_cb(struct rt2870_softc *sc, void *arg);
180 static void rt2870_wme_update_cb(struct rt2870_softc *sc, void *arg);
182 static void rt2870_vap_key_delete_cb(struct rt2870_softc *sc, void *arg);
184 static void rt2870_vap_update_beacon_cb(struct rt2870_softc *sc, void *arg);
186 static void rt2870_asic_set_bssid(struct rt2870_softc *sc,
187 const uint8_t *bssid);
189 static void rt2870_asic_set_macaddr(struct rt2870_softc *sc,
190 const uint8_t *addr);
192 static void rt2870_asic_enable_tsf_sync(struct rt2870_softc *sc);
194 static void rt2870_asic_disable_tsf_sync(struct rt2870_softc *sc);
196 static void rt2870_asic_enable_mrr(struct rt2870_softc *sc);
198 static void rt2870_asic_set_txpreamble(struct rt2870_softc *sc);
200 static void rt2870_asic_set_basicrates(struct rt2870_softc *sc);
202 static void rt2870_asic_update_rtsthreshold(struct rt2870_softc *sc);
204 static void rt2870_asic_update_txpower(struct rt2870_softc *sc);
206 static void rt2870_asic_update_promisc(struct rt2870_softc *sc);
208 static void rt2870_asic_updateprot(struct rt2870_softc *sc);
210 static void rt2870_asic_updateslot(struct rt2870_softc *sc);
212 static void rt2870_asic_wme_update(struct rt2870_softc *sc);
214 static int rt2870_asic_update_beacon(struct rt2870_softc *sc,
215 struct ieee80211vap *vap);
217 static void rt2870_asic_clear_keytables(struct rt2870_softc *sc);
219 static uint8_t rt2870_rxrate(struct rt2870_rxwi *rxwi);
221 static uint8_t rt2870_maxrssi_rxpath(struct rt2870_softc *sc,
222 const struct rt2870_rxwi *rxwi);
224 static int8_t rt2870_rssi2dbm(struct rt2870_softc *sc,
225 uint8_t rssi, uint8_t rxpath);
227 static uint8_t rt2870_rate2mcs(uint8_t rate);
229 static void rt2870_rx_frame(struct rt2870_softc *sc,
230 uint8_t *buf, uint32_t dmalen);
232 static int rt2870_tx_mgmt(struct rt2870_softc *sc,
233 struct mbuf *m, struct ieee80211_node *ni, int qid);
235 static int rt2870_tx_data(struct rt2870_softc *sc,
236 struct mbuf *m, struct ieee80211_node *ni, int qid);
238 static int rt2870_tx_raw(struct rt2870_softc *sc,
239 struct mbuf *m, struct ieee80211_node *ni,
240 const struct ieee80211_bpf_params *params);
242 static void rt2870_rx_intr(struct usb_xfer *xfer, usb_error_t error);
244 static void rt2870_tx_intr(struct usb_xfer *xfer, usb_error_t error);
246 static void rt2870_rx_done_task(void *context, int pending);
248 static void rt2870_tx_done_task(void *context, int pending);
250 static void rt2870_periodic_task(void *context, int pending);
252 static void rt2870_cmd_task(void *context, int pending);
254 static int rt2870_rx_eof(struct rt2870_softc *sc, int limit);
256 static void rt2870_tx_eof(struct rt2870_softc *sc,
257 struct rt2870_softc_tx_ring *ring);
259 static void rt2870_update_stats(struct rt2870_softc *sc);
261 static void rt2870_watchdog(struct rt2870_softc *sc);
263 static void rt2870_drain_fifo_stats(struct rt2870_softc *sc);
265 static void rt2870_update_raw_counters(struct rt2870_softc *sc);
267 static int rt2870_txrx_enable(struct rt2870_softc *sc);
269 static int rt2870_alloc_rx_ring(struct rt2870_softc *sc,
270 struct rt2870_softc_rx_ring *ring);
272 static void rt2870_reset_rx_ring(struct rt2870_softc *sc,
273 struct rt2870_softc_rx_ring *ring);
275 static void rt2870_free_rx_ring(struct rt2870_softc *sc,
276 struct rt2870_softc_rx_ring *ring);
278 static int rt2870_alloc_tx_ring(struct rt2870_softc *sc,
279 struct rt2870_softc_tx_ring *ring, int qid);
281 static void rt2870_reset_tx_ring(struct rt2870_softc *sc,
282 struct rt2870_softc_tx_ring *ring);
284 static void rt2870_free_tx_ring(struct rt2870_softc *sc,
285 struct rt2870_softc_tx_ring *ring);
287 static void rt2870_reset_cmd_ring(struct rt2870_softc *sc,
288 struct rt2870_softc_cmd_ring *ring);
290 static void rt2870_sysctl_attach(struct rt2870_softc *sc);
293 * Static variables
296 static const struct usb_device_id rt2870_usb_devid[] =
298 { USB_VP(USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB600N) }, /* Linksys WUSB600N */
299 { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA140) }, /* D-Link DWA-140 */
300 { USB_VP(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160AREVB) }, /* D-Link DWA-160A Rev. B */
301 { USB_VP(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2770F) }, /* Asus RT2770F */
302 { USB_VP(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2770) }, /* Ralink RT2770 */
305 static const struct usb_config rt2870_usb_config[RT2870_SOFTC_USB_XFER_COUNT] =
308 .type = UE_BULK,
309 .endpoint = 0x01,
310 .direction = UE_DIR_IN,
311 .bufsize = RT2870_USB_RX_BULK_BUFLEN,
312 .flags = { .ext_buffer = 1, .pipe_bof = 1, .short_xfer_ok = 1, },
313 .callback = rt2870_rx_intr,
316 .type = UE_BULK,
317 .endpoint = 0x01,
318 .direction = UE_DIR_OUT,
319 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
320 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
321 .callback = rt2870_tx_intr,
322 .timeout = RT2870_USB_XFER_TIMEOUT,
325 .type = UE_BULK,
326 .endpoint = 0x02,
327 .direction = UE_DIR_OUT,
328 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
329 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
330 .callback = rt2870_tx_intr,
331 .timeout = RT2870_USB_XFER_TIMEOUT,
334 .type = UE_BULK,
335 .endpoint = 0x03,
336 .direction = UE_DIR_OUT,
337 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
338 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
339 .callback = rt2870_tx_intr,
340 .timeout = RT2870_USB_XFER_TIMEOUT,
343 .type = UE_BULK,
344 .endpoint = 0x04,
345 .direction = UE_DIR_OUT,
346 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
347 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
348 .callback = rt2870_tx_intr,
349 .timeout = RT2870_USB_XFER_TIMEOUT,
352 .type = UE_BULK,
353 .endpoint = 0x05,
354 .direction = UE_DIR_OUT,
355 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
356 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
357 .callback = rt2870_tx_intr,
358 .timeout = RT2870_USB_XFER_TIMEOUT,
361 .type = UE_BULK,
362 .endpoint = 0x06,
363 .direction = UE_DIR_OUT,
364 .bufsize = (RT2870_TX_DESC_SIZE + MJUMPAGESIZE),
365 .flags = { .ext_buffer = 1, .pipe_bof = 1, .force_short_xfer = 1, },
366 .callback = rt2870_tx_intr,
367 .timeout = RT2870_USB_XFER_TIMEOUT,
371 static const struct
373 uint32_t reg;
374 uint32_t val;
375 } rt2870_def_mac[] =
377 { RT2870_REG_PBF_BCN_OFFSET0, 0xf8f0e8e0 },
378 { RT2870_REG_PBF_BCN_OFFSET1, 0x6f77d0c8 },
379 { RT2870_REG_LEGACY_BASIC_RATE, 0x0000013f },
380 { RT2870_REG_HT_BASIC_RATE, 0x00008003 },
381 { RT2870_REG_SYS_CTRL, 0x00000000 },
382 { RT2870_REG_RX_FILTER_CFG, 0x00017f97 },
383 { RT2870_REG_BKOFF_SLOT_CFG, 0x00000209 },
384 { RT2870_REG_TX_SW_CFG0, 0x00000000 },
385 { RT2870_REG_TX_SW_CFG1, 0x00080606 },
386 { RT2870_REG_TX_LINK_CFG, 0x00001020 },
387 { RT2870_REG_TX_TIMEOUT_CFG, 0x000a2090 },
388 { RT2870_REG_MAX_LEN_CFG, (1 << 12) | RT2870_MAX_AGG_SIZE },
389 { RT2870_REG_LED_CFG, 0x7f031e46 },
390 { RT2870_REG_PBF_MAX_PCNT, 0x1f3fbf9f },
391 { RT2870_REG_TX_RTY_CFG, 0x47d01f0f },
392 { RT2870_REG_AUTO_RSP_CFG, 0x00000013 },
393 { RT2870_REG_TX_CCK_PROT_CFG, 0x05740003 },
394 { RT2870_REG_TX_OFDM_PROT_CFG, 0x05740003 },
395 { RT2870_REG_PBF_CFG, 0x00f40006 },
396 { RT2870_REG_TX_MM40_PROT_CFG, 0x03f44084 },
397 { RT2870_REG_SCHDMA_WPDMA_GLO_CFG, 0x00000030 },
398 { RT2870_REG_TX_GF20_PROT_CFG, 0x01744004 },
399 { RT2870_REG_TX_GF40_PROT_CFG, 0x03f44084 },
400 { RT2870_REG_TX_MM20_PROT_CFG, 0x01744004 },
401 { RT2870_REG_TX_TXOP_CTRL_CFG, 0x0000583f },
402 { RT2870_REG_TX_RTS_CFG, 0x00092b20 },
403 { RT2870_REG_TX_EXP_ACK_TIME, 0x002400ca },
404 { RT2870_REG_HCCAPSMP_TXOP_HLDR_ET, 0x00000002 },
405 { RT2870_REG_XIFS_TIME_CFG, 0x33a41010 },
406 { RT2870_REG_PWR_PIN_CFG, 0x00000003 },
407 { RT2870_REG_SCHDMA_WMM_AIFSN_CFG, 0x00002273 },
408 { RT2870_REG_SCHDMA_WMM_CWMIN_CFG, 0x00002344 },
409 { RT2870_REG_SCHDMA_WMM_CWMAX_CFG, 0x000034aa },
412 #define RT2870_DEF_MAC_SIZE (sizeof(rt2870_def_mac) / sizeof(rt2870_def_mac[0]))
414 static const struct
416 uint8_t reg;
417 uint8_t val;
418 } rt2870_def_bbp[] =
420 { 65, 0x2c },
421 { 66, 0x38 },
422 { 69, 0x12 },
423 { 70, 0x0a },
424 { 73, 0x10 },
425 { 81, 0x37 },
426 { 82, 0x62 },
427 { 83, 0x6a },
428 { 84, 0x99 },
429 { 86, 0x00 },
430 { 91, 0x04 },
431 { 92, 0x00 },
432 { 103, 0x00 },
433 { 105, 0x05 },
434 { 106, 0x35 },
437 #define RT2870_DEF_BBP_SIZE (sizeof(rt2870_def_bbp) / sizeof(rt2870_def_bbp[0]))
439 SYSCTL_NODE(_hw, OID_AUTO, rt2870, CTLFLAG_RD, 0, "RT2870 driver parameters");
441 #ifdef RT2870_DEBUG
442 static int rt2870_debug = 0;
443 SYSCTL_INT(_hw_rt2870, OID_AUTO, debug, CTLFLAG_RW, &rt2870_debug, 0, "rt2870 debug level");
444 TUNABLE_INT("hw.rt2870.debug", &rt2870_debug);
445 #endif
448 * rt2870_probe
450 static int rt2870_probe(device_t dev)
452 struct usb_attach_arg *uaa;
454 uaa = device_get_ivars(dev);
456 if (uaa->usb_mode != USB_MODE_HOST)
457 return ENXIO;
459 if (uaa->info.bConfigIndex != RT2870_USB_CONFIG_INDEX)
460 return ENXIO;
462 if (uaa->info.bIfaceIndex != RT2870_USB_IFACE_INDEX)
463 return ENXIO;
465 return (usbd_lookup_id_by_uaa(rt2870_usb_devid,
466 sizeof(rt2870_usb_devid), uaa));
470 * rt2870_attach
472 static int rt2870_attach(device_t dev)
474 struct rt2870_softc *sc;
475 struct usb_attach_arg *uaa;
476 usb_error_t usb_error;
477 struct ieee80211com *ic;
478 struct ifnet *ifp;
479 struct usb_interface *iface;
480 struct usb_interface_descriptor *iface_desc;
481 uint8_t iface_index;
482 int error, ntries, i;
484 sc = device_get_softc(dev);
485 uaa = device_get_ivars(dev);
487 sc->dev = dev;
488 sc->usb_dev = uaa->device;
490 device_set_usb_desc(dev);
492 #ifdef RT2870_DEBUG
493 sc->debug = rt2870_debug;
495 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
496 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
497 "debug", CTLFLAG_RW, &sc->debug, 0, "rt2870 debug level");
498 #endif
500 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
501 "%s: attaching\n",
502 device_get_nameunit(sc->dev));
504 iface_index = RT2870_USB_IFACE_INDEX;
506 iface = usbd_get_iface(uaa->device, iface_index);
507 if (iface == NULL)
509 printf("%s: could not get USB interface\n",
510 device_get_nameunit(sc->dev));
511 return ENXIO;
514 iface_desc = usbd_get_interface_descriptor(iface);
515 if (iface_desc == NULL)
517 printf("%s: could not get USB interface descriptor\n",
518 device_get_nameunit(sc->dev));
519 return ENXIO;
522 sc->usb_endpoints = iface_desc->bNumEndpoints;
523 if ((sc->usb_endpoints != RT2870_SOFTC_USB_XFER_COUNT) &&
524 (sc->usb_endpoints != RT2870_SOFTC_USB_XFER_COUNT - 2))
526 printf("%s: wrong number of USB endpoints=%d\n",
527 device_get_nameunit(sc->dev), sc->usb_endpoints);
528 return ENXIO;
531 mtx_init(&sc->lock, device_get_nameunit(dev),
532 MTX_NETWORK_LOCK, MTX_DEF);
534 usb_error = usbd_transfer_setup(uaa->device, &iface_index,
535 sc->usb_xfer, rt2870_usb_config, sc->usb_endpoints,
536 sc, &sc->lock);
537 if (usb_error != 0)
539 printf("%s: could not allocate USB transfers: error=%s\n",
540 device_get_nameunit(sc->dev), usbd_errstr(usb_error));
541 error = ENXIO;
542 goto fail;
545 RT2870_SOFTC_LOCK(sc);
547 for (ntries = 0; ntries < 100; ntries++)
549 sc->mac_rev = rt2870_io_mac_read(sc, RT2870_REG_MAC_CSR0);
550 if (sc->mac_rev != 0x00000000 && sc->mac_rev != 0xffffffff)
551 break;
553 DELAY(10);
556 if (ntries == 100)
558 printf("%s: timeout waiting for NIC to initialize\n",
559 device_get_nameunit(sc->dev));
560 error = ENXIO;
561 goto fail;
564 rt2870_read_eeprom(sc);
566 RT2870_SOFTC_UNLOCK(sc);
568 printf("%s: MAC/BBP RT2870 (rev 0x%08x), RF %s\n",
569 device_get_nameunit(sc->dev), sc->mac_rev,
570 rt2870_rf_name(sc->rf_rev));
572 /* allocate Tx and Rx rings */
574 for (i = 0; i < sc->usb_endpoints - 1; i++)
576 error = rt2870_alloc_tx_ring(sc, &sc->tx_ring[i], i);
577 if (error != 0)
579 printf("%s: could not allocate Tx ring #%d\n",
580 device_get_nameunit(sc->dev), i);
581 goto fail;
585 if (sc->usb_endpoints == RT2870_SOFTC_USB_XFER_COUNT)
586 sc->tx_ring_mgtqid = 5;
587 else
588 sc->tx_ring_mgtqid = 0;
590 error = rt2870_alloc_rx_ring(sc, &sc->rx_ring);
591 if (error != 0)
593 printf("%s: could not allocate Rx ring\n",
594 device_get_nameunit(sc->dev));
595 goto fail;
598 callout_init(&sc->periodic_ch, 0);
599 callout_init_mtx(&sc->tx_watchdog_ch, &sc->lock, 0);
601 ifp = sc->ifp = if_alloc(IFT_IEEE80211);
602 if (ifp == NULL)
604 printf("%s: could not if_alloc()\n",
605 device_get_nameunit(sc->dev));
606 error = ENOMEM;
607 goto fail;
610 ifp->if_softc = sc;
612 if_initname(ifp, "rt2870", device_get_unit(sc->dev));
614 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
616 ifp->if_init = rt2870_init;
617 ifp->if_ioctl = rt2870_ioctl;
618 ifp->if_start = rt2870_start;
620 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
621 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
622 IFQ_SET_READY(&ifp->if_snd);
624 ic = ifp->if_l2com;
626 ic->ic_ifp = ifp;
628 ic->ic_phytype = IEEE80211_T_HT;
629 ic->ic_opmode = IEEE80211_M_STA;
631 ic->ic_caps = IEEE80211_C_MONITOR |
632 IEEE80211_C_IBSS |
633 IEEE80211_C_STA |
634 IEEE80211_C_AHDEMO |
635 IEEE80211_C_HOSTAP |
636 IEEE80211_C_WDS |
637 IEEE80211_C_MBSS |
638 /* IEEE80211_C_BGSCAN | */
639 IEEE80211_C_TXPMGT |
640 IEEE80211_C_SHPREAMBLE |
641 IEEE80211_C_SHSLOT |
642 IEEE80211_C_TXFRAG |
643 IEEE80211_C_BURST |
644 IEEE80211_C_WME |
645 IEEE80211_C_WPA;
647 ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP |
648 IEEE80211_CRYPTO_TKIP |
649 IEEE80211_CRYPTO_TKIPMIC |
650 IEEE80211_CRYPTO_AES_CCM;
652 ic->ic_htcaps = IEEE80211_HTC_HT |
653 IEEE80211_HTC_AMSDU | /* A-MSDU Tx */
654 IEEE80211_HTCAP_MAXAMSDU_3839 | /* max. A-MSDU Rx length */
655 IEEE80211_HTCAP_CHWIDTH40 | /* HT 40MHz channel width */
656 IEEE80211_HTCAP_GREENFIELD | /* HT greenfield */
657 IEEE80211_HTCAP_SHORTGI20 | /* HT 20MHz short GI */
658 IEEE80211_HTCAP_SHORTGI40 | /* HT 40MHz short GI */
659 IEEE80211_HTCAP_DSSSCCK40; /* HT 40MHz DSSS/CCK modulation */
661 /* spatial streams */
663 if (sc->nrxpath == 2)
664 ic->ic_htcaps |= IEEE80211_HTCAP_RXSTBC_2STREAM;
665 else if (sc->nrxpath == 3)
666 ic->ic_htcaps |= IEEE80211_HTCAP_RXSTBC_3STREAM;
667 else
668 ic->ic_htcaps |= IEEE80211_HTCAP_RXSTBC_1STREAM;
670 if (sc->ntxpath > 1)
671 ic->ic_htcaps |= IEEE80211_HTCAP_TXSTBC;
673 /* delayed BA */
675 if (sc->mac_rev != 0x28600100)
676 ic->ic_htcaps |= IEEE80211_HTCAP_DELBA;
678 /* init channels */
680 ic->ic_nchans = 0;
682 rt2870_init_channels(sc);
684 rt2870_init_channels_ht40(sc);
686 ieee80211_ifattach(ic, sc->mac_addr);
688 ic->ic_vap_create = rt2870_vap_create;
689 ic->ic_vap_delete = rt2870_vap_delete;
691 ic->ic_node_alloc = rt2870_node_alloc;
692 ic->ic_setregdomain = rt2870_setregdomain;
693 ic->ic_getradiocaps = rt2870_getradiocaps;
694 ic->ic_scan_start = rt2870_scan_start;
695 ic->ic_scan_end = rt2870_scan_end;
696 ic->ic_set_channel = rt2870_set_channel;
697 ic->ic_newassoc = rt2870_newassoc;
698 ic->ic_updateslot = rt2870_updateslot;
699 ic->ic_update_promisc = rt2870_update_promisc;
700 ic->ic_update_mcast = rt2870_update_mcast;
701 ic->ic_wme.wme_update = rt2870_wme_update;
702 ic->ic_raw_xmit = rt2870_raw_xmit;
704 sc->recv_action = ic->ic_recv_action;
705 ic->ic_recv_action = rt2870_recv_action;
707 sc->send_action = ic->ic_send_action;
708 ic->ic_send_action = rt2870_send_action;
710 /* hardware requires padding between 802.11 frame header and body */
712 ic->ic_flags |= IEEE80211_F_DATAPAD | IEEE80211_F_DOTH;
714 ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;
716 ieee80211_radiotap_attach(ic,
717 &sc->txtap.ihdr, sizeof(sc->txtap),
718 RT2870_SOFTC_TX_RADIOTAP_PRESENT,
719 &sc->rxtap.ihdr, sizeof(sc->rxtap),
720 RT2870_SOFTC_RX_RADIOTAP_PRESENT);
722 /* init task queue */
724 TASK_INIT(&sc->rx_done_task, 0, rt2870_rx_done_task, sc);
725 TASK_INIT(&sc->tx_done_task, 0, rt2870_tx_done_task, sc);
726 TASK_INIT(&sc->periodic_task, 0, rt2870_periodic_task, sc);
727 TASK_INIT(&sc->cmd_task, 0, rt2870_cmd_task, sc);
729 sc->rx_process_limit = 100;
731 sc->taskqueue = taskqueue_create("rt2870_taskq", M_NOWAIT,
732 taskqueue_thread_enqueue, &sc->taskqueue);
734 taskqueue_start_threads(&sc->taskqueue, 1, PI_NET, "%s taskq",
735 device_get_nameunit(sc->dev));
737 rt2870_sysctl_attach(sc);
739 if (bootverbose)
740 ieee80211_announce(ic);
742 return 0;
744 fail:
746 /* stop all USB transfers */
748 usbd_transfer_unsetup(sc->usb_xfer, sc->usb_endpoints);
750 /* free Tx and Rx rings */
752 for (i = 0; i < sc->usb_endpoints - 1; i++)
753 rt2870_free_tx_ring(sc, &sc->tx_ring[i]);
755 rt2870_free_rx_ring(sc, &sc->rx_ring);
757 mtx_destroy(&sc->lock);
759 return error;
763 * rt2870_detach
765 static int rt2870_detach(device_t dev)
767 struct rt2870_softc *sc;
768 struct ieee80211com *ic;
769 struct ifnet *ifp;
770 int i;
772 if (!device_is_attached(dev))
773 return 0;
775 sc = device_get_softc(dev);
776 ifp = sc->ifp;
777 ic = ifp->if_l2com;
779 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
780 "%s: detaching\n",
781 device_get_nameunit(sc->dev));
783 RT2870_SOFTC_LOCK(sc);
785 sc->tx_timer = 0;
787 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
789 callout_stop(&sc->periodic_ch);
790 callout_stop(&sc->tx_watchdog_ch);
792 RT2870_SOFTC_UNLOCK(sc);
794 taskqueue_block(sc->taskqueue);
796 taskqueue_drain(sc->taskqueue, &sc->rx_done_task);
797 taskqueue_drain(sc->taskqueue, &sc->tx_done_task);
798 taskqueue_drain(sc->taskqueue, &sc->periodic_task);
799 taskqueue_drain(sc->taskqueue, &sc->cmd_task);
801 /* stop all USB transfers */
803 usbd_transfer_unsetup(sc->usb_xfer, sc->usb_endpoints);
805 RT2870_SOFTC_LOCK(sc);
807 /* free Tx and Rx rings */
809 for (i = 0; i < sc->usb_endpoints - 1; i++)
810 rt2870_free_tx_ring(sc, &sc->tx_ring[i]);
812 rt2870_free_rx_ring(sc, &sc->rx_ring);
814 RT2870_SOFTC_UNLOCK(sc);
816 ieee80211_ifdetach(ic);
818 if_free(ifp);
820 taskqueue_free(sc->taskqueue);
822 mtx_destroy(&sc->lock);
824 return 0;
828 * rt2870_init_channels
830 static void rt2870_init_channels(struct rt2870_softc *sc)
832 struct ifnet *ifp;
833 struct ieee80211com *ic;
834 struct ieee80211_channel *c;
835 int i, flags;
837 ifp = sc->ifp;
838 ic = ifp->if_l2com;
840 /* set supported channels for 2GHz band */
842 for (i = 1; i <= 14; i++)
844 c = &ic->ic_channels[ic->ic_nchans++];
845 flags = IEEE80211_CHAN_B;
847 c->ic_freq = ieee80211_ieee2mhz(i, flags);
848 c->ic_ieee = i;
849 c->ic_flags = flags;
851 c = &ic->ic_channels[ic->ic_nchans++];
852 flags = IEEE80211_CHAN_B | IEEE80211_CHAN_HT20;
854 c->ic_freq = ieee80211_ieee2mhz(i, flags);
855 c->ic_ieee = i;
856 c->ic_flags = flags;
858 c = &ic->ic_channels[ic->ic_nchans++];
859 flags = IEEE80211_CHAN_G;
861 c->ic_freq = ieee80211_ieee2mhz(i, flags);
862 c->ic_ieee = i;
863 c->ic_flags = flags;
865 c = &ic->ic_channels[ic->ic_nchans++];
866 flags = IEEE80211_CHAN_G | IEEE80211_CHAN_HT20;
868 c->ic_freq = ieee80211_ieee2mhz(i, flags);
869 c->ic_ieee = i;
870 c->ic_flags = flags;
873 /* set supported channels for 5GHz band */
875 if (sc->rf_rev == RT2870_EEPROM_RF_2850 ||
876 sc->rf_rev == RT2870_EEPROM_RF_2750)
878 for (i = 36; i <= 64; i += 4)
880 c = &ic->ic_channels[ic->ic_nchans++];
881 flags = IEEE80211_CHAN_A;
883 c->ic_freq = ieee80211_ieee2mhz(i, flags);
884 c->ic_ieee = i;
885 c->ic_flags = flags;
887 c = &ic->ic_channels[ic->ic_nchans++];
888 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
890 c->ic_freq = ieee80211_ieee2mhz(i, flags);
891 c->ic_ieee = i;
892 c->ic_flags = flags;
895 for (i = 100; i <= 140; i += 4)
897 c = &ic->ic_channels[ic->ic_nchans++];
898 flags = IEEE80211_CHAN_A;
900 c->ic_freq = ieee80211_ieee2mhz(i, flags);
901 c->ic_ieee = i;
902 c->ic_flags = flags;
904 c = &ic->ic_channels[ic->ic_nchans++];
905 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
907 c->ic_freq = ieee80211_ieee2mhz(i, flags);
908 c->ic_ieee = i;
909 c->ic_flags = flags;
912 for (i = 149; i <= 165; i += 4)
914 c = &ic->ic_channels[ic->ic_nchans++];
915 flags = IEEE80211_CHAN_A;
917 c->ic_freq = ieee80211_ieee2mhz(i, flags);
918 c->ic_ieee = i;
919 c->ic_flags = flags;
921 c = &ic->ic_channels[ic->ic_nchans++];
922 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20;
924 c->ic_freq = ieee80211_ieee2mhz(i, flags);
925 c->ic_ieee = i;
926 c->ic_flags = flags;
932 * rt2870_init_channels_ht40
934 static void rt2870_init_channels_ht40(struct rt2870_softc *sc)
936 struct ifnet *ifp;
937 struct ieee80211com *ic;
938 struct ieee80211_channel *c, *cent, *ext;
939 int i, flags;
941 ifp = sc->ifp;
942 ic = ifp->if_l2com;
944 /* set supported channels for 2GHz band */
946 for (i = 1; i <= 14; i++)
948 flags = IEEE80211_CHAN_G | IEEE80211_CHAN_HT40;
950 /* find the center channel */
952 cent = ieee80211_find_channel_byieee(ic, i,
953 flags & ~IEEE80211_CHAN_HT);
954 if (cent == NULL)
956 printf("%s: skip channel %d, could not find center channel\n",
957 device_get_nameunit(sc->dev), i);
958 continue;
961 /* find the extension channel */
963 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
964 flags & ~IEEE80211_CHAN_HT);
965 if (ext == NULL)
967 printf("%s: skip channel %d, could not find extension channel\n",
968 device_get_nameunit(sc->dev), i);
969 continue;
972 c = &ic->ic_channels[ic->ic_nchans++];
974 *c = *cent;
975 c->ic_extieee = ext->ic_ieee;
976 c->ic_flags &= ~IEEE80211_CHAN_HT;
977 c->ic_flags |= IEEE80211_CHAN_HT40U;
979 c = &ic->ic_channels[ic->ic_nchans++];
981 *c = *ext;
982 c->ic_extieee = cent->ic_ieee;
983 c->ic_flags &= ~IEEE80211_CHAN_HT;
984 c->ic_flags |= IEEE80211_CHAN_HT40D;
987 /* set supported channels for 5GHz band */
989 if (sc->rf_rev == RT2870_EEPROM_RF_2850 ||
990 sc->rf_rev == RT2870_EEPROM_RF_2750)
992 for (i = 36; i <= 64; i += 4)
994 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
996 /* find the center channel */
998 cent = ieee80211_find_channel_byieee(ic, i,
999 flags & ~IEEE80211_CHAN_HT);
1000 if (cent == NULL)
1002 printf("%s: skip channel %d, could not find center channel\n",
1003 device_get_nameunit(sc->dev), i);
1004 continue;
1007 /* find the extension channel */
1009 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1010 flags & ~IEEE80211_CHAN_HT);
1011 if (ext == NULL)
1013 printf("%s: skip channel %d, could not find extension channel\n",
1014 device_get_nameunit(sc->dev), i);
1015 continue;
1018 c = &ic->ic_channels[ic->ic_nchans++];
1020 *c = *cent;
1021 c->ic_extieee = ext->ic_ieee;
1022 c->ic_flags &= ~IEEE80211_CHAN_HT;
1023 c->ic_flags |= IEEE80211_CHAN_HT40U;
1025 c = &ic->ic_channels[ic->ic_nchans++];
1027 *c = *ext;
1028 c->ic_extieee = cent->ic_ieee;
1029 c->ic_flags &= ~IEEE80211_CHAN_HT;
1030 c->ic_flags |= IEEE80211_CHAN_HT40D;
1033 for (i = 100; i <= 140; i += 4)
1035 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
1037 /* find the center channel */
1039 cent = ieee80211_find_channel_byieee(ic, i,
1040 flags & ~IEEE80211_CHAN_HT);
1041 if (cent == NULL)
1043 printf("%s: skip channel %d, could not find center channel\n",
1044 device_get_nameunit(sc->dev), i);
1045 continue;
1048 /* find the extension channel */
1050 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1051 flags & ~IEEE80211_CHAN_HT);
1052 if (ext == NULL)
1054 printf("%s: skip channel %d, could not find extension channel\n",
1055 device_get_nameunit(sc->dev), i);
1056 continue;
1059 c = &ic->ic_channels[ic->ic_nchans++];
1061 *c = *cent;
1062 c->ic_extieee = ext->ic_ieee;
1063 c->ic_flags &= ~IEEE80211_CHAN_HT;
1064 c->ic_flags |= IEEE80211_CHAN_HT40U;
1066 c = &ic->ic_channels[ic->ic_nchans++];
1068 *c = *ext;
1069 c->ic_extieee = cent->ic_ieee;
1070 c->ic_flags &= ~IEEE80211_CHAN_HT;
1071 c->ic_flags |= IEEE80211_CHAN_HT40D;
1074 for (i = 149; i <= 165; i += 4)
1076 flags = IEEE80211_CHAN_A | IEEE80211_CHAN_HT40;
1078 /* find the center channel */
1080 cent = ieee80211_find_channel_byieee(ic, i,
1081 flags & ~IEEE80211_CHAN_HT);
1082 if (cent == NULL)
1084 printf("%s: skip channel %d, could not find center channel\n",
1085 device_get_nameunit(sc->dev), i);
1086 continue;
1089 /* find the extension channel */
1091 ext = ieee80211_find_channel(ic, cent->ic_freq + 20,
1092 flags & ~IEEE80211_CHAN_HT);
1093 if (ext == NULL)
1095 printf("%s: skip channel %d, could not find extension channel\n",
1096 device_get_nameunit(sc->dev), i);
1097 continue;
1100 c = &ic->ic_channels[ic->ic_nchans++];
1102 *c = *cent;
1103 c->ic_extieee = ext->ic_ieee;
1104 c->ic_flags &= ~IEEE80211_CHAN_HT;
1105 c->ic_flags |= IEEE80211_CHAN_HT40U;
1107 c = &ic->ic_channels[ic->ic_nchans++];
1109 *c = *ext;
1110 c->ic_extieee = cent->ic_ieee;
1111 c->ic_flags &= ~IEEE80211_CHAN_HT;
1112 c->ic_flags |= IEEE80211_CHAN_HT40D;
1118 * rt2870_init_locked
1120 static void rt2870_init_locked(void *priv)
1122 struct rt2870_softc *sc;
1123 struct ifnet *ifp;
1124 struct ieee80211com *ic;
1125 int ntries, error, i;
1126 uint32_t tmp, stacnt[6];
1128 sc = priv;
1129 ifp = sc->ifp;
1130 ic = ifp->if_l2com;
1132 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1133 "%s: initializing\n",
1134 device_get_nameunit(sc->dev));
1136 RT2870_SOFTC_ASSERT_LOCKED(sc);
1138 if (!(sc->flags & RT2870_SOFTC_FLAGS_UCODE_LOADED))
1140 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1141 "%s: loading 8051 microcode\n",
1142 device_get_nameunit(sc->dev));
1144 error = rt2870_io_mcu_load_ucode(sc, rt2870_ucode, sizeof(rt2870_ucode));
1145 if (error != 0)
1147 printf("%s: could not load 8051 microcode\n",
1148 device_get_nameunit(sc->dev));
1149 goto fail;
1152 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1153 "%s: 8051 microcode was successfully loaded\n",
1154 device_get_nameunit(sc->dev));
1156 sc->flags |= RT2870_SOFTC_FLAGS_UCODE_LOADED;
1159 /* wait while DMA engine is busy */
1161 for (ntries = 0; ntries < 100; ntries++)
1163 tmp = rt2870_io_mac_read(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG);
1164 if (!(tmp & (RT2870_REG_TX_DMA_BUSY | RT2870_REG_RX_DMA_BUSY)))
1165 break;
1167 DELAY(1000);
1170 if (ntries == 100)
1172 printf("%s: timeout waiting for DMA engine\n",
1173 device_get_nameunit(sc->dev));
1174 goto fail;
1177 tmp &= 0xff0;
1178 tmp |= RT2870_REG_TX_WB_DDONE;
1180 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
1182 /* PBF hardware reset */
1184 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_SYS_CTRL);
1186 tmp &= ~(1 << 13);
1188 rt2870_io_mac_write(sc, RT2870_REG_PBF_SYS_CTRL, tmp);
1190 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL,
1191 RT2870_REG_MAC_SRST | RT2870_REG_BBP_HRST);
1193 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_DMA_CFG, 0);
1195 rt2870_io_mcu_reset(sc);
1197 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, 0);
1199 /* init Tx power per rate */
1201 for (i = 0; i < RT2870_SOFTC_TXPOW_RATE_COUNT; i++)
1203 if (sc->txpow_rate_20mhz[i] == 0xffffffff)
1204 continue;
1206 rt2870_io_mac_write(sc, RT2870_REG_TX_PWR_CFG(i),
1207 sc->txpow_rate_20mhz[i]);
1210 for (i = 0; i < RT2870_DEF_MAC_SIZE; i++)
1211 rt2870_io_mac_write(sc, rt2870_def_mac[i].reg,
1212 rt2870_def_mac[i].val);
1214 /* wait while MAC is busy */
1216 for (ntries = 0; ntries < 100; ntries++)
1218 if (!(rt2870_io_mac_read(sc, RT2870_REG_STATUS_CFG) &
1219 (RT2870_REG_STATUS_TX_BUSY | RT2870_REG_STATUS_RX_BUSY)))
1220 break;
1222 DELAY(1000);
1225 if (ntries == 100)
1227 printf("%s: timeout waiting for MAC\n",
1228 device_get_nameunit(sc->dev));
1229 goto fail;
1232 /* clear Host to MCU mailbox */
1234 rt2870_io_mac_write(sc, RT2870_REG_H2M_MAILBOX_BBP_AGENT, 0);
1235 rt2870_io_mac_write(sc, RT2870_REG_H2M_MAILBOX, 0);
1237 DELAY(1000);
1239 error = rt2870_init_bbp(sc);
1240 if (error != 0)
1241 goto fail;
1243 /* set up maximum buffer sizes */
1245 tmp = (1 << 12) | RT2870_MAX_AGG_SIZE;
1247 rt2870_io_mac_write(sc, RT2870_REG_MAX_LEN_CFG, tmp);
1249 if (sc->mac_rev == 0x28720200)
1251 /* set max. PSDU length from 16K to 32K bytes */
1253 tmp = rt2870_io_mac_read(sc, RT2870_REG_MAX_LEN_CFG);
1255 tmp &= ~(3 << 12);
1256 tmp |= (2 << 12);
1258 rt2870_io_mac_write(sc, RT2870_REG_MAX_LEN_CFG, tmp);
1261 if (sc->mac_rev >= 0x28720200 && sc->mac_rev < 0x30700200)
1263 tmp = rt2870_io_mac_read(sc, RT2870_REG_MAX_LEN_CFG);
1265 tmp &= 0xfff;
1266 tmp |= 0x2000;
1268 rt2870_io_mac_write(sc, RT2870_REG_MAX_LEN_CFG, tmp);
1271 /* set mac address */
1273 rt2870_asic_set_macaddr(sc, IF_LLADDR(ifp));
1275 /* clear statistic registers */
1277 rt2870_io_mac_read_multi(sc, RT2870_REG_RX_STA_CNT0,
1278 stacnt, sizeof(stacnt));
1280 /* send LEDs operating mode to microcontroller */
1282 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_LED1,
1283 RT2870_REG_H2M_TOKEN_NO_INTR, sc->led_off[0]);
1284 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_LED2,
1285 RT2870_REG_H2M_TOKEN_NO_INTR, sc->led_off[1]);
1286 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_LED3,
1287 RT2870_REG_H2M_TOKEN_NO_INTR, sc->led_off[2]);
1289 /* write vendor-specific BBP values (from EEPROM) */
1291 for (i = 0; i < RT2870_SOFTC_BBP_EEPROM_COUNT; i++)
1293 if (sc->bbp_eeprom[i].reg == 0x00 ||
1294 sc->bbp_eeprom[i].reg == 0xff)
1295 continue;
1297 rt2870_io_bbp_write(sc, sc->bbp_eeprom[i].reg,
1298 sc->bbp_eeprom[i].val);
1301 /* disable non-existing Rx chains */
1303 tmp = rt2870_io_bbp_read(sc, 3);
1305 tmp &= ~((1 << 4) | (1 << 3));
1307 if (sc->nrxpath == 3)
1308 tmp |= (1 << 4);
1309 else if (sc->nrxpath == 2)
1310 tmp |= (1 << 3);
1312 rt2870_io_bbp_write(sc, 3, tmp);
1314 /* disable non-existing Tx chains */
1316 tmp = rt2870_io_bbp_read(sc, 1);
1318 tmp &= ~((1 << 4) | (1 << 3));
1320 if (sc->ntxpath == 2)
1321 tmp |= (1 << 4);
1323 rt2870_io_bbp_write(sc, 1, tmp);
1325 /* set current channel */
1327 rt2870_rf_set_chan(sc, ic->ic_curchan);
1329 /* turn radio LED on */
1331 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_ON);
1333 rt2870_io_mcu_cmd(sc, RT2870_IO_MCU_CMD_BOOT,
1334 RT2870_REG_H2M_TOKEN_NO_INTR, 0);
1336 /* set RTS threshold */
1338 rt2870_asic_update_rtsthreshold(sc);
1340 /* set Tx power */
1342 rt2870_asic_update_txpower(sc);
1344 /* set up protection mode */
1346 rt2870_asic_updateprot(sc);
1348 /* clear key tables */
1350 rt2870_asic_clear_keytables(sc);
1352 if (rt2870_txrx_enable(sc) != 0)
1353 goto fail;
1355 /* clear garbage interrupts */
1357 tmp = rt2870_io_mac_read(sc, 0x1300);
1359 taskqueue_unblock(sc->taskqueue);
1361 /* init Tx and Rx rings */
1363 for(i = 0; i < sc->usb_endpoints - 1; i++)
1364 rt2870_reset_tx_ring(sc, &sc->tx_ring[i]);
1366 rt2870_reset_rx_ring(sc, &sc->rx_ring);
1368 rt2870_reset_cmd_ring(sc, &sc->cmd_ring);
1370 for(i = 0; i < sc->usb_endpoints - 1; i++)
1372 usbd_xfer_set_priv(sc->usb_xfer[i + 1], &sc->tx_ring[i]);
1373 usbd_xfer_set_stall(sc->usb_xfer[i + 1]);
1376 /* start up the receive pipe */
1378 for(i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
1379 usbd_transfer_start(sc->usb_xfer[0]);
1381 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1382 ifp->if_drv_flags |= IFF_DRV_RUNNING;
1384 sc->periodic_round = 0;
1386 callout_reset(&sc->periodic_ch, hz / 10, rt2870_periodic, sc);
1388 return;
1390 fail:
1392 rt2870_stop_locked(sc);
1396 * rt2870_init
1398 static void rt2870_init(void *priv)
1400 struct rt2870_softc *sc;
1402 sc = priv;
1404 RT2870_SOFTC_LOCK(sc);
1406 rt2870_init_locked(sc);
1408 RT2870_SOFTC_UNLOCK(sc);
1412 * rt2870_init_bbp
1414 static int rt2870_init_bbp(struct rt2870_softc *sc)
1416 int ntries, i;
1417 uint8_t tmp;
1419 for (ntries = 0; ntries < 20; ntries++)
1421 tmp = rt2870_io_bbp_read(sc, 0);
1422 if (tmp != 0x00 && tmp != 0xff)
1423 break;
1426 if (tmp == 0x00 || tmp == 0xff)
1428 printf("%s: timeout waiting for BBP to wakeup\n",
1429 device_get_nameunit(sc->dev));
1430 return ETIMEDOUT;
1433 for (i = 0; i < RT2870_DEF_BBP_SIZE; i++)
1434 rt2870_io_bbp_write(sc, rt2870_def_bbp[i].reg,
1435 rt2870_def_bbp[i].val);
1437 if ((sc->mac_rev & 0xffff) != 0x0101)
1438 rt2870_io_bbp_write(sc, 84, 0x19);
1440 if (sc->mac_rev == 0x28600100)
1442 rt2870_io_bbp_write(sc, 69, 0x16);
1443 rt2870_io_bbp_write(sc, 73, 0x12);
1446 return 0;
1450 * rt2870_stop_locked
1452 static void rt2870_stop_locked(void *priv)
1454 struct rt2870_softc *sc;
1455 struct ifnet *ifp;
1456 struct ieee80211com *ic;
1457 uint32_t tmp;
1458 int i;
1460 sc = priv;
1461 ifp = sc->ifp;
1462 ic = ifp->if_l2com;
1464 RT2870_DPRINTF(sc, RT2870_DEBUG_ANY,
1465 "%s: stopping\n",
1466 device_get_nameunit(sc->dev));
1468 RT2870_SOFTC_ASSERT_LOCKED(sc);
1470 sc->tx_timer = 0;
1472 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1473 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_OFF);
1475 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1477 callout_stop(&sc->periodic_ch);
1478 callout_stop(&sc->tx_watchdog_ch);
1480 RT2870_SOFTC_UNLOCK(sc);
1482 taskqueue_block(sc->taskqueue);
1484 taskqueue_drain(sc->taskqueue, &sc->rx_done_task);
1485 taskqueue_drain(sc->taskqueue, &sc->tx_done_task);
1486 taskqueue_drain(sc->taskqueue, &sc->periodic_task);
1487 taskqueue_drain(sc->taskqueue, &sc->cmd_task);
1489 RT2870_SOFTC_LOCK(sc);
1491 /* clear key tables */
1493 rt2870_asic_clear_keytables(sc);
1495 /* disable Tx/Rx */
1497 tmp = rt2870_io_mac_read(sc, RT2870_REG_SYS_CTRL);
1499 tmp &= ~(RT2870_REG_RX_ENABLE | RT2870_REG_TX_ENABLE);
1501 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, tmp);
1503 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_DMA_CFG, 0);
1505 /* reset adapter */
1507 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL,
1508 RT2870_REG_MAC_SRST | RT2870_REG_BBP_HRST);
1509 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, 0);
1511 /* abort any pending transfers */
1513 for (i = 0; i < sc->usb_endpoints; i++)
1514 usbd_transfer_stop(sc->usb_xfer[i]);
1518 * rt2870_stop
1520 static void rt2870_stop(void *priv)
1522 struct rt2870_softc *sc;
1524 sc = priv;
1526 RT2870_SOFTC_LOCK(sc);
1528 rt2870_stop_locked(sc);
1530 RT2870_SOFTC_UNLOCK(sc);
1534 * rt2870_start
1536 static void rt2870_start(struct ifnet *ifp)
1538 struct rt2870_softc *sc;
1539 struct ieee80211_node *ni;
1540 struct mbuf *m;
1541 int qid;
1543 sc = ifp->if_softc;
1545 RT2870_SOFTC_LOCK(sc);
1547 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1549 RT2870_SOFTC_UNLOCK(sc);
1550 return;
1553 for (;;)
1555 IF_POLL(&ifp->if_snd, m);
1556 if (m == NULL)
1557 break;
1559 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1561 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1563 qid = M_WME_GETAC(m);
1565 if (sc->tx_ring[qid].queued >= RT2870_SOFTC_TX_RING_DATA_COUNT)
1567 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
1568 "%s: if_start: Tx ring with qid=%d is full\n",
1569 device_get_nameunit(sc->dev), qid);
1571 m_freem(m);
1572 ieee80211_free_node(ni);
1573 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1574 ifp->if_oerrors++;
1575 break;
1578 if (rt2870_tx_data(sc, m, ni, qid) != 0)
1580 ieee80211_free_node(ni);
1581 ifp->if_oerrors++;
1582 break;
1585 sc->tx_timer = RT2870_TX_WATCHDOG_TIMEOUT;
1587 callout_reset(&sc->tx_watchdog_ch, hz, rt2870_tx_watchdog, sc);
1590 RT2870_SOFTC_UNLOCK(sc);
1594 * rt2870_ioctl
1596 static int rt2870_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1598 struct rt2870_softc *sc;
1599 struct ieee80211com *ic;
1600 struct ifreq *ifr;
1601 int error, startall;
1603 sc = ifp->if_softc;
1604 ic = ifp->if_l2com;
1605 ifr = (struct ifreq *) data;
1607 error = 0;
1609 switch (cmd)
1611 case SIOCSIFFLAGS:
1612 startall = 0;
1614 RT2870_SOFTC_LOCK(sc);
1616 if (ifp->if_flags & IFF_UP)
1618 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1620 if ((ifp->if_flags ^ sc->if_flags) & IFF_PROMISC)
1621 rt2870_asic_update_promisc(sc);
1623 else
1625 rt2870_init_locked(sc);
1626 startall = 1;
1629 else
1631 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1632 rt2870_stop_locked(sc);
1635 sc->if_flags = ifp->if_flags;
1637 RT2870_SOFTC_UNLOCK(sc);
1639 if (startall)
1640 ieee80211_start_all(ic);
1641 break;
1643 case SIOCGIFMEDIA:
1644 case SIOCSIFMEDIA:
1645 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1646 break;
1648 case SIOCGIFADDR:
1649 error = ether_ioctl(ifp, cmd, data);
1650 break;
1652 default:
1653 error = EINVAL;
1654 break;
1657 return error;
1661 * rt2870_vap_create
1663 static struct ieee80211vap *rt2870_vap_create(struct ieee80211com *ic,
1664 const char name[IFNAMSIZ], int unit, int opmode, int flags,
1665 const uint8_t bssid[IEEE80211_ADDR_LEN],
1666 const uint8_t mac[IEEE80211_ADDR_LEN])
1668 struct rt2870_softc *sc;
1669 struct ifnet *ifp;
1670 struct rt2870_softc_vap *rvap;
1671 struct ieee80211vap *vap;
1673 ifp = ic->ic_ifp;
1674 sc = ifp->if_softc;
1676 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
1677 "%s: VAP create: opmode=%s\n",
1678 device_get_nameunit(sc->dev),
1679 ieee80211_opmode_name[opmode]);
1681 switch (opmode)
1683 case IEEE80211_M_MONITOR:
1684 case IEEE80211_M_IBSS:
1685 case IEEE80211_M_STA:
1686 case IEEE80211_M_AHDEMO:
1687 case IEEE80211_M_HOSTAP:
1688 case IEEE80211_M_MBSS:
1689 if (!TAILQ_EMPTY(&ic->ic_vaps))
1691 if_printf(ifp, "only 1 VAP supported\n");
1692 return NULL;
1695 if (opmode == IEEE80211_M_STA)
1696 flags |= IEEE80211_CLONE_NOBEACONS;
1697 break;
1699 case IEEE80211_M_WDS:
1700 if (TAILQ_EMPTY(&ic->ic_vaps) || ic->ic_opmode != IEEE80211_M_HOSTAP)
1702 if_printf(ifp, "WDS only supported in AP mode\n");
1703 return NULL;
1706 flags &= ~IEEE80211_CLONE_BSSID;
1707 break;
1709 default:
1710 if_printf(ifp, "unknown opmode %d\n", opmode);
1711 return NULL;
1714 rvap = (struct rt2870_softc_vap *) malloc(sizeof(struct rt2870_softc_vap),
1715 M_80211_VAP, M_NOWAIT | M_ZERO);
1716 if (rvap == NULL)
1717 return NULL;
1719 vap = &rvap->vap;
1721 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
1723 rvap->newstate = vap->iv_newstate;
1724 vap->iv_newstate = rt2870_vap_newstate;
1726 vap->iv_reset = rt2870_vap_reset;
1727 vap->iv_key_update_begin = rt2870_vap_key_update_begin;
1728 vap->iv_key_update_end = rt2870_vap_key_update_end;
1729 vap->iv_key_set = rt2870_vap_key_set;
1730 vap->iv_key_delete = rt2870_vap_key_delete;
1731 vap->iv_update_beacon = rt2870_vap_update_beacon;
1733 rt2870_amrr_init(&rvap->amrr, vap,
1734 RT2870_AMRR_MIN_SUCCESS_THRESHOLD,
1735 RT2870_AMRR_MAX_SUCCESS_THRESHOLD,
1736 500);
1738 ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
1740 ic->ic_opmode = opmode;
1742 return vap;
1746 * rt2870_vap_delete
1748 static void rt2870_vap_delete(struct ieee80211vap *vap)
1750 struct rt2870_softc *sc;
1751 struct ieee80211com *ic;
1752 struct ifnet *ifp;
1753 struct rt2870_softc_vap *rvap;
1755 ic = vap->iv_ic;
1756 ifp = ic->ic_ifp;
1757 sc = ifp->if_softc;
1758 rvap = (struct rt2870_softc_vap *) vap;
1760 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
1761 "%s: VAP delete: opmode=%s\n",
1762 device_get_nameunit(sc->dev),
1763 ieee80211_opmode_name[vap->iv_opmode]);
1765 rt2870_amrr_cleanup(&rvap->amrr);
1767 ieee80211_vap_detach(vap);
1769 free(rvap, M_80211_VAP);
1773 * rt2870_reset_vap
1775 static int rt2870_vap_reset(struct ieee80211vap *vap, u_long cmd)
1777 struct rt2870_softc *sc;
1778 struct ieee80211com *ic;
1779 struct ifnet *ifp;
1780 struct rt2870_softc_vap *rvap;
1781 int error;
1783 ic = vap->iv_ic;
1784 ifp = ic->ic_ifp;
1785 sc = ifp->if_softc;
1786 rvap = (struct rt2870_softc_vap *) vap;
1788 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
1789 "%s: VAP reset: cmd=%lu\n",
1790 device_get_nameunit(sc->dev), cmd);
1792 error = 0;
1794 RT2870_SOFTC_LOCK(sc);
1796 switch (cmd)
1798 case IEEE80211_IOC_RTSTHRESHOLD:
1799 rt2870_asic_update_rtsthreshold(sc);
1800 break;
1802 case IEEE80211_IOC_PROTMODE:
1803 case IEEE80211_IOC_HTPROTMODE:
1804 rt2870_asic_updateprot(sc);
1805 break;
1807 case IEEE80211_IOC_TXPOWER:
1808 rt2870_asic_update_txpower(sc);
1809 break;
1811 case IEEE80211_IOC_SHORTGI:
1812 case IEEE80211_IOC_AMPDU_DENSITY:
1813 break;
1815 default:
1816 error = ENETRESET;
1817 break;
1820 RT2870_SOFTC_UNLOCK(sc);
1822 return error;
1826 * rt2870_vap_newstate
1828 static int rt2870_vap_newstate(struct ieee80211vap *vap,
1829 enum ieee80211_state nstate, int arg)
1831 struct rt2870_softc *sc;
1832 struct ieee80211com *ic;
1833 struct ifnet *ifp;
1834 struct rt2870_softc_vap *rvap;
1835 struct ieee80211_node *ni;
1836 int error;
1838 ic = vap->iv_ic;
1839 ifp = ic->ic_ifp;
1840 sc = ifp->if_softc;
1841 rvap = (struct rt2870_softc_vap *) vap;
1843 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
1844 "%s: VAP newstate: %s -> %s\n",
1845 device_get_nameunit(sc->dev),
1846 ieee80211_state_name[vap->iv_state], ieee80211_state_name[nstate]);
1848 error = rvap->newstate(vap, nstate, arg);
1849 if (error != 0)
1850 return error;
1852 IEEE80211_UNLOCK(ic);
1854 RT2870_SOFTC_LOCK(sc);
1856 /* turn link LED off */
1858 if (nstate != IEEE80211_S_RUN)
1859 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_OFF);
1861 switch (nstate)
1863 case IEEE80211_S_INIT:
1864 rt2870_asic_disable_tsf_sync(sc);
1865 break;
1867 case IEEE80211_S_RUN:
1868 ni = vap->iv_bss;
1870 rt2870_rf_set_chan(sc, ni->ni_chan);
1872 if (vap->iv_opmode != IEEE80211_M_MONITOR)
1874 rt2870_asic_enable_mrr(sc);
1875 rt2870_asic_set_txpreamble(sc);
1876 rt2870_asic_set_basicrates(sc);
1877 rt2870_asic_update_txpower(sc);
1878 rt2870_asic_set_bssid(sc, ni->ni_bssid);
1881 if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
1882 vap->iv_opmode == IEEE80211_M_IBSS ||
1883 vap->iv_opmode == IEEE80211_M_MBSS)
1885 error = rt2870_asic_update_beacon(sc, vap);
1886 if (error != 0)
1887 break;
1890 if (vap->iv_opmode != IEEE80211_M_MONITOR)
1891 rt2870_asic_enable_tsf_sync(sc);
1893 /* turn link LED on */
1895 if (ic->ic_opmode != IEEE80211_M_MONITOR)
1897 rt2870_led_cmd(sc, RT2870_LED_CMD_RADIO_ON |
1898 (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) ?
1899 RT2870_LED_CMD_LINK_2GHZ : RT2870_LED_CMD_LINK_5GHZ));
1901 break;
1903 default:
1904 break;
1907 RT2870_SOFTC_UNLOCK(sc);
1909 IEEE80211_LOCK(ic);
1911 return error;
1915 * rt2870_vap_key_update_begin
1917 static void rt2870_vap_key_update_begin(struct ieee80211vap *vap)
1919 struct rt2870_softc *sc;
1920 struct ieee80211com *ic;
1921 struct ifnet *ifp;
1923 ic = vap->iv_ic;
1924 ifp = ic->ic_ifp;
1925 sc = ifp->if_softc;
1927 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
1928 "%s: VAP key update begin\n",
1929 device_get_nameunit(sc->dev));
1931 taskqueue_block(sc->taskqueue);
1933 IF_LOCK(&ifp->if_snd);
1937 * rt2870_vap_key_update_end
1939 static void rt2870_vap_key_update_end(struct ieee80211vap *vap)
1941 struct rt2870_softc *sc;
1942 struct ieee80211com *ic;
1943 struct ifnet *ifp;
1945 ic = vap->iv_ic;
1946 ifp = ic->ic_ifp;
1947 sc = ifp->if_softc;
1949 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
1950 "%s: VAP key update end\n",
1951 device_get_nameunit(sc->dev));
1953 IF_UNLOCK(&ifp->if_snd);
1955 taskqueue_unblock(sc->taskqueue);
1959 * rt2870_vap_key_set
1961 static int rt2870_vap_key_set(struct ieee80211vap *vap,
1962 const struct ieee80211_key *k, const uint8_t mac[IEEE80211_ADDR_LEN])
1964 struct rt2870_softc *sc;
1965 struct ieee80211com *ic;
1966 struct ifnet *ifp;
1967 struct ieee80211_node *ni;
1968 uint16_t associd, key_base, keymode_base;
1969 uint8_t mode, vapid, wcid, iv[8];
1970 uint32_t tmp;
1972 if (k->wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP &&
1973 k->wk_cipher->ic_cipher != IEEE80211_CIPHER_TKIP &&
1974 k->wk_cipher->ic_cipher != IEEE80211_CIPHER_AES_CCM)
1975 return EINVAL;
1977 ic = vap->iv_ic;
1978 ifp = ic->ic_ifp;
1979 sc = ifp->if_softc;
1981 if (vap->iv_opmode != IEEE80211_M_HOSTAP)
1982 ni = vap->iv_bss;
1983 else
1984 ni = ieee80211_find_vap_node(&ic->ic_sta, vap, mac);
1986 associd = (ni != NULL) ? ni->ni_associd : 0;
1988 if ((vap->iv_opmode == IEEE80211_M_HOSTAP) && (ni != NULL))
1989 ieee80211_free_node(ni);
1991 switch (k->wk_cipher->ic_cipher)
1993 case IEEE80211_CIPHER_WEP:
1994 if(k->wk_keylen < 8)
1995 mode = RT2870_REG_CIPHER_MODE_WEP40;
1996 else
1997 mode = RT2870_REG_CIPHER_MODE_WEP104;
1998 break;
2000 case IEEE80211_CIPHER_TKIP:
2001 mode = RT2870_REG_CIPHER_MODE_TKIP;
2002 break;
2004 case IEEE80211_CIPHER_AES_CCM:
2005 mode = RT2870_REG_CIPHER_MODE_AES_CCMP;
2006 break;
2008 default:
2009 return EINVAL;
2012 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
2013 "%s: VAP key set: keyix=%d, keylen=%d, associd=0x%04x, mode=%d, group=%d\n",
2014 device_get_nameunit(sc->dev), k->wk_keyix, k->wk_keylen, associd, mode,
2015 (k->wk_flags & IEEE80211_KEY_GROUP) ? 1 : 0);
2017 RT2870_SOFTC_LOCK(sc);
2019 if (!(k->wk_flags & IEEE80211_KEY_GROUP))
2021 /* install pairwise key */
2023 vapid = 0;
2024 wcid = RT2870_AID2WCID(associd);
2025 key_base = RT2870_REG_PKEY(wcid);
2027 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP)
2029 memset(iv, 0, 8);
2031 iv[3] = (k->wk_keyix << 6);
2033 else
2035 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
2037 iv[0] = (k->wk_keytsc >> 8);
2038 iv[1] = ((iv[0] | 0x20) & 0x7f);
2039 iv[2] = k->wk_keytsc;
2041 else
2043 /* AES CCMP */
2045 iv[0] = k->wk_keytsc;
2046 iv[1] = k->wk_keytsc >> 8;
2047 iv[2] = 0;
2050 iv[3] = ((k->wk_keyix << 6) | IEEE80211_WEP_EXTIV);
2051 iv[4] = (k->wk_keytsc >> 16);
2052 iv[5] = (k->wk_keytsc >> 24);
2053 iv[6] = (k->wk_keytsc >> 32);
2054 iv[7] = (k->wk_keytsc >> 40);
2056 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
2057 "%s: set key: iv=%02x %02x %02x %02x %02x %02x %02x %02x\n",
2058 device_get_nameunit(sc->dev),
2059 iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]);
2062 rt2870_io_mac_write_multi(sc, RT2870_REG_IVEIV(wcid), iv, 8);
2064 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
2066 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, 16);
2068 if (vap->iv_opmode != IEEE80211_M_HOSTAP)
2070 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[16], 8);
2071 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[24], 8);
2073 else
2075 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[24], 8);
2076 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[16], 8);
2079 else
2081 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, k->wk_keylen);
2084 tmp = ((vapid & RT2870_REG_VAP_MASK) << RT2870_REG_VAP_SHIFT) |
2085 (mode << RT2870_REG_CIPHER_MODE_SHIFT) | RT2870_REG_PKEY_ENABLE;
2087 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
2090 if ((k->wk_flags & IEEE80211_KEY_GROUP) ||
2091 (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP))
2093 /* install group key */
2095 vapid = 0;
2096 key_base = RT2870_REG_SKEY(vapid, k->wk_keyix);
2097 keymode_base = RT2870_REG_SKEY_MODE(vapid);
2099 if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP)
2101 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, 16);
2103 if (vap->iv_opmode != IEEE80211_M_HOSTAP)
2105 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[16], 8);
2106 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[24], 8);
2108 else
2110 rt2870_io_mac_write_multi(sc, key_base + 16, &k->wk_key[24], 8);
2111 rt2870_io_mac_write_multi(sc, key_base + 24, &k->wk_key[16], 8);
2114 else
2116 rt2870_io_mac_write_multi(sc, key_base, k->wk_key, k->wk_keylen);
2119 tmp = rt2870_io_mac_read(sc, keymode_base);
2121 tmp &= ~(0xf << (k->wk_keyix * 4 + 16 * (vapid % 2)));
2122 tmp |= (mode << (k->wk_keyix * 4 + 16 * (vapid % 2)));
2124 rt2870_io_mac_write(sc, keymode_base, tmp);
2127 RT2870_SOFTC_UNLOCK(sc);
2129 return 1;
2133 * rt2870_vap_key_delete
2135 static int rt2870_vap_key_delete(struct ieee80211vap *vap,
2136 const struct ieee80211_key *k)
2138 struct rt2870_softc *sc;
2139 struct ieee80211com *ic;
2140 struct ifnet *ifp;
2141 struct ieee80211_node *ni;
2142 struct rt2870_cmd_argv_keydelete cmd_argv;
2143 uint16_t associd;
2145 ic = vap->iv_ic;
2146 ifp = ic->ic_ifp;
2147 sc = ifp->if_softc;
2148 ni = vap->iv_bss;
2149 associd = (ni != NULL) ? ni->ni_associd : 0;
2151 RT2870_DPRINTF(sc, RT2870_DEBUG_KEY,
2152 "%s: VAP key delete: keyix=%d, keylen=%d, associd=0x%04x, group=%d\n",
2153 device_get_nameunit(sc->dev), k->wk_keyix, k->wk_keylen, associd,
2154 (k->wk_flags & IEEE80211_KEY_GROUP) ? 1 : 0);
2156 memcpy(&cmd_argv.key, k, sizeof(struct ieee80211_key));
2157 cmd_argv.associd = associd;
2159 rt2870_do_async(sc, rt2870_vap_key_delete_cb,
2160 &cmd_argv, sizeof(struct rt2870_cmd_argv_keydelete));
2162 return 1;
2166 * rt2870_vap_update_beacon
2168 static void rt2870_vap_update_beacon(struct ieee80211vap *vap, int what)
2170 struct rt2870_softc *sc;
2171 struct ieee80211com *ic;
2172 struct ifnet *ifp;
2174 ic = vap->iv_ic;
2175 ifp = ic->ic_ifp;
2176 sc = ifp->if_softc;
2178 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
2179 "%s: VAP update beacon\n",
2180 device_get_nameunit(sc->dev));
2182 rt2870_do_async(sc, rt2870_vap_update_beacon_cb, NULL, 0);
2186 * rt2870_node_alloc
2188 static struct ieee80211_node *rt2870_node_alloc(struct ieee80211vap *vap,
2189 const uint8_t mac[IEEE80211_ADDR_LEN])
2191 return malloc(sizeof(struct rt2870_softc_node),
2192 M_80211_NODE, M_NOWAIT | M_ZERO);
2196 * rt2870_setregdomain
2198 static int rt2870_setregdomain(struct ieee80211com *ic,
2199 struct ieee80211_regdomain *reg,
2200 int nchans, struct ieee80211_channel chans[])
2202 struct rt2870_softc *sc;
2203 struct ifnet *ifp;
2205 ifp = ic->ic_ifp;
2206 sc = ifp->if_softc;
2208 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
2209 "%s: set regulatory domain: country=%d, country code string=%c%c, location=%c\n",
2210 device_get_nameunit(sc->dev),
2211 reg->country, reg->isocc[0], reg->isocc[1], reg->location);
2213 return 0;
2217 * rt2870_getradiocaps
2219 static void rt2870_getradiocaps(struct ieee80211com *ic,
2220 int maxchans, int *nchans, struct ieee80211_channel chans[])
2222 *nchans = (ic->ic_nchans >= maxchans) ? maxchans : ic->ic_nchans;
2224 memcpy(chans, ic->ic_channels, (*nchans) * sizeof(struct ieee80211_channel));
2228 * rt2870_scan_start
2230 static void rt2870_scan_start(struct ieee80211com *ic)
2232 struct rt2870_softc *sc;
2233 struct ifnet *ifp;
2235 ifp = ic->ic_ifp;
2236 sc = ifp->if_softc;
2238 RT2870_SOFTC_LOCK(sc);
2240 rt2870_asic_disable_tsf_sync(sc);
2242 RT2870_SOFTC_UNLOCK(sc);
2246 * rt2870_scan_end
2248 static void rt2870_scan_end(struct ieee80211com *ic)
2250 struct rt2870_softc *sc;
2251 struct ifnet *ifp;
2253 ifp = ic->ic_ifp;
2254 sc = ifp->if_softc;
2256 RT2870_SOFTC_LOCK(sc);
2258 rt2870_asic_enable_tsf_sync(sc);
2260 RT2870_SOFTC_UNLOCK(sc);
2264 * rt2870_set_channel
2266 static void rt2870_set_channel(struct ieee80211com *ic)
2268 struct rt2870_softc *sc;
2269 struct ifnet *ifp;
2271 ifp = ic->ic_ifp;
2272 sc = ifp->if_softc;
2274 RT2870_DPRINTF(sc, RT2870_DEBUG_CHAN,
2275 "%s: set channel: channel=%u, HT%s%s\n",
2276 device_get_nameunit(sc->dev),
2277 ieee80211_chan2ieee(ic, ic->ic_curchan),
2278 !IEEE80211_IS_CHAN_HT(ic->ic_curchan) ? " disabled" :
2279 IEEE80211_IS_CHAN_HT20(ic->ic_curchan) ? "20":
2280 IEEE80211_IS_CHAN_HT40U(ic->ic_curchan) ? "40U" : "40D",
2281 (ic->ic_flags & IEEE80211_F_SCAN) ? ", scanning" : "");
2283 RT2870_SOFTC_LOCK(sc);
2285 rt2870_rf_set_chan(sc, ic->ic_curchan);
2287 RT2870_SOFTC_UNLOCK(sc);
2291 * rt2870_newassoc
2293 static void rt2870_newassoc(struct ieee80211_node *ni, int isnew)
2295 struct rt2870_softc *sc;
2296 struct ieee80211com *ic;
2297 struct ifnet *ifp;
2298 struct ieee80211vap *vap;
2299 struct rt2870_softc_vap *rvap;
2300 uint16_t associd;
2301 uint8_t wcid;
2303 vap = ni->ni_vap;
2304 ic = vap->iv_ic;
2305 ifp = ic->ic_ifp;
2306 sc = ifp->if_softc;
2307 rvap = (struct rt2870_softc_vap *) vap;
2309 associd = (ni != NULL) ? ni->ni_associd : 0;
2310 wcid = RT2870_AID2WCID(associd);
2312 RT2870_DPRINTF(sc, RT2870_DEBUG_NODE,
2313 "%s: new association: wcid=0x%02x, "
2314 "mac addr=%s, QoS %s, ERP %s, HT %s\n",
2315 device_get_nameunit(sc->dev), wcid,
2316 ether_sprintf(ni->ni_macaddr),
2317 (ni->ni_flags & IEEE80211_NODE_QOS) ? "enabled" : "disabled",
2318 (ni->ni_flags & IEEE80211_NODE_ERP) ? "enabled" : "disabled",
2319 (ni->ni_flags & IEEE80211_NODE_HT) ? "enabled" : "disabled");
2321 RT2870_SOFTC_LOCK(sc);
2323 rt2870_io_mac_write_multi(sc, RT2870_REG_WCID(wcid),
2324 ni->ni_macaddr, IEEE80211_ADDR_LEN);
2326 rt2870_amrr_node_init(&rvap->amrr, &sc->amrr_node[wcid], ni);
2328 RT2870_DPRINTF(sc, RT2870_DEBUG_RATE,
2329 "%s: initial%s node Tx rate: associd=0x%04x, rate=0x%02x, max rate=0x%02x\n",
2330 device_get_nameunit(sc->dev),
2331 (ni->ni_flags & IEEE80211_NODE_HT) ? " HT" : "",
2332 ni->ni_associd, ni->ni_txrate,
2333 (ni->ni_flags & IEEE80211_NODE_HT) ?
2334 (ni->ni_htrates.rs_rates[ni->ni_htrates.rs_nrates - 1] | IEEE80211_RATE_MCS) :
2335 (ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates - 1] & IEEE80211_RATE_VAL));
2337 rt2870_asic_updateprot(sc);
2338 rt2870_asic_updateslot(sc);
2339 rt2870_asic_set_txpreamble(sc);
2341 RT2870_SOFTC_UNLOCK(sc);
2345 * rt2870_updateslot
2347 static void rt2870_updateslot(struct ifnet *ifp)
2349 struct rt2870_softc *sc;
2351 sc = ifp->if_softc;
2353 rt2870_do_async(sc, rt2870_updateslot_cb, NULL, 0);
2357 * rt2870_update_promisc
2359 static void rt2870_update_promisc(struct ifnet *ifp)
2361 struct rt2870_softc *sc;
2363 sc = ifp->if_softc;
2365 RT2870_SOFTC_LOCK(sc);
2367 rt2870_asic_update_promisc(sc);
2369 RT2870_SOFTC_UNLOCK(sc);
2373 * rt2870_update_mcast
2375 static void rt2870_update_mcast(struct ifnet *ifp)
2377 struct rt2870_softc *sc;
2379 sc = ifp->if_softc;
2383 * rt2870_wme_update
2385 static int rt2870_wme_update(struct ieee80211com *ic)
2387 struct rt2870_softc *sc;
2388 struct ifnet *ifp;
2390 ifp = ic->ic_ifp;
2391 sc = ifp->if_softc;
2393 rt2870_do_async(sc, rt2870_wme_update_cb, NULL, 0);
2395 return 0;
2399 * rt2870_raw_xmit
2401 static int rt2870_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2402 const struct ieee80211_bpf_params *params)
2404 struct rt2870_softc *sc;
2405 struct ieee80211com *ic;
2406 struct ifnet *ifp;
2408 ic = ni->ni_ic;
2409 ifp = ic->ic_ifp;
2410 sc = ifp->if_softc;
2412 RT2870_SOFTC_LOCK(sc);
2414 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
2416 RT2870_SOFTC_UNLOCK(sc);
2417 m_freem(m);
2418 ieee80211_free_node(ni);
2419 return ENETDOWN;
2422 if (sc->tx_ring[sc->tx_ring_mgtqid].queued >= RT2870_SOFTC_TX_RING_DATA_COUNT)
2424 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
2425 "%s: raw xmit: Tx ring with qid=%d is full\n",
2426 device_get_nameunit(sc->dev), sc->tx_ring_mgtqid);
2428 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
2429 RT2870_SOFTC_UNLOCK(sc);
2430 m_freem(m);
2431 ieee80211_free_node(ni);
2432 return ENOBUFS;
2435 if (rt2870_tx_mgmt(sc, m, ni, sc->tx_ring_mgtqid) != 0)
2437 ifp->if_oerrors++;
2438 RT2870_SOFTC_UNLOCK(sc);
2439 ieee80211_free_node(ni);
2440 return EIO;
2443 sc->tx_timer = RT2870_TX_WATCHDOG_TIMEOUT;
2445 RT2870_SOFTC_UNLOCK(sc);
2447 return 0;
2451 * rt2870_recv_action
2453 static int rt2870_recv_action(struct ieee80211_node *ni,
2454 const struct ieee80211_frame *wh,
2455 const uint8_t *frm, const uint8_t *efrm)
2457 struct rt2870_softc *sc;
2458 struct ieee80211com *ic;
2459 struct ifnet *ifp;
2460 const struct ieee80211_action *ia;
2461 uint16_t associd, baparamset;
2462 uint8_t wcid;
2463 int ret, tid;
2464 uint32_t tmp;
2466 ic = ni->ni_ic;
2467 ifp = ic->ic_ifp;
2468 sc = ifp->if_softc;
2470 ia = (const struct ieee80211_action *) frm;
2472 ret = sc->recv_action(ni, wh, frm, efrm);
2474 if (ia->ia_category != IEEE80211_ACTION_CAT_BA)
2475 return ret;
2477 associd = (ni != NULL) ? ni->ni_associd : 0;
2478 wcid = RT2870_AID2WCID(associd);
2480 switch (ia->ia_action)
2482 /* IEEE80211_ACTION_BA_ADDBA_REQUEST */
2483 case IEEE80211_ACTION_BA_ADDBA_REQUEST:
2484 baparamset = LE_READ_2(frm + 3);
2485 tid = RT2870_MS(baparamset, IEEE80211_BAPS_TID);
2487 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2488 "%s: adding A-MPDU Rx block ACK: associd=0x%04x, tid=%d\n",
2489 device_get_nameunit(sc->dev), associd, tid);
2491 RT2870_SOFTC_LOCK(sc);
2493 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID(wcid) + 4);
2495 tmp |= (0x10000 << tid);
2497 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
2499 RT2870_SOFTC_UNLOCK(sc);
2500 break;
2502 /* IEEE80211_ACTION_BA_DELBA */
2503 case IEEE80211_ACTION_BA_DELBA:
2504 baparamset = LE_READ_2(frm + 2);
2505 tid = RT2870_MS(baparamset, IEEE80211_BAPS_TID);
2507 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2508 "%s: deleting A-MPDU Rx block ACK: associd=0x%04x, tid=%d\n",
2509 device_get_nameunit(sc->dev), associd, tid);
2511 RT2870_SOFTC_LOCK(sc);
2513 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID(wcid) + 4);
2515 tmp &= ~(0x10000 << tid);
2517 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
2519 RT2870_SOFTC_UNLOCK(sc);
2520 break;
2523 return ret;
2527 * rt2870_send_action
2529 static int rt2870_send_action(struct ieee80211_node *ni,
2530 int cat, int act, void *sa)
2532 struct rt2870_softc *sc;
2533 struct ieee80211com *ic;
2534 struct ifnet *ifp;
2535 uint16_t associd, *args, baparamset;
2536 uint8_t wcid;
2537 int ret, tid;
2538 uint32_t tmp;
2540 ic = ni->ni_ic;
2541 ifp = ic->ic_ifp;
2542 sc = ifp->if_softc;
2544 ret = sc->send_action(ni, cat, act, sa);
2546 if (cat != IEEE80211_ACTION_CAT_BA)
2547 return ret;
2549 associd = (ni != NULL) ? ni->ni_associd : 0;
2550 wcid = RT2870_AID2WCID(associd);
2551 args = sa;
2553 switch (act)
2555 /* IEEE80211_ACTION_BA_DELBA */
2556 case IEEE80211_ACTION_BA_DELBA:
2557 baparamset = RT2870_SM(args[0], IEEE80211_DELBAPS_TID) | args[1];
2559 if (RT2870_MS(baparamset, IEEE80211_DELBAPS_INIT) == IEEE80211_DELBAPS_INIT)
2560 break;
2562 tid = RT2870_MS(baparamset, IEEE80211_DELBAPS_TID);
2564 RT2870_DPRINTF(sc, RT2870_DEBUG_BA,
2565 "%s: deleting A-MPDU Rx block ACK: associd=0x%04x, tid=%d\n",
2566 device_get_nameunit(sc->dev), associd, tid);
2568 RT2870_SOFTC_LOCK(sc);
2570 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID(wcid) + 4);
2572 tmp &= ~(0x10000 << tid);
2574 rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp);
2576 RT2870_SOFTC_UNLOCK(sc);
2577 break;
2580 return ret;
2584 * rt2870_amrr_update_iter_func
2586 static void rt2870_amrr_update_iter_func(void *arg, struct ieee80211_node *ni)
2588 struct rt2870_softc *sc;
2589 struct ieee80211com *ic;
2590 struct ifnet *ifp;
2591 struct ieee80211vap *vap;
2592 struct rt2870_softc_vap *rvap;
2593 uint8_t wcid;
2595 vap = arg;
2596 ic = vap->iv_ic;
2597 ifp = ic->ic_ifp;
2598 sc = ifp->if_softc;
2599 rvap = (struct rt2870_softc_vap *) vap;
2601 /* only associated stations */
2603 if ((ni->ni_vap == vap) && (ni->ni_associd != 0))
2605 wcid = RT2870_AID2WCID(ni->ni_associd);
2607 rt2870_amrr_choose(ni, &sc->amrr_node[wcid]);
2609 RT2870_DPRINTF(sc, RT2870_DEBUG_RATE,
2610 "%s:%s node Tx rate: associd=0x%04x, rate=0x%02x, max rate=0x%02x\n",
2611 device_get_nameunit(sc->dev),
2612 (ni->ni_flags & IEEE80211_NODE_HT) ? " HT" : "",
2613 ni->ni_associd, ni->ni_txrate,
2614 (ni->ni_flags & IEEE80211_NODE_HT) ?
2615 (ni->ni_htrates.rs_rates[ni->ni_htrates.rs_nrates - 1] | IEEE80211_RATE_MCS) :
2616 (ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates - 1] & IEEE80211_RATE_VAL));
2621 * rt2870_periodic
2623 static void rt2870_periodic(void *arg)
2625 struct rt2870_softc *sc;
2626 struct ifnet *ifp;
2628 sc = arg;
2629 ifp = sc->ifp;
2631 RT2870_DPRINTF(sc, RT2870_DEBUG_PERIODIC,
2632 "%s: periodic\n",
2633 device_get_nameunit(sc->dev));
2635 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
2636 return;
2638 taskqueue_enqueue(sc->taskqueue, &sc->periodic_task);
2642 * rt2870_tx_watchdog
2644 static void rt2870_tx_watchdog(void *arg)
2646 struct rt2870_softc *sc;
2647 struct ifnet *ifp;
2649 sc = arg;
2650 ifp = sc->ifp;
2652 if (sc->tx_timer == 0)
2653 return;
2655 if (--sc->tx_timer == 0)
2657 printf("%s: Tx watchdog timeout: resetting\n",
2658 device_get_nameunit(sc->dev));
2660 rt2870_stop_locked(sc);
2661 rt2870_init_locked(sc);
2663 ifp->if_oerrors++;
2665 sc->tx_watchdog_timeouts++;
2668 callout_reset(&sc->tx_watchdog_ch, hz, rt2870_tx_watchdog, sc);
2672 * rt2870_do_async
2674 static int rt2870_do_async(struct rt2870_softc *sc,
2675 void (*cb)(struct rt2870_softc *sc, void *arg),
2676 void *arg, int len)
2678 struct ifnet *ifp;
2679 struct rt2870_softc_cmd_ring *ring;
2680 struct rt2870_softc_cmd *cmd;
2681 int run_cmd_task;
2683 ifp = sc->ifp;
2684 ring = &sc->cmd_ring;
2686 RT2870_SOFTC_LOCK(sc);
2688 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
2690 RT2870_SOFTC_UNLOCK(sc);
2691 return -1;
2694 if (ring->queued >= RT2870_SOFTC_CMD_RING_CMD_COUNT)
2696 RT2870_SOFTC_UNLOCK(sc);
2697 return -1;
2700 cmd = STAILQ_FIRST(&ring->inactive);
2701 STAILQ_REMOVE_HEAD(&ring->inactive, next);
2703 cmd->cb = cb;
2705 if(arg != NULL)
2706 memcpy(cmd->data, arg, len);
2708 STAILQ_INSERT_TAIL(&ring->active, cmd, next);
2709 ring->queued++;
2711 run_cmd_task = (ring->queued == 1);
2713 RT2870_SOFTC_UNLOCK(sc);
2715 if (run_cmd_task)
2716 taskqueue_enqueue(sc->taskqueue, &sc->cmd_task);
2718 return 0;
2722 * rt2870_updateslot_cb
2724 static void rt2870_updateslot_cb(struct rt2870_softc *sc, void *arg)
2726 RT2870_SOFTC_LOCK(sc);
2728 rt2870_asic_updateslot(sc);
2730 RT2870_SOFTC_UNLOCK(sc);
2734 * rt2870_wme_update_cb
2736 static void rt2870_wme_update_cb(struct rt2870_softc *sc, void *arg)
2738 RT2870_SOFTC_LOCK(sc);
2740 rt2870_asic_wme_update(sc);
2742 RT2870_SOFTC_UNLOCK(sc);
2746 * rt2870_vap_key_delete_cb
2748 static void rt2870_vap_key_delete_cb(struct rt2870_softc *sc, void *arg)
2750 struct ieee80211_key *k;
2751 struct rt2870_cmd_argv_keydelete *cmd_argv;
2752 uint16_t associd;
2753 uint8_t vapid, wcid;
2754 uint32_t tmp;
2756 cmd_argv = arg;
2757 k = &cmd_argv->key;
2758 associd = cmd_argv->associd;
2760 RT2870_SOFTC_LOCK(sc);
2762 if (!(k->wk_flags & IEEE80211_KEY_GROUP))
2764 /* remove pairwise key */
2766 wcid = RT2870_AID2WCID(associd);
2768 tmp = rt2870_io_mac_read(sc, RT2870_REG_WCID_ATTR(wcid));
2770 tmp &= ~0xf;
2771 tmp |= (RT2870_REG_CIPHER_MODE_NONE << RT2870_REG_CIPHER_MODE_SHIFT);
2773 rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp);
2775 else
2777 /* remove group key */
2779 vapid = 0;
2781 tmp = rt2870_io_mac_read(sc, RT2870_REG_SKEY_MODE(vapid));
2783 tmp &= ~(0xf << (k->wk_keyix * 4 + 16 * (vapid % 2)));
2784 tmp |= (RT2870_REG_CIPHER_MODE_NONE << (k->wk_keyix * 4 + 16 * (vapid % 2)));
2786 rt2870_io_mac_write(sc, RT2870_REG_SKEY_MODE(vapid), tmp);
2789 RT2870_SOFTC_UNLOCK(sc);
2793 * rt2870_vap_update_beacon_cb
2795 static void rt2870_vap_update_beacon_cb(struct rt2870_softc *sc, void *arg)
2797 struct ifnet *ifp;
2798 struct ieee80211com *ic;
2799 struct ieee80211vap *vap;
2801 ifp = sc->ifp;
2802 ic = ifp->if_l2com;
2803 vap = TAILQ_FIRST(&ic->ic_vaps);
2805 if (vap == NULL)
2806 return;
2808 RT2870_SOFTC_LOCK(sc);
2810 rt2870_asic_update_beacon(sc, vap);
2812 RT2870_SOFTC_UNLOCK(sc);
2816 * rt2870_asic_set_bssid
2818 static void rt2870_asic_set_bssid(struct rt2870_softc *sc,
2819 const uint8_t *bssid)
2821 uint32_t tmp;
2823 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
2824 "%s: set bssid: bssid=%s\n",
2825 device_get_nameunit(sc->dev),
2826 ether_sprintf(bssid));
2828 tmp = bssid[0] | (bssid[1]) << 8 | (bssid[2] << 16) | (bssid[3] << 24);
2830 rt2870_io_mac_write(sc, RT2870_REG_BSSID_DW0, tmp);
2832 tmp = bssid[4] | (bssid[5] << 8);
2834 rt2870_io_mac_write(sc, RT2870_REG_BSSID_DW1, tmp);
2838 * rt2870_asic_set_macaddr
2840 static void rt2870_asic_set_macaddr(struct rt2870_softc *sc,
2841 const uint8_t *addr)
2843 uint32_t tmp;
2845 tmp = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
2847 rt2870_io_mac_write(sc, RT2870_REG_ADDR_DW0, tmp);
2849 tmp = addr[4] | (addr[5] << 8);
2851 rt2870_io_mac_write(sc, RT2870_REG_ADDR_DW1, tmp);
2855 * rt2870_asic_enable_tsf_sync
2857 static void rt2870_asic_enable_tsf_sync(struct rt2870_softc *sc)
2859 struct ifnet *ifp;
2860 struct ieee80211com *ic;
2861 struct ieee80211vap *vap;
2862 uint32_t tmp;
2864 ifp = sc->ifp;
2865 ic = ifp->if_l2com;
2866 vap = TAILQ_FIRST(&ic->ic_vaps);
2868 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
2869 "%s: enabling TSF\n",
2870 device_get_nameunit(sc->dev));
2872 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
2874 tmp &= ~0x1fffff;
2875 tmp |= vap->iv_bss->ni_intval * 16;
2876 tmp |= (RT2870_REG_TSF_TIMER_ENABLE | RT2870_REG_TBTT_TIMER_ENABLE);
2878 if (vap->iv_opmode == IEEE80211_M_STA)
2880 tmp |= (RT2870_REG_TSF_SYNC_MODE_STA << RT2870_REG_TSF_SYNC_MODE_SHIFT);
2882 else if (vap->iv_opmode == IEEE80211_M_IBSS)
2884 tmp |= RT2870_REG_BCN_TX_ENABLE;
2885 tmp |= (RT2870_REG_TSF_SYNC_MODE_IBSS << RT2870_REG_TSF_SYNC_MODE_SHIFT);
2887 else if (vap->iv_opmode == IEEE80211_M_HOSTAP)
2889 tmp |= RT2870_REG_BCN_TX_ENABLE;
2890 tmp |= (RT2870_REG_TSF_SYNC_MODE_HOSTAP << RT2870_REG_TSF_SYNC_MODE_SHIFT);
2893 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
2897 * rt2870_asic_disable_tsf_sync
2899 static void rt2870_asic_disable_tsf_sync(struct rt2870_softc *sc)
2901 uint32_t tmp;
2903 RT2870_DPRINTF(sc, RT2870_DEBUG_BEACON,
2904 "%s: disabling TSF\n",
2905 device_get_nameunit(sc->dev));
2907 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
2909 tmp &= ~(RT2870_REG_BCN_TX_ENABLE |
2910 RT2870_REG_TSF_TIMER_ENABLE |
2911 RT2870_REG_TBTT_TIMER_ENABLE);
2913 tmp &= ~(RT2870_REG_TSF_SYNC_MODE_MASK << RT2870_REG_TSF_SYNC_MODE_SHIFT);
2914 tmp |= (RT2870_REG_TSF_SYNC_MODE_DISABLE << RT2870_REG_TSF_SYNC_MODE_SHIFT);
2916 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
2920 * rt2870_asic_enable_mrr
2922 static void rt2870_asic_enable_mrr(struct rt2870_softc *sc)
2924 #define CCK(mcs) (mcs)
2925 #define OFDM(mcs) ((1 << 3) | (mcs))
2926 #define HT(mcs) (mcs)
2928 rt2870_io_mac_write(sc, RT2870_REG_TX_LG_FBK_CFG0,
2929 (OFDM(6) << 28) | /* 54 -> 48 */
2930 (OFDM(5) << 24) | /* 48 -> 36 */
2931 (OFDM(4) << 20) | /* 36 -> 24 */
2932 (OFDM(3) << 16) | /* 24 -> 18 */
2933 (OFDM(2) << 12) | /* 18 -> 12 */
2934 (OFDM(1) << 8) | /* 12 -> 9 */
2935 (OFDM(0) << 4) | /* 9 -> 6 */
2936 OFDM(0)); /* 6 -> 6 */
2938 rt2870_io_mac_write(sc, RT2870_REG_TX_LG_FBK_CFG1,
2939 (CCK(2) << 12) | /* 11 -> 5.5 */
2940 (CCK(1) << 8) | /* 5.5 -> 2 */
2941 (CCK(0) << 4) | /* 2 -> 1 */
2942 CCK(0)); /* 1 -> 1 */
2944 rt2870_io_mac_write(sc, RT2870_REG_TX_HT_FBK_CFG0,
2945 (HT(6) << 28) |
2946 (HT(5) << 24) |
2947 (HT(4) << 20) |
2948 (HT(3) << 16) |
2949 (HT(2) << 12) |
2950 (HT(1) << 8) |
2951 (HT(0) << 4) |
2952 HT(0));
2954 rt2870_io_mac_write(sc, RT2870_REG_TX_HT_FBK_CFG1,
2955 (HT(14) << 28) |
2956 (HT(13) << 24) |
2957 (HT(12) << 20) |
2958 (HT(11) << 16) |
2959 (HT(10) << 12) |
2960 (HT(9) << 8) |
2961 (HT(8) << 4) |
2962 HT(8));
2964 #undef HT
2965 #undef OFDM
2966 #undef CCK
2970 * rt2870_asic_set_txpreamble
2972 static void rt2870_asic_set_txpreamble(struct rt2870_softc *sc)
2974 struct ifnet *ifp;
2975 struct ieee80211com *ic;
2976 uint32_t tmp;
2978 ifp = sc->ifp;
2979 ic = ifp->if_l2com;
2981 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
2982 "%s: %s short Tx preamble\n",
2983 device_get_nameunit(sc->dev),
2984 (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? "enabling" : "disabling");
2986 tmp = rt2870_io_mac_read(sc, RT2870_REG_AUTO_RSP_CFG);
2988 tmp &= ~RT2870_REG_CCK_SHORT_ENABLE;
2990 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
2991 tmp |= RT2870_REG_CCK_SHORT_ENABLE;
2993 rt2870_io_mac_write(sc, RT2870_REG_AUTO_RSP_CFG, tmp);
2997 * rt2870_asic_set_basicrates
2999 static void rt2870_asic_set_basicrates(struct rt2870_softc *sc)
3001 struct ifnet *ifp;
3002 struct ieee80211com *ic;
3004 ifp = sc->ifp;
3005 ic = ifp->if_l2com;
3007 if (ic->ic_curmode == IEEE80211_MODE_11B)
3008 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0x3);
3009 else if (ic->ic_curmode == IEEE80211_MODE_11A)
3010 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0x150);
3011 else
3012 rt2870_io_mac_write(sc, RT2870_REG_LEGACY_BASIC_RATE, 0x15f);
3016 * rt2870_asic_update_rtsthreshold
3018 static void rt2870_asic_update_rtsthreshold(struct rt2870_softc *sc)
3020 struct ifnet *ifp;
3021 struct ieee80211com *ic;
3022 struct ieee80211vap *vap;
3023 uint32_t tmp;
3024 uint16_t threshold;
3026 ifp = sc->ifp;
3027 ic = ifp->if_l2com;
3028 vap = TAILQ_FIRST(&ic->ic_vaps);
3030 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3031 "%s: updating RTS threshold: %d\n",
3032 device_get_nameunit(sc->dev), vap->iv_rtsthreshold);
3034 tmp = rt2870_io_mac_read(sc, RT2870_REG_TX_RTS_CFG);
3036 tmp &= ~(RT2870_REG_TX_RTS_THRESHOLD_MASK << RT2870_REG_TX_RTS_THRESHOLD_SHIFT);
3038 threshold = (vap->iv_rtsthreshold < IEEE80211_RTS_MAX) ?
3039 vap->iv_rtsthreshold : 0x1000;
3041 tmp |= ((threshold & RT2870_REG_TX_RTS_THRESHOLD_MASK) <<
3042 RT2870_REG_TX_RTS_THRESHOLD_SHIFT);
3044 rt2870_io_mac_write(sc, RT2870_REG_TX_RTS_CFG, tmp);
3048 * rt2870_asic_update_txpower
3050 static void rt2870_asic_update_txpower(struct rt2870_softc *sc)
3052 struct ifnet *ifp;
3053 struct ieee80211com *ic;
3054 uint32_t *txpow_rate;
3055 int8_t delta;
3056 uint8_t val;
3057 uint32_t tmp;
3058 int i;
3060 ifp = sc->ifp;
3061 ic = ifp->if_l2com;
3063 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3064 "%s: updating Tx power: %d\n",
3065 device_get_nameunit(sc->dev), ic->ic_txpowlimit);
3067 if (!IEEE80211_IS_CHAN_HT40(ic->ic_curchan))
3069 txpow_rate = sc->txpow_rate_20mhz;
3071 else
3073 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
3074 txpow_rate = sc->txpow_rate_40mhz_2ghz;
3075 else
3076 txpow_rate = sc->txpow_rate_40mhz_5ghz;
3079 delta = 0;
3081 val = rt2870_io_bbp_read(sc, 1);
3082 val &= 0xfc;
3084 if (ic->ic_txpowlimit > 90)
3086 /* do nothing */
3088 else if (ic->ic_txpowlimit > 60)
3090 delta -= 1;
3092 else if (ic->ic_txpowlimit > 30)
3094 delta -= 3;
3096 else if (ic->ic_txpowlimit > 15)
3098 val |= 0x1;
3100 else if (ic->ic_txpowlimit > 9)
3102 val |= 0x1;
3103 delta -= 3;
3105 else
3107 val |= 0x2;
3110 rt2870_io_bbp_write(sc, 1, val);
3112 for (i = 0; i < RT2870_SOFTC_TXPOW_RATE_COUNT; i++)
3114 if (txpow_rate[i] == 0xffffffff)
3115 continue;
3117 tmp = rt2870_read_eeprom_txpow_rate_add_delta(txpow_rate[i], delta);
3119 rt2870_io_mac_write(sc, RT2870_REG_TX_PWR_CFG(i), tmp);
3124 * rt2870_asic_update_promisc
3126 static void rt2870_asic_update_promisc(struct rt2870_softc *sc)
3128 struct ifnet *ifp;
3129 uint32_t tmp;
3131 ifp = sc->ifp;
3133 printf("%s: %s promiscuous mode\n",
3134 device_get_nameunit(sc->dev),
3135 (ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving");
3137 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_FILTER_CFG);
3139 tmp &= ~RT2870_REG_RX_FILTER_DROP_UC_NOME;
3141 if (!(ifp->if_flags & IFF_PROMISC))
3142 tmp |= RT2870_REG_RX_FILTER_DROP_UC_NOME;
3144 rt2870_io_mac_write(sc, RT2870_REG_RX_FILTER_CFG, tmp);
3148 * rt2870_asic_updateprot
3150 static void rt2870_asic_updateprot(struct rt2870_softc *sc)
3152 struct ifnet *ifp;
3153 struct ieee80211com *ic;
3154 struct ieee80211vap *vap;
3155 uint32_t cck_prot, ofdm_prot, mm20_prot, mm40_prot, gf20_prot, gf40_prot;
3156 uint8_t htopmode;
3158 ifp = sc->ifp;
3159 ic = ifp->if_l2com;
3160 vap = TAILQ_FIRST(&ic->ic_vaps);
3162 /* CCK frame protection */
3164 cck_prot = RT2870_REG_RTSTH_ENABLE | RT2870_REG_PROT_NAV_SHORT |
3165 RT2870_REG_TXOP_ALLOW_ALL | RT2870_REG_PROT_CTRL_NONE;
3167 /* set up protection frame phy mode and rate (MCS code) */
3169 if (ic->ic_curmode == IEEE80211_MODE_11A)
3170 cck_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3171 (0 << RT2870_REG_PROT_MCS_SHIFT);
3172 else
3173 cck_prot |= ((RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3174 (3 << RT2870_REG_PROT_MCS_SHIFT));
3176 rt2870_io_mac_write(sc, RT2870_REG_TX_CCK_PROT_CFG, cck_prot);
3178 /* OFDM frame protection */
3180 ofdm_prot = RT2870_REG_RTSTH_ENABLE | RT2870_REG_PROT_NAV_SHORT |
3181 RT2870_REG_TXOP_ALLOW_ALL;
3183 if (ic->ic_flags & IEEE80211_F_USEPROT)
3185 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3186 "%s: updating protection mode: b/g protection mode=%s\n",
3187 device_get_nameunit(sc->dev),
3188 (ic->ic_protmode == IEEE80211_PROT_RTSCTS) ? "RTS/CTS" :
3189 ((ic->ic_protmode == IEEE80211_PROT_CTSONLY) ? "CTS-to-self" : "none"));
3191 if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
3192 ofdm_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3193 else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
3194 ofdm_prot |= RT2870_REG_PROT_CTRL_CTS;
3195 else
3196 ofdm_prot |= RT2870_REG_PROT_CTRL_NONE;
3198 else
3200 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3201 "%s: updating protection mode: b/g protection mode=%s\n",
3202 device_get_nameunit(sc->dev), "none");
3204 ofdm_prot |= RT2870_REG_PROT_CTRL_NONE;
3207 rt2870_io_mac_write(sc, RT2870_REG_TX_OFDM_PROT_CFG, ofdm_prot);
3209 /* HT frame protection */
3211 if ((vap->iv_opmode == IEEE80211_M_STA) && (vap->iv_state == IEEE80211_S_RUN))
3212 htopmode = vap->iv_bss->ni_htopmode;
3213 else
3214 htopmode = ic->ic_curhtprotmode;
3216 RT2870_DPRINTF(sc, RT2870_DEBUG_PROT,
3217 "%s: updating protection mode: HT operation mode=0x%02x, protection mode=%s\n",
3218 device_get_nameunit(sc->dev),
3219 htopmode & IEEE80211_HTINFO_OPMODE,
3220 (ic->ic_htprotmode == IEEE80211_PROT_RTSCTS) ? "RTS/CTS" :
3221 ((ic->ic_htprotmode == IEEE80211_PROT_CTSONLY) ? "CTS-to-self" : "none"));
3223 switch (htopmode & IEEE80211_HTINFO_OPMODE)
3225 /* IEEE80211_HTINFO_OPMODE_HT20PR */
3226 case IEEE80211_HTINFO_OPMODE_HT20PR:
3227 mm20_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3228 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3229 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20 |
3230 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3231 (4 << RT2870_REG_PROT_MCS_SHIFT);
3233 gf20_prot = mm20_prot;
3235 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3236 RT2870_REG_TXOP_ALLOW_ALL |
3237 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3238 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
3240 if (ic->ic_htprotmode == IEEE80211_PROT_RTSCTS)
3241 mm40_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3242 else if (ic->ic_htprotmode == IEEE80211_PROT_CTSONLY)
3243 mm40_prot |= RT2870_REG_PROT_CTRL_CTS;
3244 else
3245 mm40_prot |= RT2870_REG_PROT_CTRL_NONE;
3247 gf40_prot = mm40_prot;
3248 break;
3250 /* IEEE80211_HTINFO_OPMODE_MIXED */
3251 case IEEE80211_HTINFO_OPMODE_MIXED:
3252 mm20_prot = RT2870_REG_PROT_NAV_SHORT |
3253 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3254 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20;
3256 if (ic->ic_flags & IEEE80211_F_USEPROT)
3257 mm20_prot |= (RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3258 (3 << RT2870_REG_PROT_MCS_SHIFT);
3259 else
3260 mm20_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3261 (4 << RT2870_REG_PROT_MCS_SHIFT);
3263 if (ic->ic_htprotmode == IEEE80211_PROT_RTSCTS)
3264 mm20_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3265 else if (ic->ic_htprotmode == IEEE80211_PROT_CTSONLY)
3266 mm20_prot |= RT2870_REG_PROT_CTRL_CTS;
3267 else
3268 mm20_prot |= RT2870_REG_PROT_CTRL_NONE;
3270 gf20_prot = mm20_prot;
3272 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_TXOP_ALLOW_ALL;
3274 if (ic->ic_flags & IEEE80211_F_USEPROT)
3275 mm40_prot |= (RT2870_REG_PROT_PHYMODE_CCK << RT2870_REG_PROT_PHYMODE_SHIFT) |
3276 (3 << RT2870_REG_PROT_MCS_SHIFT);
3277 else
3278 mm40_prot |= (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3279 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
3281 if (ic->ic_htprotmode == IEEE80211_PROT_RTSCTS)
3282 mm40_prot |= RT2870_REG_PROT_CTRL_RTS_CTS;
3283 else if (ic->ic_htprotmode == IEEE80211_PROT_CTSONLY)
3284 mm40_prot |= RT2870_REG_PROT_CTRL_CTS;
3285 else
3286 mm40_prot |= RT2870_REG_PROT_CTRL_NONE;
3288 gf40_prot = mm40_prot;
3289 break;
3292 * IEEE80211_HTINFO_OPMODE_PURE
3293 * IEEE80211_HTINFO_OPMODE_PROTOPT
3295 case IEEE80211_HTINFO_OPMODE_PURE:
3296 case IEEE80211_HTINFO_OPMODE_PROTOPT:
3297 default:
3298 mm20_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3299 RT2870_REG_TXOP_ALLOW_CCK | RT2870_REG_TXOP_ALLOW_OFDM |
3300 RT2870_REG_TXOP_ALLOW_MM20 | RT2870_REG_TXOP_ALLOW_GF20 |
3301 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3302 (4 << RT2870_REG_PROT_MCS_SHIFT);
3304 gf20_prot = mm20_prot;
3306 mm40_prot = RT2870_REG_PROT_NAV_SHORT | RT2870_REG_PROT_CTRL_NONE |
3307 RT2870_REG_TXOP_ALLOW_ALL |
3308 (RT2870_REG_PROT_PHYMODE_OFDM << RT2870_REG_PROT_PHYMODE_SHIFT) |
3309 (0x84 << RT2870_REG_PROT_MCS_SHIFT);
3311 gf40_prot = mm40_prot;
3312 break;
3315 rt2870_io_mac_write(sc, RT2870_REG_TX_MM20_PROT_CFG, mm20_prot);
3316 rt2870_io_mac_write(sc, RT2870_REG_TX_MM40_PROT_CFG, mm40_prot);
3317 rt2870_io_mac_write(sc, RT2870_REG_TX_GF20_PROT_CFG, gf20_prot);
3318 rt2870_io_mac_write(sc, RT2870_REG_TX_GF40_PROT_CFG, gf40_prot);
3322 * rt2870_asic_updateslot
3324 static void rt2870_asic_updateslot(struct rt2870_softc *sc)
3326 struct ifnet *ifp;
3327 struct ieee80211com *ic;
3328 uint32_t tmp;
3330 ifp = sc->ifp;
3331 ic = ifp->if_l2com;
3333 RT2870_DPRINTF(sc, RT2870_DEBUG_STATE,
3334 "%s: %s short slot time\n",
3335 device_get_nameunit(sc->dev),
3336 (ic->ic_flags & IEEE80211_F_SHSLOT) ? "enabling" : "disabling");
3338 tmp = rt2870_io_mac_read(sc, RT2870_REG_BKOFF_SLOT_CFG);
3340 tmp &= ~0xff;
3341 tmp |= (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
3343 rt2870_io_mac_write(sc, RT2870_REG_BKOFF_SLOT_CFG, tmp);
3347 * rt2870_asic_wme_update
3349 static void rt2870_asic_wme_update(struct rt2870_softc *sc)
3351 struct ifnet *ifp;
3352 struct ieee80211com *ic;
3353 struct ieee80211_wme_state *wme;
3354 const struct wmeParams *wmep;
3355 int i;
3357 ifp = sc->ifp;
3358 ic = ifp->if_l2com;
3359 wme = &ic->ic_wme;
3360 wmep = wme->wme_chanParams.cap_wmeParams;
3362 RT2870_DPRINTF(sc, RT2870_DEBUG_WME,
3363 "%s: wme update: WME_AC_VO=%d/%d/%d/%d, WME_AC_VI=%d/%d/%d/%d, "
3364 "WME_AC_BK=%d/%d/%d/%d, WME_AC_BE=%d/%d/%d/%d\n",
3365 device_get_nameunit(sc->dev),
3366 wmep[WME_AC_VO].wmep_aifsn,
3367 wmep[WME_AC_VO].wmep_logcwmin, wmep[WME_AC_VO].wmep_logcwmax,
3368 wmep[WME_AC_VO].wmep_txopLimit,
3369 wmep[WME_AC_VI].wmep_aifsn,
3370 wmep[WME_AC_VI].wmep_logcwmin, wmep[WME_AC_VI].wmep_logcwmax,
3371 wmep[WME_AC_VI].wmep_txopLimit,
3372 wmep[WME_AC_BK].wmep_aifsn,
3373 wmep[WME_AC_BK].wmep_logcwmin, wmep[WME_AC_BK].wmep_logcwmax,
3374 wmep[WME_AC_BK].wmep_txopLimit,
3375 wmep[WME_AC_BE].wmep_aifsn,
3376 wmep[WME_AC_BE].wmep_logcwmin, wmep[WME_AC_BE].wmep_logcwmax,
3377 wmep[WME_AC_BE].wmep_txopLimit);
3379 for (i = 0; i < WME_NUM_AC; i++)
3380 rt2870_io_mac_write(sc, RT2870_REG_TX_EDCA_AC_CFG(i),
3381 (wmep[i].wmep_logcwmax << 16) | (wmep[i].wmep_logcwmin << 12) |
3382 (wmep[i].wmep_aifsn << 8) | wmep[i].wmep_txopLimit);
3384 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_AIFSN_CFG,
3385 (wmep[WME_AC_VO].wmep_aifsn << 12) | (wmep[WME_AC_VI].wmep_aifsn << 8) |
3386 (wmep[WME_AC_BK].wmep_aifsn << 4) | wmep[WME_AC_BE].wmep_aifsn);
3388 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_CWMIN_CFG,
3389 (wmep[WME_AC_VO].wmep_logcwmin << 12) | (wmep[WME_AC_VI].wmep_logcwmin << 8) |
3390 (wmep[WME_AC_BK].wmep_logcwmin << 4) | wmep[WME_AC_BE].wmep_logcwmin);
3392 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_CWMAX_CFG,
3393 (wmep[WME_AC_VO].wmep_logcwmax << 12) | (wmep[WME_AC_VI].wmep_logcwmax << 8) |
3394 (wmep[WME_AC_BK].wmep_logcwmax << 4) | wmep[WME_AC_BE].wmep_logcwmax);
3396 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP0_CFG,
3397 (wmep[WME_AC_BK].wmep_txopLimit << 16) | wmep[WME_AC_BE].wmep_txopLimit);
3399 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP1_CFG,
3400 (wmep[WME_AC_VO].wmep_txopLimit << 16) | wmep[WME_AC_VI].wmep_txopLimit);
3404 * rt2870_asic_update_beacon
3406 static int rt2870_asic_update_beacon(struct rt2870_softc *sc,
3407 struct ieee80211vap *vap)
3409 struct ifnet *ifp;
3410 struct ieee80211com *ic;
3411 struct rt2870_softc_vap *rvap;
3412 const struct ieee80211_txparam *tp;
3413 struct mbuf *m;
3414 struct rt2870_txwi txwi;
3415 uint8_t rate, mcs;
3416 uint32_t tmp;
3418 ifp = sc->ifp;
3419 ic = ifp->if_l2com;
3420 rvap = (struct rt2870_softc_vap *) vap;
3421 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
3423 m = ieee80211_beacon_alloc(vap->iv_bss, &rvap->beacon_offsets);
3424 if (m == NULL)
3425 return ENOMEM;
3427 rate = tp->mgmtrate;
3428 mcs = rt2870_rate2mcs(rate);
3430 memset(&txwi, 0, sizeof(struct rt2870_txwi));
3432 txwi.wcid = 0xff;
3433 txwi.pid_mpdu_len = ((htole16(m->m_pkthdr.len) & RT2870_TXWI_MPDU_LEN_MASK) <<
3434 RT2870_TXWI_MPDU_LEN_SHIFT);
3435 txwi.txop = (RT2870_TXWI_TXOP_HT << RT2870_TXWI_TXOP_SHIFT);
3436 txwi.mpdu_density_flags |=
3437 (RT2870_TXWI_FLAGS_TS << RT2870_TXWI_FLAGS_SHIFT);
3438 txwi.bawin_size_xflags |=
3439 (RT2870_TXWI_XFLAGS_NSEQ << RT2870_TXWI_XFLAGS_SHIFT);
3441 if (ieee80211_rate2phytype(ic->ic_rt, rate) != IEEE80211_T_OFDM)
3443 txwi.phymode_ifs_stbc_shortgi =
3444 (RT2870_TXWI_PHYMODE_CCK << RT2870_TXWI_PHYMODE_SHIFT);
3446 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
3447 mcs |= RT2870_TXWI_MCS_SHOTPRE;
3449 else
3451 txwi.phymode_ifs_stbc_shortgi =
3452 (RT2870_TXWI_PHYMODE_OFDM << RT2870_TXWI_PHYMODE_SHIFT);
3455 txwi.bw_mcs = (RT2870_TXWI_BW_20 << RT2870_TXWI_BW_SHIFT) |
3456 ((mcs & RT2870_TXWI_MCS_MASK) << RT2870_TXWI_MCS_SHIFT);
3458 /* disable temporarily TSF sync */
3460 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
3462 tmp &= ~(RT2870_REG_BCN_TX_ENABLE |
3463 RT2870_REG_TSF_TIMER_ENABLE |
3464 RT2870_REG_TBTT_TIMER_ENABLE);
3466 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
3468 /* write Tx wireless info and beacon frame to on-chip memory */
3470 rt2870_io_mac_write_multi(sc, RT2870_REG_BEACON_BASE(0),
3471 &txwi, sizeof(struct rt2870_txwi));
3473 rt2870_io_mac_write_multi(sc, RT2870_REG_BEACON_BASE(0) + sizeof(struct rt2870_txwi),
3474 mtod(m, uint8_t *), m->m_pkthdr.len);
3476 /* enable again TSF sync */
3478 tmp = rt2870_io_mac_read(sc, RT2870_REG_BCN_TIME_CFG);
3480 tmp |= (RT2870_REG_BCN_TX_ENABLE |
3481 RT2870_REG_TSF_TIMER_ENABLE |
3482 RT2870_REG_TBTT_TIMER_ENABLE);
3484 rt2870_io_mac_write(sc, RT2870_REG_BCN_TIME_CFG, tmp);
3486 m_freem(m);
3488 return 0;
3492 * rt2870_asic_clear_keytables
3494 static void rt2870_asic_clear_keytables(struct rt2870_softc *sc)
3496 int i;
3498 /* clear Rx WCID search table (entries = 256, entry size = 8) */
3500 for (i = 0; i < 256; i++)
3502 rt2870_io_mac_write(sc, RT2870_REG_WCID(i), 0xffffffff);
3503 rt2870_io_mac_write(sc, RT2870_REG_WCID(i) + 4, 0x0000ffff);
3506 /* clear WCID attribute table (entries = 256, entry size = 4) */
3508 rt2870_io_mac_set_region_4(sc, RT2870_REG_WCID_ATTR(0), 0, 256);
3510 /* clear IV/EIV table (entries = 256, entry size = 8) */
3512 rt2870_io_mac_set_region_4(sc, RT2870_REG_IVEIV(0), 0, 2 * 256);
3514 /* clear pairwise key table (entries = 256, entry size = 32) */
3516 rt2870_io_mac_set_region_4(sc, RT2870_REG_PKEY(0), 0, 8 * 256);
3518 /* clear shared key table (entries = 32, entry size = 32) */
3520 rt2870_io_mac_set_region_4(sc, RT2870_REG_SKEY(0, 0), 0, 8 * 32);
3522 /* clear shared key mode (entries = 32, entry size = 2) */
3524 rt2870_io_mac_set_region_4(sc, RT2870_REG_SKEY_MODE(0), 0, 16);
3528 * rt2870_rxrate
3530 static uint8_t rt2870_rxrate(struct rt2870_rxwi *rxwi)
3532 uint8_t mcs, phymode;
3533 uint8_t rate;
3535 mcs = (rxwi->bw_mcs >> RT2870_RXWI_MCS_SHIFT) & RT2870_RXWI_MCS_MASK;
3536 phymode = (rxwi->phymode_stbc_shortgi >> RT2870_RXWI_PHYMODE_SHIFT) &
3537 RT2870_RXWI_PHYMODE_MASK;
3539 rate = 2;
3541 switch (phymode)
3543 case RT2870_RXWI_PHYMODE_CCK:
3544 switch (mcs & ~RT2870_RXWI_MCS_SHOTPRE)
3546 case 0: rate = 2; break; /* 1 Mbps */
3547 case 1: rate = 4; break; /* 2 MBps */
3548 case 2: rate = 11; break; /* 5.5 Mbps */
3549 case 3: rate = 22; break; /* 11 Mbps */
3551 break;
3553 case RT2870_RXWI_PHYMODE_OFDM:
3554 switch (mcs)
3556 case 0: rate = 12; break; /* 6 Mbps */
3557 case 1: rate = 18; break; /* 9 Mbps */
3558 case 2: rate = 24; break; /* 12 Mbps */
3559 case 3: rate = 36; break; /* 18 Mbps */
3560 case 4: rate = 48; break; /* 24 Mbps */
3561 case 5: rate = 72; break; /* 36 Mbps */
3562 case 6: rate = 96; break; /* 48 Mbps */
3563 case 7: rate = 108; break; /* 54 Mbps */
3565 break;
3567 case RT2870_RXWI_PHYMODE_HT_MIXED:
3568 case RT2870_RXWI_PHYMODE_HT_GF:
3569 break;
3572 return rate;
3576 * rt2870_maxrssi_rxpath
3578 static uint8_t rt2870_maxrssi_rxpath(struct rt2870_softc *sc,
3579 const struct rt2870_rxwi *rxwi)
3581 uint8_t rxpath;
3583 rxpath = 0;
3585 if (sc->nrxpath > 1)
3586 if (rxwi->rssi[1] > rxwi->rssi[rxpath])
3587 rxpath = 1;
3589 if (sc->nrxpath > 2)
3590 if (rxwi->rssi[2] > rxwi->rssi[rxpath])
3591 rxpath = 2;
3593 return rxpath;
3597 * rt2870_rssi2dbm
3599 static int8_t rt2870_rssi2dbm(struct rt2870_softc *sc,
3600 uint8_t rssi, uint8_t rxpath)
3602 struct ifnet *ifp;
3603 struct ieee80211com *ic;
3604 struct ieee80211_channel *c;
3605 int chan;
3606 int8_t rssi_off, lna_gain;
3608 if (rssi == 0)
3609 return -99;
3611 ifp = sc->ifp;
3612 ic = ifp->if_l2com;
3613 c = ic->ic_curchan;
3614 chan = ieee80211_chan2ieee(ic, c);
3616 if (IEEE80211_IS_CHAN_5GHZ(c))
3618 rssi_off = sc->rssi_off_5ghz[rxpath];
3620 if (chan <= 64)
3621 lna_gain = sc->lna_gain[1];
3622 else if (chan <= 128)
3623 lna_gain = sc->lna_gain[2];
3624 else
3625 lna_gain = sc->lna_gain[3];
3627 else
3629 rssi_off = sc->rssi_off_2ghz[rxpath];
3630 lna_gain = sc->lna_gain[0];
3633 return (-12 - rssi_off - lna_gain - rssi);
3637 * rt2870_rate2mcs
3639 static uint8_t rt2870_rate2mcs(uint8_t rate)
3641 switch (rate)
3643 /* CCK rates */
3644 case 2: return 0;
3645 case 4: return 1;
3646 case 11: return 2;
3647 case 22: return 3;
3649 /* OFDM rates */
3650 case 12: return 0;
3651 case 18: return 1;
3652 case 24: return 2;
3653 case 36: return 3;
3654 case 48: return 4;
3655 case 72: return 5;
3656 case 96: return 6;
3657 case 108: return 7;
3660 return 0;
3664 * rt2870_rx_frame
3666 static void rt2870_rx_frame(struct rt2870_softc *sc,
3667 uint8_t *buf, uint32_t dmalen)
3669 struct ifnet *ifp;
3670 struct ieee80211com *ic;
3671 struct ieee80211_frame *wh;
3672 struct ieee80211_node *ni;
3673 struct rt2870_softc_rx_radiotap_header *tap;
3674 struct rt2870_rxwi *rxwi;
3675 struct rt2870_rxinfo *rxinfo;
3676 struct mbuf *m;
3677 uint32_t rxinfo_flags;
3678 uint8_t cipher_err, rssi, ant, phymode, bw, shortgi, mcs;
3679 int8_t rssi_dbm;
3680 int len, ampdu, amsdu;
3682 ifp = sc->ifp;
3683 ic = ifp->if_l2com;
3685 /* get Rx wireless info */
3687 rxwi = (struct rt2870_rxwi *) buf;
3688 len = (le16toh(rxwi->tid_size) >> RT2870_RXWI_SIZE_SHIFT) &
3689 RT2870_RXWI_SIZE_MASK;
3691 if (len > dmalen)
3693 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3694 "%s: bad rxwi len: DMA len=%d, rxwi len=%d\n",
3695 device_get_nameunit(sc->dev), dmalen, len);
3696 return;
3699 /* get Rx info */
3701 rxinfo = (struct rt2870_rxinfo *) ((caddr_t) rxwi + dmalen);
3702 rxinfo_flags = le32toh(rxinfo->flags);
3704 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3705 "%s: Rx frame: DMA len=%d, len=%d, rxinfo flags=0x%08x\n",
3706 device_get_nameunit(sc->dev), dmalen, len, rxinfo_flags);
3708 /* check for crc errors */
3710 if (rxinfo_flags & RT2870_RXINFO_FLAGS_CRC_ERR)
3712 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3713 "%s: rxinfo: crc error\n",
3714 device_get_nameunit(sc->dev));
3716 ifp->if_ierrors++;
3718 if (!(ifp->if_flags & IFF_PROMISC))
3719 return;
3722 wh = (struct ieee80211_frame *) (rxwi + 1);
3724 /* check for L2 padding between IEEE 802.11 frame header and body */
3726 if (rxinfo_flags & RT2870_RXINFO_FLAGS_L2PAD)
3728 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3729 "%s: L2 padding: DMA len=%d, len=%d\n",
3730 device_get_nameunit(sc->dev), dmalen, len);
3732 len += 2;
3735 m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
3736 if (m == NULL)
3738 sc->rx_mbuf_alloc_errors++;
3739 ifp->if_ierrors++;
3740 return;
3743 m->m_pkthdr.rcvif = ifp;
3744 m->m_pkthdr.len = m->m_len = len;
3746 m_copyback(m, 0, len, (caddr_t) wh);
3748 wh = mtod(m, struct ieee80211_frame *);
3750 /* check for cipher errors */
3752 if (rxinfo_flags & RT2870_RXINFO_FLAGS_DECRYPTED)
3754 cipher_err = ((rxinfo_flags >> RT2870_RXINFO_FLAGS_CIPHER_ERR_SHIFT) &
3755 RT2870_RXINFO_FLAGS_CIPHER_ERR_MASK);
3756 if (cipher_err == RT2870_RXINFO_FLAGS_CIPHER_ERR_NONE)
3758 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
3759 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
3761 m->m_flags |= M_WEP;
3763 else
3765 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3766 "%s: rxinfo: cipher error=0x%02x\n",
3767 device_get_nameunit(sc->dev), cipher_err);
3769 ifp->if_ierrors++;
3771 if (!(ifp->if_flags & IFF_PROMISC))
3773 m_free(m);
3774 return;
3778 else
3780 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
3782 ifp->if_ierrors++;
3784 if (!(ifp->if_flags & IFF_PROMISC))
3786 m_free(m);
3787 return;
3792 /* check for A-MPDU */
3794 if (rxinfo_flags & RT2870_RXINFO_FLAGS_AMPDU)
3796 m->m_flags |= M_AMPDU;
3797 ampdu = 1;
3799 else
3801 ampdu = 0;
3804 ant = rt2870_maxrssi_rxpath(sc, rxwi);
3805 rssi = rxwi->rssi[ant];
3806 rssi_dbm = rt2870_rssi2dbm(sc, rssi, ant);
3807 phymode = ((rxwi->phymode_stbc_shortgi >> RT2870_RXWI_PHYMODE_SHIFT) &
3808 RT2870_RXWI_PHYMODE_MASK);
3809 bw = ((rxwi->bw_mcs >> RT2870_RXWI_BW_SHIFT) & RT2870_RXWI_BW_MASK);
3810 shortgi = ((rxwi->phymode_stbc_shortgi >> RT2870_RXWI_SHORTGI_SHIFT) &
3811 RT2870_RXWI_SHORTGI_MASK);
3812 mcs = ((rxwi->bw_mcs >> RT2870_RXWI_MCS_SHIFT) & RT2870_RXWI_MCS_MASK);
3813 amsdu = (rxinfo_flags & RT2870_RXINFO_FLAGS_AMSDU);
3815 if (ieee80211_radiotap_active(ic))
3817 tap = &sc->rxtap;
3819 tap->flags = (rxinfo_flags & RT2870_RXINFO_FLAGS_L2PAD) ? IEEE80211_RADIOTAP_F_DATAPAD : 0;
3820 tap->dbm_antsignal = rssi_dbm;
3821 tap->dbm_antnoise = RT2870_NOISE_FLOOR;
3822 tap->antenna = ant;
3823 tap->antsignal = rssi;
3824 tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
3825 tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
3826 tap->chan_ieee = ic->ic_curchan->ic_ieee;
3827 tap->chan_maxpow = 0;
3829 if (phymode == RT2870_RXWI_PHYMODE_CCK || phymode == RT2870_RXWI_PHYMODE_OFDM)
3830 tap->rate = rt2870_rxrate(rxwi);
3831 else
3832 tap->rate = mcs | IEEE80211_RATE_MCS;
3834 if (rxwi->bw_mcs & RT2870_RXWI_MCS_SHOTPRE)
3835 tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
3837 if (shortgi)
3838 tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
3841 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
3842 "%s: received frame: len=%d, phymode=%d, bw=%d, shortgi=%d, mcs=%d, "
3843 "ant=%d, rssi=%d/%d/%d, snr=%d/%d, wcid=0x%02x, ampdu=%d, amsdu=%d\n",
3844 device_get_nameunit(sc->dev),
3845 len, phymode, bw, shortgi, mcs,
3846 ant, rxwi->rssi[0], rxwi->rssi[1], rxwi->rssi[2],
3847 rxwi->snr[0], rxwi->snr[1],
3848 rxwi->wcid, ampdu, amsdu);
3850 ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *) wh);
3851 if (ni != NULL)
3853 ieee80211_input(ni, m, rssi_dbm - RT2870_NOISE_FLOOR, RT2870_NOISE_FLOOR);
3854 ieee80211_free_node(ni);
3856 else
3858 ieee80211_input_all(ic, m, rssi_dbm - RT2870_NOISE_FLOOR, RT2870_NOISE_FLOOR);
3863 * rt2870_tx_mgmt
3865 static int rt2870_tx_mgmt(struct rt2870_softc *sc,
3866 struct mbuf *m, struct ieee80211_node *ni, int qid)
3868 struct ifnet *ifp;
3869 struct ieee80211com *ic;
3870 struct ieee80211vap *vap;
3871 const struct ieee80211_txparam *tp;
3872 struct rt2870_softc_node *rni;
3873 struct rt2870_softc_tx_ring *ring;
3874 struct rt2870_softc_tx_data *data;
3875 struct rt2870_txinfo *txinfo;
3876 struct rt2870_txwi *txwi;
3877 struct ieee80211_frame *wh;
3878 struct rt2870_softc_tx_radiotap_header *tap;
3879 u_int hdrsize, hdrspace;
3880 uint8_t rate, stbc, shortgi, mcs, pid;
3881 uint16_t len, dmalen, mpdu_len, dur;
3883 KASSERT(qid >= 0 && qid < (sc->usb_endpoints - 1),
3884 ("%s: Tx MGMT: invalid qid=%d\n",
3885 device_get_nameunit(sc->dev), qid));
3887 ifp = sc->ifp;
3888 ic = ifp->if_l2com;
3889 vap = ni->ni_vap;
3890 rni = (struct rt2870_softc_node *) ni;
3891 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
3893 ring = &sc->tx_ring[qid];
3894 data = STAILQ_FIRST(&ring->inactive);
3895 STAILQ_REMOVE_HEAD(&ring->inactive, next);
3896 txinfo = (struct rt2870_txinfo *) data->buf;
3897 txwi = (struct rt2870_txwi *) (txinfo + 1);
3899 wh = mtod(m, struct ieee80211_frame *);
3901 rate = tp->mgmtrate & IEEE80211_RATE_VAL;
3903 len = sizeof(struct rt2870_txinfo) + sizeof(struct rt2870_txwi) + m->m_pkthdr.len;
3905 /* align end on a 4-bytes boundary */
3907 dmalen = (len + 3) & ~3;
3909 /* fill Tx info */
3911 memset(txinfo, 0, sizeof(struct rt2870_txinfo));
3913 txinfo->len = htole16(dmalen - sizeof(struct rt2870_txinfo));
3915 txinfo->qsel_flags = (RT2870_TXINFO_QSEL_EDCA << RT2870_TXINFO_QSEL_SHIFT);
3917 dmalen += 4;
3919 memset((caddr_t) txinfo + len, 0, dmalen - len);
3921 /* fill Tx wireless info */
3923 if (ni->ni_flags & IEEE80211_NODE_HT)
3924 mcs = rate;
3925 else
3926 mcs = rt2870_rate2mcs(rate);
3928 pid = mcs;
3930 /* calculate MPDU length without padding */
3932 hdrsize = ieee80211_hdrsize(wh);
3933 hdrspace = ieee80211_hdrspace(ic, wh);
3934 mpdu_len = m->m_pkthdr.len - hdrspace + hdrsize;
3936 memset(txwi, 0, sizeof(struct rt2870_txwi));
3938 /* management frames do not need encryption */
3940 txwi->wcid = 0xff;
3942 txwi->pid_mpdu_len = ((htole16(pid) & RT2870_TXWI_PID_MASK) <<
3943 RT2870_TXWI_PID_SHIFT) | ((htole16(mpdu_len) & RT2870_TXWI_MPDU_LEN_MASK) <<
3944 RT2870_TXWI_MPDU_LEN_SHIFT);
3946 stbc = (ni->ni_htcap & IEEE80211_HTCAP_RXSTBC) ? 1 : 0;
3948 shortgi = (vap->iv_flags_ht & (IEEE80211_FHT_SHORTGI20 | IEEE80211_FHT_SHORTGI40)) &&
3949 (ni->ni_flags & IEEE80211_NODE_HT);
3951 txwi->phymode_ifs_stbc_shortgi |=
3952 ((stbc & RT2870_TXWI_STBC_MASK) << RT2870_TXWI_STBC_SHIFT) |
3953 ((shortgi & RT2870_TXWI_SHORTGI_MASK) << RT2870_TXWI_SHORTGI_SHIFT);
3955 txwi->phymode_ifs_stbc_shortgi |=
3956 ((shortgi & RT2870_TXWI_SHORTGI_MASK) << RT2870_TXWI_SHORTGI_SHIFT);
3958 if (ni->ni_flags & IEEE80211_NODE_HT)
3960 txwi->phymode_ifs_stbc_shortgi |=
3961 (RT2870_TXWI_PHYMODE_HT_MIXED << RT2870_TXWI_PHYMODE_SHIFT);
3963 else
3965 if (ieee80211_rate2phytype(ic->ic_rt, rate) != IEEE80211_T_OFDM)
3967 txwi->phymode_ifs_stbc_shortgi |=
3968 (RT2870_TXWI_PHYMODE_CCK << RT2870_TXWI_PHYMODE_SHIFT);
3970 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
3971 mcs |= RT2870_TXWI_MCS_SHOTPRE;
3973 else
3975 txwi->phymode_ifs_stbc_shortgi |=
3976 (RT2870_TXWI_PHYMODE_OFDM << RT2870_TXWI_PHYMODE_SHIFT);
3980 txwi->bw_mcs = (RT2870_TXWI_BW_20 << RT2870_TXWI_BW_SHIFT) |
3981 ((mcs & RT2870_TXWI_MCS_MASK) << RT2870_TXWI_MCS_SHIFT);
3983 txwi->txop = (RT2870_TXWI_TXOP_BACKOFF << RT2870_TXWI_TXOP_SHIFT);
3985 /* skip ACKs for multicast frames and probe responses */
3987 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
3988 ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) !=
3989 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP)))
3991 txwi->bawin_size_xflags |=
3992 (RT2870_TXWI_XFLAGS_ACK << RT2870_TXWI_XFLAGS_SHIFT);
3994 if (ni->ni_flags & IEEE80211_NODE_HT)
3996 /* preamble + plcp + signal extension */
3998 dur = 16 + 4 + 6;
4000 else
4002 dur = ieee80211_ack_duration(ic->ic_rt, rate,
4003 ic->ic_flags & IEEE80211_F_SHPREAMBLE);
4006 *(uint16_t *) wh->i_dur = htole16(dur);
4009 /* ask MAC to insert timestamp into probe responses */
4011 if ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
4012 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
4013 txwi->mpdu_density_flags |=
4014 (RT2870_TXWI_FLAGS_TS << RT2870_TXWI_FLAGS_SHIFT);
4016 if (ieee80211_radiotap_active_vap(vap))
4018 tap = &sc->txtap;
4020 tap->flags = IEEE80211_RADIOTAP_F_DATAPAD;
4021 tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
4022 tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
4023 tap->chan_ieee = ic->ic_curchan->ic_ieee;
4024 tap->chan_maxpow = 0;
4026 if (ni->ni_flags & IEEE80211_NODE_HT)
4027 tap->rate = mcs | IEEE80211_RATE_MCS;
4028 else
4029 tap->rate = rate;
4031 if (mcs & RT2870_TXWI_MCS_SHOTPRE)
4032 tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
4034 if (shortgi)
4035 tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
4037 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4038 tap->flags |= IEEE80211_RADIOTAP_F_WEP;
4040 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4042 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
4044 ieee80211_radiotap_tx(vap, m);
4046 wh->i_fc[1] |= IEEE80211_FC1_WEP;
4048 else
4050 ieee80211_radiotap_tx(vap, m);
4054 m_copydata(m, 0, m->m_pkthdr.len, (caddr_t) (txwi + 1));
4056 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4057 "%s: sending MGMT frame: qid=%d, hdrsize=%d, hdrspace=%d, len=%d, "
4058 "stbc=%d, shortgi=%d, mcs=%d, DMA len=%d\n",
4059 device_get_nameunit(sc->dev),
4060 qid, hdrsize, hdrspace, m->m_pkthdr.len, stbc, shortgi, mcs, dmalen);
4062 data->len = dmalen;
4063 data->m = m;
4064 data->ni = ni;
4066 STAILQ_INSERT_TAIL(&ring->pending, data, next);
4067 ring->queued++;
4069 usbd_transfer_start(sc->usb_xfer[1 + qid]);
4071 return 0;
4075 * rt2870_tx_data
4077 static int rt2870_tx_data(struct rt2870_softc *sc,
4078 struct mbuf *m, struct ieee80211_node *ni, int qid)
4080 struct ifnet *ifp;
4081 struct ieee80211com *ic;
4082 struct ieee80211vap *vap;
4083 const struct ieee80211_txparam *tp;
4084 struct rt2870_softc_node *rni;
4085 struct rt2870_softc_tx_ring *ring;
4086 struct rt2870_softc_tx_data *data;
4087 struct rt2870_txinfo *txinfo;
4088 struct rt2870_txwi *txwi;
4089 struct ieee80211_frame *wh;
4090 struct rt2870_softc_tx_radiotap_header *tap;
4091 u_int hdrsize, hdrspace;
4092 uint8_t type, rate, bw, stbc, shortgi, mcs, pid, wcid;
4093 uint16_t qos, len, dmalen, mpdu_len, dur;
4094 int hasqos;
4096 KASSERT(qid >= 0 && qid < (sc->usb_endpoints - 1),
4097 ("%s: Tx data: invalid qid=%d\n",
4098 device_get_nameunit(sc->dev), qid));
4100 ifp = sc->ifp;
4101 ic = ifp->if_l2com;
4102 vap = ni->ni_vap;
4103 rni = (struct rt2870_softc_node *) ni;
4104 tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
4106 ring = &sc->tx_ring[qid];
4107 data = STAILQ_FIRST(&ring->inactive);
4108 STAILQ_REMOVE_HEAD(&ring->inactive, next);
4109 txinfo = (struct rt2870_txinfo *) data->buf;
4110 txwi = (struct rt2870_txwi *) (txinfo + 1);
4112 wh = mtod(m, struct ieee80211_frame *);
4114 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
4116 hasqos = IEEE80211_QOS_HAS_SEQ(wh);
4117 if (hasqos)
4119 if (IEEE80211_HAS_ADDR4(wh))
4120 qos = le16toh(*(const uint16_t *)
4121 (((struct ieee80211_qosframe_addr4 *) wh)->i_qos));
4122 else
4123 qos = le16toh(*(const uint16_t *)
4124 (((struct ieee80211_qosframe *) wh)->i_qos));
4126 else
4128 qos = 0;
4131 if (IEEE80211_IS_MULTICAST(wh->i_addr1))
4132 rate = tp->mcastrate;
4133 else if (m->m_flags & M_EAPOL)
4134 rate = tp->mgmtrate;
4135 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
4136 rate = tp->ucastrate;
4137 else
4138 rate = ni->ni_txrate;
4140 rate &= IEEE80211_RATE_VAL;
4142 len = sizeof(struct rt2870_txinfo) + sizeof(struct rt2870_txwi) + m->m_pkthdr.len;
4144 /* align end on a 4-bytes boundary */
4146 dmalen = (len + 3) & ~3;
4148 /* fill Tx info */
4150 memset(txinfo, 0, sizeof(struct rt2870_txinfo));
4152 txinfo->len = htole16(dmalen - sizeof(struct rt2870_txinfo));
4154 txinfo->qsel_flags = (RT2870_TXINFO_QSEL_EDCA << RT2870_TXINFO_QSEL_SHIFT);
4156 dmalen += 4;
4158 memset((caddr_t) txinfo + len, 0, dmalen - len);
4160 /* fill Tx wireless info */
4162 if (ni->ni_flags & IEEE80211_NODE_HT)
4163 mcs = rate;
4164 else
4165 mcs = rt2870_rate2mcs(rate);
4167 pid = mcs;
4169 wcid = (type == IEEE80211_FC0_TYPE_DATA) ?
4170 RT2870_AID2WCID(ni->ni_associd) : 0xff;
4172 /* calculate MPDU length without padding */
4174 hdrsize = ieee80211_hdrsize(wh);
4175 hdrspace = ieee80211_hdrspace(ic, wh);
4176 mpdu_len = m->m_pkthdr.len - hdrspace + hdrsize;
4178 memset(txwi, 0, sizeof(struct rt2870_txwi));
4180 txwi->wcid = wcid;
4182 txwi->pid_mpdu_len = ((htole16(pid) & RT2870_TXWI_PID_MASK) <<
4183 RT2870_TXWI_PID_SHIFT) | ((htole16(mpdu_len) & RT2870_TXWI_MPDU_LEN_MASK) <<
4184 RT2870_TXWI_MPDU_LEN_SHIFT);
4186 stbc = (ni->ni_htcap & IEEE80211_HTCAP_RXSTBC) ? 1 : 0;
4188 shortgi = (vap->iv_flags_ht & (IEEE80211_FHT_SHORTGI20 | IEEE80211_FHT_SHORTGI40)) &&
4189 (ni->ni_flags & IEEE80211_NODE_HT);
4191 txwi->phymode_ifs_stbc_shortgi |=
4192 ((stbc & RT2870_TXWI_STBC_MASK) << RT2870_TXWI_STBC_SHIFT) |
4193 ((shortgi & RT2870_TXWI_SHORTGI_MASK) << RT2870_TXWI_SHORTGI_SHIFT);
4195 if (ni->ni_flags & IEEE80211_NODE_HT)
4197 txwi->phymode_ifs_stbc_shortgi |=
4198 (RT2870_TXWI_PHYMODE_HT_MIXED << RT2870_TXWI_PHYMODE_SHIFT);
4200 else
4202 if (ieee80211_rate2phytype(ic->ic_rt, rate) != IEEE80211_T_OFDM)
4204 txwi->phymode_ifs_stbc_shortgi |=
4205 (RT2870_TXWI_PHYMODE_CCK << RT2870_TXWI_PHYMODE_SHIFT);
4207 if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
4208 mcs |= RT2870_TXWI_MCS_SHOTPRE;
4210 else
4212 txwi->phymode_ifs_stbc_shortgi |=
4213 (RT2870_TXWI_PHYMODE_OFDM << RT2870_TXWI_PHYMODE_SHIFT);
4217 if ((ni->ni_flags & IEEE80211_NODE_HT) &&
4218 (ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40))
4219 bw = RT2870_TXWI_BW_40;
4220 else
4221 bw = RT2870_TXWI_BW_20;
4223 txwi->bw_mcs = ((bw & RT2870_TXWI_BW_MASK) << RT2870_TXWI_BW_SHIFT) |
4224 ((mcs & RT2870_TXWI_MCS_MASK) << RT2870_TXWI_MCS_SHIFT);
4226 txwi->txop = (RT2870_TXWI_TXOP_HT << RT2870_TXWI_TXOP_SHIFT);
4228 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
4229 (!hasqos || (qos & IEEE80211_QOS_ACKPOLICY) != IEEE80211_QOS_ACKPOLICY_NOACK))
4231 txwi->bawin_size_xflags |=
4232 (RT2870_TXWI_XFLAGS_ACK << RT2870_TXWI_XFLAGS_SHIFT);
4234 if (ni->ni_flags & IEEE80211_NODE_HT)
4236 /* preamble + plcp + signal extension */
4238 dur = 16 + 4 + 6;
4240 else
4242 dur = ieee80211_ack_duration(ic->ic_rt, rate,
4243 ic->ic_flags & IEEE80211_F_SHPREAMBLE);
4246 *(uint16_t *) wh->i_dur = htole16(dur);
4249 /* ask MAC to insert timestamp into probe responses */
4251 if ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
4252 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
4253 txwi->mpdu_density_flags |=
4254 (RT2870_TXWI_FLAGS_TS << RT2870_TXWI_FLAGS_SHIFT);
4256 if (ieee80211_radiotap_active_vap(vap))
4258 tap = &sc->txtap;
4260 tap->flags = IEEE80211_RADIOTAP_F_DATAPAD;
4261 tap->chan_flags = htole32(ic->ic_curchan->ic_flags);
4262 tap->chan_freq = htole16(ic->ic_curchan->ic_freq);
4263 tap->chan_ieee = ic->ic_curchan->ic_ieee;
4264 tap->chan_maxpow = 0;
4266 if (ni->ni_flags & IEEE80211_NODE_HT)
4267 tap->rate = mcs | IEEE80211_RATE_MCS;
4268 else
4269 tap->rate = rate;
4271 if (mcs & RT2870_TXWI_MCS_SHOTPRE)
4272 tap->flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
4274 if (shortgi)
4275 tap->flags |= IEEE80211_RADIOTAP_F_SHORTGI;
4277 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4278 tap->flags |= IEEE80211_RADIOTAP_F_WEP;
4280 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
4282 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
4284 ieee80211_radiotap_tx(vap, m);
4286 wh->i_fc[1] |= IEEE80211_FC1_WEP;
4288 else
4290 ieee80211_radiotap_tx(vap, m);
4294 m_copydata(m, 0, m->m_pkthdr.len, (caddr_t) (txwi + 1));
4296 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4297 "%s: sending data: qid=%d, hdrsize=%d, hdrspace=%d, len=%d, "
4298 "bw=%d, stbc=%d, shortgi=%d, mcs=%d, wcid=0x%02x, DMA len=%d\n",
4299 device_get_nameunit(sc->dev),
4300 qid, hdrsize, hdrspace, m->m_pkthdr.len,
4301 bw, stbc, shortgi, mcs, wcid, dmalen);
4303 data->len = dmalen;
4304 data->m = m;
4305 data->ni = ni;
4307 STAILQ_INSERT_TAIL(&ring->pending, data, next);
4308 ring->queued++;
4310 usbd_transfer_start(sc->usb_xfer[1 + qid]);
4312 return 0;
4316 * rt2870_tx_raw
4318 static int rt2870_tx_raw(struct rt2870_softc *sc,
4319 struct mbuf *m, struct ieee80211_node *ni,
4320 const struct ieee80211_bpf_params *params)
4322 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4323 "%s: Tx raw\n",
4324 device_get_nameunit(sc->dev));
4326 return 0;
4330 * rt2870_rx_intr
4332 static void rt2870_rx_intr(struct usb_xfer *xfer, usb_error_t error)
4334 struct rt2870_softc *sc;
4335 struct ifnet *ifp;
4336 struct rt2870_softc_rx_ring *ring;
4337 struct rt2870_softc_rx_data *data;
4338 int len;
4340 sc = usbd_xfer_softc(xfer);
4341 ifp = sc->ifp;
4342 ring = &sc->rx_ring;
4344 RT2870_DPRINTF(sc, RT2870_DEBUG_INTR,
4345 "%s: Rx interrupt: state=%d, error=%s\n",
4346 device_get_nameunit(sc->dev),
4347 USB_GET_STATE(xfer), usbd_errstr(error));
4349 switch (USB_GET_STATE(xfer))
4351 case USB_ST_TRANSFERRED:
4352 sc->interrupts++;
4353 sc->rx_interrupts++;
4355 data = STAILQ_FIRST(&ring->active);
4356 if (data == NULL)
4357 goto setup;
4359 STAILQ_REMOVE_HEAD(&ring->active, next);
4361 usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
4363 data->len = len;
4365 STAILQ_INSERT_TAIL(&ring->done, data, next);
4367 taskqueue_enqueue(sc->taskqueue, &sc->rx_done_task);
4369 /* FALLTHROUGH */
4371 setup:
4373 case USB_ST_SETUP:
4374 data = STAILQ_FIRST(&ring->inactive);
4375 if (data == NULL)
4376 break;
4378 STAILQ_REMOVE_HEAD(&ring->inactive, next);
4380 STAILQ_INSERT_TAIL(&ring->active, data, next);
4382 usbd_xfer_set_frame_data(xfer, 0, data->buf, usbd_xfer_max_len(xfer));
4383 usbd_transfer_submit(xfer);
4384 break;
4386 default:
4387 sc->interrupts++;
4388 sc->rx_interrupts++;
4390 data = STAILQ_FIRST(&ring->active);
4391 if (data != NULL)
4393 STAILQ_REMOVE_HEAD(&ring->active, next);
4394 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
4397 if (error != USB_ERR_CANCELLED)
4399 ifp->if_ierrors++;
4401 usbd_xfer_set_stall(xfer);
4403 goto setup;
4405 break;
4410 * rt2870_tx_intr
4412 static void rt2870_tx_intr(struct usb_xfer *xfer, usb_error_t error)
4414 struct rt2870_softc *sc;
4415 struct ifnet *ifp;
4416 struct rt2870_softc_tx_ring *ring;
4417 struct rt2870_softc_tx_data *data;
4419 sc = usbd_xfer_softc(xfer);
4420 ifp = sc->ifp;
4421 ring = usbd_xfer_get_priv(xfer);
4423 usbd_xfer_status(xfer, NULL, NULL, NULL, NULL);
4425 RT2870_DPRINTF(sc, RT2870_DEBUG_INTR,
4426 "%s: Tx interrupt: state=%d, error=%s\n",
4427 device_get_nameunit(sc->dev),
4428 USB_GET_STATE(xfer), usbd_errstr(error));
4430 switch (USB_GET_STATE(xfer))
4432 case USB_ST_TRANSFERRED:
4433 sc->interrupts++;
4434 sc->tx_interrupts[ring->qid]++;
4436 data = STAILQ_FIRST(&ring->active);
4437 if (data == NULL)
4438 goto setup;
4440 STAILQ_REMOVE_HEAD(&ring->active, next);
4442 STAILQ_INSERT_TAIL(&ring->done, data, next);
4444 taskqueue_enqueue(sc->taskqueue, &sc->tx_done_task);
4446 /* FALLTHROUGH */
4448 setup:
4450 case USB_ST_SETUP:
4451 data = STAILQ_FIRST(&ring->pending);
4452 if (data == NULL)
4453 break;
4455 STAILQ_REMOVE_HEAD(&ring->pending, next);
4456 STAILQ_INSERT_TAIL(&ring->active, data, next);
4458 usbd_xfer_set_frame_data(xfer, 0, data->buf, data->len);
4459 usbd_transfer_submit(xfer);
4461 RT2870_SOFTC_UNLOCK(sc);
4463 rt2870_start(ifp);
4465 RT2870_SOFTC_LOCK(sc);
4466 break;
4468 default:
4469 sc->interrupts++;
4470 sc->tx_interrupts[ring->qid]++;
4472 data = STAILQ_FIRST(&ring->active);
4473 if (data != NULL)
4475 STAILQ_REMOVE_HEAD(&ring->active, next);
4477 printf("%s: could not transmit buffer: qid=%d, error=%s\n",
4478 device_get_nameunit(sc->dev), ring->qid, usbd_errstr(error));
4480 if (data->m != NULL)
4482 m_freem(data->m);
4483 data->m = NULL;
4486 if (data->ni != NULL)
4488 ieee80211_free_node(data->ni);
4489 data->ni = NULL;
4492 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
4494 ring->queued--;
4497 if (error != USB_ERR_CANCELLED)
4499 ifp->if_oerrors++;
4500 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4502 usbd_xfer_set_stall(xfer);
4504 goto setup;
4506 break;
4511 * rt2870_rx_done_task
4513 static void rt2870_rx_done_task(void *context, int pending)
4515 struct rt2870_softc *sc;
4516 struct ifnet *ifp;
4518 sc = context;
4519 ifp = sc->ifp;
4521 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4522 "%s: Rx done task\n",
4523 device_get_nameunit(sc->dev));
4525 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
4526 return;
4528 if (rt2870_rx_eof(sc, sc->rx_process_limit) != 0)
4529 taskqueue_enqueue(sc->taskqueue, &sc->rx_done_task);
4533 * rt2870_tx_done_task
4535 static void rt2870_tx_done_task(void *context, int pending)
4537 struct rt2870_softc *sc;
4538 struct ifnet *ifp;
4539 int i;
4541 sc = context;
4542 ifp = sc->ifp;
4544 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4545 "%s: Tx done task\n",
4546 device_get_nameunit(sc->dev));
4548 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
4549 return;
4551 for (i = sc->usb_endpoints - 2; i >= 0; i--)
4552 rt2870_tx_eof(sc, &sc->tx_ring[i]);
4554 sc->tx_timer = 0;
4556 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4560 * rt2870_periodic_task
4562 static void rt2870_periodic_task(void *context, int pending)
4564 struct rt2870_softc *sc;
4565 struct ifnet *ifp;
4566 struct ieee80211com *ic;
4567 struct ieee80211vap *vap;
4569 sc = context;
4570 ifp = sc->ifp;
4571 ic = ifp->if_l2com;
4573 RT2870_DPRINTF(sc, RT2870_DEBUG_PERIODIC,
4574 "%s: periodic task: round=%lu\n",
4575 device_get_nameunit(sc->dev), sc->periodic_round);
4577 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
4578 return;
4580 RT2870_SOFTC_LOCK(sc);
4582 sc->periodic_round++;
4584 rt2870_update_stats(sc);
4586 if ((sc->periodic_round % 10) == 0)
4588 rt2870_update_raw_counters(sc);
4590 rt2870_watchdog(sc);
4592 vap = TAILQ_FIRST(&ic->ic_vaps);
4593 if (vap != NULL)
4595 if (vap->iv_opmode == IEEE80211_M_STA)
4596 rt2870_amrr_update_iter_func(vap, vap->iv_bss);
4597 else
4598 ieee80211_iterate_nodes(&ic->ic_sta, rt2870_amrr_update_iter_func, vap);
4602 RT2870_SOFTC_UNLOCK(sc);
4604 callout_reset(&sc->periodic_ch, hz / 10, rt2870_periodic, sc);
4608 * rt2870_cmd_task
4610 static void rt2870_cmd_task(void *context, int pending)
4612 struct rt2870_softc *sc;
4613 struct rt2870_softc_cmd_ring *ring;
4614 struct rt2870_softc_cmd *cmd;
4616 sc = context;
4617 ring = &sc->cmd_ring;
4619 while (1)
4621 RT2870_SOFTC_LOCK(sc);
4623 cmd = STAILQ_FIRST(&ring->active);
4624 if (cmd == NULL)
4626 RT2870_SOFTC_UNLOCK(sc);
4627 break;
4630 STAILQ_REMOVE_HEAD(&ring->active, next);
4632 RT2870_SOFTC_UNLOCK(sc);
4634 cmd->cb(sc, cmd->data);
4636 RT2870_SOFTC_LOCK(sc);
4638 STAILQ_INSERT_TAIL(&ring->inactive, cmd, next);
4639 ring->queued--;
4641 RT2870_SOFTC_UNLOCK(sc);
4646 * rt2870_rx_eof
4648 static int rt2870_rx_eof(struct rt2870_softc *sc, int limit)
4650 struct ifnet *ifp;
4651 struct rt2870_softc_rx_ring *ring;
4652 struct rt2870_softc_rx_data *data;
4653 uint32_t dmalen;
4654 uint8_t *buf;
4655 int nframes, len;
4657 ifp = sc->ifp;
4658 ring = &sc->rx_ring;
4660 nframes = 0;
4662 while (limit != 0)
4664 RT2870_SOFTC_LOCK(sc);
4666 data = STAILQ_FIRST(&ring->done);
4667 if (data == NULL)
4669 RT2870_SOFTC_UNLOCK(sc);
4670 break;
4673 STAILQ_REMOVE_HEAD(&ring->done, next);
4675 RT2870_SOFTC_UNLOCK(sc);
4677 buf = data->buf;
4678 len = data->len;
4680 if (len < RT2870_RX_DESC_SIZE)
4682 ifp->if_ierrors++;
4683 goto skip;
4686 while (len > (sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)))
4688 dmalen = (le32toh(*(uint32_t *) buf) & 0xffff);
4690 if (dmalen == 0 || (dmalen & 3) != 0)
4692 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4693 "%s: bad DMA len=%u\n",
4694 device_get_nameunit(sc->dev), dmalen);
4695 goto skip;
4698 if ((dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)) > len)
4700 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4701 "%s: bad DMA len: DMA len=%u, USB len=%d\n",
4702 device_get_nameunit(sc->dev),
4703 (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo)), len);
4704 goto skip;
4707 nframes++;
4709 rt2870_rx_frame(sc, buf + sizeof(uint32_t), dmalen);
4711 buf += (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo));
4712 len -= (dmalen + sizeof(uint32_t) + sizeof(struct rt2870_rxinfo));
4715 skip:
4717 RT2870_SOFTC_LOCK(sc);
4719 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
4721 usbd_transfer_start(sc->usb_xfer[0]);
4723 RT2870_SOFTC_UNLOCK(sc);
4725 limit--;
4728 RT2870_DPRINTF(sc, RT2870_DEBUG_RX,
4729 "%s: Rx eof: nframes=%d\n",
4730 device_get_nameunit(sc->dev), nframes);
4732 sc->rx_packets += nframes;
4734 return (limit == 0);
4738 * rt2870_tx_eof
4740 static void rt2870_tx_eof(struct rt2870_softc *sc,
4741 struct rt2870_softc_tx_ring *ring)
4743 struct ifnet *ifp;
4744 struct rt2870_softc_tx_data *data;
4745 int nframes;
4747 ifp = sc->ifp;
4749 nframes = 0;
4751 while (1)
4753 RT2870_SOFTC_LOCK(sc);
4755 data = STAILQ_FIRST(&ring->done);
4756 if (data == NULL)
4758 RT2870_SOFTC_UNLOCK(sc);
4759 break;
4762 STAILQ_REMOVE_HEAD(&ring->done, next);
4764 RT2870_SOFTC_UNLOCK(sc);
4766 nframes++;
4768 if (data->m->m_flags & M_TXCB)
4769 ieee80211_process_callback(data->ni, data->m, 0);
4771 m_freem(data->m);
4773 ieee80211_free_node(data->ni);
4775 data->m = NULL;
4776 data->ni = NULL;
4778 RT2870_SOFTC_LOCK(sc);
4780 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
4782 ring->queued--;
4783 ifp->if_opackets++;
4785 RT2870_SOFTC_UNLOCK(sc);
4788 RT2870_DPRINTF(sc, RT2870_DEBUG_TX,
4789 "%s: Tx eof: qid=%d, nframes=%d\n",
4790 device_get_nameunit(sc->dev), ring->qid, nframes);
4794 * rt2870_update_stats
4796 static void rt2870_update_stats(struct rt2870_softc *sc)
4798 struct ifnet *ifp;
4799 struct ieee80211com *ic;
4800 struct ieee80211vap *vap;
4801 struct ieee80211_node *ni;
4802 uint16_t associd;
4803 uint8_t wcid;
4804 uint32_t stacnt[3];
4805 int txcnt, retrycnt, failcnt;
4807 ifp = sc->ifp;
4808 ic = ifp->if_l2com;
4810 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
4811 "%s: update statistic\n",
4812 device_get_nameunit(sc->dev));
4814 rt2870_drain_fifo_stats(sc);
4816 if (ic->ic_opmode == IEEE80211_M_STA)
4818 vap = TAILQ_FIRST(&ic->ic_vaps);
4819 ni = vap->iv_bss;
4821 associd = (ni != NULL) ? ni->ni_associd : 0;
4822 wcid = RT2870_AID2WCID(associd);
4824 /* read and clear Tx statistic registers */
4826 rt2870_io_mac_read_multi(sc, RT2870_REG_TX_STA_CNT0,
4827 stacnt, sizeof(stacnt));
4829 txcnt = le32toh(stacnt[1]) & 0xffff;
4830 retrycnt = le32toh(stacnt[1]) >> 16;
4831 failcnt = le32toh(stacnt[0]) & 0xffff;
4833 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
4834 "%s: update statistic: associd=0x%04x, txcnt=%d, retrycnt=%d, failcnt=%d\n",
4835 device_get_nameunit(sc->dev),
4836 associd, txcnt, retrycnt, failcnt);
4838 ifp->if_oerrors += failcnt;
4840 rt2870_amrr_tx_update(&sc->amrr_node[wcid],
4841 txcnt + retrycnt + failcnt, txcnt + retrycnt, retrycnt + failcnt);
4846 * rt2870_watchdog
4848 static void rt2870_watchdog(struct rt2870_softc *sc)
4850 uint32_t tmp;
4851 int ntries;
4853 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
4855 RT2870_DPRINTF(sc, RT2870_DEBUG_WATCHDOG,
4856 "%s: watchdog: TXRXQ_PCNT=0x%08x\n",
4857 device_get_nameunit(sc->dev), tmp);
4859 if (((tmp >> RT2870_REG_TX0Q_PCNT_SHIFT) & RT2870_REG_TX0Q_PCNT_MASK) != 0)
4861 sc->tx_queue_not_empty[0]++;
4863 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40012);
4865 for (ntries = 0; ntries < 10; ntries++)
4867 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
4868 if (((tmp >> RT2870_REG_TX0Q_PCNT_SHIFT) & RT2870_REG_TX0Q_PCNT_MASK) == 0)
4869 break;
4871 DELAY(1);
4874 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40006);
4877 if (((tmp >> RT2870_REG_TX1Q_PCNT_SHIFT) & RT2870_REG_TX1Q_PCNT_MASK) != 0)
4879 sc->tx_queue_not_empty[1]++;
4881 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf4000a);
4883 for (ntries = 0; ntries < 10; ntries++)
4885 tmp = rt2870_io_mac_read(sc, RT2870_REG_PBF_TXRXQ_PCNT);
4886 if (((tmp >> RT2870_REG_TX1Q_PCNT_SHIFT) & RT2870_REG_TX1Q_PCNT_MASK) == 0)
4887 break;
4889 DELAY(1);
4892 rt2870_io_mac_write(sc, RT2870_REG_PBF_CFG, 0xf40006);
4897 * rt2870_drain_fifo_stats
4899 static void rt2870_drain_fifo_stats(struct rt2870_softc *sc)
4901 struct ifnet *ifp;
4902 uint32_t stats;
4903 uint8_t wcid, mcs, pid;
4904 int ok, retrycnt;
4906 ifp = sc->ifp;
4908 /* drain Tx status FIFO (maxsize = 16) */
4910 while ((stats = rt2870_io_mac_read(sc, RT2870_REG_TX_STA_FIFO)) &
4911 RT2870_REG_TX_STA_FIFO_VALID)
4913 wcid = (stats >> RT2870_REG_TX_STA_FIFO_WCID_SHIFT) &
4914 RT2870_REG_TX_STA_FIFO_WCID_MASK;
4916 /* if no ACK was requested, no feedback is available */
4918 if (!(stats & RT2870_REG_TX_STA_FIFO_ACK_REQ) || wcid == 0xff)
4919 continue;
4921 /* update AMRR statistic */
4923 ok = (stats & RT2870_REG_TX_STA_FIFO_TX_OK) ? 1 : 0;
4924 mcs = (stats >> RT2870_REG_TX_STA_FIFO_MCS_SHIFT) &
4925 RT2870_REG_TX_STA_FIFO_MCS_MASK;
4926 pid = (stats >> RT2870_REG_TX_STA_FIFO_PID_SHIFT) &
4927 RT2870_REG_TX_STA_FIFO_PID_MASK;
4928 retrycnt = pid - mcs;
4930 RT2870_DPRINTF(sc, RT2870_DEBUG_STATS,
4931 "%s: FIFO statistic: wcid=0x%02x, ok=%d, mcs=0x%02x, pid=0x%02x, retrycnt=%d\n",
4932 device_get_nameunit(sc->dev),
4933 wcid, ok, mcs, pid, retrycnt);
4935 rt2870_amrr_tx_complete(&sc->amrr_node[wcid], ok, retrycnt);
4937 if (!ok)
4938 ifp->if_oerrors++;
4943 * rt2870_update_raw_counters
4945 static void rt2870_update_raw_counters(struct rt2870_softc *sc)
4947 uint32_t tmp;
4949 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT0);
4951 sc->rx_crc_errors += tmp & 0xffff;
4952 sc->rx_phy_errors += tmp >> 16;
4954 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT1);
4956 sc->rx_false_ccas += tmp & 0xffff;
4957 sc->rx_plcp_errors += tmp >> 16;
4959 tmp = rt2870_io_mac_read(sc, RT2870_REG_RX_STA_CNT2);
4961 sc->rx_dup_packets += tmp & 0xffff;
4962 sc->rx_fifo_overflows += tmp >> 16;
4966 * rt2870_txrx_enable
4968 static int rt2870_txrx_enable(struct rt2870_softc *sc)
4970 struct ieee80211com *ic;
4971 struct ifnet *ifp;
4972 uint32_t tmp;
4973 int ntries;
4975 ifp = sc->ifp;
4976 ic = ifp->if_l2com;
4978 /* enable Tx/Rx DMA engine */
4980 tmp = rt2870_io_mac_read(sc, RT2870_REG_SCHDMA_USB_CYC_CFG);
4982 tmp &= 0xffffff00;
4983 tmp |= 0x1e;
4985 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_CYC_CFG, tmp);
4987 if ((sc->mac_rev & 0xffff) != 0x0101)
4988 rt2870_io_mac_write(sc, RT2870_REG_TX_TXOP_CTRL_CFG, 0x583f);
4990 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL, RT2870_REG_TX_ENABLE);
4992 for (ntries = 0; ntries < 200; ntries++)
4994 tmp = rt2870_io_mac_read(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG);
4995 if (!(tmp & (RT2870_REG_TX_DMA_BUSY | RT2870_REG_RX_DMA_BUSY)))
4996 break;
4998 DELAY(1000);
5001 if (ntries == 200)
5003 printf("%s: timeout waiting for DMA engine\n",
5004 device_get_nameunit(sc->dev));
5005 return -1;
5008 DELAY(50);
5010 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP0_CFG, 0);
5011 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WMM_TXOP1_CFG,
5012 (48 << 16) | 96);
5014 tmp |= RT2870_REG_TX_WB_DDONE |
5015 RT2870_REG_RX_DMA_ENABLE |
5016 RT2870_REG_TX_DMA_ENABLE;
5018 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_WPDMA_GLO_CFG, tmp);
5020 tmp = RT2870_REG_USB_DMA_TX_ENABLE |
5021 RT2870_REG_USB_DMA_RX_ENABLE |
5022 RT2870_REG_USB_DMA_RX_AGG_ENABLE |
5023 /* Rx agg limit in unit of 1024 byte */
5024 ((RT2870_USB_RX_BULK_BUFLEN / 1024 - 3) << RT2870_REG_USB_DMA_RX_AGG_LIMIT_SHIFT) |
5025 /* Rx agg timeout in unit of 33ns */
5026 0x80;
5028 rt2870_io_mac_write(sc, RT2870_REG_SCHDMA_USB_DMA_CFG, tmp);
5030 /* set Rx filter */
5032 tmp = RT2870_REG_RX_FILTER_DROP_CRC_ERR |
5033 RT2870_REG_RX_FILTER_DROP_PHY_ERR;
5035 if (ic->ic_opmode != IEEE80211_M_MONITOR)
5037 tmp |= RT2870_REG_RX_FILTER_DROP_DUPL |
5038 RT2870_REG_RX_FILTER_DROP_CTS |
5039 RT2870_REG_RX_FILTER_DROP_BA |
5040 RT2870_REG_RX_FILTER_DROP_ACK |
5041 RT2870_REG_RX_FILTER_DROP_VER_ERR |
5042 RT2870_REG_RX_FILTER_DROP_CTRL_RSV |
5043 RT2870_REG_RX_FILTER_DROP_CFACK |
5044 RT2870_REG_RX_FILTER_DROP_CFEND;
5046 if (ic->ic_opmode == IEEE80211_M_STA)
5047 tmp |= RT2870_REG_RX_FILTER_DROP_RTS |
5048 RT2870_REG_RX_FILTER_DROP_PSPOLL;
5050 if (!(ifp->if_flags & IFF_PROMISC))
5051 tmp |= RT2870_REG_RX_FILTER_DROP_UC_NOME;
5054 rt2870_io_mac_write(sc, RT2870_REG_RX_FILTER_CFG, tmp);
5056 rt2870_io_mac_write(sc, RT2870_REG_SYS_CTRL,
5057 RT2870_REG_RX_ENABLE | RT2870_REG_TX_ENABLE);
5059 return 0;
5063 * rt2870_alloc_rx_ring
5065 static int rt2870_alloc_rx_ring(struct rt2870_softc *sc,
5066 struct rt2870_softc_rx_ring *ring)
5068 struct rt2870_softc_rx_data *data;
5069 int i, error;
5071 STAILQ_INIT(&ring->inactive);
5072 STAILQ_INIT(&ring->active);
5073 STAILQ_INIT(&ring->done);
5075 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
5077 data = &ring->data[i];
5079 data->buf = malloc(RT2870_USB_RX_BULK_BUFLEN, M_USBDEV, M_NOWAIT);
5080 if (data->buf == NULL)
5082 printf("%s: could not allocate Rx buffer\n",
5083 device_get_nameunit(sc->dev));
5084 error = ENOMEM;
5085 goto fail;
5088 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5091 return 0;
5093 fail:
5095 rt2870_free_rx_ring(sc, ring);
5097 return error;
5101 * rt2870_reset_rx_ring
5103 static void rt2870_reset_rx_ring(struct rt2870_softc *sc,
5104 struct rt2870_softc_rx_ring *ring)
5106 struct rt2870_softc_rx_data *data;
5107 int i;
5109 STAILQ_INIT(&ring->inactive);
5110 STAILQ_INIT(&ring->active);
5111 STAILQ_INIT(&ring->done);
5113 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
5115 data = &ring->data[i];
5117 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5122 * rt2870_free_rx_ring
5124 static void rt2870_free_rx_ring(struct rt2870_softc *sc,
5125 struct rt2870_softc_rx_ring *ring)
5127 struct rt2870_softc_rx_data *data;
5128 int i;
5130 for (i = 0; i < RT2870_SOFTC_RX_RING_DATA_COUNT; i++)
5132 data = &ring->data[i];
5134 if (data->buf != NULL)
5136 free(data->buf, M_USBDEV);
5137 data->buf = NULL;
5143 * rt2870_alloc_tx_ring
5145 static int rt2870_alloc_tx_ring(struct rt2870_softc *sc,
5146 struct rt2870_softc_tx_ring *ring, int qid)
5148 struct rt2870_softc_tx_data *data;
5149 int i, error;
5151 STAILQ_INIT(&ring->inactive);
5152 STAILQ_INIT(&ring->pending);
5153 STAILQ_INIT(&ring->active);
5154 STAILQ_INIT(&ring->done);
5156 ring->queued = 0;
5157 ring->qid = qid;
5159 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
5161 data = &ring->data[i];
5163 data->buf = malloc(RT2870_TX_DESC_SIZE + MJUMPAGESIZE, M_USBDEV, M_NOWAIT);
5164 if (data->buf == NULL)
5166 printf("%s: could not allocate Tx buffer\n",
5167 device_get_nameunit(sc->dev));
5168 error = ENOMEM;
5169 goto fail;
5172 memset(data->buf, 0, RT2870_TX_DESC_SIZE);
5174 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5177 return 0;
5179 fail:
5181 rt2870_free_tx_ring(sc, ring);
5183 return error;
5187 * rt2870_reset_tx_ring
5189 static void rt2870_reset_tx_ring(struct rt2870_softc *sc,
5190 struct rt2870_softc_tx_ring *ring)
5192 struct rt2870_softc_tx_data *data;
5193 int i;
5195 STAILQ_INIT(&ring->inactive);
5196 STAILQ_INIT(&ring->pending);
5197 STAILQ_INIT(&ring->active);
5198 STAILQ_INIT(&ring->done);
5200 ring->queued = 0;
5202 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
5204 data = &ring->data[i];
5206 if (data->m != NULL)
5208 m_free(data->m);
5209 data->m = NULL;
5212 if (data->ni != NULL)
5214 ieee80211_free_node(data->ni);
5215 data->ni = NULL;
5218 STAILQ_INSERT_TAIL(&ring->inactive, data, next);
5223 * rt2870_free_tx_ring
5225 static void rt2870_free_tx_ring(struct rt2870_softc *sc,
5226 struct rt2870_softc_tx_ring *ring)
5228 struct rt2870_softc_tx_data *data;
5229 int i;
5231 for (i = 0; i < RT2870_SOFTC_TX_RING_DATA_COUNT; i++)
5233 data = &ring->data[i];
5235 if (data->buf != NULL)
5237 free(data->buf, M_USBDEV);
5238 data->buf = NULL;
5241 if (data->m != NULL)
5243 m_free(data->m);
5244 data->m = NULL;
5247 if (data->ni != NULL)
5249 ieee80211_free_node(data->ni);
5250 data->ni = NULL;
5256 * rt2870_reset_cmd_ring
5258 static void rt2870_reset_cmd_ring(struct rt2870_softc *sc,
5259 struct rt2870_softc_cmd_ring *ring)
5261 struct rt2870_softc_cmd *cmd;
5262 int i;
5264 STAILQ_INIT(&ring->inactive);
5265 STAILQ_INIT(&ring->active);
5267 ring->queued = 0;
5269 for (i = 0; i < RT2870_SOFTC_CMD_RING_CMD_COUNT; i++)
5271 cmd = &ring->cmd[i];
5273 STAILQ_INSERT_TAIL(&ring->inactive, cmd, next);
5278 * rt2870_sysctl_attach
5280 static void rt2870_sysctl_attach(struct rt2870_softc *sc)
5282 struct sysctl_ctx_list *ctx;
5283 struct sysctl_oid *tree;
5284 struct sysctl_oid *stats;
5286 ctx = device_get_sysctl_ctx(sc->dev);
5287 tree = device_get_sysctl_tree(sc->dev);
5289 stats = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
5290 "stats", CTLFLAG_RD, 0, "statistic");
5292 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5293 "interrupts", CTLFLAG_RD, &sc->interrupts, 0,
5294 "all interrupts");
5296 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5297 "rx_interrupts", CTLFLAG_RD, &sc->rx_interrupts, 0,
5298 "Rx interrupts");
5300 if (sc->usb_endpoints == RT2870_SOFTC_USB_XFER_COUNT)
5302 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5303 "tx_mgmt_interrupts", CTLFLAG_RD, &sc->tx_interrupts[5], 0,
5304 "Tx MGMT interrupts");
5306 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5307 "tx_hcca_interrupts", CTLFLAG_RD, &sc->tx_interrupts[4], 0,
5308 "Tx HCCA interrupts");
5311 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5312 "tx_ac3_interrupts", CTLFLAG_RD, &sc->tx_interrupts[3], 0,
5313 "Tx AC3 interrupts");
5315 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5316 "tx_ac2_interrupts", CTLFLAG_RD, &sc->tx_interrupts[2], 0,
5317 "Tx AC2 interrupts");
5319 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5320 "tx_ac1_interrupts", CTLFLAG_RD, &sc->tx_interrupts[1], 0,
5321 "Tx AC1 interrupts");
5323 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5324 "tx_ac0_interrupts", CTLFLAG_RD, &sc->tx_interrupts[0], 0,
5325 "Tx AC0 interrupts");
5327 if (sc->usb_endpoints == RT2870_SOFTC_USB_XFER_COUNT)
5329 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5330 "tx_mgmt_data_queued", CTLFLAG_RD, &sc->tx_ring[5].queued, 0,
5331 "Tx MGMT data queued");
5333 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5334 "tx_hcca_data_queued", CTLFLAG_RD, &sc->tx_ring[4].queued, 0,
5335 "Tx HCCA data queued");
5338 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5339 "tx_ac3_data_queued", CTLFLAG_RD, &sc->tx_ring[3].queued, 0,
5340 "Tx AC3 data queued");
5342 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5343 "tx_ac2_data_queued", CTLFLAG_RD, &sc->tx_ring[2].queued, 0,
5344 "Tx AC2 data queued");
5346 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5347 "tx_ac1_data_queued", CTLFLAG_RD, &sc->tx_ring[1].queued, 0,
5348 "Tx AC1 data queued");
5350 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5351 "tx_ac0_data_queued", CTLFLAG_RD, &sc->tx_ring[0].queued, 0,
5352 "Tx AC0 data queued");
5354 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5355 "tx_watchdog_timeouts", CTLFLAG_RD, &sc->tx_watchdog_timeouts, 0,
5356 "Tx watchdog timeouts");
5358 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5359 "rx_mbuf_alloc_errors", CTLFLAG_RD, &sc->rx_mbuf_alloc_errors, 0,
5360 "Rx mbuf allocation errors");
5362 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5363 "tx_queue_0_not_empty", CTLFLAG_RD, &sc->tx_queue_not_empty[0], 0,
5364 "Tx queue 0 not empty");
5366 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5367 "tx_queue_1_not_empty", CTLFLAG_RD, &sc->tx_queue_not_empty[1], 0,
5368 "Tx queue 1 not empty");
5370 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5371 "rx_packets", CTLFLAG_RD, &sc->rx_packets, 0,
5372 "Rx packets");
5374 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5375 "rx_crc_errors", CTLFLAG_RD, &sc->rx_crc_errors, 0,
5376 "Rx CRC errors");
5378 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5379 "rx_phy_errors", CTLFLAG_RD, &sc->rx_phy_errors, 0,
5380 "Rx PHY errors");
5382 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5383 "rx_false_ccas", CTLFLAG_RD, &sc->rx_false_ccas, 0,
5384 "Rx false CCAs");
5386 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5387 "rx_plcp_errors", CTLFLAG_RD, &sc->rx_plcp_errors, 0,
5388 "Rx PLCP errors");
5390 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5391 "rx_dup_packets", CTLFLAG_RD, &sc->rx_dup_packets, 0,
5392 "Rx duplicate packets");
5394 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
5395 "rx_fifo_overflows", CTLFLAG_RD, &sc->rx_fifo_overflows, 0,
5396 "Rx FIFO overflows");
5399 static device_method_t rt2870_dev_methods[] =
5401 DEVMETHOD(device_probe, rt2870_probe),
5402 DEVMETHOD(device_attach, rt2870_attach),
5403 DEVMETHOD(device_detach, rt2870_detach),
5404 { 0, 0 }
5407 static driver_t rt2870_driver =
5409 "rt2870",
5410 rt2870_dev_methods,
5411 sizeof(struct rt2870_softc),
5414 static devclass_t rt2870_dev_class;
5416 DRIVER_MODULE(rt2870, uhub, rt2870_driver, rt2870_dev_class,
5417 NULL, 0);
5419 MODULE_DEPEND(rt2870, usb, 1, 1, 1);
5420 MODULE_DEPEND(rt2870, wlan, 1, 1, 1);