Parcourir la source

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

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown il y a 9 ans
Parent
révision
14fc311271
2 fichiers modifiés avec 92 ajouts et 252 suppressions
  1. 82
    226
      src/drivers/net/ncm.c
  2. 10
    26
      src/drivers/net/ncm.h

+ 82
- 226
src/drivers/net/ncm.c Voir le fichier

35
  *
35
  *
36
  */
36
  */
37
 
37
 
38
-/** Ring refill profiler */
39
-static struct profiler ncm_refill_profiler __profiler =
40
-	{ .name = "ncm.refill" };
41
-
42
 /** Interrupt completion profiler */
38
 /** Interrupt completion profiler */
43
 static struct profiler ncm_intr_profiler __profiler =
39
 static struct profiler ncm_intr_profiler __profiler =
44
 	{ .name = "ncm.intr" };
40
 	{ .name = "ncm.intr" };
55
 static struct profiler ncm_out_profiler __profiler =
51
 static struct profiler ncm_out_profiler __profiler =
56
 	{ .name = "ncm.out" };
52
 	{ .name = "ncm.out" };
57
 
53
 
58
-/******************************************************************************
59
- *
60
- * Ring management
61
- *
62
- ******************************************************************************
63
- */
64
-
65
-/**
66
- * Transcribe receive ring name (for debugging)
67
- *
68
- * @v ncm		CDC-NCM device
69
- * @v ring		Receive ring
70
- * @ret name		Receive ring name
71
- */
72
-static inline const char * ncm_rx_name ( struct ncm_device *ncm,
73
-					 struct ncm_rx_ring *ring ) {
74
-	if ( ring == &ncm->intr ) {
75
-		return "interrupt";
76
-	} else if ( ring == &ncm->in ) {
77
-		return "bulk IN";
78
-	} else {
79
-		return "UNKNOWN";
80
-	}
81
-}
82
-
83
-/**
84
- * Allocate receive ring buffers
85
- *
86
- * @v ncm		CDC-NCM device
87
- * @v ring		Receive ring
88
- * @v mtu		I/O buffer size
89
- * @v count		Number of I/O buffers
90
- * @ret rc		Return status code
91
- */
92
-static int ncm_rx_alloc ( struct ncm_device *ncm, struct ncm_rx_ring *ring,
93
-			  size_t mtu, unsigned int count ) {
94
-	struct io_buffer *iobuf;
95
-	struct io_buffer *tmp;
96
-	unsigned int i;
97
-	int rc;
98
-
99
-	/* Initialise ring */
100
-	ring->mtu = mtu;
101
-	INIT_LIST_HEAD ( &ring->list );
102
-
103
-	/* Allocate I/O buffers */
104
-	for ( i = 0 ; i < count ; i++ ) {
105
-		iobuf = alloc_iob ( mtu );
106
-		if ( ! iobuf ) {
107
-			DBGC ( ncm, "NCM %p could not allocate %dx %zd-byte "
108
-			       "buffers for %s\n", ncm, count, mtu,
109
-			       ncm_rx_name ( ncm, ring ) );
110
-			rc = -ENOMEM;
111
-			goto err_alloc;
112
-		}
113
-		list_add ( &iobuf->list, &ring->list );
114
-	}
115
-
116
-	return 0;
117
-
118
- err_alloc:
119
-	list_for_each_entry_safe ( iobuf, tmp, &ring->list, list ) {
120
-		list_del ( &iobuf->list );
121
-		free_iob ( iobuf );
122
-	}
123
-	return rc;
124
-}
125
-
126
-/**
127
- * Refill receive ring
128
- *
129
- * @v ncm		CDC-NCM device
130
- * @v ring		Receive ring
131
- * @ret rc		Return status code
132
- */
133
-static int ncm_rx_refill ( struct ncm_device *ncm, struct ncm_rx_ring *ring ) {
134
-	struct io_buffer *iobuf;
135
-	int rc;
136
-
137
-	/* Enqueue any recycled I/O buffers */
138
-	while ( ( iobuf = list_first_entry ( &ring->list, struct io_buffer,
139
-					     list ) ) ) {
140
-
141
-		/* Profile refill */
142
-		profile_start ( &ncm_refill_profiler );
143
-
144
-		/* Reset size */
145
-		iob_put ( iobuf, ( ring->mtu - iob_len ( iobuf ) ) );
146
-
147
-		/* Enqueue I/O buffer */
148
-		if ( ( rc = usb_stream ( &ring->ep, iobuf, 0 ) ) != 0 ) {
149
-			DBGC ( ncm, "NCM %p could not enqueue %s: %s\n", ncm,
150
-			       ncm_rx_name ( ncm, ring ), strerror ( rc ) );
151
-			/* Leave in recycled list and wait for next refill */
152
-			return rc;
153
-		}
154
-
155
-		/* Remove from recycled list */
156
-		list_del ( &iobuf->list );
157
-		profile_stop ( &ncm_refill_profiler );
158
-	}
159
-
160
-	return 0;
161
-}
162
-
163
-/**
164
- * Recycle receive buffer
165
- *
166
- * @v ncm		CDC-NCM device
167
- * @v ring		Receive ring
168
- * @v iobuf		I/O buffer
169
- */
170
-static inline void ncm_rx_recycle ( struct ncm_device *ncm __unused,
171
-				    struct ncm_rx_ring *ring,
172
-				    struct io_buffer *iobuf ) {
173
-
174
-	/* Add to recycled list */
175
-	list_add_tail ( &iobuf->list, &ring->list );
176
-}
177
-
178
-/**
179
- * Free receive ring
180
- *
181
- * @v ncm		CDC-NCM device
182
- * @v ring		Receive ring
183
- */
184
-static void ncm_rx_free ( struct ncm_device *ncm __unused,
185
-			  struct ncm_rx_ring *ring ) {
186
-	struct io_buffer *iobuf;
187
-	struct io_buffer *tmp;
188
-
189
-	/* Free I/O buffers */
190
-	list_for_each_entry_safe ( iobuf, tmp, &ring->list, list ) {
191
-		list_del ( &iobuf->list );
192
-		free_iob ( iobuf );
193
-	}
194
-}
195
-
196
 /******************************************************************************
54
 /******************************************************************************
197
  *
55
  *
198
  * CDC-NCM communications interface
56
  * CDC-NCM communications interface
209
  */
