|
@@ -77,13 +77,8 @@ enum {
|
77
|
77
|
QUEUE_NB
|
78
|
78
|
};
|
79
|
79
|
|
80
|
|
-enum {
|
81
|
|
- /** Max number of pending rx packets */
|
82
|
|
- NUM_RX_BUF = 8,
|
83
|
|
-
|
84
|
|
- /** Max Ethernet frame length, including FCS and VLAN tag */
|
85
|
|
- RX_BUF_SIZE = 1522,
|
86
|
|
-};
|
|
80
|
+/** Max number of pending rx packets */
|
|
81
|
+#define NUM_RX_BUF 8
|
87
|
82
|
|
88
|
83
|
struct virtnet_nic {
|
89
|
84
|
/** Base pio register address */
|
|
@@ -160,12 +155,13 @@ static void virtnet_enqueue_iob ( struct net_device *netdev,
|
160
|
155
|
*/
|
161
|
156
|
static void virtnet_refill_rx_virtqueue ( struct net_device *netdev ) {
|
162
|
157
|
struct virtnet_nic *virtnet = netdev->priv;
|
|
158
|
+ size_t len = ( netdev->max_pkt_len + 4 /* VLAN */ );
|
163
|
159
|
|
164
|
160
|
while ( virtnet->rx_num_iobufs < NUM_RX_BUF ) {
|
165
|
161
|
struct io_buffer *iobuf;
|
166
|
162
|
|
167
|
163
|
/* Try to allocate a buffer, stop for now if out of memory */
|
168
|
|
- iobuf = alloc_iob ( RX_BUF_SIZE );
|
|
164
|
+ iobuf = alloc_iob ( len );
|
169
|
165
|
if ( ! iobuf )
|
170
|
166
|
break;
|
171
|
167
|
|
|
@@ -173,7 +169,7 @@ static void virtnet_refill_rx_virtqueue ( struct net_device *netdev ) {
|
173
|
169
|
list_add ( &iobuf->list, &virtnet->rx_iobufs );
|
174
|
170
|
|
175
|
171
|
/* Mark packet length until we know the actual size */
|
176
|
|
- iob_put ( iobuf, RX_BUF_SIZE );
|
|
172
|
+ iob_put ( iobuf, len );
|
177
|
173
|
|
178
|
174
|
virtnet_enqueue_iob ( netdev, RX_INDEX, iobuf );
|
179
|
175
|
virtnet->rx_num_iobufs++;
|
|
@@ -237,7 +233,8 @@ static int virtnet_open_legacy ( struct net_device *netdev ) {
|
237
|
233
|
|
238
|
234
|
/* Driver is ready */
|
239
|
235
|
features = vp_get_features ( ioaddr );
|
240
|
|
- vp_set_features ( ioaddr, features & ( 1 << VIRTIO_NET_F_MAC ) );
|
|
236
|
+ vp_set_features ( ioaddr, features & ( ( 1 << VIRTIO_NET_F_MAC ) |
|
|
237
|
+ ( 1 << VIRTIO_NET_F_MTU ) ) );
|
241
|
238
|
vp_set_status ( ioaddr, VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK );
|
242
|
239
|
return 0;
|
243
|
240
|
}
|
|
@@ -260,6 +257,7 @@ static int virtnet_open_modern ( struct net_device *netdev ) {
|
260
|
257
|
}
|
261
|
258
|
vpm_set_features ( &virtnet->vdev, features & (
|
262
|
259
|
( 1ULL << VIRTIO_NET_F_MAC ) |
|
|
260
|
+ ( 1ULL << VIRTIO_NET_F_MTU ) |
|
263
|
261
|
( 1ULL << VIRTIO_F_VERSION_1 ) |
|
264
|
262
|
( 1ULL << VIRTIO_F_ANY_LAYOUT ) ) );
|
265
|
263
|
vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_FEATURES_OK );
|
|
@@ -389,7 +387,7 @@ static void virtnet_process_rx_packets ( struct net_device *netdev ) {
|
389
|
387
|
virtnet->rx_num_iobufs--;
|
390
|
388
|
|
391
|
389
|
/* Update iobuf length */
|
392
|
|
- iob_unput ( iobuf, RX_BUF_SIZE );
|
|
390
|
+ iob_unput ( iobuf, iob_len ( iobuf ) );
|
393
|
391
|
iob_put ( iobuf, len - sizeof ( struct virtio_net_hdr ) );
|
394
|
392
|
|
395
|
393
|
DBGC2 ( virtnet, "VIRTIO-NET %p rx complete iobuf %p len %zd\n",
|
|
@@ -461,6 +459,7 @@ static int virtnet_probe_legacy ( struct pci_device *pci ) {
|
461
|
459
|
struct net_device *netdev;
|
462
|
460
|
struct virtnet_nic *virtnet;
|
463
|
461
|
u32 features;
|
|
462
|
+ u16 mtu;
|
464
|
463
|
int rc;
|
465
|
464
|
|
466
|
465
|
/* Allocate and hook up net device */
|
|
@@ -480,7 +479,7 @@ static int virtnet_probe_legacy ( struct pci_device *pci ) {
|
480
|
479
|
adjust_pci_device ( pci );
|
481
|
480
|
vp_reset ( ioaddr );
|
482
|
481
|
|
483
|
|
- /* Load MAC address */
|
|
482
|
+ /* Load MAC address and MTU */
|
484
|
483
|
features = vp_get_features ( ioaddr );
|
485
|
484
|
if ( features & ( 1 << VIRTIO_NET_F_MAC ) ) {
|
486
|
485
|
vp_get ( ioaddr, offsetof ( struct virtio_net_config, mac ),
|
|
@@ -488,6 +487,12 @@ static int virtnet_probe_legacy ( struct pci_device *pci ) {
|
488
|
487
|
DBGC ( virtnet, "VIRTIO-NET %p mac=%s\n", virtnet,
|
489
|
488
|
eth_ntoa ( netdev->hw_addr ) );
|
490
|
489
|
}
|
|
490
|
+ if ( features & ( 1ULL << VIRTIO_NET_F_MTU ) ) {
|
|
491
|
+ vp_get ( ioaddr, offsetof ( struct virtio_net_config, mtu ),
|
|
492
|
+ &mtu, sizeof ( mtu ) );
|
|
493
|
+ DBGC ( virtnet, "VIRTIO-NET %p mtu=%d\n", virtnet, mtu );
|
|
494
|
+ netdev->max_pkt_len = ( mtu + ETH_HLEN );
|
|
495
|
+ }
|
491
|
496
|
|
492
|
497
|
/* Register network device */
|
493
|
498
|
if ( ( rc = register_netdev ( netdev ) ) != 0 )
|
|
@@ -517,6 +522,7 @@ static int virtnet_probe_modern ( struct pci_device *pci, int *found_dev ) {
|
517
|
522
|
struct net_device *netdev;
|
518
|
523
|
struct virtnet_nic *virtnet;
|
519
|
524
|
u64 features;
|
|
525
|
+ u16 mtu;
|
520
|
526
|
int rc, common, isr, notify, config, device;
|
521
|
527
|
|
522
|
528
|
common = virtio_pci_find_capability ( pci, VIRTIO_PCI_CAP_COMMON_CFG );
|
|
@@ -583,7 +589,7 @@ static int virtnet_probe_modern ( struct pci_device *pci, int *found_dev ) {
|
583
|
589
|
vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_ACKNOWLEDGE );
|
584
|
590
|
vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_DRIVER );
|
585
|
591
|
|
586
|
|
- /* Load MAC address */
|
|
592
|
+ /* Load MAC address and MTU */
|
587
|
593
|
if ( device ) {
|
588
|
594
|
features = vpm_get_features ( &virtnet->vdev );
|
589
|
595
|
if ( features & ( 1ULL << VIRTIO_NET_F_MAC ) ) {
|
|
@@ -593,6 +599,14 @@ static int virtnet_probe_modern ( struct pci_device *pci, int *found_dev ) {
|
593
|
599
|
DBGC ( virtnet, "VIRTIO-NET %p mac=%s\n", virtnet,
|
594
|
600
|
eth_ntoa ( netdev->hw_addr ) );
|
595
|
601
|
}
|
|
602
|
+ if ( features & ( 1ULL << VIRTIO_NET_F_MTU ) ) {
|
|
603
|
+ vpm_get ( &virtnet->vdev,
|
|
604
|
+ offsetof ( struct virtio_net_config, mtu ),
|
|
605
|
+ &mtu, sizeof ( mtu ) );
|
|
606
|
+ DBGC ( virtnet, "VIRTIO-NET %p mtu=%d\n", virtnet,
|
|
607
|
+ mtu );
|
|
608
|
+ netdev->max_pkt_len = ( mtu + ETH_HLEN );
|
|
609
|
+ }
|
596
|
610
|
}
|
597
|
611
|
|
598
|
612
|
/* We need a valid MAC address */
|