Sfoglia il codice sorgente

qcacld-3.0: Add Tx comp cbk for DHCP ACK SKB CB

During hard_start_xmit, set a flag in SKB CB to indicate DHCP ACK
packet, and a callback gets called on TX completion.

Change-Id: I4e11b2c35b4747c7af35a387b404e3ccb1e8e8e4
CRs-Fixed: 2253557
Alok Kumar 6 anni fa
parent
commit
4696fb0272

+ 35 - 0
core/dp/txrx/ol_tx_send.c

@@ -611,6 +611,37 @@ static void ol_tx_update_ack_count(struct ol_tx_desc_t *tx_desc,
 	else
 		++tx_desc->vdev->txrx_stats.txack_failed;
 }
+
+/**
+ * ol_tx_notify_completion() - Notify tx completion for this desc
+ * @tx_desc: tx desc
+ * @netbuf:  buffer
+ *
+ * Return: none
+ */
+static void ol_tx_notify_completion(struct ol_tx_desc_t *tx_desc,
+				    qdf_nbuf_t netbuf)
+{
+	void *osif_dev;
+	ol_txrx_completion_fp tx_compl_cbk = NULL;
+
+	qdf_assert(tx_desc);
+
+	ol_tx_flow_pool_lock(tx_desc);
+
+	if (!tx_desc->vdev ||
+	    !tx_desc->vdev->osif_dev) {
+		ol_tx_flow_pool_unlock(tx_desc);
+		return;
+	}
+	osif_dev = tx_desc->vdev->osif_dev;
+	tx_compl_cbk = tx_desc->vdev->tx_comp;
+	ol_tx_flow_pool_unlock(tx_desc);
+
+	if (tx_compl_cbk)
+		tx_compl_cbk(netbuf, osif_dev);
+}
+
 /**
  * ol_tx_update_connectivity_stats() - update connectivity stats
  * @tx_desc: tx desc
@@ -750,6 +781,10 @@ ol_tx_completion_handler(ol_txrx_pdev_handle pdev,
 				ol_tx_update_arp_stats(tx_desc, netbuf, status);
 		}
 
+		/* check tx completion notification */
+		if (QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_NOTIFY_COMP(netbuf))
+			ol_tx_notify_completion(tx_desc, netbuf);
+
 		/* track connectivity stats */
 		ol_tx_update_connectivity_stats(tx_desc, netbuf,
 						status);

+ 1 - 0
core/dp/txrx/ol_txrx.c

@@ -2448,6 +2448,7 @@ static void ol_txrx_vdev_register(struct cdp_vdev *pvdev,
 	vdev->osif_dev = osif_vdev;
 	vdev->rx = txrx_ops->rx.rx;
 	vdev->stats_rx = txrx_ops->rx.stats_rx;
+	vdev->tx_comp = txrx_ops->tx.tx_comp;
 	txrx_ops->tx.tx = ol_tx_data;
 }
 

+ 3 - 0
core/dp/txrx/ol_txrx_types.h

@@ -1047,6 +1047,9 @@ struct ol_txrx_vdev_t {
 		uint32_t txack_failed;
 	} txrx_stats;
 
+	/* completion function used by this vdev*/
+	ol_txrx_completion_fp tx_comp;
+
 	struct {
 		/*
 		 * If the vdev object couldn't be deleted immediately because

+ 15 - 3
core/hdd/inc/wlan_hdd_softap_tx_rx.h

@@ -58,6 +58,8 @@ QDF_STATUS hdd_softap_init_tx_rx_sta(struct hdd_adapter *adapter,
 QDF_STATUS hdd_softap_deinit_tx_rx_sta(struct hdd_adapter *adapter,
 				       uint8_t sta_id);
 
+void hdd_softap_notify_tx_compl_cbk(struct sk_buff *skb, void *context);
+
 QDF_STATUS hdd_softap_rx_packet_cbk(void *context, qdf_nbuf_t rxBufChain);
 #ifdef IPA_OFFLOAD
 QDF_STATUS hdd_softap_rx_mul_packet_cbk(void *cds_context,
@@ -121,6 +123,16 @@ void hdd_softap_tx_resume_cb(void *adapter_context, bool tx_resume)
 int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
 			     uint8_t sta_id, uint16_t type);
 
+/**
+ * hdd_softap_notify_dhcp_ind() - Notify SAP for DHCP indication for tx desc
+ * @context: pointer to HDD context
+ * @netbuf: pointer to OS packet (sk_buff)
+ *
+ * Return: None
+ */
+void hdd_softap_notify_dhcp_ind(void *context,
+				struct sk_buff *netbuf);
+
 /**
  * hdd_inspect_dhcp_packet() -  Inspect DHCP packet
  * @adapter: pointer to hdd adapter
@@ -131,8 +143,8 @@ int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
  * Return: error number
  */
 int hdd_inspect_dhcp_packet(struct hdd_adapter *adapter,
-			 uint8_t sta_id,
-			 struct sk_buff *skb,
-			 enum qdf_proto_dir dir);
+			    uint8_t sta_id,
+			    struct sk_buff *skb,
+			    enum qdf_proto_dir dir);
 
 #endif /* end #if !defined(WLAN_HDD_SOFTAP_TX_RX_H) */

