|  | @@ -45,19 +45,36 @@ extern struct ib_address_vector hack_ipoib_bcast_av;
 | 
		
	
		
			
			| 45 | 45 |  #define IPOIB_MTU 2048
 | 
		
	
		
			
			| 46 | 46 |  
 | 
		
	
		
			
			| 47 | 47 |  /** Number of IPoIB send work queue entries */
 | 
		
	
		
			
			| 48 |  | -#define IPOIB_NUM_SEND_WQES 8
 | 
		
	
		
			
			|  | 48 | +#define IPOIB_DATA_NUM_SEND_WQES 4
 | 
		
	
		
			
			| 49 | 49 |  
 | 
		
	
		
			
			| 50 | 50 |  /** Number of IPoIB receive work queue entries */
 | 
		
	
		
			
			| 51 |  | -#define IPOIB_NUM_RECV_WQES 8
 | 
		
	
		
			
			|  | 51 | +#define IPOIB_DATA_NUM_RECV_WQES 8
 | 
		
	
		
			
			| 52 | 52 |  
 | 
		
	
		
			
			| 53 | 53 |  /** Number of IPoIB completion entries */
 | 
		
	
		
			
			| 54 |  | -#define IPOIB_NUM_CQES 8
 | 
		
	
		
			
			|  | 54 | +#define IPOIB_DATA_NUM_CQES 8
 | 
		
	
		
			
			| 55 | 55 |  
 | 
		
	
		
			
			| 56 |  | -struct ipoib_device {
 | 
		
	
		
			
			| 57 |  | -	struct ib_device *ibdev;
 | 
		
	
		
			
			|  | 56 | +/** An IPoIB queue set */
 | 
		
	
		
			
			|  | 57 | +struct ipoib_queue_set {
 | 
		
	
		
			
			|  | 58 | +	/** Completion queue */
 | 
		
	
		
			
			| 58 | 59 |  	struct ib_completion_queue *cq;
 | 
		
	
		
			
			|  | 60 | +	/** Queue pair */
 | 
		
	
		
			
			| 59 | 61 |  	struct ib_queue_pair *qp;
 | 
		
	
		
			
			| 60 |  | -	unsigned int rx_fill;
 | 
		
	
		
			
			|  | 62 | +	/** Receive work queue fill level */
 | 
		
	
		
			
			|  | 63 | +	unsigned int recv_fill;
 | 
		
	
		
			
			|  | 64 | +	/** Receive work queue maximum fill level */
 | 
		
	
		
			
			|  | 65 | +	unsigned int recv_max_fill;
 | 
		
	
		
			
			|  | 66 | +};
 | 
		
	
		
			
			|  | 67 | +
 | 
		
	
		
			
			|  | 68 | +/** An IPoIB device */
 | 
		
	
		
			
			|  | 69 | +struct ipoib_device {
 | 
		
	
		
			
			|  | 70 | +	/** Network device */
 | 
		
	
		
			
			|  | 71 | +	struct net_device *netdev;
 | 
		
	
		
			
			|  | 72 | +	/** Underlying Infiniband device */
 | 
		
	
		
			
			|  | 73 | +	struct ib_device *ibdev;
 | 
		
	
		
			
			|  | 74 | +	/** Data queue set */
 | 
		
	
		
			
			|  | 75 | +	struct ipoib_queue_set data;
 | 
		
	
		
			
			|  | 76 | +	/** Data queue set */
 | 
		
	
		
			
			|  | 77 | +	struct ipoib_queue_set meta;
 | 
		
	
		
			
			| 61 | 78 |  };
 | 
		
	
		
			
			| 62 | 79 |  
 | 
		
	
		
			
			| 63 | 80 |  /****************************************************************************
 | 
		
	
	
		
			
			|  | @@ -164,6 +181,69 @@ struct ll_protocol ipoib_protocol __ll_protocol = {
 | 
		
	
		
			
			| 164 | 181 |   ****************************************************************************
 | 
		
	
		
			
			| 165 | 182 |   */
 | 
		
	
		
			
			| 166 | 183 |  
 | 
		
	
		
			
			|  | 184 | +/**
 | 
		
	
		
			
			|  | 185 | + * Destroy queue set
 | 
		
	
		
			
			|  | 186 | + *
 | 
		
	
		
			
			|  | 187 | + * @v ipoib		IPoIB device
 | 
		
	
		
			
			|  | 188 | + * @v qset		Queue set
 | 
		
	
		
			
			|  | 189 | + */
 | 
		
	
		
			
			|  | 190 | +static void ipoib_destroy_qset ( struct ipoib_device *ipoib,
 | 
		
	
		
			
			|  | 191 | +				 struct ipoib_queue_set *qset ) {
 | 
		
	
		
			
			|  | 192 | +	struct ib_device *ibdev = ipoib->ibdev;
 | 
		
	
		
			
			|  | 193 | +
 | 
		
	
		
			
			|  | 194 | +	if ( qset->qp )
 | 
		
	
		
			
			|  | 195 | +		ib_destroy_qp ( ibdev, qset->qp );
 | 
		
	
		
			
			|  | 196 | +	if ( qset->cq )
 | 
		
	
		
			
			|  | 197 | +		ib_destroy_cq ( ibdev, qset->cq );
 | 
		
	
		
			
			|  | 198 | +	memset ( qset, 0, sizeof ( *qset ) );
 | 
		
	
		
			
			|  | 199 | +}
 | 
		
	
		
			
			|  | 200 | +
 | 
		
	
		
			
			|  | 201 | +/**
 | 
		
	
		
			
			|  | 202 | + * Create queue set
 | 
		
	
		
			
			|  | 203 | + *
 | 
		
	
		
			
			|  | 204 | + * @v ipoib		IPoIB device
 | 
		
	
		
			
			|  | 205 | + * @v qset		Queue set
 | 
		
	
		
			
			|  | 206 | + * @ret rc		Return status code
 | 
		
	
		
			
			|  | 207 | + */
 | 
		
	
		
			
			|  | 208 | +static int ipoib_create_qset ( struct ipoib_device *ipoib,
 | 
		
	
		
			
			|  | 209 | +			       struct ipoib_queue_set *qset,
 | 
		
	
		
			
			|  | 210 | +			       unsigned int num_cqes,
 | 
		
	
		
			
			|  | 211 | +			       unsigned int num_send_wqes,
 | 
		
	
		
			
			|  | 212 | +			       unsigned int num_recv_wqes,
 | 
		
	
		
			
			|  | 213 | +			       unsigned long qkey ) {
 | 
		
	
		
			
			|  | 214 | +	struct ib_device *ibdev = ipoib->ibdev;
 | 
		
	
		
			
			|  | 215 | +	int rc;
 | 
		
	
		
			
			|  | 216 | +
 | 
		
	
		
			
			|  | 217 | +	/* Store queue parameters */
 | 
		
	
		
			
			|  | 218 | +	qset->recv_max_fill = num_recv_wqes;
 | 
		
	
		
			
			|  | 219 | +
 | 
		
	
		
			
			|  | 220 | +	/* Allocate completion queue */
 | 
		
	
		
			
			|  | 221 | +	qset->cq = ib_create_cq ( ibdev, num_cqes );
 | 
		
	
		
			
			|  | 222 | +	if ( ! qset->cq ) {
 | 
		
	
		
			
			|  | 223 | +		DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
 | 
		
	
		
			
			|  | 224 | +		       ipoib );
 | 
		
	
		
			
			|  | 225 | +		rc = -ENOMEM;
 | 
		
	
		
			
			|  | 226 | +		goto err;
 | 
		
	
		
			
			|  | 227 | +	}
 | 
		
	
		
			
			|  | 228 | +
 | 
		
	
		
			
			|  | 229 | +	/* Allocate queue pair */
 | 
		
	
		
			
			|  | 230 | +	qset->qp = ib_create_qp ( ibdev, num_send_wqes, qset->cq,
 | 
		
	
		
			
			|  | 231 | +				  num_recv_wqes, qset->cq, qkey );
 | 
		
	
		
			
			|  | 232 | +	if ( ! qset->qp ) {
 | 
		
	
		
			
			|  | 233 | +		DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n",
 | 
		
	
		
			
			|  | 234 | +		       ipoib );
 | 
		
	
		
			
			|  | 235 | +		rc = -ENOMEM;
 | 
		
	
		
			
			|  | 236 | +		goto err;
 | 
		
	
		
			
			|  | 237 | +	}
 | 
		
	
		
			
			|  | 238 | +	qset->qp->owner_priv = ipoib->netdev;
 | 
		
	
		
			
			|  | 239 | +
 | 
		
	
		
			
			|  | 240 | +	return 0;
 | 
		
	
		
			
			|  | 241 | +
 | 
		
	
		
			
			|  | 242 | + err:
 | 
		
	
		
			
			|  | 243 | +	ipoib_destroy_qset ( ipoib, qset );
 | 
		
	
		
			
			|  | 244 | +	return rc;
 | 
		
	
		
			
			|  | 245 | +}
 | 
		
	
		
			
			|  | 246 | +
 | 
		
	
		
			
			| 167 | 247 |  /**
 | 
		
	
		
			
			| 168 | 248 |   * Transmit packet via IPoIB network device
 | 
		
	
		
			
			| 169 | 249 |   *
 | 
		
	
	
		
			
			|  | @@ -183,7 +263,7 @@ static int ipoib_transmit ( struct net_device *netdev,
 | 
		
	
		
			
			| 183 | 263 |  	}
 | 
		
	
		
			
			| 184 | 264 |  
 | 
		
	
		
			
			| 185 | 265 |  	iob_pull ( iobuf, ( sizeof ( *ipoib_pshdr ) ) );
 | 
		
	
		
			
			| 186 |  | -	return ib_post_send ( ibdev, ipoib->qp,
 | 
		
	
		
			
			|  | 266 | +	return ib_post_send ( ibdev, ipoib->data.qp,
 | 
		
	
		
			
			| 187 | 267 |  			      &hack_ipoib_bcast_av, iobuf );
 | 
		
	
		
			
			| 188 | 268 |  }
 | 
		
	
		
			
			| 189 | 269 |  
 | 
		
	
	
		
			
			|  | @@ -195,10 +275,10 @@ static int ipoib_transmit ( struct net_device *netdev,
 | 
		
	
		
			
			| 195 | 275 |   * @v completion	Completion
 | 
		
	
		
			
			| 196 | 276 |   * @v iobuf		I/O buffer
 | 
		
	
		
			
			| 197 | 277 |   */
 | 
		
	
		
			
			| 198 |  | -static void ipoib_complete_send ( struct ib_device *ibdev __unused,
 | 
		
	
		
			
			| 199 |  | -				  struct ib_queue_pair *qp,
 | 
		
	
		
			
			| 200 |  | -				  struct ib_completion *completion,
 | 
		
	
		
			
			| 201 |  | -				  struct io_buffer *iobuf ) {
 | 
		
	
		
			
			|  | 278 | +static void ipoib_data_complete_send ( struct ib_device *ibdev __unused,
 | 
		
	
		
			
			|  | 279 | +				       struct ib_queue_pair *qp,
 | 
		
	
		
			
			|  | 280 | +				       struct ib_completion *completion,
 | 
		
	
		
			
			|  | 281 | +				       struct io_buffer *iobuf ) {
 | 
		
	
		
			
			| 202 | 282 |  	struct net_device *netdev = qp->owner_priv;
 | 
		
	
		
			
			| 203 | 283 |  
 | 
		
	
		
			
			| 204 | 284 |  	netdev_tx_complete_err ( netdev, iobuf,
 | 
		
	
	
		
			
			|  | @@ -213,10 +293,10 @@ static void ipoib_complete_send ( struct ib_device *ibdev __unused,
 | 
		
	
		
			
			| 213 | 293 |   * @v completion	Completion
 | 
		
	
		
			
			| 214 | 294 |   * @v iobuf		I/O buffer
 | 
		
	
		
			
			| 215 | 295 |   */
 | 
		
	
		
			
			| 216 |  | -static void ipoib_complete_recv ( struct ib_device *ibdev __unused,
 | 
		
	
		
			
			| 217 |  | -				  struct ib_queue_pair *qp,
 | 
		
	
		
			
			| 218 |  | -				  struct ib_completion *completion,
 | 
		
	
		
			
			| 219 |  | -				  struct io_buffer *iobuf ) {
 | 
		
	
		
			
			|  | 296 | +static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
 | 
		
	
		
			
			|  | 297 | +				       struct ib_queue_pair *qp,
 | 
		
	
		
			
			|  | 298 | +				       struct ib_completion *completion,
 | 
		
	
		
			
			|  | 299 | +				       struct io_buffer *iobuf ) {
 | 
		
	
		
			
			| 220 | 300 |  	struct net_device *netdev = qp->owner_priv;
 | 
		
	
		
			
			| 221 | 301 |  	struct ipoib_device *ipoib = netdev->priv;
 | 
		
	
		
			
			| 222 | 302 |  	struct ib_global_route_header *grh = iobuf->data;
 | 
		
	
	
		
			
			|  | @@ -232,7 +312,7 @@ static void ipoib_complete_recv ( struct ib_device *ibdev __unused,
 | 
		
	
		
			
			| 232 | 312 |  		netdev_rx ( netdev, iobuf );
 | 
		
	
		
			
			| 233 | 313 |  	}
 | 
		
	
		
			
			| 234 | 314 |  
 | 
		
	
		
			
			| 235 |  | -	ipoib->rx_fill--;
 | 
		
	
		
			
			|  | 315 | +	ipoib->data.recv_fill--;
 | 
		
	
		
			
			| 236 | 316 |  }
 | 
		
	
		
			
			| 237 | 317 |  
 | 
		
	
		
			
			| 238 | 318 |  /**
 | 
		
	
	
		
			
			|  | @@ -240,21 +320,21 @@ static void ipoib_complete_recv ( struct ib_device *ibdev __unused,
 | 
		
	
		
			
			| 240 | 320 |   *
 | 
		
	
		
			
			| 241 | 321 |   * @v ipoib		IPoIB device
 | 
		
	
		
			
			| 242 | 322 |   */
 | 
		
	
		
			
			| 243 |  | -static void ipoib_refill_recv ( struct ipoib_device *ipoib ) {
 | 
		
	
		
			
			|  | 323 | +static void ipoib_refill_recv ( struct ipoib_device *ipoib,
 | 
		
	
		
			
			|  | 324 | +				struct ipoib_queue_set *qset ) {
 | 
		
	
		
			
			| 244 | 325 |  	struct ib_device *ibdev = ipoib->ibdev;
 | 
		
	
		
			
			| 245 | 326 |  	struct io_buffer *iobuf;
 | 
		
	
		
			
			| 246 | 327 |  	int rc;
 | 
		
	
		
			
			| 247 | 328 |  
 | 
		
	
		
			
			| 248 |  | -	while ( ipoib->rx_fill < IPOIB_NUM_RECV_WQES ) {
 | 
		
	
		
			
			|  | 329 | +	while ( qset->recv_fill < qset->recv_max_fill ) {
 | 
		
	
		
			
			| 249 | 330 |  		iobuf = alloc_iob ( IPOIB_MTU );
 | 
		
	
		
			
			| 250 | 331 |  		if ( ! iobuf )
 | 
		
	
		
			
			| 251 | 332 |  			break;
 | 
		
	
		
			
			| 252 |  | -		if ( ( rc = ib_post_recv ( ibdev, ipoib->qp,
 | 
		
	
		
			
			| 253 |  | -					   iobuf ) ) != 0 ) {
 | 
		
	
		
			
			|  | 333 | +		if ( ( rc = ib_post_recv ( ibdev, qset->qp, iobuf ) ) != 0 ) {
 | 
		
	
		
			
			| 254 | 334 |  			free_iob ( iobuf );
 | 
		
	
		
			
			| 255 | 335 |  			break;
 | 
		
	
		
			
			| 256 | 336 |  		}
 | 
		
	
		
			
			| 257 |  | -		ipoib->rx_fill++;
 | 
		
	
		
			
			|  | 337 | +		qset->recv_fill++;
 | 
		
	
		
			
			| 258 | 338 |  	}
 | 
		
	
		
			
			| 259 | 339 |  }
 | 
		
	
		
			
			| 260 | 340 |  
 | 
		
	
	
		
			
			|  | @@ -267,9 +347,9 @@ static void ipoib_poll ( struct net_device *netdev ) {
 | 
		
	
		
			
			| 267 | 347 |  	struct ipoib_device *ipoib = netdev->priv;
 | 
		
	
		
			
			| 268 | 348 |  	struct ib_device *ibdev = ipoib->ibdev;
 | 
		
	
		
			
			| 269 | 349 |  
 | 
		
	
		
			
			| 270 |  | -	ib_poll_cq ( ibdev, ipoib->cq, ipoib_complete_send,
 | 
		
	
		
			
			| 271 |  | -		     ipoib_complete_recv );
 | 
		
	
		
			
			| 272 |  | -	ipoib_refill_recv ( ipoib );
 | 
		
	
		
			
			|  | 350 | +	ib_poll_cq ( ibdev, ipoib->data.cq, ipoib_data_complete_send,
 | 
		
	
		
			
			|  | 351 | +		     ipoib_data_complete_recv );
 | 
		
	
		
			
			|  | 352 | +	ipoib_refill_recv ( ipoib, &ipoib->data );
 | 
		
	
		
			
			| 273 | 353 |  }
 | 
		
	
		
			
			| 274 | 354 |  
 | 
		
	
		
			
			| 275 | 355 |  /**
 | 
		
	
	
		
			
			|  | @@ -295,7 +375,7 @@ static int ipoib_open ( struct net_device *netdev ) {
 | 
		
	
		
			
			| 295 | 375 |  	int rc;
 | 
		
	
		
			
			| 296 | 376 |  
 | 
		
	
		
			
			| 297 | 377 |  	/* Attach to broadcast multicast GID */
 | 
		
	
		
			
			| 298 |  | -	if ( ( rc = ib_mcast_attach ( ibdev, ipoib->qp,
 | 
		
	
		
			
			|  | 378 | +	if ( ( rc = ib_mcast_attach ( ibdev, ipoib->data.qp,
 | 
		
	
		
			
			| 299 | 379 |  				      &ibdev->broadcast_gid ) ) != 0 ) {
 | 
		
	
		
			
			| 300 | 380 |  		DBG ( "Could not attach to broadcast GID: %s\n",
 | 
		
	
		
			
			| 301 | 381 |  		      strerror ( rc ) );
 | 
		
	
	
		
			
			|  | @@ -303,7 +383,7 @@ static int ipoib_open ( struct net_device *netdev ) {
 | 
		
	
		
			
			| 303 | 383 |  	}
 | 
		
	
		
			
			| 304 | 384 |  
 | 
		
	
		
			
			| 305 | 385 |  	/* Fill receive ring */
 | 
		
	
		
			
			| 306 |  | -	ipoib_refill_recv ( ipoib );
 | 
		
	
		
			
			|  | 386 | +	ipoib_refill_recv ( ipoib, &ipoib->data );
 | 
		
	
		
			
			| 307 | 387 |  
 | 
		
	
		
			
			| 308 | 388 |  	return 0;
 | 
		
	
		
			
			| 309 | 389 |  }
 | 
		
	
	
		
			
			|  | @@ -318,7 +398,7 @@ static void ipoib_close ( struct net_device *netdev ) {
 | 
		
	
		
			
			| 318 | 398 |  	struct ib_device *ibdev = ipoib->ibdev;
 | 
		
	
		
			
			| 319 | 399 |  
 | 
		
	
		
			
			| 320 | 400 |  	/* Detach from broadcast multicast GID */
 | 
		
	
		
			
			| 321 |  | -	ib_mcast_detach ( ibdev, ipoib->qp, &ipoib_broadcast.gid );
 | 
		
	
		
			
			|  | 401 | +	ib_mcast_detach ( ibdev, ipoib->data.qp, &ipoib_broadcast.gid );
 | 
		
	
		
			
			| 322 | 402 |  
 | 
		
	
		
			
			| 323 | 403 |  	/* FIXME: should probably flush the receive ring */
 | 
		
	
		
			
			| 324 | 404 |  }
 | 
		
	
	
		
			
			|  | @@ -353,32 +433,23 @@ int ipoib_probe ( struct ib_device *ibdev ) {
 | 
		
	
		
			
			| 353 | 433 |  	ib_set_ownerdata ( ibdev, netdev );
 | 
		
	
		
			
			| 354 | 434 |  	netdev->dev = ibdev->dev;
 | 
		
	
		
			
			| 355 | 435 |  	memset ( ipoib, 0, sizeof ( *ipoib ) );
 | 
		
	
		
			
			|  | 436 | +	ipoib->netdev = netdev;
 | 
		
	
		
			
			| 356 | 437 |  	ipoib->ibdev = ibdev;
 | 
		
	
		
			
			| 357 | 438 |  
 | 
		
	
		
			
			| 358 |  | -	/* Allocate completion queue */
 | 
		
	
		
			
			| 359 |  | -	ipoib->cq = ib_create_cq ( ibdev, IPOIB_NUM_CQES );
 | 
		
	
		
			
			| 360 |  | -	if ( ! ipoib->cq ) {
 | 
		
	
		
			
			| 361 |  | -		DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
 | 
		
	
		
			
			| 362 |  | -		       ipoib );
 | 
		
	
		
			
			| 363 |  | -		rc = -ENOMEM;
 | 
		
	
		
			
			| 364 |  | -		goto err_create_cq;
 | 
		
	
		
			
			| 365 |  | -	}
 | 
		
	
		
			
			| 366 |  | -
 | 
		
	
		
			
			| 367 |  | -	/* Allocate queue pair */
 | 
		
	
		
			
			| 368 |  | -	ipoib->qp = ib_create_qp ( ibdev, IPOIB_NUM_SEND_WQES,
 | 
		
	
		
			
			| 369 |  | -				   ipoib->cq, IPOIB_NUM_RECV_WQES,
 | 
		
	
		
			
			| 370 |  | -				   ipoib->cq, hack_ipoib_qkey );
 | 
		
	
		
			
			| 371 |  | -	if ( ! ipoib->qp ) {
 | 
		
	
		
			
			| 372 |  | -		DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n",
 | 
		
	
		
			
			| 373 |  | -		       ipoib );
 | 
		
	
		
			
			| 374 |  | -		rc = -ENOMEM;
 | 
		
	
		
			
			| 375 |  | -		goto err_create_qp;
 | 
		
	
		
			
			|  | 439 | +	/* Allocate data queue set */
 | 
		
	
		
			
			|  | 440 | +	if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->data,
 | 
		
	
		
			
			|  | 441 | +					IPOIB_DATA_NUM_CQES,
 | 
		
	
		
			
			|  | 442 | +					IPOIB_DATA_NUM_SEND_WQES,
 | 
		
	
		
			
			|  | 443 | +					IPOIB_DATA_NUM_RECV_WQES,
 | 
		
	
		
			
			|  | 444 | +					hack_ipoib_qkey ) ) != 0 ) {
 | 
		
	
		
			
			|  | 445 | +		DBGC ( ipoib, "IPoIB %p could not allocate data QP: %s\n",
 | 
		
	
		
			
			|  | 446 | +		       ipoib, strerror ( rc ) );
 | 
		
	
		
			
			|  | 447 | +		goto err_create_data_qset;
 | 
		
	
		
			
			| 376 | 448 |  	}
 | 
		
	
		
			
			| 377 |  | -	ipoib->qp->owner_priv = netdev;
 | 
		
	
		
			
			| 378 | 449 |  
 | 
		
	
		
			
			| 379 | 450 |  	/* Construct MAC address */
 | 
		
	
		
			
			| 380 | 451 |  	mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
 | 
		
	
		
			
			| 381 |  | -	mac->qpn = htonl ( ipoib->qp->qpn );
 | 
		
	
		
			
			|  | 452 | +	mac->qpn = htonl ( ipoib->data.qp->qpn );
 | 
		
	
		
			
			| 382 | 453 |  	memcpy ( &mac->gid, &ibdev->port_gid, sizeof ( mac->gid ) );
 | 
		
	
		
			
			| 383 | 454 |  
 | 
		
	
		
			
			| 384 | 455 |  	/* Register network device */
 | 
		
	
	
		
			
			|  | @@ -388,10 +459,8 @@ int ipoib_probe ( struct ib_device *ibdev ) {
 | 
		
	
		
			
			| 388 | 459 |  	return 0;
 | 
		
	
		
			
			| 389 | 460 |  
 | 
		
	
		
			
			| 390 | 461 |   err_register_netdev:
 | 
		
	
		
			
			| 391 |  | -	ib_destroy_qp ( ibdev, ipoib->qp );
 | 
		
	
		
			
			| 392 |  | - err_create_qp:
 | 
		
	
		
			
			| 393 |  | -	ib_destroy_cq ( ibdev, ipoib->cq );
 | 
		
	
		
			
			| 394 |  | - err_create_cq:
 | 
		
	
		
			
			|  | 462 | +	ipoib_destroy_qset ( ipoib, &ipoib->data );
 | 
		
	
		
			
			|  | 463 | + err_create_data_qset:
 | 
		
	
		
			
			| 395 | 464 |  	netdev_nullify ( netdev );
 | 
		
	
		
			
			| 396 | 465 |  	netdev_put ( netdev );
 | 
		
	
		
			
			| 397 | 466 |  	return rc;
 |