|  | @@ -832,6 +832,62 @@ static void intelxl_close_admin ( struct intelxl_nic *intelxl ) {
 | 
		
	
		
			
			| 832 | 832 |   ******************************************************************************
 | 
		
	
		
			
			| 833 | 833 |   */
 | 
		
	
		
			
			| 834 | 834 |  
 | 
		
	
		
			
			|  | 835 | +/**
 | 
		
	
		
			
			|  | 836 | + * Allocate descriptor ring
 | 
		
	
		
			
			|  | 837 | + *
 | 
		
	
		
			
			|  | 838 | + * @v intelxl		Intel device
 | 
		
	
		
			
			|  | 839 | + * @v ring		Descriptor ring
 | 
		
	
		
			
			|  | 840 | + * @ret rc		Return status code
 | 
		
	
		
			
			|  | 841 | + */
 | 
		
	
		
			
			|  | 842 | +static int intelxl_alloc_ring ( struct intelxl_nic *intelxl,
 | 
		
	
		
			
			|  | 843 | +				struct intelxl_ring *ring ) {
 | 
		
	
		
			
			|  | 844 | +	physaddr_t address;
 | 
		
	
		
			
			|  | 845 | +	int rc;
 | 
		
	
		
			
			|  | 846 | +
 | 
		
	
		
			
			|  | 847 | +	/* Allocate descriptor ring */
 | 
		
	
		
			
			|  | 848 | +	ring->desc.raw = malloc_dma ( ring->len, INTELXL_ALIGN );
 | 
		
	
		
			
			|  | 849 | +	if ( ! ring->desc.raw ) {
 | 
		
	
		
			
			|  | 850 | +		rc = -ENOMEM;
 | 
		
	
		
			
			|  | 851 | +		goto err_alloc;
 | 
		
	
		
			
			|  | 852 | +	}
 | 
		
	
		
			
			|  | 853 | +	address = virt_to_bus ( ring->desc.raw );
 | 
		
	
		
			
			|  | 854 | +
 | 
		
	
		
			
			|  | 855 | +	/* Initialise descriptor ring */
 | 
		
	
		
			
			|  | 856 | +	memset ( ring->desc.raw, 0, ring->len );
 | 
		
	
		
			
			|  | 857 | +
 | 
		
	
		
			
			|  | 858 | +	/* Reset tail pointer */
 | 
		
	
		
			
			|  | 859 | +	writel ( 0, ( intelxl->regs + ring->tail ) );
 | 
		
	
		
			
			|  | 860 | +
 | 
		
	
		
			
			|  | 861 | +	/* Reset counters */
 | 
		
	
		
			
			|  | 862 | +	ring->prod = 0;
 | 
		
	
		
			
			|  | 863 | +	ring->cons = 0;
 | 
		
	
		
			
			|  | 864 | +
 | 
		
	
		
			
			|  | 865 | +	DBGC ( intelxl, "INTELXL %p ring %06x is at [%08llx,%08llx)\n",
 | 
		
	
		
			
			|  | 866 | +	       intelxl, ( ring->reg + ring->tail ),
 | 
		
	
		
			
			|  | 867 | +	       ( ( unsigned long long ) address ),
 | 
		
	
		
			
			|  | 868 | +	       ( ( unsigned long long ) address + ring->len ) );
 | 
		
	
		
			
			|  | 869 | +
 | 
		
	
		
			
			|  | 870 | +	return 0;
 | 
		
	
		
			
			|  | 871 | +
 | 
		
	
		
			
			|  | 872 | +	free_dma ( ring->desc.raw, ring->len );
 | 
		
	
		
			
			|  | 873 | + err_alloc:
 | 
		
	
		
			
			|  | 874 | +	return rc;
 | 
		
	
		
			
			|  | 875 | +}
 | 
		
	
		
			
			|  | 876 | +
 | 
		
	
		
			
			|  | 877 | +/**
 | 
		
	
		
			
			|  | 878 | + * Free descriptor ring
 | 
		
	
		
			
			|  | 879 | + *
 | 
		
	
		
			
			|  | 880 | + * @v intelxl		Intel device
 | 
		
	
		
			
			|  | 881 | + * @v ring		Descriptor ring
 | 
		
	
		
			
			|  | 882 | + */
 | 
		
	
		
			
			|  | 883 | +static void intelxl_free_ring ( struct intelxl_nic *intelxl __unused,
 | 
		
	
		
			
			|  | 884 | +				struct intelxl_ring *ring ) {
 | 
		
	
		
			
			|  | 885 | +
 | 
		
	
		
			
			|  | 886 | +	/* Free descriptor ring */
 | 
		
	
		
			
			|  | 887 | +	free_dma ( ring->desc.raw, ring->len );
 | 
		
	
		
			
			|  | 888 | +	ring->desc.raw = NULL;
 | 
		
	
		
			
			|  | 889 | +}
 | 
		
	
		
			
			|  | 890 | +
 | 
		
	
		
			
			| 835 | 891 |  /**
 | 
		
	
		
			
			| 836 | 892 |   * Dump queue context (for debugging)
 | 
		
	
		
			
			| 837 | 893 |   *
 | 
		
	
	
		
			
			|  | @@ -1100,17 +1156,8 @@ static int intelxl_create_ring ( struct intelxl_nic *intelxl,
 | 
		
	
		
			
			| 1100 | 1156 |  	int rc;
 | 
		
	
		
			
			| 1101 | 1157 |  
 | 
		
	
		
			
			| 1102 | 1158 |  	/* Allocate descriptor ring */
 | 
		
	
		
			
			| 1103 |  | -	ring->desc.raw = malloc_dma ( ring->len, INTELXL_ALIGN );
 | 
		
	
		
			
			| 1104 |  | -	if ( ! ring->desc.raw ) {
 | 
		
	
		
			
			| 1105 |  | -		rc = -ENOMEM;
 | 
		
	
		
			
			|  | 1159 | +	if ( ( rc = intelxl_alloc_ring ( intelxl, ring ) ) != 0 )
 | 
		
	
		
			
			| 1106 | 1160 |  		goto err_alloc;
 | 
		
	
		
			
			| 1107 |  | -	}
 | 
		
	
		
			
			| 1108 |  | -
 | 
		
	
		
			
			| 1109 |  | -	/* Initialise descriptor ring */
 | 
		
	
		
			
			| 1110 |  | -	memset ( ring->desc.raw, 0, ring->len );
 | 
		
	
		
			
			| 1111 |  | -
 | 
		
	
		
			
			| 1112 |  | -	/* Reset tail pointer */
 | 
		
	
		
			
			| 1113 |  | -	writel ( 0, ( intelxl->regs + ring->tail ) );
 | 
		
	
		
			
			| 1114 | 1161 |  
 | 
		
	
		
			
			| 1115 | 1162 |  	/* Program queue context */
 | 
		
	
		
			
			| 1116 | 1163 |  	address = virt_to_bus ( ring->desc.raw );
 | 
		
	
	
		
			
			|  | @@ -1121,21 +1168,12 @@ static int intelxl_create_ring ( struct intelxl_nic *intelxl,
 | 
		
	
		
			
			| 1121 | 1168 |  	if ( ( rc = intelxl_enable_ring ( intelxl, ring ) ) != 0 )
 | 
		
	
		
			
			| 1122 | 1169 |  		goto err_enable;
 | 
		
	
		
			
			| 1123 | 1170 |  
 | 
		
	
		
			
			| 1124 |  | -	/* Reset counters */
 | 
		
	
		
			
			| 1125 |  | -	ring->prod = 0;
 | 
		
	
		
			
			| 1126 |  | -	ring->cons = 0;
 | 
		
	
		
			
			| 1127 |  | -
 | 
		
	
		
			
			| 1128 |  | -	DBGC ( intelxl, "INTELXL %p ring %06x is at [%08llx,%08llx)\n",
 | 
		
	
		
			
			| 1129 |  | -	       intelxl, ( ring->reg + ring->tail ),
 | 
		
	
		
			
			| 1130 |  | -	       ( ( unsigned long long ) address ),
 | 
		
	
		
			
			| 1131 |  | -	       ( ( unsigned long long ) address + ring->len ) );
 | 
		
	
		
			
			| 1132 |  | -
 | 
		
	
		
			
			| 1133 | 1171 |  	return 0;
 | 
		
	
		
			
			| 1134 | 1172 |  
 | 
		
	
		
			
			| 1135 | 1173 |  	intelxl_disable_ring ( intelxl, ring );
 | 
		
	
		
			
			| 1136 | 1174 |   err_enable:
 | 
		
	
		
			
			| 1137 | 1175 |   err_context:
 | 
		
	
		
			
			| 1138 |  | -	free_dma ( ring->desc.raw, ring->len );
 | 
		
	
		
			
			|  | 1176 | +	intelxl_free_ring ( intelxl, ring );
 | 
		
	
		
			
			| 1139 | 1177 |   err_alloc:
 | 
		
	
		
			
			| 1140 | 1178 |  	return rc;
 | 
		
	
		
			
			| 1141 | 1179 |  }
 | 
		
	
	
		
			
			|  | @@ -1157,8 +1195,7 @@ static void intelxl_destroy_ring ( struct intelxl_nic *intelxl,
 | 
		
	
		
			
			| 1157 | 1195 |  	}
 | 
		
	
		
			
			| 1158 | 1196 |  
 | 
		
	
		
			
			| 1159 | 1197 |  	/* Free descriptor ring */
 | 
		
	
		
			
			| 1160 |  | -	free_dma ( ring->desc.raw, ring->len );
 | 
		
	
		
			
			| 1161 |  | -	ring->desc.raw = NULL;
 | 
		
	
		
			
			|  | 1198 | +	intelxl_free_ring ( intelxl, ring );
 | 
		
	
		
			
			| 1162 | 1199 |  }
 | 
		
	
		
			
			| 1163 | 1200 |  
 | 
		
	
		
			
			| 1164 | 1201 |  /**
 | 
		
	
	
		
			
			|  | @@ -1211,6 +1248,22 @@ static void intelxl_refill_rx ( struct intelxl_nic *intelxl ) {
 | 
		
	
		
			
			| 1211 | 1248 |  	}
 | 
		
	
		
			
			| 1212 | 1249 |  }
 | 
		
	
		
			
			| 1213 | 1250 |  
 | 
		
	
		
			
			|  | 1251 | +/**
 | 
		
	
		
			
			|  | 1252 | + * Discard unused receive I/O buffers
 | 
		
	
		
			
			|  | 1253 | + *
 | 
		
	
		
			
			|  | 1254 | + * @v intelxl		Intel device
 | 
		
	
		
			
			|  | 1255 | + */
 | 
		
	
		
			
			|  | 1256 | +static void intelxl_empty_rx ( struct intelxl_nic *intelxl ) {
 | 
		
	
		
			
			|  | 1257 | +	unsigned int i;
 | 
		
	
		
			
			|  | 1258 | +
 | 
		
	
		
			
			|  | 1259 | +	/* Discard any unused receive buffers */
 | 
		
	
		
			
			|  | 1260 | +	for ( i = 0 ; i < INTELXL_RX_NUM_DESC ; i++ ) {
 | 
		
	
		
			
			|  | 1261 | +		if ( intelxl->rx_iobuf[i] )
 | 
		
	
		
			
			|  | 1262 | +			free_iob ( intelxl->rx_iobuf[i] );
 | 
		
	
		
			
			|  | 1263 | +		intelxl->rx_iobuf[i] = NULL;
 | 
		
	
		
			
			|  | 1264 | +	}
 | 
		
	
		
			
			|  | 1265 | +}
 | 
		
	
		
			
			|  | 1266 | +
 | 
		
	
		
			
			| 1214 | 1267 |  /******************************************************************************
 | 
		
	
		
			
			| 1215 | 1268 |   *
 | 
		
	
		
			
			| 1216 | 1269 |   * Network device interface
 | 
		
	
	
		
			
			|  | @@ -1297,7 +1350,6 @@ static int intelxl_open ( struct net_device *netdev ) {
 | 
		
	
		
			
			| 1297 | 1350 |  static void intelxl_close ( struct net_device *netdev ) {
 | 
		
	
		
			
			| 1298 | 1351 |  	struct intelxl_nic *intelxl = netdev->priv;
 | 
		
	
		
			
			| 1299 | 1352 |  	unsigned int queue;
 | 
		
	
		
			
			| 1300 |  | -	unsigned int i;
 | 
		
	
		
			
			| 1301 | 1353 |  
 | 
		
	
		
			
			| 1302 | 1354 |  	/* Dump contexts (for debugging) */
 | 
		
	
		
			
			| 1303 | 1355 |  	intelxl_context_dump ( intelxl, INTELXL_PFCM_LANCTXCTL_TYPE_TX,
 | 
		
	
	
		
			
			|  | @@ -1319,11 +1371,7 @@ static void intelxl_close ( struct net_device *netdev ) {
 | 
		
	
		
			
			| 1319 | 1371 |  	intelxl_destroy_ring ( intelxl, &intelxl->rx );
 | 
		
	
		
			
			| 1320 | 1372 |  
 | 
		
	
		
			
			| 1321 | 1373 |  	/* Discard any unused receive buffers */
 | 
		
	
		
			
			| 1322 |  | -	for ( i = 0 ; i < INTELXL_RX_NUM_DESC ; i++ ) {
 | 
		
	
		
			
			| 1323 |  | -		if ( intelxl->rx_iobuf[i] )
 | 
		
	
		
			
			| 1324 |  | -			free_iob ( intelxl->rx_iobuf[i] );
 | 
		
	
		
			
			| 1325 |  | -		intelxl->rx_iobuf[i] = NULL;
 | 
		
	
		
			
			| 1326 |  | -	}
 | 
		
	
		
			
			|  | 1374 | +	intelxl_empty_rx ( intelxl );
 | 
		
	
		
			
			| 1327 | 1375 |  }
 | 
		
	
		
			
			| 1328 | 1376 |  
 | 
		
	
		
			
			| 1329 | 1377 |  /**
 |