Loading drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +23 −13 Original line number Diff line number Diff line Loading @@ -168,7 +168,7 @@ struct rmnet_ipa3_context { tether_device [IPACM_MAX_CLIENT_DEVICE_TYPES]; bool dl_csum_offload_enabled; atomic_t suspend_pend; atomic_t ap_suspend; }; static struct rmnet_ipa3_context *rmnet_ipa3_ctx; Loading Loading @@ -1172,19 +1172,25 @@ static int ipa3_wwan_xmit(struct sk_buff *skb, struct net_device *dev) qmap_check = RMNET_MAP_GET_CD_BIT(skb); spin_lock_irqsave(&wwan_ptr->lock, flags); if (netif_queue_stopped(dev)) { /* * Checking rmnet suspend in progress or not, because in suspend * clock will be disabled, without clock transferring data * not possible. /* There can be a race between enabling the wake queue and * suspend in progress. Check if suspend is pending and * return from here itself. */ if (!atomic_read(&rmnet_ipa3_ctx->suspend_pend) && qmap_check && if (atomic_read(&rmnet_ipa3_ctx->ap_suspend)) { netif_stop_queue(dev); spin_unlock_irqrestore(&wwan_ptr->lock, flags); return NETDEV_TX_BUSY; } if (netif_queue_stopped(dev)) { if (qmap_check && atomic_read(&wwan_ptr->outstanding_pkts) < outstanding_high_ctl) { pr_err("[%s]Queue stop, send ctrl pkts\n", dev->name); IPAWANERR("[%s]Queue stop, send ctrl pkts\n", dev->name); goto send; } else { pr_err("[%s]fatal: %s stopped\n", dev->name, __func__); IPAWANERR("[%s]fatal: %s stopped\n", dev->name, __func__); spin_unlock_irqrestore(&wwan_ptr->lock, flags); return NETDEV_TX_BUSY; } Loading Loading @@ -1221,7 +1227,7 @@ static int ipa3_wwan_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_BUSY; } if (ret) { pr_err("[%s] fatal: ipa rm timer request resource failed %d\n", IPAWANERR("[%s] fatal: ipa rm timer req resource failed %d\n", dev->name, ret); dev_kfree_skb_any(skb); dev->stats.tx_dropped++; Loading Loading @@ -2243,6 +2249,7 @@ static void ipa3_wake_tx_queue(struct work_struct *work) { if (IPA_NETDEV()) { __netif_tx_lock_bh(netdev_get_tx_queue(IPA_NETDEV(), 0)); IPAWANDBG("Waking up the workqueue.\n"); netif_wake_queue(IPA_NETDEV()); __netif_tx_unlock_bh(netdev_get_tx_queue(IPA_NETDEV(), 0)); } Loading Loading @@ -2657,7 +2664,7 @@ static int ipa3_wwan_probe(struct platform_device *pdev) ipa3_proxy_clk_unvote(); } atomic_set(&rmnet_ipa3_ctx->is_ssr, 0); atomic_set(&rmnet_ipa3_ctx->suspend_pend, 0); atomic_set(&rmnet_ipa3_ctx->ap_suspend, 0); ipa3_update_ssr_state(false); IPAWANERR("rmnet_ipa completed initialization\n"); Loading Loading @@ -2780,12 +2787,13 @@ static int rmnet_ipa_ap_suspend(struct device *dev) * scenarios observing the data was processed when IPA clock are off. * Added changes to synchronize rmnet supend and xmit. */ atomic_set(&rmnet_ipa3_ctx->suspend_pend, 1); atomic_set(&rmnet_ipa3_ctx->ap_suspend, 1); spin_lock_irqsave(&wwan_ptr->lock, flags); /* Do not allow A7 to suspend in case there are outstanding packets */ if (atomic_read(&wwan_ptr->outstanding_pkts) != 0) { IPAWANDBG("Outstanding packets, postponing AP suspend.\n"); ret = -EAGAIN; atomic_set(&rmnet_ipa3_ctx->ap_suspend, 0); spin_unlock_irqrestore(&wwan_ptr->lock, flags); goto bail; } Loading @@ -2797,11 +2805,11 @@ static int rmnet_ipa_ap_suspend(struct device *dev) dev_put(netdev); spin_unlock_irqrestore(&wwan_ptr->lock, flags); IPAWANDBG("De-activating the PM/RM resource.\n"); if (ipa3_ctx->use_ipa_pm) ipa_pm_deactivate_sync(rmnet_ipa3_ctx->pm_hdl); else ipa_rm_release_resource(IPA_RM_RESOURCE_WWAN_0_PROD); atomic_set(&rmnet_ipa3_ctx->suspend_pend, 0); ret = 0; bail: IPAWANDBG("Exit with %d\n", ret); Loading @@ -2823,6 +2831,8 @@ static int rmnet_ipa_ap_resume(struct device *dev) struct net_device *netdev = IPA_NETDEV(); IPAWANDBG("Enter...\n"); /* Clear the suspend in progress flag. */ atomic_set(&rmnet_ipa3_ctx->ap_suspend, 0); if (netdev) { netif_wake_queue(netdev); /* Starting Watch dog timer, pipe was changes to resume state */ Loading Loading
drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +23 −13 Original line number Diff line number Diff line Loading @@ -168,7 +168,7 @@ struct rmnet_ipa3_context { tether_device [IPACM_MAX_CLIENT_DEVICE_TYPES]; bool dl_csum_offload_enabled; atomic_t suspend_pend; atomic_t ap_suspend; }; static struct rmnet_ipa3_context *rmnet_ipa3_ctx; Loading Loading @@ -1172,19 +1172,25 @@ static int ipa3_wwan_xmit(struct sk_buff *skb, struct net_device *dev) qmap_check = RMNET_MAP_GET_CD_BIT(skb); spin_lock_irqsave(&wwan_ptr->lock, flags); if (netif_queue_stopped(dev)) { /* * Checking rmnet suspend in progress or not, because in suspend * clock will be disabled, without clock transferring data * not possible. /* There can be a race between enabling the wake queue and * suspend in progress. Check if suspend is pending and * return from here itself. */ if (!atomic_read(&rmnet_ipa3_ctx->suspend_pend) && qmap_check && if (atomic_read(&rmnet_ipa3_ctx->ap_suspend)) { netif_stop_queue(dev); spin_unlock_irqrestore(&wwan_ptr->lock, flags); return NETDEV_TX_BUSY; } if (netif_queue_stopped(dev)) { if (qmap_check && atomic_read(&wwan_ptr->outstanding_pkts) < outstanding_high_ctl) { pr_err("[%s]Queue stop, send ctrl pkts\n", dev->name); IPAWANERR("[%s]Queue stop, send ctrl pkts\n", dev->name); goto send; } else { pr_err("[%s]fatal: %s stopped\n", dev->name, __func__); IPAWANERR("[%s]fatal: %s stopped\n", dev->name, __func__); spin_unlock_irqrestore(&wwan_ptr->lock, flags); return NETDEV_TX_BUSY; } Loading Loading @@ -1221,7 +1227,7 @@ static int ipa3_wwan_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_BUSY; } if (ret) { pr_err("[%s] fatal: ipa rm timer request resource failed %d\n", IPAWANERR("[%s] fatal: ipa rm timer req resource failed %d\n", dev->name, ret); dev_kfree_skb_any(skb); dev->stats.tx_dropped++; Loading Loading @@ -2243,6 +2249,7 @@ static void ipa3_wake_tx_queue(struct work_struct *work) { if (IPA_NETDEV()) { __netif_tx_lock_bh(netdev_get_tx_queue(IPA_NETDEV(), 0)); IPAWANDBG("Waking up the workqueue.\n"); netif_wake_queue(IPA_NETDEV()); __netif_tx_unlock_bh(netdev_get_tx_queue(IPA_NETDEV(), 0)); } Loading Loading @@ -2657,7 +2664,7 @@ static int ipa3_wwan_probe(struct platform_device *pdev) ipa3_proxy_clk_unvote(); } atomic_set(&rmnet_ipa3_ctx->is_ssr, 0); atomic_set(&rmnet_ipa3_ctx->suspend_pend, 0); atomic_set(&rmnet_ipa3_ctx->ap_suspend, 0); ipa3_update_ssr_state(false); IPAWANERR("rmnet_ipa completed initialization\n"); Loading Loading @@ -2780,12 +2787,13 @@ static int rmnet_ipa_ap_suspend(struct device *dev) * scenarios observing the data was processed when IPA clock are off. * Added changes to synchronize rmnet supend and xmit. */ atomic_set(&rmnet_ipa3_ctx->suspend_pend, 1); atomic_set(&rmnet_ipa3_ctx->ap_suspend, 1); spin_lock_irqsave(&wwan_ptr->lock, flags); /* Do not allow A7 to suspend in case there are outstanding packets */ if (atomic_read(&wwan_ptr->outstanding_pkts) != 0) { IPAWANDBG("Outstanding packets, postponing AP suspend.\n"); ret = -EAGAIN; atomic_set(&rmnet_ipa3_ctx->ap_suspend, 0); spin_unlock_irqrestore(&wwan_ptr->lock, flags); goto bail; } Loading @@ -2797,11 +2805,11 @@ static int rmnet_ipa_ap_suspend(struct device *dev) dev_put(netdev); spin_unlock_irqrestore(&wwan_ptr->lock, flags); IPAWANDBG("De-activating the PM/RM resource.\n"); if (ipa3_ctx->use_ipa_pm) ipa_pm_deactivate_sync(rmnet_ipa3_ctx->pm_hdl); else ipa_rm_release_resource(IPA_RM_RESOURCE_WWAN_0_PROD); atomic_set(&rmnet_ipa3_ctx->suspend_pend, 0); ret = 0; bail: IPAWANDBG("Exit with %d\n", ret); Loading @@ -2823,6 +2831,8 @@ static int rmnet_ipa_ap_resume(struct device *dev) struct net_device *netdev = IPA_NETDEV(); IPAWANDBG("Enter...\n"); /* Clear the suspend in progress flag. */ atomic_set(&rmnet_ipa3_ctx->ap_suspend, 0); if (netdev) { netif_wake_queue(netdev); /* Starting Watch dog timer, pipe was changes to resume state */ Loading