|  | @@ -16,7 +16,20 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
		
	
		
			
			| 16 | 16 |  #define NETFRONT_NUM_TX_DESC 16
 | 
		
	
		
			
			| 17 | 17 |  
 | 
		
	
		
			
			| 18 | 18 |  /** Number of receive ring entries */
 | 
		
	
		
			
			| 19 |  | -#define NETFRONT_NUM_RX_DESC 8
 | 
		
	
		
			
			|  | 19 | +#define NETFRONT_NUM_RX_DESC 32
 | 
		
	
		
			
			|  | 20 | +
 | 
		
	
		
			
			|  | 21 | +/** Receive ring fill level
 | 
		
	
		
			
			|  | 22 | + *
 | 
		
	
		
			
			|  | 23 | + * The xen-netback driver from kernels 3.18 to 4.2 inclusive have a
 | 
		
	
		
			
			|  | 24 | + * bug (CA-163395) which prevents packet reception if fewer than 18
 | 
		
	
		
			
			|  | 25 | + * receive descriptors are available.  This was fixed in upstream
 | 
		
	
		
			
			|  | 26 | + * kernel commit d5d4852 ("xen-netback: require fewer guest Rx slots
 | 
		
	
		
			
			|  | 27 | + * when not using GSO").
 | 
		
	
		
			
			|  | 28 | + *
 | 
		
	
		
			
			|  | 29 | + * We provide 18 receive descriptors to avoid unpleasant silent
 | 
		
	
		
			
			|  | 30 | + * failures on these kernel versions.
 | 
		
	
		
			
			|  | 31 | + */
 | 
		
	
		
			
			|  | 32 | +#define NETFRONT_RX_FILL 18
 | 
		
	
		
			
			| 20 | 33 |  
 | 
		
	
		
			
			| 21 | 34 |  /** Grant reference indices */
 | 
		
	
		
			
			| 22 | 35 |  enum netfront_ref_index {
 | 
		
	
	
		
			
			|  | @@ -88,6 +101,21 @@ netfront_init_ring ( struct netfront_ring *ring, const char *ref_key,
 | 
		
	
		
			
			| 88 | 101 |  	ring->ids = ids;
 | 
		
	
		
			
			| 89 | 102 |  }
 | 
		
	
		
			
			| 90 | 103 |  
 | 
		
	
		
			
			|  | 104 | +/**
 | 
		
	
		
			
			|  | 105 | + * Calculate descriptor ring fill level
 | 
		
	
		
			
			|  | 106 | + *
 | 
		
	
		
			
			|  | 107 | + * @v ring		Descriptor ring
 | 
		
	
		
			
			|  | 108 | + * @v fill		Fill level
 | 
		
	
		
			
			|  | 109 | + */
 | 
		
	
		
			
			|  | 110 | +static inline __attribute__ (( always_inline )) unsigned int
 | 
		
	
		
			
			|  | 111 | +netfront_ring_fill ( struct netfront_ring *ring ) {
 | 
		
	
		
			
			|  | 112 | +	unsigned int fill_level;
 | 
		
	
		
			
			|  | 113 | +
 | 
		
	
		
			
			|  | 114 | +	fill_level = ( ring->id_prod - ring->id_cons );
 | 
		
	
		
			
			|  | 115 | +	assert ( fill_level <= ring->count );
 | 
		
	
		
			
			|  | 116 | +	return fill_level;
 | 
		
	
		
			
			|  | 117 | +}
 | 
		
	
		
			
			|  | 118 | +
 | 
		
	
		
			
			| 91 | 119 |  /**
 | 
		
	
		
			
			| 92 | 120 |   * Check whether or not descriptor ring is full
 | 
		
	
		
			
			| 93 | 121 |   *
 | 
		
	
	
		
			
			|  | @@ -96,11 +124,8 @@ netfront_init_ring ( struct netfront_ring *ring, const char *ref_key,
 | 
		
	
		
			
			| 96 | 124 |   */
 | 
		
	
		
			
			| 97 | 125 |  static inline __attribute__ (( always_inline )) int
 | 
		
	
		
			
			| 98 | 126 |  netfront_ring_is_full ( struct netfront_ring *ring ) {
 | 
		
	
		
			
			| 99 |  | -	unsigned int fill_level;
 | 
		
	
		
			
			| 100 | 127 |  
 | 
		
	
		
			
			| 101 |  | -	fill_level = ( ring->id_prod - ring->id_cons );
 | 
		
	
		
			
			| 102 |  | -	assert ( fill_level <= ring->count );
 | 
		
	
		
			
			| 103 |  | -	return ( fill_level >= ring->count );
 | 
		
	
		
			
			|  | 128 | +	return ( netfront_ring_fill ( ring ) >= ring->count );
 | 
		
	
		
			
			| 104 | 129 |  }
 | 
		
	
		
			
			| 105 | 130 |  
 | 
		
	
		
			
			| 106 | 131 |  /**
 | 
		
	
	
		
			
			|  | @@ -112,7 +137,7 @@ netfront_ring_is_full ( struct netfront_ring *ring ) {
 | 
		
	
		
			
			| 112 | 137 |  static inline __attribute__ (( always_inline )) int
 | 
		
	
		
			
			| 113 | 138 |  netfront_ring_is_empty ( struct netfront_ring *ring ) {
 | 
		
	
		
			
			| 114 | 139 |  
 | 
		
	
		
			
			| 115 |  | -	return ( ring->id_prod == ring->id_cons );
 | 
		
	
		
			
			|  | 140 | +	return ( netfront_ring_fill ( ring ) == 0 );
 | 
		
	
		
			
			| 116 | 141 |  }
 | 
		
	
		
			
			| 117 | 142 |  
 | 
		
	
		
			
			| 118 | 143 |  /** A netfront NIC */
 |