Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
 1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 2/* Google virtual Ethernet (gve) driver
 3 *
 4 * Copyright (C) 2015-2021 Google, Inc.
 5 */
 6
 7#include "gve.h"
 8#include "gve_adminq.h"
 9#include "gve_utils.h"
10
11void gve_tx_remove_from_block(struct gve_priv *priv, int queue_idx)
12{
13	struct gve_notify_block *block =
14			&priv->ntfy_blocks[gve_tx_idx_to_ntfy(priv, queue_idx)];
15
16	block->tx = NULL;
17}
18
19void gve_tx_add_to_block(struct gve_priv *priv, int queue_idx)
20{
21	unsigned int active_cpus = min_t(int, priv->num_ntfy_blks / 2,
22					 num_online_cpus());
23	int ntfy_idx = gve_tx_idx_to_ntfy(priv, queue_idx);
24	struct gve_notify_block *block = &priv->ntfy_blocks[ntfy_idx];
25	struct gve_tx_ring *tx = &priv->tx[queue_idx];
26
27	block->tx = tx;
28	tx->ntfy_id = ntfy_idx;
29	netif_set_xps_queue(priv->dev, get_cpu_mask(ntfy_idx % active_cpus),
30			    queue_idx);
31}
32
33void gve_rx_remove_from_block(struct gve_priv *priv, int queue_idx)
34{
35	struct gve_notify_block *block =
36			&priv->ntfy_blocks[gve_rx_idx_to_ntfy(priv, queue_idx)];
37
38	block->rx = NULL;
39}
40
41void gve_rx_add_to_block(struct gve_priv *priv, int queue_idx)
42{
43	u32 ntfy_idx = gve_rx_idx_to_ntfy(priv, queue_idx);
44	struct gve_notify_block *block = &priv->ntfy_blocks[ntfy_idx];
45	struct gve_rx_ring *rx = &priv->rx[queue_idx];
46
47	block->rx = rx;
48	rx->ntfy_id = ntfy_idx;
49}
50
51struct sk_buff *gve_rx_copy(struct net_device *dev, struct napi_struct *napi,
52			    struct gve_rx_slot_page_info *page_info, u16 len)
53{
54	void *va = page_info->page_address + page_info->page_offset +
55		page_info->pad;
56	struct sk_buff *skb;
57
58	skb = napi_alloc_skb(napi, len);
59	if (unlikely(!skb))
60		return NULL;
61
62	__skb_put(skb, len);
63	skb_copy_to_linear_data_offset(skb, 0, va, len);
64	skb->protocol = eth_type_trans(skb, dev);
65
66	return skb;
67}
68
69void gve_dec_pagecnt_bias(struct gve_rx_slot_page_info *page_info)
70{
71	page_info->pagecnt_bias--;
72	if (page_info->pagecnt_bias == 0) {
73		int pagecount = page_count(page_info->page);
74
75		/* If we have run out of bias - set it back up to INT_MAX
76		 * minus the existing refs.
77		 */
78		page_info->pagecnt_bias = INT_MAX - pagecount;
79
80		/* Set pagecount back up to max. */
81		page_ref_add(page_info->page, INT_MAX - pagecount);
82	}
83}