diff --git a/core/rtw_mlme_ext.c b/core/rtw_mlme_ext.c index c6abf49f..4bca2f95 100644 --- a/core/rtw_mlme_ext.c +++ b/core/rtw_mlme_ext.c @@ -7342,15 +7342,15 @@ void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntfr #endif /* CONFIG_BEAMFORMING */ } -void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe) +s32 dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe) { if (RTW_CANNOT_RUN(padapter)) { rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf); rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe); - return; + return _FAIL; } - rtw_hal_mgnt_xmit(padapter, pmgntframe); + return rtw_hal_mgnt_xmit(padapter, pmgntframe); } s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms) diff --git a/core/rtw_xmit.c b/core/rtw_xmit.c index c5c2f073..ea73f2bc 100644 --- a/core/rtw_xmit.c +++ b/core/rtw_xmit.c @@ -4223,20 +4223,11 @@ int rtw_ieee80211_radiotap_iterator_init( #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)) static struct xmit_frame* monitor_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv) { - int tries; - int delay = 300; - struct xmit_frame *pmgntframe = NULL; - - for(tries = 3; tries >= 0; tries--) { - pmgntframe = alloc_mgtxmitframe(pxmitpriv); - if(pmgntframe != NULL) - return pmgntframe; - rtw_udelay_os(delay); - delay += delay/2; - } - return NULL; + + return alloc_mgtxmitframe(pxmitpriv); } + s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev) { int ret = 0; @@ -4280,9 +4271,27 @@ s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev) if (unlikely(skb->len < rtap_len)) goto fail; + // check tx queue if is about to get full + if (pxmitpriv->free_xframe_ext_cnt <= 4) + { + pxmitpriv->tx_drop++; + rtw_skb_free(skb); + return NETDEV_TX_OK; + } + // check if we can allocate more buffers before even trying to do anything + if (pxmitpriv->free_xmit_extbuf_cnt <= 4) + { + pxmitpriv->tx_drop++; + rtw_skb_free(skb); + return NETDEV_TX_OK; + } + + if ((pmgntframe = monitor_alloc_mgtxmitframe(pxmitpriv)) == NULL) { DBG_COUNTER(padapter->tx_logs.core_tx_err_pxmitframe); - return NETDEV_TX_BUSY; + pxmitpriv->tx_drop++; + rtw_skb_free(skb); + return NETDEV_TX_OK; } ret = rtw_ieee80211_radiotap_iterator_init(&iterator, rtap_hdr, skb->len, NULL); @@ -4393,7 +4402,11 @@ s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev) pmlmeext->mgnt_seq++; pattrib->last_txcmdsz = pattrib->pktlen; - dump_mgntframe(padapter, pmgntframe); + if (_SUCCESS != dump_mgntframe(padapter, pmgntframe) ) + { + pxmitpriv->tx_drop++; + goto fail; + } DBG_COUNTER(padapter->tx_logs.core_tx); pxmitpriv->tx_pkts++; pxmitpriv->tx_bytes += skb->len; diff --git a/include/rtw_mlme_ext.h b/include/rtw_mlme_ext.h index 4f6afea4..eebd9155 100644 --- a/include/rtw_mlme_ext.h +++ b/include/rtw_mlme_ext.h @@ -958,7 +958,7 @@ void update_mgnt_tx_rate(_adapter *padapter, u8 rate); void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib); void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib); void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe); -void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe); +s32 dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe); s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms); s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe); s32 dump_mgntframe_and_wait_ack_timeout(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms);