Просмотр исходного кода

[ecm] Use generic refill framework for bulk IN and interrupt endpoints

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 лет назад
Родитель
Сommit
1706ab7ff3
2 измененных файлов: 40 добавлений и 133 удалений
  1. 34
    109
      src/drivers/net/ecm.c
  2. 6
    24
      src/drivers/net/ecm.h

+ 34
- 109
src/drivers/net/ecm.c Просмотреть файл

35
  *
35
  *
36
  */
36
  */
37
 
37
 
38
-/** Refill profiler */
39
-static struct profiler ecm_refill_profiler __profiler =
40
-	{ .name = "ecm.refill" };
41
-
42
 /** Interrupt completion profiler */
38
 /** Interrupt completion profiler */
43
 static struct profiler ecm_intr_profiler __profiler =
39
 static struct profiler ecm_intr_profiler __profiler =
44
 	{ .name = "ecm.intr" };
40
 	{ .name = "ecm.intr" };
114
 	return 0;
110
 	return 0;
115
 }
111
 }
116
 
112
 
117
-/******************************************************************************
118
- *
119
- * Ring management
120
- *
121
- ******************************************************************************
122
- */
123
-
124
-/**
125
- * Transcribe receive ring name (for debugging)
126
- *
127
- * @v ecm		CDC-ECM device
128
- * @v ring		Receive ring
129
- * @ret name		Receive ring name
130
- */
131
-static inline const char * ecm_rx_name ( struct ecm_device *ecm,
132
-					 struct ecm_rx_ring *ring ) {
133
-	if ( ring == &ecm->intr ) {
134
-		return "interrupt";
135
-	} else if ( ring == &ecm->in ) {
136
-		return "bulk IN";
137
-	} else {
138
-		return "UNKNOWN";
139
-	}
140
-}
141
-
142
-/**
143
- * Refill receive ring
144
- *
145
- * @v ecm		CDC-ECM device
146
- * @v ring		Receive ring
147
- */
148
-static void ecm_rx_refill ( struct ecm_device *ecm, struct ecm_rx_ring *ring ) {
149
-	struct net_device *netdev = ecm->netdev;
150
-	struct io_buffer *iobuf;
151
-	int rc;
152
-
153
-	/* Refill ring */
154
-	while ( ring->fill < ring->max ) {
155
-
156
-		/* Profile refill */
157
-		profile_start ( &ecm_refill_profiler );
158
-
159
-		/* Allocate I/O buffer */
160
-		iobuf = alloc_iob ( ring->mtu );
161
-		if ( ! iobuf ) {
162
-			/* Wait for next refill */
163
-			break;
164
-		}
165
-		iob_put ( iobuf, ring->mtu );
166
-
167
-		/* Enqueue I/O buffer */
168
-		if ( ( rc = usb_stream ( &ring->ep, iobuf, 0 ) ) != 0 ) {
169
-			netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
170
-			break;
171
-		}
172
-
173
-		/* Increment fill level */
174
-		ring->fill++;
175
-		profile_stop ( &ecm_refill_profiler );
176
-	}
177
-}
178
-
179
 /******************************************************************************
113
 /******************************************************************************
180
  *
114
  *
181
  * CDC-ECM communications interface
115
  * CDC-ECM communications interface
192
  */
126
  */
