[Openib-windows] RE: Handling LionCub Rev. C HCAs

Leonid Keller leonid at mellanox.co.il
Sun Mar 26 10:42:38 PST 2006


Looks fine, but I did't test it.
If you saw it working on both types of flashes you may commit it.

> -----Original Message-----
> From: Fab Tillier [mailto:ftillier at silverstorm.com] 
> Sent: Thursday, March 23, 2006 3:31 AM
> To: Leonid Keller
> Cc: openib-windows at openib.org
> Subject: Handling LionCub Rev. C HCAs
> 
> Hi Leonid,
> 
> The following patch enables LionCub Rev C HCAs to be used 
> with the mt23108 driver.  The Flash sector size is 128K on 
> these, rather than the "standard" 64K.
> The patch updates the driver to determine the Flash sector 
> size dynamically, rather than using a hard coded value.
> 
> The driver tries to read the GUIDs from the Flash, and would 
> fail loading if it couldn't find it.
> 
> Let me know if I can commit this.
> 
> Thanks,
> 
> - Fab
> 
> Index: hw/mt23108/kernel/hca_driver.c
> ===================================================================
> --- hw/mt23108/kernel/hca_driver.c	(revision 249)
> +++ hw/mt23108/kernel/hca_driver.c	(working copy)
> @@ -914,6 +914,7 @@
>  	NTSTATUS			status;
>  	hca_dev_ext_t		*p_ext;
>  	net64_t				ca_guid = 0;
> +
>  	HCA_ENTER( HCA_DBG_PNP );
>  
>  	/* Handled on the way up. */
> @@ -1260,7 +1261,10 @@
>  
> NULL,
>  
> &event,
>  
> &ioStatus );
> -	if (p_irp == NULL) {
> +	if (p_irp == NULL)
> +	{
> +		HCA_TRACE( HCA_DBG_ERROR,
> +			("IoBuildSynchronousFsdRequest failed.\n") );
>  		status = STATUS_INSUFFICIENT_RESOURCES;
>  		goto End;
>  	}
> @@ -1473,9 +1477,9 @@
>  	NTSTATUS		status = STATUS_SUCCESS;
>  	BUS_INTERFACE_STANDARD		BusInterface;
>  
> -    uint32_t NODE_GUIDH, NODE_GUIDL;
> +	uint32_t NODE_GUIDH, NODE_GUIDL;
>  	uint32_t prim_ptr = 0;
> -    uint32_t signature;
> +	uint32_t signature, offset, sect_size;
>  
>  	primary_sector_t	ps;
>  	cl_memset( &ps, 0, sizeof(primary_sector_t)); @@ 
> -1487,39 +1491,67 @@
>  	
>  	status = fw_flash_init (&BusInterface);
>  	if (status != STATUS_SUCCESS )
> -		return status;
> -    status = fw_flash_read_data(&BusInterface, &signature, 0x24, 4); 
> +		goto err1;
> +
> +	status = fw_flash_read_data(&BusInterface, &signature, 
> FW_SIG_OFFSET,
> 4);
>  	if (status != STATUS_SUCCESS )
> -		return status;
> -    //signature = cl_ntoh32(signature);
> +		goto err2;
>  
> -    if (signature == FW_SIGNATURE)
> -    {
> -       //Fail Safe image
> -        
> -        // Assume flash has been verified, and both images 
> have the same guids,
> therefore,
> -        // we only need to read the primary image's guids
> -        status = fw_flash_readbuf(&BusInterface, FW_SECT_SIZE, &ps,
> sizeof(ps));
> -		if ( status == STATUS_SUCCESS )
> +	if (signature == FW_SIGNATURE)
> +	{
> +		//Fail Safe image
> +
> +		/* Find the sector size offset. */
> +		status = fw_flash_read_data(
> +			&BusInterface, &offset, FW_SECT_PTR_OFFSET, 4 );
> +		if( status != STATUS_SUCCESS )
> +			goto err2;
> +
> +		offset &= 0x0000FFFF;
> +
> +		status = fw_flash_read_data(
> +			&BusInterface, &sect_size, 
> FW_SECT_OFFSET + offset, 4 );
> +		if( status != STATUS_SUCCESS )
> +			goto err2;
> +
> +		sect_size = 1 << (sect_size & 0x0000FFFF);
> +
> +		/* Try to read the GUIDs from the primary image. */
> +		status = fw_flash_readbuf(&BusInterface, sect_size, &ps,
> sizeof(ps));
> +		if ( status == STATUS_SUCCESS && ps.signature 
> != FW_SIGNATURE )
>  		{
> +			/* Hmm, that didn't work.  Try the 
> secondary image. */
> +			status = fw_flash_readbuf(
> +				&BusInterface, sect_size * 2, 
> &ps, sizeof(ps) );
> +		}
> +		if( status == STATUS_SUCCESS )
> +		{
> +			signature = ps.signature;
>  			status = 
> fw_flash_read_data(&BusInterface, &prim_ptr, ps.fi_addr+0x24, 4);
>  			if (status == STATUS_SUCCESS )
>  				prim_ptr = prim_ptr + ps.fi_addr;
>  		}
> -    }
> -    else
> -    {
> -        // Short image
> -        prim_ptr = signature;       
> -    }
> +		else
> +		{
> +			signature = 0;
> +		}
> +	}
> +	else
> +	{
> +		// Short image
> +		HCA_TRACE( HCA_DBG_ERROR,
> +			("Invalid signature %08x, assuming 
> short image.\n",
> signature) );
> +		prim_ptr = signature;       
> +		signature = FW_SIGNATURE;
> +	}
>  
> -    if ( signature == FW_SIGNATURE || prim_ptr < MAX_FLASH_SIZE )
> -    {
> +	if ( signature == FW_SIGNATURE && prim_ptr < MAX_FLASH_SIZE )
> +	{
>  		/* now we can read ca guid
>  		 * since we read it in host mode fw_flash_read4() 
>  		 * swaps it back in BE - how it was stored in FW
>  		 */
> -        if (( status = fw_flash_read4(&BusInterface, 
> prim_ptr, &NODE_GUIDL)) ==
> STATUS_SUCCESS )
> +		if (( status = fw_flash_read4(&BusInterface, prim_ptr,
> &NODE_GUIDL)) == STATUS_SUCCESS )
>  			if (( status = 
> fw_flash_read4(&BusInterface, prim_ptr+4,
> &NODE_GUIDH)) == STATUS_SUCCESS )
>  			{
>  				*ca_guid = NODE_GUIDH;
> @@ -1527,13 +1559,15 @@
>  			}
>  	}
>  	else 
> -    {
> -        //invalid GUID pointer
> -        return STATUS_NO_SUCH_DEVICE;
> -    }
> +	{
> +		//invalid GUID pointer
> +		status = STATUS_NO_SUCH_DEVICE;
> +	}
> +err2:
>  	fw_flash_deinit(&BusInterface);
> +err1:
>  	BusInterface.InterfaceDereference((PVOID)BusInterface.Context);
> -    return status;
> +	return status;
>  }
>  
>  static NTSTATUS
> @@ -1548,14 +1582,20 @@
>  	static uint32_t curr_bank =	0xffffffff;
>  
>  	if (addr & 0x3)
> +	{
> +		HCA_TRACE( HCA_DBG_ERROR, ("Invalid address 
> %08x\n", addr) );
>  		return STATUS_INVALID_PARAMETER;
> +	}
>  
>  	bank = addr & BANK_MASK;
>  	if (bank !=  curr_bank)
>  	{
>  		curr_bank = bank;
>  		if ((status = fw_set_bank(p_BusInterface, 
> bank)) != STATUS_SUCCESS )
> +		{
> +			HCA_TRACE( HCA_DBG_ERROR, ("fw_set_bank returned
> %08x\n", status) );
>  			return STATUS_INVALID_PARAMETER;
> +		}
>  	}
>  	status = fw_flash_read_data(p_BusInterface, &lcl_data, addr, 4);
>  	*p_data = cl_ntoh32(lcl_data);
> @@ -1576,11 +1616,13 @@
>      if (offset & 0x3)
>      {
>          //Address should be 4-bytes aligned
> +		HCA_TRACE( HCA_DBG_ERROR, ("Invalid address 
> %08x\n", offset) );
>          return STATUS_INVALID_PARAMETER;
>      }
>      if (len & 0x3)
>      {
>          //Length should be 4-bytes aligned
> +		HCA_TRACE( HCA_DBG_ERROR, ("Invalid length 
> %d\n", len) );
>          return STATUS_INVALID_PARAMETER;
>      }
>      p_lcl_data = (uint32_t *)p_data;
> Index: hw/mt23108/kernel/hca_driver.h
> ===================================================================
> --- hw/mt23108/kernel/hca_driver.h	(revision 249)
> +++ hw/mt23108/kernel/hca_driver.h	(working copy)
> @@ -138,6 +138,11 @@
>  #define FW_CLOSE_IF		0x7e
>  
>  #define FW_SIGNATURE		(0x5a445a44)
> -#define FW_SECT_SIZE		(0x10000)
> +#define FW_SIG_OFFSET		(0x24)
>  
> +#define FW_SECT_PTR_OFFSET	(0x14)
> +/* The real offset is 0x32, but we're reading DWORDS at a 
> time, so we align */
> +#define FW_SECT_OFFSET		(0x30)
> +
> +
>  #endif	/* !defined( _HCA_DRIVER_H_ ) */
> 



More information about the ofw mailing list