diff --git a/sys/dev/rtwn/if_rtwnvar.h b/sys/dev/rtwn/if_rtwnvar.h --- a/sys/dev/rtwn/if_rtwnvar.h +++ b/sys/dev/rtwn/if_rtwnvar.h @@ -133,7 +133,8 @@ */ enum { RTWN_RX_DATA, - RTWN_RX_TX_REPORT, + RTWN_RX_TX_REPORT, /* Per-packet */ + RTWN_RX_TX_REPORT2, /* Per-MACID summary */ RTWN_RX_OTHER }; @@ -348,6 +349,8 @@ int (*sc_classify_intr)(struct rtwn_softc *, void *, int); void (*sc_handle_tx_report)(struct rtwn_softc *, uint8_t *, int); + void (*sc_handle_tx_report2)(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 +552,8 @@ (((_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_report2(_sc, _buf, _len) \ + (((_sc)->sc_handle_tx_report2)((_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/pci/rtwn_pci_rx.c b/sys/dev/rtwn/pci/rtwn_pci_rx.c --- a/sys/dev/rtwn/pci/rtwn_pci_rx.c +++ b/sys/dev/rtwn/pci/rtwn_pci_rx.c @@ -236,6 +236,33 @@ #endif } +static void +rtwn_pci_tx_report2(struct rtwn_pci_softc *pc, int len) +{ + struct rtwn_softc *sc = &pc->pc_sc; + + 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); + return; + } + + RTWN_NT_LOCK(sc); + rtwn_handle_tx_report2(sc, pc->pc_rx_buf, len); + RTWN_NT_UNLOCK(sc); + +#ifdef IEEE80211_SUPPORT_SUPERG + /* + * NB: this will executed only when 'report' bit is set. + */ + if (sc->sc_tx_n_active > 0 && --sc->sc_tx_n_active <= 1) + rtwn_cmd_sleepable(sc, NULL, 0, rtwn_ff_flush_all); +#endif +} + + static void rtwn_pci_c2h_report(struct rtwn_pci_softc *pc, int len) { @@ -341,6 +368,9 @@ case RTWN_RX_TX_REPORT: rtwn_pci_tx_report(pc, len); break; + case RTWN_RX_TX_REPORT2: + rtwn_pci_tx_report2(pc, len); + break; case RTWN_RX_OTHER: rtwn_pci_c2h_report(pc, len); break; diff --git a/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c b/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c --- a/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c +++ b/sys/dev/rtwn/rtl8188e/pci/r88ee_attach.c @@ -145,6 +145,7 @@ 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_report2 = rtwn_nop_softc_uint8_int; 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 --- a/sys/dev/rtwn/rtl8188e/r88e_rx.c +++ b/sys/dev/rtwn/rtl8188e/r88e_rx.c @@ -63,8 +63,9 @@ 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_REPORT2); 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 --- a/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c +++ b/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c @@ -138,6 +138,7 @@ 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_report2 = rtwn_nop_softc_uint8_int; 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/rtl8192c/pci/r92ce_attach.c b/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c --- a/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c +++ b/sys/dev/rtwn/rtl8192c/pci/r92ce_attach.c @@ -175,6 +175,7 @@ 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_report2 = 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/usb/r92cu_attach.c b/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c --- a/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c +++ b/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c @@ -167,6 +167,7 @@ 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_report2 = 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 --- a/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c +++ b/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c @@ -116,6 +116,7 @@ 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_report2 = rtwn_nop_softc_uint8_int; 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 --- a/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c +++ b/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c @@ -205,6 +205,7 @@ 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_report2 = rtwn_nop_softc_uint8_int; 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 --- a/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c +++ b/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c @@ -190,6 +190,7 @@ 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_report2 = rtwn_nop_softc_uint8_int; 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 --- a/sys/dev/rtwn/usb/rtwn_usb_rx.c +++ b/sys/dev/rtwn/usb/rtwn_usb_rx.c @@ -326,6 +326,27 @@ rtwn_handle_tx_report(sc, buf, len); RTWN_NT_UNLOCK(sc); +#ifdef IEEE80211_SUPPORT_SUPERG + /* + * NB: this will executed only when 'report' bit is set. + */ + 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_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_report2(sc, buf, len); + RTWN_NT_UNLOCK(sc); + #ifdef IEEE80211_SUPPORT_SUPERG /* * NB: this will executed only when 'report' bit is set.