193
 static void ecm_intr_complete ( struct usb_endpoint *ep,
127
 static void ecm_intr_complete ( struct usb_endpoint *ep,
194
 				struct io_buffer *iobuf, int rc ) {
128
 				struct io_buffer *iobuf, int rc ) {
195
-	struct ecm_device *ecm = container_of ( ep, struct ecm_device, intr.ep);
129
+	struct ecm_device *ecm = container_of ( ep, struct ecm_device, intr );
196
 	struct net_device *netdev = ecm->netdev;
130
 	struct net_device *netdev = ecm->netdev;
197
 	struct usb_setup_packet *message;
131
 	struct usb_setup_packet *message;
198
 	size_t len = iob_len ( iobuf );
132
 	size_t len = iob_len ( iobuf );
200
 	/* Profile completions */
134
 	/* Profile completions */
201
 	profile_start ( &ecm_intr_profiler );
135
 	profile_start ( &ecm_intr_profiler );
202
 
136
 
203
-	/* Decrement fill level */
204
-	assert ( ecm->intr.fill > 0 );
205
-	ecm->intr.fill--;
206
-
207
 	/* Ignore packets cancelled when the endpoint closes */
137
 	/* Ignore packets cancelled when the endpoint closes */
208
 	if ( ! ep->open )
138
 	if ( ! ep->open )
209
 		goto ignore;
139
 		goto ignore;
220
 	if ( len < sizeof ( *message ) ) {
150
 	if ( len < sizeof ( *message ) ) {
221
 		DBGC ( ecm, "ECM %p underlength interrupt:\n", ecm );
151
 		DBGC ( ecm, "ECM %p underlength interrupt:\n", ecm );
222
 		DBGC_HDA ( ecm, 0, iobuf->data, iob_len ( iobuf ) );
152
 		DBGC_HDA ( ecm, 0, iobuf->data, iob_len ( iobuf ) );
153
+		rc = -EINVAL;
223
 		goto error;
154
 		goto error;
224
 	}
155
 	}
225
 	message = iobuf->data;
156
 	message = iobuf->data;
244
 	default:
175
 	default:
245
 		DBGC ( ecm, "ECM %p unrecognised interrupt:\n", ecm );
176
 		DBGC ( ecm, "ECM %p unrecognised interrupt:\n", ecm );
246
 		DBGC_HDA ( ecm, 0, iobuf->data, iob_len ( iobuf ) );
177
 		DBGC_HDA ( ecm, 0, iobuf->data, iob_len ( iobuf ) );
178
+		rc = -ENOTSUP;
247
 		goto error;
179
 		goto error;
248
 	}
180
 	}
249
 
181
 
275
 	int rc;
207
 	int rc;
276
 
208
 
277
 	/* Open interrupt endpoint */
209
 	/* Open interrupt endpoint */
278
-	if ( ( rc = usb_endpoint_open ( &ecm->intr.ep ) ) != 0 ) {
210
+	if ( ( rc = usb_endpoint_open ( &ecm->intr ) ) != 0 ) {
279
 		DBGC ( ecm, "ECM %p could not open interrupt: %s\n",
211
 		DBGC ( ecm, "ECM %p could not open interrupt: %s\n",
280
 		       ecm, strerror ( rc ) );
212
 		       ecm, strerror ( rc ) );
281
 		goto err_open;
213
 		goto err_open;
282
 	}
214
 	}
283
 
215
 
284
-	/* Refill interrupt ring */
285
-	ecm_rx_refill ( ecm, &ecm->intr );
216
+	/* Refill interrupt endpoint */
217
+	usb_refill ( &ecm->intr );
286
 
218
 
287
 	return 0;
219
 	return 0;
288
 
220
 
289
-	usb_endpoint_close ( &ecm->intr.ep );
290
-	assert ( ecm->intr.fill == 0 );
221
+	usb_endpoint_close ( &ecm->intr );
291
  err_open:
222
  err_open:
292
 	return rc;
223
 	return rc;
293
 }
224
 }
300
 static void ecm_comms_close ( struct ecm_device *ecm ) {
231
 static void ecm_comms_close ( struct ecm_device *ecm ) {
301
 
232
 
302
 	/* Close interrupt endpoint */
233
 	/* Close interrupt endpoint */
303
-	usb_endpoint_close ( &ecm->intr.ep );
304
-	assert ( ecm->intr.fill == 0 );
234
+	usb_endpoint_close ( &ecm->intr );
305
 }
235
 }
306
 
236
 
307
 /******************************************************************************
237
 /******************************************************************************
320
  */
250
  */
321
 static void ecm_in_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
251
 static void ecm_in_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