67
  */
210
 static void ncm_intr_complete ( struct usb_endpoint *ep,
68
 static void ncm_intr_complete ( struct usb_endpoint *ep,
211
 				struct io_buffer *iobuf, int rc ) {
69
 				struct io_buffer *iobuf, int rc ) {
212
-	struct ncm_device *ncm = container_of ( ep, struct ncm_device, intr.ep);
70
+	struct ncm_device *ncm = container_of ( ep, struct ncm_device, intr );
213
 	struct net_device *netdev = ncm->netdev;
71
 	struct net_device *netdev = ncm->netdev;
214
 	struct usb_setup_packet *message;
72
 	struct usb_setup_packet *message;
215
 	size_t len = iob_len ( iobuf );
73
 	size_t len = iob_len ( iobuf );
219
 
77
 
220
 	/* Ignore packets cancelled when the endpoint closes */
78
 	/* Ignore packets cancelled when the endpoint closes */
221
 	if ( ! ep->open )
79
 	if ( ! ep->open )
222
-		goto done;
80
+		goto ignore;
223
 
81
 
224
 	/* Ignore packets with errors */
82
 	/* Ignore packets with errors */
225
 	if ( rc != 0 ) {
83
 	if ( rc != 0 ) {
226
 		DBGC ( ncm, "NCM %p interrupt failed: %s\n",
84
 		DBGC ( ncm, "NCM %p interrupt failed: %s\n",
227
 		       ncm, strerror ( rc ) );
85
 		       ncm, strerror ( rc ) );
228
 		DBGC_HDA ( ncm, 0, iobuf->data, iob_len ( iobuf ) );
86
 		DBGC_HDA ( ncm, 0, iobuf->data, iob_len ( iobuf ) );
229
-		goto done;
87
+		goto error;
230
 	}
88
 	}
231
 
89
 
232
 	/* Extract message header */
90
 	/* Extract message header */
233
 	if ( len < sizeof ( *message ) ) {
91
 	if ( len < sizeof ( *message ) ) {
234
 		DBGC ( ncm, "NCM %p underlength interrupt:\n", ncm );
92
 		DBGC ( ncm, "NCM %p underlength interrupt:\n", ncm );
235
 		DBGC_HDA ( ncm, 0, iobuf->data, iob_len ( iobuf ) );
93
 		DBGC_HDA ( ncm, 0, iobuf->data, iob_len ( iobuf ) );
236
-		goto done;
94
+		rc = -EINVAL;
95
+		goto error;
237
 	}
96
 	}
238
 	message = iobuf->data;
97
 	message = iobuf->data;
239
 
98
 
257
 	default:
116
 	default:
258
 		DBGC ( ncm, "NCM %p unrecognised interrupt:\n", ncm );
117
 		DBGC ( ncm, "NCM %p unrecognised interrupt:\n", ncm );
259
 		DBGC_HDA ( ncm, 0, iobuf->data, iob_len ( iobuf ) );
118
 		DBGC_HDA ( ncm, 0, iobuf->data, iob_len ( iobuf ) );
260
-		break;
119
+		goto error;
261
 	}
120
 	}
262
 
121
 
263
- done:
264
-	/* Recycle buffer */
265
-	ncm_rx_recycle ( ncm, &ncm->intr, iobuf );
122
+	/* Free I/O buffer */
123
+	free_iob ( iobuf );
266
 	profile_stop ( &ncm_intr_profiler );
124
 	profile_stop ( &ncm_intr_profiler );
125
+
126
+	return;
127
+
128
+ error:
129
+	netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
130
+ ignore:
131
+	free_iob ( iobuf );
132
+	return;
267
 }
133
 }
268
 
134
 
269
 /** Interrupt endpoint operations */
