* is called in the data workqueue context with the
* netdev_vif mutex held.
*/
-void slsi_ba_process_complete(struct net_device *dev)
+void slsi_ba_process_complete(struct net_device *dev, bool from_ba_timer)
{
struct netdev_vif *ndev_vif = netdev_priv(dev);
struct sk_buff *skb;
- while ((skb = slsi_skb_dequeue(&ndev_vif->ba_complete)) != NULL) {
- slsi_rx_data_deliver_skb(ndev_vif->sdev, dev, skb);
- }
+ while ((skb = slsi_skb_dequeue(&ndev_vif->ba_complete)) != NULL)
+ slsi_rx_data_deliver_skb(ndev_vif->sdev, dev, skb, from_ba_timer);
}
static void slsi_ba_signal_process_complete(struct net_device *dev)
#ifdef CONFIG_SCSC_WLAN_RX_NAPI
conf_hip4_ver = scsc_wifi_get_hip_config_version(&sdev->hip4_inst.hip_control->init);
if (conf_hip4_ver == 4)
- slsi_ba_process_complete(dev);
+ slsi_ba_process_complete(dev, true);
else
slsi_ba_signal_process_complete(dev);
#else
/*****************************************************************************
*
- * Copyright (c) 2012 - 2016 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
****************************************************************************/
int slsi_ba_process_frame(struct net_device *dev, struct slsi_peer *peer,
struct sk_buff *skb, u16 sequence_number, u16 tid);
-void slsi_ba_process_complete(struct net_device *dev);
+void slsi_ba_process_complete(struct net_device *dev, bool from_ba_timer);
bool slsi_ba_check(struct slsi_peer *peer, u16 tid);
u16 snap_type;
} __packed;
-void slsi_rx_data_deliver_skb(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb);
+void slsi_rx_data_deliver_skb(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb, bool from_ba_timer);
void slsi_rx_dbg_sap_work(struct work_struct *work);
void slsi_rx_netdev_data_work(struct work_struct *work);
void slsi_rx_netdev_mlme_work(struct work_struct *work);
return (fapi_get_u16(skb, u.ma_unitdata_ind.data_unit_descriptor) == FAPI_DATAUNITDESCRIPTOR_AMSDU);
}
-void slsi_rx_data_deliver_skb(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
+void slsi_rx_data_deliver_skb(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb, bool from_ba_timer)
{
struct netdev_vif *ndev_vif = netdev_priv(dev);
struct sk_buff_head msdu_list;
conf_hip4_ver = scsc_wifi_get_hip_config_version(&sdev->hip4_inst.hip_control->init);
if (conf_hip4_ver == 4) {
#ifdef CONFIG_SCSC_WLAN_RX_NAPI_GRO
- napi_gro_receive(&sdev->hip4_inst.hip_priv->napi, rx_skb);
+ if (!from_ba_timer)
+ napi_gro_receive(&sdev->hip4_inst.hip_priv->napi, rx_skb);
+ else
+ netif_receive_skb(rx_skb);
#else
netif_receive_skb(rx_skb);
#endif
SLSI_NET_WARN(dev, "Packet received from TDLS but no TDLS exists (seq: %x) Skip BA\n", seq_num);
/* Skip BA reorder and pass the frames Up */
- slsi_rx_data_deliver_skb(sdev, dev, skb);
+ slsi_rx_data_deliver_skb(sdev, dev, skb, false);
return;
}
return;
/* Pass to next receive process */
- slsi_rx_data_deliver_skb(sdev, dev, skb);
+ slsi_rx_data_deliver_skb(sdev, dev, skb, false);
}
static int slsi_rx_data_cfm(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
/* SKBs in a BA session are not passed yet */
if (atomic_read(&ndev_vif->ba_flush)) {
atomic_set(&ndev_vif->ba_flush, 0);
- slsi_ba_process_complete(dev);
+ slsi_ba_process_complete(dev, false);
}
break;
case MA_UNITDATA_CFM:
if (atomic_read(&ndev_vif->ba_flush)) {
atomic_set(&ndev_vif->ba_flush, 0);
- slsi_ba_process_complete(dev);
+ slsi_ba_process_complete(dev, false);
}
skb = slsi_skb_work_dequeue(w);