Browse Source

qcacld-3.0: Update OS queue status in TXRX module

Add function: ol_txrx_set_vdev_os_queue_status() to update
OS queue stop/start status in TXRX module.
Also call cdp_hl_fc_set_os_queue_status() from 'flow control
resume timer' to update OS queue status in TXRX module.

Change-Id: I03260985a48084bc523a3814c93c0e6b213e1970
CRs-fixed: 2236321
Ajit Pal Singh 6 years ago
parent
commit
851a777ffc
2 changed files with 56 additions and 7 deletions
  1. 31 1
      core/dp/txrx/ol_txrx.c
  2. 25 6
      core/hdd/src/wlan_hdd_tx_rx.c

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

@@ -5034,6 +5034,35 @@ static int ol_txrx_register_hl_flow_control(struct cdp_soc_t *soc,
 	pdev->pause_cb = flowcontrol;
 	return 0;
 }
+
+static int ol_txrx_set_vdev_os_queue_status(u8 vdev_id,
+					    enum netif_action_type action)
+{
+	struct ol_txrx_vdev_t *vdev =
+	(struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id);
+
+	if (!vdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid vdev_id %d", __func__, vdev_id);
+		return -EINVAL;
+	}
+
+	switch (action) {
+	case WLAN_NETIF_PRIORITY_QUEUE_ON:
+		qdf_spin_lock_bh(&vdev->pdev->tx_mutex);
+		vdev->prio_q_paused = 0;
+		qdf_spin_unlock_bh(&vdev->pdev->tx_mutex);
+		break;
+	case WLAN_WAKE_NON_PRIORITY_QUEUE:
+		qdf_atomic_set(&vdev->os_q_paused, 0);
+		break;
+	default:
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid action %d", __func__, action);
+		return -EINVAL;
+	}
+	return 0;
+}
 #endif /* QCA_HL_NETDEV_FLOW_CONTROL */
 
 /**
@@ -6039,7 +6068,8 @@ static struct cdp_lflowctl_ops ol_ops_l_flowctl = {
 	.register_tx_flow_control = ol_txrx_register_hl_flow_control,
 	.vdev_flush = ol_txrx_vdev_flush,
 	.vdev_pause = ol_txrx_vdev_pause,
-	.vdev_unpause = ol_txrx_vdev_unpause
+	.vdev_unpause = ol_txrx_vdev_unpause,
+	.set_vdev_os_queue_status = ol_txrx_set_vdev_os_queue_status
 };
 #else /* QCA_HL_NETDEV_FLOW_CONTROL */
 static struct cdp_lflowctl_ops ol_ops_l_flowctl = { };

+ 25 - 6
core/hdd/src/wlan_hdd_tx_rx.c

@@ -115,23 +115,42 @@ void hdd_deregister_hl_netdev_fc_timer(struct hdd_adapter *adapter)
  * hdd_tx_resume_timer_expired_handler() - TX Q resume timer handler
  * @adapter_context: pointer to vdev adapter
  *
- * If Blocked OS Q is not resumed during timeout period, to prevent
- * permanent stall, resume OS Q forcefully.
- *
  * Return: None
  */
 void hdd_tx_resume_timer_expired_handler(void *adapter_context)
 {
 	struct hdd_adapter *adapter = (struct hdd_adapter *)adapter_context;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	u32 p_qpaused;
+	u32 np_qpaused;
 
 	if (!adapter) {
-		/* INVALID ARG */
+		hdd_err("invalid adapter context");
 		return;
 	}
 
 	hdd_debug("Enabling queues");
-	wlan_hdd_netif_queue_control(adapter, WLAN_WAKE_NON_PRIORITY_QUEUE,
-				     WLAN_DATA_FLOW_CONTROL);
+	spin_lock_bh(&adapter->pause_map_lock);
+	p_qpaused = adapter->pause_map & BIT(WLAN_DATA_FLOW_CONTROL_PRIORITY);
+	np_qpaused = adapter->pause_map & BIT(WLAN_DATA_FLOW_CONTROL);
+	spin_unlock_bh(&adapter->pause_map_lock);
+
+	if (p_qpaused) {
+		wlan_hdd_netif_queue_control(adapter,
+					     WLAN_NETIF_PRIORITY_QUEUE_ON,
+					     WLAN_DATA_FLOW_CONTROL_PRIORITY);
+		cdp_hl_fc_set_os_queue_status(soc,
+					      adapter->session_id,
+					      WLAN_NETIF_PRIORITY_QUEUE_ON);
+	}
+	if (np_qpaused) {
+		wlan_hdd_netif_queue_control(adapter,
+					     WLAN_WAKE_NON_PRIORITY_QUEUE,
+					     WLAN_DATA_FLOW_CONTROL);
+		cdp_hl_fc_set_os_queue_status(soc,
+					      adapter->session_id,
+					      WLAN_WAKE_NON_PRIORITY_QUEUE);
+	}
 }
 
 #endif /* QCA_HL_NETDEV_FLOW_CONTROL */