summaryrefslogtreecommitdiffstats
path: root/src/drivers/net/exanic.h
blob: 041b9e21ab28100b67925814e611620799435fde (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
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
#ifndef _EXANIC_H
#define _EXANIC_H

/** @file
 *
 * Exablaze ExaNIC driver
 *
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdint.h>
#include <ipxe/pci.h>
#include <ipxe/ethernet.h>
#include <ipxe/uaccess.h>
#include <ipxe/retry.h>
#include <ipxe/i2c.h>
#include <ipxe/bitbash.h>

/** Maximum number of ports */
#define EXANIC_MAX_PORTS 8

/** Register BAR */
#define EXANIC_REGS_BAR PCI_BASE_ADDRESS_0

/** Transmit region BAR */
#define EXANIC_TX_BAR PCI_BASE_ADDRESS_2

/** Alignment for DMA regions */
#define EXANIC_ALIGN 0x1000

/** Flag for 32-bit DMA addresses */
#define EXANIC_DMA_32_BIT 0x00000001UL

/** Register set length */
#define EXANIC_REGS_LEN 0x2000

/** Transmit feedback region length */
#define EXANIC_TXF_LEN 0x1000

/** Transmit feedback slot
 *
 * This is a policy decision.
 */
#define EXANIC_TXF_SLOT( index ) ( 0x40 * (index) )

/** Receive region length */
#define EXANIC_RX_LEN 0x200000

/** Transmit feedback base address register */
#define EXANIC_TXF_BASE 0x0014

/** Capabilities register */
#define EXANIC_CAPS 0x0038
#define EXANIC_CAPS_100M 0x01000000UL		/**< 100Mbps supported */
#define EXANIC_CAPS_1G 0x02000000UL		/**< 1Gbps supported */
#define EXANIC_CAPS_10G 0x04000000UL		/**< 10Gbps supported */
#define EXANIC_CAPS_40G 0x08000000UL		/**< 40Gbps supported */
#define EXANIC_CAPS_100G 0x10000000UL		/**< 100Gbps supported */
#define EXANIC_CAPS_SPEED_MASK 0x1f000000UL	/**< Supported speeds mask */

/** I2C GPIO register */
#define EXANIC_I2C 0x012c

/** Power control register */
#define EXANIC_POWER 0x0138
#define EXANIC_POWER_ON 0x000000f0UL		/**< Power on PHYs */

/** Port register offset */
#define EXANIC_PORT_REGS( index ) ( 0x0200 + ( 0x40 * (index) ) )

/** Port enable register */
#define EXANIC_PORT_ENABLE 0x0000
#define EXANIC_PORT_ENABLE_ENABLED 0x00000001UL	/**< Port is enabled */

/** Port speed register */
#define EXANIC_PORT_SPEED 0x0004

/** Port status register */
#define EXANIC_PORT_STATUS 0x0008
#define EXANIC_PORT_STATUS_LINK 0x00000008UL	/**< Link is up */
#define EXANIC_PORT_STATUS_ABSENT 0x80000000UL	/**< Port is not present */

/** Port MAC address (second half) register */
#define EXANIC_PORT_MAC 0x000c

/** Port flags register */
#define EXANIC_PORT_FLAGS 0x0010
#define EXANIC_PORT_FLAGS_PROMISC 0x00000001UL	/**< Promiscuous mode */

/** Port receive chunk base address register */
#define EXANIC_PORT_RX_BASE 0x0014

/** Port transmit command register */
#define EXANIC_PORT_TX_COMMAND 0x0020

/** Port transmit region offset register */
#define EXANIC_PORT_TX_OFFSET 0x0024

/** Port transmit region length register */
#define EXANIC_PORT_TX_LEN 0x0028

/** Port MAC address (first half) register */
#define EXANIC_PORT_OUI 0x0030

/** Port interrupt configuration register */
#define EXANIC_PORT_IRQ 0x0034

/** An ExaNIC transmit chunk descriptor */
struct exanic_tx_descriptor {
	/** Feedback ID */
	uint16_t txf_id;
	/** Feedback slot */
	uint16_t txf_slot;
	/** Payload length (including padding */
	uint16_t len;
	/** Payload type */
	uint8_t type;
	/** Flags */
	uint8_t flags;
} __attribute__ (( packed ));

/** An ExaNIC transmit chunk */
struct exanic_tx_chunk {
	/** Descriptor */
	struct exanic_tx_descriptor desc;
	/** Padding */
	uint8_t pad[2];
	/** Payload data */
	uint8_t data[2038];
} __attribute__ (( packed ));

/** Raw Ethernet frame type */
#define EXANIC_TYPE_RAW 0x01

/** An ExaNIC receive chunk descriptor */
struct exanic_rx_descriptor {
	/** Timestamp */
	uint32_t timestamp;
	/** Status (valid only on final chunk) */
	uint8_t status;
	/** Length (zero except on the final chunk) */
	uint8_t len;
	/** Filter number */
	uint8_t filter;
	/** Generation */
	uint8_t generation;
} __attribute__ (( packed ));

/** An ExaNIC receive chunk */
struct exanic_rx_chunk {
	/** Payload data */
	uint8_t data[120];
	/** Descriptor */
	struct exanic_rx_descriptor desc;
} __attribute__ (( packed ));

/** Receive status error mask */
#define EXANIC_STATUS_ERROR_MASK 0x0f

/** An ExaNIC I2C bus configuration */
struct exanic_i2c_config {
	/** GPIO bit for pulling SCL low */
	uint8_t setscl;
	/** GPIO bit for pulling SDA low */
	uint8_t setsda;
	/** GPIO bit for reading SDA */
	uint8_t getsda;
};

/** EEPROM address */
#define EXANIC_EEPROM_ADDRESS 0x50

/** An ExaNIC port */
struct exanic_port {
	/** Network device */
	struct net_device *netdev;
	/** Port registers */
	void *regs;

	/** Transmit region offset */
	size_t tx_offset;
	/** Transmit region */
	void *tx;
	/** Number of transmit descriptors */
	uint16_t tx_count;
	/** Transmit producer counter */
	uint16_t tx_prod;
	/** Transmit consumer counter */
	uint16_t tx_cons;
	/** Transmit feedback slot */
	uint16_t txf_slot;
	/** Transmit feedback region */
	uint16_t *txf;

	/** Receive region */
	userptr_t rx;
	/** Receive consumer counter */
	unsigned int rx_cons;
	/** Receive I/O buffer (if any) */
	struct io_buffer *rx_iobuf;
	/** Receive status */
	int rx_rc;

	/** Port status */
	uint32_t status;
	/** Default link speed (as raw register value) */
	uint32_t default_speed;
	/** Speed capability bitmask */
	uint32_t speeds;
	/** Current attempted link speed (as a capability bit index) */
	unsigned int speed;
	/** Port status check timer */
	struct retry_timer timer;
};

/** An ExaNIC */
struct exanic {
	/** Registers */
	void *regs;
	/** Transmit region */
	void *tx;
	/** Transmit feedback region */
	void *txf;

	/** I2C bus configuration */
	struct exanic_i2c_config i2cfg;
	/** I2C bit-bashing interface */
	struct i2c_bit_basher basher;
	/** I2C serial EEPROM */
	struct i2c_device eeprom;

	/** Capabilities */
	uint32_t caps;
	/** Base MAC address */
	uint8_t mac[ETH_ALEN];

	/** Ports */
	struct exanic_port *port[EXANIC_MAX_PORTS];
};

/** Maximum used length of transmit region
 *
 * This is a policy decision to avoid overflowing the 16-bit transmit
 * producer and consumer counters.
 */
#define EXANIC_MAX_TX_LEN ( 256 * sizeof ( struct exanic_tx_chunk ) )

/** Maximum length of received packet
 *
 * This is a policy decision.
 */
#define EXANIC_MAX_RX_LEN ( ETH_FRAME_LEN + 4 /* VLAN */ + 4 /* CRC */ )

/** Interval between link state checks
 *
 * This is a policy decision.
 */
#define EXANIC_LINK_INTERVAL ( 1 * TICKS_PER_SEC )

#endif /* _EXANIC_H */