| 
				
			 | 
			
			
				
				@@ -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 */ 
			 |