implement qwx_dp_tx_process_htt_tx_complete()
authorstsp <stsp@openbsd.org>
Thu, 8 Feb 2024 14:35:07 +0000 (14:35 +0000)
committerstsp <stsp@openbsd.org>
Thu, 8 Feb 2024 14:35:07 +0000 (14:35 +0000)
sys/dev/ic/qwx.c
sys/dev/ic/qwxvar.h

index d9f94e5..1861b81 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: qwx.c,v 1.26 2024/02/08 14:33:40 stsp Exp $   */
+/*     $OpenBSD: qwx.c,v 1.27 2024/02/08 14:35:07 stsp Exp $   */
 
 /*
  * Copyright 2023 Stefan Sperling <stsp@openbsd.org>
@@ -14786,11 +14786,77 @@ qwx_dp_tx_status_parse(struct qwx_softc *sc, struct hal_wbm_release_ring *desc,
                ts->rate_stats = 0;
 }
 
+void
+qwx_dp_tx_free_txbuf(struct qwx_softc *sc, int msdu_id,
+    struct dp_tx_ring *tx_ring)
+{
+       struct qwx_tx_data *tx_data;
+
+       if (msdu_id >= sc->hw_params.tx_ring_size)
+               return;
+
+       tx_data = &tx_ring->data[msdu_id];
+
+       bus_dmamap_unload(sc->sc_dmat, tx_data->map);
+       m_freem(tx_data->m);
+       tx_data->m = NULL;
+
+       if (tx_ring->queued > 0)
+               tx_ring->queued--;
+}
+
+void
+qwx_dp_tx_htt_tx_complete_buf(struct qwx_softc *sc, struct dp_tx_ring *tx_ring,
+    struct qwx_dp_htt_wbm_tx_status *ts)
+{
+       /* Not using Tx status info for now. Just free the buffer. */
+       qwx_dp_tx_free_txbuf(sc, ts->msdu_id, tx_ring);
+}
+
 void
 qwx_dp_tx_process_htt_tx_complete(struct qwx_softc *sc, void *desc,
     uint8_t mac_id, uint32_t msdu_id, struct dp_tx_ring *tx_ring)
 {
-       printf("%s: not implemented\n", __func__);
+       struct htt_tx_wbm_completion *status_desc;
+       struct qwx_dp_htt_wbm_tx_status ts = {0};
+       enum hal_wbm_htt_tx_comp_status wbm_status;
+
+       status_desc = desc + HTT_TX_WBM_COMP_STATUS_OFFSET;
+
+       wbm_status = FIELD_GET(HTT_TX_WBM_COMP_INFO0_STATUS,
+           status_desc->info0);
+
+       switch (wbm_status) {
+       case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK:
+       case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP:
+       case HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL:
+               ts.acked = (wbm_status == HAL_WBM_REL_HTT_TX_COMP_STATUS_OK);
+               ts.msdu_id = msdu_id;
+               ts.ack_rssi = FIELD_GET(HTT_TX_WBM_COMP_INFO1_ACK_RSSI,
+                   status_desc->info1);
+
+               if (FIELD_GET(HTT_TX_WBM_COMP_INFO2_VALID, status_desc->info2))
+                       ts.peer_id = FIELD_GET(HTT_TX_WBM_COMP_INFO2_SW_PEER_ID,
+                           status_desc->info2);
+               else
+                       ts.peer_id = HTT_INVALID_PEER_ID;
+
+               qwx_dp_tx_htt_tx_complete_buf(sc, tx_ring, &ts);
+               break;
+       case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ:
+       case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT:
+               qwx_dp_tx_free_txbuf(sc, msdu_id, tx_ring);
+               break;
+       case HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY:
+               /* This event is to be handled only when the driver decides to
+                * use WDS offload functionality.
+                */
+               break;
+       default:
+               printf("%s: Unknown htt tx status %d\n",
+                   sc->sc_dev.dv_xname, wbm_status);
+               break;
+       }
 }
 
 void
index bbf99a3..4fdd652 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: qwxvar.h,v 1.13 2024/02/08 11:20:29 stsp Exp $        */
+/*     $OpenBSD: qwxvar.h,v 1.14 2024/02/08 14:35:07 stsp Exp $        */
 
 /*
  * Copyright (c) 2018-2019 The Linux Foundation.
@@ -842,6 +842,13 @@ void qwx_dp_htt_htc_t2h_msg_handler(struct qwx_softc *, struct mbuf *);
 
 struct qwx_dp;
 
+struct qwx_dp_htt_wbm_tx_status {
+       uint32_t msdu_id;
+       int acked;
+       int ack_rssi;
+       uint16_t peer_id;
+};
+
 #define DP_NUM_CLIENTS_MAX 64
 #define DP_AVG_TIDS_PER_CLIENT 2
 #define DP_NUM_TIDS_MAX (DP_NUM_CLIENTS_MAX * DP_AVG_TIDS_PER_CLIENT)