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