135
 /** Interrupt endpoint operations */
280
 static int ncm_comms_open ( struct ncm_device *ncm ) {
146
 static int ncm_comms_open ( struct ncm_device *ncm ) {
281
 	int rc;
147
 	int rc;
282
 
148
 
283
-	/* Allocate I/O buffers */
284
-	if ( ( rc = ncm_rx_alloc ( ncm, &ncm->intr, ncm->intr.ep.mtu,
285
-				   NCM_INTR_COUNT ) ) != 0 ) {
286
-		DBGC ( ncm, "NCM %p could not allocate RX buffers: %s\n",
287
-		       ncm, strerror ( rc ) );
288
-		goto err_alloc;
289
-	}
290
-
291
 	/* Open interrupt endpoint */
149
 	/* Open interrupt endpoint */
292
-	if ( ( rc = usb_endpoint_open ( &ncm->intr.ep ) ) != 0 ) {
150
+	if ( ( rc = usb_endpoint_open ( &ncm->intr ) ) != 0 ) {
293
 		DBGC ( ncm, "NCM %p could not open interrupt: %s\n",
151
 		DBGC ( ncm, "NCM %p could not open interrupt: %s\n",
294
 		       ncm, strerror ( rc ) );
152
 		       ncm, strerror ( rc ) );
295
 		goto err_open;
153
 		goto err_open;
296
 	}
154
 	}
297
 
155
 
156
+	/* Refill interrupt endpoint */
157
+	usb_refill ( &ncm->intr );
158
+
298
 	return 0;
159
 	return 0;
299
 
160
 
300
-	usb_endpoint_close ( &ncm->intr.ep );
161
+	usb_endpoint_close ( &ncm->intr );
301
  err_open:
162
  err_open:
302
-	ncm_rx_free ( ncm, &ncm->intr );
303
- err_alloc:
304
 	return rc;
163
 	return rc;
305
 }
164
 }
306
 
165
 
312
 static void ncm_comms_close ( struct ncm_device *ncm ) {
171
 static void ncm_comms_close ( struct ncm_device *ncm ) {
313
 
172
 
314
 	/* Close interrupt endpoint */
173
 	/* Close interrupt endpoint */
315
-	usb_endpoint_close ( &ncm->intr.ep );
316
-
317
-	/* Free I/O buffers */
318
-	ncm_rx_free ( ncm, &ncm->intr );
174
+	usb_endpoint_close ( &ncm->intr );
319
 }
175
 }
320
 
176
 
321
 /******************************************************************************
177
 /******************************************************************************
326
  */
182
  */
327
 
183
 
328
 /**
184
 /**
329
- * Allocate bulk IN receive ring buffers
185
+ * Prefill bulk IN endpoint
330
  *
186
  *
331
  * @v ncm		CDC-NCM device
187
  * @v ncm		CDC-NCM device
332
  * @ret rc		Return status code
188
  * @ret rc		Return status code
333
  */
189
  */
334
-static int ncm_in_alloc ( struct ncm_device *ncm ) {
190
+static int ncm_in_prefill ( struct ncm_device *ncm ) {
335
 	size_t mtu;
191
 	size_t mtu;
336
 	unsigned int count;
192
 	unsigned int count;
337
 	int rc;
193
 	int rc;
358
 			count = NCM_IN_MIN_COUNT;
214
 			count = NCM_IN_MIN_COUNT;
359
 		if ( ( count * mtu ) > NCM_IN_MAX_SIZE )
215
 		if ( ( count * mtu ) > NCM_IN_MAX_SIZE )
360
 			continue;
216
 			continue;
361
-		if ( ( rc = ncm_rx_alloc ( ncm, &ncm->in, mtu, count ) ) != 0 )
217
+		usb_refill_init ( &ncm->in, mtu, count );
218
+		if ( ( rc = usb_prefill ( &ncm->in ) ) != 0 ) {
219
+			DBGC ( ncm, "NCM %p could not prefill %dx %zd-byte "
220
+			       "buffers for bulk IN\n", ncm, count, mtu );
362
 			continue;
221
 			continue;
222
+		}
363
 
223
 
364
 		DBGC ( ncm, "NCM %p using %dx %zd-byte buffers for bulk IN\n",
224
 		DBGC ( ncm, "NCM %p using %dx %zd-byte buffers for bulk IN\n",
365
 		       ncm, count, mtu );
225
 		       ncm, count, mtu );
366
 		return 0;
226
 		return 0;
367
 	}
227
 	}
368
 
228
 
369
-	DBGC ( ncm, "NCM %p could not allocate bulk IN buffers\n", ncm );
229
+	DBGC ( ncm, "NCM %p could not prefill bulk IN endpoint\n", ncm );
370
 	return -ENOMEM;
230
 	return -ENOMEM;
371
 }
231
 }
372
 
232
 
379
  */
239
  */
380
 static void ncm_in_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
240
 static void ncm_in_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
