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