summaryrefslogtreecommitdiffstats
path: root/src/drivers/net/sfc/efx_common.h
blob: 3487966ce2497030d30af1e5316857b0a5bbf6a4 (plain) (blame)
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
/**************************************************************************
 *
 * GPL common net driver for Solarflare network cards
 *
 * Written by Michael Brown <mbrown@fensystems.co.uk>
 *
 * Copyright Fen Systems Ltd. 2005
 * Copyright Level 5 Networks Inc. 2005
 * Copyright Solarflare Communications Inc. 2013-2017
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or any later version.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 *
 ***************************************************************************/
#ifndef EFX_COMMON_H
#define EFX_COMMON_H

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#define __packed    __attribute__((__packed__))
#define __force     /*nothing*/

typedef uint16_t    __le16;
typedef uint32_t    __le32;
typedef uint64_t    __le64;

#define BUILD_BUG_ON_ZERO(e) (sizeof(struct{int: -!!(e); }))
#define BUILD_BUG_ON(e) ((void)BUILD_BUG_ON_ZERO(e))

#include <stdbool.h>
#include <ipxe/io.h>
#include <ipxe/netdevice.h>
#include "efx_bitfield.h"
#include "mcdi.h"

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif

/**************************************************************************
 *
 * Hardware data structures and sizing
 *
 ***************************************************************************/
typedef efx_qword_t efx_rx_desc_t;
typedef efx_qword_t efx_tx_desc_t;
typedef efx_qword_t efx_event_t;

#define EFX_BUF_ALIGN		4096
#define EFX_RXD_SIZE		512
#define EFX_RXD_MASK            (EFX_RXD_SIZE - 1)
#define EFX_TXD_SIZE		512
#define EFX_TXD_MASK            (EFX_TXD_SIZE - 1)
#define EFX_EVQ_SIZE		512
#define EFX_EVQ_MASK            (EFX_EVQ_SIZE - 1)

/* There is space for 512 rx descriptors available. This number can be
 * anything between 1 and 512 in powers of 2. This value will affect the
 * network performance. During a test we were able to push 239 descriptors
 * before we ran out of space.
 */
#define EFX_NUM_RX_DESC		64
#define EFX_NUM_RX_DESC_MASK    (EFX_NUM_RX_DESC - 1)

/* The packet size is usually 1500 bytes hence we choose 1600 as the buf size,
 * which is (1500+metadata)
 */
#define EFX_RX_BUF_SIZE		1600

/* Settings for the state field in efx_nic.
 */
#define EFX_STATE_POLLING	1

typedef unsigned long long dma_addr_t;

/** A buffer table allocation backing a tx dma, rx dma or eventq */
struct efx_special_buffer {
	dma_addr_t dma_addr;
	int id;
};

/** A transmit queue */
struct efx_tx_queue {
	/* The hardware ring */
	efx_tx_desc_t *ring;

	/* The software ring storing io_buffers. */
	struct io_buffer *buf[EFX_TXD_SIZE];

	/* The buffer table reservation pushed to hardware */
	struct efx_special_buffer entry;

	/* Software descriptor write ptr */
	unsigned int write_ptr;

	/* Hardware descriptor read ptr */
	unsigned int read_ptr;
};

/** A receive queue */
struct efx_rx_queue {
	/* The hardware ring */
	efx_rx_desc_t *ring;

	/* The software ring storing io_buffers */
	struct io_buffer *buf[EFX_NUM_RX_DESC];

	/* The buffer table reservation pushed to hardware */
	struct efx_special_buffer entry;

	/* Descriptor write ptr, into both the hardware and software rings */
	unsigned int write_ptr;

	/* Hardware completion ptr */
	unsigned int read_ptr;

	/* The value of RX_CONT in the previous RX event */
	unsigned int rx_cont_prev;
};

/** An event queue */
struct efx_ev_queue {
	/* The hardware ring to push to hardware.
	 * Must be the first entry in the structure.
	 */
	efx_event_t *ring;

	/* The buffer table reservation pushed to hardware */
	struct efx_special_buffer entry;

	/* Pointers into the ring */
	unsigned int read_ptr;
};

/* Hardware revisions */
enum efx_revision {
	EFX_HUNTINGTON,
};

/** Hardware access */
struct efx_nic {
	struct net_device *netdev;
	enum efx_revision revision;
	const struct efx_nic_type *type;

	int port;
	u32 state;

	/** Memory and IO base */
	void *membase;
	unsigned long mmio_start;
	unsigned long mmio_len;

	/* Buffer table allocation head */
	int buffer_head;

	/* Queues */
	struct efx_rx_queue rxq;
	struct efx_tx_queue txq;
	struct efx_ev_queue evq;

	unsigned int rx_prefix_size;

	/** INT_REG_KER */
	int int_en;
	efx_oword_t int_ker __aligned;

	/* Set to true if firmware supports the workaround for bug35388 */
	bool workaround_35388;

};


/** Efx device type definition */
struct efx_nic_type {
	int (*mcdi_rpc)(struct efx_nic *efx, unsigned int cmd,
			const efx_dword_t *inbuf, size_t inlen,
			efx_dword_t *outbuf, size_t outlen,
			size_t *outlen_actual, bool quiet);
};

extern const struct efx_nic_type hunt_nic_type;

#define EFX_MAC_FRAME_LEN(_mtu)					\
	(((_mtu)						\
	  + /* EtherII already included */			\
	  + 4 /* FCS */						\
	  /* No VLAN supported */				\
	  + 16 /* bug16772 */					\
	  + 7) & ~7)

/*******************************************************************************
 *
 *
 * Hardware API
 *
 *
 ******************************************************************************/
static inline void _efx_writel(struct efx_nic *efx, uint32_t value,
			       unsigned int reg)
{
	writel((value), (efx)->membase + (reg));
}

static inline uint32_t _efx_readl(struct efx_nic *efx, unsigned int reg)
{
	return readl((efx)->membase + (reg));
}

#define efx_writel_table(efx, value, index, reg)		\
	efx_writel(efx, value, (reg) + ((index) * reg##_STEP))

#define efx_writel_page(efx, value, index, reg)			\
	efx_writel(efx, value, (reg) + ((index) * 0x2000))

/* Hardware access */
extern void efx_writel(struct efx_nic *efx, efx_dword_t *value,
		       unsigned int reg);
extern void efx_readl(struct efx_nic *efx, efx_dword_t *value,
		      unsigned int reg);

/* Initialisation */
extern void efx_probe(struct net_device *netdev, enum efx_revision rev);
extern void efx_remove(struct net_device *netdev);

#endif /* EFX_COMMON_H */