381
 			      int rc ) {
241
 			      int rc ) {
382
-	struct ncm_device *ncm = container_of ( ep, struct ncm_device, in.ep );
242
+	struct ncm_device *ncm = container_of ( ep, struct ncm_device, in );
383
 	struct net_device *netdev = ncm->netdev;
243
 	struct net_device *netdev = ncm->netdev;
384
 	struct ncm_transfer_header *nth;
244
 	struct ncm_transfer_header *nth;
385
 	struct ncm_datagram_pointer *ndp;
245
 	struct ncm_datagram_pointer *ndp;
404
 	if ( rc != 0 ) {
264
 	if ( rc != 0 ) {
405
 		DBGC ( ncm, "NCM %p bulk IN failed: %s\n",
265
 		DBGC ( ncm, "NCM %p bulk IN failed: %s\n",
406
 		       ncm, strerror ( rc ) );
266
 		       ncm, strerror ( rc ) );
407
-		goto drop;
267
+		goto error;
408
 	}
268
 	}
409
 
269
 
410
 	/* Locate transfer header */
270
 	/* Locate transfer header */
411
 	len = iob_len ( iobuf );
271
 	len = iob_len ( iobuf );
412
 	if ( sizeof ( *nth ) > len ) {
272
 	if ( sizeof ( *nth ) > len ) {
413
 		DBGC ( ncm, "NCM %p packet too short for NTH:\n", ncm );
273
 		DBGC ( ncm, "NCM %p packet too short for NTH:\n", ncm );
274
+		rc = -EINVAL;
414
 		goto error;
275
 		goto error;
415
 	}
276
 	}
416
 	nth = iobuf->data;
277
 	nth = iobuf->data;
419
 	ndp_offset = le16_to_cpu ( nth->offset );
280
 	ndp_offset = le16_to_cpu ( nth->offset );
420
 	if ( ( ndp_offset + sizeof ( *ndp ) ) > len ) {
281
 	if ( ( ndp_offset + sizeof ( *ndp ) ) > len ) {
421
 		DBGC ( ncm, "NCM %p packet too short for NDP:\n", ncm );
282
 		DBGC ( ncm, "NCM %p packet too short for NDP:\n", ncm );
283
+		rc = -EINVAL;
422
 		goto error;
284
 		goto error;
423
 	}
285
 	}
424
 	ndp = ( iobuf->data + ndp_offset );
286
 	ndp = ( iobuf->data + ndp_offset );
425
 	ndp_len = le16_to_cpu ( ndp->header_len );
287
 	ndp_len = le16_to_cpu ( ndp->header_len );
426
 	if ( ndp_len < offsetof ( typeof ( *ndp ), desc ) ) {
288
 	if ( ndp_len < offsetof ( typeof ( *ndp ), desc ) ) {
427
 		DBGC ( ncm, "NCM %p NDP header length too short:\n", ncm );
289
 		DBGC ( ncm, "NCM %p NDP header length too short:\n", ncm );
290
+		rc = -EINVAL;
428
 		goto error;
291
 		goto error;
429
 	}
292
 	}
430
 	if ( ( ndp_offset + ndp_len ) > len ) {
293
 	if ( ( ndp_offset + ndp_len ) > len ) {
431
 		DBGC ( ncm, "NCM %p packet too short for NDP:\n", ncm );
294
 		DBGC ( ncm, "NCM %p packet too short for NDP:\n", ncm );
295
+		rc = -EINVAL;
432
 		goto error;
296
 		goto error;
433
 	}
297
 	}
434
 
298
 
445
 		pkt_len = le16_to_cpu ( desc->len );
309
 		pkt_len = le16_to_cpu ( desc->len );
446
 		if ( pkt_len < ETH_HLEN ) {
310
 		if ( pkt_len < ETH_HLEN ) {
447
 			DBGC ( ncm, "NCM %p underlength datagram:\n", ncm );
311
 			DBGC ( ncm, "NCM %p underlength datagram:\n", ncm );
312
+			rc = -EINVAL;
448
 			goto error;
313
 			goto error;
449
 		}
314
 		}
450
 		if ( ( pkt_offset + pkt_len ) > len ) {
315
 		if ( ( pkt_offset + pkt_len ) > len ) {
451
 			DBGC ( ncm, "NCM %p datagram exceeds packet:\n", ncm );
316
 			DBGC ( ncm, "NCM %p datagram exceeds packet:\n", ncm );
317
+			rc = -EINVAL;
452
 			goto error;
318
 			goto error;
453
 		}
319
 		}
454
 
320
 
468
 		 * received packet and reuse the same I/O buffer for
334
 		 * received packet and reuse the same I/O buffer for
469
 		 * transmission.
335
 		 * transmission.
470
 		 */
336
 		 */
471
-		headroom = ( sizeof ( struct ncm_ntb_header ) +
472
-			     ncm->out.padding );
337
+		headroom = ( sizeof ( struct ncm_ntb_header ) + ncm->padding );
473
 		pkt = alloc_iob ( headroom + pkt_len );
338
 		pkt = alloc_iob ( headroom + pkt_len );
474
 		if ( ! pkt ) {
339
 		if ( ! pkt ) {
475
 			/* Record error and continue */
340
 			/* Record error and continue */
490
 	}
355
 	}
491
 
356
 
492
 	/* Recycle I/O buffer */
357
 	/* Recycle I/O buffer */
493
-	ncm_rx_recycle ( ncm, &ncm->in, iobuf );
358
+	usb_recycle ( &ncm->in, iobuf );
494
 	profile_stop ( &ncm_in_profiler );
359
 	profile_stop ( &ncm_in_profiler );
495
 
360
 
496
 	return;
361
 	return;
497
 
362
 
498
  error:
363
  error:
499
-	rc = -EIO;
500
- drop:
501
 	/* Record error against network device */
364
 	/* Record error against network device */
502
 	DBGC_HDA ( ncm, 0, iobuf->data, iob_len ( iobuf ) );
365
 	DBGC_HDA ( ncm, 0, iobuf->data, iob_len ( iobuf ) );
503
 	netdev_rx_err ( netdev, NULL, rc );
366
 	netdev_rx_err ( netdev, NULL, rc );
504
  ignore:
367
  ignore:
505
-	ncm_rx_recycle ( ncm, &ncm->in, iobuf );
368
+	usb_recycle ( &ncm->in, iobuf );
506
 }
