|
@@ -290,6 +290,65 @@ e1000_configure_tx ( struct e1000_adapter *adapter )
|
290
|
290
|
E1000_WRITE_FLUSH ( hw );
|
291
|
291
|
}
|
292
|
292
|
|
|
293
|
+static void
|
|
294
|
+e1000_free_rx_resources ( struct e1000_adapter *adapter )
|
|
295
|
+{
|
|
296
|
+ int i;
|
|
297
|
+
|
|
298
|
+ DBG ( "e1000_free_rx_resources\n" );
|
|
299
|
+
|
|
300
|
+ free_dma ( adapter->rx_base, adapter->rx_ring_size );
|
|
301
|
+
|
|
302
|
+ for ( i = 0; i < NUM_RX_DESC; i++ ) {
|
|
303
|
+ free_iob ( adapter->rx_iobuf[i] );
|
|
304
|
+ }
|
|
305
|
+}
|
|
306
|
+
|
|
307
|
+/**
|
|
308
|
+ * e1000_refill_rx_ring - allocate Rx io_buffers
|
|
309
|
+ *
|
|
310
|
+ * @v adapter e1000 private structure
|
|
311
|
+ *
|
|
312
|
+ * @ret rc Returns 0 on success, negative on failure
|
|
313
|
+ **/
|
|
314
|
+int e1000_refill_rx_ring ( struct e1000_adapter *adapter )
|
|
315
|
+{
|
|
316
|
+ int i, rx_curr;
|
|
317
|
+ int rc = 0;
|
|
318
|
+ struct e1000_rx_desc *rx_curr_desc;
|
|
319
|
+ struct e1000_hw *hw = &adapter->hw;
|
|
320
|
+ struct io_buffer *iob;
|
|
321
|
+
|
|
322
|
+ DBG ("e1000_refill_rx_ring\n");
|
|
323
|
+
|
|
324
|
+ for ( i = 0; i < NUM_RX_DESC; i++ ) {
|
|
325
|
+ rx_curr = ( ( adapter->rx_curr + i ) % NUM_RX_DESC );
|
|
326
|
+ rx_curr_desc = adapter->rx_base + rx_curr;
|
|
327
|
+
|
|
328
|
+ if ( rx_curr_desc->status & E1000_RXD_STAT_DD )
|
|
329
|
+ continue;
|
|
330
|
+
|
|
331
|
+ if ( adapter->rx_iobuf[rx_curr] != NULL )
|
|
332
|
+ continue;
|
|
333
|
+
|
|
334
|
+ DBG2 ( "Refilling rx desc %d\n", rx_curr );
|
|
335
|
+
|
|
336
|
+ iob = alloc_iob ( MAXIMUM_ETHERNET_VLAN_SIZE );
|
|
337
|
+ adapter->rx_iobuf[rx_curr] = iob;
|
|
338
|
+
|
|
339
|
+ if ( ! iob ) {
|
|
340
|
+ DBG ( "alloc_iob failed\n" );
|
|
341
|
+ rc = -ENOMEM;
|
|
342
|
+ break;
|
|
343
|
+ } else {
|
|
344
|
+ rx_curr_desc->buffer_addr = virt_to_bus ( iob->data );
|
|
345
|
+
|
|
346
|
+ E1000_WRITE_REG ( hw, RDT, rx_curr );
|
|
347
|
+ }
|
|
348
|
+ }
|
|
349
|
+ return rc;
|
|
350
|
+}
|
|
351
|
+
|
293
|
352
|
/**
|
294
|
353
|
* e1000_setup_rx_resources - allocate Rx resources (Descriptors)
|
295
|
354
|
*
|
|
@@ -300,8 +359,7 @@ e1000_configure_tx ( struct e1000_adapter *adapter )
|
300
|
359
|
static int
|
301
|
360
|
e1000_setup_rx_resources ( struct e1000_adapter *adapter )
|
302
|
361
|
{
|
303
|
|
- int i, j;
|
304
|
|
- struct e1000_rx_desc *rx_curr_desc;
|
|
362
|
+ int i, rc = 0;
|
305
|
363
|
|
306
|
364
|
DBG ( "e1000_setup_rx_resources\n" );
|
307
|
365
|
|
|
@@ -311,50 +369,23 @@ e1000_setup_rx_resources ( struct e1000_adapter *adapter )
|
311
|
369
|
|
312
|
370
|
adapter->rx_base =
|
313
|
371
|
malloc_dma ( adapter->rx_ring_size, adapter->rx_ring_size );
|
314
|
|
-
|
|
372
|
+
|
315
|
373
|
if ( ! adapter->rx_base ) {
|
316
|
374
|
return -ENOMEM;
|
317
|
375
|
}
|
318
|
376
|
memset ( adapter->rx_base, 0, adapter->rx_ring_size );
|
319
|
377
|
|
320
|
378
|
for ( i = 0; i < NUM_RX_DESC; i++ ) {
|
321
|
|
-
|
322
|
|
- adapter->rx_iobuf[i] = alloc_iob ( MAXIMUM_ETHERNET_VLAN_SIZE );
|
323
|
|
-
|
324
|
|
- /* If unable to allocate all iobufs, free any that
|
325
|
|
- * were successfully allocated, and return an error
|
326
|
|
- */
|
327
|
|
- if ( ! adapter->rx_iobuf[i] ) {
|
328
|
|
- for ( j = 0; j < i; j++ ) {
|
329
|
|
- free_iob ( adapter->rx_iobuf[j] );
|
330
|
|
- }
|
331
|
|
- return -ENOMEM;
|
332
|
|
- }
|
333
|
|
-
|
334
|
|
- rx_curr_desc = ( void * ) ( adapter->rx_base ) +
|
335
|
|
- ( i * sizeof ( *adapter->rx_base ) );
|
336
|
|
-
|
337
|
|
- rx_curr_desc->buffer_addr = virt_to_bus ( adapter->rx_iobuf[i]->data );
|
338
|
|
-
|
339
|
|
- DBG ( "i = %d rx_curr_desc->buffer_addr = %#16llx\n",
|
340
|
|
- i, rx_curr_desc->buffer_addr );
|
341
|
|
-
|
342
|
|
- }
|
343
|
|
- return 0;
|
344
|
|
-}
|
345
|
|
-
|
346
|
|
-static void
|
347
|
|
-e1000_free_rx_resources ( struct e1000_adapter *adapter )
|
348
|
|
-{
|
349
|
|
- int i;
|
350
|
|
-
|
351
|
|
- DBG ( "e1000_free_rx_resources\n" );
|
|
379
|
+ /* let e1000_refill_rx_ring() io_buffer allocations */
|
|
380
|
+ adapter->rx_iobuf[i] = NULL;
|
|
381
|
+ }
|
352
|
382
|
|
353
|
|
- free_dma ( adapter->rx_base, adapter->rx_ring_size );
|
|
383
|
+ /* allocate io_buffers */
|
|
384
|
+ rc = e1000_refill_rx_ring ( adapter );
|
|
385
|
+ if ( rc < 0 )
|
|
386
|
+ e1000_free_rx_resources ( adapter );
|
354
|
387
|
|
355
|
|
- for ( i = 0; i < NUM_RX_DESC; i++ ) {
|
356
|
|
- free_iob ( adapter->rx_iobuf[i] );
|
357
|
|
- }
|
|
388
|
+ return rc;
|
358
|
389
|
}
|
359
|
390
|
|
360
|
391
|
/**
|
|
@@ -676,12 +707,10 @@ e1000_poll ( struct net_device *netdev )
|
676
|
707
|
uint32_t rx_status;
|
677
|
708
|
uint32_t rx_len;
|
678
|
709
|
uint32_t rx_err;
|
679
|
|
- struct io_buffer *rx_iob;
|
680
|
710
|
struct e1000_tx_desc *tx_curr_desc;
|
681
|
711
|
struct e1000_rx_desc *rx_curr_desc;
|
682
|
712
|
uint32_t i;
|
683
|
|
- uint64_t tmp_buffer_addr;
|
684
|
|
-
|
|
713
|
+
|
685
|
714
|
DBGP ( "e1000_poll\n" );
|
686
|
715
|
|
687
|
716
|
/* Acknowledge interrupts */
|
|
@@ -741,46 +770,37 @@ e1000_poll ( struct net_device *netdev )
|
741
|
770
|
if ( ! ( rx_status & E1000_RXD_STAT_DD ) )
|
742
|
771
|
break;
|
743
|
772
|
|
|
773
|
+ if ( adapter->rx_iobuf[i] == NULL )
|
|
774
|
+ break;
|
|
775
|
+
|
744
|
776
|
DBG ( "RCTL = %#08x\n", E1000_READ_REG ( &adapter->hw, RCTL ) );
|
745
|
777
|
|
746
|
778
|
rx_len = rx_curr_desc->length;
|
747
|
779
|
|
748
|
780
|
DBG ( "Received packet, rx_curr: %d rx_status: %#08x rx_len: %d\n",
|
749
|
781
|
i, rx_status, rx_len );
|
750
|
|
-
|
|
782
|
+
|
751
|
783
|
rx_err = rx_curr_desc->errors;
|
752
|
|
-
|
|
784
|
+
|
|
785
|
+ iob_put ( adapter->rx_iobuf[i], rx_len );
|
|
786
|
+
|
753
|
787
|
if ( rx_err & E1000_RXD_ERR_FRAME_ERR_MASK ) {
|
754
|
788
|
|
755
|
|
- netdev_rx_err ( netdev, NULL, -EINVAL );
|
|
789
|
+ netdev_rx_err ( netdev, adapter->rx_iobuf[i], -EINVAL );
|
756
|
790
|
DBG ( "e1000_poll: Corrupted packet received!"
|
757
|
791
|
" rx_err: %#08x\n", rx_err );
|
758
|
792
|
} else {
|
759
|
|
-
|
760
|
|
- /* If unable allocate space for this packet,
|
761
|
|
- * try again next poll
|
762
|
|
- */
|
763
|
|
- rx_iob = alloc_iob ( rx_len );
|
764
|
|
- if ( ! rx_iob )
|
765
|
|
- break;
|
766
|
|
-
|
767
|
|
- memcpy ( iob_put ( rx_iob, rx_len ),
|
768
|
|
- adapter->rx_iobuf[i]->data, rx_len );
|
769
|
|
-
|
770
|
|
- /* Add this packet to the receive queue.
|
771
|
|
- */
|
772
|
|
- netdev_rx ( netdev, rx_iob );
|
|
793
|
+ /* Add this packet to the receive queue. */
|
|
794
|
+ netdev_rx ( netdev, adapter->rx_iobuf[i] );
|
773
|
795
|
}
|
|
796
|
+ adapter->rx_iobuf[i] = NULL;
|
774
|
797
|
|
775
|
|
- tmp_buffer_addr = rx_curr_desc->buffer_addr;
|
776
|
798
|
memset ( rx_curr_desc, 0, sizeof ( *rx_curr_desc ) );
|
777
|
|
- rx_curr_desc->buffer_addr = tmp_buffer_addr;
|
778
|
|
-
|
779
|
|
- E1000_WRITE_REG ( hw, RDT, adapter->rx_curr );
|
780
|
799
|
|
781
|
800
|
adapter->rx_curr = ( adapter->rx_curr + 1 ) % NUM_RX_DESC;
|
782
|
801
|
}
|
783
|
|
-}
|
|
802
|
+ e1000_refill_rx_ring(adapter);
|
|
803
|
+}
|
784
|
804
|
|
785
|
805
|
/**
|
786
|
806
|
* e1000_irq - enable or Disable interrupts
|