static int rmnet_xmit(struct sk_buff *skb, struct net_device *dev) { struct rmnet_private *p = netdev_priv(dev); if (netif_queue_stopped(dev)) { pr_err("[%s]fatal: rmnet_xmit called when " "netif_queue is stopped", dev->name); return 0; } if (!ul_is_connected) { p->waiting_for_ul = 1; msm_bam_dmux_kickoff_ul_wakeup(); return NETDEV_TX_BUSY; } _rmnet_xmit(skb, dev); if (msm_bam_dmux_is_ch_full(p->ch_id)) { netif_stop_queue(dev); DBG0("%s: High WM hit, stopping queue=%p\n", __func__, skb); } return 0; }
static int rmnet_xmit(struct sk_buff *skb, struct net_device *dev) { struct rmnet_private *p = netdev_priv(dev); unsigned long flags; int awake; int ret = 0; if (netif_queue_stopped(dev)) { pr_err("[%s]fatal: rmnet_xmit called when " "netif_queue is stopped", dev->name); return 0; } spin_lock_irqsave(&p->lock, flags); awake = msm_bam_dmux_ul_power_vote(); if (!awake) { /* send SKB once wakeup is complete */ netif_stop_queue(dev); p->waiting_for_ul_skb = skb; spin_unlock_irqrestore(&p->lock, flags); ret = 0; goto exit; } spin_unlock_irqrestore(&p->lock, flags); ret = _rmnet_xmit(skb, dev); if (ret == -EPERM) { ret = NETDEV_TX_BUSY; goto exit; } /* * detected SSR a bit early. shut some things down now, and leave * the rest to the main ssr handling code when that happens later */ if (ret == -EFAULT) { netif_carrier_off(dev); dev_kfree_skb_any(skb); ret = 0; goto exit; } if (ret == -EAGAIN) { /* * This should not happen * EAGAIN means we attempted to overflow the high watermark * Clearly the queue is not stopped like it should be, so * stop it and return BUSY to the TCP/IP framework. It will * retry this packet with the queue is restarted which happens * in the write_done callback when the low watermark is hit. */ netif_stop_queue(dev); ret = NETDEV_TX_BUSY; goto exit; } spin_lock_irqsave(&p->tx_queue_lock, flags); if (msm_bam_dmux_is_ch_full(p->ch_id)) { netif_stop_queue(dev); DBG0("%s: High WM hit, stopping queue=%p\n", __func__, skb); } spin_unlock_irqrestore(&p->tx_queue_lock, flags); exit: msm_bam_dmux_ul_power_unvote(); return ret; }