322
 			      int rc ) {
252
 			      int rc ) {
323
-	struct ecm_device *ecm = container_of ( ep, struct ecm_device, in.ep );
253
+	struct ecm_device *ecm = container_of ( ep, struct ecm_device, in );
324
 	struct net_device *netdev = ecm->netdev;
254
 	struct net_device *netdev = ecm->netdev;
325
 
255
 
326
 	/* Profile receive completions */
256
 	/* Profile receive completions */
327
 	profile_start ( &ecm_in_profiler );
257
 	profile_start ( &ecm_in_profiler );
328
 
258
 
329
-	/* Decrement fill level */
330
-	assert ( ecm->in.fill > 0 );
331
-	ecm->in.fill--;
332
-
333
 	/* Ignore packets cancelled when the endpoint closes */
259
 	/* Ignore packets cancelled when the endpoint closes */
334
 	if ( ! ep->open )
260
 	if ( ! ep->open )
335
 		goto ignore;
261
 		goto ignore;
373
 	profile_start ( &ecm_out_profiler );
299
 	profile_start ( &ecm_out_profiler );
374
 
300
 
375
 	/* Enqueue I/O buffer */
301
 	/* Enqueue I/O buffer */
376
-	if ( ( rc = usb_stream ( &ecm->out.ep, iobuf, 1 ) ) != 0 )
302
+	if ( ( rc = usb_stream ( &ecm->out, iobuf, 1 ) ) != 0 )
377
 		return rc;
303
 		return rc;
378
 
304
 
379
 	profile_stop ( &ecm_out_profiler );
305
 	profile_stop ( &ecm_out_profiler );
389
  */
315
  */
390
 static void ecm_out_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
316
 static void ecm_out_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
391
 			       int rc ) {
317
 			       int rc ) {
392
-	struct ecm_device *ecm = container_of ( ep, struct ecm_device, out.ep );
318
+	struct ecm_device *ecm = container_of ( ep, struct ecm_device, out );
393
 	struct net_device *netdev = ecm->netdev;
319
 	struct net_device *netdev = ecm->netdev;
394
 
320
 
395
 	/* Report TX completion */
321
 	/* Report TX completion */
420
 	}
346
 	}
421
 
347
 
422
 	/* Open bulk IN endpoint */
348
 	/* Open bulk IN endpoint */
423
-	if ( ( rc = usb_endpoint_open ( &ecm->in.ep ) ) != 0 ) {
349
+	if ( ( rc = usb_endpoint_open ( &ecm->in ) ) != 0 ) {
424
 		DBGC ( ecm, "ECM %p could not open bulk IN: %s\n",
350
 		DBGC ( ecm, "ECM %p could not open bulk IN: %s\n",
425
 		       ecm, strerror ( rc ) );
351
 		       ecm, strerror ( rc ) );
426
 		goto err_open_in;
352
 		goto err_open_in;
427
 	}
353
 	}
428
 
354
 
429
 	/* Open bulk OUT endpoint */
355
 	/* Open bulk OUT endpoint */
430
-	if ( ( rc = usb_endpoint_open ( &ecm->out.ep ) ) != 0 ) {
356
+	if ( ( rc = usb_endpoint_open ( &ecm->out ) ) != 0 ) {
431
 		DBGC ( ecm, "ECM %p could not open bulk OUT: %s\n",
357
 		DBGC ( ecm, "ECM %p could not open bulk OUT: %s\n",
432
 		       ecm, strerror ( rc ) );
358
 		       ecm, strerror ( rc ) );
433
 		goto err_open_out;
359
 		goto err_open_out;
434
 	}
360
 	}
435
 
361
 
436
-	/* Refill bulk IN ring */
437
-	ecm_rx_refill ( ecm, &ecm->in );
362
+	/* Refill bulk IN endpoint */
363
+	usb_refill ( &ecm->in );
438
 
364
 
439
 	return 0;
365
 	return 0;
440
 
366
 
441
-	usb_endpoint_close ( &ecm->out.ep );
367
+	usb_endpoint_close ( &ecm->out );
442
  err_open_out:
368
  err_open_out:
443
-	usb_endpoint_close ( &ecm->in.ep );
444
-	assert ( ecm->in.fill == 0 );
369
+	usb_endpoint_close ( &ecm->in );
445
  err_open_in:
370
  err_open_in:
446
 	usb_set_interface ( usb, ecm->data, 0 );