369
 }
507
 
370
 
508
 /** Bulk IN endpoint operations */
371
 /** Bulk IN endpoint operations */
521
 			      struct io_buffer *iobuf ) {
384
 			      struct io_buffer *iobuf ) {
522
 	struct ncm_ntb_header *header;
385
 	struct ncm_ntb_header *header;
523
 	size_t len = iob_len ( iobuf );
386
 	size_t len = iob_len ( iobuf );
524
-	size_t header_len = ( sizeof ( *header ) + ncm->out.padding );
387
+	size_t header_len = ( sizeof ( *header ) + ncm->padding );
525
 	int rc;
388
 	int rc;
526
 
389
 
527
 	/* Profile transmissions */
390
 	/* Profile transmissions */
535
 	/* Populate header */
398
 	/* Populate header */
536
 	header->nth.magic = cpu_to_le32 ( NCM_TRANSFER_HEADER_MAGIC );
399
 	header->nth.magic = cpu_to_le32 ( NCM_TRANSFER_HEADER_MAGIC );
537
 	header->nth.header_len = cpu_to_le16 ( sizeof ( header->nth ) );
400
 	header->nth.header_len = cpu_to_le16 ( sizeof ( header->nth ) );
538
-	header->nth.sequence = cpu_to_le16 ( ncm->out.sequence );
401
+	header->nth.sequence = cpu_to_le16 ( ncm->sequence );
539
 	header->nth.len = cpu_to_le16 ( iob_len ( iobuf ) );
402
 	header->nth.len = cpu_to_le16 ( iob_len ( iobuf ) );
540
 	header->nth.offset =
403
 	header->nth.offset =
541
 		cpu_to_le16 ( offsetof ( typeof ( *header ), ndp ) );
404
 		cpu_to_le16 ( offsetof ( typeof ( *header ), ndp ) );
548
 	memset ( &header->desc[1], 0, sizeof ( header->desc[1] ) );
411
 	memset ( &header->desc[1], 0, sizeof ( header->desc[1] ) );
549
 
412
 
550
 	/* Enqueue I/O buffer */
413
 	/* Enqueue I/O buffer */
551
-	if ( ( rc = usb_stream ( &ncm->out.ep, iobuf, 0 ) ) != 0 )
414
+	if ( ( rc = usb_stream ( &ncm->out, iobuf, 0 ) ) != 0 )
552
 		return rc;
415
 		return rc;
553
 
416
 
554
 	/* Increment sequence number */
417
 	/* Increment sequence number */
555
-	ncm->out.sequence++;
418
+	ncm->sequence++;
556
 
419
 
557
 	profile_stop ( &ncm_out_profiler );
420
 	profile_stop ( &ncm_out_profiler );
558
 	return 0;
421
 	return 0;
567
  */
430
  */
568
 static void ncm_out_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
431
 static void ncm_out_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
569
 			       int rc ) {
432
 			       int rc ) {
570
-	struct ncm_device *ncm = container_of ( ep, struct ncm_device, out.ep );
433
+	struct ncm_device *ncm = container_of ( ep, struct ncm_device, out );
571
 	struct net_device *netdev = ncm->netdev;
434
 	struct net_device *netdev = ncm->netdev;
572
 
435
 
573
 	/* Report TX completion */
436
 	/* Report TX completion */
590
 	struct ncm_set_ntb_input_size size;
453
 	struct ncm_set_ntb_input_size size;
591
 	int rc;
454
 	int rc;
592
 
455
 
593
-	/* Allocate I/O buffers */
594
-	if ( ( rc = ncm_in_alloc ( ncm ) ) != 0 )
595
-		goto err_alloc;
456
+	/* Prefill I/O buffers */
457
+	if ( ( rc = ncm_in_prefill ( ncm ) ) != 0 )
458
+		goto err_prefill;
596
 
459
 
597
 	/* Set maximum input size */
460
 	/* Set maximum input size */
598
 	memset ( &size, 0, sizeof ( size ) );
461
 	memset ( &size, 0, sizeof ( size ) );
599
-	size.mtu = cpu_to_le32 ( ncm->in.mtu );
462
+	size.mtu = cpu_to_le32 ( ncm->in.len );
600
 	if ( ( rc = usb_control ( usb, NCM_SET_NTB_INPUT_SIZE, 0, ncm->comms,
463
 	if ( ( rc = usb_control ( usb, NCM_SET_NTB_INPUT_SIZE, 0, ncm->comms,
601
 				  &size, sizeof ( size ) ) ) != 0 ) {
464
 				  &size, sizeof ( size ) ) ) != 0 ) {
602
 		DBGC ( ncm, "NCM %p could not set input size to %zd: %s\n",
465
 		DBGC ( ncm, "NCM %p could not set input size to %zd: %s\n",
613
 	}
476
 	}
614
 
477
 
615
 	/* Open bulk IN endpoint */
478
 	/* Open bulk IN endpoint */
616
-	if ( ( rc = usb_endpoint_open ( &ncm->in.ep ) ) != 0 ) {
479
+	if ( ( rc = usb_endpoint_open ( &ncm->in ) ) != 0 ) {
617
 		DBGC ( ncm, "NCM %p could not open bulk IN: %s\n",
480
 		DBGC ( ncm, "NCM %p could not open bulk IN: %s\n",
618
 		       ncm, strerror ( rc ) );
481
 		       ncm, strerror ( rc ) );
619
 		goto err_open_in;
482
 		goto err_open_in;
620
 	}
483
 	}
621
 
484
 
622
 	/* Open bulk OUT endpoint */
485
 	/* Open bulk OUT endpoint */
623
-	if ( ( rc = usb_endpoint_open ( &ncm->out.ep ) ) != 0 ) {
486
+	if ( ( rc = usb_endpoint_open ( &ncm->out ) ) != 0 ) {
624
 		DBGC ( ncm, "NCM %p could not open bulk OUT: %s\n",
487
 		DBGC ( ncm, "NCM %p could not open bulk OUT: %s\n",
625
 		       ncm, strerror ( rc ) );
488
 		       ncm, strerror ( rc ) );
626
 		goto err_open_out;
489
 		goto err_open_out;
627
 	}
490
 	}
628
 
491
 
629
-	/* Reset transmit sequence number */
630
-	ncm->out.sequence = 0;
492
+	/* Refill bulk IN endpoint */
493
+	if ( ( rc = usb_refill ( &ncm->in ) ) != 0 ) {
494
+		DBGC ( ncm, "NCM %p could not refill bulk IN: %s\n",
495
+		       ncm, strerror ( rc ) );
496
+		goto err_refill;
497
+	}
631
 
498
 
632
 	return 0;
499
 	return 0;
633
 
500
 
634
-	usb_endpoint_close ( &ncm->out.ep );
501
+ err_refill:
502
+	usb_endpoint_close ( &ncm->out );
635
  err_open_out:
503
  err_open_out:
636
-	usb_endpoint_close ( &ncm->in.ep );
504
+	usb_endpoint_close ( &ncm->in );
637
  err_open_in:
505
  err_open_in:
638
 	usb_set_interface ( usb, ncm->data, 0 );
506
 	usb_set_interface ( usb, ncm->data, 0 );
639
  err_set_interface:
507
  err_set_interface:
640
  err_set_ntb_input_size:
508
  err_set_ntb_input_size:
641
-	ncm_rx_free ( ncm, &ncm->in );
642
- err_alloc:
509
+	usb_flush ( &ncm->in );
510
+ err_prefill:
643
 	return rc;
511
 	return rc;
644
 }
512
 }
645
 
513
 
652
 	struct usb_device *usb = ncm->usb;
520
 	struct usb_device *usb = ncm->usb;
653
 
521
 
654
 	/* Close endpoints */
522
 	/* Close endpoints */
655
-	usb_endpoint_close ( &ncm->out.ep );
656
-	usb_endpoint_close ( &ncm->in.ep );
523
+	usb_endpoint_close ( &ncm->out );
524
+	usb_endpoint_close ( &ncm->in );
657
 
525
 
658
 	/* Reset data interface */
526
 	/* Reset data interface */
659
 	usb_set_interface ( usb, ncm->data, 0 );
527
 	usb_set_interface ( usb, ncm->data, 0 );
660
-
661
-	/* Free I/O buffers */
662
-	ncm_rx_free ( ncm, &ncm->in );
663
 }
