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 "rt2860_softc.h"
20 #include "rt2860_reg.h"
21 #include "rt2860_eeprom.h"
22 #include "rt2860_ucode.h"
23 #include "rt2860_txwi.h"
24 #include "rt2860_rxwi.h"
25 #include "rt2860_io.h"
26 #include "rt2860_read_eeprom.h"
27 #include "rt2860_led.h"
28 #include "rt2860_rf.h"
29 #include "rt2860_debug.h"
35 #define PCI_VENDOR_RALINK 0x1814
36 #define PCI_PRODUCT_RALINK_RT2860_PCI 0x0601
37 #define PCI_PRODUCT_RALINK_RT2860_PCIe 0x0681
38 #define PCI_PRODUCT_RALINK_RT2760_PCI 0x0701
39 #define PCI_PRODUCT_RALINK_RT2790_PCIe 0x0781
41 #define RT2860_MAX_AGG_SIZE 3840
43 #define RT2860_TX_DATA_SEG0_SIZE \
44 (sizeof(struct rt2860_txwi) + sizeof(struct ieee80211_qosframe_addr4))
46 #define RT2860_NOISE_FLOOR -95
48 #define RT2860_AID2WCID(aid) ((aid) & 0xff)
50 #define RT2860_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
52 #define RT2860_ACK_SIZE 14
54 #define IEEE80211_HAS_ADDR4(wh) \
55 (((wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
57 #define RT2860_MS(_v, _f) (((_v) & _f) >> _f##_S)
58 #define RT2860_SM(_v, _f) (((_v) << _f##_S) & _f)
60 #define RT2860_TX_WATCHDOG_TIMEOUT 5
62 #define RT2860_WCID_RESERVED 0xff
63 #define RT2860_WCID_MCAST 0x00
66 * Data structures and types
69 struct rt2860_pci_ident
77 * Static function prototypes
80 static int rt2860_probe(device_t dev
);
82 static int rt2860_attach(device_t dev
);
84 static int rt2860_detach(device_t dev
);
86 static int rt2860_shutdown(device_t dev
);
88 static int rt2860_suspend(device_t dev
);
90 static int rt2860_resume(device_t dev
);
92 static void rt2860_init_channels(struct rt2860_softc
*sc
);
94 static void rt2860_init_channels_ht40(struct rt2860_softc
*sc
);
96 static void rt2860_init_locked(void *priv
);
98 static void rt2860_init(void *priv
);
100 static int rt2860_init_bbp(struct rt2860_softc
*sc
);
102 static void rt2860_stop_locked(void *priv
);
104 static void rt2860_stop(void *priv
);
106 static void rt2860_start(struct ifnet
*ifp
);
108 static int rt2860_ioctl(struct ifnet
*ifp
, u_long cmd
, caddr_t data
);
110 static int rt2860_reset(struct ifnet
*ifp
);
112 static int rt2860_newstate(struct ieee80211com
*ic
,
113 enum ieee80211_state nstate
, int arg
);
115 static void rt2860_scan_start(struct ieee80211com
*ic
);
117 static void rt2860_scan_end(struct ieee80211com
*ic
);
119 static void rt2860_set_channel(struct ieee80211com
*ic
);
121 static void rt2860_newassoc(struct ieee80211_node
*ni
, int isnew
);
123 static void rt2860_updateslot(struct ifnet
*ifp
);
125 static int rt2860_wme_update(struct ieee80211com
*ic
);
127 static void rt2860_update_beacon(struct ieee80211com
*ic
, int what
);
129 static void rt2860_key_update_begin(struct ieee80211com
*ic
);
131 static void rt2860_key_update_end(struct ieee80211com
*ic
);
133 static int rt2860_key_set(struct ieee80211com
*ic
,
134 const struct ieee80211_key
*k
, const uint8_t mac
[IEEE80211_ADDR_LEN
]);
136 static int rt2860_key_delete(struct ieee80211com
*ic
,
137 const struct ieee80211_key
*k
);
139 static int rt2860_raw_xmit(struct ieee80211_node
*ni
, struct mbuf
*m
,
140 const struct ieee80211_bpf_params
*params
);
142 static int rt2860_media_change(struct ifnet
*ifp
);
144 static struct ieee80211_node
*rt2860_node_alloc(struct ieee80211_node_table
*nt
);
146 static void rt2860_recv_action(struct ieee80211_node
*ni
,
147 const uint8_t *frm
, const uint8_t *efrm
);
149 static int rt2860_send_action(struct ieee80211_node
*ni
,
150 int category
, int action
, uint16_t args
[4]);
152 static void rt2860_amrr_update_iter_func(void *arg
, struct ieee80211_node
*ni
);
154 static void rt2860_periodic(void *arg
);
156 static void rt2860_tx_watchdog(void *arg
);
158 static void rt2860_asic_set_bssid(struct rt2860_softc
*sc
,
159 const uint8_t *bssid
);
161 static void rt2860_asic_set_macaddr(struct rt2860_softc
*sc
,
162 const uint8_t *addr
);
164 static void rt2860_asic_enable_tsf_sync(struct rt2860_softc
*sc
);
166 static void rt2860_asic_disable_tsf_sync(struct rt2860_softc
*sc
);
168 static void rt2860_asic_enable_mrr(struct rt2860_softc
*sc
);
170 static void rt2860_asic_set_txpreamble(struct rt2860_softc
*sc
);
172 static void rt2860_asic_set_basicrates(struct rt2860_softc
*sc
);
174 static void rt2860_asic_update_rtsthreshold(struct rt2860_softc
*sc
);
176 static void rt2860_asic_update_txpower(struct rt2860_softc
*sc
);
178 static void rt2860_asic_update_promisc(struct rt2860_softc
*sc
);
180 static void rt2860_asic_updateprot(struct rt2860_softc
*sc
);
182 static void rt2860_asic_updateslot(struct rt2860_softc
*sc
);
184 static void rt2860_asic_wme_update(struct rt2860_softc
*sc
);
186 static void rt2860_asic_update_beacon(struct rt2860_softc
*sc
);
188 static void rt2860_asic_clear_keytables(struct rt2860_softc
*sc
);
190 static int rt2860_beacon_alloc(struct rt2860_softc
*sc
);
192 static uint8_t rt2860_rxrate(struct rt2860_rxwi
*rxwi
);
194 static uint8_t rt2860_maxrssi_rxpath(struct rt2860_softc
*sc
,
195 const struct rt2860_rxwi
*rxwi
);
197 static int8_t rt2860_rssi2dbm(struct rt2860_softc
*sc
,
198 uint8_t rssi
, uint8_t rxpath
);
200 static uint8_t rt2860_rate2mcs(uint8_t rate
);
202 static int rt2860_ackrate(struct ieee80211com
*ic
, int rate
);
204 static uint16_t rt2860_txtime(int len
, int rate
, uint32_t flags
);
206 static int rt2860_tx_frame(struct rt2860_softc
*sc
,
207 struct mbuf
*m
, struct ieee80211_node
*ni
, int qid
);
209 static int rt2860_tx_raw(struct rt2860_softc
*sc
,
210 struct mbuf
*m
, struct ieee80211_node
*ni
,
211 const struct ieee80211_bpf_params
*params
);
213 static void rt2860_intr(void *arg
);
215 static void rt2860_tx_coherent_intr(struct rt2860_softc
*sc
);
217 static void rt2860_rx_coherent_intr(struct rt2860_softc
*sc
);
219 static void rt2860_txrx_coherent_intr(struct rt2860_softc
*sc
);
221 static void rt2860_fifo_sta_full_intr(struct rt2860_softc
*sc
);
223 static void rt2860_rx_intr(struct rt2860_softc
*sc
);
225 static void rt2860_rx_delay_intr(struct rt2860_softc
*sc
);
227 static void rt2860_tx_intr(struct rt2860_softc
*sc
, int qid
);
229 static void rt2860_tx_delay_intr(struct rt2860_softc
*sc
);
231 static void rt2860_pre_tbtt_intr(struct rt2860_softc
*sc
);
233 static void rt2860_tbtt_intr(struct rt2860_softc
*sc
);
235 static void rt2860_mcu_cmd_intr(struct rt2860_softc
*sc
);
237 static void rt2860_auto_wakeup_intr(struct rt2860_softc
*sc
);
239 static void rt2860_gp_timer_intr(struct rt2860_softc
*sc
);
241 static void rt2860_rx_done_task(void *context
, int pending
);
243 static void rt2860_tx_done_task(void *context
, int pending
);
245 static void rt2860_fifo_sta_full_task(void *context
, int pending
);
247 static void rt2860_periodic_task(void *context
, int pending
);
249 static int rt2860_rx_eof(struct rt2860_softc
*sc
, int limit
);
251 static void rt2860_tx_eof(struct rt2860_softc
*sc
,
252 struct rt2860_softc_tx_ring
*ring
);
254 static void rt2860_update_stats(struct rt2860_softc
*sc
);
256 static void rt2860_bbp_tuning(struct rt2860_softc
*sc
);
258 static void rt2860_watchdog(struct rt2860_softc
*sc
);
260 static void rt2860_drain_fifo_stats(struct rt2860_softc
*sc
);
262 static void rt2860_update_raw_counters(struct rt2860_softc
*sc
);
264 static void rt2860_intr_enable(struct rt2860_softc
*sc
, uint32_t intr_mask
);
266 static void rt2860_intr_disable(struct rt2860_softc
*sc
, uint32_t intr_mask
);
268 static int rt2860_txrx_enable(struct rt2860_softc
*sc
);
270 static int rt2860_alloc_rx_ring(struct rt2860_softc
*sc
,
271 struct rt2860_softc_rx_ring
*ring
);
273 static void rt2860_reset_rx_ring(struct rt2860_softc
*sc
,
274 struct rt2860_softc_rx_ring
*ring
);
276 static void rt2860_free_rx_ring(struct rt2860_softc
*sc
,
277 struct rt2860_softc_rx_ring
*ring
);
279 static int rt2860_alloc_tx_ring(struct rt2860_softc
*sc
,
280 struct rt2860_softc_tx_ring
*ring
, int qid
);
282 static void rt2860_reset_tx_ring(struct rt2860_softc
*sc
,
283 struct rt2860_softc_tx_ring
*ring
);
285 static void rt2860_free_tx_ring(struct rt2860_softc
*sc
,
286 struct rt2860_softc_tx_ring
*ring
);
288 static void rt2860_dma_map_addr(void *arg
, bus_dma_segment_t
*segs
,
289 int nseg
, int error
);
291 static void rt2860_sysctl_attach(struct rt2860_softc
*sc
);
297 static const struct rt2860_pci_ident rt2860_pci_ids
[] =
299 { PCI_VENDOR_RALINK
, PCI_PRODUCT_RALINK_RT2860_PCI
, "Ralink RT2860 PCI" },
300 { PCI_VENDOR_RALINK
, PCI_PRODUCT_RALINK_RT2860_PCIe
, "Ralink RT2860 PCIe" },
301 { PCI_VENDOR_RALINK
, PCI_PRODUCT_RALINK_RT2760_PCI
, "Ralink RT2760 PCI" },
302 { PCI_VENDOR_RALINK
, PCI_PRODUCT_RALINK_RT2790_PCIe
, "Ralink RT2790 PCIe" },
312 { RT2860_REG_PBF_BCN_OFFSET0
, 0xf8f0e8e0 },
313 { RT2860_REG_PBF_BCN_OFFSET1
, 0x6f77d0c8 },
314 { RT2860_REG_LEGACY_BASIC_RATE
, 0x0000013f },
315 { RT2860_REG_HT_BASIC_RATE
, 0x00008003 },
316 { RT2860_REG_SYS_CTRL
, 0x00000000 },
317 { RT2860_REG_RX_FILTER_CFG
, 0x00017f97 },
318 { RT2860_REG_BKOFF_SLOT_CFG
, 0x00000209 },
319 { RT2860_REG_TX_SW_CFG0
, 0x00000000 },
320 { RT2860_REG_TX_SW_CFG1
, 0x00080606 },
321 { RT2860_REG_TX_LINK_CFG
, 0x00001020 },
322 { RT2860_REG_TX_TIMEOUT_CFG
, 0x000a2090 },
323 { RT2860_REG_MAX_LEN_CFG
, (1 << 12) | RT2860_MAX_AGG_SIZE
},
324 { RT2860_REG_LED_CFG
, 0x7f031e46 },
325 { RT2860_REG_PBF_MAX_PCNT
, 0x1f3fbf9f },
326 { RT2860_REG_TX_RTY_CFG
, 0x47d01f0f },
327 { RT2860_REG_AUTO_RSP_CFG
, 0x00000013 },
328 { RT2860_REG_TX_CCK_PROT_CFG
, 0x05740003 },
329 { RT2860_REG_TX_OFDM_PROT_CFG
, 0x05740003 },
330 { RT2860_REG_TX_GF20_PROT_CFG
, 0x01744004 },
331 { RT2860_REG_TX_GF40_PROT_CFG
, 0x03f44084 },
332 { RT2860_REG_TX_MM20_PROT_CFG
, 0x01744004 },
333 { RT2860_REG_TX_MM40_PROT_CFG
, 0x03f54084 },
334 { RT2860_REG_TX_TXOP_CTRL_CFG
, 0x0000583f },
335 { RT2860_REG_TX_RTS_CFG
, 0x00092b20 },
336 { RT2860_REG_TX_EXP_ACK_TIME
, 0x002400ca },
337 { RT2860_REG_HCCAPSMP_TXOP_HLDR_ET
, 0x00000002 },
338 { RT2860_REG_XIFS_TIME_CFG
, 0x33a41010 },
339 { RT2860_REG_PWR_PIN_CFG
, 0x00000003 },
340 { RT2860_REG_SCHDMA_WMM_AIFSN_CFG
, 0x00002273 },
341 { RT2860_REG_SCHDMA_WMM_CWMIN_CFG
, 0x00002344 },
342 { RT2860_REG_SCHDMA_WMM_CWMAX_CFG
, 0x000034aa },
345 #define RT2860_DEF_MAC_SIZE (sizeof(rt2860_def_mac) / sizeof(rt2860_def_mac[0]))
370 #define RT2860_DEF_BBP_SIZE (sizeof(rt2860_def_bbp) / sizeof(rt2860_def_bbp[0]))
372 SYSCTL_NODE(_hw
, OID_AUTO
, rt2860
, CTLFLAG_RD
, 0, "RT2860 driver parameters");
375 static int rt2860_debug
= 0;
376 SYSCTL_INT(_hw_rt2860
, OID_AUTO
, debug
, CTLFLAG_RW
, &rt2860_debug
, 0, "rt2860 debug level");
377 TUNABLE_INT("hw.rt2860.debug", &rt2860_debug
);
383 static int rt2860_probe(device_t dev
)
385 const struct rt2860_pci_ident
*ident
;
387 for (ident
= rt2860_pci_ids
; ident
->name
!= NULL
; ident
++)
389 if (pci_get_vendor(dev
) == ident
->vendor
&&
390 pci_get_device(dev
) == ident
->device
)
392 device_set_desc(dev
, ident
->name
);
403 static int rt2860_attach(device_t dev
)
405 struct rt2860_softc
*sc
;
407 struct ieee80211com
*ic
;
408 int error
, ntries
, i
;
410 sc
= device_get_softc(dev
);
412 if (pci_get_powerstate(dev
) != PCI_POWERSTATE_D0
)
414 printf("%s: chip is in D%d power mode, setting to D0\n",
415 device_get_nameunit(dev
), pci_get_powerstate(dev
));
416 pci_set_powerstate(dev
, PCI_POWERSTATE_D0
);
419 /* enable bus-mastering */
421 pci_enable_busmaster(dev
);
425 mtx_init(&sc
->lock
, device_get_nameunit(dev
),
426 MTX_NETWORK_LOCK
, MTX_DEF
| MTX_RECURSE
);
428 sc
->mem_rid
= PCIR_BAR(0);
429 sc
->mem
= bus_alloc_resource_any(dev
, SYS_RES_MEMORY
,
430 &sc
->mem_rid
, RF_ACTIVE
);
433 printf("%s: could not allocate memory resource\n",
434 device_get_nameunit(dev
));
439 sc
->bst
= rman_get_bustag(sc
->mem
);
440 sc
->bsh
= rman_get_bushandle(sc
->mem
);
443 sc
->irq
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
,
444 &sc
->irq_rid
, RF_ACTIVE
| RF_SHAREABLE
);
447 printf("%s: could not allocate interrupt resource\n",
448 device_get_nameunit(dev
));
454 sc
->debug
= rt2860_debug
;
456 SYSCTL_ADD_INT(device_get_sysctl_ctx(dev
),
457 SYSCTL_CHILDREN(device_get_sysctl_tree(dev
)), OID_AUTO
,
458 "debug", CTLFLAG_RW
, &sc
->debug
, 0, "rt2860 debug level");
461 RT2860_DPRINTF(sc
, RT2860_DEBUG_ANY
,
463 device_get_nameunit(sc
->dev
));
465 /* wait for NIC to initialize */
467 for (ntries
= 0; ntries
< 100; ntries
++)
469 sc
->mac_rev
= rt2860_io_mac_read(sc
, RT2860_REG_MAC_CSR0
);
470 if (sc
->mac_rev
!= 0x00000000 && sc
->mac_rev
!= 0xffffffff)
478 printf("%s: timeout waiting for NIC to initialize\n",
479 device_get_nameunit(dev
));
484 rt2860_read_eeprom(sc
);
486 printf("%s: MAC/BBP RT2860 (rev 0x%08x), RF %s\n",
487 device_get_nameunit(sc
->dev
), sc
->mac_rev
,
488 rt2860_rf_name(sc
->rf_rev
));
490 /* allocate Tx and Rx rings */
492 for (i
= 0; i
< RT2860_SOFTC_TX_RING_COUNT
; i
++)
494 error
= rt2860_alloc_tx_ring(sc
, &sc
->tx_ring
[i
], i
);
497 printf("%s: could not allocate Tx ring #%d\n",
498 device_get_nameunit(sc
->dev
), i
);
503 sc
->tx_ring_mgtqid
= 5;
505 error
= rt2860_alloc_rx_ring(sc
, &sc
->rx_ring
);
508 printf("%s: could not allocate Rx ring\n",
509 device_get_nameunit(sc
->dev
));
513 callout_init(&sc
->periodic_ch
, 0);
514 callout_init_mtx(&sc
->tx_watchdog_ch
, &sc
->lock
, 0);
516 ifp
= sc
->ifp
= if_alloc(IFT_ETHER
);
519 printf("%s: could not if_alloc()\n",
520 device_get_nameunit(sc
->dev
));
527 if_initname(ifp
, "rt2860", device_get_unit(sc
->dev
));
529 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
531 ifp
->if_init
= rt2860_init
;
532 ifp
->if_ioctl
= rt2860_ioctl
;
533 ifp
->if_start
= rt2860_start
;
535 IFQ_SET_MAXLEN(&ifp
->if_snd
, IFQ_MAXLEN
);
536 ifp
->if_snd
.ifq_drv_maxlen
= IFQ_MAXLEN
;
537 IFQ_SET_READY(&ifp
->if_snd
);
543 ic
->ic_phytype
= IEEE80211_T_HT
;
544 ic
->ic_opmode
= IEEE80211_M_STA
;
545 ic
->ic_state
= IEEE80211_S_INIT
;
547 ic
->ic_caps
= IEEE80211_C_MONITOR
|
554 IEEE80211_C_SHPREAMBLE
|
561 IEEE80211_C_AES_CCM
|
564 ic
->ic_htcaps
= IEEE80211_HTC_HT
|
565 IEEE80211_HTC_AMSDU
| /* A-MSDU Tx */
566 IEEE80211_HTC_AMPDU
| /* A-MPDU Tx */
567 IEEE80211_HTCAP_MAXAMSDU_3839
| /* max. A-MSDU Rx length */
568 IEEE80211_HTCAP_CHWIDTH40
| /* HT 40MHz channel width */
569 IEEE80211_HTCAP_GREENFIELD
| /* HT greenfield */
570 IEEE80211_HTCAP_SHORTGI20
| /* HT 20MHz short GI */
571 IEEE80211_HTCAP_SHORTGI40
| /* HT 40MHz short GI */
572 IEEE80211_HTCAP_SMPS_OFF
; /* MIMO power save disabled */
574 /* spatial streams */
576 if (sc
->nrxpath
== 2)
577 ic
->ic_htcaps
|= IEEE80211_HTCAP_RXSTBC_2STREAM
;
578 else if (sc
->nrxpath
== 3)
579 ic
->ic_htcaps
|= IEEE80211_HTCAP_RXSTBC_3STREAM
;
581 ic
->ic_htcaps
|= IEEE80211_HTCAP_RXSTBC_1STREAM
;
584 ic
->ic_htcaps
|= IEEE80211_HTCAP_TXSTBC
;
588 if (sc
->mac_rev
!= 0x28600100)
589 ic
->ic_htcaps
|= IEEE80211_HTCAP_DELBA
;
594 ic
->ic_regdomain
= 0;
595 ic
->ic_countrycode
= CTRY_DEFAULT
;
598 rt2860_init_channels(sc
);
600 rt2860_init_channels_ht40(sc
);
602 IEEE80211_ADDR_COPY(ic
->ic_myaddr
, sc
->mac_addr
);
604 ieee80211_ifattach(ic
);
606 sc
->newstate
= ic
->ic_newstate
;
607 ic
->ic_newstate
= rt2860_newstate
;
609 ic
->ic_reset
= rt2860_reset
;
610 ic
->ic_node_alloc
= rt2860_node_alloc
;
611 ic
->ic_scan_start
= rt2860_scan_start
;
612 ic
->ic_scan_end
= rt2860_scan_end
;
613 ic
->ic_set_channel
= rt2860_set_channel
;
614 ic
->ic_newassoc
= rt2860_newassoc
;
615 ic
->ic_updateslot
= rt2860_updateslot
;
616 ic
->ic_wme
.wme_update
= rt2860_wme_update
;
617 ic
->ic_update_beacon
= rt2860_update_beacon
;
618 ic
->ic_crypto
.cs_key_update_begin
= rt2860_key_update_begin
;
619 ic
->ic_crypto
.cs_key_update_end
= rt2860_key_update_end
;
620 ic
->ic_crypto
.cs_key_set
= rt2860_key_set
;
621 ic
->ic_crypto
.cs_key_delete
= rt2860_key_delete
;
622 ic
->ic_raw_xmit
= rt2860_raw_xmit
;
624 sc
->recv_action
= ic
->ic_recv_action
;
625 ic
->ic_recv_action
= rt2860_recv_action
;
627 sc
->send_action
= ic
->ic_send_action
;
628 ic
->ic_send_action
= rt2860_send_action
;
630 /* override Rx A-MPDU factor */
632 ic
->ic_ampdu_rxmax
= IEEE80211_HTCAP_MAXRXAMPDU_32K
;
633 ic
->ic_ampdu_density
= IEEE80211_HTCAP_MPDUDENSITY_NA
;
634 ic
->ic_ampdu_limit
= ic
->ic_ampdu_rxmax
;
636 /* hardware requires padding between 802.11 frame header and body */
638 ic
->ic_flags
|= IEEE80211_F_WME
| IEEE80211_F_DATAPAD
| IEEE80211_F_DOTH
;
640 ic
->ic_flags_ext
|= IEEE80211_FEXT_SWBMISS
;
642 ieee80211_media_init(ic
, rt2860_media_change
, ieee80211_media_status
);
644 rt2860_amrr_init(&sc
->amrr
, ic
,
646 RT2860_AMRR_MIN_SUCCESS_THRESHOLD
,
647 RT2860_AMRR_MAX_SUCCESS_THRESHOLD
,
650 bpfattach2(ifp
, DLT_IEEE802_11_RADIO
,
651 sizeof(struct ieee80211_frame
) + IEEE80211_RADIOTAP_HDRLEN
,
654 sc
->rxtap_len
= sizeof(sc
->rxtapu
);
655 sc
->rxtap
.ihdr
.it_len
= htole16(sc
->rxtap_len
);
656 sc
->rxtap
.ihdr
.it_present
= htole32(RT2860_SOFTC_RX_RADIOTAP_PRESENT
);
658 sc
->txtap_len
= sizeof(sc
->txtapu
);
659 sc
->txtap
.ihdr
.it_len
= htole16(sc
->txtap_len
);
660 sc
->txtap
.ihdr
.it_present
= htole32(RT2860_SOFTC_TX_RADIOTAP_PRESENT
);
662 /* init task queue */
664 TASK_INIT(&sc
->rx_done_task
, 0, rt2860_rx_done_task
, sc
);
665 TASK_INIT(&sc
->tx_done_task
, 0, rt2860_tx_done_task
, sc
);
666 TASK_INIT(&sc
->fifo_sta_full_task
, 0, rt2860_fifo_sta_full_task
, sc
);
667 TASK_INIT(&sc
->periodic_task
, 0, rt2860_periodic_task
, sc
);
669 sc
->rx_process_limit
= 100;
671 sc
->taskqueue
= taskqueue_create("rt2860_taskq", M_NOWAIT
,
672 taskqueue_thread_enqueue
, &sc
->taskqueue
);
674 taskqueue_start_threads(&sc
->taskqueue
, 1, PI_NET
, "%s taskq",
675 device_get_nameunit(sc
->dev
));
677 rt2860_sysctl_attach(sc
);
680 ieee80211_announce(ic
);
682 /* set up interrupt */
684 error
= bus_setup_intr(dev
, sc
->irq
, INTR_TYPE_NET
| INTR_MPSAFE
,
685 NULL
, rt2860_intr
, sc
, &sc
->irqh
);
688 printf("%s: could not set up interrupt\n",
689 device_get_nameunit(dev
));
697 /* free Tx and Rx rings */
699 for (i
= 0; i
< RT2860_SOFTC_TX_RING_COUNT
; i
++)
700 rt2860_free_tx_ring(sc
, &sc
->tx_ring
[i
]);
702 rt2860_free_rx_ring(sc
, &sc
->rx_ring
);
704 mtx_destroy(&sc
->lock
);
707 bus_release_resource(dev
, SYS_RES_MEMORY
, sc
->mem_rid
, sc
->mem
);
710 bus_release_resource(dev
, SYS_RES_IRQ
, sc
->irq_rid
, sc
->irq
);
718 static int rt2860_detach(device_t dev
)
720 struct rt2860_softc
*sc
;
721 struct ieee80211com
*ic
;
725 sc
= device_get_softc(dev
);
729 RT2860_DPRINTF(sc
, RT2860_DEBUG_ANY
,
731 device_get_nameunit(sc
->dev
));
733 RT2860_SOFTC_LOCK(sc
);
735 ifp
->if_drv_flags
&= ~(IFF_DRV_RUNNING
| IFF_DRV_OACTIVE
);
737 ieee80211_new_state(ic
, IEEE80211_S_INIT
, -1);
739 callout_stop(&sc
->periodic_ch
);
740 callout_stop(&sc
->tx_watchdog_ch
);
742 taskqueue_drain(sc
->taskqueue
, &sc
->rx_done_task
);
743 taskqueue_drain(sc
->taskqueue
, &sc
->tx_done_task
);
744 taskqueue_drain(sc
->taskqueue
, &sc
->fifo_sta_full_task
);
745 taskqueue_drain(sc
->taskqueue
, &sc
->periodic_task
);
747 /* free Tx and Rx rings */
749 for (i
= 0; i
< RT2860_SOFTC_TX_RING_COUNT
; i
++)
750 rt2860_free_tx_ring(sc
, &sc
->tx_ring
[i
]);
752 rt2860_free_rx_ring(sc
, &sc
->rx_ring
);
754 RT2860_SOFTC_UNLOCK(sc
);
758 ieee80211_ifdetach(ic
);
762 taskqueue_free(sc
->taskqueue
);
764 mtx_destroy(&sc
->lock
);
766 bus_generic_detach(dev
);
768 bus_teardown_intr(dev
, sc
->irq
, sc
->irqh
);
770 bus_release_resource(dev
, SYS_RES_IRQ
, sc
->irq_rid
, sc
->irq
);
772 bus_release_resource(dev
, SYS_RES_MEMORY
, sc
->mem_rid
, sc
->mem
);
780 static int rt2860_shutdown(device_t dev
)
782 struct rt2860_softc
*sc
;
784 sc
= device_get_softc(dev
);
786 RT2860_DPRINTF(sc
, RT2860_DEBUG_ANY
,
787 "%s: shutting down\n",
788 device_get_nameunit(sc
->dev
));
792 sc
->flags
&= ~RT2860_SOFTC_FLAGS_UCODE_LOADED
;
800 static int rt2860_suspend(device_t dev
)
802 struct rt2860_softc
*sc
;
804 sc
= device_get_softc(dev
);
806 RT2860_DPRINTF(sc
, RT2860_DEBUG_ANY
,
808 device_get_nameunit(sc
->dev
));
812 sc
->flags
&= ~RT2860_SOFTC_FLAGS_UCODE_LOADED
;
820 static int rt2860_resume(device_t dev
)
822 struct rt2860_softc
*sc
;
825 sc
= device_get_softc(dev
);
828 RT2860_DPRINTF(sc
, RT2860_DEBUG_ANY
,
830 device_get_nameunit(sc
->dev
));
832 if (ifp
->if_flags
& IFF_UP
)
839 * rt2860_init_channels
841 static void rt2860_init_channels(struct rt2860_softc
*sc
)
843 struct ieee80211com
*ic
;
844 struct ieee80211_channel
*c
;
849 /* set supported channels for 2GHz band */
851 for (i
= 1; i
<= 14; i
++)
853 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
854 flags
= IEEE80211_CHAN_B
;
856 c
->ic_freq
= ieee80211_ieee2mhz(i
, flags
);
860 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
861 flags
= IEEE80211_CHAN_B
| IEEE80211_CHAN_HT20
;
863 c
->ic_freq
= ieee80211_ieee2mhz(i
, flags
);
867 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
868 flags
= IEEE80211_CHAN_G
;
870 c
->ic_freq
= ieee80211_ieee2mhz(i
, flags
);
874 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
875 flags
= IEEE80211_CHAN_G
| IEEE80211_CHAN_HT20
;
877 c
->ic_freq
= ieee80211_ieee2mhz(i
, flags
);
882 /* set supported channels for 5GHz band */
884 if (sc
->rf_rev
== RT2860_EEPROM_RF_2850
||
885 sc
->rf_rev
== RT2860_EEPROM_RF_2750
)
887 for (i
= 36; i
<= 64; i
+= 4)
889 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
890 flags
= IEEE80211_CHAN_A
;
892 c
->ic_freq
= ieee80211_ieee2mhz(i
, flags
);
896 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
897 flags
= IEEE80211_CHAN_A
| IEEE80211_CHAN_HT20
;
899 c
->ic_freq
= ieee80211_ieee2mhz(i
, flags
);
904 for (i
= 100; i
<= 140; i
+= 4)
906 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
907 flags
= IEEE80211_CHAN_A
;
909 c
->ic_freq
= ieee80211_ieee2mhz(i
, flags
);
913 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
914 flags
= IEEE80211_CHAN_A
| IEEE80211_CHAN_HT20
;
916 c
->ic_freq
= ieee80211_ieee2mhz(i
, flags
);
921 for (i
= 149; i
<= 165; i
+= 4)
923 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
924 flags
= IEEE80211_CHAN_A
;
926 c
->ic_freq
= ieee80211_ieee2mhz(i
, flags
);
930 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
931 flags
= IEEE80211_CHAN_A
| IEEE80211_CHAN_HT20
;
933 c
->ic_freq
= ieee80211_ieee2mhz(i
, flags
);
941 * rt2860_init_channels_ht40
943 static void rt2860_init_channels_ht40(struct rt2860_softc
*sc
)
945 struct ieee80211com
*ic
;
946 struct ieee80211_channel
*c
, *cent
, *ext
;
951 /* set supported channels for 2GHz band */
953 for (i
= 1; i
<= 14; i
++)
955 flags
= IEEE80211_CHAN_G
| IEEE80211_CHAN_HT40
;
957 /* find the center channel */
959 cent
= ieee80211_find_channel_byieee(ic
, i
,
960 flags
& ~IEEE80211_CHAN_HT
);
963 printf("%s: skip channel %d, could not find center channel\n",
964 device_get_nameunit(sc
->dev
), i
);
968 /* find the extension channel */
970 ext
= ieee80211_find_channel(ic
, cent
->ic_freq
+ 20,
971 flags
& ~IEEE80211_CHAN_HT
);
974 printf("%s: skip channel %d, could not find extension channel\n",
975 device_get_nameunit(sc
->dev
), i
);
979 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
982 c
->ic_extieee
= ext
->ic_ieee
;
983 c
->ic_flags
&= ~IEEE80211_CHAN_HT
;
984 c
->ic_flags
|= IEEE80211_CHAN_HT40U
;
986 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
989 c
->ic_extieee
= cent
->ic_ieee
;
990 c
->ic_flags
&= ~IEEE80211_CHAN_HT
;
991 c
->ic_flags
|= IEEE80211_CHAN_HT40D
;
994 /* set supported channels for 5GHz band */
996 if (sc
->rf_rev
== RT2860_EEPROM_RF_2850
||
997 sc
->rf_rev
== RT2860_EEPROM_RF_2750
)
999 for (i
= 36; i
<= 64; i
+= 4)
1001 flags
= IEEE80211_CHAN_A
| IEEE80211_CHAN_HT40
;
1003 /* find the center channel */
1005 cent
= ieee80211_find_channel_byieee(ic
, i
,
1006 flags
& ~IEEE80211_CHAN_HT
);
1009 printf("%s: skip channel %d, could not find center channel\n",
1010 device_get_nameunit(sc
->dev
), i
);
1014 /* find the extension channel */
1016 ext
= ieee80211_find_channel(ic
, cent
->ic_freq
+ 20,
1017 flags
& ~IEEE80211_CHAN_HT
);
1020 printf("%s: skip channel %d, could not find extension channel\n",
1021 device_get_nameunit(sc
->dev
), i
);
1025 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
1028 c
->ic_extieee
= ext
->ic_ieee
;
1029 c
->ic_flags
&= ~IEEE80211_CHAN_HT
;
1030 c
->ic_flags
|= IEEE80211_CHAN_HT40U
;
1032 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
1035 c
->ic_extieee
= cent
->ic_ieee
;
1036 c
->ic_flags
&= ~IEEE80211_CHAN_HT
;
1037 c
->ic_flags
|= IEEE80211_CHAN_HT40D
;
1040 for (i
= 100; i
<= 140; i
+= 4)
1042 flags
= IEEE80211_CHAN_A
| IEEE80211_CHAN_HT40
;
1044 /* find the center channel */
1046 cent
= ieee80211_find_channel_byieee(ic
, i
,
1047 flags
& ~IEEE80211_CHAN_HT
);
1050 printf("%s: skip channel %d, could not find center channel\n",
1051 device_get_nameunit(sc
->dev
), i
);
1055 /* find the extension channel */
1057 ext
= ieee80211_find_channel(ic
, cent
->ic_freq
+ 20,
1058 flags
& ~IEEE80211_CHAN_HT
);
1061 printf("%s: skip channel %d, could not find extension channel\n",
1062 device_get_nameunit(sc
->dev
), i
);
1066 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
1069 c
->ic_extieee
= ext
->ic_ieee
;
1070 c
->ic_flags
&= ~IEEE80211_CHAN_HT
;
1071 c
->ic_flags
|= IEEE80211_CHAN_HT40U
;
1073 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
1076 c
->ic_extieee
= cent
->ic_ieee
;
1077 c
->ic_flags
&= ~IEEE80211_CHAN_HT
;
1078 c
->ic_flags
|= IEEE80211_CHAN_HT40D
;
1081 for (i
= 149; i
<= 165; i
+= 4)
1083 flags
= IEEE80211_CHAN_A
| IEEE80211_CHAN_HT40
;
1085 /* find the center channel */
1087 cent
= ieee80211_find_channel_byieee(ic
, i
,
1088 flags
& ~IEEE80211_CHAN_HT
);
1091 printf("%s: skip channel %d, could not find center channel\n",
1092 device_get_nameunit(sc
->dev
), i
);
1096 /* find the extension channel */
1098 ext
= ieee80211_find_channel(ic
, cent
->ic_freq
+ 20,
1099 flags
& ~IEEE80211_CHAN_HT
);
1102 printf("%s: skip channel %d, could not find extension channel\n",
1103 device_get_nameunit(sc
->dev
), i
);
1107 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
1110 c
->ic_extieee
= ext
->ic_ieee
;
1111 c
->ic_flags
&= ~IEEE80211_CHAN_HT
;
1112 c
->ic_flags
|= IEEE80211_CHAN_HT40U
;
1114 c
= &ic
->ic_channels
[ic
->ic_nchans
++];
1117 c
->ic_extieee
= cent
->ic_ieee
;
1118 c
->ic_flags
&= ~IEEE80211_CHAN_HT
;
1119 c
->ic_flags
|= IEEE80211_CHAN_HT40D
;
1125 * rt2860_init_locked
1127 static void rt2860_init_locked(void *priv
)
1129 struct rt2860_softc
*sc
;
1130 struct ieee80211com
*ic
;
1132 int error
, i
, ntries
;
1133 uint32_t tmp
, stacnt
[6];
1139 RT2860_DPRINTF(sc
, RT2860_DEBUG_ANY
,
1140 "%s: initializing\n",
1141 device_get_nameunit(sc
->dev
));
1143 RT2860_SOFTC_ASSERT_LOCKED(sc
);
1145 if (!(sc
->flags
& RT2860_SOFTC_FLAGS_UCODE_LOADED
))
1147 RT2860_DPRINTF(sc
, RT2860_DEBUG_ANY
,
1148 "%s: loading 8051 microcode\n",
1149 device_get_nameunit(sc
->dev
));
1151 error
= rt2860_io_mcu_load_ucode(sc
, rt2860_ucode
, sizeof(rt2860_ucode
));
1154 printf("%s: could not load 8051 microcode\n",
1155 device_get_nameunit(sc
->dev
));
1159 RT2860_DPRINTF(sc
, RT2860_DEBUG_ANY
,
1160 "%s: 8051 microcode was successfully loaded\n",
1161 device_get_nameunit(sc
->dev
));
1163 sc
->flags
|= RT2860_SOFTC_FLAGS_UCODE_LOADED
;
1166 rt2860_io_mac_write(sc
, RT2860_REG_PWR_PIN_CFG
, 0x2);
1168 /* disable DMA engine */
1170 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_SCHDMA_WPDMA_GLO_CFG
);
1173 tmp
|= RT2860_REG_TX_WB_DDONE
;
1175 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_WPDMA_GLO_CFG
, tmp
);
1177 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_WPDMA_RST_IDX
, 0xffffffff);
1179 /* PBF hardware reset */
1181 rt2860_io_mac_write(sc
, RT2860_REG_PBF_SYS_CTRL
, 0xe1f);
1182 rt2860_io_mac_write(sc
, RT2860_REG_PBF_SYS_CTRL
, 0xe00);
1184 /* wait while DMA engine is busy */
1186 for (ntries
= 0; ntries
< 100; ntries
++)
1188 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_SCHDMA_WPDMA_GLO_CFG
);
1189 if (!(tmp
& (RT2860_REG_TX_DMA_BUSY
| RT2860_REG_RX_DMA_BUSY
)))
1197 printf("%s: timeout waiting for DMA engine\n",
1198 device_get_nameunit(sc
->dev
));
1203 tmp
|= RT2860_REG_TX_WB_DDONE
;
1205 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_WPDMA_GLO_CFG
, tmp
);
1207 /* reset Rx and Tx rings */
1209 tmp
= RT2860_REG_RST_IDX_RX
|
1210 RT2860_REG_RST_IDX_TX_MGMT
|
1211 RT2860_REG_RST_IDX_TX_HCCA
|
1212 RT2860_REG_RST_IDX_TX_AC3
|
1213 RT2860_REG_RST_IDX_TX_AC2
|
1214 RT2860_REG_RST_IDX_TX_AC1
|
1215 RT2860_REG_RST_IDX_TX_AC0
;
1217 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_WPDMA_RST_IDX
, tmp
);
1219 /* PBF hardware reset */
1221 rt2860_io_mac_write(sc
, RT2860_REG_PBF_SYS_CTRL
, 0xe1f);
1222 rt2860_io_mac_write(sc
, RT2860_REG_PBF_SYS_CTRL
, 0xe00);
1224 rt2860_io_mac_write(sc
, RT2860_REG_PWR_PIN_CFG
, 0x3);
1226 rt2860_io_mac_write(sc
, RT2860_REG_SYS_CTRL
,
1227 RT2860_REG_MAC_SRST
| RT2860_REG_BBP_HRST
);
1228 rt2860_io_mac_write(sc
, RT2860_REG_SYS_CTRL
, 0);
1230 /* init Tx power per rate */
1232 for (i
= 0; i
< RT2860_SOFTC_TXPOW_RATE_COUNT
; i
++)
1234 if (sc
->txpow_rate_20mhz
[i
] == 0xffffffff)
1237 rt2860_io_mac_write(sc
, RT2860_REG_TX_PWR_CFG(i
),
1238 sc
->txpow_rate_20mhz
[i
]);
1241 for (i
= 0; i
< RT2860_DEF_MAC_SIZE
; i
++)
1242 rt2860_io_mac_write(sc
, rt2860_def_mac
[i
].reg
,
1243 rt2860_def_mac
[i
].val
);
1245 /* wait while MAC is busy */
1247 for (ntries
= 0; ntries
< 100; ntries
++)
1249 if (!(rt2860_io_mac_read(sc
, RT2860_REG_STATUS_CFG
) &
1250 (RT2860_REG_STATUS_TX_BUSY
| RT2860_REG_STATUS_RX_BUSY
)))
1258 printf("%s: timeout waiting for MAC\n",
1259 device_get_nameunit(sc
->dev
));
1263 /* clear Host to MCU mailbox */
1265 rt2860_io_mac_write(sc
, RT2860_REG_H2M_MAILBOX_BBP_AGENT
, 0);
1266 rt2860_io_mac_write(sc
, RT2860_REG_H2M_MAILBOX
, 0);
1268 rt2860_io_mcu_cmd(sc
, RT2860_IO_MCU_CMD_BOOT
,
1269 RT2860_REG_H2M_TOKEN_NO_INTR
, 0);
1273 error
= rt2860_init_bbp(sc
);
1277 /* set up maximum buffer sizes */
1279 tmp
= (1 << 12) | RT2860_MAX_AGG_SIZE
;
1281 rt2860_io_mac_write(sc
, RT2860_REG_MAX_LEN_CFG
, tmp
);
1283 /* set mac address */
1285 IEEE80211_ADDR_COPY(ic
->ic_myaddr
, IF_LLADDR(ifp
));
1287 rt2860_asic_set_macaddr(sc
, ic
->ic_myaddr
);
1289 /* clear statistic registers */
1291 rt2860_io_mac_read_multi(sc
, RT2860_REG_RX_STA_CNT0
,
1292 stacnt
, sizeof(stacnt
));
1294 /* set RTS threshold */
1296 rt2860_asic_update_rtsthreshold(sc
);
1300 rt2860_asic_update_txpower(sc
);
1302 /* set up protection mode */
1304 sc
->tx_ampdu_sessions
= 0;
1306 rt2860_asic_updateprot(sc
);
1308 /* clear beacon frame space (entries = 8, entry size = 512) */
1310 rt2860_io_mac_set_region_4(sc
, RT2860_REG_BEACON_BASE(0), 0, 1024);
1312 taskqueue_unblock(sc
->taskqueue
);
1314 /* init Tx rings (4 EDCAs + HCCA + MGMT) */
1316 for (i
= 0; i
< RT2860_SOFTC_TX_RING_COUNT
; i
++)
1317 rt2860_reset_tx_ring(sc
, &sc
->tx_ring
[i
]);
1319 for (i
= 0; i
< RT2860_SOFTC_TX_RING_COUNT
; i
++)
1321 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_TX_BASE_PTR(i
),
1322 sc
->tx_ring
[i
].desc_phys_addr
);
1323 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_TX_MAX_CNT(i
),
1324 RT2860_SOFTC_TX_RING_DESC_COUNT
);
1325 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_TX_CTX_IDX(i
), 0);
1330 rt2860_reset_rx_ring(sc
, &sc
->rx_ring
);
1332 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_RX_BASE_PTR
,
1333 sc
->rx_ring
.desc_phys_addr
);
1334 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_RX_MAX_CNT
,
1335 RT2860_SOFTC_RX_RING_DATA_COUNT
);
1336 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_RX_CALC_IDX
,
1337 RT2860_SOFTC_RX_RING_DATA_COUNT
- 1);
1339 /* wait while DMA engine is busy */
1341 for (ntries
= 0; ntries
< 100; ntries
++)
1343 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_SCHDMA_WPDMA_GLO_CFG
);
1344 if (!(tmp
& (RT2860_REG_TX_DMA_BUSY
| RT2860_REG_RX_DMA_BUSY
)))
1352 printf("%s: timeout waiting for DMA engine\n",
1353 device_get_nameunit(sc
->dev
));
1358 tmp
|= RT2860_REG_TX_WB_DDONE
;
1360 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_WPDMA_GLO_CFG
, tmp
);
1362 /* disable interrupts mitigation */
1364 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_DELAY_INT_CFG
, 0);
1366 /* send LEDs operating mode to microcontroller */
1368 rt2860_io_mcu_cmd(sc
, RT2860_IO_MCU_CMD_LED1
,
1369 RT2860_REG_H2M_TOKEN_NO_INTR
, sc
->led_off
[0]);
1370 rt2860_io_mcu_cmd(sc
, RT2860_IO_MCU_CMD_LED2
,
1371 RT2860_REG_H2M_TOKEN_NO_INTR
, sc
->led_off
[1]);
1372 rt2860_io_mcu_cmd(sc
, RT2860_IO_MCU_CMD_LED3
,
1373 RT2860_REG_H2M_TOKEN_NO_INTR
, sc
->led_off
[2]);
1375 /* turn radio LED on */
1377 rt2860_led_cmd(sc
, RT2860_LED_CMD_RADIO_ON
);
1379 /* write vendor-specific BBP values (from EEPROM) */
1381 for (i
= 0; i
< RT2860_SOFTC_BBP_EEPROM_COUNT
; i
++)
1383 if (sc
->bbp_eeprom
[i
].reg
== 0x00 ||
1384 sc
->bbp_eeprom
[i
].reg
== 0xff)
1387 rt2860_io_bbp_write(sc
, sc
->bbp_eeprom
[i
].reg
,
1388 sc
->bbp_eeprom
[i
].val
);
1392 tmp = rt2860_io_mac_read(sc, RT2860_REG_SCHDMA_GPIO_CTRL_CFG);
1395 rt2860_io_mcu_cmd(sc, RT2860_IO_MCU_CMD_SLEEP,
1396 RT2860_REG_H2M_TOKEN_RADIOOFF, 0x02ff);
1397 rt2860_io_mcu_cmd_check(sc, RT2860_REG_H2M_TOKEN_RADIOOFF);
1399 rt2860_io_mcu_cmd(sc, RT2860_IO_MCU_CMD_WAKEUP,
1400 RT2860_REG_H2M_TOKEN_WAKEUP, 0);
1401 rt2860_io_mcu_cmd_check(sc, RT2860_REG_H2M_TOKEN_WAKEUP);
1405 /* disable non-existing Rx chains */
1407 tmp
= rt2860_io_bbp_read(sc
, 3);
1409 tmp
&= ~((1 << 4) | (1 << 3));
1411 if (sc
->nrxpath
== 3)
1413 else if (sc
->nrxpath
== 2)
1416 rt2860_io_bbp_write(sc
, 3, tmp
);
1418 /* disable non-existing Tx chains */
1420 tmp
= rt2860_io_bbp_read(sc
, 1);
1422 tmp
&= ~((1 << 4) | (1 << 3));
1424 if (sc
->ntxpath
== 2)
1427 rt2860_io_bbp_write(sc
, 1, tmp
);
1429 /* set current channel */
1431 rt2860_rf_set_chan(sc
, ic
->ic_curchan
);
1433 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_WMM_TXOP0_CFG
, 0);
1434 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_WMM_TXOP1_CFG
,
1437 if ((sc
->mac_rev
& 0xffff) != 0x0101)
1438 rt2860_io_mac_write(sc
, RT2860_REG_TX_TXOP_CTRL_CFG
, 0x583f);
1440 /* clear pending interrupts */
1442 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_INT_STATUS
, 0xffffffff);
1444 /* enable interrupts */
1446 tmp
= RT2860_REG_INT_TX_COHERENT
|
1447 RT2860_REG_INT_RX_COHERENT
|
1448 RT2860_REG_INT_GP_TIMER
|
1449 RT2860_REG_INT_AUTO_WAKEUP
|
1450 RT2860_REG_INT_FIFO_STA_FULL
|
1452 RT2860_REG_INT_PRE_TBTT |
1453 RT2860_REG_INT_TBTT |
1455 RT2860_REG_INT_TXRX_COHERENT
|
1456 RT2860_REG_INT_MCU_CMD
|
1457 RT2860_REG_INT_TX_MGMT_DONE
|
1458 RT2860_REG_INT_TX_HCCA_DONE
|
1459 RT2860_REG_INT_TX_AC3_DONE
|
1460 RT2860_REG_INT_TX_AC2_DONE
|
1461 RT2860_REG_INT_TX_AC1_DONE
|
1462 RT2860_REG_INT_TX_AC0_DONE
|
1463 RT2860_REG_INT_RX_DONE
;
1465 sc
->intr_enable_mask
= tmp
;
1467 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_INT_MASK
, tmp
);
1469 if (rt2860_txrx_enable(sc
) != 0)
1472 /* clear garbage interrupts */
1474 tmp
= rt2860_io_mac_read(sc
, 0x1300);
1476 ifp
->if_drv_flags
&= ~IFF_DRV_OACTIVE
;
1477 ifp
->if_drv_flags
|= IFF_DRV_RUNNING
;
1479 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
)
1481 if (ic
->ic_roaming
!= IEEE80211_ROAMING_MANUAL
)
1482 ieee80211_new_state(ic
, IEEE80211_S_SCAN
, -1);
1486 ieee80211_new_state(ic
, IEEE80211_S_RUN
, -1);
1489 sc
->periodic_round
= 0;
1491 callout_reset(&sc
->periodic_ch
, hz
/ 10, rt2860_periodic
, sc
);
1497 rt2860_stop_locked(sc
);
1503 static void rt2860_init(void *priv
)
1505 struct rt2860_softc
*sc
;
1509 RT2860_SOFTC_LOCK(sc
);
1511 rt2860_init_locked(sc
);
1513 RT2860_SOFTC_UNLOCK(sc
);
1519 static int rt2860_init_bbp(struct rt2860_softc
*sc
)
1524 for (ntries
= 0; ntries
< 20; ntries
++)
1526 tmp
= rt2860_io_bbp_read(sc
, 0);
1527 if (tmp
!= 0x00 && tmp
!= 0xff)
1531 if (tmp
== 0x00 || tmp
== 0xff)
1533 printf("%s: timeout waiting for BBP to wakeup\n",
1534 device_get_nameunit(sc
->dev
));
1538 for (i
= 0; i
< RT2860_DEF_BBP_SIZE
; i
++)
1539 rt2860_io_bbp_write(sc
, rt2860_def_bbp
[i
].reg
,
1540 rt2860_def_bbp
[i
].val
);
1542 if ((sc
->mac_rev
& 0xffff) != 0x0101)
1543 rt2860_io_bbp_write(sc
, 84, 0x19);
1549 * rt2860_stop_locked
1551 static void rt2860_stop_locked(void *priv
)
1553 struct rt2860_softc
*sc
;
1554 struct ieee80211com
*ic
;
1562 RT2860_DPRINTF(sc
, RT2860_DEBUG_ANY
,
1564 device_get_nameunit(sc
->dev
));
1566 RT2860_SOFTC_ASSERT_LOCKED(sc
);
1570 if (ifp
->if_drv_flags
& IFF_DRV_RUNNING
)
1571 rt2860_led_cmd(sc
, RT2860_LED_CMD_RADIO_OFF
);
1573 ifp
->if_drv_flags
&= ~(IFF_DRV_RUNNING
| IFF_DRV_OACTIVE
);
1575 ieee80211_new_state(ic
, IEEE80211_S_INIT
, -1);
1577 callout_stop(&sc
->periodic_ch
);
1578 callout_stop(&sc
->tx_watchdog_ch
);
1580 RT2860_SOFTC_UNLOCK(sc
);
1582 taskqueue_block(sc
->taskqueue
);
1584 taskqueue_drain(sc
->taskqueue
, &sc
->rx_done_task
);
1585 taskqueue_drain(sc
->taskqueue
, &sc
->tx_done_task
);
1586 taskqueue_drain(sc
->taskqueue
, &sc
->fifo_sta_full_task
);
1587 taskqueue_drain(sc
->taskqueue
, &sc
->periodic_task
);
1589 RT2860_SOFTC_LOCK(sc
);
1591 /* clear key tables */
1593 rt2860_asic_clear_keytables(sc
);
1595 /* disable interrupts */
1597 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_INT_MASK
, 0);
1601 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_SYS_CTRL
);
1603 tmp
&= ~(RT2860_REG_RX_ENABLE
| RT2860_REG_TX_ENABLE
);
1605 rt2860_io_mac_write(sc
, RT2860_REG_SYS_CTRL
, tmp
);
1609 rt2860_io_mac_write(sc
, RT2860_REG_SYS_CTRL
,
1610 RT2860_REG_MAC_SRST
| RT2860_REG_BBP_HRST
);
1611 rt2860_io_mac_write(sc
, RT2860_REG_SYS_CTRL
, 0);
1613 if (sc
->beacon_mbuf
!= NULL
)
1615 m_free(sc
->beacon_mbuf
);
1616 sc
->beacon_mbuf
= NULL
;
1623 static void rt2860_stop(void *priv
)
1625 struct rt2860_softc
*sc
;
1629 RT2860_SOFTC_LOCK(sc
);
1631 rt2860_stop_locked(sc
);
1633 RT2860_SOFTC_UNLOCK(sc
);
1639 static void rt2860_start(struct ifnet
*ifp
)
1641 struct rt2860_softc
*sc
;
1642 struct ieee80211com
*ic
;
1643 struct ieee80211_node
*ni
;
1644 struct ether_header
*eh
;
1651 RT2860_SOFTC_LOCK(sc
);
1653 if (!(ifp
->if_drv_flags
& IFF_DRV_RUNNING
))
1655 RT2860_SOFTC_UNLOCK(sc
);
1661 IF_POLL(&ic
->ic_mgtq
, m
);
1664 if (sc
->tx_ring
[sc
->tx_ring_mgtqid
].data_queued
>= RT2860_SOFTC_TX_RING_DATA_COUNT
)
1666 RT2860_DPRINTF(sc
, RT2860_DEBUG_TX
,
1667 "%s: if_start: Tx ring with qid=%d is full\n",
1668 device_get_nameunit(sc
->dev
), sc
->tx_ring_mgtqid
);
1670 ifp
->if_drv_flags
|= IFF_DRV_OACTIVE
;
1672 sc
->tx_data_queue_full
[sc
->tx_ring_mgtqid
]++;
1677 IF_DEQUEUE(&ic
->ic_mgtq
, m
);
1679 ni
= (struct ieee80211_node
*) m
->m_pkthdr
.rcvif
;
1680 m
->m_pkthdr
.rcvif
= NULL
;
1682 if (bpf_peers_present(ic
->ic_rawbpf
))
1683 bpf_mtap(ic
->ic_rawbpf
, m
);
1685 if (rt2860_tx_frame(sc
, m
, ni
, sc
->tx_ring_mgtqid
) != 0)
1688 rt2860_drain_fifo_stats(sc
);
1692 if (ic
->ic_state
!= IEEE80211_S_RUN
)
1695 IF_POLL(&ifp
->if_snd
, m
);
1699 IFQ_DRV_DEQUEUE(&ifp
->if_snd
, m
);
1701 if (ic
->ic_flags
& IEEE80211_F_SCAN
)
1702 ieee80211_cancel_scan(ic
);
1704 if (m
->m_len
< sizeof(struct ether_header
) &&
1705 !(m
= m_pullup(m
, sizeof (struct ether_header
))))
1708 eh
= mtod(m
, struct ether_header
*);
1710 ni
= ieee80211_find_txnode(ic
, eh
->ether_dhost
);
1713 RT2860_DPRINTF(sc
, RT2860_DEBUG_TX
,
1714 "%s: if_start: could not find Tx node\n",
1715 device_get_nameunit(sc
->dev
));
1721 ieee80211_classify(ic
, m
, ni
);
1723 qid
= M_WME_GETAC(m
);
1725 if (sc
->tx_ring
[qid
].data_queued
>= RT2860_SOFTC_TX_RING_DATA_COUNT
)
1727 RT2860_DPRINTF(sc
, RT2860_DEBUG_TX
,
1728 "%s: if_start: Tx ring with qid=%d is full\n",
1729 device_get_nameunit(sc
->dev
), qid
);
1732 ieee80211_free_node(ni
);
1734 ifp
->if_drv_flags
|= IFF_DRV_OACTIVE
;
1737 sc
->tx_data_queue_full
[qid
]++;
1744 m
= ieee80211_encap(ic
, m
, ni
);
1747 ieee80211_free_node(ni
);
1752 if (bpf_peers_present(ic
->ic_rawbpf
))
1753 bpf_mtap(ic
->ic_rawbpf
, m
);
1755 if (rt2860_tx_frame(sc
, m
, ni
, qid
) != 0)
1757 ieee80211_free_node(ni
);
1764 rt2860_drain_fifo_stats(sc
);
1767 sc
->tx_timer
= RT2860_TX_WATCHDOG_TIMEOUT
;
1769 ic
->ic_lastdata
= ticks
;
1771 callout_reset(&sc
->tx_watchdog_ch
, hz
, rt2860_tx_watchdog
, sc
);
1774 RT2860_SOFTC_UNLOCK(sc
);
1780 static int rt2860_ioctl(struct ifnet
*ifp
, u_long cmd
, caddr_t data
)
1782 struct rt2860_softc
*sc
;
1783 struct ieee80211com
*ic
;
1794 RT2860_SOFTC_LOCK(sc
);
1796 if (ifp
->if_flags
& IFF_UP
)
1798 if (ifp
->if_drv_flags
& IFF_DRV_RUNNING
)
1800 if ((ifp
->if_flags
^ sc
->if_flags
) & IFF_PROMISC
)
1801 rt2860_asic_update_promisc(sc
);
1805 rt2860_init_locked(sc
);
1810 if (ifp
->if_drv_flags
& IFF_DRV_RUNNING
)
1811 rt2860_stop_locked(sc
);
1814 sc
->if_flags
= ifp
->if_flags
;
1816 RT2860_SOFTC_UNLOCK(sc
);
1820 error
= ieee80211_ioctl(ic
, cmd
, data
);
1823 if (error
== ENETRESET
)
1825 RT2860_SOFTC_LOCK(sc
);
1827 if ((ifp
->if_flags
& IFF_UP
) &&
1828 (ifp
->if_drv_flags
& IFF_DRV_RUNNING
) &&
1829 (ic
->ic_roaming
!= IEEE80211_ROAMING_MANUAL
))
1831 rt2860_stop_locked(sc
);
1832 rt2860_init_locked(sc
);
1835 RT2860_SOFTC_UNLOCK(sc
);
1846 static int rt2860_reset(struct ifnet
*ifp
)
1848 struct rt2860_softc
*sc
;
1849 struct ieee80211com
*ic
;
1854 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
)
1857 rt2860_rf_set_chan(sc
, ic
->ic_curchan
);
1865 static int rt2860_newstate(struct ieee80211com
*ic
,
1866 enum ieee80211_state nstate
, int arg
)
1868 struct rt2860_softc
*sc
;
1870 struct ieee80211_node
*ni
;
1876 RT2860_DPRINTF(sc
, RT2860_DEBUG_STATE
,
1877 "%s: newstate: %s -> %s\n",
1878 device_get_nameunit(sc
->dev
),
1879 ieee80211_state_name
[ic
->ic_state
], ieee80211_state_name
[nstate
]);
1881 error
= sc
->newstate(ic
, nstate
, arg
);
1885 RT2860_SOFTC_LOCK(sc
);
1887 /* turn link LED off */
1889 if (nstate
!= IEEE80211_S_RUN
)
1890 rt2860_led_cmd(sc
, RT2860_LED_CMD_RADIO_OFF
);
1894 case IEEE80211_S_INIT
:
1895 rt2860_asic_disable_tsf_sync(sc
);
1898 case IEEE80211_S_RUN
:
1901 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
)
1902 rt2860_rf_set_chan(sc
, ni
->ni_chan
);
1904 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
)
1906 rt2860_asic_enable_mrr(sc
);
1907 rt2860_asic_set_txpreamble(sc
);
1908 rt2860_asic_set_basicrates(sc
);
1909 rt2860_asic_update_txpower(sc
);
1910 rt2860_asic_set_bssid(sc
, ni
->ni_bssid
);
1913 if (ic
->ic_opmode
== IEEE80211_M_STA
)
1914 rt2860_newassoc(ni
, 1);
1916 if (ic
->ic_opmode
== IEEE80211_M_HOSTAP
||
1917 ic
->ic_opmode
== IEEE80211_M_IBSS
)
1919 error
= rt2860_beacon_alloc(sc
);
1923 rt2860_asic_update_beacon(sc
);
1926 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
)
1927 rt2860_asic_enable_tsf_sync(sc
);
1929 /* turn link LED on */
1931 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
)
1933 rt2860_led_cmd(sc
, RT2860_LED_CMD_RADIO_ON
|
1934 (IEEE80211_IS_CHAN_2GHZ(ni
->ni_chan
) ?
1935 RT2860_LED_CMD_LINK_2GHZ
: RT2860_LED_CMD_LINK_5GHZ
));
1943 RT2860_SOFTC_UNLOCK(sc
);
1951 static void rt2860_scan_start(struct ieee80211com
*ic
)
1953 struct rt2860_softc
*sc
;
1959 rt2860_asic_disable_tsf_sync(sc
);
1965 static void rt2860_scan_end(struct ieee80211com
*ic
)
1967 struct rt2860_softc
*sc
;
1973 rt2860_asic_enable_tsf_sync(sc
);
1977 * rt2860_set_channel
1979 static void rt2860_set_channel(struct ieee80211com
*ic
)
1981 struct rt2860_softc
*sc
;
1987 RT2860_DPRINTF(sc
, RT2860_DEBUG_CHAN
,
1988 "%s: set channel: channel=%u, HT%s%s\n",
1989 device_get_nameunit(sc
->dev
),
1990 ieee80211_chan2ieee(ic
, ic
->ic_curchan
),
1991 !IEEE80211_IS_CHAN_HT(ic
->ic_curchan
) ? " disabled" :
1992 IEEE80211_IS_CHAN_HT20(ic
->ic_curchan
) ? "20":
1993 IEEE80211_IS_CHAN_HT40U(ic
->ic_curchan
) ? "40U" : "40D",
1994 (ic
->ic_flags
& IEEE80211_F_SCAN
) ? ", scanning" : "");
1996 RT2860_SOFTC_LOCK(sc
);
1998 rt2860_rf_set_chan(sc
, ic
->ic_curchan
);
2000 RT2860_SOFTC_UNLOCK(sc
);
2006 static void rt2860_newassoc(struct ieee80211_node
*ni
, int isnew
)
2008 struct rt2860_softc
*sc
;
2009 struct ieee80211com
*ic
;
2017 RT2860_DPRINTF(sc
, RT2860_DEBUG_NODE
,
2018 "%s: new association: associd=0x%04x, "
2019 "mac addr=%s, QoS %s, ERP %s, HT %s\n",
2020 device_get_nameunit(sc
->dev
), ni
->ni_associd
,
2021 ether_sprintf(ni
->ni_macaddr
),
2022 (ni
->ni_flags
& IEEE80211_NODE_QOS
) ? "enabled" : "disabled",
2023 (ni
->ni_flags
& IEEE80211_NODE_ERP
) ? "enabled" : "disabled",
2024 (ni
->ni_flags
& IEEE80211_NODE_HT
) ? "enabled" : "disabled");
2026 wcid
= RT2860_AID2WCID(ni
->ni_associd
);
2030 rt2860_io_mac_write_multi(sc
, RT2860_REG_WCID(wcid
),
2031 ni
->ni_macaddr
, IEEE80211_ADDR_LEN
);
2033 rt2860_amrr_node_init(&sc
->amrr
, &sc
->amrr_node
[wcid
], ni
);
2035 RT2860_DPRINTF(sc
, RT2860_DEBUG_RATE
,
2036 "%s: initial%s node Tx rate: associd=0x%04x, rate=0x%02x, max rate=0x%02x\n",
2037 device_get_nameunit(sc
->dev
),
2038 (ni
->ni_flags
& IEEE80211_NODE_HT
) ? " HT" : "",
2040 (ni
->ni_flags
& IEEE80211_NODE_HT
) ?
2041 (ni
->ni_htrates
.rs_rates
[ni
->ni_txrate
] | IEEE80211_RATE_MCS
) :
2042 (ni
->ni_rates
.rs_rates
[ni
->ni_txrate
] & IEEE80211_RATE_VAL
),
2043 (ni
->ni_flags
& IEEE80211_NODE_HT
) ?
2044 (ni
->ni_htrates
.rs_rates
[ni
->ni_htrates
.rs_nrates
- 1] | IEEE80211_RATE_MCS
) :
2045 (ni
->ni_rates
.rs_rates
[ni
->ni_rates
.rs_nrates
- 1] & IEEE80211_RATE_VAL
));
2047 rt2860_asic_updateprot(sc
);
2048 rt2860_asic_updateslot(sc
);
2049 rt2860_asic_set_txpreamble(sc
);
2055 static void rt2860_updateslot(struct ifnet
*ifp
)
2057 struct rt2860_softc
*sc
;
2061 rt2860_asic_updateslot(sc
);
2067 static int rt2860_wme_update(struct ieee80211com
*ic
)
2069 struct rt2860_softc
*sc
;
2075 rt2860_asic_wme_update(sc
);
2081 * rt2860_update_beacon
2083 static void rt2860_update_beacon(struct ieee80211com
*ic
, int what
)
2085 struct rt2860_softc
*sc
;
2088 struct ieee80211_beacon_offsets
*bo
;
2092 m
= sc
->beacon_mbuf
;
2093 bo
= &sc
->beacon_offsets
;
2095 RT2860_DPRINTF(sc
, RT2860_DEBUG_BEACON
,
2096 "%s: update beacon: what=%d\n",
2097 device_get_nameunit(sc
->dev
), what
);
2099 setbit(bo
->bo_flags
, what
);
2101 ieee80211_beacon_update(ic
->ic_bss
, bo
, m
, 0);
2103 rt2860_asic_update_beacon(sc
);
2107 * rt2860_key_update_begin
2109 static void rt2860_key_update_begin(struct ieee80211com
*ic
)
2111 struct rt2860_softc
*sc
;
2117 RT2860_DPRINTF(sc
, RT2860_DEBUG_KEY
,
2118 "%s: key update begin\n",
2119 device_get_nameunit(sc
->dev
));
2121 taskqueue_block(sc
->taskqueue
);
2123 IF_LOCK(&ifp
->if_snd
);
2127 * rt2860_key_update_end
2129 static void rt2860_key_update_end(struct ieee80211com
*ic
)
2131 struct rt2860_softc
*sc
;
2137 RT2860_DPRINTF(sc
, RT2860_DEBUG_KEY
,
2138 "%s: key update end\n",
2139 device_get_nameunit(sc
->dev
));
2141 IF_UNLOCK(&ifp
->if_snd
);
2143 taskqueue_unblock(sc
->taskqueue
);
2149 static int rt2860_key_set(struct ieee80211com
*ic
,
2150 const struct ieee80211_key
*k
, const uint8_t mac
[IEEE80211_ADDR_LEN
])
2152 struct rt2860_softc
*sc
;
2154 struct ieee80211_node
*ni
;
2155 uint16_t associd
, key_base
, keymode_base
;
2156 uint8_t mode
, vapid
, wcid
, iv
[8];
2159 if (k
->wk_cipher
->ic_cipher
!= IEEE80211_CIPHER_WEP
&&
2160 k
->wk_cipher
->ic_cipher
!= IEEE80211_CIPHER_TKIP
&&
2161 k
->wk_cipher
->ic_cipher
!= IEEE80211_CIPHER_AES_CCM
)
2166 ni
= ieee80211_find_node(&ic
->ic_sta
, mac
);
2167 associd
= (ni
!= NULL
) ? ni
->ni_associd
: 0;
2170 ieee80211_free_node(ni
);
2172 switch (k
->wk_cipher
->ic_cipher
)
2174 case IEEE80211_CIPHER_WEP
:
2175 if(k
->wk_keylen
< 8)
2176 mode
= RT2860_REG_CIPHER_MODE_WEP40
;
2178 mode
= RT2860_REG_CIPHER_MODE_WEP104
;
2181 case IEEE80211_CIPHER_TKIP
:
2182 mode
= RT2860_REG_CIPHER_MODE_TKIP
;
2185 case IEEE80211_CIPHER_AES_CCM
:
2186 mode
= RT2860_REG_CIPHER_MODE_AES_CCMP
;
2193 RT2860_DPRINTF(sc
, RT2860_DEBUG_KEY
,
2194 "%s: set key: keyix=%d, keylen=%d, macaddr=%s, associd=0x%04x, mode=%d, group=%d\n",
2195 device_get_nameunit(sc
->dev
), k
->wk_keyix
, k
->wk_keylen
, ether_sprintf(mac
),
2196 associd
, mode
, (k
->wk_flags
& IEEE80211_KEY_GROUP
) ? 1 : 0);
2198 if (!(k
->wk_flags
& IEEE80211_KEY_GROUP
))
2200 /* install pairwise key */
2204 wcid
= RT2860_AID2WCID(associd
);
2208 key_base
= RT2860_REG_PKEY(wcid
);
2210 if (k
->wk_cipher
->ic_cipher
== IEEE80211_CIPHER_WEP
)
2214 iv
[3] = (k
->wk_keyix
<< 6);
2218 if (k
->wk_cipher
->ic_cipher
== IEEE80211_CIPHER_TKIP
)
2220 iv
[0] = (k
->wk_keytsc
>> 8);
2221 iv
[1] = ((iv
[0] | 0x20) & 0x7f);
2222 iv
[2] = k
->wk_keytsc
;
2228 iv
[0] = k
->wk_keytsc
;
2229 iv
[1] = k
->wk_keytsc
>> 8;
2233 iv
[3] = ((k
->wk_keyix
<< 6) | IEEE80211_WEP_EXTIV
);
2234 iv
[4] = (k
->wk_keytsc
>> 16);
2235 iv
[5] = (k
->wk_keytsc
>> 24);
2236 iv
[6] = (k
->wk_keytsc
>> 32);
2237 iv
[7] = (k
->wk_keytsc
>> 40);
2239 RT2860_DPRINTF(sc
, RT2860_DEBUG_KEY
,
2240 "%s: set key: iv=%02x %02x %02x %02x %02x %02x %02x %02x\n",
2241 device_get_nameunit(sc
->dev
),
2242 iv
[0], iv
[1], iv
[2], iv
[3], iv
[4], iv
[5], iv
[6], iv
[7]);
2245 rt2860_io_mac_write_multi(sc
, RT2860_REG_IVEIV(wcid
), iv
, 8);
2247 if (k
->wk_cipher
->ic_cipher
== IEEE80211_CIPHER_TKIP
)
2249 rt2860_io_mac_write_multi(sc
, key_base
, k
->wk_key
, 16);
2251 if (ic
->ic_opmode
!= IEEE80211_M_HOSTAP
)
2253 rt2860_io_mac_write_multi(sc
, key_base
+ 16, &k
->wk_key
[16], 8);
2254 rt2860_io_mac_write_multi(sc
, key_base
+ 24, &k
->wk_key
[24], 8);
2258 rt2860_io_mac_write_multi(sc
, key_base
+ 16, &k
->wk_key
[24], 8);
2259 rt2860_io_mac_write_multi(sc
, key_base
+ 24, &k
->wk_key
[16], 8);
2264 rt2860_io_mac_write_multi(sc
, key_base
, k
->wk_key
, k
->wk_keylen
);
2267 tmp
= ((vapid
& RT2860_REG_VAP_MASK
) << RT2860_REG_VAP_SHIFT
) |
2268 (mode
<< RT2860_REG_CIPHER_MODE_SHIFT
) | RT2860_REG_PKEY_ENABLE
;
2270 rt2860_io_mac_write(sc
, RT2860_REG_WCID_ATTR(wcid
), tmp
);
2275 if ((k
->wk_flags
& IEEE80211_KEY_GROUP
) ||
2276 (k
->wk_cipher
->ic_cipher
== IEEE80211_CIPHER_WEP
))
2278 /* install group key */
2281 wcid
= RT2860_WCID_MCAST
;
2282 key_base
= RT2860_REG_SKEY(vapid
, k
->wk_keyix
);
2283 keymode_base
= RT2860_REG_SKEY_MODE(vapid
);
2285 if (k
->wk_cipher
->ic_cipher
== IEEE80211_CIPHER_TKIP
)
2287 rt2860_io_mac_write_multi(sc
, key_base
, k
->wk_key
, 16);
2289 if (ic
->ic_opmode
!= IEEE80211_M_HOSTAP
)
2291 rt2860_io_mac_write_multi(sc
, key_base
+ 16, &k
->wk_key
[16], 8);
2292 rt2860_io_mac_write_multi(sc
, key_base
+ 24, &k
->wk_key
[24], 8);
2296 rt2860_io_mac_write_multi(sc
, key_base
+ 16, &k
->wk_key
[24], 8);
2297 rt2860_io_mac_write_multi(sc
, key_base
+ 24, &k
->wk_key
[16], 8);
2302 rt2860_io_mac_write_multi(sc
, key_base
, k
->wk_key
, k
->wk_keylen
);
2305 tmp
= rt2860_io_mac_read(sc
, keymode_base
);
2307 tmp
&= ~(0xf << (k
->wk_keyix
* 4 + 16 * (vapid
% 2)));
2308 tmp
|= (mode
<< (k
->wk_keyix
* 4 + 16 * (vapid
% 2)));
2310 rt2860_io_mac_write(sc
, keymode_base
, tmp
);
2312 if (ic
->ic_opmode
== IEEE80211_M_HOSTAP
)
2314 if (k
->wk_cipher
->ic_cipher
== IEEE80211_CIPHER_WEP
)
2318 iv
[3] = (k
->wk_keyix
<< 6);
2322 if (k
->wk_cipher
->ic_cipher
== IEEE80211_CIPHER_TKIP
)
2324 iv
[0] = (k
->wk_keytsc
>> 8);
2325 iv
[1] = ((iv
[0] | 0x20) & 0x7f);
2326 iv
[2] = k
->wk_keytsc
;
2332 iv
[0] = k
->wk_keytsc
;
2333 iv
[1] = k
->wk_keytsc
>> 8;
2337 iv
[3] = ((k
->wk_keyix
<< 6) | IEEE80211_WEP_EXTIV
);
2338 iv
[4] = (k
->wk_keytsc
>> 16);
2339 iv
[5] = (k
->wk_keytsc
>> 24);
2340 iv
[6] = (k
->wk_keytsc
>> 32);
2341 iv
[7] = (k
->wk_keytsc
>> 40);
2343 RT2860_DPRINTF(sc
, RT2860_DEBUG_KEY
,
2344 "%s: set key: iv=%02x %02x %02x %02x %02x %02x %02x %02x\n",
2345 device_get_nameunit(sc
->dev
),
2346 iv
[0], iv
[1], iv
[2], iv
[3], iv
[4], iv
[5], iv
[6], iv
[7]);
2349 rt2860_io_mac_write_multi(sc
, RT2860_REG_IVEIV(wcid
), iv
, 8);
2351 tmp
= ((vapid
& RT2860_REG_VAP_MASK
) << RT2860_REG_VAP_SHIFT
) |
2352 (mode
<< RT2860_REG_CIPHER_MODE_SHIFT
) | RT2860_REG_PKEY_ENABLE
;
2354 rt2860_io_mac_write(sc
, RT2860_REG_WCID_ATTR(wcid
), tmp
);
2364 static int rt2860_key_delete(struct ieee80211com
*ic
,
2365 const struct ieee80211_key
*k
)
2367 struct rt2860_softc
*sc
;
2368 uint8_t vapid
, wcid
;
2371 sc
= ic
->ic_ifp
->if_softc
;
2373 RT2860_DPRINTF(sc
, RT2860_DEBUG_KEY
,
2374 "%s: delete key: keyix=%d, keylen=%d, wcid=0x%02x, group=%d\n",
2375 device_get_nameunit(sc
->dev
), k
->wk_keyix
, k
->wk_keylen
, k
->wk_pad
,
2376 (k
->wk_flags
& IEEE80211_KEY_GROUP
) ? 1 : 0);
2378 if (!(k
->wk_flags
& IEEE80211_KEY_GROUP
))
2380 /* remove pairwise key */
2388 tmp
= ((vapid
& RT2860_REG_VAP_MASK
) << RT2860_REG_VAP_SHIFT
) |
2389 (RT2860_REG_CIPHER_MODE_NONE
<< RT2860_REG_CIPHER_MODE_SHIFT
) | RT2860_REG_PKEY_ENABLE
;
2391 rt2860_io_mac_write(sc
, RT2860_REG_WCID_ATTR(wcid
), tmp
);
2395 /* remove group key */
2398 wcid
= RT2860_WCID_MCAST
;
2400 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_SKEY_MODE(vapid
));
2402 tmp
&= ~(0xf << (k
->wk_keyix
* 4 + 16 * (vapid
% 2)));
2403 tmp
|= (RT2860_REG_CIPHER_MODE_NONE
<< (k
->wk_keyix
* 4 + 16 * (vapid
% 2)));
2405 rt2860_io_mac_write(sc
, RT2860_REG_SKEY_MODE(vapid
), tmp
);
2407 if (ic
->ic_opmode
== IEEE80211_M_HOSTAP
)
2409 tmp
= ((vapid
& RT2860_REG_VAP_MASK
) << RT2860_REG_VAP_SHIFT
) |
2410 (RT2860_REG_CIPHER_MODE_NONE
<< RT2860_REG_CIPHER_MODE_SHIFT
) | RT2860_REG_PKEY_ENABLE
;
2412 rt2860_io_mac_write(sc
, RT2860_REG_WCID_ATTR(wcid
), tmp
);
2422 static int rt2860_raw_xmit(struct ieee80211_node
*ni
, struct mbuf
*m
,
2423 const struct ieee80211_bpf_params
*params
)
2429 * rt2860_media_change
2431 static int rt2860_media_change(struct ifnet
*ifp
)
2433 struct rt2860_softc
*sc
;
2438 error
= ieee80211_media_change(ifp
);
2439 if (error
!= ENETRESET
)
2442 RT2860_SOFTC_LOCK(sc
);
2444 if ((ifp
->if_flags
& IFF_UP
) && (ifp
->if_drv_flags
& IFF_DRV_RUNNING
))
2446 rt2860_stop_locked(sc
);
2447 rt2860_init_locked(sc
);
2450 RT2860_SOFTC_UNLOCK(sc
);
2458 static struct ieee80211_node
*rt2860_node_alloc(struct ieee80211_node_table
*nt
)
2460 return malloc(sizeof(struct rt2860_softc_node
),
2461 M_80211_NODE
, M_NOWAIT
| M_ZERO
);
2465 * rt2860_recv_action
2467 static void rt2860_recv_action(struct ieee80211_node
*ni
,
2468 const uint8_t *frm
, const uint8_t *efrm
)
2470 struct rt2860_softc
*sc
;
2471 struct ieee80211com
*ic
;
2473 const struct ieee80211_action
*ia
;
2474 struct ieee80211_tx_ampdu
*tx_ampdu
;
2475 uint16_t associd
, status
, baparamset
;
2477 int tid
, bufsize
, ac
;
2484 ia
= (const struct ieee80211_action
*) frm
;
2486 sc
->recv_action(ni
, frm
, efrm
);
2488 if (ia
->ia_category
!= IEEE80211_ACTION_CAT_BA
)
2491 associd
= (ni
!= NULL
) ? ni
->ni_associd
: 0;
2492 wcid
= RT2860_AID2WCID(associd
);
2494 switch (ia
->ia_action
)
2496 /* IEEE80211_ACTION_BA_ADDBA_REQUEST */
2497 case IEEE80211_ACTION_BA_ADDBA_REQUEST
:
2498 baparamset
= LE_READ_2(frm
+ 3);
2499 tid
= RT2860_MS(baparamset
, IEEE80211_BAPS_TID
);
2500 bufsize
= RT2860_MS(baparamset
, IEEE80211_BAPS_BUFSIZ
);
2502 RT2860_DPRINTF(sc
, RT2860_DEBUG_BA
,
2503 "%s: received ADDBA request: associd=0x%04x, tid=%d, bufsize=%d\n",
2504 device_get_nameunit(sc
->dev
), associd
, tid
, bufsize
);
2506 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_WCID(wcid
) + 4);
2508 tmp
|= (0x10000 << tid
);
2510 rt2860_io_mac_write(sc
, RT2860_REG_WCID(wcid
) + 4, tmp
);
2513 /* IEEE80211_ACTION_BA_ADDBA_RESPONSE */
2514 case IEEE80211_ACTION_BA_ADDBA_RESPONSE
:
2515 status
= LE_READ_2(frm
+ 3);
2516 baparamset
= LE_READ_2(frm
+ 4);
2517 tid
= RT2860_MS(baparamset
, IEEE80211_BAPS_TID
);
2518 bufsize
= RT2860_MS(baparamset
, IEEE80211_BAPS_BUFSIZ
);
2519 ac
= TID_TO_WME_AC(tid
);
2520 tx_ampdu
= &ni
->ni_tx_ampdu
[ac
];
2522 RT2860_DPRINTF(sc
, RT2860_DEBUG_BA
,
2523 "%s: received ADDBA response: associd=0x%04x, status=%d, tid=%d, bufsize=%d\n",
2524 device_get_nameunit(sc
->dev
), associd
, status
, tid
, bufsize
);
2526 if (sc
->mac_rev
>= 0x28720200)
2528 if (tx_ampdu
->txa_wnd
> 13)
2529 tx_ampdu
->txa_wnd
= 13;
2533 if (tx_ampdu
->txa_wnd
> 7)
2534 tx_ampdu
->txa_wnd
= 7;
2537 if (status
== IEEE80211_STATUS_SUCCESS
)
2539 sc
->tx_ampdu_sessions
++;
2541 rt2860_asic_updateprot(sc
);
2545 /* IEEE80211_ACTION_BA_DELBA */
2546 case IEEE80211_ACTION_BA_DELBA
:
2547 baparamset
= LE_READ_2(frm
+ 2);
2548 tid
= RT2860_MS(baparamset
, IEEE80211_BAPS_TID
);
2550 RT2860_DPRINTF(sc
, RT2860_DEBUG_BA
,
2551 "%s: received DELBA request: associd=0x%04x, tid=%d\n",
2552 device_get_nameunit(sc
->dev
), associd
, tid
);
2554 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_WCID(wcid
) + 4);
2556 tmp
&= ~(0x10000 << tid
);
2558 rt2860_io_mac_write(sc
, RT2860_REG_WCID(wcid
) + 4, tmp
);
2564 * rt2860_send_action
2566 static int rt2860_send_action(struct ieee80211_node
*ni
,
2567 int category
, int action
, uint16_t args
[4])
2569 struct rt2860_softc
*sc
;
2570 struct ieee80211com
*ic
;
2572 uint16_t associd
, baparamset
;
2581 ret
= sc
->send_action(ni
, category
, action
, args
);
2583 if (category
!= IEEE80211_ACTION_CAT_BA
)
2586 associd
= (ni
!= NULL
) ? ni
->ni_associd
: 0;
2587 wcid
= RT2860_AID2WCID(associd
);
2591 /* IEEE80211_ACTION_BA_DELBA */
2592 case IEEE80211_ACTION_BA_DELBA
:
2593 baparamset
= RT2860_SM(args
[0], IEEE80211_DELBAPS_TID
) | args
[1];
2595 tid
= RT2860_MS(baparamset
, IEEE80211_DELBAPS_TID
);
2597 RT2860_DPRINTF(sc
, RT2860_DEBUG_BA
,
2598 "%s: sending DELBA request: associd=0x%04x, tid=%d\n",
2599 device_get_nameunit(sc
->dev
), associd
, tid
);
2601 if (RT2860_MS(baparamset
, IEEE80211_DELBAPS_INIT
) != IEEE80211_DELBAPS_INIT
)
2603 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_WCID(wcid
) + 4);
2605 tmp
&= ~(0x10000 << tid
);
2607 rt2860_io_mac_write(sc
, RT2860_REG_WCID(wcid
) + 4, tmp
);
2611 sc
->tx_ampdu_sessions
--;
2613 rt2860_asic_updateprot(sc
);
2622 * rt2860_amrr_update_iter_func
2624 static void rt2860_amrr_update_iter_func(void *arg
, struct ieee80211_node
*ni
)
2626 struct rt2860_softc
*sc
;
2627 struct ieee80211com
*ic
;
2633 /* only associated stations */
2635 if (ni
->ni_associd
!= 0)
2637 wcid
= RT2860_AID2WCID(ni
->ni_associd
);
2639 RT2860_DPRINTF(sc
, RT2860_DEBUG_RATE
,
2640 "%s: AMRR node: wcid=0x%02x, txcnt=%d, success=%d, retrycnt=%d\n",
2641 device_get_nameunit(sc
->dev
),
2642 wcid
, sc
->amrr_node
[wcid
].txcnt
, sc
->amrr_node
[wcid
].success
, sc
->amrr_node
[wcid
].retrycnt
);
2644 rt2860_amrr_choose(ni
, &sc
->amrr_node
[wcid
]);
2646 RT2860_DPRINTF(sc
, RT2860_DEBUG_RATE
,
2647 "%s:%s node Tx rate: associd=0x%04x, rate=0x%02x, max rate=0x%02x\n",
2648 device_get_nameunit(sc
->dev
),
2649 (ni
->ni_flags
& IEEE80211_NODE_HT
) ? " HT" : "",
2651 (ni
->ni_flags
& IEEE80211_NODE_HT
) ?
2652 (ni
->ni_htrates
.rs_rates
[ni
->ni_txrate
] | IEEE80211_RATE_MCS
) :
2653 (ni
->ni_rates
.rs_rates
[ni
->ni_txrate
] & IEEE80211_RATE_VAL
),
2654 (ni
->ni_flags
& IEEE80211_NODE_HT
) ?
2655 (ni
->ni_htrates
.rs_rates
[ni
->ni_htrates
.rs_nrates
- 1] | IEEE80211_RATE_MCS
) :
2656 (ni
->ni_rates
.rs_rates
[ni
->ni_rates
.rs_nrates
- 1] & IEEE80211_RATE_VAL
));
2663 static void rt2860_periodic(void *arg
)
2665 struct rt2860_softc
*sc
;
2669 RT2860_DPRINTF(sc
, RT2860_DEBUG_PERIODIC
,
2671 device_get_nameunit(sc
->dev
));
2673 taskqueue_enqueue(sc
->taskqueue
, &sc
->periodic_task
);
2677 * rt2860_tx_watchdog
2679 static void rt2860_tx_watchdog(void *arg
)
2681 struct rt2860_softc
*sc
;
2687 if (sc
->tx_timer
== 0)
2690 if (--sc
->tx_timer
== 0)
2692 printf("%s: Tx watchdog timeout: resetting\n",
2693 device_get_nameunit(sc
->dev
));
2695 rt2860_stop_locked(sc
);
2696 rt2860_init_locked(sc
);
2700 sc
->tx_watchdog_timeouts
++;
2703 callout_reset(&sc
->tx_watchdog_ch
, hz
, rt2860_tx_watchdog
, sc
);
2707 * rt2860_asic_set_bssid
2709 static void rt2860_asic_set_bssid(struct rt2860_softc
*sc
,
2710 const uint8_t *bssid
)
2714 RT2860_DPRINTF(sc
, RT2860_DEBUG_STATE
,
2715 "%s: set bssid: bssid=%s\n",
2716 device_get_nameunit(sc
->dev
), ether_sprintf(bssid
));
2718 tmp
= bssid
[0] | (bssid
[1]) << 8 | (bssid
[2] << 16) | (bssid
[3] << 24);
2720 rt2860_io_mac_write(sc
, RT2860_REG_BSSID_DW0
, tmp
);
2722 tmp
= bssid
[4] | (bssid
[5] << 8);
2724 rt2860_io_mac_write(sc
, RT2860_REG_BSSID_DW1
, tmp
);
2728 * rt2860_asic_set_macaddr
2730 static void rt2860_asic_set_macaddr(struct rt2860_softc
*sc
,
2731 const uint8_t *addr
)
2735 tmp
= addr
[0] | (addr
[1] << 8) | (addr
[2] << 16) | (addr
[3] << 24);
2737 rt2860_io_mac_write(sc
, RT2860_REG_ADDR_DW0
, tmp
);
2739 tmp
= addr
[4] | (addr
[5] << 8);
2741 rt2860_io_mac_write(sc
, RT2860_REG_ADDR_DW1
, tmp
);
2745 * rt2860_asic_enable_tsf_sync
2747 static void rt2860_asic_enable_tsf_sync(struct rt2860_softc
*sc
)
2749 struct ieee80211com
*ic
;
2754 RT2860_DPRINTF(sc
, RT2860_DEBUG_BEACON
,
2755 "%s: enabling TSF\n",
2756 device_get_nameunit(sc
->dev
));
2758 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_BCN_TIME_CFG
);
2761 tmp
|= ic
->ic_bss
->ni_intval
* 16;
2762 tmp
|= (RT2860_REG_TSF_TIMER_ENABLE
| RT2860_REG_TBTT_TIMER_ENABLE
);
2764 if (ic
->ic_opmode
== IEEE80211_M_STA
)
2766 tmp
|= (RT2860_REG_TSF_SYNC_MODE_STA
<< RT2860_REG_TSF_SYNC_MODE_SHIFT
);
2768 else if (ic
->ic_opmode
== IEEE80211_M_IBSS
)
2770 tmp
|= RT2860_REG_BCN_TX_ENABLE
;
2771 tmp
|= (RT2860_REG_TSF_SYNC_MODE_IBSS
<< RT2860_REG_TSF_SYNC_MODE_SHIFT
);
2773 else if (ic
->ic_opmode
== IEEE80211_M_HOSTAP
)
2775 tmp
|= RT2860_REG_BCN_TX_ENABLE
;
2776 tmp
|= (RT2860_REG_TSF_SYNC_MODE_HOSTAP
<< RT2860_REG_TSF_SYNC_MODE_SHIFT
);
2779 rt2860_io_mac_write(sc
, RT2860_REG_BCN_TIME_CFG
, tmp
);
2783 * rt2860_asic_disable_tsf_sync
2785 static void rt2860_asic_disable_tsf_sync(struct rt2860_softc
*sc
)
2789 RT2860_DPRINTF(sc
, RT2860_DEBUG_BEACON
,
2790 "%s: disabling TSF\n",
2791 device_get_nameunit(sc
->dev
));
2793 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_BCN_TIME_CFG
);
2795 tmp
&= ~(RT2860_REG_BCN_TX_ENABLE
|
2796 RT2860_REG_TSF_TIMER_ENABLE
|
2797 RT2860_REG_TBTT_TIMER_ENABLE
);
2799 tmp
&= ~(RT2860_REG_TSF_SYNC_MODE_MASK
<< RT2860_REG_TSF_SYNC_MODE_SHIFT
);
2800 tmp
|= (RT2860_REG_TSF_SYNC_MODE_DISABLE
<< RT2860_REG_TSF_SYNC_MODE_SHIFT
);
2802 rt2860_io_mac_write(sc
, RT2860_REG_BCN_TIME_CFG
, tmp
);
2806 * rt2860_asic_enable_mrr
2808 static void rt2860_asic_enable_mrr(struct rt2860_softc
*sc
)
2810 #define CCK(mcs) (mcs)
2811 #define OFDM(mcs) ((1 << 3) | (mcs))
2812 #define HT(mcs) (mcs)
2814 rt2860_io_mac_write(sc
, RT2860_REG_TX_LG_FBK_CFG0
,
2815 (OFDM(6) << 28) | /* 54 -> 48 */
2816 (OFDM(5) << 24) | /* 48 -> 36 */
2817 (OFDM(4) << 20) | /* 36 -> 24 */
2818 (OFDM(3) << 16) | /* 24 -> 18 */
2819 (OFDM(2) << 12) | /* 18 -> 12 */
2820 (OFDM(1) << 8) | /* 12 -> 9 */
2821 (OFDM(0) << 4) | /* 9 -> 6 */
2822 OFDM(0)); /* 6 -> 6 */
2824 rt2860_io_mac_write(sc
, RT2860_REG_TX_LG_FBK_CFG1
,
2825 (CCK(2) << 12) | /* 11 -> 5.5 */
2826 (CCK(1) << 8) | /* 5.5 -> 2 */
2827 (CCK(0) << 4) | /* 2 -> 1 */
2828 CCK(0)); /* 1 -> 1 */
2830 rt2860_io_mac_write(sc
, RT2860_REG_TX_HT_FBK_CFG0
,
2840 rt2860_io_mac_write(sc
, RT2860_REG_TX_HT_FBK_CFG1
,
2856 * rt2860_asic_set_txpreamble
2858 static void rt2860_asic_set_txpreamble(struct rt2860_softc
*sc
)
2860 struct ieee80211com
*ic
;
2865 RT2860_DPRINTF(sc
, RT2860_DEBUG_STATE
,
2866 "%s: %s short Tx preamble\n",
2867 device_get_nameunit(sc
->dev
),
2868 (ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
) ? "enabling" : "disabling");
2870 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_AUTO_RSP_CFG
);
2872 tmp
&= ~RT2860_REG_CCK_SHORT_ENABLE
;
2874 if (sc
->ic
.ic_flags
& IEEE80211_F_SHPREAMBLE
)
2875 tmp
|= RT2860_REG_CCK_SHORT_ENABLE
;
2877 rt2860_io_mac_write(sc
, RT2860_REG_AUTO_RSP_CFG
, tmp
);
2881 * rt2860_asic_set_basicrates
2883 static void rt2860_asic_set_basicrates(struct rt2860_softc
*sc
)
2885 struct ieee80211com
*ic
;
2889 if (ic
->ic_curmode
== IEEE80211_MODE_11B
)
2890 rt2860_io_mac_write(sc
, RT2860_REG_LEGACY_BASIC_RATE
, 0x3);
2891 else if (ic
->ic_curmode
== IEEE80211_MODE_11A
)
2892 rt2860_io_mac_write(sc
, RT2860_REG_LEGACY_BASIC_RATE
, 0x150);
2894 rt2860_io_mac_write(sc
, RT2860_REG_LEGACY_BASIC_RATE
, 0x15f);
2898 * rt2860_asic_update_rtsthreshold
2900 static void rt2860_asic_update_rtsthreshold(struct rt2860_softc
*sc
)
2902 struct ieee80211com
*ic
;
2908 RT2860_DPRINTF(sc
, RT2860_DEBUG_PROT
,
2909 "%s: updating RTS threshold: %d\n",
2910 device_get_nameunit(sc
->dev
), ic
->ic_rtsthreshold
);
2912 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_TX_RTS_CFG
);
2914 tmp
&= ~(RT2860_REG_TX_RTS_THRESHOLD_MASK
<< RT2860_REG_TX_RTS_THRESHOLD_SHIFT
);
2916 if (ic
->ic_flags_ext
& IEEE80211_FEXT_AMSDU_TX
)
2919 threshold
= ic
->ic_rtsthreshold
;
2922 tmp
|= ((threshold
& RT2860_REG_TX_RTS_THRESHOLD_MASK
) <<
2923 RT2860_REG_TX_RTS_THRESHOLD_SHIFT
);
2925 rt2860_io_mac_write(sc
, RT2860_REG_TX_RTS_CFG
, tmp
);
2929 * rt2860_asic_update_txpower
2931 static void rt2860_asic_update_txpower(struct rt2860_softc
*sc
)
2933 struct ieee80211com
*ic
;
2934 uint32_t *txpow_rate
;
2942 RT2860_DPRINTF(sc
, RT2860_DEBUG_STATE
,
2943 "%s: updating Tx power: %d\n",
2944 device_get_nameunit(sc
->dev
), ic
->ic_txpowlimit
);
2946 if (!IEEE80211_IS_CHAN_HT40(ic
->ic_curchan
))
2948 txpow_rate
= sc
->txpow_rate_20mhz
;
2952 if (IEEE80211_IS_CHAN_2GHZ(ic
->ic_curchan
))
2953 txpow_rate
= sc
->txpow_rate_40mhz_2ghz
;
2955 txpow_rate
= sc
->txpow_rate_40mhz_5ghz
;
2960 val
= rt2860_io_bbp_read(sc
, 1);
2963 if (ic
->ic_txpowlimit
> 90)
2967 else if (ic
->ic_txpowlimit
> 60)
2971 else if (ic
->ic_txpowlimit
> 30)
2975 else if (ic
->ic_txpowlimit
> 15)
2979 else if (ic
->ic_txpowlimit
> 9)
2989 rt2860_io_bbp_write(sc
, 1, val
);
2991 for (i
= 0; i
< RT2860_SOFTC_TXPOW_RATE_COUNT
; i
++)
2993 if (txpow_rate
[i
] == 0xffffffff)
2996 tmp
= rt2860_read_eeprom_txpow_rate_add_delta(txpow_rate
[i
], delta
);
2998 rt2860_io_mac_write(sc
, RT2860_REG_TX_PWR_CFG(i
), tmp
);
3003 * rt2860_asic_update_promisc
3005 static void rt2860_asic_update_promisc(struct rt2860_softc
*sc
)
3010 ifp
= sc
->ic
.ic_ifp
;
3012 printf("%s: %s promiscuous mode\n",
3013 device_get_nameunit(sc
->dev
),
3014 (ifp
->if_flags
& IFF_PROMISC
) ? "entering" : "leaving");
3016 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_RX_FILTER_CFG
);
3018 tmp
&= ~RT2860_REG_RX_FILTER_DROP_UC_NOME
;
3020 if (!(ifp
->if_flags
& IFF_PROMISC
))
3021 tmp
|= RT2860_REG_RX_FILTER_DROP_UC_NOME
;
3023 rt2860_io_mac_write(sc
, RT2860_REG_RX_FILTER_CFG
, tmp
);
3027 * rt2860_asic_updateprot
3029 static void rt2860_asic_updateprot(struct rt2860_softc
*sc
)
3031 struct ieee80211com
*ic
;
3032 uint32_t cck_prot
, ofdm_prot
, mm20_prot
, mm40_prot
, gf20_prot
, gf40_prot
;
3034 enum ieee80211_protmode htprotmode
;
3038 /* CCK frame protection */
3040 cck_prot
= RT2860_REG_RTSTH_ENABLE
| RT2860_REG_PROT_NAV_SHORT
|
3041 RT2860_REG_TXOP_ALLOW_ALL
| RT2860_REG_PROT_CTRL_NONE
;
3043 /* set up protection frame phy mode and rate (MCS code) */
3045 if (ic
->ic_curmode
== IEEE80211_MODE_11A
)
3046 cck_prot
|= (RT2860_REG_PROT_PHYMODE_OFDM
<< RT2860_REG_PROT_PHYMODE_SHIFT
) |
3047 (0 << RT2860_REG_PROT_MCS_SHIFT
);
3049 cck_prot
|= ((RT2860_REG_PROT_PHYMODE_CCK
<< RT2860_REG_PROT_PHYMODE_SHIFT
) |
3050 (3 << RT2860_REG_PROT_MCS_SHIFT
));
3052 rt2860_io_mac_write(sc
, RT2860_REG_TX_CCK_PROT_CFG
, cck_prot
);
3054 /* OFDM frame protection */
3056 ofdm_prot
= RT2860_REG_RTSTH_ENABLE
| RT2860_REG_PROT_NAV_SHORT
|
3057 RT2860_REG_TXOP_ALLOW_ALL
;
3059 if (ic
->ic_flags
& IEEE80211_F_USEPROT
)
3061 RT2860_DPRINTF(sc
, RT2860_DEBUG_PROT
,
3062 "%s: updating protection mode: b/g protection mode=%s\n",
3063 device_get_nameunit(sc
->dev
),
3064 (ic
->ic_protmode
== IEEE80211_PROT_RTSCTS
) ? "RTS/CTS" :
3065 ((ic
->ic_protmode
== IEEE80211_PROT_CTSONLY
) ? "CTS-to-self" : "none"));
3067 if (ic
->ic_protmode
== IEEE80211_PROT_RTSCTS
)
3068 ofdm_prot
|= RT2860_REG_PROT_CTRL_RTS_CTS
;
3069 else if (ic
->ic_protmode
== IEEE80211_PROT_CTSONLY
)
3070 ofdm_prot
|= RT2860_REG_PROT_CTRL_CTS
;
3072 ofdm_prot
|= RT2860_REG_PROT_CTRL_NONE
;
3076 RT2860_DPRINTF(sc
, RT2860_DEBUG_PROT
,
3077 "%s: updating protection mode: b/g protection mode=%s\n",
3078 device_get_nameunit(sc
->dev
), "none");
3080 ofdm_prot
|= RT2860_REG_PROT_CTRL_NONE
;
3083 rt2860_io_mac_write(sc
, RT2860_REG_TX_OFDM_PROT_CFG
, ofdm_prot
);
3085 /* HT frame protection */
3087 if ((ic
->ic_opmode
== IEEE80211_M_STA
) && (ic
->ic_state
== IEEE80211_S_RUN
))
3088 htopmode
= ic
->ic_bss
->ni_htopmode
;
3090 htopmode
= ic
->ic_curhtprotmode
;
3092 htprotmode
= ic
->ic_htprotmode
;
3094 /* force HT mixed mode and RTS/CTS protection if A-MPDU Tx aggregation is enabled */
3096 if (sc
->tx_ampdu_sessions
> 0)
3098 RT2860_DPRINTF(sc
, RT2860_DEBUG_PROT
,
3099 "%s: updating protection mode: forcing HT mixed mode and RTS/CTS protection\n",
3100 device_get_nameunit(sc
->dev
));
3102 htopmode
= IEEE80211_HTINFO_OPMODE_MIXED
;
3103 htprotmode
= IEEE80211_PROT_RTSCTS
;
3106 RT2860_DPRINTF(sc
, RT2860_DEBUG_PROT
,
3107 "%s: updating protection mode: HT operation mode=0x%02x, protection mode=%s\n",
3108 device_get_nameunit(sc
->dev
),
3109 htopmode
& IEEE80211_HTINFO_OPMODE
,
3110 (htprotmode
== IEEE80211_PROT_RTSCTS
) ? "RTS/CTS" :
3111 ((htprotmode
== IEEE80211_PROT_CTSONLY
) ? "CTS-to-self" : "none"));
3113 switch (htopmode
& IEEE80211_HTINFO_OPMODE
)
3115 /* IEEE80211_HTINFO_OPMODE_HT20PR */
3116 case IEEE80211_HTINFO_OPMODE_HT20PR
:
3117 mm20_prot
= RT2860_REG_PROT_NAV_SHORT
| RT2860_REG_PROT_CTRL_NONE
|
3118 RT2860_REG_TXOP_ALLOW_CCK
| RT2860_REG_TXOP_ALLOW_OFDM
|
3119 RT2860_REG_TXOP_ALLOW_MM20
| RT2860_REG_TXOP_ALLOW_GF20
|
3120 (RT2860_REG_PROT_PHYMODE_OFDM
<< RT2860_REG_PROT_PHYMODE_SHIFT
) |
3121 (4 << RT2860_REG_PROT_MCS_SHIFT
);
3123 gf20_prot
= mm20_prot
;
3125 mm40_prot
= RT2860_REG_PROT_NAV_SHORT
| RT2860_REG_TXOP_ALLOW_ALL
|
3126 (RT2860_REG_PROT_PHYMODE_OFDM
<< RT2860_REG_PROT_PHYMODE_SHIFT
) |
3127 (0x84 << RT2860_REG_PROT_MCS_SHIFT
);
3129 if (htprotmode
== IEEE80211_PROT_RTSCTS
)
3130 mm40_prot
|= RT2860_REG_PROT_CTRL_RTS_CTS
;
3131 else if (htprotmode
== IEEE80211_PROT_CTSONLY
)
3132 mm40_prot
|= RT2860_REG_PROT_CTRL_CTS
;
3134 mm40_prot
|= RT2860_REG_PROT_CTRL_NONE
;
3136 gf40_prot
= mm40_prot
;
3139 /* IEEE80211_HTINFO_OPMODE_MIXED */
3140 case IEEE80211_HTINFO_OPMODE_MIXED
:
3141 mm20_prot
= RT2860_REG_PROT_NAV_SHORT
|
3142 RT2860_REG_TXOP_ALLOW_CCK
| RT2860_REG_TXOP_ALLOW_OFDM
|
3143 RT2860_REG_TXOP_ALLOW_MM20
| RT2860_REG_TXOP_ALLOW_GF20
;
3145 if (ic
->ic_flags
& IEEE80211_F_USEPROT
)
3146 mm20_prot
|= (RT2860_REG_PROT_PHYMODE_CCK
<< RT2860_REG_PROT_PHYMODE_SHIFT
) |
3147 (3 << RT2860_REG_PROT_MCS_SHIFT
);
3149 mm20_prot
|= (RT2860_REG_PROT_PHYMODE_OFDM
<< RT2860_REG_PROT_PHYMODE_SHIFT
) |
3150 (4 << RT2860_REG_PROT_MCS_SHIFT
);
3152 if (htprotmode
== IEEE80211_PROT_RTSCTS
)
3153 mm20_prot
|= RT2860_REG_PROT_CTRL_RTS_CTS
;
3154 else if (htprotmode
== IEEE80211_PROT_CTSONLY
)
3155 mm20_prot
|= RT2860_REG_PROT_CTRL_CTS
;
3157 mm20_prot
|= RT2860_REG_PROT_CTRL_NONE
;
3159 gf20_prot
= mm20_prot
;
3161 mm40_prot
= RT2860_REG_PROT_NAV_SHORT
| RT2860_REG_TXOP_ALLOW_ALL
;
3163 if (ic
->ic_flags
& IEEE80211_F_USEPROT
)
3164 mm40_prot
|= (RT2860_REG_PROT_PHYMODE_CCK
<< RT2860_REG_PROT_PHYMODE_SHIFT
) |
3165 (3 << RT2860_REG_PROT_MCS_SHIFT
);
3167 mm40_prot
|= (RT2860_REG_PROT_PHYMODE_OFDM
<< RT2860_REG_PROT_PHYMODE_SHIFT
) |
3168 (0x84 << RT2860_REG_PROT_MCS_SHIFT
);
3170 if (htprotmode
== IEEE80211_PROT_RTSCTS
)
3171 mm40_prot
|= RT2860_REG_PROT_CTRL_RTS_CTS
;
3172 else if (htprotmode
== IEEE80211_PROT_CTSONLY
)
3173 mm40_prot
|= RT2860_REG_PROT_CTRL_CTS
;
3175 mm40_prot
|= RT2860_REG_PROT_CTRL_NONE
;
3177 gf40_prot
= mm40_prot
;
3181 * IEEE80211_HTINFO_OPMODE_PURE
3182 * IEEE80211_HTINFO_OPMODE_PROTOPT
3184 case IEEE80211_HTINFO_OPMODE_PURE
:
3185 case IEEE80211_HTINFO_OPMODE_PROTOPT
:
3187 mm20_prot
= RT2860_REG_PROT_NAV_SHORT
| RT2860_REG_PROT_CTRL_NONE
|
3188 RT2860_REG_TXOP_ALLOW_CCK
| RT2860_REG_TXOP_ALLOW_OFDM
|
3189 RT2860_REG_TXOP_ALLOW_MM20
| RT2860_REG_TXOP_ALLOW_GF20
|
3190 (RT2860_REG_PROT_PHYMODE_OFDM
<< RT2860_REG_PROT_PHYMODE_SHIFT
) |
3191 (4 << RT2860_REG_PROT_MCS_SHIFT
);
3193 gf20_prot
= mm20_prot
;
3195 mm40_prot
= RT2860_REG_PROT_NAV_SHORT
| RT2860_REG_PROT_CTRL_NONE
|
3196 RT2860_REG_TXOP_ALLOW_ALL
|
3197 (RT2860_REG_PROT_PHYMODE_OFDM
<< RT2860_REG_PROT_PHYMODE_SHIFT
) |
3198 (0x84 << RT2860_REG_PROT_MCS_SHIFT
);
3200 gf40_prot
= mm40_prot
;
3204 rt2860_io_mac_write(sc
, RT2860_REG_TX_MM20_PROT_CFG
, mm20_prot
);
3205 rt2860_io_mac_write(sc
, RT2860_REG_TX_MM40_PROT_CFG
, mm40_prot
);
3206 rt2860_io_mac_write(sc
, RT2860_REG_TX_GF20_PROT_CFG
, gf20_prot
);
3207 rt2860_io_mac_write(sc
, RT2860_REG_TX_GF40_PROT_CFG
, gf40_prot
);
3211 * rt2860_asic_updateslot
3213 static void rt2860_asic_updateslot(struct rt2860_softc
*sc
)
3215 struct ieee80211com
*ic
;
3220 RT2860_DPRINTF(sc
, RT2860_DEBUG_STATE
,
3221 "%s: %s short slot time\n",
3222 device_get_nameunit(sc
->dev
),
3223 (ic
->ic_flags
& (IEEE80211_F_SHSLOT
| IEEE80211_F_BURST
)) ? "enabling" : "disabling");
3225 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_BKOFF_SLOT_CFG
);
3228 tmp
|= (ic
->ic_flags
& (IEEE80211_F_SHSLOT
|IEEE80211_F_BURST
)) ? 9 : 20;
3230 rt2860_io_mac_write(sc
, RT2860_REG_BKOFF_SLOT_CFG
, tmp
);
3234 * rt2860_asic_wme_update
3236 static void rt2860_asic_wme_update(struct rt2860_softc
*sc
)
3238 struct ieee80211com
*ic
;
3239 struct ieee80211_wme_state
*wme
;
3240 const struct wmeParams
*wmep
;
3245 wmep
= wme
->wme_chanParams
.cap_wmeParams
;
3247 RT2860_DPRINTF(sc
, RT2860_DEBUG_WME
,
3248 "%s: wme update: WME_AC_VO=%d/%d/%d/%d, WME_AC_VI=%d/%d/%d/%d, "
3249 "WME_AC_BK=%d/%d/%d/%d, WME_AC_BE=%d/%d/%d/%d\n",
3250 device_get_nameunit(sc
->dev
),
3251 wmep
[WME_AC_VO
].wmep_aifsn
,
3252 wmep
[WME_AC_VO
].wmep_logcwmin
, wmep
[WME_AC_VO
].wmep_logcwmax
,
3253 wmep
[WME_AC_VO
].wmep_txopLimit
,
3254 wmep
[WME_AC_VI
].wmep_aifsn
,
3255 wmep
[WME_AC_VI
].wmep_logcwmin
, wmep
[WME_AC_VI
].wmep_logcwmax
,
3256 wmep
[WME_AC_VI
].wmep_txopLimit
,
3257 wmep
[WME_AC_BK
].wmep_aifsn
,
3258 wmep
[WME_AC_BK
].wmep_logcwmin
, wmep
[WME_AC_BK
].wmep_logcwmax
,
3259 wmep
[WME_AC_BK
].wmep_txopLimit
,
3260 wmep
[WME_AC_BE
].wmep_aifsn
,
3261 wmep
[WME_AC_BE
].wmep_logcwmin
, wmep
[WME_AC_BE
].wmep_logcwmax
,
3262 wmep
[WME_AC_BE
].wmep_txopLimit
);
3264 for (i
= 0; i
< WME_NUM_AC
; i
++)
3265 rt2860_io_mac_write(sc
, RT2860_REG_TX_EDCA_AC_CFG(i
),
3266 (wmep
[i
].wmep_logcwmax
<< 16) | (wmep
[i
].wmep_logcwmin
<< 12) |
3267 (wmep
[i
].wmep_aifsn
<< 8) | wmep
[i
].wmep_txopLimit
);
3269 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_WMM_AIFSN_CFG
,
3270 (wmep
[WME_AC_VO
].wmep_aifsn
<< 12) | (wmep
[WME_AC_VI
].wmep_aifsn
<< 8) |
3271 (wmep
[WME_AC_BK
].wmep_aifsn
<< 4) | wmep
[WME_AC_BE
].wmep_aifsn
);
3273 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_WMM_CWMIN_CFG
,
3274 (wmep
[WME_AC_VO
].wmep_logcwmin
<< 12) | (wmep
[WME_AC_VI
].wmep_logcwmin
<< 8) |
3275 (wmep
[WME_AC_BK
].wmep_logcwmin
<< 4) | wmep
[WME_AC_BE
].wmep_logcwmin
);
3277 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_WMM_CWMAX_CFG
,
3278 (wmep
[WME_AC_VO
].wmep_logcwmax
<< 12) | (wmep
[WME_AC_VI
].wmep_logcwmax
<< 8) |
3279 (wmep
[WME_AC_BK
].wmep_logcwmax
<< 4) | wmep
[WME_AC_BE
].wmep_logcwmax
);
3281 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_WMM_TXOP0_CFG
,
3282 (wmep
[WME_AC_BK
].wmep_txopLimit
<< 16) | wmep
[WME_AC_BE
].wmep_txopLimit
);
3284 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_WMM_TXOP1_CFG
,
3285 (wmep
[WME_AC_VO
].wmep_txopLimit
<< 16) | wmep
[WME_AC_VI
].wmep_txopLimit
);
3289 * rt2860_asic_update_beacon
3291 static void rt2860_asic_update_beacon(struct rt2860_softc
*sc
)
3293 struct ieee80211com
*ic
;
3295 struct rt2860_txwi
*txwi
;
3300 m
= sc
->beacon_mbuf
;
3301 txwi
= &sc
->beacon_txwi
;
3303 /* disable temporarily TSF sync */
3305 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_BCN_TIME_CFG
);
3307 tmp
&= ~(RT2860_REG_BCN_TX_ENABLE
|
3308 RT2860_REG_TSF_TIMER_ENABLE
|
3309 RT2860_REG_TBTT_TIMER_ENABLE
);
3311 rt2860_io_mac_write(sc
, RT2860_REG_BCN_TIME_CFG
, tmp
);
3313 /* write Tx wireless info and beacon frame to on-chip memory */
3315 rt2860_io_mac_write_multi(sc
, RT2860_REG_BEACON_BASE(0),
3316 txwi
, sizeof(struct rt2860_txwi
));
3318 rt2860_io_mac_write_multi(sc
, RT2860_REG_BEACON_BASE(0) + sizeof(struct rt2860_txwi
),
3319 mtod(m
, uint8_t *), m
->m_pkthdr
.len
);
3321 /* enable again TSF sync */
3323 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_BCN_TIME_CFG
);
3325 tmp
|= (RT2860_REG_BCN_TX_ENABLE
|
3326 RT2860_REG_TSF_TIMER_ENABLE
|
3327 RT2860_REG_TBTT_TIMER_ENABLE
);
3329 rt2860_io_mac_write(sc
, RT2860_REG_BCN_TIME_CFG
, tmp
);
3333 * rt2860_asic_clear_keytables
3335 static void rt2860_asic_clear_keytables(struct rt2860_softc
*sc
)
3339 /* clear Rx WCID search table (entries = 256, entry size = 8) */
3341 for (i
= 0; i
< 256; i
++)
3343 rt2860_io_mac_write(sc
, RT2860_REG_WCID(i
), 0xffffffff);
3344 rt2860_io_mac_write(sc
, RT2860_REG_WCID(i
) + 4, 0x0000ffff);
3347 /* clear WCID attribute table (entries = 256, entry size = 4) */
3349 rt2860_io_mac_set_region_4(sc
, RT2860_REG_WCID_ATTR(0), 0, 256);
3351 /* clear IV/EIV table (entries = 256, entry size = 8) */
3353 rt2860_io_mac_set_region_4(sc
, RT2860_REG_IVEIV(0), 0, 2 * 256);
3355 /* clear pairwise key table (entries = 256, entry size = 32) */
3357 rt2860_io_mac_set_region_4(sc
, RT2860_REG_PKEY(0), 0, 8 * 256);
3359 /* clear shared key table (entries = 32, entry size = 32) */
3361 rt2860_io_mac_set_region_4(sc
, RT2860_REG_SKEY(0, 0), 0, 8 * 32);
3363 /* clear shared key mode (entries = 32, entry size = 2) */
3365 rt2860_io_mac_set_region_4(sc
, RT2860_REG_SKEY_MODE(0), 0, 16);
3369 * rt2860_beacon_alloc
3371 static int rt2860_beacon_alloc(struct rt2860_softc
*sc
)
3373 struct ieee80211com
*ic
;
3375 struct rt2860_txwi txwi
;
3380 m
= ieee80211_beacon_alloc(ic
->ic_bss
, &sc
->beacon_offsets
);
3384 rate
= IEEE80211_IS_CHAN_5GHZ(ic
->ic_curchan
) ? 12 : 2;
3385 mcs
= rt2860_rate2mcs(rate
);
3387 memset(&txwi
, 0, sizeof(struct rt2860_txwi
));
3390 txwi
.pid_mpdu_len
= ((htole16(m
->m_pkthdr
.len
) & RT2860_TXWI_MPDU_LEN_MASK
) <<
3391 RT2860_TXWI_MPDU_LEN_SHIFT
);
3392 txwi
.txop
= (RT2860_TXWI_TXOP_HT
<< RT2860_TXWI_TXOP_SHIFT
);
3393 txwi
.mpdu_density_flags
|=
3394 (RT2860_TXWI_FLAGS_TS
<< RT2860_TXWI_FLAGS_SHIFT
);
3395 txwi
.bawin_size_xflags
|=
3396 (RT2860_TXWI_XFLAGS_NSEQ
<< RT2860_TXWI_XFLAGS_SHIFT
);
3400 txwi
.phymode_ifs_stbc_shortgi
=
3401 (RT2860_TXWI_PHYMODE_CCK
<< RT2860_TXWI_PHYMODE_SHIFT
);
3403 if (rate
!= 2 && (ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
))
3404 mcs
|= RT2860_TXWI_MCS_SHOTPRE
;
3408 txwi
.phymode_ifs_stbc_shortgi
=
3409 (RT2860_TXWI_PHYMODE_OFDM
<< RT2860_TXWI_PHYMODE_SHIFT
);
3412 txwi
.bw_mcs
= (RT2860_TXWI_BW_20
<< RT2860_TXWI_BW_SHIFT
) |
3413 ((mcs
& RT2860_TXWI_MCS_MASK
) << RT2860_TXWI_MCS_SHIFT
);
3415 if (sc
->beacon_mbuf
!= NULL
)
3417 m_free(sc
->beacon_mbuf
);
3418 sc
->beacon_mbuf
= NULL
;
3421 sc
->beacon_mbuf
= m
;
3422 sc
->beacon_txwi
= txwi
;
3430 static uint8_t rt2860_rxrate(struct rt2860_rxwi
*rxwi
)
3432 uint8_t mcs
, phymode
;
3435 mcs
= (rxwi
->bw_mcs
>> RT2860_RXWI_MCS_SHIFT
) & RT2860_RXWI_MCS_MASK
;
3436 phymode
= (rxwi
->phymode_stbc_shortgi
>> RT2860_RXWI_PHYMODE_SHIFT
) &
3437 RT2860_RXWI_PHYMODE_MASK
;
3443 case RT2860_RXWI_PHYMODE_CCK
:
3444 switch (mcs
& ~RT2860_RXWI_MCS_SHOTPRE
)
3446 case 0: rate
= 2; break; /* 1 Mbps */
3447 case 1: rate
= 4; break; /* 2 MBps */
3448 case 2: rate
= 11; break; /* 5.5 Mbps */
3449 case 3: rate
= 22; break; /* 11 Mbps */
3453 case RT2860_RXWI_PHYMODE_OFDM
:
3456 case 0: rate
= 12; break; /* 6 Mbps */
3457 case 1: rate
= 18; break; /* 9 Mbps */
3458 case 2: rate
= 24; break; /* 12 Mbps */
3459 case 3: rate
= 36; break; /* 18 Mbps */
3460 case 4: rate
= 48; break; /* 24 Mbps */
3461 case 5: rate
= 72; break; /* 36 Mbps */
3462 case 6: rate
= 96; break; /* 48 Mbps */
3463 case 7: rate
= 108; break; /* 54 Mbps */
3467 case RT2860_RXWI_PHYMODE_HT_MIXED
:
3468 case RT2860_RXWI_PHYMODE_HT_GF
:
3476 * rt2860_maxrssi_rxpath
3478 static uint8_t rt2860_maxrssi_rxpath(struct rt2860_softc
*sc
,
3479 const struct rt2860_rxwi
*rxwi
)
3485 if (sc
->nrxpath
> 1)
3486 if (rxwi
->rssi
[1] > rxwi
->rssi
[rxpath
])
3489 if (sc
->nrxpath
> 2)
3490 if (rxwi
->rssi
[2] > rxwi
->rssi
[rxpath
])
3499 static int8_t rt2860_rssi2dbm(struct rt2860_softc
*sc
,
3500 uint8_t rssi
, uint8_t rxpath
)
3502 struct ieee80211com
*ic
;
3503 struct ieee80211_channel
*c
;
3505 int8_t rssi_off
, lna_gain
;
3512 chan
= ieee80211_chan2ieee(ic
, c
);
3514 if (IEEE80211_IS_CHAN_5GHZ(c
))
3516 rssi_off
= sc
->rssi_off_5ghz
[rxpath
];
3519 lna_gain
= sc
->lna_gain
[1];
3520 else if (chan
<= 128)
3521 lna_gain
= sc
->lna_gain
[2];
3523 lna_gain
= sc
->lna_gain
[3];
3527 rssi_off
= sc
->rssi_off_2ghz
[rxpath
];
3528 lna_gain
= sc
->lna_gain
[0];
3531 return (-12 - rssi_off
- lna_gain
- rssi
);
3537 static uint8_t rt2860_rate2mcs(uint8_t rate
)
3564 static int rt2860_ackrate(struct ieee80211com
*ic
, int rate
)
3576 return (ic
->ic_curmode
== IEEE80211_MODE_11B
) ? 4 : rate
;
3595 /* default to 1Mbps */
3602 static uint16_t rt2860_txtime(int len
, int rate
, uint32_t flags
)
3606 if (RT2860_RATE_IS_OFDM(rate
))
3608 txtime
= (8 + 4 * len
+ 3 + rate
- 1) / rate
;
3609 txtime
= 16 + 4 + 4 * txtime
+ 6;
3613 txtime
= (16 * len
+ rate
- 1) / rate
;
3615 if (rate
!= 2 && (flags
& IEEE80211_F_SHPREAMBLE
))
3627 static int rt2860_tx_frame(struct rt2860_softc
*sc
,
3628 struct mbuf
*m
, struct ieee80211_node
*ni
, int qid
)
3630 struct ieee80211com
*ic
;
3631 struct rt2860_softc_tx_ring
*ring
;
3632 struct rt2860_softc_tx_data
*data
;
3633 struct rt2860_txdesc
*desc
;
3634 struct rt2860_txwi
*txwi
;
3635 struct ieee80211_frame
*wh
;
3636 struct ieee80211_tx_ampdu
*tx_ampdu
;
3637 struct rt2860_softc_tx_radiotap_header
*tap
;
3638 bus_dma_segment_t dma_seg
[RT2860_SOFTC_MAX_SCATTER
];
3639 u_int hdrsize
, hdrspace
;
3640 uint8_t type
, rate
, bw
, stbc
, shortgi
, mcs
, pid
, wcid
, mpdu_density
, bawin_size
, qsel
;
3641 uint16_t qos
, len
, dmalen
, mpdu_len
, dur
;
3642 int error
, hasqos
, ac
, ampdu
, mimops
, ackrate
, ndmasegs
, ndescs
, i
, j
;
3644 KASSERT(qid
>= 0 && qid
< RT2860_SOFTC_TX_RING_COUNT
,
3645 ("%s: Tx frame: invalid qid=%d\n",
3646 device_get_nameunit(sc
->dev
), qid
));
3650 ring
= &sc
->tx_ring
[qid
];
3651 desc
= &ring
->desc
[ring
->desc_cur
];
3652 data
= &ring
->data
[ring
->data_cur
];
3653 txwi
= (struct rt2860_txwi
*) (ring
->seg0
+ ring
->data_cur
* RT2860_TX_DATA_SEG0_SIZE
);
3655 wh
= mtod(m
, struct ieee80211_frame
*);
3657 type
= wh
->i_fc
[0] & IEEE80211_FC0_TYPE_MASK
;
3659 hasqos
= IEEE80211_QOS_HAS_SEQ(wh
);
3662 if (IEEE80211_HAS_ADDR4(wh
))
3663 qos
= le16toh(*(const uint16_t *)
3664 (((struct ieee80211_qosframe_addr4
*) wh
)->i_qos
));
3666 qos
= le16toh(*(const uint16_t *)
3667 (((struct ieee80211_qosframe
*) wh
)->i_qos
));
3674 if (ni
->ni_flags
& IEEE80211_NODE_HT
)
3676 if (IEEE80211_IS_MULTICAST(wh
->i_addr1
) || type
!= IEEE80211_FC0_TYPE_DATA
)
3678 else if (ic
->ic_fixed_rate
!= IEEE80211_FIXED_RATE_NONE
)
3679 rate
= ic
->ic_fixed_rate
;
3681 rate
= ni
->ni_htrates
.rs_rates
[ni
->ni_txrate
];
3685 if (IEEE80211_IS_MULTICAST(wh
->i_addr1
) || type
!= IEEE80211_FC0_TYPE_DATA
)
3686 rate
= IEEE80211_IS_CHAN_5GHZ(ic
->ic_curchan
) ? 12 : 2;
3687 else if (ic
->ic_fixed_rate
!= IEEE80211_FIXED_RATE_NONE
)
3688 rate
= ic
->ic_fixed_rate
;
3690 rate
= ni
->ni_rates
.rs_rates
[ni
->ni_txrate
];
3693 rate
&= IEEE80211_RATE_VAL
;
3695 /* fill Tx wireless info */
3697 if (ni
->ni_flags
& IEEE80211_NODE_HT
)
3700 mcs
= rt2860_rate2mcs(rate
);
3702 /* management frames do not need encryption */
3704 if (type
== IEEE80211_FC0_TYPE_DATA
)
3705 wcid
= !IEEE80211_IS_MULTICAST(wh
->i_addr1
) ? RT2860_AID2WCID(ni
->ni_associd
) : RT2860_WCID_MCAST
;
3707 wcid
= RT2860_WCID_RESERVED
;
3709 /* calculate MPDU length without padding */
3711 hdrsize
= ieee80211_hdrsize(wh
);
3712 hdrspace
= ieee80211_hdrspace(ic
, wh
);
3713 mpdu_len
= m
->m_pkthdr
.len
- hdrspace
+ hdrsize
;
3715 memset(txwi
, 0, sizeof(struct rt2860_txwi
));
3719 /* MIMO power save */
3721 if ((ni
->ni_flags
& IEEE80211_NODE_HT
) &&
3722 ((ni
->ni_htcap
& IEEE80211_HTCAP_SMPS
) != IEEE80211_HTCAP_SMPS_OFF
))
3726 if ((ni
->ni_htcap
& IEEE80211_HTCAP_SMPS
) == IEEE80211_HTCAP_SMPS_DYNAMIC
)
3728 /* dynamic MIMO power save */
3730 txwi
->mpdu_density_flags
|=
3731 (RT2860_TXWI_FLAGS_MIMOPS
<< RT2860_TXWI_FLAGS_SHIFT
);
3735 /* static MIMO power save */
3750 txwi
->pid_mpdu_len
= ((htole16(pid
) & RT2860_TXWI_PID_MASK
) <<
3751 RT2860_TXWI_PID_SHIFT
) | ((htole16(mpdu_len
) & RT2860_TXWI_MPDU_LEN_MASK
) <<
3752 RT2860_TXWI_MPDU_LEN_SHIFT
);
3754 stbc
= (ic
->ic_htcaps
& IEEE80211_HTCAP_TXSTBC
) &&
3755 (ni
->ni_flags
& IEEE80211_NODE_HT
) && (ni
->ni_htcap
& IEEE80211_HTCAP_RXSTBC
);
3757 shortgi
= (ic
->ic_flags_ext
& (IEEE80211_FEXT_SHORTGI20
| IEEE80211_FEXT_SHORTGI40
)) &&
3758 (ni
->ni_flags
& IEEE80211_NODE_HT
) && (ni
->ni_htcap
& (IEEE80211_HTCAP_SHORTGI20
| IEEE80211_HTCAP_SHORTGI40
));
3760 txwi
->phymode_ifs_stbc_shortgi
|=
3761 ((stbc
& RT2860_TXWI_STBC_MASK
) << RT2860_TXWI_STBC_SHIFT
) |
3762 ((shortgi
& RT2860_TXWI_SHORTGI_MASK
) << RT2860_TXWI_SHORTGI_SHIFT
);
3764 if (ni
->ni_flags
& IEEE80211_NODE_HT
)
3766 txwi
->phymode_ifs_stbc_shortgi
|=
3767 (RT2860_TXWI_PHYMODE_HT_MIXED
<< RT2860_TXWI_PHYMODE_SHIFT
);
3771 if (!RT2860_RATE_IS_OFDM(rate
))
3773 txwi
->phymode_ifs_stbc_shortgi
|=
3774 (RT2860_TXWI_PHYMODE_CCK
<< RT2860_TXWI_PHYMODE_SHIFT
);
3776 if (rate
!= 2 && (ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
))
3777 mcs
|= RT2860_TXWI_MCS_SHOTPRE
;
3781 txwi
->phymode_ifs_stbc_shortgi
|=
3782 (RT2860_TXWI_PHYMODE_OFDM
<< RT2860_TXWI_PHYMODE_SHIFT
);
3786 if ((ni
->ni_flags
& IEEE80211_NODE_HT
) && (ni
->ni_chw
== 40))
3787 bw
= RT2860_TXWI_BW_40
;
3789 bw
= RT2860_TXWI_BW_20
;
3791 txwi
->bw_mcs
= ((bw
& RT2860_TXWI_BW_MASK
) << RT2860_TXWI_BW_SHIFT
) |
3792 ((mcs
& RT2860_TXWI_MCS_MASK
) << RT2860_TXWI_MCS_SHIFT
);
3794 if (type
!= IEEE80211_FC0_TYPE_DATA
)
3795 txwi
->txop
= (RT2860_TXWI_TXOP_BACKOFF
<< RT2860_TXWI_TXOP_SHIFT
);
3797 txwi
->txop
= (RT2860_TXWI_TXOP_HT
<< RT2860_TXWI_TXOP_SHIFT
);
3799 /* skip ACKs for multicast frames */
3801 if (!IEEE80211_IS_MULTICAST(wh
->i_addr1
) &&
3802 (!hasqos
|| (qos
& IEEE80211_QOS_ACKPOLICY
) != IEEE80211_QOS_ACKPOLICY_NOACK
))
3804 txwi
->bawin_size_xflags
|=
3805 (RT2860_TXWI_XFLAGS_ACK
<< RT2860_TXWI_XFLAGS_SHIFT
);
3807 if (ni
->ni_flags
& IEEE80211_NODE_HT
)
3809 /* preamble + plcp + signal extension + SIFS */
3811 dur
= 16 + 4 + 6 + 10;
3815 ackrate
= rt2860_ackrate(ic
, rate
);
3817 dur
= rt2860_txtime(RT2860_ACK_SIZE
, ackrate
, ic
->ic_flags
) +
3821 *(uint16_t *) wh
->i_dur
= htole16(dur
);
3824 /* check for A-MPDU */
3826 if ((qos
& IEEE80211_QOS_ACKPOLICY
) == IEEE80211_QOS_ACKPOLICY_BA
)
3828 ac
= M_WME_GETAC(m
);
3829 tx_ampdu
= &ni
->ni_tx_ampdu
[ac
];
3831 mpdu_density
= RT2860_MS(ni
->ni_htparam
, IEEE80211_HTCAP_MPDUDENSITY
);
3832 bawin_size
= tx_ampdu
->txa_wnd
;
3834 txwi
->mpdu_density_flags
|=
3835 ((mpdu_density
& RT2860_TXWI_MPDU_DENSITY_MASK
) << RT2860_TXWI_MPDU_DENSITY_SHIFT
) |
3836 (RT2860_TXWI_FLAGS_AMPDU
<< RT2860_TXWI_FLAGS_SHIFT
);
3838 txwi
->bawin_size_xflags
|=
3839 ((bawin_size
& RT2860_TXWI_BAWIN_SIZE_MASK
) << RT2860_TXWI_BAWIN_SIZE_SHIFT
);
3841 if (IEEE80211_HAS_ADDR4(wh
))
3842 ((struct ieee80211_qosframe_addr4
*) wh
)->i_qos
[0] &= ~IEEE80211_QOS_ACKPOLICY
;
3844 ((struct ieee80211_qosframe
*) wh
)->i_qos
[0] &= ~IEEE80211_QOS_ACKPOLICY
;
3853 /* ask MAC to insert timestamp into probe responses */
3855 if ((wh
->i_fc
[0] & (IEEE80211_FC0_TYPE_MASK
| IEEE80211_FC0_SUBTYPE_MASK
)) ==
3856 (IEEE80211_FC0_TYPE_MGT
| IEEE80211_FC0_SUBTYPE_PROBE_RESP
))
3857 txwi
->mpdu_density_flags
|=
3858 (RT2860_TXWI_FLAGS_TS
<< RT2860_TXWI_FLAGS_SHIFT
);
3860 if (bpf_peers_present(sc
->drvbpf
))
3864 tap
->flags
= IEEE80211_RADIOTAP_F_DATAPAD
;
3865 tap
->chan_flags
= htole32(ic
->ic_curchan
->ic_flags
);
3866 tap
->chan_freq
= htole16(ic
->ic_curchan
->ic_freq
);
3867 tap
->chan_ieee
= ic
->ic_curchan
->ic_ieee
;
3868 tap
->chan_maxpow
= 0;
3870 if (ni
->ni_flags
& IEEE80211_NODE_HT
)
3871 tap
->rate
= mcs
| IEEE80211_RATE_MCS
;
3875 if (mcs
& RT2860_TXWI_MCS_SHOTPRE
)
3876 tap
->flags
|= IEEE80211_RADIOTAP_F_SHORTPRE
;
3879 tap
->flags
|= IEEE80211_RADIOTAP_F_SHORTGI
;
3881 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
)
3882 tap
->flags
|= IEEE80211_RADIOTAP_F_WEP
;
3884 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
)
3886 wh
->i_fc
[1] &= ~IEEE80211_FC1_WEP
;
3888 bpf_mtap2(sc
->drvbpf
, tap
, sc
->txtap_len
, m
);
3890 wh
->i_fc
[1] |= IEEE80211_FC1_WEP
;
3894 bpf_mtap2(sc
->drvbpf
, tap
, sc
->txtap_len
, m
);
3898 /* copy and trim 802.11 header */
3900 m_copydata(m
, 0, hdrsize
, (caddr_t
) (txwi
+ 1));
3903 error
= bus_dmamap_load_mbuf_sg(ring
->data_dma_tag
, data
->dma_map
, m
,
3904 dma_seg
, &ndmasegs
, 0);
3907 /* too many fragments, linearize */
3909 RT2860_DPRINTF(sc
, RT2860_DEBUG_TX
,
3910 "%s: could not load mbuf DMA map, trying to linearize mbuf\n",
3911 device_get_nameunit(sc
->dev
));
3913 m
= m_defrag(m
, M_DONTWAIT
);
3917 sc
->tx_defrag_packets
++;
3919 error
= bus_dmamap_load_mbuf_sg(ring
->data_dma_tag
, data
->dma_map
, m
,
3920 dma_seg
, &ndmasegs
, 0);
3923 printf("%s: could not load mbuf DMA map: error=%d\n",
3924 device_get_nameunit(sc
->dev
), error
);
3930 if (m
->m_pkthdr
.len
== 0)
3933 /* determine how many Tx descs are required */
3935 ndescs
= 1 + ndmasegs
/ 2;
3936 if ((ring
->desc_queued
+ ndescs
) > (RT2860_SOFTC_TX_RING_DESC_COUNT
- 2))
3938 RT2860_DPRINTF(sc
, RT2860_DEBUG_TX
,
3939 "%s: there are not enough Tx descs\n",
3940 device_get_nameunit(sc
->dev
));
3942 sc
->no_tx_desc_avail
++;
3944 bus_dmamap_unload(ring
->data_dma_tag
, data
->dma_map
);
3952 /* set up Tx descs */
3954 /* first segment is Tx wireless info and 802.11 header */
3956 len
= sizeof(struct rt2860_txwi
) + hdrsize
;
3958 /* align end on a 4-bytes boundary */
3960 dmalen
= (len
+ 3) & ~ 3;
3962 memset((caddr_t
) txwi
+ len
, 0, dmalen
- len
);
3964 qsel
= RT2860_TXDESC_QSEL_EDCA
;
3966 desc
->sdp0
= htole32(ring
->seg0_phys_addr
+ ring
->data_cur
* RT2860_TX_DATA_SEG0_SIZE
);
3967 desc
->sdl0
= htole16(dmalen
);
3968 desc
->qsel_flags
= (qsel
<< RT2860_TXDESC_QSEL_SHIFT
);
3970 /* set up payload segments */
3972 for (i
= ndmasegs
, j
= 0; i
>= 2; i
-= 2)
3974 desc
->sdp1
= htole32(dma_seg
[j
].ds_addr
);
3975 desc
->sdl1
= htole16(dma_seg
[j
].ds_len
);
3977 ring
->desc_queued
++;
3978 ring
->desc_cur
= (ring
->desc_cur
+ 1) % RT2860_SOFTC_TX_RING_DESC_COUNT
;
3982 desc
= &ring
->desc
[ring
->desc_cur
];
3984 desc
->sdp0
= htole32(dma_seg
[j
].ds_addr
);
3985 desc
->sdl0
= htole16(dma_seg
[j
].ds_len
);
3986 desc
->qsel_flags
= (qsel
<< RT2860_TXDESC_QSEL_SHIFT
);
3991 /* finalize last payload segment */
3995 desc
->sdp1
= htole32(dma_seg
[j
].ds_addr
);
3996 desc
->sdl1
= htole16(dma_seg
[j
].ds_len
| RT2860_TXDESC_SDL1_LASTSEG
);
4000 desc
->sdl0
|= htole16(RT2860_TXDESC_SDL0_LASTSEG
);
4004 RT2860_DPRINTF(sc
, RT2860_DEBUG_TX
,
4005 "%s: sending frame: qid=%d, hdrsize=%d, hdrspace=%d, len=%d, "
4006 "bw=%d, stbc=%d, shortgi=%d, mcs=%d, wcid=0x%02x, ampdu=%d, mimops=%d, DMA len=%d, ndmasegs=%d, DMA ds_len=%d/%d/%d/%d/%d\n",
4007 device_get_nameunit(sc
->dev
),
4008 qid
, hdrsize
, hdrspace
, m
->m_pkthdr
.len
+ hdrsize
,
4009 bw
, stbc
, shortgi
, mcs
, wcid
, ampdu
, mimops
, dmalen
, ndmasegs
,
4010 dma_seg
[0].ds_len
, dma_seg
[1].ds_len
, dma_seg
[2].ds_len
, dma_seg
[3].ds_len
, dma_seg
[4].ds_len
);
4012 bus_dmamap_sync(ring
->seg0_dma_tag
, ring
->seg0_dma_map
,
4013 BUS_DMASYNC_PREWRITE
);
4014 bus_dmamap_sync(ring
->data_dma_tag
, data
->dma_map
,
4015 BUS_DMASYNC_PREWRITE
);
4016 bus_dmamap_sync(ring
->desc_dma_tag
, ring
->desc_dma_map
,
4017 BUS_DMASYNC_PREWRITE
);
4019 ring
->desc_queued
++;
4020 ring
->desc_cur
= (ring
->desc_cur
+ 1) % RT2860_SOFTC_TX_RING_DESC_COUNT
;
4022 ring
->data_queued
++;
4023 ring
->data_cur
= (ring
->data_cur
+ 1) % RT2860_SOFTC_TX_RING_DATA_COUNT
;
4027 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_TX_CTX_IDX(qid
), ring
->desc_cur
);
4035 static int rt2860_tx_raw(struct rt2860_softc
*sc
,
4036 struct mbuf
*m
, struct ieee80211_node
*ni
,
4037 const struct ieee80211_bpf_params
*params
)
4039 RT2860_DPRINTF(sc
, RT2860_DEBUG_TX
,
4041 device_get_nameunit(sc
->dev
));
4049 static void rt2860_intr(void *arg
)
4051 struct rt2860_softc
*sc
;
4058 /* acknowledge interrupts */
4060 status
= rt2860_io_mac_read(sc
, RT2860_REG_SCHDMA_INT_STATUS
);
4061 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_INT_STATUS
, status
);
4063 RT2860_DPRINTF(sc
, RT2860_DEBUG_INTR
,
4064 "%s: interrupt: status = 0x%08x\n",
4065 device_get_nameunit(sc
->dev
), status
);
4067 if (status
== 0xffffffff || /* device likely went away */
4068 status
== 0) /* not for us */
4073 if (!(ifp
->if_drv_flags
& IFF_DRV_RUNNING
))
4076 if (status
& RT2860_REG_INT_TX_COHERENT
)
4077 rt2860_tx_coherent_intr(sc
);
4079 if (status
& RT2860_REG_INT_RX_COHERENT
)
4080 rt2860_rx_coherent_intr(sc
);
4082 if (status
& RT2860_REG_INT_TXRX_COHERENT
)
4083 rt2860_txrx_coherent_intr(sc
);
4085 if (status
& RT2860_REG_INT_FIFO_STA_FULL
)
4086 rt2860_fifo_sta_full_intr(sc
);
4088 if (status
& RT2860_REG_INT_TX_MGMT_DONE
)
4089 rt2860_tx_intr(sc
, 5);
4091 if (status
& RT2860_REG_INT_RX_DONE
)
4094 if (status
& RT2860_REG_INT_RX_DELAY_DONE
)
4095 rt2860_rx_delay_intr(sc
);
4097 if (status
& RT2860_REG_INT_TX_HCCA_DONE
)
4098 rt2860_tx_intr(sc
, 4);
4100 if (status
& RT2860_REG_INT_TX_AC3_DONE
)
4101 rt2860_tx_intr(sc
, 3);
4103 if (status
& RT2860_REG_INT_TX_AC2_DONE
)
4104 rt2860_tx_intr(sc
, 2);
4106 if (status
& RT2860_REG_INT_TX_AC1_DONE
)
4107 rt2860_tx_intr(sc
, 1);
4109 if (status
& RT2860_REG_INT_TX_AC0_DONE
)
4110 rt2860_tx_intr(sc
, 0);
4112 if (status
& RT2860_REG_INT_TX_DELAY_DONE
)
4113 rt2860_tx_delay_intr(sc
);
4115 if (status
& RT2860_REG_INT_PRE_TBTT
)
4116 rt2860_pre_tbtt_intr(sc
);
4118 if (status
& RT2860_REG_INT_TBTT
)
4119 rt2860_tbtt_intr(sc
);
4121 if (status
& RT2860_REG_INT_MCU_CMD
)
4122 rt2860_mcu_cmd_intr(sc
);
4124 if (status
& RT2860_REG_INT_AUTO_WAKEUP
)
4125 rt2860_auto_wakeup_intr(sc
);
4127 if (status
& RT2860_REG_INT_GP_TIMER
)
4128 rt2860_gp_timer_intr(sc
);
4132 * rt2860_tx_coherent_intr
4134 static void rt2860_tx_coherent_intr(struct rt2860_softc
*sc
)
4139 RT2860_DPRINTF(sc
, RT2860_DEBUG_INTR
,
4140 "%s: Tx coherent interrupt\n",
4141 device_get_nameunit(sc
->dev
));
4143 sc
->tx_coherent_interrupts
++;
4145 /* restart DMA engine */
4147 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_SCHDMA_WPDMA_GLO_CFG
);
4149 tmp
&= ~(RT2860_REG_TX_WB_DDONE
|
4150 RT2860_REG_RX_DMA_ENABLE
|
4151 RT2860_REG_TX_DMA_ENABLE
);
4153 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_WPDMA_GLO_CFG
, tmp
);
4155 /* init Tx rings (4 EDCAs + HCCA + MGMT) */
4157 for (i
= 0; i
< RT2860_SOFTC_TX_RING_COUNT
; i
++)
4158 rt2860_reset_tx_ring(sc
, &sc
->tx_ring
[i
]);
4160 for (i
= 0; i
< RT2860_SOFTC_TX_RING_COUNT
; i
++)
4162 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_TX_BASE_PTR(i
),
4163 sc
->tx_ring
[i
].desc_phys_addr
);
4164 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_TX_MAX_CNT(i
),
4165 RT2860_SOFTC_TX_RING_DESC_COUNT
);
4166 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_TX_CTX_IDX(i
), 0);
4171 rt2860_reset_rx_ring(sc
, &sc
->rx_ring
);
4173 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_RX_BASE_PTR
,
4174 sc
->rx_ring
.desc_phys_addr
);
4175 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_RX_MAX_CNT
,
4176 RT2860_SOFTC_RX_RING_DATA_COUNT
);
4177 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_RX_CALC_IDX
,
4178 RT2860_SOFTC_RX_RING_DATA_COUNT
- 1);
4180 rt2860_txrx_enable(sc
);
4184 * rt2860_rx_coherent_intr
4186 static void rt2860_rx_coherent_intr(struct rt2860_softc
*sc
)
4191 RT2860_DPRINTF(sc
, RT2860_DEBUG_INTR
,
4192 "%s: Rx coherent interrupt\n",
4193 device_get_nameunit(sc
->dev
));
4195 sc
->rx_coherent_interrupts
++;
4197 /* restart DMA engine */
4199 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_SCHDMA_WPDMA_GLO_CFG
);
4201 tmp
&= ~(RT2860_REG_TX_WB_DDONE
|
4202 RT2860_REG_RX_DMA_ENABLE
|
4203 RT2860_REG_TX_DMA_ENABLE
);
4205 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_WPDMA_GLO_CFG
, tmp
);
4207 /* init Tx rings (4 EDCAs + HCCA + MGMT) */
4209 for (i
= 0; i
< RT2860_SOFTC_TX_RING_COUNT
; i
++)
4210 rt2860_reset_tx_ring(sc
, &sc
->tx_ring
[i
]);
4212 for (i
= 0; i
< RT2860_SOFTC_TX_RING_COUNT
; i
++)
4214 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_TX_BASE_PTR(i
),
4215 sc
->tx_ring
[i
].desc_phys_addr
);
4216 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_TX_MAX_CNT(i
),
4217 RT2860_SOFTC_TX_RING_DESC_COUNT
);
4218 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_TX_CTX_IDX(i
), 0);
4223 rt2860_reset_rx_ring(sc
, &sc
->rx_ring
);
4225 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_RX_BASE_PTR
,
4226 sc
->rx_ring
.desc_phys_addr
);
4227 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_RX_MAX_CNT
,
4228 RT2860_SOFTC_RX_RING_DATA_COUNT
);
4229 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_RX_CALC_IDX
,
4230 RT2860_SOFTC_RX_RING_DATA_COUNT
- 1);
4232 rt2860_txrx_enable(sc
);
4236 * rt2860_txrx_coherent_intr
4238 static void rt2860_txrx_coherent_intr(struct rt2860_softc
*sc
)
4243 RT2860_DPRINTF(sc
, RT2860_DEBUG_INTR
,
4244 "%s: Tx/Rx coherent interrupt\n",
4245 device_get_nameunit(sc
->dev
));
4247 sc
->txrx_coherent_interrupts
++;
4249 /* restart DMA engine */
4251 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_SCHDMA_WPDMA_GLO_CFG
);
4253 tmp
&= ~(RT2860_REG_TX_WB_DDONE
|
4254 RT2860_REG_RX_DMA_ENABLE
|
4255 RT2860_REG_TX_DMA_ENABLE
);
4257 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_WPDMA_GLO_CFG
, tmp
);
4259 /* init Tx rings (4 EDCAs + HCCA + MGMT) */
4261 for (i
= 0; i
< RT2860_SOFTC_TX_RING_COUNT
; i
++)
4262 rt2860_reset_tx_ring(sc
, &sc
->tx_ring
[i
]);
4264 for (i
= 0; i
< RT2860_SOFTC_TX_RING_COUNT
; i
++)
4266 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_TX_BASE_PTR(i
),
4267 sc
->tx_ring
[i
].desc_phys_addr
);
4268 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_TX_MAX_CNT(i
),
4269 RT2860_SOFTC_TX_RING_DESC_COUNT
);
4270 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_TX_CTX_IDX(i
), 0);
4275 rt2860_reset_rx_ring(sc
, &sc
->rx_ring
);
4277 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_RX_BASE_PTR
,
4278 sc
->rx_ring
.desc_phys_addr
);
4279 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_RX_MAX_CNT
,
4280 RT2860_SOFTC_RX_RING_DATA_COUNT
);
4281 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_RX_CALC_IDX
,
4282 RT2860_SOFTC_RX_RING_DATA_COUNT
- 1);
4284 rt2860_txrx_enable(sc
);
4288 * rt2860_fifo_sta_full_intr
4290 static void rt2860_fifo_sta_full_intr(struct rt2860_softc
*sc
)
4292 RT2860_DPRINTF(sc
, RT2860_DEBUG_INTR
,
4293 "%s: FIFO statistic full interrupt\n",
4294 device_get_nameunit(sc
->dev
));
4296 sc
->fifo_sta_full_interrupts
++;
4298 RT2860_SOFTC_LOCK(sc
);
4300 if (!(sc
->intr_disable_mask
& RT2860_REG_INT_FIFO_STA_FULL
))
4302 rt2860_intr_disable(sc
, RT2860_REG_INT_FIFO_STA_FULL
);
4304 taskqueue_enqueue(sc
->taskqueue
, &sc
->fifo_sta_full_task
);
4307 sc
->intr_pending_mask
|= RT2860_REG_INT_FIFO_STA_FULL
;
4309 RT2860_SOFTC_UNLOCK(sc
);
4315 static void rt2860_rx_intr(struct rt2860_softc
*sc
)
4317 RT2860_DPRINTF(sc
, RT2860_DEBUG_INTR
,
4318 "%s: Rx interrupt\n",
4319 device_get_nameunit(sc
->dev
));
4321 sc
->rx_interrupts
++;
4323 RT2860_SOFTC_LOCK(sc
);
4325 if (!(sc
->intr_disable_mask
& RT2860_REG_INT_RX_DONE
))
4327 rt2860_intr_disable(sc
, RT2860_REG_INT_RX_DONE
);
4329 taskqueue_enqueue(sc
->taskqueue
, &sc
->rx_done_task
);
4332 sc
->intr_pending_mask
|= RT2860_REG_INT_RX_DONE
;
4334 RT2860_SOFTC_UNLOCK(sc
);
4338 * rt2860_rx_delay_intr
4340 static void rt2860_rx_delay_intr(struct rt2860_softc
*sc
)
4342 RT2860_DPRINTF(sc
, RT2860_DEBUG_INTR
,
4343 "%s: Rx delay interrupt\n",
4344 device_get_nameunit(sc
->dev
));
4346 sc
->rx_delay_interrupts
++;
4352 static void rt2860_tx_intr(struct rt2860_softc
*sc
, int qid
)
4354 KASSERT(qid
>= 0 && qid
< RT2860_SOFTC_TX_RING_COUNT
,
4355 ("%s: Tx interrupt: invalid qid=%d\n",
4356 device_get_nameunit(sc
->dev
), qid
));
4358 RT2860_DPRINTF(sc
, RT2860_DEBUG_INTR
,
4359 "%s: Tx interrupt: qid=%d\n",
4360 device_get_nameunit(sc
->dev
), qid
);
4362 sc
->tx_interrupts
[qid
]++;
4364 RT2860_SOFTC_LOCK(sc
);
4366 if (!(sc
->intr_disable_mask
& (RT2860_REG_INT_TX_AC0_DONE
<< qid
)))
4368 rt2860_intr_disable(sc
, (RT2860_REG_INT_TX_AC0_DONE
<< qid
));
4370 taskqueue_enqueue(sc
->taskqueue
, &sc
->tx_done_task
);
4373 sc
->intr_pending_mask
|= (RT2860_REG_INT_TX_AC0_DONE
<< qid
);
4375 RT2860_SOFTC_UNLOCK(sc
);
4379 * rt2860_tx_delay_intr
4381 static void rt2860_tx_delay_intr(struct rt2860_softc
*sc
)
4383 RT2860_DPRINTF(sc
, RT2860_DEBUG_INTR
,
4384 "%s: Tx delay interrupt\n",
4385 device_get_nameunit(sc
->dev
));
4387 sc
->tx_delay_interrupts
++;
4391 * rt2860_pre_tbtt_intr
4393 static void rt2860_pre_tbtt_intr(struct rt2860_softc
*sc
)
4395 RT2860_DPRINTF(sc
, RT2860_DEBUG_INTR
,
4396 "%s: Pre-TBTT interrupt\n",
4397 device_get_nameunit(sc
->dev
));
4399 sc
->pre_tbtt_interrupts
++;
4405 static void rt2860_tbtt_intr(struct rt2860_softc
*sc
)
4407 RT2860_DPRINTF(sc
, RT2860_DEBUG_INTR
,
4408 "%s: TBTT interrupt\n",
4409 device_get_nameunit(sc
->dev
));
4411 sc
->tbtt_interrupts
++;
4415 * rt2860_mcu_cmd_intr
4417 static void rt2860_mcu_cmd_intr(struct rt2860_softc
*sc
)
4419 RT2860_DPRINTF(sc
, RT2860_DEBUG_INTR
,
4420 "%s: MCU command interrupt\n",
4421 device_get_nameunit(sc
->dev
));
4423 sc
->mcu_cmd_interrupts
++;
4427 * rt2860_auto_wakeup_intr
4429 static void rt2860_auto_wakeup_intr(struct rt2860_softc
*sc
)
4431 RT2860_DPRINTF(sc
, RT2860_DEBUG_INTR
,
4432 "%s: auto wakeup interrupt\n",
4433 device_get_nameunit(sc
->dev
));
4435 sc
->auto_wakeup_interrupts
++;
4439 * rt2860_gp_timer_intr
4441 static void rt2860_gp_timer_intr(struct rt2860_softc
*sc
)
4443 RT2860_DPRINTF(sc
, RT2860_DEBUG_INTR
,
4444 "%s: GP timer interrupt\n",
4445 device_get_nameunit(sc
->dev
));
4447 sc
->gp_timer_interrupts
++;
4451 * rt2860_rx_done_task
4453 static void rt2860_rx_done_task(void *context
, int pending
)
4455 struct rt2860_softc
*sc
;
4462 RT2860_DPRINTF(sc
, RT2860_DEBUG_RX
,
4463 "%s: Rx done task\n",
4464 device_get_nameunit(sc
->dev
));
4466 if (!(ifp
->if_drv_flags
& IFF_DRV_RUNNING
))
4469 sc
->intr_pending_mask
&= ~RT2860_REG_INT_RX_DONE
;
4471 again
= rt2860_rx_eof(sc
, sc
->rx_process_limit
);
4473 RT2860_SOFTC_LOCK(sc
);
4475 if ((sc
->intr_pending_mask
& RT2860_REG_INT_RX_DONE
) || again
)
4477 RT2860_DPRINTF(sc
, RT2860_DEBUG_RX
,
4478 "%s: Rx done task: scheduling again\n",
4479 device_get_nameunit(sc
->dev
));
4481 taskqueue_enqueue(sc
->taskqueue
, &sc
->rx_done_task
);
4485 rt2860_intr_enable(sc
, RT2860_REG_INT_RX_DONE
);
4488 RT2860_SOFTC_UNLOCK(sc
);
4492 * rt2860_tx_done_task
4494 static void rt2860_tx_done_task(void *context
, int pending
)
4496 struct rt2860_softc
*sc
;
4504 RT2860_DPRINTF(sc
, RT2860_DEBUG_TX
,
4505 "%s: Tx done task\n",
4506 device_get_nameunit(sc
->dev
));
4508 if (!(ifp
->if_drv_flags
& IFF_DRV_RUNNING
))
4511 for (i
= RT2860_SOFTC_TX_RING_COUNT
- 1; i
>= 0; i
--)
4513 if (sc
->intr_pending_mask
& (RT2860_REG_INT_TX_AC0_DONE
<< i
))
4515 sc
->intr_pending_mask
&= ~(RT2860_REG_INT_TX_AC0_DONE
<< i
);
4517 rt2860_tx_eof(sc
, &sc
->tx_ring
[i
]);
4523 ifp
->if_drv_flags
&= ~IFF_DRV_OACTIVE
;
4525 intr_mask
= (RT2860_REG_INT_TX_MGMT_DONE
|
4526 RT2860_REG_INT_TX_HCCA_DONE
|
4527 RT2860_REG_INT_TX_AC3_DONE
|
4528 RT2860_REG_INT_TX_AC2_DONE
|
4529 RT2860_REG_INT_TX_AC1_DONE
|
4530 RT2860_REG_INT_TX_AC0_DONE
);
4532 RT2860_SOFTC_LOCK(sc
);
4534 rt2860_intr_enable(sc
, ~sc
->intr_pending_mask
&
4535 (sc
->intr_disable_mask
& intr_mask
));
4537 if (sc
->intr_pending_mask
& intr_mask
)
4539 RT2860_DPRINTF(sc
, RT2860_DEBUG_TX
,
4540 "%s: Tx done task: scheduling again\n",
4541 device_get_nameunit(sc
->dev
));
4543 taskqueue_enqueue(sc
->taskqueue
, &sc
->tx_done_task
);
4546 RT2860_SOFTC_UNLOCK(sc
);
4550 * rt2860_fifo_sta_full_task
4552 static void rt2860_fifo_sta_full_task(void *context
, int pending
)
4554 struct rt2860_softc
*sc
;
4560 RT2860_DPRINTF(sc
, RT2860_DEBUG_STATS
,
4561 "%s: FIFO statistic full task\n",
4562 device_get_nameunit(sc
->dev
));
4564 if (!(ifp
->if_drv_flags
& IFF_DRV_RUNNING
))
4567 sc
->intr_pending_mask
&= ~RT2860_REG_INT_FIFO_STA_FULL
;
4569 rt2860_drain_fifo_stats(sc
);
4571 RT2860_SOFTC_LOCK(sc
);
4573 if (sc
->intr_pending_mask
& RT2860_REG_INT_FIFO_STA_FULL
)
4575 RT2860_DPRINTF(sc
, RT2860_DEBUG_STATS
,
4576 "%s: FIFO statistic full task: scheduling again\n",
4577 device_get_nameunit(sc
->dev
));
4579 taskqueue_enqueue(sc
->taskqueue
, &sc
->fifo_sta_full_task
);
4583 rt2860_intr_enable(sc
, RT2860_REG_INT_FIFO_STA_FULL
);
4586 RT2860_SOFTC_UNLOCK(sc
);
4590 * rt2860_periodic_task
4592 static void rt2860_periodic_task(void *context
, int pending
)
4594 struct rt2860_softc
*sc
;
4596 struct ieee80211com
*ic
;
4602 RT2860_DPRINTF(sc
, RT2860_DEBUG_PERIODIC
,
4603 "%s: periodic task: round=%lu\n",
4604 device_get_nameunit(sc
->dev
), sc
->periodic_round
);
4606 if (!(ifp
->if_drv_flags
& IFF_DRV_RUNNING
))
4609 RT2860_SOFTC_LOCK(sc
);
4611 sc
->periodic_round
++;
4613 rt2860_update_stats(sc
);
4615 if ((sc
->periodic_round
% 10) == 0)
4617 rt2860_bbp_tuning(sc
);
4619 rt2860_update_raw_counters(sc
);
4621 rt2860_watchdog(sc
);
4623 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
&& ic
->ic_state
== IEEE80211_S_RUN
)
4625 if (ic
->ic_opmode
== IEEE80211_M_STA
)
4626 rt2860_amrr_update_iter_func(sc
, ic
->ic_bss
);
4628 ieee80211_iterate_nodes(&ic
->ic_sta
, rt2860_amrr_update_iter_func
, sc
);
4632 RT2860_SOFTC_UNLOCK(sc
);
4634 callout_reset(&sc
->periodic_ch
, hz
/ 10, rt2860_periodic
, sc
);
4640 static int rt2860_rx_eof(struct rt2860_softc
*sc
, int limit
)
4642 struct ieee80211com
*ic
;
4644 struct ieee80211_frame
*wh
;
4645 struct ieee80211_node
*ni
;
4646 struct rt2860_softc_node
*rni
;
4647 struct rt2860_softc_rx_radiotap_header
*tap
;
4648 struct rt2860_softc_rx_ring
*ring
;
4649 struct rt2860_rxdesc
*desc
;
4650 struct rt2860_softc_rx_data
*data
;
4651 struct rt2860_rxwi
*rxwi
;
4652 struct mbuf
*m
, *mnew
;
4653 bus_dma_segment_t segs
[1];
4654 bus_dmamap_t dma_map
;
4655 uint32_t index
, desc_flags
;
4656 uint8_t cipher_err
, rssi
, ant
, phymode
, bw
, shortgi
, mcs
, keyidx
;
4658 int error
, nsegs
, len
, ampdu
, amsdu
, nframes
, i
;
4662 ring
= &sc
->rx_ring
;
4668 index
= rt2860_io_mac_read(sc
, RT2860_REG_SCHDMA_RX_DRX_IDX
);
4669 if (ring
->cur
== index
)
4672 desc
= &ring
->desc
[ring
->cur
];
4673 desc_flags
= le32toh(desc
->flags
);
4674 data
= &ring
->data
[ring
->cur
];
4676 bus_dmamap_sync(ring
->desc_dma_tag
, ring
->desc_dma_map
,
4677 BUS_DMASYNC_POSTREAD
);
4679 if (!(desc
->sdl0
& htole16(RT2860_RXDESC_SDL0_DDONE
)))
4684 mnew
= m_getjcl(M_DONTWAIT
, MT_DATA
, M_PKTHDR
, MJUMPAGESIZE
);
4687 sc
->rx_mbuf_alloc_errors
++;
4692 mnew
->m_len
= mnew
->m_pkthdr
.len
= MJUMPAGESIZE
;
4694 error
= bus_dmamap_load_mbuf_sg(ring
->data_dma_tag
, ring
->spare_dma_map
,
4695 mnew
, segs
, &nsegs
, BUS_DMA_NOWAIT
);
4700 sc
->rx_mbuf_dmamap_errors
++;
4706 KASSERT(nsegs
== 1, ("%s: too many DMA segments",
4707 device_get_name(sc
->dev
)));
4709 bus_dmamap_sync(ring
->data_dma_tag
, data
->dma_map
,
4710 BUS_DMASYNC_POSTREAD
);
4711 bus_dmamap_unload(ring
->data_dma_tag
, data
->dma_map
);
4713 dma_map
= data
->dma_map
;
4714 data
->dma_map
= ring
->spare_dma_map
;
4715 ring
->spare_dma_map
= dma_map
;
4717 bus_dmamap_sync(ring
->data_dma_tag
, data
->dma_map
,
4718 BUS_DMASYNC_PREREAD
);
4723 desc
->sdp0
= htole32(segs
[0].ds_addr
);
4725 /* get Rx wireless info */
4727 rxwi
= mtod(m
, struct rt2860_rxwi
*);
4728 len
= (le16toh(rxwi
->tid_size
) >> RT2860_RXWI_SIZE_SHIFT
) &
4729 RT2860_RXWI_SIZE_MASK
;
4731 /* check for L2 padding between IEEE 802.11 frame header and body */
4733 if (desc_flags
& RT2860_RXDESC_FLAGS_L2PAD
)
4735 RT2860_DPRINTF(sc
, RT2860_DEBUG_RX
,
4736 "%s: L2 padding: len=%d\n",
4737 device_get_nameunit(sc
->dev
), len
);
4742 m
->m_pkthdr
.rcvif
= ifp
;
4743 m
->m_data
= (caddr_t
) (rxwi
+ 1);
4744 m
->m_pkthdr
.len
= m
->m_len
= len
;
4746 /* check for crc errors */
4748 if (desc_flags
& RT2860_RXDESC_FLAGS_CRC_ERR
)
4750 RT2860_DPRINTF(sc
, RT2860_DEBUG_RX
,
4751 "%s: rxdesc: crc error\n",
4752 device_get_nameunit(sc
->dev
));
4756 if (!(ifp
->if_flags
& IFF_PROMISC
))
4763 wh
= (struct ieee80211_frame
*) (rxwi
+ 1);
4765 /* check for cipher errors */
4767 if (desc_flags
& RT2860_RXDESC_FLAGS_DECRYPTED
)
4769 cipher_err
= ((desc_flags
>> RT2860_RXDESC_FLAGS_CIPHER_ERR_SHIFT
) &
4770 RT2860_RXDESC_FLAGS_CIPHER_ERR_MASK
);
4771 if (cipher_err
== RT2860_RXDESC_FLAGS_CIPHER_ERR_NONE
)
4773 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
)
4774 wh
->i_fc
[1] &= ~IEEE80211_FC1_WEP
;
4776 m
->m_flags
|= M_WEP
;
4780 RT2860_DPRINTF(sc
, RT2860_DEBUG_RX
,
4781 "%s: rxdesc: cipher error=0x%02x\n",
4782 device_get_nameunit(sc
->dev
), cipher_err
);
4784 if ((cipher_err
== RT2860_RXDESC_FLAGS_CIPHER_ERR_MIC
) &&
4785 (desc_flags
& RT2860_RXDESC_FLAGS_MYBSS
))
4787 keyidx
= (rxwi
->udf_bssidx_keyidx
>> RT2860_RXWI_KEYIDX_SHIFT
) &
4788 RT2860_RXWI_KEYIDX_MASK
;
4790 ieee80211_notify_michael_failure(ic
, wh
, keyidx
);
4795 if (!(ifp
->if_flags
& IFF_PROMISC
))
4804 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
)
4806 RT2860_DPRINTF(sc
, RT2860_DEBUG_RX
,
4807 "%s: rxdesc: not decrypted but protected flag set\n",
4808 device_get_nameunit(sc
->dev
));
4812 if (!(ifp
->if_flags
& IFF_PROMISC
))
4820 /* check for A-MPDU */
4822 if (desc_flags
& RT2860_RXDESC_FLAGS_AMPDU
)
4824 m
->m_flags
|= M_AMPDU
;
4835 /* check for A-MSDU */
4837 if (desc_flags
& RT2860_RXDESC_FLAGS_AMSDU
)
4848 ant
= rt2860_maxrssi_rxpath(sc
, rxwi
);
4849 rssi
= rxwi
->rssi
[ant
];
4850 rssi_dbm
= rt2860_rssi2dbm(sc
, rssi
, ant
);
4851 phymode
= ((rxwi
->phymode_stbc_shortgi
>> RT2860_RXWI_PHYMODE_SHIFT
) &
4852 RT2860_RXWI_PHYMODE_MASK
);
4853 bw
= ((rxwi
->bw_mcs
>> RT2860_RXWI_BW_SHIFT
) & RT2860_RXWI_BW_MASK
);
4854 shortgi
= ((rxwi
->phymode_stbc_shortgi
>> RT2860_RXWI_SHORTGI_SHIFT
) &
4855 RT2860_RXWI_SHORTGI_MASK
);
4856 mcs
= ((rxwi
->bw_mcs
>> RT2860_RXWI_MCS_SHIFT
) & RT2860_RXWI_MCS_MASK
);
4858 if (bpf_peers_present(sc
->drvbpf
))
4862 tap
->flags
= IEEE80211_RADIOTAP_F_DATAPAD
;
4863 tap
->dbm_antsignal
= rssi_dbm
;
4864 tap
->dbm_antnoise
= RT2860_NOISE_FLOOR
;
4866 tap
->antsignal
= rssi
;
4867 tap
->chan_flags
= htole32(ic
->ic_curchan
->ic_flags
);
4868 tap
->chan_freq
= htole16(ic
->ic_curchan
->ic_freq
);
4869 tap
->chan_ieee
= ic
->ic_curchan
->ic_ieee
;
4870 tap
->chan_maxpow
= 0;
4872 if (phymode
== RT2860_TXWI_PHYMODE_HT_MIXED
|| phymode
== RT2860_TXWI_PHYMODE_HT_GF
)
4873 tap
->rate
= mcs
| IEEE80211_RATE_MCS
;
4875 tap
->rate
= rt2860_rxrate(rxwi
);
4877 if (desc_flags
& RT2860_RXDESC_FLAGS_CRC_ERR
)
4878 tap
->flags
|= IEEE80211_RADIOTAP_F_BADFCS
;
4880 if (desc_flags
& RT2860_RXDESC_FLAGS_FRAG
)
4881 tap
->flags
|= IEEE80211_RADIOTAP_F_FRAG
;
4883 if (rxwi
->bw_mcs
& RT2860_RXWI_MCS_SHOTPRE
)
4884 tap
->flags
|= IEEE80211_RADIOTAP_F_SHORTPRE
;
4887 tap
->flags
|= IEEE80211_RADIOTAP_F_SHORTGI
;
4889 bpf_mtap2(sc
->drvbpf
, tap
, sc
->rxtap_len
, m
);
4892 RT2860_DPRINTF(sc
, RT2860_DEBUG_RX
,
4893 "%s: received frame: len=%d, phymode=%d, bw=%d, shortgi=%d, mcs=%d, "
4894 "ant=%d, rssi=%d/%d/%d, snr=%d/%d, wcid=0x%02x, ampdu=%d, amsdu=%d\n",
4895 device_get_nameunit(sc
->dev
),
4896 len
, phymode
, bw
, shortgi
, mcs
,
4897 ant
, rxwi
->rssi
[0], rxwi
->rssi
[1], rxwi
->rssi
[2],
4898 rxwi
->snr
[0], rxwi
->snr
[1],
4899 rxwi
->wcid
, ampdu
, amsdu
);
4901 ni
= ieee80211_find_rxnode(ic
, (struct ieee80211_frame_min
*) wh
);
4905 rni
= (struct rt2860_softc_node
*) ni
;
4907 for (i
= 0; i
< RT2860_SOFTC_RSSI_DBM_COUNT
; i
++)
4908 rni
->last_rssi_dbm
[i
] = rt2860_rssi2dbm(sc
, rxwi
->rssi
[i
], i
);
4911 ieee80211_input(ic
, m
, ni
, rssi_dbm
, RT2860_NOISE_FLOOR
, 0);
4913 ieee80211_free_node(ni
);
4917 desc
->sdl0
&= ~htole16(RT2860_RXDESC_SDL0_DDONE
);
4919 bus_dmamap_sync(ring
->desc_dma_tag
, ring
->desc_dma_map
,
4920 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
4922 ring
->cur
= (ring
->cur
+ 1) % RT2860_SOFTC_RX_RING_DATA_COUNT
;
4928 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_RX_CALC_IDX
,
4929 RT2860_SOFTC_RX_RING_DATA_COUNT
- 1);
4931 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_RX_CALC_IDX
,
4934 RT2860_DPRINTF(sc
, RT2860_DEBUG_RX
,
4935 "%s: Rx eof: nframes=%d\n",
4936 device_get_nameunit(sc
->dev
), nframes
);
4938 sc
->rx_packets
+= nframes
;
4940 return (limit
== 0);
4946 static void rt2860_tx_eof(struct rt2860_softc
*sc
,
4947 struct rt2860_softc_tx_ring
*ring
)
4950 struct rt2860_txdesc
*desc
;
4951 struct rt2860_softc_tx_data
*data
;
4953 int ndescs
, nframes
;
4962 index
= rt2860_io_mac_read(sc
, RT2860_REG_SCHDMA_TX_DTX_IDX(ring
->qid
));
4963 if (ring
->desc_next
== index
)
4968 rt2860_drain_fifo_stats(sc
);
4970 desc
= &ring
->desc
[ring
->desc_next
];
4972 bus_dmamap_sync(ring
->desc_dma_tag
, ring
->desc_dma_map
,
4973 BUS_DMASYNC_POSTREAD
);
4975 if (desc
->sdl0
& htole16(RT2860_TXDESC_SDL0_LASTSEG
) ||
4976 desc
->sdl1
& htole16(RT2860_TXDESC_SDL1_LASTSEG
))
4980 data
= &ring
->data
[ring
->data_next
];
4982 if (data
->m
->m_flags
& M_TXCB
)
4983 ieee80211_process_callback(data
->ni
, data
->m
, 0);
4985 bus_dmamap_sync(ring
->data_dma_tag
, data
->dma_map
,
4986 BUS_DMASYNC_POSTWRITE
);
4987 bus_dmamap_unload(ring
->data_dma_tag
, data
->dma_map
);
4991 ieee80211_free_node(data
->ni
);
4998 RT2860_SOFTC_LOCK(sc
);
5000 ring
->data_queued
--;
5001 ring
->data_next
= (ring
->data_next
+ 1) % RT2860_SOFTC_TX_RING_DATA_COUNT
;
5003 RT2860_SOFTC_UNLOCK(sc
);
5006 desc
->sdl0
&= ~htole16(RT2860_TXDESC_SDL0_DDONE
);
5008 bus_dmamap_sync(ring
->desc_dma_tag
, ring
->desc_dma_map
,
5009 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
5011 RT2860_SOFTC_LOCK(sc
);
5013 ring
->desc_queued
--;
5014 ring
->desc_next
= (ring
->desc_next
+ 1) % RT2860_SOFTC_TX_RING_DESC_COUNT
;
5016 RT2860_SOFTC_UNLOCK(sc
);
5019 RT2860_DPRINTF(sc
, RT2860_DEBUG_TX
,
5020 "%s: Tx eof: qid=%d, ndescs=%d, nframes=%d\n",
5021 device_get_nameunit(sc
->dev
), ring
->qid
, ndescs
, nframes
);
5025 * rt2860_update_stats
5027 static void rt2860_update_stats(struct rt2860_softc
*sc
)
5030 struct ieee80211com
*ic
;
5031 struct ieee80211_node
*ni
;
5033 int beacons
, noretryok
, retryok
, failed
, underflows
, zerolen
;
5040 RT2860_DPRINTF(sc
, RT2860_DEBUG_STATS
,
5041 "%s: update statistic\n",
5042 device_get_nameunit(sc
->dev
));
5044 rt2860_drain_fifo_stats(sc
);
5046 /* read and clear Tx statistic registers */
5048 rt2860_io_mac_read_multi(sc
, RT2860_REG_TX_STA_CNT0
,
5049 stacnt
, sizeof(stacnt
));
5051 stacnt
[0] = le32toh(stacnt
[0]);
5052 stacnt
[1] = le32toh(stacnt
[1]);
5053 stacnt
[2] = le32toh(stacnt
[2]);
5055 beacons
= stacnt
[0] >> 16;
5056 noretryok
= stacnt
[1] & 0xffff;
5057 retryok
= stacnt
[1] >> 16;
5058 failed
= stacnt
[0] & 0xffff;
5059 underflows
= stacnt
[2] >> 16;
5060 zerolen
= stacnt
[2] & 0xffff;
5062 RT2860_DPRINTF(sc
, RT2860_DEBUG_STATS
,
5063 "%s: update statistic: beacons=%d, noretryok=%d, retryok=%d, failed=%d, underflows=%d, zerolen=%d\n",
5064 device_get_nameunit(sc
->dev
),
5065 beacons
, noretryok
, retryok
, failed
, underflows
, zerolen
);
5067 ifp
->if_oerrors
+= failed
;
5069 sc
->tx_beacons
+= beacons
;
5070 sc
->tx_noretryok
+= noretryok
;
5071 sc
->tx_retryok
+= retryok
;
5072 sc
->tx_failed
+= failed
;
5073 sc
->tx_underflows
+= underflows
;
5074 sc
->tx_zerolen
+= zerolen
;
5076 if (ic
->ic_opmode
== IEEE80211_M_STA
&& ic
->ic_state
== IEEE80211_S_RUN
)
5080 associd
= (ni
!= NULL
) ? ni
->ni_associd
: 0;
5081 wcid
= RT2860_AID2WCID(associd
);
5083 rt2860_amrr_tx_update(&sc
->amrr_node
[wcid
],
5084 noretryok
+ retryok
+ failed
, noretryok
+ retryok
, retryok
+ failed
);
5091 static void rt2860_bbp_tuning(struct rt2860_softc
*sc
)
5093 struct ieee80211com
*ic
;
5094 struct ieee80211_node
*ni
;
5096 int8_t rssi
, old
, new;
5098 /* RT2860C does not support BBP tuning */
5100 if (sc
->mac_rev
== 0x28600100)
5105 if ((ic
->ic_flags
& IEEE80211_F_SCAN
) ||
5106 ic
->ic_opmode
!= IEEE80211_M_STA
|| ic
->ic_state
!= IEEE80211_S_RUN
)
5111 chan
= ieee80211_chan2ieee(ic
, ni
->ni_chan
);
5115 else if (chan
<= 64)
5117 else if (chan
<= 128)
5122 rssi
= ieee80211_getrssi(ic
);
5124 if (IEEE80211_IS_CHAN_2GHZ(ni
->ni_chan
))
5126 new = 0x2e + sc
->lna_gain
[group
];
5130 if (!IEEE80211_IS_CHAN_HT40(ni
->ni_chan
))
5131 new = 0x32 + sc
->lna_gain
[group
] * 5 / 3;
5133 new = 0x3a + sc
->lna_gain
[group
] * 5 / 3;
5136 /* Tune if absolute average RSSI is greater than -80 */
5141 old
= rt2860_io_bbp_read(sc
, 66);
5144 rt2860_io_bbp_write(sc
, 66, new);
5150 static void rt2860_watchdog(struct rt2860_softc
*sc
)
5155 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_PBF_TXRXQ_PCNT
);
5157 RT2860_DPRINTF(sc
, RT2860_DEBUG_WATCHDOG
,
5158 "%s: watchdog: TXRXQ_PCNT=0x%08x\n",
5159 device_get_nameunit(sc
->dev
), tmp
);
5161 if (((tmp
>> RT2860_REG_TX0Q_PCNT_SHIFT
) & RT2860_REG_TX0Q_PCNT_MASK
) != 0)
5163 sc
->tx_queue_not_empty
[0]++;
5165 rt2860_io_mac_write(sc
, RT2860_REG_PBF_CFG
, 0xf40012);
5167 for (ntries
= 0; ntries
< 10; ntries
++)
5169 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_PBF_TXRXQ_PCNT
);
5170 if (((tmp
>> RT2860_REG_TX0Q_PCNT_SHIFT
) & RT2860_REG_TX0Q_PCNT_MASK
) == 0)
5176 rt2860_io_mac_write(sc
, RT2860_REG_PBF_CFG
, 0xf40006);
5179 if (((tmp
>> RT2860_REG_TX1Q_PCNT_SHIFT
) & RT2860_REG_TX1Q_PCNT_MASK
) != 0)
5181 sc
->tx_queue_not_empty
[1]++;
5183 rt2860_io_mac_write(sc
, RT2860_REG_PBF_CFG
, 0xf4000a);
5185 for (ntries
= 0; ntries
< 10; ntries
++)
5187 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_PBF_TXRXQ_PCNT
);
5188 if (((tmp
>> RT2860_REG_TX1Q_PCNT_SHIFT
) & RT2860_REG_TX1Q_PCNT_MASK
) == 0)
5194 rt2860_io_mac_write(sc
, RT2860_REG_PBF_CFG
, 0xf40006);
5199 * rt2860_drain_fifo_stats
5201 static void rt2860_drain_fifo_stats(struct rt2860_softc
*sc
)
5205 uint8_t wcid
, mcs
, pid
;
5206 int ok
, agg
, retrycnt
;
5208 ifp
= sc
->ic
.ic_ifp
;
5210 /* drain Tx status FIFO (maxsize = 16) */
5212 while ((stats
= rt2860_io_mac_read(sc
, RT2860_REG_TX_STA_FIFO
)) &
5213 RT2860_REG_TX_STA_FIFO_VALID
)
5215 wcid
= (stats
>> RT2860_REG_TX_STA_FIFO_WCID_SHIFT
) &
5216 RT2860_REG_TX_STA_FIFO_WCID_MASK
;
5218 /* if no ACK was requested, no feedback is available */
5220 if (!(stats
& RT2860_REG_TX_STA_FIFO_ACK_REQ
) || wcid
== RT2860_WCID_RESERVED
)
5223 /* update AMRR statistic */
5225 ok
= (stats
& RT2860_REG_TX_STA_FIFO_TX_OK
) ? 1 : 0;
5226 agg
= (stats
& RT2860_REG_TX_STA_FIFO_AGG
) ? 1 : 0;
5227 mcs
= (stats
>> RT2860_REG_TX_STA_FIFO_MCS_SHIFT
) &
5228 RT2860_REG_TX_STA_FIFO_MCS_MASK
;
5229 pid
= (stats
>> RT2860_REG_TX_STA_FIFO_PID_SHIFT
) &
5230 RT2860_REG_TX_STA_FIFO_PID_MASK
;
5231 retrycnt
= pid
- mcs
;
5233 RT2860_DPRINTF(sc
, RT2860_DEBUG_STATS
,
5234 "%s: FIFO statistic: wcid=0x%02x, ok=%d, agg=%d, mcs=0x%02x, pid=0x%02x, retrycnt=%d\n",
5235 device_get_nameunit(sc
->dev
),
5236 wcid
, ok
, agg
, mcs
, pid
, retrycnt
);
5238 rt2860_amrr_tx_complete(&sc
->amrr_node
[wcid
], ok
, retrycnt
);
5246 * rt2860_update_raw_counters
5248 static void rt2860_update_raw_counters(struct rt2860_softc
*sc
)
5252 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_TX_AGG_CNT
);
5254 sc
->tx_nonagg
+= tmp
& 0xffff;
5255 sc
->tx_agg
+= tmp
>> 16;
5257 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_TX_AGG_CNT0
);
5259 sc
->tx_ampdu
+= (tmp
& 0xffff) / 1 + (tmp
>> 16) / 2;
5261 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_TX_AGG_CNT1
);
5263 sc
->tx_ampdu
+= (tmp
& 0xffff) / 3 + (tmp
>> 16) / 4;
5265 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_TX_AGG_CNT2
);
5267 sc
->tx_ampdu
+= (tmp
& 0xffff) / 5 + (tmp
>> 16) / 6;
5269 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_TX_AGG_CNT3
);
5271 sc
->tx_ampdu
+= (tmp
& 0xffff) / 7 + (tmp
>> 16) / 8;
5273 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_TX_AGG_CNT4
);
5275 sc
->tx_ampdu
+= (tmp
& 0xffff) / 9 + (tmp
>> 16) / 10;
5277 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_TX_AGG_CNT5
);
5279 sc
->tx_ampdu
+= (tmp
& 0xffff) / 11 + (tmp
>> 16) / 12;
5281 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_TX_AGG_CNT6
);
5283 sc
->tx_ampdu
+= (tmp
& 0xffff) / 13 + (tmp
>> 16) / 14;
5285 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_TX_AGG_CNT7
);
5287 sc
->tx_ampdu
+= (tmp
& 0xffff) / 15 + (tmp
>> 16) / 16;
5289 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_RX_STA_CNT0
);
5291 sc
->rx_crc_errors
+= tmp
& 0xffff;
5292 sc
->rx_phy_errors
+= tmp
>> 16;
5294 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_RX_STA_CNT1
);
5296 sc
->rx_false_ccas
+= tmp
& 0xffff;
5297 sc
->rx_plcp_errors
+= tmp
>> 16;
5299 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_RX_STA_CNT2
);
5301 sc
->rx_dup_packets
+= tmp
& 0xffff;
5302 sc
->rx_fifo_overflows
+= tmp
>> 16;
5304 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_TXRX_MPDU_DEN_CNT
);
5306 sc
->tx_mpdu_zero_density
+= tmp
& 0xffff;
5307 sc
->rx_mpdu_zero_density
+= tmp
>> 16;
5311 * rt2860_intr_enable
5313 static void rt2860_intr_enable(struct rt2860_softc
*sc
, uint32_t intr_mask
)
5317 sc
->intr_disable_mask
&= ~intr_mask
;
5319 tmp
= sc
->intr_enable_mask
& ~sc
->intr_disable_mask
;
5321 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_INT_MASK
, tmp
);
5325 * rt2860_intr_disable
5327 static void rt2860_intr_disable(struct rt2860_softc
*sc
, uint32_t intr_mask
)
5331 sc
->intr_disable_mask
|= intr_mask
;
5333 tmp
= sc
->intr_enable_mask
& ~sc
->intr_disable_mask
;
5335 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_INT_MASK
, tmp
);
5339 * rt2860_txrx_enable
5341 static int rt2860_txrx_enable(struct rt2860_softc
*sc
)
5343 struct ieee80211com
*ic
;
5351 /* enable Tx/Rx DMA engine */
5353 rt2860_io_mac_write(sc
, RT2860_REG_SYS_CTRL
, RT2860_REG_TX_ENABLE
);
5355 for (ntries
= 0; ntries
< 200; ntries
++)
5357 tmp
= rt2860_io_mac_read(sc
, RT2860_REG_SCHDMA_WPDMA_GLO_CFG
);
5358 if (!(tmp
& (RT2860_REG_TX_DMA_BUSY
| RT2860_REG_RX_DMA_BUSY
)))
5366 printf("%s: timeout waiting for DMA engine\n",
5367 device_get_nameunit(sc
->dev
));
5373 tmp
|= RT2860_REG_TX_WB_DDONE
|
5374 RT2860_REG_RX_DMA_ENABLE
|
5375 RT2860_REG_TX_DMA_ENABLE
|
5376 (RT2860_REG_WPDMA_BT_SIZE64
<< RT2860_REG_WPDMA_BT_SIZE_SHIFT
);
5378 rt2860_io_mac_write(sc
, RT2860_REG_SCHDMA_WPDMA_GLO_CFG
, tmp
);
5382 tmp
= RT2860_REG_RX_FILTER_DROP_CRC_ERR
|
5383 RT2860_REG_RX_FILTER_DROP_PHY_ERR
;
5385 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
)
5387 tmp
|= RT2860_REG_RX_FILTER_DROP_DUPL
|
5388 RT2860_REG_RX_FILTER_DROP_CTS
|
5389 RT2860_REG_RX_FILTER_DROP_BA
|
5390 RT2860_REG_RX_FILTER_DROP_ACK
|
5391 RT2860_REG_RX_FILTER_DROP_VER_ERR
|
5392 RT2860_REG_RX_FILTER_DROP_CTRL_RSV
|
5393 RT2860_REG_RX_FILTER_DROP_CFACK
|
5394 RT2860_REG_RX_FILTER_DROP_CFEND
;
5396 if (ic
->ic_opmode
== IEEE80211_M_STA
)
5397 tmp
|= RT2860_REG_RX_FILTER_DROP_RTS
|
5398 RT2860_REG_RX_FILTER_DROP_PSPOLL
;
5400 if (!(ifp
->if_flags
& IFF_PROMISC
))
5401 tmp
|= RT2860_REG_RX_FILTER_DROP_UC_NOME
;
5404 rt2860_io_mac_write(sc
, RT2860_REG_RX_FILTER_CFG
, tmp
);
5406 rt2860_io_mac_write(sc
, RT2860_REG_SYS_CTRL
,
5407 RT2860_REG_RX_ENABLE
| RT2860_REG_TX_ENABLE
);
5413 * rt2860_alloc_rx_ring
5415 static int rt2860_alloc_rx_ring(struct rt2860_softc
*sc
,
5416 struct rt2860_softc_rx_ring
*ring
)
5418 struct rt2860_rxdesc
*desc
;
5419 struct rt2860_softc_rx_data
*data
;
5420 bus_dma_segment_t segs
[1];
5421 int i
, nsegs
, error
;
5423 error
= bus_dma_tag_create(bus_get_dma_tag(sc
->dev
), PAGE_SIZE
, 0,
5424 BUS_SPACE_MAXADDR_32BIT
, BUS_SPACE_MAXADDR
, NULL
, NULL
,
5425 RT2860_SOFTC_RX_RING_DATA_COUNT
* sizeof(struct rt2860_rxdesc
), 1,
5426 RT2860_SOFTC_RX_RING_DATA_COUNT
* sizeof(struct rt2860_rxdesc
),
5427 0, NULL
, NULL
, &ring
->desc_dma_tag
);
5430 printf("%s: could not create Rx desc DMA tag\n",
5431 device_get_nameunit(sc
->dev
));
5435 error
= bus_dmamem_alloc(ring
->desc_dma_tag
, (void **) &ring
->desc
,
5436 BUS_DMA_NOWAIT
| BUS_DMA_ZERO
, &ring
->desc_dma_map
);
5439 printf("%s: could not allocate Rx desc DMA memory\n",
5440 device_get_nameunit(sc
->dev
));
5444 error
= bus_dmamap_load(ring
->desc_dma_tag
, ring
->desc_dma_map
,
5446 RT2860_SOFTC_RX_RING_DATA_COUNT
* sizeof(struct rt2860_rxdesc
),
5447 rt2860_dma_map_addr
, &ring
->desc_phys_addr
, 0);
5450 printf("%s: could not load Rx desc DMA map\n",
5451 device_get_nameunit(sc
->dev
));
5455 error
= bus_dma_tag_create(bus_get_dma_tag(sc
->dev
), PAGE_SIZE
, 0,
5456 BUS_SPACE_MAXADDR_32BIT
, BUS_SPACE_MAXADDR
, NULL
, NULL
,
5457 MJUMPAGESIZE
, 1, MJUMPAGESIZE
, 0, NULL
, NULL
,
5458 &ring
->data_dma_tag
);
5461 printf("%s: could not create Rx data DMA tag\n",
5462 device_get_nameunit(sc
->dev
));
5466 for (i
= 0; i
< RT2860_SOFTC_RX_RING_DATA_COUNT
; i
++)
5468 desc
= &ring
->desc
[i
];
5469 data
= &ring
->data
[i
];
5471 error
= bus_dmamap_create(ring
->data_dma_tag
, 0, &data
->dma_map
);
5474 printf("%s: could not create Rx data DMA map\n",
5475 device_get_nameunit(sc
->dev
));
5479 data
->m
= m_getjcl(M_DONTWAIT
, MT_DATA
, M_PKTHDR
, MJUMPAGESIZE
);
5480 if (data
->m
== NULL
)
5482 printf("%s: could not allocate Rx mbuf\n",
5483 device_get_nameunit(sc
->dev
));
5488 data
->m
->m_len
= data
->m
->m_pkthdr
.len
= MJUMPAGESIZE
;
5490 error
= bus_dmamap_load_mbuf_sg(ring
->data_dma_tag
, data
->dma_map
,
5491 data
->m
, segs
, &nsegs
, BUS_DMA_NOWAIT
);
5494 printf("%s: could not load Rx mbuf DMA map\n",
5495 device_get_nameunit(sc
->dev
));
5499 KASSERT(nsegs
== 1, ("%s: too many DMA segments",
5500 device_get_name(sc
->dev
)));
5502 desc
->sdp0
= htole32(segs
[0].ds_addr
);
5503 desc
->sdl0
= htole16(MJUMPAGESIZE
);
5506 error
= bus_dmamap_create(ring
->data_dma_tag
, 0, &ring
->spare_dma_map
);
5509 printf("%s: could not create Rx spare DMA map\n",
5510 device_get_nameunit(sc
->dev
));
5514 bus_dmamap_sync(ring
->desc_dma_tag
, ring
->desc_dma_map
,
5515 BUS_DMASYNC_PREWRITE
);
5521 rt2860_free_rx_ring(sc
, ring
);
5527 * rt2860_reset_rx_ring
5529 static void rt2860_reset_rx_ring(struct rt2860_softc
*sc
,
5530 struct rt2860_softc_rx_ring
*ring
)
5532 struct rt2860_rxdesc
*desc
;
5535 for (i
= 0; i
< RT2860_SOFTC_RX_RING_DATA_COUNT
; i
++)
5537 desc
= &ring
->desc
[i
];
5539 desc
->sdl0
&= ~htole16(RT2860_RXDESC_SDL0_DDONE
);
5542 bus_dmamap_sync(ring
->desc_dma_tag
, ring
->desc_dma_map
,
5543 BUS_DMASYNC_PREWRITE
);
5549 * rt2860_free_rx_ring
5551 static void rt2860_free_rx_ring(struct rt2860_softc
*sc
,
5552 struct rt2860_softc_rx_ring
*ring
)
5554 struct rt2860_softc_rx_data
*data
;
5557 if (ring
->desc
!= NULL
)
5559 bus_dmamap_sync(ring
->desc_dma_tag
, ring
->desc_dma_map
,
5560 BUS_DMASYNC_POSTWRITE
);
5561 bus_dmamap_unload(ring
->desc_dma_tag
, ring
->desc_dma_map
);
5562 bus_dmamem_free(ring
->desc_dma_tag
, ring
->desc
,
5563 ring
->desc_dma_map
);
5566 if (ring
->desc_dma_tag
!= NULL
)
5567 bus_dma_tag_destroy(ring
->desc_dma_tag
);
5569 for (i
= 0; i
< RT2860_SOFTC_RX_RING_DATA_COUNT
; i
++)
5571 data
= &ring
->data
[i
];
5573 if (data
->m
!= NULL
)
5575 bus_dmamap_sync(ring
->data_dma_tag
, data
->dma_map
,
5576 BUS_DMASYNC_POSTREAD
);
5577 bus_dmamap_unload(ring
->data_dma_tag
, data
->dma_map
);
5581 if (data
->dma_map
!= NULL
)
5582 bus_dmamap_destroy(ring
->data_dma_tag
, data
->dma_map
);
5585 if (ring
->spare_dma_map
!= NULL
)
5586 bus_dmamap_destroy(ring
->data_dma_tag
, ring
->spare_dma_map
);
5588 if (ring
->data_dma_tag
!= NULL
)
5589 bus_dma_tag_destroy(ring
->data_dma_tag
);
5593 * rt2860_alloc_tx_ring
5595 static int rt2860_alloc_tx_ring(struct rt2860_softc
*sc
,
5596 struct rt2860_softc_tx_ring
*ring
, int qid
)
5598 struct rt2860_softc_tx_data
*data
;
5601 error
= bus_dma_tag_create(bus_get_dma_tag(sc
->dev
), PAGE_SIZE
, 0,
5602 BUS_SPACE_MAXADDR_32BIT
, BUS_SPACE_MAXADDR
, NULL
, NULL
,
5603 RT2860_SOFTC_TX_RING_DESC_COUNT
* sizeof(struct rt2860_txdesc
), 1,
5604 RT2860_SOFTC_TX_RING_DESC_COUNT
* sizeof(struct rt2860_txdesc
),
5605 0, NULL
, NULL
, &ring
->desc_dma_tag
);
5608 printf("%s: could not create Tx desc DMA tag\n",
5609 device_get_nameunit(sc
->dev
));
5613 error
= bus_dmamem_alloc(ring
->desc_dma_tag
, (void **) &ring
->desc
,
5614 BUS_DMA_NOWAIT
| BUS_DMA_ZERO
, &ring
->desc_dma_map
);
5617 printf("%s: could not allocate Tx desc DMA memory\n",
5618 device_get_nameunit(sc
->dev
));
5622 error
= bus_dmamap_load(ring
->desc_dma_tag
, ring
->desc_dma_map
,
5624 RT2860_SOFTC_TX_RING_DESC_COUNT
* sizeof(struct rt2860_txdesc
),
5625 rt2860_dma_map_addr
, &ring
->desc_phys_addr
, 0);
5628 printf("%s: could not load Tx desc DMA map\n",
5629 device_get_nameunit(sc
->dev
));
5633 ring
->desc_queued
= 0;
5635 ring
->desc_next
= 0;
5637 error
= bus_dma_tag_create(bus_get_dma_tag(sc
->dev
), PAGE_SIZE
, 0,
5638 BUS_SPACE_MAXADDR_32BIT
, BUS_SPACE_MAXADDR
, NULL
, NULL
,
5639 RT2860_SOFTC_TX_RING_DATA_COUNT
* RT2860_TX_DATA_SEG0_SIZE
, 1,
5640 RT2860_SOFTC_TX_RING_DATA_COUNT
* RT2860_TX_DATA_SEG0_SIZE
,
5641 0, NULL
, NULL
, &ring
->seg0_dma_tag
);
5644 printf("%s: could not create Tx seg0 DMA tag\n",
5645 device_get_nameunit(sc
->dev
));
5649 error
= bus_dmamem_alloc(ring
->seg0_dma_tag
, (void **) &ring
->seg0
,
5650 BUS_DMA_NOWAIT
| BUS_DMA_ZERO
, &ring
->seg0_dma_map
);
5653 printf("%s: could not allocate Tx seg0 DMA memory\n",
5654 device_get_nameunit(sc
->dev
));
5658 error
= bus_dmamap_load(ring
->seg0_dma_tag
, ring
->seg0_dma_map
,
5660 RT2860_SOFTC_TX_RING_DATA_COUNT
* RT2860_TX_DATA_SEG0_SIZE
,
5661 rt2860_dma_map_addr
, &ring
->seg0_phys_addr
, 0);
5664 printf("%s: could not load Tx seg0 DMA map\n",
5665 device_get_nameunit(sc
->dev
));
5669 error
= bus_dma_tag_create(bus_get_dma_tag(sc
->dev
), PAGE_SIZE
, 0,
5670 BUS_SPACE_MAXADDR_32BIT
, BUS_SPACE_MAXADDR
, NULL
, NULL
,
5671 MJUMPAGESIZE
, RT2860_SOFTC_MAX_SCATTER
, MJUMPAGESIZE
, 0, NULL
, NULL
,
5672 &ring
->data_dma_tag
);
5675 printf("%s: could not create Tx data DMA tag\n",
5676 device_get_nameunit(sc
->dev
));
5680 for (i
= 0; i
< RT2860_SOFTC_TX_RING_DATA_COUNT
; i
++)
5682 data
= &ring
->data
[i
];
5684 error
= bus_dmamap_create(ring
->data_dma_tag
, 0, &data
->dma_map
);
5687 printf("%s: could not create Tx data DMA map\n",
5688 device_get_nameunit(sc
->dev
));
5693 ring
->data_queued
= 0;
5695 ring
->data_next
= 0;
5703 rt2860_free_tx_ring(sc
, ring
);
5709 * rt2860_reset_tx_ring
5711 static void rt2860_reset_tx_ring(struct rt2860_softc
*sc
,
5712 struct rt2860_softc_tx_ring
*ring
)
5714 struct rt2860_softc_tx_data
*data
;
5715 struct rt2860_txdesc
*desc
;
5718 for (i
= 0; i
< RT2860_SOFTC_TX_RING_DESC_COUNT
; i
++)
5720 desc
= &ring
->desc
[i
];
5726 ring
->desc_queued
= 0;
5728 ring
->desc_next
= 0;
5730 bus_dmamap_sync(ring
->desc_dma_tag
, ring
->desc_dma_map
,
5731 BUS_DMASYNC_PREWRITE
);
5733 bus_dmamap_sync(ring
->seg0_dma_tag
, ring
->seg0_dma_map
,
5734 BUS_DMASYNC_PREWRITE
);
5736 for (i
= 0; i
< RT2860_SOFTC_TX_RING_DATA_COUNT
; i
++)
5738 data
= &ring
->data
[i
];
5740 if (data
->m
!= NULL
)
5742 bus_dmamap_sync(ring
->data_dma_tag
, data
->dma_map
,
5743 BUS_DMASYNC_POSTWRITE
);
5744 bus_dmamap_unload(ring
->data_dma_tag
, data
->dma_map
);
5749 if (data
->ni
!= NULL
)
5751 ieee80211_free_node(data
->ni
);
5756 ring
->data_queued
= 0;
5758 ring
->data_next
= 0;
5762 * rt2860_free_tx_ring
5764 static void rt2860_free_tx_ring(struct rt2860_softc
*sc
,
5765 struct rt2860_softc_tx_ring
*ring
)
5767 struct rt2860_softc_tx_data
*data
;
5770 if (ring
->desc
!= NULL
)
5772 bus_dmamap_sync(ring
->desc_dma_tag
, ring
->desc_dma_map
,
5773 BUS_DMASYNC_POSTWRITE
);
5774 bus_dmamap_unload(ring
->desc_dma_tag
, ring
->desc_dma_map
);
5775 bus_dmamem_free(ring
->desc_dma_tag
, ring
->desc
,
5776 ring
->desc_dma_map
);
5779 if (ring
->desc_dma_tag
!= NULL
)
5780 bus_dma_tag_destroy(ring
->desc_dma_tag
);
5782 if (ring
->seg0
!= NULL
)
5784 bus_dmamap_sync(ring
->seg0_dma_tag
, ring
->seg0_dma_map
,
5785 BUS_DMASYNC_POSTWRITE
);
5786 bus_dmamap_unload(ring
->seg0_dma_tag
, ring
->seg0_dma_map
);
5787 bus_dmamem_free(ring
->seg0_dma_tag
, ring
->seg0
,
5788 ring
->seg0_dma_map
);
5791 if (ring
->seg0_dma_tag
!= NULL
)
5792 bus_dma_tag_destroy(ring
->seg0_dma_tag
);
5794 for (i
= 0; i
< RT2860_SOFTC_TX_RING_DATA_COUNT
; i
++)
5796 data
= &ring
->data
[i
];
5798 if (data
->m
!= NULL
)
5800 bus_dmamap_sync(ring
->data_dma_tag
, data
->dma_map
,
5801 BUS_DMASYNC_POSTWRITE
);
5802 bus_dmamap_unload(ring
->data_dma_tag
, data
->dma_map
);
5806 if (data
->ni
!= NULL
)
5807 ieee80211_free_node(data
->ni
);
5809 if (data
->dma_map
!= NULL
)
5810 bus_dmamap_destroy(ring
->data_dma_tag
, data
->dma_map
);
5813 if (ring
->data_dma_tag
!= NULL
)
5814 bus_dma_tag_destroy(ring
->data_dma_tag
);
5818 * rt2860_dma_map_addr
5820 static void rt2860_dma_map_addr(void *arg
, bus_dma_segment_t
*segs
,
5821 int nseg
, int error
)
5826 KASSERT(nseg
== 1, ("too many DMA segments, %d should be 1", nseg
));
5828 *(bus_addr_t
*) arg
= segs
[0].ds_addr
;
5832 * rt2860_sysctl_attach
5834 static void rt2860_sysctl_attach(struct rt2860_softc
*sc
)
5836 struct sysctl_ctx_list
*ctx
;
5837 struct sysctl_oid
*tree
;
5838 struct sysctl_oid
*stats
;
5840 ctx
= device_get_sysctl_ctx(sc
->dev
);
5841 tree
= device_get_sysctl_tree(sc
->dev
);
5843 stats
= SYSCTL_ADD_NODE(ctx
, SYSCTL_CHILDREN(tree
), OID_AUTO
,
5844 "stats", CTLFLAG_RD
, 0, "statistic");
5846 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5847 "interrupts", CTLFLAG_RD
, &sc
->interrupts
, 0,
5850 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5851 "tx_coherent_interrupts", CTLFLAG_RD
, &sc
->tx_coherent_interrupts
, 0,
5852 "Tx coherent interrupts");
5854 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5855 "rx_coherent_interrupts", CTLFLAG_RD
, &sc
->rx_coherent_interrupts
, 0,
5856 "Rx coherent interrupts");
5858 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5859 "txrx_coherent_interrupts", CTLFLAG_RD
, &sc
->txrx_coherent_interrupts
, 0,
5860 "Tx/Rx coherent interrupts");
5862 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5863 "fifo_sta_full_interrupts", CTLFLAG_RD
, &sc
->fifo_sta_full_interrupts
, 0,
5864 "FIFO statistic full interrupts");
5866 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5867 "rx_interrupts", CTLFLAG_RD
, &sc
->rx_interrupts
, 0,
5870 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5871 "rx_delay_interrupts", CTLFLAG_RD
, &sc
->rx_delay_interrupts
, 0,
5872 "Rx delay interrupts");
5874 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5875 "tx_mgmt_interrupts", CTLFLAG_RD
, &sc
->tx_interrupts
[5], 0,
5876 "Tx MGMT interrupts");
5878 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5879 "tx_hcca_interrupts", CTLFLAG_RD
, &sc
->tx_interrupts
[4], 0,
5880 "Tx HCCA interrupts");
5882 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5883 "tx_ac3_interrupts", CTLFLAG_RD
, &sc
->tx_interrupts
[3], 0,
5884 "Tx AC3 interrupts");
5886 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5887 "tx_ac2_interrupts", CTLFLAG_RD
, &sc
->tx_interrupts
[2], 0,
5888 "Tx AC2 interrupts");
5890 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5891 "tx_ac1_interrupts", CTLFLAG_RD
, &sc
->tx_interrupts
[1], 0,
5892 "Tx AC1 interrupts");
5894 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5895 "tx_ac0_interrupts", CTLFLAG_RD
, &sc
->tx_interrupts
[0], 0,
5896 "Tx AC0 interrupts");
5898 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5899 "tx_delay_interrupts", CTLFLAG_RD
, &sc
->tx_delay_interrupts
, 0,
5900 "Tx delay interrupts");
5902 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5903 "pre_tbtt_interrupts", CTLFLAG_RD
, &sc
->pre_tbtt_interrupts
, 0,
5904 "Pre-TBTT interrupts");
5906 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5907 "tbtt_interrupts", CTLFLAG_RD
, &sc
->tbtt_interrupts
, 0,
5910 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5911 "mcu_cmd_interrupts", CTLFLAG_RD
, &sc
->mcu_cmd_interrupts
, 0,
5912 "MCU command interrupts");
5914 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5915 "auto_wakeup_interrupts", CTLFLAG_RD
, &sc
->auto_wakeup_interrupts
, 0,
5916 "auto wakeup interrupts");
5918 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5919 "gp_timer_interrupts", CTLFLAG_RD
, &sc
->gp_timer_interrupts
, 0,
5920 "GP timer interrupts");
5922 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5923 "tx_mgmt_desc_queued", CTLFLAG_RD
, &sc
->tx_ring
[5].desc_queued
, 0,
5924 "Tx MGMT descriptors queued");
5926 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5927 "tx_mgmt_data_queued", CTLFLAG_RD
, &sc
->tx_ring
[5].data_queued
, 0,
5928 "Tx MGMT data queued");
5930 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5931 "tx_hcca_desc_queued", CTLFLAG_RD
, &sc
->tx_ring
[4].desc_queued
, 0,
5932 "Tx HCCA descriptors queued");
5934 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5935 "tx_hcca_data_queued", CTLFLAG_RD
, &sc
->tx_ring
[4].data_queued
, 0,
5936 "Tx HCCA data queued");
5938 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5939 "tx_ac3_desc_queued", CTLFLAG_RD
, &sc
->tx_ring
[3].desc_queued
, 0,
5940 "Tx AC3 descriptors queued");
5942 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5943 "tx_ac3_data_queued", CTLFLAG_RD
, &sc
->tx_ring
[3].data_queued
, 0,
5944 "Tx AC3 data queued");
5946 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5947 "tx_ac2_desc_queued", CTLFLAG_RD
, &sc
->tx_ring
[2].desc_queued
, 0,
5948 "Tx AC2 descriptors queued");
5950 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5951 "tx_ac2_data_queued", CTLFLAG_RD
, &sc
->tx_ring
[2].data_queued
, 0,
5952 "Tx AC2 data queued");
5954 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5955 "tx_ac1_desc_queued", CTLFLAG_RD
, &sc
->tx_ring
[1].desc_queued
, 0,
5956 "Tx AC1 descriptors queued");
5958 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5959 "tx_ac1_data_queued", CTLFLAG_RD
, &sc
->tx_ring
[1].data_queued
, 0,
5960 "Tx AC1 data queued");
5962 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5963 "tx_ac0_desc_queued", CTLFLAG_RD
, &sc
->tx_ring
[0].desc_queued
, 0,
5964 "Tx AC0 descriptors queued");
5966 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5967 "tx_ac0_data_queued", CTLFLAG_RD
, &sc
->tx_ring
[0].data_queued
, 0,
5968 "Tx AC0 data queued");
5970 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5971 "tx_mgmt_data_queue_full", CTLFLAG_RD
, &sc
->tx_data_queue_full
[5], 0,
5972 "Tx MGMT data queue full");
5974 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5975 "tx_hcca_data_queue_full", CTLFLAG_RD
, &sc
->tx_data_queue_full
[4], 0,
5976 "Tx HCCA data queue full");
5978 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5979 "tx_ac3_data_queue_full", CTLFLAG_RD
, &sc
->tx_data_queue_full
[3], 0,
5980 "Tx AC3 data queue full");
5982 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5983 "tx_ac2_data_queue_full", CTLFLAG_RD
, &sc
->tx_data_queue_full
[2], 0,
5984 "Tx AC2 data queue full");
5986 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5987 "tx_ac1_data_queue_full", CTLFLAG_RD
, &sc
->tx_data_queue_full
[1], 0,
5988 "Tx AC1 data queue full");
5990 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5991 "tx_ac0_data_queue_full", CTLFLAG_RD
, &sc
->tx_data_queue_full
[0], 0,
5992 "Tx AC0 data queue full");
5994 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5995 "tx_watchdog_timeouts", CTLFLAG_RD
, &sc
->tx_watchdog_timeouts
, 0,
5996 "Tx watchdog timeouts");
5998 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
5999 "tx_defrag_packets", CTLFLAG_RD
, &sc
->tx_defrag_packets
, 0,
6000 "Tx defragmented packets");
6002 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6003 "no_tx_desc_avail", CTLFLAG_RD
, &sc
->no_tx_desc_avail
, 0,
6004 "no Tx descriptors available");
6006 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6007 "rx_mbuf_alloc_errors", CTLFLAG_RD
, &sc
->rx_mbuf_alloc_errors
, 0,
6008 "Rx mbuf allocation errors");
6010 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6011 "rx_mbuf_dmamap_errors", CTLFLAG_RD
, &sc
->rx_mbuf_dmamap_errors
, 0,
6012 "Rx mbuf DMA mapping errors");
6014 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6015 "tx_queue_0_not_empty", CTLFLAG_RD
, &sc
->tx_queue_not_empty
[0], 0,
6016 "Tx queue 0 not empty");
6018 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6019 "tx_queue_1_not_empty", CTLFLAG_RD
, &sc
->tx_queue_not_empty
[1], 0,
6020 "Tx queue 1 not empty");
6022 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6023 "tx_beacons", CTLFLAG_RD
, &sc
->tx_beacons
, 0,
6026 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6027 "tx_noretryok", CTLFLAG_RD
, &sc
->tx_noretryok
, 0,
6028 "Tx successfull without retries");
6030 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6031 "tx_retryok", CTLFLAG_RD
, &sc
->tx_retryok
, 0,
6032 "Tx successfull with retries");
6034 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6035 "tx_failed", CTLFLAG_RD
, &sc
->tx_failed
, 0,
6038 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6039 "tx_underflows", CTLFLAG_RD
, &sc
->tx_underflows
, 0,
6042 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6043 "tx_zerolen", CTLFLAG_RD
, &sc
->tx_zerolen
, 0,
6046 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6047 "tx_nonagg", CTLFLAG_RD
, &sc
->tx_nonagg
, 0,
6048 "Tx non-aggregated");
6050 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6051 "tx_agg", CTLFLAG_RD
, &sc
->tx_agg
, 0,
6054 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6055 "tx_ampdu", CTLFLAG_RD
, &sc
->tx_ampdu
, 0,
6058 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6059 "tx_mpdu_zero_density", CTLFLAG_RD
, &sc
->tx_mpdu_zero_density
, 0,
6060 "Tx MPDU with zero density");
6062 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6063 "rx_packets", CTLFLAG_RD
, &sc
->rx_packets
, 0,
6066 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6067 "rx_ampdu", CTLFLAG_RD
, &sc
->rx_ampdu
, 0,
6070 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6071 "rx_mpdu_zero_density", CTLFLAG_RD
, &sc
->rx_mpdu_zero_density
, 0,
6072 "Rx MPDU with zero density");
6074 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6075 "rx_amsdu", CTLFLAG_RD
, &sc
->rx_amsdu
, 0,
6078 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6079 "rx_crc_errors", CTLFLAG_RD
, &sc
->rx_crc_errors
, 0,
6082 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6083 "rx_phy_errors", CTLFLAG_RD
, &sc
->rx_phy_errors
, 0,
6086 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6087 "rx_false_ccas", CTLFLAG_RD
, &sc
->rx_false_ccas
, 0,
6090 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6091 "rx_plcp_errors", CTLFLAG_RD
, &sc
->rx_plcp_errors
, 0,
6094 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6095 "rx_dup_packets", CTLFLAG_RD
, &sc
->rx_dup_packets
, 0,
6096 "Rx duplicate packets");
6098 SYSCTL_ADD_INT(ctx
, SYSCTL_CHILDREN(stats
), OID_AUTO
,
6099 "rx_fifo_overflows", CTLFLAG_RD
, &sc
->rx_fifo_overflows
, 0,
6100 "Rx FIFO overflows");
6103 static device_method_t rt2860_dev_methods
[] =
6105 DEVMETHOD(device_probe
, rt2860_probe
),
6106 DEVMETHOD(device_attach
, rt2860_attach
),
6107 DEVMETHOD(device_detach
, rt2860_detach
),
6108 DEVMETHOD(device_shutdown
, rt2860_shutdown
),
6109 DEVMETHOD(device_suspend
, rt2860_suspend
),
6110 DEVMETHOD(device_resume
, rt2860_resume
),
6114 static driver_t rt2860_driver
=
6118 sizeof(struct rt2860_softc
)
6121 static devclass_t rt2860_dev_class
;
6123 DRIVER_MODULE(rt2860
, pci
, rt2860_driver
, rt2860_dev_class
, 0, 0);
6125 MODULE_DEPEND(rt2860
, pci
, 1, 1, 1);
6126 MODULE_DEPEND(rt2860
, wlan
, 1, 1, 1);