diff --git a/core/hdd/inc/wlan_hdd_tx_rx.h b/core/hdd/inc/wlan_hdd_tx_rx.h index d69ec9450dec..9b5519a3ac03 100644 --- a/core/hdd/inc/wlan_hdd_tx_rx.h +++ b/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) */ diff --git a/core/hdd/src/wlan_hdd_softap_tx_rx.c b/core/hdd/src/wlan_hdd_softap_tx_rx.c index 2496df84b67a..8d13e4f37226 100644 --- a/core/hdd/src/wlan_hdd_softap_tx_rx.c +++ b/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, diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c index 7ce4610c965f..9cb443980da0 100644 --- a/core/hdd/src/wlan_hdd_tx_rx.c +++ b/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 */