Browse Source

[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 years ago
parent
commit
1706ab7ff3
2 changed files with 40 additions and 133 deletions
  1. 34
    109
      src/drivers/net/ecm.c
  2. 6
    24
      src/drivers/net/ecm.h

+ 34
- 109
src/drivers/net/ecm.c View File

@@ -35,10 +35,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
35 35
  *
36 36
  */
37 37
 
38
-/** Refill profiler */
39
-static struct profiler ecm_refill_profiler __profiler =
40
-	{ .name = "ecm.refill" };
41
-
42 38
 /** Interrupt completion profiler */
43 39
 static struct profiler ecm_intr_profiler __profiler =
44 40
 	{ .name = "ecm.intr" };
@@ -114,68 +110,6 @@ int ecm_fetch_mac ( struct usb_device *usb,
114 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 115
  * CDC-ECM communications interface
@@ -192,7 +126,7 @@ static void ecm_rx_refill ( struct ecm_device *ecm, struct ecm_rx_ring *ring ) {
192 126
  */
193 127
 static void ecm_intr_complete ( struct usb_endpoint *ep,
194 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 130
 	struct net_device *netdev = ecm->netdev;
197 131
 	struct usb_setup_packet *message;
198 132
 	size_t len = iob_len ( iobuf );
@@ -200,10 +134,6 @@ static void ecm_intr_complete ( struct usb_endpoint *ep,
200 134
 	/* Profile completions */
201 135
 	profile_start ( &ecm_intr_profiler );
202 136
 
203
-	/* Decrement fill level */
204
-	assert ( ecm->intr.fill > 0 );
205
-	ecm->intr.fill--;
206
-
207 137
 	/* Ignore packets cancelled when the endpoint closes */
208 138
 	if ( ! ep->open )
209 139
 		goto ignore;
@@ -220,6 +150,7 @@ static void ecm_intr_complete ( struct usb_endpoint *ep,
220 150
 	if ( len < sizeof ( *message ) ) {
221 151
 		DBGC ( ecm, "ECM %p underlength interrupt:\n", ecm );
222 152
 		DBGC_HDA ( ecm, 0, iobuf->data, iob_len ( iobuf ) );
153
+		rc = -EINVAL;
223 154
 		goto error;
224 155
 	}
225 156
 	message = iobuf->data;
@@ -244,6 +175,7 @@ static void ecm_intr_complete ( struct usb_endpoint *ep,
244 175
 	default:
245 176
 		DBGC ( ecm, "ECM %p unrecognised interrupt:\n", ecm );
246 177
 		DBGC_HDA ( ecm, 0, iobuf->data, iob_len ( iobuf ) );
178
+		rc = -ENOTSUP;
247 179
 		goto error;
248 180
 	}
249 181
 
@@ -275,19 +207,18 @@ static int ecm_comms_open ( struct ecm_device *ecm ) {
275 207
 	int rc;
276 208
 
277 209
 	/* Open interrupt endpoint */
278
-	if ( ( rc = usb_endpoint_open ( &ecm->intr.ep ) ) != 0 ) {
210
+	if ( ( rc = usb_endpoint_open ( &ecm->intr ) ) != 0 ) {
279 211
 		DBGC ( ecm, "ECM %p could not open interrupt: %s\n",
280 212
 		       ecm, strerror ( rc ) );
281 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 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 222
  err_open:
292 223
 	return rc;
293 224
 }
@@ -300,8 +231,7 @@ static int ecm_comms_open ( struct ecm_device *ecm ) {
300 231
 static void ecm_comms_close ( struct ecm_device *ecm ) {
301 232
 
302 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,16 +250,12 @@ static void ecm_comms_close ( struct ecm_device *ecm ) {
320 250
  */
321 251
 static void ecm_in_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
322 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 254
 	struct net_device *netdev = ecm->netdev;
325 255
 
326 256
 	/* Profile receive completions */
327 257
 	profile_start ( &ecm_in_profiler );
328 258
 
329
-	/* Decrement fill level */
330
-	assert ( ecm->in.fill > 0 );
331
-	ecm->in.fill--;
332
-
333 259
 	/* Ignore packets cancelled when the endpoint closes */
334 260
 	if ( ! ep->open )
335 261
 		goto ignore;
@@ -373,7 +299,7 @@ static int ecm_out_transmit ( struct ecm_device *ecm,
373 299
 	profile_start ( &ecm_out_profiler );
374 300
 
375 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 303
 		return rc;
378 304
 
379 305
 	profile_stop ( &ecm_out_profiler );
@@ -389,7 +315,7 @@ static int ecm_out_transmit ( struct ecm_device *ecm,
389 315
  */
390 316
 static void ecm_out_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
391 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 319
 	struct net_device *netdev = ecm->netdev;
394 320
 
395 321
 	/* Report TX completion */
@@ -420,28 +346,27 @@ static int ecm_data_open ( struct ecm_device *ecm ) {
420 346
 	}
421 347
 
422 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 350
 		DBGC ( ecm, "ECM %p could not open bulk IN: %s\n",
425 351
 		       ecm, strerror ( rc ) );
426 352
 		goto err_open_in;
427 353
 	}
428 354
 
429 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 357
 		DBGC ( ecm, "ECM %p could not open bulk OUT: %s\n",
432 358
 		       ecm, strerror ( rc ) );
433 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 365
 	return 0;
440 366
 
441
-	usb_endpoint_close ( &ecm->out.ep );
367
+	usb_endpoint_close ( &ecm->out );
442 368
  err_open_out:
443
-	usb_endpoint_close ( &ecm->in.ep );
444
-	assert ( ecm->in.fill == 0 );
369
+	usb_endpoint_close ( &ecm->in );
445 370
  err_open_in:
446 371
 	usb_set_interface ( usb, ecm->data, 0 );
447 372
  err_set_interface:
@@ -457,9 +382,8 @@ static void ecm_data_close ( struct ecm_device *ecm ) {
457 382
 	struct usb_device *usb = ecm->usb;
458 383
 
459 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 388
 	/* Reset data interface */
465 389
 	usb_set_interface ( usb, ecm->data, 0 );
@@ -555,15 +479,18 @@ static int ecm_transmit ( struct net_device *netdev,
555 479
  */
556 480
 static void ecm_poll ( struct net_device *netdev ) {
557 481
 	struct ecm_device *ecm = netdev->priv;
482
+	int rc;
558 483
 
559 484
 	/* Poll USB bus */
560 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 496
 /** CDC-ECM network device operations */
@@ -611,9 +538,11 @@ static int ecm_probe ( struct usb_function *func,
611 538
 	ecm->usb = usb;
612 539
 	ecm->bus = usb->port->hub->bus;
613 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 546
 	DBGC ( ecm, "ECM %p on %s\n", ecm, func->name );
618 547
 
619 548
 	/* Identify interfaces */
@@ -644,27 +573,23 @@ static int ecm_probe ( struct usb_function *func,
644 573
 	}
645 574
 
646 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 577
 					     USB_INTERRUPT, 0 ) ) != 0 ) {
649 578
 		DBGC ( ecm, "ECM %p could not describe interrupt endpoint: "
650 579
 		       "%s\n", ecm, strerror ( rc ) );
651 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 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 585
 					     USB_BULK_IN, 0 ) ) != 0 ) {
659 586
 		DBGC ( ecm, "ECM %p could not describe bulk IN endpoint: "
660 587
 		       "%s\n", ecm, strerror ( rc ) );
661 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 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 593
 					     USB_BULK_OUT, 0 ) ) != 0 ) {
669 594
 		DBGC ( ecm, "ECM %p could not describe bulk OUT endpoint: "
670 595
 		       "%s\n", ecm, strerror ( rc ) );

+ 6
- 24
src/drivers/net/ecm.h View File

@@ -64,24 +64,6 @@ struct ecm_ethernet_descriptor {
64 64
 	uint8_t wol;
65 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 67
 /** A CDC-ECM network device */
86 68
 struct ecm_device {
87 69
 	/** USB device */
@@ -96,12 +78,12 @@ struct ecm_device {
96 78
 	/** Data interface */
97 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 89
 /** Interrupt maximum fill level

Loading…
Cancel
Save