in build/gve_tx.c [766:822]
netdev_tx_t gve_tx(struct sk_buff *skb, struct net_device *dev)
{
struct gve_priv *priv = netdev_priv(dev);
struct gve_tx_ring *tx;
int nsegs;
WARN(skb_get_queue_mapping(skb) >= priv->tx_cfg.num_queues,
"skb queue index out of range");
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,16,0)
/* Workaround for bug in older kernels */
if (skb_get_queue_mapping(skb) >= priv->tx_cfg.num_queues) {
return -EBUSY;
}
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4,16,0) */
tx = &priv->tx[skb_get_queue_mapping(skb)];
if (unlikely(gve_maybe_stop_tx(priv, tx, skb))) {
/* We need to ring the txq doorbell -- we have stopped the Tx
* queue for want of resources, but prior calls to gve_tx()
* may have added descriptors without ringing the doorbell.
*/
gve_tx_put_doorbell(priv, tx->q_resources, tx->req);
return NETDEV_TX_BUSY;
}
if (tx->raw_addressing)
nsegs = gve_tx_add_skb_no_copy(priv, tx, skb);
else
nsegs = gve_tx_add_skb_copy(priv, tx, skb);
/* If the packet is getting sent, we need to update the skb */
if (nsegs) {
netdev_tx_sent_queue(tx->netdev_txq, skb->len);
skb_tx_timestamp(skb);
tx->req += nsegs;
} else {
dev_kfree_skb_any(skb);
}
/* If we have xmit_more - don't ring the doorbell unless we are stopped */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)
if (!netif_xmit_stopped(tx->netdev_txq)
#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7, 8) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8, 0)) || RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8, 2) || LINUX_VERSION_CODE > KERNEL_VERSION(5,2,0) || defined(KUNIT_KERNEL)
&& netdev_xmit_more()
#else /* (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7, 8) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8, 0)) || RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8,2) || LINUX_VERSION_CODE > KERNEL_VERSION(5,2,0) */
&& skb->xmit_more
#endif /* (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7, 8) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8, 0)) || RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(8,2) || LINUX_VERSION_CODE > KERNEL_VERSION(5,2,0) */
)
return NETDEV_TX_OK;
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) */
/* Give packets to NIC. Even if this packet failed to send the doorbell
* might need to be rung because of xmit_more.
*/
gve_tx_put_doorbell(priv, tx->q_resources, tx->req);
return NETDEV_TX_OK;
}