+ 102 - 31
core/hdd/src/wlan_hdd_softap_tx_rx.c

@@ -304,6 +304,46 @@ int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
 	return 0;
 }
 
+void hdd_softap_notify_dhcp_ind(void *context, struct sk_buff *netbuf)
+{
+	struct hdd_ap_ctx *hdd_ap_ctx;
+	struct qdf_mac_addr *dest_mac_addr;
+	uint8_t sta_id;
+	struct hdd_adapter *adapter = context;
+
+	if (hdd_validate_adapter(adapter)) {
+		hdd_err("Invalid adapter");
+		return;
+	}
+
+	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
+	if (!hdd_ap_ctx) {
+		hdd_err("HDD sap context is NULL");
+		return;
+	}
+
+	dest_mac_addr = (struct qdf_mac_addr *)netbuf->data;
+
+	if (QDF_NBUF_CB_GET_IS_BCAST(netbuf) ||
+	    QDF_NBUF_CB_GET_IS_MCAST(netbuf)) {
+		/* The BC/MC station ID is assigned during BSS
+		 * starting phase.  SAP will return the station ID
+		 * used for BC/MC traffic.
+		 */
+		sta_id = hdd_ap_ctx->broadcast_sta_id;
+	} else {
+		if (QDF_STATUS_SUCCESS !=
+		    hdd_softap_get_sta_id(adapter,
+					  dest_mac_addr, &sta_id)) {
+			QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
+				  QDF_TRACE_LEVEL_INFO_HIGH,
+				  "%s: Failed to find right station", __func__);
+			return;
+		}
+	}
+	hdd_post_dhcp_ind(adapter, sta_id, WMA_DHCP_STOP_IND);
+}
+
 /**
  * hdd_inspect_dhcp_packet() - Inspect DHCP packet
  * @adapter: pointer to hdd adapter
@@ -333,15 +373,18 @@ int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
  * Return: error number
  */
 int hdd_inspect_dhcp_packet(struct hdd_adapter *adapter,
-				       uint8_t sta_id,
-				       struct sk_buff *skb,
-				       enum qdf_proto_dir dir)
+			    uint8_t sta_id,
+			    struct sk_buff *skb,
+			    enum qdf_proto_dir dir)
 {
 	enum qdf_proto_subtype subtype = QDF_PROTO_INVALID;
 	struct hdd_station_info *hdd_sta_info;
 	int errno = 0;
 
-	if ((adapter->device_mode == QDF_SAP_MODE) &&
+	hdd_debug("sta_id=%d, dir=%d", sta_id, dir);
+
+	if (((adapter->device_mode == QDF_SAP_MODE) ||
+	     (adapter->device_mode == QDF_P2P_GO_MODE)) &&
 	    ((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_DHCP ==
 				QDF_NBUF_CB_GET_PACKET_TYPE(skb)) ||
 	     (dir == QDF_RX && qdf_nbuf_is_ipv4_dhcp_pkt(skb) == true))) {
@@ -382,9 +425,11 @@ int hdd_inspect_dhcp_packet(struct hdd_adapter *adapter,
 		case QDF_PROTO_DHCP_NACK:
 			hdd_sta_info->dhcp_phase = DHCP_PHASE_ACK;
 			if (hdd_sta_info->dhcp_nego_status ==
-				DHCP_NEGO_IN_PROGRESS)
-				errno = hdd_post_dhcp_ind(adapter, sta_id,
-							   WMA_DHCP_STOP_IND);
+				DHCP_NEGO_IN_PROGRESS) {
+				hdd_debug("Setting NOTIFY_COMP Flag");
+				QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_NOTIFY_COMP(skb)
+									= 1;
+			}
 			hdd_sta_info->dhcp_nego_status = DHCP_NEGO_STOP;
 			break;
 		default:
@@ -418,8 +463,8 @@ static netdev_tx_t __hdd_softap_hard_start_xmit(struct sk_buff *skb,
 	sme_ac_enum_type ac = SME_AC_BE;
 	struct hdd_adapter *adapter = (struct hdd_adapter *) netdev_priv(dev);
 	struct hdd_ap_ctx *ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
-	struct qdf_mac_addr *pDestMacAddress;
-	uint8_t STAId;
+	struct qdf_mac_addr *dest_mac_addr;
+	uint8_t sta_id;
 	uint32_t num_seg;
 
 	++adapter->hdd_stats.tx_rx_stats.tx_called;
@@ -460,7 +505,7 @@ static netdev_tx_t __hdd_softap_hard_start_xmit(struct sk_buff *skb,
 
 	wlan_hdd_classify_pkt(skb);
 
-	pDestMacAddress = (struct qdf_mac_addr *) skb->data;
+	dest_mac_addr = (struct qdf_mac_addr *)skb->data;
 
 	if (QDF_NBUF_CB_GET_IS_BCAST(skb) ||
 	    QDF_NBUF_CB_GET_IS_MCAST(skb)) {
@@ -468,47 +513,47 @@ static netdev_tx_t __hdd_softap_hard_start_xmit(struct sk_buff *skb,
 		 * starting phase.  SAP will return the station ID
 		 * used for BC/MC traffic.
 		 */
-		STAId = ap_ctx->broadcast_sta_id;
+		sta_id = ap_ctx->broadcast_sta_id;
 	} else {
 		if (QDF_STATUS_SUCCESS !=
 			 hdd_softap_get_sta_id(adapter,
-				 pDestMacAddress, &STAId)) {
+				 dest_mac_addr, &sta_id)) {
 			QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
 				  QDF_TRACE_LEVEL_INFO_HIGH,
 				  "%s: Failed to find right station", __func__);
 			goto drop_pkt;
 		}
 
-		if (STAId >= WLAN_MAX_STA_COUNT) {
+		if (sta_id >= WLAN_MAX_STA_COUNT) {
 			QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
 				  QDF_TRACE_LEVEL_INFO_HIGH,
 				  "%s: Failed to find right station", __func__);
 			goto drop_pkt;
-		} else if (false == adapter->sta_info[STAId].in_use) {
+		} else if (!adapter->sta_info[sta_id].in_use) {
 			QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
 				  QDF_TRACE_LEVEL_INFO_HIGH,
 				  "%s: STA %d is unregistered", __func__,
-				  STAId);
+				  sta_id);
 			goto drop_pkt;
-		} else if (true == adapter->sta_info[STAId].
+		} else if (adapter->sta_info[sta_id].
 							is_deauth_in_progress) {
 			QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
 				  QDF_TRACE_LEVEL_INFO_HIGH,
 				  "%s: STA %d deauth in progress", __func__,
-				  STAId);
+				  sta_id);
 			goto drop_pkt;
 		}
 
 		if ((OL_TXRX_PEER_STATE_CONN !=
-		     adapter->sta_info[STAId].peer_state)
+		     adapter->sta_info[sta_id].peer_state)
 		    && (OL_TXRX_PEER_STATE_AUTH !=
-			adapter->sta_info[STAId].peer_state)) {
+			adapter->sta_info[sta_id].peer_state)) {
 			QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
 				  QDF_TRACE_LEVEL_INFO_HIGH,
 				  "%s: Station not connected yet", __func__);
 			goto drop_pkt;
 		} else if (OL_TXRX_PEER_STATE_CONN ==
-			   adapter->sta_info[STAId].peer_state) {
+			   adapter->sta_info[sta_id].peer_state) {
 			if (ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X) {
 				QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
 					  QDF_TRACE_LEVEL_INFO_HIGH,
@@ -519,8 +564,8 @@ static netdev_tx_t __hdd_softap_hard_start_xmit(struct sk_buff *skb,
 		}
 	}
 
-	hdd_get_tx_resource(adapter, STAId,
-			WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
+	hdd_get_tx_resource(adapter, sta_id,
+			    WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
 
 	/* Get TL AC corresponding to Qdisc queue index/AC. */
 	ac = hdd_qdisc_ac_to_tl_ac[skb->queue_mapping];
@@ -551,20 +596,22 @@ static netdev_tx_t __hdd_softap_hard_start_xmit(struct sk_buff *skb,
 	qdf_net_buf_debug_acquire_skb(skb, __FILE__, __LINE__);
 
 	adapter->stats.tx_bytes += skb->len;
-	adapter->sta_info[STAId].tx_bytes += skb->len;
+	adapter->sta_info[sta_id].tx_bytes += skb->len;
 
 	if (qdf_nbuf_is_tso(skb)) {
 		num_seg = qdf_nbuf_get_tso_num_seg(skb);
 		adapter->stats.tx_packets += num_seg;
-		adapter->sta_info[STAId].tx_packets += num_seg;
+		adapter->sta_info[sta_id].tx_packets += num_seg;
 	} else {
 		++adapter->stats.tx_packets;
-		adapter->sta_info[STAId].tx_packets++;
+		adapter->sta_info[sta_id].tx_packets++;
 	}
-	adapter->sta_info[STAId].last_tx_rx_ts = qdf_system_ticks();
+	adapter->sta_info[sta_id].last_tx_rx_ts = qdf_system_ticks();
 
-	if (STAId != ap_ctx->broadcast_sta_id)
-		hdd_inspect_dhcp_packet(adapter, STAId, skb, QDF_TX);
+	QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_NOTIFY_COMP(skb) = 0;
+
+	if (sta_id != ap_ctx->broadcast_sta_id)
+		hdd_inspect_dhcp_packet(adapter, sta_id, skb, QDF_TX);
 
 	hdd_event_eapol_log(skb, QDF_TX);
 	QDF_NBUF_CB_TX_PACKET_TRACK(skb) = QDF_NBUF_TX_PKT_DATA_TRACK;
@@ -586,10 +633,10 @@ static netdev_tx_t __hdd_softap_hard_start_xmit(struct sk_buff *skb,
 	}
 
 	if (adapter->tx_fn(adapter->txrx_vdev,
-		 (qdf_nbuf_t) skb) != NULL) {
+		 (qdf_nbuf_t)skb) != NULL) {
 		QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
 			  "%s: Failed to send packet to txrx for staid:%d",
-			  __func__, STAId);
+			  __func__, sta_id);
 		++adapter->hdd_stats.tx_rx_stats.tx_dropped_ac[ac];
 		goto drop_pkt_and_release_skb;
 	}
@@ -805,6 +852,30 @@ QDF_STATUS hdd_softap_deinit_tx_rx_sta(struct hdd_adapter *adapter,
 	return status;
 }
 
+/**
+ * hdd_softap_notify_tx_compl_cbk() - callback to notify tx completion
+ * @skb: pointer to skb data
+ * @adapter: pointer to vdev apdapter
+ *
+ * Return: None
+ */
+void hdd_softap_notify_tx_compl_cbk(struct sk_buff *skb,
+				    void *context)
+{
+	int errno;
+	struct hdd_adapter *adapter = NULL;
+
+	adapter = (struct hdd_adapter *)context;
+	errno = hdd_validate_adapter(adapter);
+	if (errno)
+		return;
+
+	if (QDF_NBUF_CB_PACKET_TYPE_DHCP == QDF_NBUF_CB_GET_PACKET_TYPE(skb)) {
+		hdd_debug("sending DHCP indication");
+		hdd_softap_notify_dhcp_ind(context, skb);
+	}
+}
+
 /**
  * hdd_softap_rx_packet_cbk() - Receive packet handler
  * @context: pointer to HDD context
@@ -826,7 +897,6 @@ QDF_STATUS hdd_softap_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
 	struct sk_buff *next = NULL;
 	struct hdd_context *hdd_ctx = NULL;
 	struct qdf_mac_addr *src_mac;
-
 	uint8_t staid;
 
 	/* Sanity check on inputs */
@@ -1035,6 +1105,7 @@ QDF_STATUS hdd_softap_register_sta(struct hdd_adapter *adapter,
 	/* Register the vdev transmit and receive functions */
 	qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
 	txrx_ops.rx.rx = hdd_softap_rx_packet_cbk;
+	txrx_ops.tx.tx_comp = hdd_softap_notify_tx_compl_cbk;
 	cdp_vdev_register(soc,
 		(struct cdp_vdev *)cdp_get_vdev_from_vdev_id(soc,
 		(struct cdp_pdev *)pdev, adapter->session_id),

+ 1 - 1
core/hdd/src/wlan_hdd_tx_rx.c

@@ -1091,7 +1091,7 @@ static netdev_tx_t __hdd_hard_start_xmit(struct sk_buff *skb,
 	}
 
 	if (adapter->tx_fn(adapter->txrx_vdev,
-		 (qdf_nbuf_t) skb) != NULL) {
+		 (qdf_nbuf_t)skb) != NULL) {
 		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
 			  "%s: Failed to send packet to txrx for staid: %d",
 			  __func__, STAId);