Browse Source

[intelxl] Allow for virtual function admin queue register maps

The register map for the virtual functions appears to have been
constructed using a random number generator.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 5 years ago
parent
commit
c5ccfe79cf
2 changed files with 59 additions and 21 deletions
  1. 31
    16
      src/drivers/net/intelxl.c
  2. 28
    5
      src/drivers/net/intelxl.h

+ 31
- 16
src/drivers/net/intelxl.c View File

123
  ******************************************************************************
123
  ******************************************************************************
124
  */
124
  */
125
 
125
 
126
+/** Admin queue register offsets */
127
+static const struct intelxl_admin_offsets intelxl_admin_offsets = {
128
+	.bal = INTELXL_ADMIN_BAL,
129
+	.bah = INTELXL_ADMIN_BAH,
130
+	.len = INTELXL_ADMIN_LEN,
131
+	.head = INTELXL_ADMIN_HEAD,
132
+	.tail = INTELXL_ADMIN_TAIL,
133
+};
134
+
126
 /**
135
 /**
127
  * Create admin queue
136
  * Create admin queue
128
  *
137
  *
133
 static int intelxl_create_admin ( struct intelxl_nic *intelxl,
142
 static int intelxl_create_admin ( struct intelxl_nic *intelxl,
134
 				  struct intelxl_admin *admin ) {
143
 				  struct intelxl_admin *admin ) {
135
 	size_t len = ( sizeof ( admin->desc[0] ) * INTELXL_ADMIN_NUM_DESC );
144
 	size_t len = ( sizeof ( admin->desc[0] ) * INTELXL_ADMIN_NUM_DESC );
136
-	void *admin_regs = ( intelxl->regs + admin->reg );
145
+	const struct intelxl_admin_offsets *regs = admin->regs;
146
+	void *admin_regs = ( intelxl->regs + admin->base );
137
 	physaddr_t address;
147
 	physaddr_t address;
138
 
148
 
139
 	/* Allocate admin queue */
149
 	/* Allocate admin queue */
147
 	memset ( admin->desc, 0, len );
157
 	memset ( admin->desc, 0, len );
148
 
158
 
149
 	/* Reset head and tail registers */
159
 	/* Reset head and tail registers */
150
-	writel ( 0, admin_regs + INTELXL_ADMIN_HEAD );
151
-	writel ( 0, admin_regs + INTELXL_ADMIN_TAIL );
160
+	writel ( 0, admin_regs + regs->head );
161
+	writel ( 0, admin_regs + regs->tail );
152
 
162
 
153
 	/* Reset queue index */
163
 	/* Reset queue index */
154
 	admin->index = 0;
164
 	admin->index = 0;
155
 
165
 
156
 	/* Program queue address */
166
 	/* Program queue address */
157
 	address = virt_to_bus ( admin->desc );
167
 	address = virt_to_bus ( admin->desc );
158
-	writel ( ( address & 0xffffffffUL ), admin_regs + INTELXL_ADMIN_BAL );
168
+	writel ( ( address & 0xffffffffUL ), admin_regs + regs->bal );
159
 	if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) {
169
 	if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) {
160
 		writel ( ( ( ( uint64_t ) address ) >> 32 ),
170
 		writel ( ( ( ( uint64_t ) address ) >> 32 ),
161
-			 admin_regs + INTELXL_ADMIN_BAH );
171
+			 admin_regs + regs->bah );
162
 	} else {
172
 	} else {
163
-		writel ( 0, admin_regs + INTELXL_ADMIN_BAH );
173
+		writel ( 0, admin_regs + regs->bah );
164
 	}
174
 	}
165
 
175
 
166
 	/* Program queue length and enable queue */
176
 	/* Program queue length and enable queue */
167
 	writel ( ( INTELXL_ADMIN_LEN_LEN ( INTELXL_ADMIN_NUM_DESC ) |
177
 	writel ( ( INTELXL_ADMIN_LEN_LEN ( INTELXL_ADMIN_NUM_DESC ) |
168
 		   INTELXL_ADMIN_LEN_ENABLE ),
178
 		   INTELXL_ADMIN_LEN_ENABLE ),
169
-		 admin_regs + INTELXL_ADMIN_LEN );
179
+		 admin_regs + regs->len );
170
 
180
 