528
 }
664
 
529
 
665
 /******************************************************************************
530
 /******************************************************************************
680
 	int rc;
545
 	int rc;
681
 
546
 
682
 	/* Reset sequence number */
547
 	/* Reset sequence number */
683
-	ncm->out.sequence = 0;
548
+	ncm->sequence = 0;
684
 
549
 
685
 	/* Open communications interface */
550
 	/* Open communications interface */
686
 	if ( ( rc = ncm_comms_open ( ncm ) ) != 0 )
551
 	if ( ( rc = ncm_comms_open ( ncm ) ) != 0 )
687
 		goto err_comms_open;
552
 		goto err_comms_open;
688
 
553
 
689
-	/* Refill interrupt ring */
690
-	if ( ( rc = ncm_rx_refill ( ncm, &ncm->intr ) ) != 0 )
691
-		goto err_intr_refill;
692
-
693
 	/* Open data interface */
554
 	/* Open data interface */
694
 	if ( ( rc = ncm_data_open ( ncm ) ) != 0 )
555
 	if ( ( rc = ncm_data_open ( ncm ) ) != 0 )
695
 		goto err_data_open;
556
 		goto err_data_open;
696
 
557
 
697
-	/* Refill bulk IN ring */
698
-	if ( ( rc = ncm_rx_refill ( ncm, &ncm->in ) ) != 0 )
699
-		goto err_in_refill;
700
-
701
 	return 0;
