فهرست منبع

qcacld-3.0: fix non-linear data TX dma failed issue

Currently non-linear, non-tso TX data is not handled correctly,
only the non-tso, single linear data is supported. the frag paged
data in skb is missed while packet length for HW access
is entire packet length, HW DMA failed.

temporarily to linearize skb so that non-linear data could be TX
correctly.

Change-Id: Ic0f2b7a0b021ca190c870551a66181f50ae72c65
CRs-Fixed: 2180318
jinweic chen 7 سال پیش
والد
کامیت
5104601ba7
3فایلهای تغییر یافته به همراه39 افزوده شده و 0 حذف شده
  1. 19 0
      core/hdd/inc/wlan_hdd_tx_rx.h
  2. 10 0
      core/hdd/src/wlan_hdd_softap_tx_rx.c
  3. 10 0
      core/hdd/src/wlan_hdd_tx_rx.c

+ 19 - 0
core/hdd/inc/wlan_hdd_tx_rx.h

@@ -224,4 +224,23 @@ hdd_skb_fill_gso_size(struct net_device *dev, struct sk_buff *skb)
  * Return: tx acked count
  */
 uint32_t hdd_txrx_get_tx_ack_count(struct hdd_adapter *adapter);
+
+#ifdef CONFIG_HL_SUPPORT
+static inline QDF_STATUS
+hdd_skb_nontso_linearize(struct sk_buff *skb)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static inline QDF_STATUS
+hdd_skb_nontso_linearize(struct sk_buff *skb)
+{
+	if (qdf_nbuf_is_nonlinear(skb) && qdf_nbuf_is_tso(skb) == false) {
+		if (qdf_unlikely(skb_linearize(skb)))
+			return QDF_STATUS_E_NOMEM;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 #endif /* end #if !defined(WLAN_HDD_TX_RX_H) */

+ 10 - 0
core/hdd/src/wlan_hdd_softap_tx_rx.c

@@ -597,6 +597,16 @@ static netdev_tx_t __hdd_softap_hard_start_xmit(struct sk_buff *skb,
 			(uint8_t *)&skb->data[QDF_DP_TRACE_RECORD_SIZE],
 			(qdf_nbuf_len(skb)-QDF_DP_TRACE_RECORD_SIZE), QDF_TX));
 
+	/* check whether need to linearize skb, like non-linear udp data */
+	if (hdd_skb_nontso_linearize(skb) != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+			  QDF_TRACE_LEVEL_INFO_HIGH,
+			  "%s: skb %pK linearize failed. drop the pkt",
+			  __func__, skb);
+		++adapter->hdd_stats.tx_rx_stats.tx_dropped_ac[ac];
+		goto drop_pkt_and_release_skb;
+	}
+
 	if (adapter->tx_fn(adapter->txrx_vdev,
 		 (qdf_nbuf_t) skb) != NULL) {
 		QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH,

+ 10 - 0
core/hdd/src/wlan_hdd_tx_rx.c

@@ -1092,6 +1092,16 @@ static netdev_tx_t __hdd_hard_start_xmit(struct sk_buff *skb,
 		goto drop_pkt_and_release_skb;
 	}
 
+	/* check whether need to linearize skb, like non-linear udp data */
+	if (hdd_skb_nontso_linearize(skb) != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
+			  QDF_TRACE_LEVEL_INFO_HIGH,
+			  "%s: skb %pK linearize failed. drop the pkt",
+			  __func__, skb);
+		++adapter->hdd_stats.tx_rx_stats.tx_dropped_ac[ac];
+		goto drop_pkt_and_release_skb;
+	}
+
 	/*
 	 * If a transmit function is not registered, drop packet
 	 */