171
 	DBGC ( intelxl, "INTELXL %p A%cQ is at [%08llx,%08llx) buf "
181
 	DBGC ( intelxl, "INTELXL %p A%cQ is at [%08llx,%08llx) buf "
172
 	       "[%08llx,%08llx)\n", intelxl,
182
 	       "[%08llx,%08llx)\n", intelxl,
173
-	       ( ( admin->reg == INTELXL_ADMIN_CMD ) ? 'T' : 'R' ),
183
+	       ( ( admin == &intelxl->command ) ? 'T' : 'R' ),
174
 	       ( ( unsigned long long ) address ),
184
 	       ( ( unsigned long long ) address ),
175
 	       ( ( unsigned long long ) address + len ),
185
 	       ( ( unsigned long long ) address + len ),
176
 	       ( ( unsigned long long ) virt_to_bus ( admin->buffer ) ),
186
 	       ( ( unsigned long long ) virt_to_bus ( admin->buffer ) ),
188
 static void intelxl_destroy_admin ( struct intelxl_nic *intelxl,
198
 static void intelxl_destroy_admin ( struct intelxl_nic *intelxl,
189
 				    struct intelxl_admin *admin ) {
199
 				    struct intelxl_admin *admin ) {
190
 	size_t len = ( sizeof ( admin->desc[0] ) * INTELXL_ADMIN_NUM_DESC );
200
 	size_t len = ( sizeof ( admin->desc[0] ) * INTELXL_ADMIN_NUM_DESC );
191
-	void *admin_regs = ( intelxl->regs + admin->reg );
201
+	const struct intelxl_admin_offsets *regs = admin->regs;
202
+	void *admin_regs = ( intelxl->regs + admin->base );
192
 
203
 
193
 	/* Disable queue */
204
 	/* Disable queue */
194
-	writel ( 0, admin_regs + INTELXL_ADMIN_LEN );
205
+	writel ( 0, admin_regs + regs->len );
195
 
206
 
196
 	/* Free queue */
207
 	/* Free queue */
197
 	free_dma ( admin->desc, ( len + sizeof ( *admin->buffer ) ) );
208
 	free_dma ( admin->desc, ( len + sizeof ( *admin->buffer ) ) );
207
 static int intelxl_admin_command ( struct intelxl_nic *intelxl,
218
 static int intelxl_admin_command ( struct intelxl_nic *intelxl,
208
 				   struct intelxl_admin_descriptor *cmd ) {
219
 				   struct intelxl_admin_descriptor *cmd ) {
209
 	struct intelxl_admin *admin = &intelxl->command;
220
 	struct intelxl_admin *admin = &intelxl->command;
210
-	void *admin_regs = ( intelxl->regs + admin->reg );
221
+	const struct intelxl_admin_offsets *regs = admin->regs;
222
+	void *admin_regs = ( intelxl->regs + admin->base );
211
 	struct intelxl_admin_descriptor *desc;
223
 	struct intelxl_admin_descriptor *desc;
212
 	uint64_t buffer;
224
 	uint64_t buffer;
213
 	unsigned int index;
225
 	unsigned int index;
245
 
257
 
246
 	/* Post command descriptor */
258
 	/* Post command descriptor */
247
 	wmb();
259
 	wmb();
248
-	writel ( tail, admin_regs + INTELXL_ADMIN_TAIL );
260
+	writel ( tail, admin_regs + regs->tail );
249
 
261
 
250
 	/* Wait for completion */
262
 	/* Wait for completion */
251
 	for ( i = 0 ; i < INTELXL_ADMIN_MAX_WAIT_MS ; i++ ) {
263
 	for ( i = 0 ; i < INTELXL_ADMIN_MAX_WAIT_MS ; i++ ) {
558
  */
570
  */
559
 static void intelxl_refill_admin ( struct intelxl_nic *intelxl ) {
571
 static void intelxl_refill_admin ( struct intelxl_nic *intelxl ) {
560
 	struct intelxl_admin *admin = &intelxl->event;
572
 	struct intelxl_admin *admin = &intelxl->event;
561
-	void *admin_regs = ( intelxl->regs + admin->reg );
573
+	const struct intelxl_admin_offsets *regs = admin->regs;
574
+	void *admin_regs = ( intelxl->regs + admin->base );
562
 	unsigned int tail;
575
 	unsigned int tail;
563
 
576
 
564
 	/* Update tail pointer */
577
 	/* Update tail pointer */
565
 	tail = ( ( admin->index + INTELXL_ADMIN_NUM_DESC - 1 ) %
578
 	tail = ( ( admin->index + INTELXL_ADMIN_NUM_DESC - 1 ) %
566
 		 INTELXL_ADMIN_NUM_DESC );
579
 		 INTELXL_ADMIN_NUM_DESC );
567
-	writel ( tail, admin_regs + INTELXL_ADMIN_TAIL );
580
+	writel ( tail, admin_regs + regs->tail );
568
 }
581
 }
569
 
582
 
570
 /**
583
 /**
1383
 	netdev->dev = &pci->dev;
1396
 	netdev->dev = &pci->dev;
1384
 	memset ( intelxl, 0, sizeof ( *intelxl ) );
1397
 	memset ( intelxl, 0, sizeof ( *intelxl ) );
1385
 	intelxl->pf = PCI_FUNC ( pci->busdevfn );
1398
 	intelxl->pf = PCI_FUNC ( pci->busdevfn );
1386
-	intelxl_init_admin ( &intelxl->command, INTELXL_ADMIN_CMD );
1387
-	intelxl_init_admin ( &intelxl->event, INTELXL_ADMIN_EVT );
1399
+	intelxl_init_admin ( &intelxl->command, INTELXL_ADMIN_CMD,
1400
+			     &intelxl_admin_offsets );
1401
+	intelxl_init_admin ( &intelxl->event, INTELXL_ADMIN_EVT,
1402
+			     &intelxl_admin_offsets );
1388
 	intelxl_init_ring ( &intelxl->tx, INTELXL_TX_NUM_DESC,
1403
 	intelxl_init_ring ( &intelxl->tx, INTELXL_TX_NUM_DESC,
1389
 			    intelxl_context_tx );
1404
 			    intelxl_context_tx );
1390
 	intelxl_init_ring ( &intelxl->rx, INTELXL_RX_NUM_DESC,
1405
 	intelxl_init_ring ( &intelxl->rx, INTELXL_RX_NUM_DESC,

+ 28
- 5
src/drivers/net/intelxl.h View File

53
 /** Admin Queue Tail Register (offset) */
53
 /** Admin Queue Tail Register (offset) */
54
 #define INTELXL_ADMIN_TAIL 0x400
54
 #define INTELXL_ADMIN_TAIL 0x400
55
 
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
+
56
 /** Admin queue data buffer command parameters */
74
 /** Admin queue data buffer command parameters */
57
 struct intelxl_admin_buffer_params {
75
 struct intelxl_admin_buffer_params {
58
 	/** Reserved */
76
 	/** Reserved */
343
 	/** Queue index */
361
 	/** Queue index */
344
 	unsigned int index;
362
 	unsigned int index;
345
 
363
 
346
-	/** Register block */
347
-	unsigned int reg;
364
+	/** Register block base */
365
+	unsigned int base;
366
+	/** Register offsets */
367
+	const struct intelxl_admin_offsets *regs;
348
 	/** Data buffer */
368
 	/** Data buffer */
349
 	union intelxl_admin_buffer *buffer;
369
 	union intelxl_admin_buffer *buffer;
350
 };
370
 };
353
  * Initialise admin queue
373
  * Initialise admin queue
354
  *
374
  *
355
  * @v admin		Admin queue
375
  * @v admin		Admin queue
356
- * @v reg		Register block
376
+ * @v base		Register block base
377
+ * @v regs		Register offsets
357
  */
378
  */
358
 static inline __attribute__ (( always_inline )) void
379
 static inline __attribute__ (( always_inline )) void
359
-intelxl_init_admin ( struct intelxl_admin *admin, unsigned int reg ) {
380
+intelxl_init_admin ( struct intelxl_admin *admin, unsigned int base,
381
+		     const struct intelxl_admin_offsets *regs ) {
360
 
382
 
361
-	admin->reg = reg;
383
+	admin->base = base;
384
+	admin->regs = regs;
362
 }
385
 }
363
 
386
 
364
 /** Number of admin queue descriptors */
387
 /** Number of admin queue descriptors */

Loading…
Cancel
Save