aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/intel/i40evf/i40evf.h
blob: ff6529b288a137190e35fe3d86ea17ad1929db51 (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
/*******************************************************************************
 *
 * Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
 * Copyright(c) 2013 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * The full GNU General Public License is included in this distribution in
 * the file called "COPYING".
 *
 * Contact Information:
 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 ******************************************************************************/

#ifndef _I40EVF_H_
#define _I40EVF_H_

#include <linux/module.h>
#include <linux/pci.h>
#include <linux/aer.h>
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/sctp.h>
#include <linux/ipv6.h>
#include <net/ip6_checksum.h>
#include <net/udp.h>
#include <linux/sctp.h>


#include "i40e_type.h"
#include "i40e_virtchnl.h"
#include "i40e_txrx.h"

#define DEFAULT_DEBUG_LEVEL_SHIFT 3
#define PFX "i40evf: "
#define DPRINTK(nlevel, klevel, fmt, args...) \
	((void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
	printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \
		__func__ , ## args)))

/* dummy struct to make common code less painful */
struct i40e_vsi {
	struct i40evf_adapter *back;
	struct net_device *netdev;
	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
	u16 seid;
	u16 id;
	unsigned long state;
	int base_vector;
	u16 work_limit;
	/* high bit set means dynamic, use accessor routines to read/write.
	 * hardware only supports 2us resolution for the ITR registers.
	 * these values always store the USER setting, and must be converted
	 * before programming to a register.
	 */
	u16 rx_itr_setting;
	u16 tx_itr_setting;
};

/* How many Rx Buffers do we bundle into one write to the hardware ? */
#define I40EVF_RX_BUFFER_WRITE	16	/* Must be power of 2 */
#define I40EVF_DEFAULT_TXD   512
#define I40EVF_DEFAULT_RXD   512
#define I40EVF_MAX_TXD       4096
#define I40EVF_MIN_TXD       64
#define I40EVF_MAX_RXD       4096
#define I40EVF_MIN_RXD       64
#define I40EVF_REQ_DESCRIPTOR_MULTIPLE  8

/* Supported Rx Buffer Sizes */
#define I40EVF_RXBUFFER_64    64     /* Used for packet split */
#define I40EVF_RXBUFFER_128   128    /* Used for packet split */
#define I40EVF_RXBUFFER_256   256    /* Used for packet split */
#define I40EVF_RXBUFFER_2048  2048
#define I40EVF_MAX_RXBUFFER   16384  /* largest size for single descriptor */
#define I40EVF_MAX_AQ_BUF_SIZE    4096
#define I40EVF_AQ_LEN             32
#define I40EVF_AQ_MAX_ERR         10 /* times to try before resetting AQ */

#define MAXIMUM_ETHERNET_VLAN_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)

#define I40E_RX_DESC(R, i) (&(((union i40e_32byte_rx_desc *)((R)->desc))[i]))
#define I40E_TX_DESC(R, i) (&(((struct i40e_tx_desc *)((R)->desc))[i]))
#define I40E_TX_CTXTDESC(R, i) \
	(&(((struct i40e_tx_context_desc *)((R)->desc))[i]))
#define MAX_RX_QUEUES 8
#define MAX_TX_QUEUES MAX_RX_QUEUES

/* MAX_MSIX_Q_VECTORS of these are allocated,
 * but we only use one per queue-specific vector.
 */
struct i40e_q_vector {
	struct i40evf_adapter *adapter;
	struct i40e_vsi *vsi;
	struct napi_struct napi;
	unsigned long reg_idx;
	struct i40e_ring_container rx;
	struct i40e_ring_container tx;
	u32 ring_mask;
	u8 num_ringpairs;	/* total number of ring pairs in vector */
	int v_idx;	  /* vector index in list */
	char name[IFNAMSIZ + 9];
	cpumask_var_t affinity_mask;
};

/* Helper macros to switch between ints/sec and what the register uses.
 * And yes, it's the same math going both ways.  The lowest value
 * supported by all of the i40e hardware is 8.
 */
#define EITR_INTS_PER_SEC_TO_REG(_eitr) \
	((_eitr) ? (1000000000 / ((_eitr) * 256)) : 8)
#define EITR_REG_TO_INTS_PER_SEC EITR_INTS_PER_SEC_TO_REG

#define I40EVF_DESC_UNUSED(R) \
	((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
	(R)->next_to_clean - (R)->next_to_use - 1)

#define I40EVF_RX_DESC_ADV(R, i)	    \
	(&(((union i40e_adv_rx_desc *)((R).desc))[i]))
#define I40EVF_TX_DESC_ADV(R, i)	    \
	(&(((union i40e_adv_tx_desc *)((R).desc))[i]))
#define I40EVF_TX_CTXTDESC_ADV(R, i)	    \
	(&(((struct i40e_adv_tx_context_desc *)((R).desc))[i]))

#define OTHER_VECTOR 1
#define NONQ_VECS (OTHER_VECTOR)

#define MAX_MSIX_Q_VECTORS 4
#define MAX_MSIX_COUNT 5

#define MIN_MSIX_Q_VECTORS 1
#define MIN_MSIX_COUNT (MIN_MSIX_Q_VECTORS + NONQ_VECS)

#define I40EVF_QUEUE_END_OF_LIST 0x7FF
#define I40EVF_FREE_VECTOR 0x7FFF
struct i40evf_mac_filter {
	struct list_head list;
	u8 macaddr[ETH_ALEN];
	bool remove;		/* filter needs to be removed */
	bool add;		/* filter needs to be added */
};

struct i40evf_vlan_filter {
	struct list_head list;
	u16 vlan;
	bool remove;		/* filter needs to be removed */
	bool add;		/* filter needs to be added */
};

/* Driver state. The order of these is important! */
enum i40evf_state_t {
	__I40EVF_STARTUP,		/* driver loaded, probe complete */
	__I40EVF_FAILED,		/* PF communication failed. Fatal. */
	__I40EVF_REMOVE,		/* driver is being unloaded */
	__I40EVF_INIT_VERSION_CHECK,	/* aq msg sent, awaiting reply */
	__I40EVF_INIT_GET_RESOURCES,	/* aq msg sent, awaiting reply */
	__I40EVF_INIT_SW,		/* got resources, setting up structs */
	/* Below here, watchdog is running */
	__I40EVF_DOWN,			/* ready, can be opened */
	__I40EVF_TESTING,		/* in ethtool self-test */
	__I40EVF_RESETTING,		/* in reset */
	__I40EVF_RUNNING,		/* opened, working */
};

enum i40evf_critical_section_t {
	__I40EVF_IN_CRITICAL_TASK,	/* cannot be interrupted */
};
/* make common code happy */
#define __I40E_DOWN __I40EVF_DOWN

/* board specific private data structure */
struct i40evf_adapter {
	struct timer_list watchdog_timer;
	struct vlan_group *vlgrp;
	struct work_struct reset_task;
	struct work_struct adminq_task;
	struct delayed_work init_task;
	struct i40e_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
	struct list_head vlan_filter_list;
	char name[MAX_MSIX_COUNT][IFNAMSIZ + 9];

	/* Interrupt Throttle Rate */
	u32 itr_setting;
	u16 eitr_low;
	u16 eitr_high;

	/* TX */
	struct i40e_ring *tx_rings[I40E_MAX_VSI_QP];
	u64 restart_queue;
	u64 hw_csum_tx_good;
	u64 lsc_int;
	u64 hw_tso_ctxt;
	u64 hw_tso6_ctxt;
	u32 tx_timeout_count;
	struct list_head mac_filter_list;
#ifdef DEBUG
	bool detect_tx_hung;
#endif /* DEBUG */

	/* RX */
	struct i40e_ring *rx_rings[I40E_MAX_VSI_QP];
	int txd_count;
	int rxd_count;
	u64 hw_csum_rx_error;
	u64 hw_rx_no_dma_resources;
	u64 hw_csum_rx_good;
	u64 non_eop_descs;
	int num_msix_vectors;
	struct msix_entry *msix_entries;

	u64 rx_hdr_split;

	u32 init_state;
	volatile unsigned long flags;
#define I40EVF_FLAG_RX_CSUM_ENABLED              (u32)(1)
#define I40EVF_FLAG_RX_1BUF_CAPABLE              (u32)(1 << 1)
#define I40EVF_FLAG_RX_PS_CAPABLE                (u32)(1 << 2)
#define I40EVF_FLAG_RX_PS_ENABLED                (u32)(1 << 3)
#define I40EVF_FLAG_IN_NETPOLL                   (u32)(1 << 4)
#define I40EVF_FLAG_IMIR_ENABLED                 (u32)(1 << 5)
#define I40EVF_FLAG_MQ_CAPABLE                   (u32)(1 << 6)
#define I40EVF_FLAG_NEED_LINK_UPDATE             (u32)(1 << 7)
/* duplcates for common code */
#define I40E_FLAG_FDIR_ATR_ENABLED		 0
#define I40E_FLAG_DCB_ENABLED			 0
#define I40E_FLAG_IN_NETPOLL			 I40EVF_FLAG_IN_NETPOLL
#define I40E_FLAG_RX_CSUM_ENABLED                I40EVF_FLAG_RX_CSUM_ENABLED
	/* flags for admin queue service task */
	u32 aq_required;
	u32 aq_pending;
#define I40EVF_FLAG_AQ_ENABLE_QUEUES		(u32)(1)
#define I40EVF_FLAG_AQ_DISABLE_QUEUES		(u32)(1 << 1)
#define I40EVF_FLAG_AQ_ADD_MAC_FILTER		(u32)(1 << 2)
#define I40EVF_FLAG_AQ_ADD_VLAN_FILTER		(u32)(1 << 3)
#define I40EVF_FLAG_AQ_DEL_MAC_FILTER		(u32)(1 << 4)
#define I40EVF_FLAG_AQ_DEL_VLAN_FILTER		(u32)(1 << 5)
#define I40EVF_FLAG_AQ_CONFIGURE_QUEUES		(u32)(1 << 6)
#define I40EVF_FLAG_AQ_MAP_VECTORS		(u32)(1 << 7)
#define I40EVF_FLAG_AQ_HANDLE_RESET		(u32)(1 << 8)
	/* OS defined structs */
	struct net_device *netdev;
	struct pci_dev *pdev;
	struct net_device_stats net_stats;

	/* structs defined in i40e_vf.h */
	struct i40e_hw hw;

	enum i40evf_state_t state;
	volatile unsigned long crit_section;
	u64 tx_busy;

	struct work_struct watchdog_task;
	bool netdev_registered;
	bool dev_closed;
	bool link_up;
	enum i40e_virtchnl_ops current_op;
	struct i40e_virtchnl_vf_resource *vf_res; /* incl. all VSIs */
	struct i40e_virtchnl_vsi_resource *vsi_res; /* our LAN VSI */
	u16 msg_enable;
	struct i40e_eth_stats current_stats;
	struct i40e_vsi vsi;
	u32 aq_wait_count;
};

struct i40evf_info {
	enum i40e_mac_type	mac;
	unsigned int		flags;
};


/* needed by i40evf_ethtool.c */
extern char i40evf_driver_name[];
extern const char i40evf_driver_version[];

int i40evf_up(struct i40evf_adapter *adapter);
void i40evf_down(struct i40evf_adapter *adapter);
void i40evf_reinit_locked(struct i40evf_adapter *adapter);
void i40evf_reset(struct i40evf_adapter *adapter);
void i40evf_set_ethtool_ops(struct net_device *netdev);
void i40evf_update_stats(struct i40evf_adapter *adapter);
void i40evf_reset_interrupt_capability(struct i40evf_adapter *adapter);
int i40evf_init_interrupt_scheme(struct i40evf_adapter *adapter);
void i40evf_irq_enable_queues(struct i40evf_adapter *adapter, u32 mask);

void i40e_napi_add_all(struct i40evf_adapter *adapter);
void i40e_napi_del_all(struct i40evf_adapter *adapter);

int i40evf_send_api_ver(struct i40evf_adapter *adapter);
int i40evf_verify_api_ver(struct i40evf_adapter *adapter);
int i40evf_send_vf_config_msg(struct i40evf_adapter *adapter);
int i40evf_get_vf_config(struct i40evf_adapter *adapter);
void i40evf_irq_enable(struct i40evf_adapter *adapter, bool flush);
void i40evf_configure_queues(struct i40evf_adapter *adapter);
void i40evf_deconfigure_queues(struct i40evf_adapter *adapter);
void i40evf_enable_queues(struct i40evf_adapter *adapter);
void i40evf_disable_queues(struct i40evf_adapter *adapter);
void i40evf_map_queues(struct i40evf_adapter *adapter);
void i40evf_add_ether_addrs(struct i40evf_adapter *adapter);
void i40evf_del_ether_addrs(struct i40evf_adapter *adapter);
void i40evf_add_vlans(struct i40evf_adapter *adapter);
void i40evf_del_vlans(struct i40evf_adapter *adapter);
void i40evf_set_promiscuous(struct i40evf_adapter *adapter, int flags);
void i40evf_request_stats(struct i40evf_adapter *adapter);
void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
				enum i40e_virtchnl_ops v_opcode,
				i40e_status v_retval, u8 *msg, u16 msglen);
#endif /* _I40EVF_H_ */