371
 	usb_set_interface ( usb, ecm->data, 0 );
447
  err_set_interface:
372
  err_set_interface:
457
 	struct usb_device *usb = ecm->usb;
382
 	struct usb_device *usb = ecm->usb;
458
 
383
 
459
 	/* Close endpoints */
384
 	/* Close endpoints */
460
-	usb_endpoint_close ( &ecm->out.ep );
461
-	usb_endpoint_close ( &ecm->in.ep );
462
-	assert ( ecm->in.fill == 0 );
385
+	usb_endpoint_close ( &ecm->out );
386
+	usb_endpoint_close ( &ecm->in );
463
 
387
 
464
 	/* Reset data interface */
388
 	/* Reset data interface */
465
 	usb_set_interface ( usb, ecm->data, 0 );
389
 	usb_set_interface ( usb, ecm->data, 0 );
555
  */
479
  */
556
 static void ecm_poll ( struct net_device *netdev ) {
480
 static void ecm_poll ( struct net_device *netdev ) {
557
 	struct ecm_device *ecm = netdev->priv;
481
 	struct ecm_device *ecm = netdev->priv;
482
+	int rc;
558
 
483
 
559
 	/* Poll USB bus */
484
 	/* Poll USB bus */
560
 	usb_poll ( ecm->bus );
485
 	usb_poll ( ecm->bus );
561
 
486
 
562
-	/* Refill interrupt ring */
563
-	ecm_rx_refill ( ecm, &ecm->intr );
487
+	/* Refill interrupt endpoint */
488
+	if ( ( rc = usb_refill ( &ecm->intr ) ) != 0 )
489
+		netdev_rx_err ( netdev, NULL, rc );
564
 
490
 
565
-	/* Refill bulk IN ring */
566
-	ecm_rx_refill ( ecm, &ecm->in );
491
+	/* Refill bulk IN endpoint */
492
+	if ( ( rc = usb_refill ( &ecm->in ) ) != 0 )
493
+		netdev_rx_err ( netdev, NULL, rc );
567
 }
494
 }
568
 
495
 
569
 /** CDC-ECM network device operations */
496
 /** CDC-ECM network device operations */
611
 	ecm->usb = usb;
538
 	ecm->usb = usb;
612
 	ecm->bus = usb->port->hub->bus;
539
 	ecm->bus = usb->port->hub->bus;
613
 	ecm->netdev = netdev;
540
 	ecm->netdev = netdev;
614
-	usb_endpoint_init ( &ecm->intr.ep, usb, &ecm_intr_operations );
615
-	usb_endpoint_init ( &ecm->in.ep, usb, &ecm_in_operations );
616
-	usb_endpoint_init ( &ecm->out.ep, usb, &ecm_out_operations );
541
+	usb_endpoint_init ( &ecm->intr, usb, &ecm_intr_operations );
542
+	usb_endpoint_init ( &ecm->in, usb, &ecm_in_operations );
543
+	usb_endpoint_init ( &ecm->out, usb, &ecm_out_operations );
544
+	usb_refill_init ( &ecm->intr, 0, ECM_INTR_MAX_FILL );
545
+	usb_refill_init ( &ecm->in, ECM_IN_MTU, ECM_IN_MAX_FILL );
617
 	DBGC ( ecm, "ECM %p on %s\n", ecm, func->name );
546
 	DBGC ( ecm, "ECM %p on %s\n", ecm, func->name );
618
 
547
 
619
 	/* Identify interfaces */
548
 	/* Identify interfaces */
644
 	}
573
 	}
645
 
574
 
646
 	/* Describe interrupt endpoint */
575
 	/* Describe interrupt endpoint */
647
-	if ( ( rc = usb_endpoint_described ( &ecm->intr.ep, config, comms,
576
+	if ( ( rc = usb_endpoint_described ( &ecm->intr, config, comms,
648
 					     USB_INTERRUPT, 0 ) ) != 0 ) {
577
 					     USB_INTERRUPT, 0 ) ) != 0 ) {
649
 		DBGC ( ecm, "ECM %p could not describe interrupt endpoint: "
578
 		DBGC ( ecm, "ECM %p could not describe interrupt endpoint: "
650
 		       "%s\n", ecm, strerror ( rc ) );
579
 		       "%s\n", ecm, strerror ( rc ) );
651
 		goto err_interrupt;
580
 		goto err_interrupt;
652
 	}
581
 	}
