|  | @@ -2136,7 +2136,7 @@ static int hermon_map_vpm ( struct hermon *hermon,
 | 
		
	
		
			
			| 2136 | 2136 |  static int hermon_start_firmware ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 2137 | 2137 |  	struct hermonprm_query_fw fw;
 | 
		
	
		
			
			| 2138 | 2138 |  	unsigned int fw_pages;
 | 
		
	
		
			
			| 2139 |  | -	size_t fw_size;
 | 
		
	
		
			
			|  | 2139 | +	size_t fw_len;
 | 
		
	
		
			
			| 2140 | 2140 |  	physaddr_t fw_base;
 | 
		
	
		
			
			| 2141 | 2141 |  	int rc;
 | 
		
	
		
			
			| 2142 | 2142 |  
 | 
		
	
	
		
			
			|  | @@ -2154,17 +2154,22 @@ static int hermon_start_firmware ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 2154 | 2154 |  	       hermon, fw_pages, ( fw_pages * 4 ) );
 | 
		
	
		
			
			| 2155 | 2155 |  
 | 
		
	
		
			
			| 2156 | 2156 |  	/* Allocate firmware pages and map firmware area */
 | 
		
	
		
			
			| 2157 |  | -	fw_size = ( fw_pages * HERMON_PAGE_SIZE );
 | 
		
	
		
			
			| 2158 |  | -	hermon->firmware_area = umalloc ( fw_size );
 | 
		
	
		
			
			|  | 2157 | +	fw_len = ( fw_pages * HERMON_PAGE_SIZE );
 | 
		
	
		
			
			| 2159 | 2158 |  	if ( ! hermon->firmware_area ) {
 | 
		
	
		
			
			| 2160 |  | -		rc = -ENOMEM;
 | 
		
	
		
			
			| 2161 |  | -		goto err_alloc_fa;
 | 
		
	
		
			
			|  | 2159 | +		hermon->firmware_len = fw_len;
 | 
		
	
		
			
			|  | 2160 | +		hermon->firmware_area = umalloc ( hermon->firmware_len );
 | 
		
	
		
			
			|  | 2161 | +		if ( ! hermon->firmware_area ) {
 | 
		
	
		
			
			|  | 2162 | +			rc = -ENOMEM;
 | 
		
	
		
			
			|  | 2163 | +			goto err_alloc_fa;
 | 
		
	
		
			
			|  | 2164 | +		}
 | 
		
	
		
			
			|  | 2165 | +	} else {
 | 
		
	
		
			
			|  | 2166 | +		assert ( hermon->firmware_len == fw_len );
 | 
		
	
		
			
			| 2162 | 2167 |  	}
 | 
		
	
		
			
			| 2163 | 2168 |  	fw_base = user_to_phys ( hermon->firmware_area, 0 );
 | 
		
	
		
			
			| 2164 | 2169 |  	DBGC ( hermon, "Hermon %p firmware area at physical [%08lx,%08lx)\n",
 | 
		
	
		
			
			| 2165 |  | -	       hermon, fw_base, ( fw_base + fw_size ) );
 | 
		
	
		
			
			|  | 2170 | +	       hermon, fw_base, ( fw_base + fw_len ) );
 | 
		
	
		
			
			| 2166 | 2171 |  	if ( ( rc = hermon_map_vpm ( hermon, hermon_cmd_map_fa,
 | 
		
	
		
			
			| 2167 |  | -				     0, fw_base, fw_size ) ) != 0 ) {
 | 
		
	
		
			
			|  | 2172 | +				     0, fw_base, fw_len ) ) != 0 ) {
 | 
		
	
		
			
			| 2168 | 2173 |  		DBGC ( hermon, "Hermon %p could not map firmware: %s\n",
 | 
		
	
		
			
			| 2169 | 2174 |  		       hermon, strerror ( rc ) );
 | 
		
	
		
			
			| 2170 | 2175 |  		goto err_map_fa;
 | 
		
	
	
		
			
			|  | @@ -2183,8 +2188,6 @@ static int hermon_start_firmware ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 2183 | 2188 |   err_run_fw:
 | 
		
	
		
			
			| 2184 | 2189 |   err_map_fa:
 | 
		
	
		
			
			| 2185 | 2190 |  	hermon_cmd_unmap_fa ( hermon );
 | 
		
	
		
			
			| 2186 |  | -	ufree ( hermon->firmware_area );
 | 
		
	
		
			
			| 2187 |  | -	hermon->firmware_area = UNULL;
 | 
		
	
		
			
			| 2188 | 2191 |   err_alloc_fa:
 | 
		
	
		
			
			| 2189 | 2192 |   err_query_fw:
 | 
		
	
		
			
			| 2190 | 2193 |  	return rc;
 | 
		
	
	
		
			
			|  | @@ -2202,10 +2205,9 @@ static void hermon_stop_firmware ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 2202 | 2205 |  		DBGC ( hermon, "Hermon %p FATAL could not stop firmware: %s\n",
 | 
		
	
		
			
			| 2203 | 2206 |  		       hermon, strerror ( rc ) );
 | 
		
	
		
			
			| 2204 | 2207 |  		/* Leak memory and return; at least we avoid corruption */
 | 
		
	
		
			
			|  | 2208 | +		hermon->firmware_area = UNULL;
 | 
		
	
		
			
			| 2205 | 2209 |  		return;
 | 
		
	
		
			
			| 2206 | 2210 |  	}
 | 
		
	
		
			
			| 2207 |  | -	ufree ( hermon->firmware_area );
 | 
		
	
		
			
			| 2208 |  | -	hermon->firmware_area = UNULL;
 | 
		
	
		
			
			| 2209 | 2211 |  }
 | 
		
	
		
			
			| 2210 | 2212 |  
 | 
		
	
		
			
			| 2211 | 2213 |  /***************************************************************************
 | 
		
	
	
		
			
			|  | @@ -2285,14 +2287,14 @@ static uint64_t icm_align ( uint64_t icm_offset, size_t len ) {
 | 
		
	
		
			
			| 2285 | 2287 |  }
 | 
		
	
		
			
			| 2286 | 2288 |  
 | 
		
	
		
			
			| 2287 | 2289 |  /**
 | 
		
	
		
			
			| 2288 |  | - * Allocate ICM
 | 
		
	
		
			
			|  | 2290 | + * Map ICM (allocating if necessary)
 | 
		
	
		
			
			| 2289 | 2291 |   *
 | 
		
	
		
			
			| 2290 | 2292 |   * @v hermon		Hermon device
 | 
		
	
		
			
			| 2291 | 2293 |   * @v init_hca		INIT_HCA structure to fill in
 | 
		
	
		
			
			| 2292 | 2294 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 2293 | 2295 |   */
 | 
		
	
		
			
			| 2294 |  | -static int hermon_alloc_icm ( struct hermon *hermon,
 | 
		
	
		
			
			| 2295 |  | -			      struct hermonprm_init_hca *init_hca ) {
 | 
		
	
		
			
			|  | 2296 | +static int hermon_map_icm ( struct hermon *hermon,
 | 
		
	
		
			
			|  | 2297 | +			    struct hermonprm_init_hca *init_hca ) {
 | 
		
	
		
			
			| 2296 | 2298 |  	struct hermonprm_scalar_parameter icm_size;
 | 
		
	
		
			
			| 2297 | 2299 |  	struct hermonprm_scalar_parameter icm_aux_size;
 | 
		
	
		
			
			| 2298 | 2300 |  	uint64_t icm_offset = 0;
 | 
		
	
	
		
			
			|  | @@ -2519,10 +2521,17 @@ static int hermon_alloc_icm ( struct hermon *hermon,
 | 
		
	
		
			
			| 2519 | 2521 |  	/* Allocate ICM data and auxiliary area */
 | 
		
	
		
			
			| 2520 | 2522 |  	DBGC ( hermon, "Hermon %p requires %zd kB ICM and %zd kB AUX ICM\n",
 | 
		
	
		
			
			| 2521 | 2523 |  	       hermon, ( icm_len / 1024 ), ( icm_aux_len / 1024 ) );
 | 
		
	
		
			
			| 2522 |  | -	hermon->icm = umalloc ( icm_aux_len + icm_len );
 | 
		
	
		
			
			| 2523 | 2524 |  	if ( ! hermon->icm ) {
 | 
		
	
		
			
			| 2524 |  | -		rc = -ENOMEM;
 | 
		
	
		
			
			| 2525 |  | -		goto err_alloc;
 | 
		
	
		
			
			|  | 2525 | +		hermon->icm_len = icm_len;
 | 
		
	
		
			
			|  | 2526 | +		hermon->icm_aux_len = icm_aux_len;
 | 
		
	
		
			
			|  | 2527 | +		hermon->icm = umalloc ( hermon->icm_aux_len + hermon->icm_len );
 | 
		
	
		
			
			|  | 2528 | +		if ( ! hermon->icm ) {
 | 
		
	
		
			
			|  | 2529 | +			rc = -ENOMEM;
 | 
		
	
		
			
			|  | 2530 | +			goto err_alloc;
 | 
		
	
		
			
			|  | 2531 | +		}
 | 
		
	
		
			
			|  | 2532 | +	} else {
 | 
		
	
		
			
			|  | 2533 | +		assert ( hermon->icm_len == icm_len );
 | 
		
	
		
			
			|  | 2534 | +		assert ( hermon->icm_aux_len == icm_aux_len );
 | 
		
	
		
			
			| 2526 | 2535 |  	}
 | 
		
	
		
			
			| 2527 | 2536 |  	icm_phys = user_to_phys ( hermon->icm, 0 );
 | 
		
	
		
			
			| 2528 | 2537 |  
 | 
		
	
	
		
			
			|  | @@ -2559,19 +2568,17 @@ static int hermon_alloc_icm ( struct hermon *hermon,
 | 
		
	
		
			
			| 2559 | 2568 |  	assert ( i == 0 ); /* We don't handle partial failure at present */
 | 
		
	
		
			
			| 2560 | 2569 |   err_map_icm_aux:
 | 
		
	
		
			
			| 2561 | 2570 |  	hermon_cmd_unmap_icm_aux ( hermon );
 | 
		
	
		
			
			| 2562 |  | -	ufree ( hermon->icm );
 | 
		
	
		
			
			| 2563 |  | -	hermon->icm = UNULL;
 | 
		
	
		
			
			| 2564 | 2571 |   err_alloc:
 | 
		
	
		
			
			| 2565 | 2572 |   err_set_icm_size:
 | 
		
	
		
			
			| 2566 | 2573 |  	return rc;
 | 
		
	
		
			
			| 2567 | 2574 |  }
 | 
		
	
		
			
			| 2568 | 2575 |  
 | 
		
	
		
			
			| 2569 | 2576 |  /**
 | 
		
	
		
			
			| 2570 |  | - * Free ICM
 | 
		
	
		
			
			|  | 2577 | + * Unmap ICM
 | 
		
	
		
			
			| 2571 | 2578 |   *
 | 
		
	
		
			
			| 2572 | 2579 |   * @v hermon		Hermon device
 | 
		
	
		
			
			| 2573 | 2580 |   */
 | 
		
	
		
			
			| 2574 |  | -static void hermon_free_icm ( struct hermon *hermon ) {
 | 
		
	
		
			
			|  | 2581 | +static void hermon_unmap_icm ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 2575 | 2582 |  	struct hermonprm_scalar_parameter unmap_icm;
 | 
		
	
		
			
			| 2576 | 2583 |  	int i;
 | 
		
	
		
			
			| 2577 | 2584 |  
 | 
		
	
	
		
			
			|  | @@ -2587,13 +2594,11 @@ static void hermon_free_icm ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 2587 | 2594 |  				       &unmap_icm );
 | 
		
	
		
			
			| 2588 | 2595 |  	}
 | 
		
	
		
			
			| 2589 | 2596 |  	hermon_cmd_unmap_icm_aux ( hermon );
 | 
		
	
		
			
			| 2590 |  | -	ufree ( hermon->icm );
 | 
		
	
		
			
			| 2591 |  | -	hermon->icm = UNULL;
 | 
		
	
		
			
			| 2592 | 2597 |  }
 | 
		
	
		
			
			| 2593 | 2598 |  
 | 
		
	
		
			
			| 2594 | 2599 |  /***************************************************************************
 | 
		
	
		
			
			| 2595 | 2600 |   *
 | 
		
	
		
			
			| 2596 |  | - * Initialisation
 | 
		
	
		
			
			|  | 2601 | + * Initialisation and teardown
 | 
		
	
		
			
			| 2597 | 2602 |   *
 | 
		
	
		
			
			| 2598 | 2603 |   ***************************************************************************
 | 
		
	
		
			
			| 2599 | 2604 |   */
 | 
		
	
	
		
			
			|  | @@ -2602,19 +2607,22 @@ static void hermon_free_icm ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 2602 | 2607 |   * Reset device
 | 
		
	
		
			
			| 2603 | 2608 |   *
 | 
		
	
		
			
			| 2604 | 2609 |   * @v hermon		Hermon device
 | 
		
	
		
			
			| 2605 |  | - * @v pci		PCI device
 | 
		
	
		
			
			| 2606 | 2610 |   */
 | 
		
	
		
			
			| 2607 |  | -static void hermon_reset ( struct hermon *hermon,
 | 
		
	
		
			
			| 2608 |  | -			   struct pci_device *pci ) {
 | 
		
	
		
			
			|  | 2611 | +static void hermon_reset ( struct hermon *hermon ) {
 | 
		
	
		
			
			|  | 2612 | +	struct pci_device *pci = hermon->pci;
 | 
		
	
		
			
			| 2609 | 2613 |  	struct pci_config_backup backup;
 | 
		
	
		
			
			| 2610 | 2614 |  	static const uint8_t backup_exclude[] =
 | 
		
	
		
			
			| 2611 | 2615 |  		PCI_CONFIG_BACKUP_EXCLUDE ( 0x58, 0x5c );
 | 
		
	
		
			
			| 2612 | 2616 |  
 | 
		
	
		
			
			|  | 2617 | +	/* Perform device reset and preserve PCI configuration */
 | 
		
	
		
			
			| 2613 | 2618 |  	pci_backup ( pci, &backup, backup_exclude );
 | 
		
	
		
			
			| 2614 | 2619 |  	writel ( HERMON_RESET_MAGIC,
 | 
		
	
		
			
			| 2615 | 2620 |  		 ( hermon->config + HERMON_RESET_OFFSET ) );
 | 
		
	
		
			
			| 2616 | 2621 |  	mdelay ( HERMON_RESET_WAIT_TIME_MS );
 | 
		
	
		
			
			| 2617 | 2622 |  	pci_restore ( pci, &backup, backup_exclude );
 | 
		
	
		
			
			|  | 2623 | +
 | 
		
	
		
			
			|  | 2624 | +	/* Reset command interface toggle */
 | 
		
	
		
			
			|  | 2625 | +	hermon->toggle = 0;
 | 
		
	
		
			
			| 2618 | 2626 |  }
 | 
		
	
		
			
			| 2619 | 2627 |  
 | 
		
	
		
			
			| 2620 | 2628 |  /**
 | 
		
	
	
		
			
			|  | @@ -2686,6 +2694,118 @@ static int hermon_configure_special_qps ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 2686 | 2694 |  	return 0;
 | 
		
	
		
			
			| 2687 | 2695 |  }
 | 
		
	
		
			
			| 2688 | 2696 |  
 | 
		
	
		
			
			|  | 2697 | +/**
 | 
		
	
		
			
			|  | 2698 | + * Start Hermon device
 | 
		
	
		
			
			|  | 2699 | + *
 | 
		
	
		
			
			|  | 2700 | + * @v hermon		Hermon device
 | 
		
	
		
			
			|  | 2701 | + * @v running		Firmware is already running
 | 
		
	
		
			
			|  | 2702 | + * @ret rc		Return status code
 | 
		
	
		
			
			|  | 2703 | + */
 | 
		
	
		
			
			|  | 2704 | +static int hermon_start ( struct hermon *hermon, int running ) {
 | 
		
	
		
			
			|  | 2705 | +	struct hermonprm_init_hca init_hca;
 | 
		
	
		
			
			|  | 2706 | +	unsigned int i;
 | 
		
	
		
			
			|  | 2707 | +	int rc;
 | 
		
	
		
			
			|  | 2708 | +
 | 
		
	
		
			
			|  | 2709 | +	/* Start firmware if not already running */
 | 
		
	
		
			
			|  | 2710 | +	if ( ! running ) {
 | 
		
	
		
			
			|  | 2711 | +		if ( ( rc = hermon_start_firmware ( hermon ) ) != 0 )
 | 
		
	
		
			
			|  | 2712 | +			goto err_start_firmware;
 | 
		
	
		
			
			|  | 2713 | +	}
 | 
		
	
		
			
			|  | 2714 | +
 | 
		
	
		
			
			|  | 2715 | +	/* Allocate and map ICM */
 | 
		
	
		
			
			|  | 2716 | +	memset ( &init_hca, 0, sizeof ( init_hca ) );
 | 
		
	
		
			
			|  | 2717 | +	if ( ( rc = hermon_map_icm ( hermon, &init_hca ) ) != 0 )
 | 
		
	
		
			
			|  | 2718 | +		goto err_map_icm;
 | 
		
	
		
			
			|  | 2719 | +
 | 
		
	
		
			
			|  | 2720 | +	/* Initialise HCA */
 | 
		
	
		
			
			|  | 2721 | +	MLX_FILL_1 ( &init_hca, 0, version, 0x02 /* "Must be 0x02" */ );
 | 
		
	
		
			
			|  | 2722 | +	MLX_FILL_1 ( &init_hca, 5, udp, 1 );
 | 
		
	
		
			
			|  | 2723 | +	MLX_FILL_1 ( &init_hca, 74, uar_parameters.log_max_uars, 8 );
 | 
		
	
		
			
			|  | 2724 | +	if ( ( rc = hermon_cmd_init_hca ( hermon, &init_hca ) ) != 0 ) {
 | 
		
	
		
			
			|  | 2725 | +		DBGC ( hermon, "Hermon %p could not initialise HCA: %s\n",
 | 
		
	
		
			
			|  | 2726 | +		       hermon, strerror ( rc ) );
 | 
		
	
		
			
			|  | 2727 | +		goto err_init_hca;
 | 
		
	
		
			
			|  | 2728 | +	}
 | 
		
	
		
			
			|  | 2729 | +
 | 
		
	
		
			
			|  | 2730 | +	/* Set up memory protection */
 | 
		
	
		
			
			|  | 2731 | +	if ( ( rc = hermon_setup_mpt ( hermon ) ) != 0 )
 | 
		
	
		
			
			|  | 2732 | +		goto err_setup_mpt;
 | 
		
	
		
			
			|  | 2733 | +	for ( i = 0 ; i < hermon->cap.num_ports ; i++ )
 | 
		
	
		
			
			|  | 2734 | +		hermon->port[i].ibdev->rdma_key = hermon->lkey;
 | 
		
	
		
			
			|  | 2735 | +
 | 
		
	
		
			
			|  | 2736 | +	/* Set up event queue */
 | 
		
	
		
			
			|  | 2737 | +	if ( ( rc = hermon_create_eq ( hermon ) ) != 0 )
 | 
		
	
		
			
			|  | 2738 | +		goto err_create_eq;
 | 
		
	
		
			
			|  | 2739 | +
 | 
		
	
		
			
			|  | 2740 | +	/* Configure special QPs */
 | 
		
	
		
			
			|  | 2741 | +	if ( ( rc = hermon_configure_special_qps ( hermon ) ) != 0 )
 | 
		
	
		
			
			|  | 2742 | +		goto err_conf_special_qps;
 | 
		
	
		
			
			|  | 2743 | +
 | 
		
	
		
			
			|  | 2744 | +	return 0;
 | 
		
	
		
			
			|  | 2745 | +
 | 
		
	
		
			
			|  | 2746 | + err_conf_special_qps:
 | 
		
	
		
			
			|  | 2747 | +	hermon_destroy_eq ( hermon );
 | 
		
	
		
			
			|  | 2748 | + err_create_eq:
 | 
		
	
		
			
			|  | 2749 | + err_setup_mpt:
 | 
		
	
		
			
			|  | 2750 | +	hermon_cmd_close_hca ( hermon );
 | 
		
	
		
			
			|  | 2751 | + err_init_hca:
 | 
		
	
		
			
			|  | 2752 | +	hermon_unmap_icm ( hermon );
 | 
		
	
		
			
			|  | 2753 | + err_map_icm:
 | 
		
	
		
			
			|  | 2754 | +	hermon_stop_firmware ( hermon );
 | 
		
	
		
			
			|  | 2755 | + err_start_firmware:
 | 
		
	
		
			
			|  | 2756 | +	return rc;
 | 
		
	
		
			
			|  | 2757 | +}
 | 
		
	
		
			
			|  | 2758 | +
 | 
		
	
		
			
			|  | 2759 | +/**
 | 
		
	
		
			
			|  | 2760 | + * Stop Hermon device
 | 
		
	
		
			
			|  | 2761 | + *
 | 
		
	
		
			
			|  | 2762 | + * @v hermon		Hermon device
 | 
		
	
		
			
			|  | 2763 | + */
 | 
		
	
		
			
			|  | 2764 | +static void hermon_stop ( struct hermon *hermon ) {
 | 
		
	
		
			
			|  | 2765 | +	hermon_destroy_eq ( hermon );
 | 
		
	
		
			
			|  | 2766 | +	hermon_cmd_close_hca ( hermon );
 | 
		
	
		
			
			|  | 2767 | +	hermon_unmap_icm ( hermon );
 | 
		
	
		
			
			|  | 2768 | +	hermon_stop_firmware ( hermon );
 | 
		
	
		
			
			|  | 2769 | +	hermon_reset ( hermon );
 | 
		
	
		
			
			|  | 2770 | +}
 | 
		
	
		
			
			|  | 2771 | +
 | 
		
	
		
			
			|  | 2772 | +/**
 | 
		
	
		
			
			|  | 2773 | + * Open Hermon device
 | 
		
	
		
			
			|  | 2774 | + *
 | 
		
	
		
			
			|  | 2775 | + * @v hermon		Hermon device
 | 
		
	
		
			
			|  | 2776 | + * @ret rc		Return status code
 | 
		
	
		
			
			|  | 2777 | + */
 | 
		
	
		
			
			|  | 2778 | +static int hermon_open ( struct hermon *hermon ) {
 | 
		
	
		
			
			|  | 2779 | +	int rc;
 | 
		
	
		
			
			|  | 2780 | +
 | 
		
	
		
			
			|  | 2781 | +	/* Start device if applicable */
 | 
		
	
		
			
			|  | 2782 | +	if ( hermon->open_count == 0 ) {
 | 
		
	
		
			
			|  | 2783 | +		if ( ( rc = hermon_start ( hermon, 0 ) ) != 0 )
 | 
		
	
		
			
			|  | 2784 | +			return rc;
 | 
		
	
		
			
			|  | 2785 | +	}
 | 
		
	
		
			
			|  | 2786 | +
 | 
		
	
		
			
			|  | 2787 | +	/* Increment open counter */
 | 
		
	
		
			
			|  | 2788 | +	hermon->open_count++;
 | 
		
	
		
			
			|  | 2789 | +
 | 
		
	
		
			
			|  | 2790 | +	return 0;
 | 
		
	
		
			
			|  | 2791 | +}
 | 
		
	
		
			
			|  | 2792 | +
 | 
		
	
		
			
			|  | 2793 | +/**
 | 
		
	
		
			
			|  | 2794 | + * Close Hermon device
 | 
		
	
		
			
			|  | 2795 | + *
 | 
		
	
		
			
			|  | 2796 | + * @v hermon		Hermon device
 | 
		
	
		
			
			|  | 2797 | + */
 | 
		
	
		
			
			|  | 2798 | +static void hermon_close ( struct hermon *hermon ) {
 | 
		
	
		
			
			|  | 2799 | +
 | 
		
	
		
			
			|  | 2800 | +	/* Decrement open counter */
 | 
		
	
		
			
			|  | 2801 | +	assert ( hermon->open_count != 0 );
 | 
		
	
		
			
			|  | 2802 | +	hermon->open_count--;
 | 
		
	
		
			
			|  | 2803 | +
 | 
		
	
		
			
			|  | 2804 | +	/* Stop device if applicable */
 | 
		
	
		
			
			|  | 2805 | +	if ( hermon->open_count == 0 )
 | 
		
	
		
			
			|  | 2806 | +		hermon_stop ( hermon );
 | 
		
	
		
			
			|  | 2807 | +}
 | 
		
	
		
			
			|  | 2808 | +
 | 
		
	
		
			
			| 2689 | 2809 |  /***************************************************************************
 | 
		
	
		
			
			| 2690 | 2810 |   *
 | 
		
	
		
			
			| 2691 | 2811 |   * Infiniband link-layer operations
 | 
		
	
	
		
			
			|  | @@ -2699,11 +2819,15 @@ static int hermon_configure_special_qps ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 2699 | 2819 |   * @v ibdev		Infiniband device
 | 
		
	
		
			
			| 2700 | 2820 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 2701 | 2821 |   */
 | 
		
	
		
			
			| 2702 |  | -static int hermon_open ( struct ib_device *ibdev ) {
 | 
		
	
		
			
			|  | 2822 | +static int hermon_ib_open ( struct ib_device *ibdev ) {
 | 
		
	
		
			
			| 2703 | 2823 |  	struct hermon *hermon = ib_get_drvdata ( ibdev );
 | 
		
	
		
			
			| 2704 | 2824 |  	union hermonprm_set_port set_port;
 | 
		
	
		
			
			| 2705 | 2825 |  	int rc;
 | 
		
	
		
			
			| 2706 | 2826 |  
 | 
		
	
		
			
			|  | 2827 | +	/* Open hardware */
 | 
		
	
		
			
			|  | 2828 | +	if ( ( rc = hermon_open ( hermon ) ) != 0 )
 | 
		
	
		
			
			|  | 2829 | +		goto err_open;
 | 
		
	
		
			
			|  | 2830 | +
 | 
		
	
		
			
			| 2707 | 2831 |  	/* Set port parameters */
 | 
		
	
		
			
			| 2708 | 2832 |  	memset ( &set_port, 0, sizeof ( set_port ) );
 | 
		
	
		
			
			| 2709 | 2833 |  	MLX_FILL_8 ( &set_port.ib, 0,
 | 
		
	
	
		
			
			|  | @@ -2724,20 +2848,26 @@ static int hermon_open ( struct ib_device *ibdev ) {
 | 
		
	
		
			
			| 2724 | 2848 |  					  &set_port ) ) != 0 ) {
 | 
		
	
		
			
			| 2725 | 2849 |  		DBGC ( hermon, "Hermon %p port %d could not set port: %s\n",
 | 
		
	
		
			
			| 2726 | 2850 |  		       hermon, ibdev->port, strerror ( rc ) );
 | 
		
	
		
			
			| 2727 |  | -		return rc;
 | 
		
	
		
			
			|  | 2851 | +		goto err_set_port;
 | 
		
	
		
			
			| 2728 | 2852 |  	}
 | 
		
	
		
			
			| 2729 | 2853 |  
 | 
		
	
		
			
			| 2730 | 2854 |  	/* Initialise port */
 | 
		
	
		
			
			| 2731 | 2855 |  	if ( ( rc = hermon_cmd_init_port ( hermon, ibdev->port ) ) != 0 ) {
 | 
		
	
		
			
			| 2732 | 2856 |  		DBGC ( hermon, "Hermon %p port %d could not initialise port: "
 | 
		
	
		
			
			| 2733 | 2857 |  		       "%s\n", hermon, ibdev->port, strerror ( rc ) );
 | 
		
	
		
			
			| 2734 |  | -		return rc;
 | 
		
	
		
			
			|  | 2858 | +		goto err_init_port;
 | 
		
	
		
			
			| 2735 | 2859 |  	}
 | 
		
	
		
			
			| 2736 | 2860 |  
 | 
		
	
		
			
			| 2737 | 2861 |  	/* Update MAD parameters */
 | 
		
	
		
			
			| 2738 | 2862 |  	ib_smc_update ( ibdev, hermon_mad );
 | 
		
	
		
			
			| 2739 | 2863 |  
 | 
		
	
		
			
			| 2740 | 2864 |  	return 0;
 | 
		
	
		
			
			|  | 2865 | +
 | 
		
	
		
			
			|  | 2866 | + err_init_port:
 | 
		
	
		
			
			|  | 2867 | + err_set_port:
 | 
		
	
		
			
			|  | 2868 | +	hermon_close ( hermon );
 | 
		
	
		
			
			|  | 2869 | + err_open:
 | 
		
	
		
			
			|  | 2870 | +	return rc;
 | 
		
	
		
			
			| 2741 | 2871 |  }
 | 
		
	
		
			
			| 2742 | 2872 |  
 | 
		
	
		
			
			| 2743 | 2873 |  /**
 | 
		
	
	
		
			
			|  | @@ -2745,15 +2875,19 @@ static int hermon_open ( struct ib_device *ibdev ) {
 | 
		
	
		
			
			| 2745 | 2875 |   *
 | 
		
	
		
			
			| 2746 | 2876 |   * @v ibdev		Infiniband device
 | 
		
	
		
			
			| 2747 | 2877 |   */
 | 
		
	
		
			
			| 2748 |  | -static void hermon_close ( struct ib_device *ibdev ) {
 | 
		
	
		
			
			|  | 2878 | +static void hermon_ib_close ( struct ib_device *ibdev ) {
 | 
		
	
		
			
			| 2749 | 2879 |  	struct hermon *hermon = ib_get_drvdata ( ibdev );
 | 
		
	
		
			
			| 2750 | 2880 |  	int rc;
 | 
		
	
		
			
			| 2751 | 2881 |  
 | 
		
	
		
			
			|  | 2882 | +	/* Close port */
 | 
		
	
		
			
			| 2752 | 2883 |  	if ( ( rc = hermon_cmd_close_port ( hermon, ibdev->port ) ) != 0 ) {
 | 
		
	
		
			
			| 2753 | 2884 |  		DBGC ( hermon, "Hermon %p port %d could not close port: %s\n",
 | 
		
	
		
			
			| 2754 | 2885 |  		       hermon, ibdev->port, strerror ( rc ) );
 | 
		
	
		
			
			| 2755 | 2886 |  		/* Nothing we can do about this */
 | 
		
	
		
			
			| 2756 | 2887 |  	}
 | 
		
	
		
			
			|  | 2888 | +
 | 
		
	
		
			
			|  | 2889 | +	/* Close hardware */
 | 
		
	
		
			
			|  | 2890 | +	hermon_close ( hermon );
 | 
		
	
		
			
			| 2757 | 2891 |  }
 | 
		
	
		
			
			| 2758 | 2892 |  
 | 
		
	
		
			
			| 2759 | 2893 |  /**
 | 
		
	
	
		
			
			|  | @@ -2883,8 +3017,8 @@ static struct ib_device_operations hermon_ib_operations = {
 | 
		
	
		
			
			| 2883 | 3017 |  	.post_recv	= hermon_post_recv,
 | 
		
	
		
			
			| 2884 | 3018 |  	.poll_cq	= hermon_poll_cq,
 | 
		
	
		
			
			| 2885 | 3019 |  	.poll_eq	= hermon_poll_eq,
 | 
		
	
		
			
			| 2886 |  | -	.open		= hermon_open,
 | 
		
	
		
			
			| 2887 |  | -	.close		= hermon_close,
 | 
		
	
		
			
			|  | 3020 | +	.open		= hermon_ib_open,
 | 
		
	
		
			
			|  | 3021 | +	.close		= hermon_ib_close,
 | 
		
	
		
			
			| 2888 | 3022 |  	.mcast_attach	= hermon_mcast_attach,
 | 
		
	
		
			
			| 2889 | 3023 |  	.mcast_detach	= hermon_mcast_detach,
 | 
		
	
		
			
			| 2890 | 3024 |  	.set_port_info	= hermon_inform_sma,
 | 
		
	
	
		
			
			|  | @@ -3073,6 +3207,10 @@ static int hermon_eth_open ( struct net_device *netdev ) {
 | 
		
	
		
			
			| 3073 | 3207 |  	union hermonprm_set_port set_port;
 | 
		
	
		
			
			| 3074 | 3208 |  	int rc;
 | 
		
	
		
			
			| 3075 | 3209 |  
 | 
		
	
		
			
			|  | 3210 | +	/* Open hardware */
 | 
		
	
		
			
			|  | 3211 | +	if ( ( rc = hermon_open ( hermon ) ) != 0 )
 | 
		
	
		
			
			|  | 3212 | +		goto err_open;
 | 
		
	
		
			
			|  | 3213 | +
 | 
		
	
		
			
			| 3076 | 3214 |  	/* Allocate completion queue */
 | 
		
	
		
			
			| 3077 | 3215 |  	port->eth_cq = ib_create_cq ( ibdev, HERMON_ETH_NUM_CQES,
 | 
		
	
		
			
			| 3078 | 3216 |  				      &hermon_eth_cq_op );
 | 
		
	
	
		
			
			|  | @@ -3167,6 +3305,8 @@ static int hermon_eth_open ( struct net_device *netdev ) {
 | 
		
	
		
			
			| 3167 | 3305 |   err_create_qp:
 | 
		
	
		
			
			| 3168 | 3306 |  	ib_destroy_cq ( ibdev, port->eth_cq );
 | 
		
	
		
			
			| 3169 | 3307 |   err_create_cq:
 | 
		
	
		
			
			|  | 3308 | +	hermon_close ( hermon );
 | 
		
	
		
			
			|  | 3309 | + err_open:
 | 
		
	
		
			
			| 3170 | 3310 |  	return rc;
 | 
		
	
		
			
			| 3171 | 3311 |  }
 | 
		
	
		
			
			| 3172 | 3312 |  
 | 
		
	
	
		
			
			|  | @@ -3191,6 +3331,9 @@ static void hermon_eth_close ( struct net_device *netdev ) {
 | 
		
	
		
			
			| 3191 | 3331 |  	/* Tear down the queues */
 | 
		
	
		
			
			| 3192 | 3332 |  	ib_destroy_qp ( ibdev, port->eth_qp );
 | 
		
	
		
			
			| 3193 | 3333 |  	ib_destroy_cq ( ibdev, port->eth_cq );
 | 
		
	
		
			
			|  | 3334 | +
 | 
		
	
		
			
			|  | 3335 | +	/* Close hardware */
 | 
		
	
		
			
			|  | 3336 | +	hermon_close ( hermon );
 | 
		
	
		
			
			| 3194 | 3337 |  }
 | 
		
	
		
			
			| 3195 | 3338 |  
 | 
		
	
		
			
			| 3196 | 3339 |  /** Hermon Ethernet network device operations */
 | 
		
	
	
		
			
			|  | @@ -3562,6 +3705,8 @@ static struct hermon * hermon_alloc ( void ) {
 | 
		
	
		
			
			| 3562 | 3705 |   */
 | 
		
	
		
			
			| 3563 | 3706 |  static void hermon_free ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 3564 | 3707 |  
 | 
		
	
		
			
			|  | 3708 | +	ufree ( hermon->icm );
 | 
		
	
		
			
			|  | 3709 | +	ufree ( hermon->firmware_area );
 | 
		
	
		
			
			| 3565 | 3710 |  	free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
 | 
		
	
		
			
			| 3566 | 3711 |  	free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
 | 
		
	
		
			
			| 3567 | 3712 |  	free ( hermon );
 | 
		
	
	
		
			
			|  | @@ -3571,9 +3716,9 @@ static void hermon_free ( struct hermon *hermon ) {
 | 
		
	
		
			
			| 3571 | 3716 |   * Initialise Hermon PCI parameters
 | 
		
	
		
			
			| 3572 | 3717 |   *
 | 
		
	
		
			
			| 3573 | 3718 |   * @v hermon		Hermon device
 | 
		
	
		
			
			| 3574 |  | - * @v pci		PCI device
 | 
		
	
		
			
			| 3575 | 3719 |   */
 | 
		
	
		
			
			| 3576 |  | -static void hermon_pci_init ( struct hermon *hermon, struct pci_device *pci ) {
 | 
		
	
		
			
			|  | 3720 | +static void hermon_pci_init ( struct hermon *hermon ) {
 | 
		
	
		
			
			|  | 3721 | +	struct pci_device *pci = hermon->pci;
 | 
		
	
		
			
			| 3577 | 3722 |  
 | 
		
	
		
			
			| 3578 | 3723 |  	/* Fix up PCI device */
 | 
		
	
		
			
			| 3579 | 3724 |  	adjust_pci_device ( pci );
 | 
		
	
	
		
			
			|  | @@ -3597,7 +3742,6 @@ static int hermon_probe ( struct pci_device *pci ) {
 | 
		
	
		
			
			| 3597 | 3742 |  	struct ib_device *ibdev;
 | 
		
	
		
			
			| 3598 | 3743 |  	struct net_device *netdev;
 | 
		
	
		
			
			| 3599 | 3744 |  	struct hermon_port *port;
 | 
		
	
		
			
			| 3600 |  | -	struct hermonprm_init_hca init_hca;
 | 
		
	
		
			
			| 3601 | 3745 |  	unsigned int i;
 | 
		
	
		
			
			| 3602 | 3746 |  	int rc;
 | 
		
	
		
			
			| 3603 | 3747 |  
 | 
		
	
	
		
			
			|  | @@ -3608,12 +3752,13 @@ static int hermon_probe ( struct pci_device *pci ) {
 | 
		
	
		
			
			| 3608 | 3752 |  		goto err_alloc;
 | 
		
	
		
			
			| 3609 | 3753 |  	}
 | 
		
	
		
			
			| 3610 | 3754 |  	pci_set_drvdata ( pci, hermon );
 | 
		
	
		
			
			|  | 3755 | +	hermon->pci = pci;
 | 
		
	
		
			
			| 3611 | 3756 |  
 | 
		
	
		
			
			| 3612 | 3757 |  	/* Initialise PCI parameters */
 | 
		
	
		
			
			| 3613 |  | -	hermon_pci_init ( hermon, pci );
 | 
		
	
		
			
			|  | 3758 | +	hermon_pci_init ( hermon );
 | 
		
	
		
			
			| 3614 | 3759 |  
 | 
		
	
		
			
			| 3615 | 3760 |  	/* Reset device */
 | 
		
	
		
			
			| 3616 |  | -	hermon_reset ( hermon, pci );
 | 
		
	
		
			
			|  | 3761 | +	hermon_reset ( hermon );
 | 
		
	
		
			
			| 3617 | 3762 |  
 | 
		
	
		
			
			| 3618 | 3763 |  	/* Start firmware */
 | 
		
	
		
			
			| 3619 | 3764 |  	if ( ( rc = hermon_start_firmware ( hermon ) ) != 0 )
 | 
		
	
	
		
			
			|  | @@ -3650,34 +3795,9 @@ static int hermon_probe ( struct pci_device *pci ) {
 | 
		
	
		
			
			| 3650 | 3795 |  		netdev->priv = &hermon->port[i];
 | 
		
	
		
			
			| 3651 | 3796 |  	}
 | 
		
	
		
			
			| 3652 | 3797 |  
 | 
		
	
		
			
			| 3653 |  | -	/* Allocate ICM */
 | 
		
	
		
			
			| 3654 |  | -	memset ( &init_hca, 0, sizeof ( init_hca ) );
 | 
		
	
		
			
			| 3655 |  | -	if ( ( rc = hermon_alloc_icm ( hermon, &init_hca ) ) != 0 )
 | 
		
	
		
			
			| 3656 |  | -		goto err_alloc_icm;
 | 
		
	
		
			
			| 3657 |  | -
 | 
		
	
		
			
			| 3658 |  | -	/* Initialise HCA */
 | 
		
	
		
			
			| 3659 |  | -	MLX_FILL_1 ( &init_hca, 0, version, 0x02 /* "Must be 0x02" */ );
 | 
		
	
		
			
			| 3660 |  | -	MLX_FILL_1 ( &init_hca, 5, udp, 1 );
 | 
		
	
		
			
			| 3661 |  | -	MLX_FILL_1 ( &init_hca, 74, uar_parameters.log_max_uars, 8 );
 | 
		
	
		
			
			| 3662 |  | -	if ( ( rc = hermon_cmd_init_hca ( hermon, &init_hca ) ) != 0 ) {
 | 
		
	
		
			
			| 3663 |  | -		DBGC ( hermon, "Hermon %p could not initialise HCA: %s\n",
 | 
		
	
		
			
			| 3664 |  | -		       hermon, strerror ( rc ) );
 | 
		
	
		
			
			| 3665 |  | -		goto err_init_hca;
 | 
		
	
		
			
			| 3666 |  | -	}
 | 
		
	
		
			
			| 3667 |  | -
 | 
		
	
		
			
			| 3668 |  | -	/* Set up memory protection */
 | 
		
	
		
			
			| 3669 |  | -	if ( ( rc = hermon_setup_mpt ( hermon ) ) != 0 )
 | 
		
	
		
			
			| 3670 |  | -		goto err_setup_mpt;
 | 
		
	
		
			
			| 3671 |  | -	for ( i = 0 ; i < hermon->cap.num_ports ; i++ )
 | 
		
	
		
			
			| 3672 |  | -		hermon->port[i].ibdev->rdma_key = hermon->lkey;
 | 
		
	
		
			
			| 3673 |  | -
 | 
		
	
		
			
			| 3674 |  | -	/* Set up event queue */
 | 
		
	
		
			
			| 3675 |  | -	if ( ( rc = hermon_create_eq ( hermon ) ) != 0 )
 | 
		
	
		
			
			| 3676 |  | -		goto err_create_eq;
 | 
		
	
		
			
			| 3677 |  | -
 | 
		
	
		
			
			| 3678 |  | -	/* Configure special QPs */
 | 
		
	
		
			
			| 3679 |  | -	if ( ( rc = hermon_configure_special_qps ( hermon ) ) != 0 )
 | 
		
	
		
			
			| 3680 |  | -		goto err_conf_special_qps;
 | 
		
	
		
			
			|  | 3798 | +	/* Start device */
 | 
		
	
		
			
			|  | 3799 | +	if ( ( rc = hermon_start ( hermon, 1 ) ) != 0 )
 | 
		
	
		
			
			|  | 3800 | +		goto err_start;
 | 
		
	
		
			
			| 3681 | 3801 |  
 | 
		
	
		
			
			| 3682 | 3802 |  	/* Determine port types */
 | 
		
	
		
			
			| 3683 | 3803 |  	for ( i = 0 ; i < hermon->cap.num_ports ; i++ ) {
 | 
		
	
	
		
			
			|  | @@ -3693,6 +3813,10 @@ static int hermon_probe ( struct pci_device *pci ) {
 | 
		
	
		
			
			| 3693 | 3813 |  			goto err_register;
 | 
		
	
		
			
			| 3694 | 3814 |  	}
 | 
		
	
		
			
			| 3695 | 3815 |  
 | 
		
	
		
			
			|  | 3816 | +	/* Leave device quiescent until opened */
 | 
		
	
		
			
			|  | 3817 | +	if ( hermon->open_count == 0 )
 | 
		
	
		
			
			|  | 3818 | +		hermon_stop ( hermon );
 | 
		
	
		
			
			|  | 3819 | +
 | 
		
	
		
			
			| 3696 | 3820 |  	return 0;
 | 
		
	
		
			
			| 3697 | 3821 |  
 | 
		
	
		
			
			| 3698 | 3822 |  	i = hermon->cap.num_ports;
 | 
		
	
	
		
			
			|  | @@ -3702,14 +3826,8 @@ static int hermon_probe ( struct pci_device *pci ) {
 | 
		
	
		
			
			| 3702 | 3826 |  		port->type->unregister_dev ( hermon, port );
 | 
		
	
		
			
			| 3703 | 3827 |  	}
 | 
		
	
		
			
			| 3704 | 3828 |   err_set_port_type:
 | 
		
	
		
			
			| 3705 |  | - err_conf_special_qps:
 | 
		
	
		
			
			| 3706 |  | -	hermon_destroy_eq ( hermon );
 | 
		
	
		
			
			| 3707 |  | - err_create_eq:
 | 
		
	
		
			
			| 3708 |  | - err_setup_mpt:
 | 
		
	
		
			
			| 3709 |  | -	hermon_cmd_close_hca ( hermon );
 | 
		
	
		
			
			| 3710 |  | - err_init_hca:
 | 
		
	
		
			
			| 3711 |  | -	hermon_free_icm ( hermon );
 | 
		
	
		
			
			| 3712 |  | - err_alloc_icm:
 | 
		
	
		
			
			|  | 3829 | +	hermon_stop ( hermon );
 | 
		
	
		
			
			|  | 3830 | + err_start:
 | 
		
	
		
			
			| 3713 | 3831 |  	i = hermon->cap.num_ports;
 | 
		
	
		
			
			| 3714 | 3832 |   err_alloc_netdev:
 | 
		
	
		
			
			| 3715 | 3833 |  	for ( i-- ; ( signed int ) i >= 0 ; i-- ) {
 | 
		
	
	
		
			
			|  | @@ -3742,10 +3860,6 @@ static void hermon_remove ( struct pci_device *pci ) {
 | 
		
	
		
			
			| 3742 | 3860 |  		port = &hermon->port[i];
 | 
		
	
		
			
			| 3743 | 3861 |  		port->type->unregister_dev ( hermon, port );
 | 
		
	
		
			
			| 3744 | 3862 |  	}
 | 
		
	
		
			
			| 3745 |  | -	hermon_destroy_eq ( hermon );
 | 
		
	
		
			
			| 3746 |  | -	hermon_cmd_close_hca ( hermon );
 | 
		
	
		
			
			| 3747 |  | -	hermon_free_icm ( hermon );
 | 
		
	
		
			
			| 3748 |  | -	hermon_stop_firmware ( hermon );
 | 
		
	
		
			
			| 3749 | 3863 |  	for ( i = ( hermon->cap.num_ports - 1 ) ; i >= 0 ; i-- ) {
 | 
		
	
		
			
			| 3750 | 3864 |  		netdev_nullify ( hermon->port[i].netdev );
 | 
		
	
		
			
			| 3751 | 3865 |  		netdev_put ( hermon->port[i].netdev );
 | 
		
	
	
		
			
			|  | @@ -3773,9 +3887,10 @@ static int hermon_bofm_probe ( struct pci_device *pci ) {
 | 
		
	
		
			
			| 3773 | 3887 |  		goto err_alloc;
 | 
		
	
		
			
			| 3774 | 3888 |  	}
 | 
		
	
		
			
			| 3775 | 3889 |  	pci_set_drvdata ( pci, hermon );
 | 
		
	
		
			
			|  | 3890 | +	hermon->pci = pci;
 | 
		
	
		
			
			| 3776 | 3891 |  
 | 
		
	
		
			
			| 3777 | 3892 |  	/* Initialise PCI parameters */
 | 
		
	
		
			
			| 3778 |  | -	hermon_pci_init ( hermon, pci );
 | 
		
	
		
			
			|  | 3893 | +	hermon_pci_init ( hermon );
 | 
		
	
		
			
			| 3779 | 3894 |  
 | 
		
	
		
			
			| 3780 | 3895 |  	/* Initialise BOFM device */
 | 
		
	
		
			
			| 3781 | 3896 |  	bofm_init ( &hermon->bofm, pci, &hermon_bofm_operations );
 |