Browse Source

qcacmn: Add ol_txrx_completion_fp in ol_txrx_ops

Add ol_txrx_completion_fp in ol_txrx_ops to provide support for
callback during TX completion.

Change-Id: I7af478636badd8f8562460cefaf5db56633df8e9
CRs-Fixed: 2253569
Yun Park 6 years ago
parent
commit
aadee8cc5a
4 changed files with 107 additions and 2 deletions
  1. 9 0
      dp/inc/cdp_txrx_cmn_struct.h
  2. 91 1
      dp/wifi3.0/dp_tx.c
  3. 4 0
      dp/wifi3.0/dp_types.h
  4. 3 1
      qdf/linux/src/i_qdf_nbuf.h

+ 9 - 0
dp/inc/cdp_txrx_cmn_struct.h

@@ -436,6 +436,14 @@ typedef qdf_nbuf_t (*ol_txrx_tx_exc_fp)(void *data_vdev,
 					struct cdp_tx_exception_metadata
 						*tx_exc_metadata);
 
+/**
+ * ol_txrx_completion_fp - top-level transmit function
+ * for tx completion
+ * @skb: skb data
+ * @osif_dev: the virtual device's OS shim object
+ */
+typedef void (*ol_txrx_completion_fp)(qdf_nbuf_t skb,
+				      void *osif_dev);
 /**
  * ol_txrx_tx_flow_control_fp - tx flow control notification
  * function from txrx to OS shim
@@ -593,6 +601,7 @@ struct ol_txrx_ops {
 		ol_txrx_tx_fp         tx;
 		ol_txrx_tx_exc_fp     tx_exception;
 		ol_txrx_tx_free_ext_fp tx_free_ext;
+		ol_txrx_completion_fp tx_comp;
 	} tx;
 
 	/* rx function pointers - specified by OS shim, stored by txrx */

+ 91 - 1
dp/wifi3.0/dp_tx.c

@@ -1847,8 +1847,9 @@ qdf_nbuf_t dp_tx_send_mesh(void *vap_dev, qdf_nbuf_t nbuf)
 	if (nbuf_clone) {
 		if (!dp_tx_send(vap_dev, nbuf_clone)) {
 			DP_STATS_INC(vdev, tx_i.mesh.exception_fw, 1);
-		} else
+		} else {
 			qdf_nbuf_free(nbuf_clone);
+		}
 	}
 
 	if (no_enc_frame)
@@ -2624,6 +2625,91 @@ static void dp_tx_update_peer_stats(struct dp_peer *peer,
 	}
 }
 
+#ifdef QCA_LL_TX_FLOW_CONTROL_V2
+/**
+ * dp_tx_flow_pool_lock() - take flow pool lock
+ * @soc: core txrx main context
+ * @tx_desc: tx desc
+ *
+ * Return: None
+ */
+static inline
+void dp_tx_flow_pool_lock(struct dp_soc *soc,
+			  struct dp_tx_desc_s *tx_desc)
+{
+	struct dp_tx_desc_pool_s *pool;
+	uint8_t desc_pool_id;
+
+	desc_pool_id = tx_desc->pool_id;
+	pool = &soc->tx_desc[desc_pool_id];
+
+	qdf_spin_lock_bh(&pool->flow_pool_lock);
+}
+
+/**
+ * dp_tx_flow_pool_unlock() - release flow pool lock
+ * @soc: core txrx main context
+ * @tx_desc: tx desc
+ *
+ * Return: None
+ */
+static inline
+void dp_tx_flow_pool_unlock(struct dp_soc *soc,
+			    struct dp_tx_desc_s *tx_desc)
+{
+	struct dp_tx_desc_pool_s *pool;
+	uint8_t desc_pool_id;
+
+	desc_pool_id = tx_desc->pool_id;
+	pool = &soc->tx_desc[desc_pool_id];
+
+	qdf_spin_unlock_bh(&pool->flow_pool_lock);
+}
+#else
+static inline
+void dp_tx_flow_pool_lock(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc)
+{
+}
+
+static inline
+void dp_tx_flow_pool_unlock(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc)
+{
+}
+#endif
+
+/**
+ * dp_tx_notify_completion() - Notify tx completion for this desc
+ * @soc: core txrx main context
+ * @tx_desc: tx desc
+ * @netbuf:  buffer
+ *
+ * Return: none
+ */
+static inline void dp_tx_notify_completion(struct dp_soc *soc,
+					   struct dp_tx_desc_s *tx_desc,
+					   qdf_nbuf_t netbuf)
+{
+	void *osif_dev;
+	ol_txrx_completion_fp tx_compl_cbk = NULL;
+
+	qdf_assert(tx_desc);
+
+	dp_tx_flow_pool_lock(soc, tx_desc);
+
+	if (!tx_desc->vdev ||
+	    !tx_desc->vdev->osif_vdev) {
+		dp_tx_flow_pool_unlock(soc, tx_desc);
+		return;
+	}
+
+	osif_dev = tx_desc->vdev->osif_vdev;
+	tx_compl_cbk = tx_desc->vdev->tx_comp;
+	dp_tx_flow_pool_unlock(soc, tx_desc);
+
+	if (tx_compl_cbk)
+		tx_compl_cbk(netbuf, osif_dev);
+}
+
 /**
  * dp_tx_comp_process_tx_status() - Parse and Dump Tx completion status info
  * @tx_desc: software descriptor head pointer
@@ -2737,6 +2823,10 @@ static void dp_tx_comp_process_desc(struct dp_soc *soc,
 		peer = dp_peer_find_by_id(soc, ts.peer_id);
 		length = qdf_nbuf_len(desc->nbuf);
 
+		/* check tx completion notification */
+		if (QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_NOTIFY_COMP(desc->nbuf))
+			dp_tx_notify_completion(soc, desc, desc->nbuf);
+
 		dp_tx_comp_process_tx_status(desc, length);
 
 		/*currently m_copy/tx_capture is not supported for scatter gather packets*/

+ 4 - 0
dp/wifi3.0/dp_types.h

@@ -1216,6 +1216,10 @@ struct dp_vdev {
 	ol_txrx_rx_mon_fp osif_rx_mon;
 
 	ol_txrx_mcast_me_fp me_convert;
+
+	/* completion function used by this vdev*/
+	ol_txrx_completion_fp tx_comp;
+
 	/* deferred vdev deletion state */
 	struct {
 		/* VDEV delete pending */

+ 3 - 1
qdf/linux/src/i_qdf_nbuf.h

@@ -245,7 +245,7 @@ struct qdf_nbuf_cb {
 						flag_chfrag_cont:1,
 						flag_chfrag_end:1,
 						flag_ext_header:1,
-						reserved:1;
+						flag_notify_comp:1;
 				} bits;
 				uint8_t u8;
 			} flags;
@@ -348,6 +348,8 @@ QDF_COMPILE_TIME_ASSERT(qdf_nbuf_cb_size,
 		((skb)->cb))->u.tx.flags.bits.flag_nbuf)
 #define QDF_NBUF_CB_TX_NUM_EXTRA_FRAGS(skb) \
 	(((struct qdf_nbuf_cb *)((skb)->cb))->u.tx.flags.bits.num)
+#define QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_NOTIFY_COMP(skb) \
+	(((struct qdf_nbuf_cb *)((skb)->cb))->u.tx.flags.bits.flag_notify_comp)
 #define QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_CHFRAG_START(skb) \
 	(((struct qdf_nbuf_cb *) \
 	((skb)->cb))->u.tx.flags.bits.flag_chfrag_start)