Browse Source

[intelxl] Add driver for Intel 40 Gigabit Ethernet NICs

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 6 years ago
parent
commit
d2063b7693
3 changed files with 2316 additions and 0 deletions
  1. 1525
    0
      src/drivers/net/intelxl.c
  2. 790
    0
      src/drivers/net/intelxl.h
  3. 1
    0
      src/include/ipxe/errfile.h

+ 1525
- 0
src/drivers/net/intelxl.c
File diff suppressed because it is too large
View File


+ 790
- 0
src/drivers/net/intelxl.h View File

@@ -0,0 +1,790 @@
1
+#ifndef _INTELX_H
2
+#define _INTELX_H
3
+
4
+/** @file
5
+ *
6
+ * Intel 40 Gigabit Ethernet network card driver
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11
+
12
+#include <stdint.h>
13
+#include <ipxe/if_ether.h>
14
+
15
+struct intelxl_nic;
16
+
17
+/** BAR size */
18
+#define INTELXL_BAR_SIZE 0x200000
19
+
20
+/** Alignment
21
+ *
22
+ * No data structure requires greater than 128 byte alignment.
23
+ */
24
+#define INTELXL_ALIGN 128
25
+
26
+/******************************************************************************
27
+ *
28
+ * Admin queue
29
+ *
30
+ ******************************************************************************
31
+ */
32
+
33
+/** PF Admin Command Queue register block */
34
+#define INTELXL_ADMIN_CMD 0x080000
35
+
36
+/** PF Admin Event Queue register block */
37
+#define INTELXL_ADMIN_EVT 0x080080
38
+
39
+/** Admin Queue Base Address Low Register (offset) */
40
+#define INTELXL_ADMIN_BAL 0x000
41
+
42
+/** Admin Queue Base Address High Register (offset) */
43
+#define INTELXL_ADMIN_BAH 0x100
44
+
45
+/** Admin Queue Length Register (offset) */
46
+#define INTELXL_ADMIN_LEN 0x200
47
+#define INTELXL_ADMIN_LEN_LEN(x)	( (x) << 0 )	/**< Queue length */
48
+#define INTELXL_ADMIN_LEN_ENABLE	0x80000000UL	/**< Queue enable */
49
+
50
+/** Admin Queue Head Register (offset) */
51
+#define INTELXL_ADMIN_HEAD 0x300
52
+
53
+/** Admin Queue Tail Register (offset) */
54
+#define INTELXL_ADMIN_TAIL 0x400
55
+
56
+/** Admin queue data buffer command parameters */
57
+struct intelxl_admin_buffer_params {
58
+	/** Reserved */
59
+	uint8_t reserved[8];
60
+	/** Buffer address high */
61
+	uint32_t high;
62
+	/** Buffer address low */
63
+	uint32_t low;
64
+} __attribute__ (( packed ));
65
+
66
+/** Admin queue Get Version command */
67
+#define INTELXL_ADMIN_VERSION 0x0001
68
+
69
+/** Admin queue version number */
70
+struct intelxl_admin_version {
71
+	/** Major version number */
72
+	uint16_t major;
73
+	/** Minor version number */
74
+	uint16_t minor;
75
+} __attribute__ (( packed ));
76
+
77
+/** Admin queue Get Version command parameters */
78
+struct intelxl_admin_version_params {
79
+	/** ROM version */
80
+	uint32_t rom;
81
+	/** Firmware build ID */
82
+	uint32_t build;
83
+	/** Firmware version */
84
+	struct intelxl_admin_version firmware;
85
+	/** API version */
86
+	struct intelxl_admin_version api;
87
+} __attribute__ (( packed ));
88
+
89
+/** Admin queue Driver Version command */
90
+#define INTELXL_ADMIN_DRIVER 0x0002
91
+
92
+/** Admin queue Driver Version command parameters */
93
+struct intelxl_admin_driver_params {
94
+	/** Driver version */
95
+	uint8_t major;
96
+	/** Minor version */
97
+	uint8_t minor;
98
+	/** Build version */
99
+	uint8_t build;
100
+	/** Sub-build version */
101
+	uint8_t sub;
102
+	/** Reserved */
103
+	uint8_t reserved[4];
104
+	/** Data buffer address */
105
+	uint64_t address;
106
+} __attribute__ (( packed ));
107
+
108
+/** Admin queue Driver Version data buffer */
109
+struct intelxl_admin_driver_buffer {
110
+	/** Driver name */
111
+	char name[32];
112
+} __attribute__ (( packed ));
113
+
114
+/** Admin queue Shutdown command */
115
+#define INTELXL_ADMIN_SHUTDOWN 0x0003
116
+
117
+/** Admin queue Shutdown command parameters */
118
+struct intelxl_admin_shutdown_params {
119
+	/** Driver unloading */
120
+	uint8_t unloading;
121
+	/** Reserved */
122
+	uint8_t reserved[15];
123
+} __attribute__ (( packed ));
124
+
125
+/** Driver is unloading */
126
+#define INTELXL_ADMIN_SHUTDOWN_UNLOADING 0x01
127
+
128
+/** Admin queue Get Switch Configuration command */
129
+#define INTELXL_ADMIN_SWITCH 0x0200
130
+
131
+/** Switching element configuration */
132
+struct intelxl_admin_switch_config {
133
+	/** Switching element type */
134
+	uint8_t type;
135
+	/** Revision */
136
+	uint8_t revision;
137
+	/** Switching element ID */
138
+	uint16_t seid;
139
+	/** Uplink switching element ID */
140
+	uint16_t uplink;
141
+	/** Downlink switching element ID */
142
+	uint16_t downlink;
143
+	/** Reserved */
144
+	uint8_t reserved_b[3];
145
+	/** Connection type */
146
+	uint8_t connection;
147
+	/** Reserved */
148
+	uint8_t reserved_c[2];
149
+	/** Element specific information */
150
+	uint16_t info;
151
+} __attribute__ (( packed ));
152
+
153
+/** Virtual Station Inferface element type */
154
+#define INTELXL_ADMIN_SWITCH_TYPE_VSI 19
155
+
156
+/** Admin queue Get Switch Configuration command parameters */
157
+struct intelxl_admin_switch_params {
158
+	/** Starting switching element identifier */
159
+	uint16_t next;
160
+	/** Reserved */
161
+	uint8_t reserved[6];
162
+	/** Data buffer address */
163
+	uint64_t address;
164
+} __attribute__ (( packed ));
165
+
166
+/** Admin queue Get Switch Configuration data buffer */
167
+struct intelxl_admin_switch_buffer {
168
+	/** Number of switching elements reported */
169
+	uint16_t count;
170
+	/** Total number of switching elements */
171
+	uint16_t total;
172
+	/** Reserved */
173
+	uint8_t reserved_a[12];
174
+	/** Switch configuration */
175
+	struct intelxl_admin_switch_config cfg;
176
+} __attribute__ (( packed ));
177
+
178
+/** Admin queue Get VSI Parameters command */
179
+#define INTELXL_ADMIN_VSI 0x0212
180
+
181
+/** Admin queue Get VSI Parameters command parameters */
182
+struct intelxl_admin_vsi_params {
183
+	/** VSI switching element ID */
184
+	uint16_t vsi;
185
+	/** Reserved */
186
+	uint8_t reserved[6];
187
+	/** Data buffer address */
188
+	uint64_t address;
189
+} __attribute__ (( packed ));
190
+
191
+/** Admin queue Get VSI Parameters data buffer */
192
+struct intelxl_admin_vsi_buffer {
193
+	/** Reserved */
194
+	uint8_t reserved_a[30];
195
+	/** Queue numbers */
196
+	uint16_t queue[16];
197
+	/** Reserved */
198
+	uint8_t reserved_b[34];
199
+	/** Queue set handles for each traffic class */
200
+	uint16_t qset[8];
201
+	/** Reserved */
202
+	uint8_t reserved_c[16];
203
+} __attribute__ (( packed ));
204
+
205
+/** Admin queue Set VSI Promiscuous Modes command */
206
+#define INTELXL_ADMIN_PROMISC 0x0254
207
+
208
+/** Admin queue Set VSI Promiscuous Modes command parameters */
209
+struct intelxl_admin_promisc_params {
210
+	/** Flags */
211
+	uint16_t flags;
212
+	/** Valid flags */
213
+	uint16_t valid;
214
+	/** VSI switching element ID */
215
+	uint16_t vsi;
216
+	/** Reserved */
217
+	uint8_t reserved[10];
218
+} __attribute__ (( packed ));
219
+
220
+/** Promiscuous unicast mode */
221
+#define INTELXL_ADMIN_PROMISC_FL_UNICAST 0x0001
222
+
223
+/** Promiscuous multicast mode */
224
+#define INTELXL_ADMIN_PROMISC_FL_MULTICAST 0x0002
225
+
226
+/** Promiscuous broadcast mode */
227
+#define INTELXL_ADMIN_PROMISC_FL_BROADCAST 0x0004
228
+
229
+/** Promiscuous VLAN mode */
230
+#define INTELXL_ADMIN_PROMISC_FL_VLAN 0x0010
231
+
232
+/** Admin queue Restart Autonegotiation command */
233
+#define INTELXL_ADMIN_AUTONEG 0x0605
234
+
235
+/** Admin queue Restart Autonegotiation command parameters */
236
+struct intelxl_admin_autoneg_params {
237
+	/** Flags */
238
+	uint8_t flags;
239
+	/** Reserved */
240
+	uint8_t reserved[15];
241
+} __attribute__ (( packed ));
242
+
243
+/** Restart autonegotiation */
244
+#define INTELXL_ADMIN_AUTONEG_FL_RESTART 0x02
245
+
246
+/** Enable link */
247
+#define INTELXL_ADMIN_AUTONEG_FL_ENABLE 0x04
248
+
249
+/** Admin queue Get Link Status command */
250
+#define INTELXL_ADMIN_LINK 0x0607
251
+
252
+/** Admin queue Get Link Status command parameters */
253
+struct intelxl_admin_link_params {
254
+	/** Link status notification */
255
+	uint8_t notify;
256
+	/** Reserved */
257
+	uint8_t reserved_a;
258
+	/** PHY type */
259
+	uint8_t phy;
260
+	/** Link speed */
261
+	uint8_t speed;
262
+	/** Link status */
263
+	uint8_t status;
264
+	/** Reserved */
265
+	uint8_t reserved_b[11];
266
+} __attribute__ (( packed ));
267
+
268
+/** Notify driver of link status changes */
269
+#define INTELXL_ADMIN_LINK_NOTIFY 0x03
270
+
271
+/** Link is up */
272
+#define INTELXL_ADMIN_LINK_UP 0x01
273
+
274
+/** Admin queue command parameters */
275
+union intelxl_admin_params {
276
+	/** Additional data buffer command parameters */
277
+	struct intelxl_admin_buffer_params buffer;
278
+	/** Get Version command parameters */
279
+	struct intelxl_admin_version_params version;
280
+	/** Driver Version command parameters */
281
+	struct intelxl_admin_driver_params driver;
282
+	/** Shutdown command parameters */
283
+	struct intelxl_admin_shutdown_params shutdown;
284
+	/** Get Switch Configuration command parameters */
285
+	struct intelxl_admin_switch_params sw;
286
+	/** Get VSI Parameters command parameters */
287
+	struct intelxl_admin_vsi_params vsi;
288
+	/** Set VSI Promiscuous Modes command parameters */
289
+	struct intelxl_admin_promisc_params promisc;
290
+	/** Restart Autonegotiation command parameters */
291
+	struct intelxl_admin_autoneg_params autoneg;
292
+	/** Get Link Status command parameters */
293
+	struct intelxl_admin_link_params link;
294
+} __attribute__ (( packed ));
295
+
296
+/** Admin queue data buffer */
297
+union intelxl_admin_buffer {
298
+	/** Driver Version data buffer */
299
+	struct intelxl_admin_driver_buffer driver;
300
+	/** Get Switch Configuration data buffer */
301
+	struct intelxl_admin_switch_buffer sw;
302
+	/** Get VSI Parameters data buffer */
303
+	struct intelxl_admin_vsi_buffer vsi;
304
+} __attribute__ (( packed ));
305
+
306
+/** Admin queue descriptor */
307
+struct intelxl_admin_descriptor {
308
+	/** Flags */
309
+	uint16_t flags;
310
+	/** Opcode */
311
+	uint16_t opcode;
312
+	/** Data length */
313
+	uint16_t len;
314
+	/** Return value */
315
+	uint16_t ret;
316
+	/** Cookie */
317
+	uint32_t cookie;
318
+	/** Reserved */
319
+	uint32_t reserved;
320
+	/** Parameters */
321
+	union intelxl_admin_params params;
322
+} __attribute__ (( packed ));
323
+
324
+/** Admin descriptor done */
325
+#define INTELXL_ADMIN_FL_DD 0x0001
326
+
327
+/** Admin descriptor contains a completion */
328
+#define INTELXL_ADMIN_FL_CMP 0x0002
329
+
330
+/** Admin descriptor completed in error */
331
+#define INTELXL_ADMIN_FL_ERR 0x0004
332
+
333
+/** Admin descriptor uses data buffer for command parameters */
334
+#define INTELXL_ADMIN_FL_RD 0x0400
335
+
336
+/** Admin descriptor uses data buffer */
337
+#define INTELXL_ADMIN_FL_BUF 0x1000
338
+
339
+/** Admin queue */
340
+struct intelxl_admin {
341
+	/** Descriptors */
342
+	struct intelxl_admin_descriptor *desc;
343
+	/** Queue index */
344
+	unsigned int index;
345
+
346
+	/** Register block */
347
+	unsigned int reg;
348
+	/** Data buffer */
349
+	union intelxl_admin_buffer *buffer;
350
+};
351
+
352
+/**
353
+ * Initialise admin queue
354
+ *
355
+ * @v admin		Admin queue
356
+ * @v reg		Register block
357
+ */
358
+static inline __attribute__ (( always_inline )) void
359
+intelxl_init_admin ( struct intelxl_admin *admin, unsigned int reg ) {
360
+
361
+	admin->reg = reg;
362
+}
363
+
364
+/** Number of admin queue descriptors */
365
+#define INTELXL_ADMIN_NUM_DESC 4
366
+
367
+/** Maximum time to wait for an admin request to complete */
368
+#define INTELXL_ADMIN_MAX_WAIT_MS 100
369
+
370
+/** Admin queue API major version */
371
+#define INTELXL_ADMIN_API_MAJOR 1
372
+
373
+/******************************************************************************
374
+ *
375
+ * Transmit and receive queue context
376
+ *
377
+ ******************************************************************************
378
+ */
379
+
380
+/** CMLAN Context Data Register */
381
+#define INTELXL_PFCM_LANCTXDATA(x) ( 0x10c100 + ( 0x80 * (x) ) )
382
+
383
+/** CMLAN Context Control Register */
384
+#define INTELXL_PFCM_LANCTXCTL 0x10c300
385
+#define INTELXL_PFCM_LANCTXCTL_QUEUE_NUM(x) \
386
+	( (x) << 0 )					/**< Queue number */
387
+#define INTELXL_PFCM_LANCTXCTL_SUB_LINE(x) \
388
+	( (x) << 12 )					/**< Sub-line */
389
+#define INTELXL_PFCM_LANCTXCTL_TYPE(x) \
390
+	( (x) << 15 )					/**< Queue type */
391
+#define INTELXL_PFCM_LANCTXCTL_TYPE_RX \
392
+	INTELXL_PFCM_LANCTXCTL_TYPE ( 0x0 )		/**< RX queue type */
393
+#define INTELXL_PFCM_LANCTXCTL_TYPE_TX \
394
+	INTELXL_PFCM_LANCTXCTL_TYPE ( 0x1 )		/**< TX queue type */
395
+#define INTELXL_PFCM_LANCTXCTL_OP_CODE(x) \
396
+	( (x) << 17 )					/**< Op code */
397
+#define INTELXL_PFCM_LANCTXCTL_OP_CODE_READ \
398
+	INTELXL_PFCM_LANCTXCTL_OP_CODE ( 0x0 )		/**< Read context */
399
+#define INTELXL_PFCM_LANCTXCTL_OP_CODE_WRITE \
400
+	INTELXL_PFCM_LANCTXCTL_OP_CODE ( 0x1 )		/**< Write context */
401
+
402
+/** CMLAN Context Status Register */
403
+#define INTELXL_PFCM_LANCTXSTAT 0x10c380
404
+#define INTELXL_PFCM_LANCTXSTAT_DONE   0x00000001UL	/**< Complete */
405
+
406
+/** Queue context line */
407
+struct intelxl_context_line {
408
+	/** Raw data */
409
+	uint32_t raw[4];
410
+} __attribute__ (( packed ));
411
+
412
+/** Transmit queue context */
413
+struct intelxl_context_tx {
414
+	/** Head pointer */
415
+	uint16_t head;
416
+	/** Flags */
417
+	uint16_t flags;
418
+	/** Base address */
419
+	uint64_t base;
420
+	/** Reserved */
421
+	uint8_t reserved_a[8];
422
+	/** Queue count */
423
+	uint16_t count;
424
+	/** Reserved */
425
+	uint8_t reserved_b[100];
426
+	/** Queue set */
427
+	uint16_t qset;
428
+	/** Reserved */
429
+	uint8_t reserved_c[4];
430
+} __attribute__ (( packed ));
431
+
432
+/** New transmit queue context */
433
+#define INTELXL_CTX_TX_FL_NEW 0x4000
434
+
435
+/** Transmit queue base address */
436
+#define INTELXL_CTX_TX_BASE( base ) ( (base) >> 7 )
437
+
438
+/** Transmit queue count */
439
+#define INTELXL_CTX_TX_COUNT( count ) ( (count) << 1 )
440
+
441
+/** Transmit queue set */
442
+#define INTELXL_CTX_TX_QSET( qset) ( (qset) << 4 )
443
+
444
+/** Receive queue context */
445
+struct intelxl_context_rx {
446
+	/** Head pointer */
447
+	uint16_t head;
448
+	/** Reserved */
449
+	uint8_t reserved_a[2];
450
+	/** Base address and queue count */
451
+	uint64_t base_count;
452
+	/** Data buffer length */
453
+	uint16_t len;
454
+	/** Flags */
455
+	uint8_t flags;
456
+	/** Reserved */
457
+	uint8_t reserved_b[7];
458
+	/** Maximum frame size */
459
+	uint16_t mfs;
460
+} __attribute__ (( packed ));
461
+
462
+/** Receive queue base address and queue count */
463
+#define INTELXL_CTX_RX_BASE_COUNT( base, count ) \
464
+	( ( (base) >> 7 ) | ( ( ( uint64_t ) (count) ) << 57 ) )
465
+
466
+/** Receive queue data buffer length */
467
+#define INTELXL_CTX_RX_LEN( len ) ( (len) >> 1 )
468
+
469
+/** Strip CRC from received packets */
470
+#define INTELXL_CTX_RX_FL_CRCSTRIP 0x20
471
+
472
+/** Receive queue maximum frame size */
473
+#define INTELXL_CTX_RX_MFS( mfs ) ( (mfs) >> 2 )
474
+
475
+/** Maximum time to wait for a context operation to complete */
476
+#define INTELXL_CTX_MAX_WAIT_MS 100
477
+
478
+/** Time to wait for a queue to become enabled */
479
+#define INTELXL_QUEUE_ENABLE_DELAY_US 20
480
+
481
+/** Time to wait for a transmit queue to become pre-disabled */
482
+#define INTELXL_QUEUE_PRE_DISABLE_DELAY_US 400
483
+
484
+/** Maximum time to wait for a queue to become disabled */
485
+#define INTELXL_QUEUE_DISABLE_MAX_WAIT_MS 1000
486
+
487
+/******************************************************************************
488
+ *
489
+ * Transmit and receive descriptors
490
+ *
491
+ ******************************************************************************
492
+ */
493
+
494
+/** Global Transmit Queue Head register */
495
+#define INTELXL_QTX_HEAD(x) ( 0x0e4000 + ( 0x4 * (x) ) )
496
+
497
+/** Global Transmit Pre Queue Disable register */
498
+#define INTELXL_GLLAN_TXPRE_QDIS(x) ( 0x0e6500 + ( 0x4 * ( (x) / 0x80 ) ) )
499
+#define INTELXL_GLLAN_TXPRE_QDIS_QINDX(x) \
500
+	( (x) << 0 )					/**< Queue index */
501
+#define INTELXL_GLLAN_TXPRE_QDIS_SET_QDIS \
502
+	0x40000000UL					/**< Set disable */
503
+#define INTELXL_GLLAN_TXPRE_QDIS_CLEAR_QDIS				\
504
+	0x80000000UL					/**< Clear disable */
505
+
506
+/** Global Transmit Queue register block */
507
+#define INTELXL_QTX(x) ( 0x100000 + ( 0x4 * (x) ) )
508
+
509
+/** Global Receive Queue register block */
510
+#define INTELXL_QRX(x) ( 0x120000 + ( 0x4 * (x) ) )
511
+
512
+/** Queue Enable Register (offset) */
513
+#define INTELXL_QXX_ENA 0x0000
514
+#define INTELXL_QXX_ENA_REQ		0x00000001UL	/**< Enable request */
515
+#define INTELXL_QXX_ENA_STAT		0x00000004UL	/**< Enabled status */
516
+
517
+/** Queue Control Register (offset) */
518
+#define INTELXL_QXX_CTL 0x4000
519
+#define INTELXL_QXX_CTL_PFVF_Q(x)	( (x) << 0 )	/**< PF/VF queue */
520
+#define INTELXL_QXX_CTL_PFVF_Q_PF \
521
+	INTELXL_QXX_CTL_PFVF_Q ( 0x2 )			/**< PF queue */
522
+#define INTELXL_QXX_CTL_PFVF_PF_INDX(x)	( (x) << 2 )	/**< PF index */
523
+
524
+/** Queue Tail Pointer Register (offset) */
525
+#define INTELXL_QXX_TAIL 0x8000
526
+
527
+/** Transmit data descriptor */
528
+struct intelxl_tx_data_descriptor {
529
+	/** Buffer address */
530
+	uint64_t address;
531
+	/** Flags */
532
+	uint32_t flags;
533
+	/** Length */
534
+	uint32_t len;
535
+} __attribute__ (( packed ));
536
+
537
+/** Transmit data descriptor type */
538
+#define INTELXL_TX_DATA_DTYP 0x0
539
+
540
+/** Transmit data descriptor end of packet */
541
+#define INTELXL_TX_DATA_EOP 0x10
542
+
543
+/** Transmit data descriptor report status */
544
+#define INTELXL_TX_DATA_RS 0x20
545
+
546
+/** Transmit data descriptor pretty please
547
+ *
548
+ * This bit is completely missing from older versions of the XL710
549
+ * datasheet.  Later versions describe it innocuously as "reserved,
550
+ * must be 1".  Without this bit, everything will appear to work (up
551
+ * to and including the port "transmit good octets" counter), but no
552
+ * packet will actually be sent.
553
+ */
554
+#define INTELXL_TX_DATA_JFDI 0x40
555
+
556
+/** Transmit data descriptor length */
557
+#define INTELXL_TX_DATA_LEN( len ) ( (len) << 2 )
558
+
559
+/** Transmit writeback descriptor */
560
+struct intelxl_tx_writeback_descriptor {
561
+	/** Reserved */
562
+	uint8_t reserved_a[8];
563
+	/** Flags */
564
+	uint8_t flags;
565
+	/** Reserved */
566
+	uint8_t reserved_b[7];
567
+} __attribute__ (( packed ));
568
+
569
+/** Transmit writeback descriptor complete */
570
+#define INTELXL_TX_WB_FL_DD 0x01
571
+
572
+/** Receive data descriptor */
573
+struct intelxl_rx_data_descriptor {
574
+	/** Buffer address */
575
+	uint64_t address;
576
+	/** Flags */
577
+	uint32_t flags;
578
+	/** Reserved */
579
+	uint8_t reserved[4];
580
+} __attribute__ (( packed ));
581
+
582
+/** Receive writeback descriptor */
583
+struct intelxl_rx_writeback_descriptor {
584
+	/** Reserved */
585
+	uint8_t reserved[8];
586
+	/** Flags */
587
+	uint32_t flags;
588
+	/** Length */
589
+	uint32_t len;
590
+} __attribute__ (( packed ));
591
+
592
+/** Receive writeback descriptor complete */
593
+#define INTELXL_RX_WB_FL_DD 0x00000001UL
594
+
595
+/** Receive writeback descriptor error */
596
+#define INTELXL_RX_WB_FL_RXE 0x00080000UL
597
+
598
+/** Receive writeback descriptor length */
599
+#define INTELXL_RX_WB_LEN(len) ( ( (len) >> 6 ) & 0x3fff )
600
+
601
+/** Packet descriptor */
602
+union intelxl_descriptor {
603
+	/** Transmit data descriptor */
604
+	struct intelxl_tx_data_descriptor tx;
605
+	/** Transmit writeback descriptor */
606
+	struct intelxl_tx_writeback_descriptor tx_wb;
607
+	/** Receive data descriptor */
608
+	struct intelxl_rx_data_descriptor rx;
609
+	/** Receive writeback descriptor */
610
+	struct intelxl_rx_writeback_descriptor rx_wb;
611
+};
612
+
613
+/** Descriptor ring */
614
+struct intelxl_ring {
615
+	/** Descriptors */
616
+	union intelxl_descriptor *desc;
617
+	/** Producer index */
618
+	unsigned int prod;
619
+	/** Consumer index */
620
+	unsigned int cons;
621
+
622
+	/** Register block */
623
+	unsigned int reg;
624
+	/** Length (in bytes) */
625
+	size_t len;
626
+	/** Program queue context
627
+	 *
628
+	 * @v intelxl		Intel device
629
+	 * @v address		Descriptor ring base address
630
+	 */
631
+	int ( * context ) ( struct intelxl_nic *intelxl, physaddr_t address );
632
+};
633
+
634
+/**
635
+ * Initialise descriptor ring
636
+ *
637
+ * @v ring		Descriptor ring
638
+ * @v count		Number of descriptors
639
+ * @v context		Method to program queue context
640
+ */
641
+static inline __attribute__ (( always_inline)) void
642
+intelxl_init_ring ( struct intelxl_ring *ring, unsigned int count,
643
+		    int ( * context ) ( struct intelxl_nic *intelxl,
644
+					physaddr_t address ) ) {
645
+
646
+	ring->len = ( count * sizeof ( ring->desc[0] ) );
647
+	ring->context = context;
648
+}
649
+
650
+/** Number of transmit descriptors */
651
+#define INTELXL_TX_NUM_DESC 16
652
+
653
+/** Transmit descriptor ring maximum fill level */
654
+#define INTELXL_TX_FILL ( INTELXL_TX_NUM_DESC - 1 )
655
+
656
+/** Number of receive descriptors
657
+ *
658
+ * In PXE mode (i.e. able to post single receive descriptors), 8
659
+ * descriptors is the only permitted value covering all possible
660
+ * numbers of PFs.
661
+ */
662
+#define INTELXL_RX_NUM_DESC 8
663
+
664
+/** Receive descriptor ring fill level */
665
+#define INTELXL_RX_FILL ( INTELXL_RX_NUM_DESC - 1 )
666
+
667
+/******************************************************************************
668
+ *
669
+ * Top level
670
+ *
671
+ ******************************************************************************
672
+ */
673
+
674
+/** PF Interrupt Zero Dynamic Control Register */
675
+#define INTELXL_PFINT_DYN_CTL0 0x038480
676
+#define INTELXL_PFINT_DYN_CTL0_INTENA	0x00000001UL	/**< Enable */
677
+#define INTELXL_PFINT_DYN_CTL0_CLEARPBA	0x00000002UL	/**< Acknowledge */
678
+#define INTELXL_PFINT_DYN_CTL0_INTENA_MASK 0x80000000UL	/**< Ignore enable */
679
+
680
+/** PF Interrupt Zero Linked List Register */
681
+#define INTELXL_PFINT_LNKLST0 0x038500
682
+#define INTELXL_PFINT_LNKLST0_FIRSTQ_INDX(x) \
683
+	( (x) << 0 )					/**< Queue index */
684
+#define INTELXL_PFINT_LNKLST0_FIRSTQ_INDX_NONE \
685
+	INTELXL_PFINT_LNKLST0_FIRSTQ_INDX ( 0x7ff )	/**< End of list */
686
+#define INTELXL_PFINT_LNKLST0_FIRSTQ_TYPE(x) \
687
+	( (x) << 11 )					/**< Queue type */
688
+#define INTELXL_PFINT_LNKLST0_FIRSTQ_TYPE_RX \
689
+	INTELXL_PFINT_LNKLST0_FIRSTQ_TYPE ( 0x0 )	/**< Receive queue */
690
+#define INTELXL_PFINT_LNKLST0_FIRSTQ_TYPE_TX \
691
+	INTELXL_PFINT_LNKLST0_FIRSTQ_TYPE ( 0x1 )	/**< Transmit queue */
692
+
693
+/** PF Interrupt Zero Cause Enablement Register */
694
+#define INTELXL_PFINT_ICR0_ENA 0x038800
695
+#define INTELXL_PFINT_ICR0_ENA_ADMINQ	0x40000000UL	/**< Admin event */
696
+
697
+/** Receive Queue Interrupt Cause Control Register */
698
+#define INTELXL_QINT_RQCTL(x) ( 0x03a000 + ( 0x4 * (x) ) )
699
+#define INTELXL_QINT_RQCTL_NEXTQ_INDX(x) ( (x) << 16 )	/**< Queue index */
700
+#define INTELXL_QINT_RQCTL_NEXTQ_INDX_NONE \
701
+	INTELXL_QINT_RQCTL_NEXTQ_INDX ( 0x7ff )		/**< End of list */
702
+#define INTELXL_QINT_RQCTL_NEXTQ_TYPE(x) ( (x) << 27 )	/**< Queue type */
703
+#define INTELXL_QINT_RQCTL_NEXTQ_TYPE_RX \
704
+	INTELXL_QINT_RQCTL_NEXTQ_TYPE ( 0x0 )		/**< Receive queue */
705
+#define INTELXL_QINT_RQCTL_NEXTQ_TYPE_TX \
706
+	INTELXL_QINT_RQCTL_NEXTQ_TYPE ( 0x1 )		/**< Transmit queue */
707
+#define INTELXL_QINT_RQCTL_CAUSE_ENA	0x40000000UL	/**< Enable */
708
+
709
+/** Transmit Queue Interrupt Cause Control Register */
710
+#define INTELXL_QINT_TQCTL(x) ( 0x03c000 + ( 0x4 * (x) ) )
711
+#define INTELXL_QINT_TQCTL_NEXTQ_INDX(x) ( (x) << 16 )	/**< Queue index */
712
+#define INTELXL_QINT_TQCTL_NEXTQ_INDX_NONE \
713
+	INTELXL_QINT_TQCTL_NEXTQ_INDX ( 0x7ff )		/**< End of list */
714
+#define INTELXL_QINT_TQCTL_NEXTQ_TYPE(x) ( (x) << 27 )	/**< Queue type */
715
+#define INTELXL_QINT_TQCTL_NEXTQ_TYPE_RX \
716
+	INTELXL_QINT_TQCTL_NEXTQ_TYPE ( 0x0 )		/**< Receive queue */
717
+#define INTELXL_QINT_TQCTL_NEXTQ_TYPE_TX \
718
+	INTELXL_QINT_TQCTL_NEXTQ_TYPE ( 0x1 )		/**< Transmit queue */
719
+#define INTELXL_QINT_TQCTL_CAUSE_ENA	0x40000000UL	/**< Enable */
720
+
721
+/** PF Control Register */
722
+#define INTELXL_PFGEN_CTRL 0x092400
723
+#define INTELXL_PFGEN_CTRL_PFSWR	0x00000001UL	/**< Software Reset */
724
+
725
+/** Time to delay for device reset, in milliseconds */
726
+#define INTELXL_RESET_DELAY_MS 100
727
+
728
+/** PF Queue Allocation Register */
729
+#define INTELXL_PFLAN_QALLOC 0x1c0400
730
+#define INTELXL_PFLAN_QALLOC_FIRSTQ(x) \
731
+	( ( (x) >> 0 ) & 0x7ff )			/**< First queue */
732
+#define INTELXL_PFLAN_QALLOC_LASTQ(x) \
733
+	( ( (x) >> 16 ) & 0x7ff )			/**< Last queue */
734
+
735
+/** PF LAN Port Number Register */
736
+#define INTELXL_PFGEN_PORTNUM 0x1c0480
737
+#define INTELXL_PFGEN_PORTNUM_PORT_NUM(x) \
738
+	( ( (x) >> 0 ) & 0x3 )				/**< Port number */
739
+
740
+/** Port MAC Address Low Register */
741
+#define INTELXL_PRTGL_SAL 0x1e2120
742
+
743
+/** Port MAC Address High Register */
744
+#define INTELXL_PRTGL_SAH 0x1e2140
745
+#define INTELXL_PRTGL_SAH_MFS_GET(x)	( (x) >> 16 )	/**< Max frame size */
746
+#define INTELXL_PRTGL_SAH_MFS_SET(x)	( (x) << 16 )	/**< Max frame size */
747
+
748
+/** Receive address */
749
+union intelxl_receive_address {
750
+	struct {
751
+		uint32_t low;
752
+		uint32_t high;
753
+	} __attribute__ (( packed )) reg;
754
+	uint8_t raw[ETH_ALEN];
755
+};
756
+
757
+/** An Intel 40Gigabit network card */
758
+struct intelxl_nic {
759
+	/** Registers */
760
+	void *regs;
761
+	/** Maximum frame size */
762
+	size_t mfs;
763
+
764
+	/** Physical function number */
765
+	unsigned int pf;
766
+	/** Absolute queue number base */
767
+	unsigned int base;
768
+	/** Port number */
769
+	unsigned int port;
770
+	/** Queue number */
771
+	unsigned int queue;
772
+	/** Virtual Station Interface switching element ID */
773
+	unsigned int vsi;
774
+	/** Queue set handle */
775
+	unsigned int qset;
776
+
777
+	/** Admin command queue */
778
+	struct intelxl_admin command;
779
+	/** Admin event queue */
780
+	struct intelxl_admin event;
781
+
782
+	/** Transmit descriptor ring */
783
+	struct intelxl_ring tx;
784
+	/** Receive descriptor ring */
785
+	struct intelxl_ring rx;
786
+	/** Receive I/O buffers */
787
+	struct io_buffer *rx_iobuf[INTELXL_RX_NUM_DESC];
788
+};
789
+
790
+#endif /* _INTELXL_H */

+ 1
- 0
src/include/ipxe/errfile.h View File

@@ -204,6 +204,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
204 204
 #define ERRFILE_lan78xx		     ( ERRFILE_DRIVER | 0x00c80000 )
205 205
 #define ERRFILE_ena		     ( ERRFILE_DRIVER | 0x00c90000 )
206 206
 #define ERRFILE_icplus		     ( ERRFILE_DRIVER | 0x00ca0000 )
207
+#define ERRFILE_intelxl		     ( ERRFILE_DRIVER | 0x00cb0000 )
207 208
 
208 209
 #define ERRFILE_aoe			( ERRFILE_NET | 0x00000000 )
209 210
 #define ERRFILE_arp			( ERRFILE_NET | 0x00010000 )

Loading…
Cancel
Save