summaryrefslogtreecommitdiff
path: root/arch/um/drivers/vector_kern.h
blob: 806df551be0b456bd2676022b745ae0221b20bdf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2002 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 */

#ifndef __UM_VECTOR_KERN_H
#define __UM_VECTOR_KERN_H

#include <linux/netdevice.h>
#include <linux/platform_device.h>
#include <linux/skbuff.h>
#include <linux/socket.h>
#include <linux/list.h>
#include <linux/ctype.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>

#include "vector_user.h"

/* Queue structure specially adapted for multiple enqueue/dequeue
 * in a mmsgrecv/mmsgsend context
 */

/* Dequeue method */

#define QUEUE_SENDMSG 0
#define QUEUE_SENDMMSG 1

#define VECTOR_RX 1
#define VECTOR_TX (1 << 1)
#define VECTOR_BPF (1 << 2)
#define VECTOR_QDISC_BYPASS (1 << 3)
#define VECTOR_BPF_FLASH (1 << 4)

#define ETH_MAX_PACKET 1500
#define ETH_HEADER_OTHER 32 /* just in case someone decides to go mad on QnQ */

#define MAX_FILTER_PROG (2 << 16)

struct vector_queue {
	struct mmsghdr *mmsg_vector;
	void **skbuff_vector;
	 /* backlink to device which owns us */
	struct net_device *dev;
	spinlock_t head_lock;
	spinlock_t tail_lock;
	int queue_depth, head, tail, max_depth, max_iov_frags;
	short options;
};

struct vector_estats {
	uint64_t rx_queue_max;
	uint64_t rx_queue_running_average;
	uint64_t tx_queue_max;
	uint64_t tx_queue_running_average;
	uint64_t rx_encaps_errors;
	uint64_t tx_timeout_count;
	uint64_t tx_restart_queue;
	uint64_t tx_kicks;
	uint64_t tx_flow_control_xon;
	uint64_t tx_flow_control_xoff;
	uint64_t rx_csum_offload_good;
	uint64_t rx_csum_offload_errors;
	uint64_t sg_ok;
	uint64_t sg_linearized;
};

#define VERIFY_HEADER_NOK -1
#define VERIFY_HEADER_OK 0
#define VERIFY_CSUM_OK 1

struct vector_private {
	struct list_head list;
	struct net_device *dev;
	struct napi_struct		napi	____cacheline_aligned;

	int unit;

	/* Timeout timer in TX */

	struct timer_list tl;

	/* Scheduled "remove device" work */
	struct work_struct reset_tx;
	struct vector_fds *fds;

	struct vector_queue *rx_queue;
	struct vector_queue *tx_queue;

	int rx_irq;
	int tx_irq;

	struct arglist *parsed;

	void *transport_data; /* transport specific params if needed */

	int max_packet;
	int req_size; /* different from max packet - used for TSO */
	int headroom;

	int options;

	/* remote address if any - some transports will leave this as null */

	int header_size;
	int rx_header_size;
	int coalesce;

	void *header_rxbuffer;
	void *header_txbuffer;

	int (*form_header)(uint8_t *header,
		struct sk_buff *skb, struct vector_private *vp);
	int (*verify_header)(uint8_t *header,
		struct sk_buff *skb, struct vector_private *vp);

	spinlock_t stats_lock;

	bool rexmit_scheduled;
	bool opened;
	bool in_write_poll;
	bool in_error;

	/* guest allowed to use ethtool flash to load bpf */
	bool bpf_via_flash;

	/* ethtool stats */

	struct vector_estats estats;
	struct sock_fprog *bpf;

	char user[];
};

extern int build_transport_data(struct vector_private *vp);

#endif