|  | @@ -16,9 +16,6 @@ Skeleton NIC driver for Etherboot
 | 
		
	
		
			
			| 16 | 16 |  #include <gpxe/netdevice.h>
 | 
		
	
		
			
			| 17 | 17 |  #include <gpxe/infiniband.h>
 | 
		
	
		
			
			| 18 | 18 |  
 | 
		
	
		
			
			| 19 |  | -struct mlx_nic {
 | 
		
	
		
			
			| 20 |  | -};
 | 
		
	
		
			
			| 21 |  | -
 | 
		
	
		
			
			| 22 | 19 |  /* to get some global routines like printf */
 | 
		
	
		
			
			| 23 | 20 |  #include "etherboot.h"
 | 
		
	
		
			
			| 24 | 21 |  /* to get the interface to the body of the program */
 | 
		
	
	
		
			
			|  | @@ -27,6 +24,16 @@ struct mlx_nic {
 | 
		
	
		
			
			| 27 | 24 |  #include "mt_version.c"
 | 
		
	
		
			
			| 28 | 25 |  #include "mt25218_imp.c"
 | 
		
	
		
			
			| 29 | 26 |  
 | 
		
	
		
			
			|  | 27 | +struct mlx_nic {
 | 
		
	
		
			
			|  | 28 | +	/** Queue pair handle */
 | 
		
	
		
			
			|  | 29 | +	udqp_t ipoib_qph;
 | 
		
	
		
			
			|  | 30 | +	/** Broadcast Address Vector */
 | 
		
	
		
			
			|  | 31 | +	ud_av_t bcast_av;
 | 
		
	
		
			
			|  | 32 | +	/** Send completion queue */
 | 
		
	
		
			
			|  | 33 | +	cq_t snd_cqh;
 | 
		
	
		
			
			|  | 34 | +	/** Receive completion queue */
 | 
		
	
		
			
			|  | 35 | +	cq_t rcv_cqh;
 | 
		
	
		
			
			|  | 36 | +};
 | 
		
	
		
			
			| 30 | 37 |  
 | 
		
	
		
			
			| 31 | 38 |  int prompt_key(int secs, unsigned char *ch_p)
 | 
		
	
		
			
			| 32 | 39 |  {
 | 
		
	
	
		
			
			|  | @@ -192,8 +199,28 @@ static uint8_t ib_broadcast[IB_ALEN] = { 0xff, };
 | 
		
	
		
			
			| 192 | 199 |   */
 | 
		
	
		
			
			| 193 | 200 |  static int mlx_transmit ( struct net_device *netdev,
 | 
		
	
		
			
			| 194 | 201 |  			  struct io_buffer *iobuf ) {
 | 
		
	
		
			
			| 195 |  | -	struct ibhdr *ibhdr = iobuf->data;
 | 
		
	
		
			
			|  | 202 | +	struct mlx_nic *mlx = netdev->priv;
 | 
		
	
		
			
			|  | 203 | +	ud_send_wqe_t snd_wqe;
 | 
		
	
		
			
			|  | 204 | +	int rc;
 | 
		
	
		
			
			|  | 205 | +
 | 
		
	
		
			
			|  | 206 | +	snd_wqe = alloc_send_wqe ( mlx->ipoib_qph );
 | 
		
	
		
			
			|  | 207 | +	if ( ! snd_wqe ) {
 | 
		
	
		
			
			|  | 208 | +		DBGC ( mlx, "MLX %p out of TX WQEs\n", mlx );
 | 
		
	
		
			
			|  | 209 | +		return -ENOBUFS;
 | 
		
	
		
			
			|  | 210 | +	}
 | 
		
	
		
			
			|  | 211 | +
 | 
		
	
		
			
			|  | 212 | +	prep_send_wqe_buf ( mlx->ipoib_qph, mlx->bcast_av, snd_wqe,
 | 
		
	
		
			
			|  | 213 | +			    iobuf->data, 0, iob_len ( iobuf ), 0 );
 | 
		
	
		
			
			|  | 214 | +	if ( ( rc = post_send_req ( mlx->ipoib_qph, snd_wqe, 1 ) ) != 0 ) {
 | 
		
	
		
			
			|  | 215 | +		DBGC ( mlx, "MLX %p could not post TX WQE %p: %s\n",
 | 
		
	
		
			
			|  | 216 | +		       mlx, snd_wqe, strerror ( rc ) );
 | 
		
	
		
			
			|  | 217 | +		free_wqe ( snd_wqe );
 | 
		
	
		
			
			|  | 218 | +		return rc;
 | 
		
	
		
			
			|  | 219 | +	}
 | 
		
	
		
			
			|  | 220 | +
 | 
		
	
		
			
			|  | 221 | +	return 0;
 | 
		
	
		
			
			| 196 | 222 |  
 | 
		
	
		
			
			|  | 223 | +#if 0
 | 
		
	
		
			
			| 197 | 224 |  	( void ) netdev;
 | 
		
	
		
			
			| 198 | 225 |  
 | 
		
	
		
			
			| 199 | 226 |  	iob_pull ( iobuf, sizeof ( *ibhdr ) );	
 | 
		
	
	
		
			
			|  | @@ -208,46 +235,47 @@ static int mlx_transmit ( struct net_device *netdev,
 | 
		
	
		
			
			| 208 | 235 |  					   ntohs ( ibhdr->proto ),
 | 
		
	
		
			
			| 209 | 236 |  					   iobuf->data, iob_len ( iobuf ) );
 | 
		
	
		
			
			| 210 | 237 |  	}
 | 
		
	
		
			
			|  | 238 | +#endif
 | 
		
	
		
			
			| 211 | 239 |  }
 | 
		
	
		
			
			| 212 | 240 |  
 | 
		
	
		
			
			| 213 | 241 |  /**
 | 
		
	
		
			
			| 214 | 242 |   * Handle TX completion
 | 
		
	
		
			
			| 215 | 243 |   *
 | 
		
	
		
			
			| 216 | 244 |   * @v netdev		Network device
 | 
		
	
		
			
			| 217 |  | - * @v cqe		Completion queue entry
 | 
		
	
		
			
			|  | 245 | + * @v ib_cqe		Completion queue entry
 | 
		
	
		
			
			| 218 | 246 |   */
 | 
		
	
		
			
			| 219 | 247 |  static void mlx_tx_complete ( struct net_device *netdev,
 | 
		
	
		
			
			| 220 |  | -			      struct ib_cqe_st *cqe ) {
 | 
		
	
		
			
			|  | 248 | +			      struct ib_cqe_st *ib_cqe ) {
 | 
		
	
		
			
			| 221 | 249 |  	netdev_tx_complete_next_err ( netdev,
 | 
		
	
		
			
			| 222 |  | -				      ( cqe->is_error ? -EIO : 0 ) );
 | 
		
	
		
			
			|  | 250 | +				      ( ib_cqe->is_error ? -EIO : 0 ) );
 | 
		
	
		
			
			| 223 | 251 |  }
 | 
		
	
		
			
			| 224 | 252 |  
 | 
		
	
		
			
			| 225 | 253 |  /**
 | 
		
	
		
			
			| 226 | 254 |   * Handle RX completion
 | 
		
	
		
			
			| 227 | 255 |   *
 | 
		
	
		
			
			| 228 | 256 |   * @v netdev		Network device
 | 
		
	
		
			
			| 229 |  | - * @v cqe		Completion queue entry
 | 
		
	
		
			
			|  | 257 | + * @v ib_cqe		Completion queue entry
 | 
		
	
		
			
			| 230 | 258 |   */
 | 
		
	
		
			
			| 231 | 259 |  static void mlx_rx_complete ( struct net_device *netdev,
 | 
		
	
		
			
			| 232 |  | -			      struct ib_cqe_st *cqe ) {
 | 
		
	
		
			
			|  | 260 | +			      struct ib_cqe_st *ib_cqe ) {
 | 
		
	
		
			
			| 233 | 261 |  	unsigned int len;
 | 
		
	
		
			
			| 234 | 262 |  	struct io_buffer *iobuf;
 | 
		
	
		
			
			| 235 | 263 |  	void *buf;
 | 
		
	
		
			
			| 236 | 264 |  
 | 
		
	
		
			
			| 237 | 265 |  	/* Check for errors */
 | 
		
	
		
			
			| 238 |  | -	if ( cqe->is_error ) {
 | 
		
	
		
			
			|  | 266 | +	if ( ib_cqe->is_error ) {
 | 
		
	
		
			
			| 239 | 267 |  		netdev_rx_err ( netdev, NULL, -EIO );
 | 
		
	
		
			
			| 240 | 268 |  		return;
 | 
		
	
		
			
			| 241 | 269 |  	}
 | 
		
	
		
			
			| 242 | 270 |  
 | 
		
	
		
			
			| 243 | 271 |  	/* Allocate I/O buffer */
 | 
		
	
		
			
			| 244 |  | -	len = cqe->count;
 | 
		
	
		
			
			|  | 272 | +	len = ( ib_cqe->count - GRH_SIZE );
 | 
		
	
		
			
			| 245 | 273 |  	iobuf = alloc_iob ( len );
 | 
		
	
		
			
			| 246 | 274 |  	if ( ! iobuf ) {
 | 
		
	
		
			
			| 247 | 275 |  		netdev_rx_err ( netdev, NULL, -ENOMEM );
 | 
		
	
		
			
			| 248 | 276 |  		return;
 | 
		
	
		
			
			| 249 | 277 |  	}
 | 
		
	
		
			
			| 250 |  | -	buf = get_rcv_wqe_buf ( cqe->wqe, 1 );
 | 
		
	
		
			
			|  | 278 | +	buf = get_rcv_wqe_buf ( ib_cqe->wqe, 1 );
 | 
		
	
		
			
			| 251 | 279 |  	memcpy ( iob_put ( iobuf, len ), buf, len );
 | 
		
	
		
			
			| 252 | 280 |  	//	DBG ( "Received packet header:\n" );
 | 
		
	
		
			
			| 253 | 281 |  	//	struct recv_wqe_st *rcv_wqe = ib_cqe.wqe;
 | 
		
	
	
		
			
			|  | @@ -263,52 +291,33 @@ static void mlx_rx_complete ( struct net_device *netdev,
 | 
		
	
		
			
			| 263 | 291 |   *
 | 
		
	
		
			
			| 264 | 292 |   * @v netdev		Network device
 | 
		
	
		
			
			| 265 | 293 |   * @v cq		Completion queue
 | 
		
	
		
			
			|  | 294 | + * @v handler		Completion handler
 | 
		
	
		
			
			| 266 | 295 |   */
 | 
		
	
		
			
			| 267 |  | -static void mlx_poll_cq ( struct net_device *netdev,
 | 
		
	
		
			
			| 268 |  | -			  struct cq_st *cq ) {
 | 
		
	
		
			
			|  | 296 | +static void mlx_poll_cq ( struct net_device *netdev, cq_t cq,
 | 
		
	
		
			
			|  | 297 | +			  void ( * handler ) ( struct net_device *netdev,
 | 
		
	
		
			
			|  | 298 | +					       struct ib_cqe_st *ib_cqe ) ) {
 | 
		
	
		
			
			| 269 | 299 |  	struct mlx_nic *mlx = netdev->priv;
 | 
		
	
		
			
			| 270 |  | -	struct ib_cqe_st cqe;
 | 
		
	
		
			
			|  | 300 | +	struct ib_cqe_st ib_cqe;
 | 
		
	
		
			
			| 271 | 301 |  	uint8_t num_cqes;
 | 
		
	
		
			
			| 272 | 302 |  
 | 
		
	
		
			
			| 273 | 303 |  	while ( 1 ) {
 | 
		
	
		
			
			| 274 | 304 |  
 | 
		
	
		
			
			| 275 |  | -		unsigned long cons_idx;
 | 
		
	
		
			
			| 276 |  | -		union cqe_st *temp;
 | 
		
	
		
			
			| 277 |  | -
 | 
		
	
		
			
			| 278 |  | -		cons_idx = ( cq->cons_counter & ( cq->num_cqes - 1 ) );
 | 
		
	
		
			
			| 279 |  | -		temp = &cq->cq_buf[cons_idx];
 | 
		
	
		
			
			| 280 |  | -		if ( EX_FLD_BE ( temp, arbelprm_completion_queue_entry_st,
 | 
		
	
		
			
			| 281 |  | -				 owner ) == 0 ) {
 | 
		
	
		
			
			| 282 |  | -			DBG ( "software owned\n" );
 | 
		
	
		
			
			| 283 |  | -			DBGC_HD ( mlx, temp, sizeof ( *temp ) );
 | 
		
	
		
			
			| 284 |  | -			DBG ( "my_qpn=%lx, g=%ld, s=%ld, op=%02lx, cnt=%lx\n",
 | 
		
	
		
			
			| 285 |  | -			      EX_FLD_BE ( temp, arbelprm_completion_queue_entry_st, my_qpn ),
 | 
		
	
		
			
			| 286 |  | -			      EX_FLD_BE ( temp, arbelprm_completion_queue_entry_st, g ),
 | 
		
	
		
			
			| 287 |  | -			      EX_FLD_BE ( temp, arbelprm_completion_queue_entry_st, s ),
 | 
		
	
		
			
			| 288 |  | -			      EX_FLD_BE ( temp, arbelprm_completion_queue_entry_st, opcode ),
 | 
		
	
		
			
			| 289 |  | -			      EX_FLD_BE ( temp, arbelprm_completion_queue_entry_st, byte_cnt ) );
 | 
		
	
		
			
			| 290 |  | -		}
 | 
		
	
		
			
			| 291 |  | -
 | 
		
	
		
			
			| 292 | 305 |  		/* Poll for single completion queue entry */
 | 
		
	
		
			
			| 293 |  | -		ib_poll_cq ( cq, &cqe, &num_cqes );
 | 
		
	
		
			
			|  | 306 | +		ib_poll_cq ( cq, &ib_cqe, &num_cqes );
 | 
		
	
		
			
			| 294 | 307 |  
 | 
		
	
		
			
			| 295 | 308 |  		/* Return if no entries in the queue */
 | 
		
	
		
			
			| 296 | 309 |  		if ( ! num_cqes )
 | 
		
	
		
			
			| 297 | 310 |  			return;
 | 
		
	
		
			
			| 298 | 311 |  
 | 
		
	
		
			
			| 299 | 312 |  		DBGC ( mlx, "MLX %p cpl in %p: err %x send %x "
 | 
		
	
		
			
			| 300 |  | -		       "wqe %p count %lx\n", mlx, cq, cqe.is_error,
 | 
		
	
		
			
			| 301 |  | -		       cqe.is_send, cqe.wqe, cqe.count );
 | 
		
	
		
			
			|  | 313 | +		       "wqe %p count %lx\n", mlx, cq, ib_cqe.is_error,
 | 
		
	
		
			
			|  | 314 | +		       ib_cqe.is_send, ib_cqe.wqe, ib_cqe.count );
 | 
		
	
		
			
			| 302 | 315 |  
 | 
		
	
		
			
			| 303 | 316 |  		/* Handle TX/RX completion */
 | 
		
	
		
			
			| 304 |  | -		if ( cqe.is_send ) {
 | 
		
	
		
			
			| 305 |  | -			mlx_tx_complete ( netdev, &cqe );
 | 
		
	
		
			
			| 306 |  | -		} else {
 | 
		
	
		
			
			| 307 |  | -			mlx_rx_complete ( netdev, &cqe );
 | 
		
	
		
			
			| 308 |  | -		}
 | 
		
	
		
			
			| 309 |  | -		
 | 
		
	
		
			
			|  | 317 | +		handler ( netdev, &ib_cqe );
 | 
		
	
		
			
			|  | 318 | +
 | 
		
	
		
			
			| 310 | 319 |  		/* Free associated work queue entry */
 | 
		
	
		
			
			| 311 |  | -		free_wqe ( cqe.wqe );
 | 
		
	
		
			
			|  | 320 | +		free_wqe ( ib_cqe.wqe );
 | 
		
	
		
			
			| 312 | 321 |  	}
 | 
		
	
		
			
			| 313 | 322 |  }
 | 
		
	
		
			
			| 314 | 323 |  
 | 
		
	
	
		
			
			|  | @@ -318,6 +327,7 @@ static void mlx_poll_cq ( struct net_device *netdev,
 | 
		
	
		
			
			| 318 | 327 |   * @v netdev		Network device
 | 
		
	
		
			
			| 319 | 328 |   */
 | 
		
	
		
			
			| 320 | 329 |  static void mlx_poll ( struct net_device *netdev ) {
 | 
		
	
		
			
			|  | 330 | +	struct mlx_nic *mlx = netdev->priv;
 | 
		
	
		
			
			| 321 | 331 |  	int rc;
 | 
		
	
		
			
			| 322 | 332 |  
 | 
		
	
		
			
			| 323 | 333 |  	if ( ( rc = poll_error_buf() ) != 0 ) {
 | 
		
	
	
		
			
			|  | @@ -330,8 +340,8 @@ static void mlx_poll ( struct net_device *netdev ) {
 | 
		
	
		
			
			| 330 | 340 |  		return;
 | 
		
	
		
			
			| 331 | 341 |  	}
 | 
		
	
		
			
			| 332 | 342 |  
 | 
		
	
		
			
			| 333 |  | -	//	mlx_poll_cq ( netdev, ipoib_data.snd_cqh );
 | 
		
	
		
			
			| 334 |  | -	mlx_poll_cq ( netdev, ipoib_data.rcv_cqh );
 | 
		
	
		
			
			|  | 343 | +	mlx_poll_cq ( netdev, mlx->snd_cqh, mlx_tx_complete );
 | 
		
	
		
			
			|  | 344 | +	mlx_poll_cq ( netdev, mlx->rcv_cqh, mlx_rx_complete );
 | 
		
	
		
			
			| 335 | 345 |  }
 | 
		
	
		
			
			| 336 | 346 |  
 | 
		
	
		
			
			| 337 | 347 |  /**
 | 
		
	
	
		
			
			|  | @@ -386,7 +396,7 @@ static void mlx_remove ( struct pci_device *pci ) {
 | 
		
	
		
			
			| 386 | 396 |  	struct net_device *netdev = pci_get_drvdata ( pci );
 | 
		
	
		
			
			| 387 | 397 |  
 | 
		
	
		
			
			| 388 | 398 |  	unregister_netdev ( netdev );
 | 
		
	
		
			
			| 389 |  | -	ipoib_close(0);
 | 
		
	
		
			
			|  | 399 | +	ib_driver_close ( 0 );
 | 
		
	
		
			
			| 390 | 400 |  	netdev_nullify ( netdev );
 | 
		
	
		
			
			| 391 | 401 |  	netdev_put ( netdev );
 | 
		
	
		
			
			| 392 | 402 |  }
 | 
		
	
	
		
			
			|  | @@ -473,6 +483,7 @@ static int mlx_probe ( struct pci_device *pci,
 | 
		
	
		
			
			| 473 | 483 |  	struct net_device *netdev;
 | 
		
	
		
			
			| 474 | 484 |  	struct mlx_nic *mlx;
 | 
		
	
		
			
			| 475 | 485 |  	struct ib_mac *mac;
 | 
		
	
		
			
			|  | 486 | +	udqp_t qph;
 | 
		
	
		
			
			| 476 | 487 |  	int rc;
 | 
		
	
		
			
			| 477 | 488 |  
 | 
		
	
		
			
			| 478 | 489 |  	/* Allocate net device */
 | 
		
	
	
		
			
			|  | @@ -489,11 +500,15 @@ static int mlx_probe ( struct pci_device *pci,
 | 
		
	
		
			
			| 489 | 500 |  	adjust_pci_device ( pci );
 | 
		
	
		
			
			| 490 | 501 |  
 | 
		
	
		
			
			| 491 | 502 |  	/* Initialise hardware */
 | 
		
	
		
			
			| 492 |  | -	if ( ( rc = ipoib_init ( pci ) ) != 0 )
 | 
		
	
		
			
			|  | 503 | +	if ( ( rc = ib_driver_init ( pci, &qph ) ) != 0 )
 | 
		
	
		
			
			| 493 | 504 |  		goto err_ipoib_init;
 | 
		
	
		
			
			|  | 505 | +	mlx->ipoib_qph = qph;
 | 
		
	
		
			
			|  | 506 | +	mlx->bcast_av = ib_data.bcast_av;
 | 
		
	
		
			
			|  | 507 | +	mlx->snd_cqh = ib_data.ipoib_snd_cq;
 | 
		
	
		
			
			|  | 508 | +	mlx->rcv_cqh = ib_data.ipoib_rcv_cq;
 | 
		
	
		
			
			| 494 | 509 |  	mac = ( ( struct ib_mac * ) netdev->ll_addr );
 | 
		
	
		
			
			| 495 |  | -	mac->qpn = htonl ( ipoib_data.ipoib_qpn );
 | 
		
	
		
			
			| 496 |  | -	memcpy ( &mac->gid, ipoib_data.port_gid_raw, sizeof ( mac->gid ) );
 | 
		
	
		
			
			|  | 510 | +	mac->qpn = htonl ( ib_get_qpn ( mlx->ipoib_qph ) );
 | 
		
	
		
			
			|  | 511 | +	memcpy ( &mac->gid, ib_data.port_gid.raw, sizeof ( mac->gid ) );
 | 
		
	
		
			
			| 497 | 512 |  
 | 
		
	
		
			
			| 498 | 513 |  	/* Register network device */
 | 
		
	
		
			
			| 499 | 514 |  	if ( ( rc = register_netdev ( netdev ) ) != 0 )
 | 
		
	
	
		
			
			|  | @@ -503,7 +518,7 @@ static int mlx_probe ( struct pci_device *pci,
 | 
		
	
		
			
			| 503 | 518 |  
 | 
		
	
		
			
			| 504 | 519 |   err_register_netdev:
 | 
		
	
		
			
			| 505 | 520 |   err_ipoib_init:
 | 
		
	
		
			
			| 506 |  | -	ipoib_close(0);
 | 
		
	
		
			
			|  | 521 | +	ib_driver_close ( 0 );
 | 
		
	
		
			
			| 507 | 522 |  	netdev_nullify ( netdev );
 | 
		
	
		
			
			| 508 | 523 |  	netdev_put ( netdev );
 | 
		
	
		
			
			| 509 | 524 |  	return rc;
 |