|  | @@ -344,6 +344,15 @@ hermon_cmd_hw2sw_eq ( struct hermon *hermon, unsigned int index,
 | 
		
	
		
			
			| 344 | 344 |  			    1, NULL, index, eqctx );
 | 
		
	
		
			
			| 345 | 345 |  }
 | 
		
	
		
			
			| 346 | 346 |  
 | 
		
	
		
			
			|  | 347 | +static inline int
 | 
		
	
		
			
			|  | 348 | +hermon_cmd_query_eq ( struct hermon *hermon, unsigned int index,
 | 
		
	
		
			
			|  | 349 | +		      struct hermonprm_eqc *eqctx ) {
 | 
		
	
		
			
			|  | 350 | +	return hermon_cmd ( hermon,
 | 
		
	
		
			
			|  | 351 | +			    HERMON_HCR_OUT_CMD ( HERMON_HCR_QUERY_EQ,
 | 
		
	
		
			
			|  | 352 | +						 1, sizeof ( *eqctx ) ),
 | 
		
	
		
			
			|  | 353 | +			    0, NULL, index, eqctx );
 | 
		
	
		
			
			|  | 354 | +}
 | 
		
	
		
			
			|  | 355 | +
 | 
		
	
		
			
			| 347 | 356 |  static inline int
 | 
		
	
		
			
			| 348 | 357 |  hermon_cmd_sw2hw_cq ( struct hermon *hermon, unsigned long cqn,
 | 
		
	
		
			
			| 349 | 358 |  		      const struct hermonprm_completion_queue_context *cqctx ){
 | 
		
	
	
		
			
			|  | @@ -667,7 +676,7 @@ static int hermon_create_cq ( struct ib_device *ibdev,
 | 
		
	
		
			
			| 667 | 676 |  	MLX_FILL_1 ( &cqctx, 2,
 | 
		
	
		
			
			| 668 | 677 |  		     page_offset, ( hermon_cq->mtt.page_offset >> 5 ) );
 | 
		
	
		
			
			| 669 | 678 |  	MLX_FILL_2 ( &cqctx, 3,
 | 
		
	
		
			
			| 670 |  | -		     usr_page, HERMON_UAR_PAGE,
 | 
		
	
		
			
			|  | 679 | +		     usr_page, HERMON_UAR_NON_EQ_PAGE,
 | 
		
	
		
			
			| 671 | 680 |  		     log_cq_size, fls ( cq->num_cqes - 1 ) );
 | 
		
	
		
			
			| 672 | 681 |  	MLX_FILL_1 ( &cqctx, 7, mtt_base_addr_l,
 | 
		
	
		
			
			| 673 | 682 |  		     ( hermon_cq->mtt.mtt_base_addr >> 3 ) );
 | 
		
	
	
		
			
			|  | @@ -773,6 +782,11 @@ static int hermon_create_qp ( struct ib_device *ibdev,
 | 
		
	
		
			
			| 773 | 782 |  		goto err_hermon_qp;
 | 
		
	
		
			
			| 774 | 783 |  	}
 | 
		
	
		
			
			| 775 | 784 |  
 | 
		
	
		
			
			|  | 785 | +	/* Calculate doorbell address */
 | 
		
	
		
			
			|  | 786 | +	hermon_qp->send.doorbell =
 | 
		
	
		
			
			|  | 787 | +		( hermon->uar + HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE +
 | 
		
	
		
			
			|  | 788 | +		  HERMON_DB_POST_SND_OFFSET );
 | 
		
	
		
			
			|  | 789 | +
 | 
		
	
		
			
			| 776 | 790 |  	/* Allocate work queue buffer */
 | 
		
	
		
			
			| 777 | 791 |  	hermon_qp->send.num_wqes = ( qp->send.num_wqes /* headroom */ + 1 +
 | 
		
	
		
			
			| 778 | 792 |  				( 2048 / sizeof ( hermon_qp->send.wqe[0] ) ) );
 | 
		
	
	
		
			
			|  | @@ -817,7 +831,7 @@ static int hermon_create_qp ( struct ib_device *ibdev,
 | 
		
	
		
			
			| 817 | 831 |  		     qpc_eec_data.log_sq_stride,
 | 
		
	
		
			
			| 818 | 832 |  		     ( fls ( sizeof ( hermon_qp->send.wqe[0] ) - 1 ) - 4 ) );
 | 
		
	
		
			
			| 819 | 833 |  	MLX_FILL_1 ( &qpctx, 5,
 | 
		
	
		
			
			| 820 |  | -		     qpc_eec_data.usr_page, HERMON_UAR_PAGE );
 | 
		
	
		
			
			|  | 834 | +		     qpc_eec_data.usr_page, HERMON_UAR_NON_EQ_PAGE );
 | 
		
	
		
			
			| 821 | 835 |  	MLX_FILL_1 ( &qpctx, 33, qpc_eec_data.cqn_snd, qp->send.cq->cqn );
 | 
		
	
		
			
			| 822 | 836 |  	MLX_FILL_1 ( &qpctx, 38, qpc_eec_data.page_offset,
 | 
		
	
		
			
			| 823 | 837 |  		     ( hermon_qp->mtt.page_offset >> 6 ) );
 | 
		
	
	
		
			
			|  | @@ -1029,9 +1043,8 @@ static int hermon_post_send ( struct ib_device *ibdev,
 | 
		
	
		
			
			| 1029 | 1043 |  	/* Ring doorbell register */
 | 
		
	
		
			
			| 1030 | 1044 |  	MLX_FILL_1 ( &db_reg.send, 0, qn, qp->qpn );
 | 
		
	
		
			
			| 1031 | 1045 |  	DBGCP ( hermon, "Ringing doorbell %08lx with %08lx\n",
 | 
		
	
		
			
			| 1032 |  | -		virt_to_phys ( hermon->uar + HERMON_DB_POST_SND_OFFSET ),
 | 
		
	
		
			
			| 1033 |  | -		db_reg.dword[0] );
 | 
		
	
		
			
			| 1034 |  | -	writel ( db_reg.dword[0], ( hermon->uar + HERMON_DB_POST_SND_OFFSET ));
 | 
		
	
		
			
			|  | 1046 | +		virt_to_phys ( hermon_send_wq->doorbell ), db_reg.dword[0] );
 | 
		
	
		
			
			|  | 1047 | +	writel ( db_reg.dword[0], ( hermon_send_wq->doorbell ) );
 | 
		
	
		
			
			| 1035 | 1048 |  
 | 
		
	
		
			
			| 1036 | 1049 |  	/* Update work queue's index */
 | 
		
	
		
			
			| 1037 | 1050 |  	wq->next_idx++;
 | 
		
	
	
		
			
			|  | @@ -1209,7 +1222,7 @@ static void hermon_poll_cq ( struct ib_device *ibdev,
 | 
		
	
		
			
			| 1209 | 1222 |  
 | 
		
	
		
			
			| 1210 | 1223 |  		/* Update doorbell record */
 | 
		
	
		
			
			| 1211 | 1224 |  		MLX_FILL_1 ( &hermon_cq->doorbell, 0, update_ci,
 | 
		
	
		
			
			| 1212 |  | -			     ( cq->next_idx & 0xffffffUL ) );
 | 
		
	
		
			
			|  | 1225 | +			     ( cq->next_idx & 0x00ffffffUL ) );
 | 
		
	
		
			
			| 1213 | 1226 |  	}
 | 
		
	
		
			
			| 1214 | 1227 |  }
 | 
		
	
		
			
			| 1215 | 1228 |  
 | 
		
	
	
		
			
			|  | @@ -1442,6 +1455,15 @@ static int hermon_create_eq ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 1442 | 1455 |  	unsigned int i;
 | 
		
	
		
			
			| 1443 | 1456 |  	int rc;
 | 
		
	
		
			
			| 1444 | 1457 |  
 | 
		
	
		
			
			|  | 1458 | +	/* Select event queue number */
 | 
		
	
		
			
			|  | 1459 | +	hermon_eq->eqn = ( 4 * hermon->cap.reserved_uars );
 | 
		
	
		
			
			|  | 1460 | +	if ( hermon_eq->eqn < hermon->cap.reserved_eqs )
 | 
		
	
		
			
			|  | 1461 | +		hermon_eq->eqn = hermon->cap.reserved_eqs;
 | 
		
	
		
			
			|  | 1462 | +
 | 
		
	
		
			
			|  | 1463 | +	/* Calculate doorbell address */
 | 
		
	
		
			
			|  | 1464 | +	hermon_eq->doorbell =
 | 
		
	
		
			
			|  | 1465 | +		( hermon->uar + HERMON_DB_EQ_OFFSET ( hermon_eq->eqn ) );
 | 
		
	
		
			
			|  | 1466 | +
 | 
		
	
		
			
			| 1445 | 1467 |  	/* Allocate event queue itself */
 | 
		
	
		
			
			| 1446 | 1468 |  	hermon_eq->eqe_size =
 | 
		
	
		
			
			| 1447 | 1469 |  		( HERMON_NUM_EQES * sizeof ( hermon_eq->eqe[0] ) );
 | 
		
	
	
		
			
			|  | @@ -1471,7 +1493,8 @@ static int hermon_create_eq ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 1471 | 1493 |  	MLX_FILL_1 ( &eqctx, 3, log_eq_size, fls ( HERMON_NUM_EQES - 1 ) );
 | 
		
	
		
			
			| 1472 | 1494 |  	MLX_FILL_1 ( &eqctx, 7, mtt_base_addr_l,
 | 
		
	
		
			
			| 1473 | 1495 |  		     ( hermon_eq->mtt.mtt_base_addr >> 3 ) );
 | 
		
	
		
			
			| 1474 |  | -	if ( ( rc = hermon_cmd_sw2hw_eq ( hermon, 0, &eqctx ) ) != 0 ) {
 | 
		
	
		
			
			|  | 1496 | +	if ( ( rc = hermon_cmd_sw2hw_eq ( hermon, hermon_eq->eqn,
 | 
		
	
		
			
			|  | 1497 | +					  &eqctx ) ) != 0 ) {
 | 
		
	
		
			
			| 1475 | 1498 |  		DBGC ( hermon, "Hermon %p SW2HW_EQ failed: %s\n",
 | 
		
	
		
			
			| 1476 | 1499 |  		       hermon, strerror ( rc ) );
 | 
		
	
		
			
			| 1477 | 1500 |  		goto err_sw2hw_eq;
 | 
		
	
	
		
			
			|  | @@ -1480,17 +1503,21 @@ static int hermon_create_eq ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 1480 | 1503 |  	/* Map events to this event queue */
 | 
		
	
		
			
			| 1481 | 1504 |  	memset ( &mask, 0, sizeof ( mask ) );
 | 
		
	
		
			
			| 1482 | 1505 |  	MLX_FILL_1 ( &mask, 1, port_state_change, 1 );
 | 
		
	
		
			
			| 1483 |  | -	if ( ( rc = hermon_cmd_map_eq ( hermon, ( HERMON_MAP_EQ_MAP | 0 ),
 | 
		
	
		
			
			|  | 1506 | +	if ( ( rc = hermon_cmd_map_eq ( hermon,
 | 
		
	
		
			
			|  | 1507 | +					( HERMON_MAP_EQ | hermon_eq->eqn ),
 | 
		
	
		
			
			| 1484 | 1508 |  					&mask ) ) != 0 ) {
 | 
		
	
		
			
			| 1485 | 1509 |  		DBGC ( hermon, "Hermon %p MAP_EQ failed: %s\n",
 | 
		
	
		
			
			| 1486 | 1510 |  		       hermon, strerror ( rc )  );
 | 
		
	
		
			
			| 1487 | 1511 |  		goto err_map_eq;
 | 
		
	
		
			
			| 1488 | 1512 |  	}
 | 
		
	
		
			
			| 1489 | 1513 |  
 | 
		
	
		
			
			|  | 1514 | +	DBGC ( hermon, "Hermon %p EQN %#lx ring at [%p,%p])\n",
 | 
		
	
		
			
			|  | 1515 | +	       hermon, hermon_eq->eqn, hermon_eq->eqe,
 | 
		
	
		
			
			|  | 1516 | +	       ( ( ( void * ) hermon_eq->eqe ) + hermon_eq->eqe_size ) );
 | 
		
	
		
			
			| 1490 | 1517 |  	return 0;
 | 
		
	
		
			
			| 1491 | 1518 |  
 | 
		
	
		
			
			| 1492 | 1519 |   err_map_eq:
 | 
		
	
		
			
			| 1493 |  | -	hermon_cmd_hw2sw_eq ( hermon, 0, &eqctx );
 | 
		
	
		
			
			|  | 1520 | +	hermon_cmd_hw2sw_eq ( hermon, hermon_eq->eqn, &eqctx );
 | 
		
	
		
			
			| 1494 | 1521 |   err_sw2hw_eq:
 | 
		
	
		
			
			| 1495 | 1522 |  	hermon_free_mtt ( hermon, &hermon_eq->mtt );
 | 
		
	
		
			
			| 1496 | 1523 |   err_alloc_mtt:
 | 
		
	
	
		
			
			|  | @@ -1514,7 +1541,8 @@ static void hermon_destroy_eq ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 1514 | 1541 |  	/* Unmap events from event queue */
 | 
		
	
		
			
			| 1515 | 1542 |  	memset ( &mask, 0, sizeof ( mask ) );
 | 
		
	
		
			
			| 1516 | 1543 |  	MLX_FILL_1 ( &mask, 1, port_state_change, 1 );
 | 
		
	
		
			
			| 1517 |  | -	if ( ( rc = hermon_cmd_map_eq ( hermon, ( HERMON_MAP_EQ_UNMAP | 0 ),
 | 
		
	
		
			
			|  | 1544 | +	if ( ( rc = hermon_cmd_map_eq ( hermon,
 | 
		
	
		
			
			|  | 1545 | +					( HERMON_UNMAP_EQ | hermon_eq->eqn ),
 | 
		
	
		
			
			| 1518 | 1546 |  					&mask ) ) != 0 ) {
 | 
		
	
		
			
			| 1519 | 1547 |  		DBGC ( hermon, "Hermon %p FATAL MAP_EQ failed to unmap: %s\n",
 | 
		
	
		
			
			| 1520 | 1548 |  		       hermon, strerror ( rc ) );
 | 
		
	
	
		
			
			|  | @@ -1522,7 +1550,8 @@ static void hermon_destroy_eq ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 1522 | 1550 |  	}
 | 
		
	
		
			
			| 1523 | 1551 |  
 | 
		
	
		
			
			| 1524 | 1552 |  	/* Take ownership back from hardware */
 | 
		
	
		
			
			| 1525 |  | -	if ( ( rc = hermon_cmd_hw2sw_eq ( hermon, 0, &eqctx ) ) != 0 ) {
 | 
		
	
		
			
			|  | 1553 | +	if ( ( rc = hermon_cmd_hw2sw_eq ( hermon, hermon_eq->eqn,
 | 
		
	
		
			
			|  | 1554 | +					  &eqctx ) ) != 0 ) {
 | 
		
	
		
			
			| 1526 | 1555 |  		DBGC ( hermon, "Hermon %p FATAL HW2SW_EQ failed: %s\n",
 | 
		
	
		
			
			| 1527 | 1556 |  		       hermon, strerror ( rc ) );
 | 
		
	
		
			
			| 1528 | 1557 |  		/* Leak memory and return; at least we avoid corruption */
 | 
		
	
	
		
			
			|  | @@ -1578,6 +1607,7 @@ static void hermon_poll_eq ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 1578 | 1607 |  	unsigned int event_type;
 | 
		
	
		
			
			| 1579 | 1608 |  
 | 
		
	
		
			
			| 1580 | 1609 |  	while ( 1 ) {
 | 
		
	
		
			
			|  | 1610 | +		/* Look for event entry */
 | 
		
	
		
			
			| 1581 | 1611 |  		eqe_idx_mask = ( HERMON_NUM_EQES - 1 );
 | 
		
	
		
			
			| 1582 | 1612 |  		eqe = &hermon_eq->eqe[hermon_eq->next_idx & eqe_idx_mask];
 | 
		
	
		
			
			| 1583 | 1613 |  		if ( MLX_GET ( &eqe->generic, owner ) ^
 | 
		
	
	
		
			
			|  | @@ -1605,13 +1635,12 @@ static void hermon_poll_eq ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 1605 | 1635 |  		hermon_eq->next_idx++;
 | 
		
	
		
			
			| 1606 | 1636 |  
 | 
		
	
		
			
			| 1607 | 1637 |  		/* Ring doorbell */
 | 
		
	
		
			
			| 1608 |  | -		memset ( &db_reg, 0, sizeof ( db_reg ) );
 | 
		
	
		
			
			| 1609 |  | -		MLX_FILL_1 ( &db_reg.event, 0, ci, hermon_eq->next_idx );
 | 
		
	
		
			
			|  | 1638 | +		MLX_FILL_1 ( &db_reg.event, 0,
 | 
		
	
		
			
			|  | 1639 | +			     ci, ( hermon_eq->next_idx & 0x00ffffffUL ) );
 | 
		
	
		
			
			| 1610 | 1640 |  		DBGCP ( hermon, "Ringing doorbell %08lx with %08lx\n",
 | 
		
	
		
			
			| 1611 |  | -			virt_to_phys ( hermon->uar + HERMON_DB_EQ0_OFFSET ),
 | 
		
	
		
			
			|  | 1641 | +			virt_to_phys ( hermon_eq->doorbell ),
 | 
		
	
		
			
			| 1612 | 1642 |  			db_reg.dword[0] );
 | 
		
	
		
			
			| 1613 |  | -		writel ( db_reg.dword[0],
 | 
		
	
		
			
			| 1614 |  | -			 ( hermon->uar + HERMON_DB_EQ0_OFFSET ) );
 | 
		
	
		
			
			|  | 1643 | +		writel ( db_reg.dword[0], hermon_eq->doorbell );
 | 
		
	
		
			
			| 1615 | 1644 |  	}
 | 
		
	
		
			
			| 1616 | 1645 |  }
 | 
		
	
		
			
			| 1617 | 1646 |  
 | 
		
	
	
		
			
			|  | @@ -2161,9 +2190,8 @@ static int hermon_probe ( struct pci_device *pci,
 | 
		
	
		
			
			| 2161 | 2190 |  	/* Get PCI BARs */
 | 
		
	
		
			
			| 2162 | 2191 |  	hermon->config = ioremap ( pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR),
 | 
		
	
		
			
			| 2163 | 2192 |  				   HERMON_PCI_CONFIG_BAR_SIZE );
 | 
		
	
		
			
			| 2164 |  | -	hermon->uar = ioremap ( ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ) +
 | 
		
	
		
			
			| 2165 |  | -				  HERMON_UAR_PAGE * HERMON_PAGE_SIZE ),
 | 
		
	
		
			
			| 2166 |  | -				HERMON_PAGE_SIZE );
 | 
		
	
		
			
			|  | 2193 | +	hermon->uar = ioremap ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ),
 | 
		
	
		
			
			|  | 2194 | +				HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
 | 
		
	
		
			
			| 2167 | 2195 |  
 | 
		
	
		
			
			| 2168 | 2196 |  	/* Allocate space for mailboxes */
 | 
		
	
		
			
			| 2169 | 2197 |  	hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE,
 |