diff --git a/sys/dev/rtwn/if_rtwnvar.h b/sys/dev/rtwn/if_rtwnvar.h index d4458384dbd7..1b839a215348 100644 --- a/sys/dev/rtwn/if_rtwnvar.h +++ b/sys/dev/rtwn/if_rtwnvar.h @@ -134,6 +134,7 @@ struct rtwn_vap { enum { RTWN_RX_DATA, RTWN_RX_TX_REPORT, + RTWN_RX_TX_REPORT_PERIODIC, RTWN_RX_OTHER }; @@ -179,17 +180,18 @@ struct rtwn_softc { int sc_ratectl; uint8_t sc_detached; - uint8_t sc_flags; + uint32_t sc_flags; /* Device flags */ -#define RTWN_FLAG_CCK_HIPWR 0x01 -#define RTWN_FLAG_EXT_HDR 0x02 -#define RTWN_FLAG_CAM_FIXED 0x04 +#define RTWN_FLAG_CCK_HIPWR 0x00000001 +#define RTWN_FLAG_EXT_HDR 0x00000002 +#define RTWN_FLAG_CAM_FIXED 0x00000004 +#define RTWN_FLAG_HAS_TX_RPT 0x00000008 /* Driver state */ -#define RTWN_STARTED 0x08 -#define RTWN_RUNNING 0x10 -#define RTWN_FW_LOADED 0x20 -#define RTWN_TEMP_MEASURED 0x40 -#define RTWN_RCR_LOCKED 0x80 +#define RTWN_STARTED 0x00010000 +#define RTWN_RUNNING 0x00020000 +#define RTWN_FW_LOADED 0x00040000 +#define RTWN_TEMP_MEASURED 0x00080000 +#define RTWN_RCR_LOCKED 0x00100000 #define RTWN_CHIP_HAS_BCNQ1(_sc) \ ((_sc)->bcn_status_reg[0] != (_sc)->bcn_status_reg[1]) @@ -348,6 +350,8 @@ struct rtwn_softc { int (*sc_classify_intr)(struct rtwn_softc *, void *, int); void (*sc_handle_tx_report)(struct rtwn_softc *, uint8_t *, int); + void (*sc_handle_tx_report_periodic)(struct rtwn_softc *, + uint8_t *, int); void (*sc_handle_c2h_report)(struct rtwn_softc *, uint8_t *, int); int (*sc_check_frame)(struct rtwn_softc *, struct mbuf *); @@ -549,6 +553,8 @@ void rtwn_suspend(struct rtwn_softc *); (((_sc)->sc_classify_intr)((_sc), (_buf), (_len))) #define rtwn_handle_tx_report(_sc, _buf, _len) \ (((_sc)->sc_handle_tx_report)((_sc), (_buf), (_len))) +#define rtwn_handle_tx_report_periodic(_sc, _buf, _len) \ + (((_sc)->sc_handle_tx_report_periodic)((_sc), (_buf), (_len))) #define rtwn_handle_c2h_report(_sc, _buf, _len) \ (((_sc)->sc_handle_c2h_report)((_sc), (_buf), (_len))) #define rtwn_check_frame(_sc, _m) \ diff --git a/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c b/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c index 190a0dcd0e2b..191575417d58 100644 --- a/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c +++ b/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c @@ -145,6 +145,7 @@ r88ee_attach(struct rtwn_pci_softc *pc) sc->sc_get_rssi_ofdm = r88e_get_rssi_ofdm; sc->sc_classify_intr = r88e_classify_intr; sc->sc_handle_tx_report = r88e_ratectl_tx_complete; + sc->sc_handle_tx_report_periodic = rtwn_nop_softc_uint8_int; /* XXX TODO */ sc->sc_handle_c2h_report = r88e_handle_c2h_report; sc->sc_check_frame = rtwn_nop_int_softc_mbuf; sc->sc_rf_read = r92c_rf_read; diff --git a/sys/dev/rtwn/rtl8188e/r88e_rx.c b/sys/dev/rtwn/rtl8188e/r88e_rx.c index 4f8517f1e490..3fdfdd8eda43 100644 --- a/sys/dev/rtwn/rtl8188e/r88e_rx.c +++ b/sys/dev/rtwn/rtl8188e/r88e_rx.c @@ -63,8 +63,9 @@ r88e_classify_intr(struct rtwn_softc *sc, void *buf, int len) case R88E_RXDW3_RPT_RX: return (RTWN_RX_DATA); case R88E_RXDW3_RPT_TX1: /* per-packet Tx report */ - case R88E_RXDW3_RPT_TX2: /* periodical Tx report */ return (RTWN_RX_TX_REPORT); + case R88E_RXDW3_RPT_TX2: /* periodical Tx report */ + return (RTWN_RX_TX_REPORT_PERIODIC); case R88E_RXDW3_RPT_HIS: return (RTWN_RX_OTHER); default: /* shut up the compiler */ diff --git a/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c b/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c index 77193321bb9e..3b3f823d3531 100644 --- a/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c +++ b/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c @@ -124,7 +124,8 @@ r88eu_attach(struct rtwn_usb_softc *uc) uc->tx_agg_desc_num = 6; /* Common part. */ - sc->sc_flags = RTWN_FLAG_EXT_HDR; + sc->sc_flags = RTWN_FLAG_EXT_HDR + | RTWN_FLAG_HAS_TX_RPT; sc->sc_set_chan = r92c_set_chan; sc->sc_fill_tx_desc = r92c_fill_tx_desc; @@ -138,6 +139,7 @@ r88eu_attach(struct rtwn_usb_softc *uc) sc->sc_get_rssi_ofdm = r88e_get_rssi_ofdm; sc->sc_classify_intr = r88e_classify_intr; sc->sc_handle_tx_report = r88e_ratectl_tx_complete; + sc->sc_handle_tx_report_periodic = rtwn_nop_softc_uint8_int; /* XXX TODO */ sc->sc_handle_c2h_report = r88e_handle_c2h_report; sc->sc_check_frame = rtwn_nop_int_softc_mbuf; sc->sc_rf_read = r92c_rf_read; diff --git a/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c b/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c index f4f936493cda..21727846edcb 100644 --- a/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c +++ b/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c @@ -279,8 +279,14 @@ void r88eu_post_init(struct rtwn_softc *sc) { - /* Enable per-packet TX report. */ - rtwn_setbits_1(sc, R88E_TX_RPT_CTRL, 0, R88E_TX_RPT1_ENA); + /* Enable per-packet TX report (RPT1) and timer report (RPT2). */ + rtwn_setbits_1(sc, R88E_TX_RPT_CTRL, 0, R88E_TX_RPT1_ENA | R88E_TX_RPT2_ENA); + + /* Set Max RPT MACID */ + rtwn_write_1(sc, R88E_TX_RPT_MACID_MAX, 0x02); + + /* Enable periodic TX report; 32uS units */ + rtwn_write_2(sc, R88E_TX_RPT_TIME, 0xcdf0); /* Disable Tx if MACID is not associated. */ rtwn_write_4(sc, R88E_MACID_NO_LINK, 0xffffffff); diff --git a/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c b/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c index 423bf2af1845..dacc7a844c49 100644 --- a/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c +++ b/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c @@ -175,6 +175,7 @@ r92ce_attach(struct rtwn_pci_softc *pc) sc->sc_get_rssi_ofdm = r92c_get_rssi_ofdm; sc->sc_classify_intr = r92c_classify_intr; sc->sc_handle_tx_report = rtwn_nop_softc_uint8_int; + sc->sc_handle_tx_report_periodic = rtwn_nop_softc_uint8_int; sc->sc_handle_c2h_report = rtwn_nop_softc_uint8_int; sc->sc_check_frame = rtwn_nop_int_softc_mbuf; sc->sc_rf_read = r92c_rf_read; diff --git a/sys/dev/rtwn/rtl8192c/r92c_tx.c b/sys/dev/rtwn/rtl8192c/r92c_tx.c index 770223726f40..f7d866f77090 100644 --- a/sys/dev/rtwn/rtl8192c/r92c_tx.c +++ b/sys/dev/rtwn/rtl8192c/r92c_tx.c @@ -294,7 +294,7 @@ r92c_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni, r92c_calculate_tx_agg_window(sc, ni, tid))); } if (sc->sc_ratectl == RTWN_RATECTL_NET80211) { - txd->txdw2 |= htole32(R92C_TXDW2_CCX_RPT); +// txd->txdw2 |= htole32(R92C_TXDW2_CCX_RPT); sc->sc_tx_n_active++; #ifndef RTWN_WITHOUT_UCODE rs->rs_c2h_pending++; diff --git a/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c b/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c index 585610225193..258892df643e 100644 --- a/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c +++ b/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c @@ -167,6 +167,7 @@ r92cu_attach(struct rtwn_usb_softc *uc) sc->sc_get_rssi_ofdm = r92c_get_rssi_ofdm; sc->sc_classify_intr = r92c_classify_intr; sc->sc_handle_tx_report = rtwn_nop_softc_uint8_int; + sc->sc_handle_tx_report_periodic = rtwn_nop_softc_uint8_int; sc->sc_handle_c2h_report = rtwn_nop_softc_uint8_int; sc->sc_check_frame = rtwn_nop_int_softc_mbuf; sc->sc_rf_read = r92c_rf_read; diff --git a/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c b/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c index a0a93925358c..ac5ec45a893c 100644 --- a/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c +++ b/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c @@ -116,6 +116,7 @@ r92eu_attach(struct rtwn_usb_softc *uc) sc->sc_get_rssi_ofdm = r88e_get_rssi_ofdm; sc->sc_classify_intr = r12au_classify_intr; sc->sc_handle_tx_report = r12a_ratectl_tx_complete; + sc->sc_handle_tx_report_periodic = rtwn_nop_softc_uint8_int; /* XXX TODO */ sc->sc_handle_c2h_report = r92e_handle_c2h_report; sc->sc_check_frame = rtwn_nop_int_softc_mbuf; sc->sc_rf_read = r92e_rf_read; diff --git a/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c b/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c index 52a8e3d7ccf5..a55e5d413603 100644 --- a/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c +++ b/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c @@ -200,6 +200,7 @@ r12au_attach(struct rtwn_usb_softc *uc) sc->sc_get_rssi_ofdm = r88e_get_rssi_ofdm; sc->sc_classify_intr = r12au_classify_intr; sc->sc_handle_tx_report = r12a_ratectl_tx_complete; + sc->sc_handle_tx_report_periodic = rtwn_nop_softc_uint8_int; /* XXX TODO */ sc->sc_handle_c2h_report = r12a_handle_c2h_report; sc->sc_check_frame = r12a_check_frame_checksum; sc->sc_rf_write = r12a_rf_write; diff --git a/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c b/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c index 480b1ae36b11..4a90c6cec9c5 100644 --- a/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c +++ b/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c @@ -185,6 +185,7 @@ r21au_attach(struct rtwn_usb_softc *uc) sc->sc_get_rssi_ofdm = r88e_get_rssi_ofdm; sc->sc_classify_intr = r12au_classify_intr; sc->sc_handle_tx_report = r12a_ratectl_tx_complete; + sc->sc_handle_tx_report_periodic = rtwn_nop_softc_uint8_int; /* XXX TODO */ sc->sc_handle_c2h_report = r12a_handle_c2h_report; sc->sc_check_frame = r12a_check_frame_checksum; sc->sc_rf_read = r12a_c_cut_rf_read; diff --git a/sys/dev/rtwn/usb/rtwn_usb_rx.c b/sys/dev/rtwn/usb/rtwn_usb_rx.c index 5db967ddcc18..f9d2ec0334d5 100644 --- a/sys/dev/rtwn/usb/rtwn_usb_rx.c +++ b/sys/dev/rtwn/usb/rtwn_usb_rx.c @@ -333,6 +333,23 @@ rtwn_report_intr(struct rtwn_usb_softc *uc, struct usb_xfer *xfer, if (sc->sc_tx_n_active > 0 && --sc->sc_tx_n_active <= 1) rtwn_cmd_sleepable(sc, NULL, 0, rtwn_ff_flush_all); #endif + break; + case RTWN_RX_TX_REPORT_PERIODIC: + /* Note: for RTL8188E we need decoding from rtl8xxxu:rtl8188e_handle_ra_tx_report2() */ + if (sc->sc_ratectl != RTWN_RATECTL_NET80211) { + /* shouldn't happen */ + device_printf(sc->sc_dev, + "%s called while ratectl = %d!\n", + __func__, sc->sc_ratectl); + break; + } + + RTWN_NT_LOCK(sc); + rtwn_handle_tx_report_periodic(sc, buf, len); + RTWN_NT_UNLOCK(sc); + + /* TODO: FF flushing if the queue is empty? Can we even discover that? */ + break; case RTWN_RX_OTHER: rtwn_handle_c2h_report(sc, buf, len);