qcacld-3.0: Data path changes to use converged APIs (Part 3)

Changes to register a per vdev tx callback function.

Register a per-vdev transmit function during vdev registration.
The OS interface (HDD) adapter stores this transmit function and
invokes it to transmit data frames.

Change-Id: I1dfe6f58d1d26069dadc2d719fff242c29071bad
CRs-Fixed: 994638
diff --git a/core/dp/ol/inc/ol_txrx_osif_api.h b/core/dp/ol/inc/ol_txrx_osif_api.h
index b2f707a..0d2136c 100644
--- a/core/dp/ol/inc/ol_txrx_osif_api.h
+++ b/core/dp/ol/inc/ol_txrx_osif_api.h
@@ -128,8 +128,7 @@
 				    int max_seg_payload_bytes,
 				    qdf_nbuf_t jumbo_tcp_frame);
 
-qdf_nbuf_t ol_tx_send_data_frame(uint8_t sta_id, qdf_nbuf_t skb,
-									  uint8_t proto_type);
+qdf_nbuf_t ol_tx_data(ol_txrx_vdev_handle data_vdev, qdf_nbuf_t skb);
 
 #ifdef IPA_OFFLOAD
 qdf_nbuf_t ol_tx_send_ipa_data_frame(void *vdev,
diff --git a/core/dp/txrx/ol_tx.c b/core/dp/txrx/ol_tx.c
index 0956af1..eb9cf21 100644
--- a/core/dp/txrx/ol_tx.c
+++ b/core/dp/txrx/ol_tx.c
@@ -132,19 +132,16 @@
 #endif
 
 /**
- * ol_tx_send_data_frame() - send data frame
- * @sta_id: sta id
+ * ol_tx_data() - send data frame
+ * @vdev: virtual device handle
  * @skb: skb
- * @proto_type: proto type
  *
  * Return: skb/NULL for success
  */
-qdf_nbuf_t ol_tx_send_data_frame(uint8_t sta_id, qdf_nbuf_t skb,
-				 uint8_t proto_type)
+qdf_nbuf_t ol_tx_data(ol_txrx_vdev_handle vdev, qdf_nbuf_t skb)
 {
 	void *qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
-	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
-	struct ol_txrx_peer_t *peer;
+	struct ol_txrx_pdev_t *pdev = vdev->pdev;
 	qdf_nbuf_t ret;
 	QDF_STATUS status;
 
@@ -159,25 +156,6 @@
 		return skb;
 	}
 
-	if (sta_id >= WLAN_MAX_STA_COUNT) {
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_WARN,
-			"%s:Invalid sta id", __func__);
-		return skb;
-	}
-
-	peer = ol_txrx_peer_find_by_local_id(pdev, sta_id);
-	if (!peer) {
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_WARN,
-			"%s:Invalid peer", __func__);
-		return skb;
-	}
-
-	if (peer->state < ol_txrx_peer_state_conn) {
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_WARN,
-			"%s: station to be yet registered..dropping pkt", __func__);
-		return skb;
-	}
-
 	status = qdf_nbuf_map_single(qdf_ctx, skb, QDF_DMA_TO_DEVICE);
 	if (qdf_unlikely(status != QDF_STATUS_SUCCESS)) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_WARN,
@@ -185,8 +163,6 @@
 		return skb;
 	}
 
-	qdf_nbuf_trace_set_proto_type(skb, proto_type);
-
 	if ((ol_cfg_is_ip_tcp_udp_checksum_offload_enabled(pdev->ctrl_pdev))
 		&& (qdf_nbuf_get_protocol(skb) == htons(ETH_P_IP))
 		&& (qdf_nbuf_get_ip_summed(skb) == CHECKSUM_PARTIAL))
@@ -194,7 +170,7 @@
 
 	/* Terminate the (single-element) list of tx frames */
 	qdf_nbuf_set_next(skb, NULL);
-	ret = OL_TX_LL(peer->vdev, skb);
+	ret = OL_TX_LL(vdev, skb);
 	if (ret) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_WARN,
 			"%s: Failed to tx", __func__);
diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c
index 63e4aa8..7719a0f 100644
--- a/core/dp/txrx/ol_txrx.c
+++ b/core/dp/txrx/ol_txrx.c
@@ -1198,7 +1198,9 @@
 				struct ol_txrx_ops *txrx_ops)
 {
 	vdev->osif_dev = osif_vdev;
+
 	vdev->rx = txrx_ops->rx.rx;
+	txrx_ops->tx.tx = ol_tx_data;
 }
 
 /**
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index d8d0e4c..8cee414 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -1021,6 +1021,7 @@
 		 queue_oper_history[WLAN_HDD_MAX_HISTORY_ENTRY];
 	struct hdd_netif_queue_stats queue_oper_stats[WLAN_REASON_TYPE_MAX];
 	struct hdd_lro_s lro_info;
+	ol_txrx_tx_fp tx_fn;
 };
 
 #define WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.station)
diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c
index d3606b5..6093ed5 100644
--- a/core/hdd/src/wlan_hdd_assoc.c
+++ b/core/hdd/src/wlan_hdd_assoc.c
@@ -1308,6 +1308,7 @@
 	ol_txrx_vdev_register(
 		 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
 		 pAdapter, &txrx_ops);
+	pAdapter->tx_fn = txrx_ops.tx.tx;
 
 	if (!pRoamInfo->fAuthRequired) {
 		/*
@@ -2872,6 +2873,7 @@
 	ol_txrx_vdev_register(
 		 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
 		 pAdapter, &txrx_ops);
+	pAdapter->tx_fn = txrx_ops.tx.tx;
 
 	return qdf_status;
 }
diff --git a/core/hdd/src/wlan_hdd_ocb.c b/core/hdd/src/wlan_hdd_ocb.c
index fcca731..f7c240e 100644
--- a/core/hdd/src/wlan_hdd_ocb.c
+++ b/core/hdd/src/wlan_hdd_ocb.c
@@ -275,6 +275,7 @@
 	ol_txrx_vdev_register(
 		 ol_txrx_get_vdev_from_vdev_id(adapter->sessionId),
 		 adapter, &txrx_ops);
+	adapter->tx_fn = txrx_ops.tx.tx;
 
 	if (pHddStaCtx->conn_info.staId[0] != 0 &&
 	     pHddStaCtx->conn_info.staId[0] != peer_id) {
diff --git a/core/hdd/src/wlan_hdd_softap_tx_rx.c b/core/hdd/src/wlan_hdd_softap_tx_rx.c
index 09b862d..fb4739f 100644
--- a/core/hdd/src/wlan_hdd_softap_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_softap_tx_rx.c
@@ -171,8 +171,8 @@
 	hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
 	struct qdf_mac_addr *pDestMacAddress;
 	uint8_t STAId;
-	uint8_t proto_type = 0;
 #ifdef QCA_PKT_PROTO_TRACE
+	uint8_t proto_type = 0;
 	hdd_context_t *hddCtxt = (hdd_context_t *) pAdapter->pHddCtx;
 #endif /* QCA_PKT_PROTO_TRACE */
 
@@ -199,6 +199,16 @@
 		goto drop_pkt;
 	}
 
+	/*
+	* If a transmit function is not registered, drop packet
+	*/
+	if (!pAdapter->tx_fn) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
+			 "%s: TX function not registered by the data path",
+			 __func__);
+		goto drop_pkt;
+	}
+
 	pDestMacAddress = (struct qdf_mac_addr *) skb->data;
 
 	if (qdf_is_macaddr_broadcast(pDestMacAddress) ||
@@ -313,8 +323,11 @@
 				(uint8_t *)&skb->data[QDF_DP_TRACE_RECORD_SIZE],
 				(qdf_nbuf_len(skb)-QDF_DP_TRACE_RECORD_SIZE)));
 
-	if (ol_tx_send_data_frame(STAId, skb,
-							  proto_type) != NULL) {
+#ifdef QCA_PKT_PROTO_TRACE
+	qdf_nbuf_trace_set_proto_type(skb, proto_type);
+#endif
+	if (pAdapter->tx_fn(ol_txrx_get_vdev_by_sta_id(STAId),
+		 (qdf_nbuf_t) skb) != NULL) {
 		QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_WARN,
 			  "%s: Failed to send packet to txrx for staid:%d",
 			  __func__, STAId);
@@ -706,6 +719,7 @@
 	ol_txrx_vdev_register(
 		 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
 		 pAdapter, &txrx_ops);
+	pAdapter->tx_fn = txrx_ops.tx.tx;
 
 	/* if ( WPA ), tell TL to go to 'connected' and after keys come to the
 	 * driver then go to 'authenticated'.  For all other authentication
diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c
index 492a72b..9a29448 100644
--- a/core/hdd/src/wlan_hdd_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_tx_rx.c
@@ -299,8 +299,8 @@
 	bool granted;
 	uint8_t STAId = WLAN_MAX_STA_COUNT;
 	hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
-	uint8_t proto_type = 0;
 #ifdef QCA_PKT_PROTO_TRACE
+	uint8_t proto_type = 0;
 	hdd_context_t *hddCtxt = WLAN_HDD_GET_CTX(pAdapter);
 #endif /* QCA_PKT_PROTO_TRACE */
 
@@ -489,8 +489,32 @@
 				(uint8_t *)&skb->data[QDF_DP_TRACE_RECORD_SIZE],
 				(qdf_nbuf_len(skb)-QDF_DP_TRACE_RECORD_SIZE)));
 
-	if (ol_tx_send_data_frame(STAId, (qdf_nbuf_t) skb,
-							  proto_type) != NULL) {
+	/* Check if station is connected */
+	if (ol_txrx_peer_state_conn ==
+		 pAdapter->aStaInfo[STAId].tlSTAState) {
+			QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+				 QDF_TRACE_LEVEL_WARN,
+				 "%s: station is not connected..dropping pkt",
+				 __func__);
+				goto drop_pkt;
+	}
+
+#ifdef QCA_PKT_PROTO_TRACE
+	qdf_nbuf_trace_set_proto_type(skb, proto_type);
+#endif
+
+	/*
+	* If a transmit function is not registered, drop packet
+	*/
+	if (!pAdapter->tx_fn) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
+			 "%s: TX function not registered by the data path",
+			 __func__);
+		goto drop_pkt;
+	}
+
+	if (pAdapter->tx_fn(ol_txrx_get_vdev_by_sta_id(STAId),
+		 (qdf_nbuf_t) skb) != NULL) {
 		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_WARN,
 			  "%s: Failed to send packet to txrx for staid:%d",
 			  __func__, STAId);