653
-	ecm->intr.mtu = ecm->intr.ep.mtu;
654
-	ecm->intr.max = ECM_INTR_MAX_FILL;
655
 
582
 
656
 	/* Describe bulk IN endpoint */
583
 	/* Describe bulk IN endpoint */
657
-	if ( ( rc = usb_endpoint_described ( &ecm->in.ep, config, data,
584
+	if ( ( rc = usb_endpoint_described ( &ecm->in, config, data,
658
 					     USB_BULK_IN, 0 ) ) != 0 ) {
585
 					     USB_BULK_IN, 0 ) ) != 0 ) {
659
 		DBGC ( ecm, "ECM %p could not describe bulk IN endpoint: "
586
 		DBGC ( ecm, "ECM %p could not describe bulk IN endpoint: "
660
 		       "%s\n", ecm, strerror ( rc ) );
587
 		       "%s\n", ecm, strerror ( rc ) );
661
 		goto err_bulk_in;
588
 		goto err_bulk_in;
662
 	}
589
 	}
663
-	ecm->in.mtu = ECM_IN_MTU;
664
-	ecm->in.max = ECM_IN_MAX_FILL;
665
 
590
 
666
 	/* Describe bulk OUT endpoint */
591
 	/* Describe bulk OUT endpoint */
667
-	if ( ( rc = usb_endpoint_described ( &ecm->out.ep, config, data,
592
+	if ( ( rc = usb_endpoint_described ( &ecm->out, config, data,
668
 					     USB_BULK_OUT, 0 ) ) != 0 ) {
593
 					     USB_BULK_OUT, 0 ) ) != 0 ) {
669
 		DBGC ( ecm, "ECM %p could not describe bulk OUT endpoint: "
594
 		DBGC ( ecm, "ECM %p could not describe bulk OUT endpoint: "
670
 		       "%s\n", ecm, strerror ( rc ) );
595
 		       "%s\n", ecm, strerror ( rc ) );

+ 6
- 24
src/drivers/net/ecm.h Просмотреть файл

64
 	uint8_t wol;
64
 	uint8_t wol;
65
 } __attribute__ (( packed ));
65
 } __attribute__ (( packed ));
66
 
66
 
67
-/** A CDC-ECM receive ring */
68
-struct ecm_rx_ring {
69
-	/** USB endpoint */
70
-	struct usb_endpoint ep;
71
-	/** I/O buffer size */
72
-	size_t mtu;
73
-	/** Fill level */
74
-	unsigned int fill;
75
-	/** Maximum fill level */
76
-	unsigned int max;
77
-};
78
-
79
-/** A CDC-ECM transmit ring */
80
-struct ecm_tx_ring {
81
-	/** USB endpoint */
82
-	struct usb_endpoint ep;
83
-};
84
-
85
 /** A CDC-ECM network device */
67
 /** A CDC-ECM network device */
86
 struct ecm_device {
68
 struct ecm_device {
87
 	/** USB device */
69
 	/** USB device */
96
 	/** Data interface */
78
 	/** Data interface */
97
 	unsigned int data;
79
 	unsigned int data;
98
 
80
 
99
-	/** Interrupt ring */
100
-	struct ecm_rx_ring intr;
101
-	/** Bulk IN ring */
102
-	struct ecm_rx_ring in;
103
-	/** Bulk OUT ring */
104
-	struct ecm_tx_ring out;
81
+	/** Interrupt endpoint */
82
+	struct usb_endpoint intr;
83
+	/** Bulk IN endpoint */
84
+	struct usb_endpoint in;
85
+	/** Bulk OUT endpoint */
86
+	struct usb_endpoint out;
105
 };
87
 };
106
 
88
 
107
 /** Interrupt maximum fill level
89
 /** Interrupt maximum fill level

Загрузка…
Отмена
Сохранить