text: /*
  ** Copyright 2005-2019  Solarflare Communications Inc.
  **                      7505 Irvine Center Drive, Irvine, CA 92618, USA
  ** Copyright 2002-2005  Level 5 Networks Inc.
  **
  ** This program is free software; you can redistribute it and/or modify it
  ** under the terms of version 2 of the GNU General Public License as
  ** published by the Free Software Foundation.
  **
  ** This program is distributed in the hope that it will be useful,
  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  ** GNU General Public License for more details.
  */
  
  /****************************************************************************
   * Driver for Solarflare network controllers -
   *          resource management for Xen backend, OpenOnload, etc
   *           (including support for SFE4001 10GBT NIC)
   *
   * This file provides helpers to turn bit shifts into dword shifts and
   * check that the bit fields haven't overflown the dword etc.
   *
   * Copyright 2005-2008: Solarflare Communications Inc,
   *                      9501 Jeronimo Road, Suite 250,
   *                      Irvine, CA 92618, USA
   *
   * Developed and maintained by Solarflare Communications:
   *                      <linux-xen-drivers@solarflare.com>
   *                      <onload-dev@solarflare.com>
   *
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 as published
   * by the Free Software Foundation, incorporated herein by reference.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   ****************************************************************************
   */
  
  #ifndef __CI_EFHW_CHECK_H__
  #define __CI_EFHW_CHECK_H__
  
  /*----------------------------------------------------------------------------
   *
   * Helpers to turn bit shifts into dword shifts and check that the bit fields
   * haven't overflown the dword etc. Aim is to preserve consistency with the
   * autogenerated headers - once stable we could hard code.
   *
   *---------------------------------------------------------------------------*/
  
  /* mask constructors */
  #define __FALCON_MASK(WIDTH, T)	((((T)1) << (WIDTH)) - 1)
  #define __FALCON_MASK32(WIDTH)	__FALCON_MASK((WIDTH), uint32_t)
  #define __FALCON_MASK64(WIDTH)	__FALCON_MASK((WIDTH), uint64_t)
  
  #define __FALCON_MASKFIELD32(LBN, WIDTH) \
  	((uint32_t)(__FALCON_MASK32(WIDTH) << (LBN)))
  
  
  /* constructors for fields within one DWORD */
  #define __DW2(LBN)		((LBN) - 32)
  #define __DW3(LBN)		((LBN) - 64)
  #define __DW4(LBN)		((LBN) - 96)
  
  
  /* width for lower portion of field spanning DWORDs */
  #define __LW(LBN)		(32 - LBN) /* 0 -> 1 */
  #define __LW2(LBN)		(64 - LBN) /* 1 -> 2 */
  #define __LW3(LBN)		(96 - LBN) /* 2 -> 3 */
  
  
  /* constructors for lower portion of field spanning DWORDs */
  #define __LOW(v, F) \
  	((uint32_t)(((v) & __FALCON_MASK64(__LW(F##_LBN))) << (F##_LBN)))
  #define __LOW2(v, F) \
          ((uint32_t)(((v) & __FALCON_MASK64(__LW2(F##_LBN))) << __DW2(F##_LBN)))
  #define __LOW3(v, F) \
  	((uint32_t)(((v) & __FALCON_MASK64(__LW3(F##_LBN))) << __DW3(F##_LBN)))
  
  /* constructors for upper portion of field spanning DWORDs */
  #define __HIGH(v, F) \
  	((uint32_t)(((v) >> __LW(F##_LBN)) & \
  		    __FALCON_MASK64((F##_WIDTH - __LW(F##_LBN)))))
  #define __HIGH2(v, F) \
  	((uint32_t)(((v) >> __LW2((F##_LBN))) & \
  		    __FALCON_MASK64((F##_WIDTH - __LW2((F##_LBN))))))
  #define __HIGH3(v, F) \
  	((unit32_t)(((v) >> __LW3((F##_LBN))) & \
  		     __FALCON_MASK64((F##_WIDTH - __LW3((F##_LBN))))))
  
  
  /* checks that the autogenerated headers are consistent with our model */
  #define __RANGECHCK(v, WIDTH) \
  	EFHW_ASSERT(((uint64_t)(v) & ~(__FALCON_MASK64((WIDTH)))) == 0)
  
  
  /* check field width if field within a DWORD */
  #define __DWCHCK(F) \
  	EFHW_BUILD_ASSERT(((F##_LBN) >= 0)  && (((F##_LBN)+(F##_WIDTH)) <= 32))
  #define __DW2CHCK(F) \
  	EFHW_BUILD_ASSERT(((F##_LBN) >= 32) && (((F##_LBN)+(F##_WIDTH)) <= 64))
  #define __DW3CHCK(F) \
  	EFHW_BUILD_ASSERT(((F##_LBN) >= 64) && (((F##_LBN)+(F##_WIDTH)) <= 96))
  #define __DW4CHCK(F) \
  	EFHW_BUILD_ASSERT(((F##_LBN) >= 96) && (((F##_LBN)+(F##_WIDTH)) <= 128))
  
  
  /* check field width if field spans a DWORD */
  #define __LWCHK(F)	EFHW_BUILD_ASSERT(F##_WIDTH >= __LW(F##_LBN))
  #define __LW2CHK(F)	EFHW_BUILD_ASSERT(F##_WIDTH >= __LW2(F##_LBN))
  #define __LW3CHK(F)	EFHW_BUILD_ASSERT(F##_WIDTH >= __LW3(F##_LBN))
  
  
  /* fields in the first qword */
  #define __QWCHCK(F) \
  	EFHW_BUILD_ASSERT(((F##_LBN) >= 0) && (((F##_LBN)+(F##_WIDTH)) <= 64))
  
  #endif /* __CI_EFHW_CHECK_H__ */
  