558
 	return 0;
702
 
559
 
703
- err_in_refill:
704
 	ncm_data_close ( ncm );
560
 	ncm_data_close ( ncm );
705
  err_data_open:
561
  err_data_open:
706
- err_intr_refill:
707
 	ncm_comms_close ( ncm );
562
 	ncm_comms_close ( ncm );
708
  err_comms_open:
563
  err_comms_open:
709
 	return rc;
564
 	return rc;
755
 	/* Poll USB bus */
610
 	/* Poll USB bus */
756
 	usb_poll ( ncm->bus );
611
 	usb_poll ( ncm->bus );
757
 
612
 
758
-	/* Refill interrupt ring */
759
-	if ( ( rc = ncm_rx_refill ( ncm, &ncm->intr ) ) != 0 )
613
+	/* Refill interrupt endpoint */
614
+	if ( ( rc = usb_refill ( &ncm->intr ) ) != 0 )
760
 		netdev_rx_err ( netdev, NULL, rc );
615
 		netdev_rx_err ( netdev, NULL, rc );
761
 
616
 
762
-	/* Refill bulk IN ring */
763
-	if ( ( rc = ncm_rx_refill ( ncm, &ncm->in ) ) != 0 )
617
+	/* Refill bulk IN endpoint */
618
+	if ( ( rc = usb_refill ( &ncm->in ) ) != 0 )
764
 		netdev_rx_err ( netdev, NULL, rc );
619
 		netdev_rx_err ( netdev, NULL, rc );
765
 }
620
 }
766
 
621
 
810
 	ncm->usb = usb;
665
 	ncm->usb = usb;
811
 	ncm->bus = usb->port->hub->bus;
666
 	ncm->bus = usb->port->hub->bus;
812
 	ncm->netdev = netdev;
667
 	ncm->netdev = netdev;
813
-	usb_endpoint_init ( &ncm->intr.ep, usb, &ncm_intr_operations );
814
-	usb_endpoint_init ( &ncm->in.ep, usb, &ncm_in_operations );
815
-	usb_endpoint_init ( &ncm->out.ep, usb, &ncm_out_operations );
668
+	usb_endpoint_init ( &ncm->intr, usb, &ncm_intr_operations );
669
+	usb_endpoint_init ( &ncm->in, usb, &ncm_in_operations );
670
+	usb_endpoint_init ( &ncm->out, usb, &ncm_out_operations );
671
+	usb_refill_init ( &ncm->intr, 0, NCM_INTR_COUNT );
816
 	DBGC ( ncm, "NCM %p on %s\n", ncm, func->name );
672
 	DBGC ( ncm, "NCM %p on %s\n", ncm, func->name );
817
 
673
 
818
 	/* Identify interfaces */
674
 	/* Identify interfaces */
843
 	}
699
 	}
844
 
700
 
845
 	/* Describe interrupt endpoint */
701
 	/* Describe interrupt endpoint */
846
-	if ( ( rc = usb_endpoint_described ( &ncm->intr.ep, config, comms,
702
+	if ( ( rc = usb_endpoint_described ( &ncm->intr, config, comms,
847
 					     USB_INTERRUPT, 0 ) ) != 0 ) {
703
 					     USB_INTERRUPT, 0 ) ) != 0 ) {
848
 		DBGC ( ncm, "NCM %p could not describe interrupt endpoint: "
704
 		DBGC ( ncm, "NCM %p could not describe interrupt endpoint: "
849
 		       "%s\n", ncm, strerror ( rc ) );
705
 		       "%s\n", ncm, strerror ( rc ) );
851
 	}
707
 	}
852
 
708
 
853
 	/* Describe bulk IN endpoint */
709
 	/* Describe bulk IN endpoint */
854
-	if ( ( rc = usb_endpoint_described ( &ncm->in.ep, config, data,
710
+	if ( ( rc = usb_endpoint_described ( &ncm->in, config, data,
855
 					     USB_BULK_IN, 0 ) ) != 0 ) {
711
 					     USB_BULK_IN, 0 ) ) != 0 ) {
856
 		DBGC ( ncm, "NCM %p could not describe bulk IN endpoint: "
712
 		DBGC ( ncm, "NCM %p could not describe bulk IN endpoint: "
857
 		       "%s\n", ncm, strerror ( rc ) );
713
 		       "%s\n", ncm, strerror ( rc ) );
859
 	}
715
 	}
