netdev_tx_t gve_tx()

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;
}