860
 
716
 
861
 	/* Describe bulk OUT endpoint */
717
 	/* Describe bulk OUT endpoint */
862
-	if ( ( rc = usb_endpoint_described ( &ncm->out.ep, config, data,
718
+	if ( ( rc = usb_endpoint_described ( &ncm->out, config, data,
863
 					     USB_BULK_OUT, 0 ) ) != 0 ) {
719
 					     USB_BULK_OUT, 0 ) ) != 0 ) {
864
 		DBGC ( ncm, "NCM %p could not describe bulk OUT endpoint: "
720
 		DBGC ( ncm, "NCM %p could not describe bulk OUT endpoint: "
865
 		       "%s\n", ncm, strerror ( rc ) );
721
 		       "%s\n", ncm, strerror ( rc ) );
894
 	DBGC2 ( ncm, "NCM %p maximum IN size is %zd bytes\n", ncm, ncm->mtu );
750
 	DBGC2 ( ncm, "NCM %p maximum IN size is %zd bytes\n", ncm, ncm->mtu );
895
 
751
 
896
 	/* Calculate transmit padding */
752
 	/* Calculate transmit padding */
897
-	ncm->out.padding = ( ( le16_to_cpu ( params.out.remainder ) -
898
-			       sizeof ( struct ncm_ntb_header ) - ETH_HLEN ) &
899
-			     ( le16_to_cpu ( params.out.divisor ) - 1 ) );
753
+	ncm->padding = ( ( le16_to_cpu ( params.out.remainder ) -
754
+			   sizeof ( struct ncm_ntb_header ) - ETH_HLEN ) &
755
+			 ( le16_to_cpu ( params.out.divisor ) - 1 ) );
900
 	DBGC2 ( ncm, "NCM %p using %zd-byte transmit padding\n",
756
 	DBGC2 ( ncm, "NCM %p using %zd-byte transmit padding\n",
901
-		ncm, ncm->out.padding );
902
-	assert ( ( ( sizeof ( struct ncm_ntb_header ) + ncm->out.padding +
757
+		ncm, ncm->padding );
758
+	assert ( ( ( sizeof ( struct ncm_ntb_header ) + ncm->padding +
903
 		     ETH_HLEN ) % le16_to_cpu ( params.out.divisor ) ) ==
759
 		     ETH_HLEN ) % le16_to_cpu ( params.out.divisor ) ) ==
904
 		 le16_to_cpu ( params.out.remainder ) );
760
 		 le16_to_cpu ( params.out.remainder ) );
905
 
761
 

+ 10
- 26
src/drivers/net/ncm.h Voir le fichier

139
 	struct ncm_datagram_descriptor desc[2];
139
 	struct ncm_datagram_descriptor desc[2];
140
 } __attribute__ (( packed ));
140
 } __attribute__ (( packed ));
141
 
141
 
142
-/** A CDC-NCM receive ring */
143
-struct ncm_rx_ring {
144
-	/** USB endpoint */
145
-	struct usb_endpoint ep;
146
-	/** I/O buffer size */
147
-	size_t mtu;
148
-	/** Recycled buffer list */
149
-	struct list_head list;
150
-};
151
-
152
-/** A CDC-NCM transmit ring */
153
-struct ncm_tx_ring {
154
-	/** USB endpoint */
155
-	struct usb_endpoint ep;
156
-	/** Transmitted packet sequence number */
157
-	uint16_t sequence;
158
-	/** Alignment padding required on transmitted packets */
159
-	size_t padding;
160
-};
161
-
162
 /** A CDC-NCM network device */
142
 /** A CDC-NCM network device */
163
 struct ncm_device {
143
 struct ncm_device {
164
 	/** USB device */
144
 	/** USB device */
175
 
155
 
176
 	/** Maximum supported NTB input size */
156
 	/** Maximum supported NTB input size */
177
 	size_t mtu;
157
 	size_t mtu;
158
+	/** Transmitted packet sequence number */
159
+	uint16_t sequence;
160
+	/** Alignment padding required on transmitted packets */
161
+	size_t padding;
178
 
162
 
179
-	/** Interrupt ring */
180
-	struct ncm_rx_ring intr;
181
-	/** Bulk IN ring */
182
-	struct ncm_rx_ring in;
183
-	/** Bulk OUT ring */
184
-	struct ncm_tx_ring out;
163
+	/** Interrupt endpoint */
164
+	struct usb_endpoint intr;
165
+	/** Bulk IN endpoint */
166
+	struct usb_endpoint in;
167
+	/** Bulk OUT endpoint */
168
+	struct usb_endpoint out;
185
 };
169
 };
186
 
170
 
187
 /** Bulk IN ring minimum buffer count
171
 /** Bulk IN ring minimum buffer count

Chargement…
Annuler
Enregistrer