/*
 * Celestica Seastone2 and Questone2 FPGA Port Management Definitions
 *
 * Copyright (c) 2019 Cumulus Networks, Inc.  All rights reserved.
 *
 */

#ifndef CEL_SEA2QUE2_H__
#define CEL_SEA2QUE2_H__

/*******************************************************************************
 *
 *                              Useful Macros
 *
 *  These macros provide field and bit maniplation.
 *
 ******************************************************************************/

/**
 *  @brief Retrieve the value of a field in a register. This doesn't actually
 *         access the hardware, it merely isolates and shifts a value to extract
 *         a field.
 *  @param [in] _reg The register value which contains the _field
 *  @param [in] _field The name of the field, from the constants, below, without
 *         the trailing _LSB or _MSB.
 *  @return The value of the field
 */
#define GET_FIELD(_reg, _field) \
	(((_reg) & GENMASK(_field##_MSB, _field##_LSB)) >> _field##_LSB)

/**
 *  @brief Set the value of a field in a register. This doesn't actually access
 *         the hardware, it merely isolates and shifts a field within a value to
 *         place that field within the value.
 *  @param [in] _reg The register value which contains the _field
 *  @param [in] _field The name of the field, from the constants, below, without
 *         the trailing _LSB or _MSB.
 *  @param [in] _val The value of the field to place within the register.
 *  @return The new register value with the modified field value
 */
#define PUT_FIELD(_reg, _field, _val) \
	(((_reg) & ~GENMASK(_field##_MSB, _field##_LSB)) | \
	 ((_val) << _field##_LSB))

/**
 *  @brief Get the width of a field in a register.
 *  @param [in] _field The name of the field, from the constants, below, without
 *         the trailing _LSB or _MSB.
 *  @return The number of bits in the field
 */
#define FIELD_WIDTH(_field) \
	(_field##_MSB - _field##_LSB + 1)

/**
 *  @brief Get the value of a bit in a register. Very similar to #GET_FIELD
 *         except it operates on only one bit.
 *  @param [in] _reg The register value which contains the _bit
 *  @param [in] _bit The name of the bit field, from the constants, below,
 *         without the trailing _BIT.
 *  @return The of the bit field
 */
#define GET_BIT(_reg, _bit) \
	(((_reg) >> _bit##_BIT) & 1)

/**
 *  @brief Put the value of a bit in a register. Very similar to #PUT_FIELD
 *         except it operates on only one bit.
 *  @param [in] _reg The register value which contains the _bit
 *  @param [in] _bit The name of the bit field, from the constants, below,
 *         without the trailing _BIT.
 *  @param [in] _val The value of the bit. Any non-zero value is 1.
 *  @return The new register value with the modified bit field value
 */
#define PUT_BIT(_reg, _bit, _val) \
	(((_reg) & ~(1 << _bit##_BIT)) | ((!!(_val)) << _bit##_BIT))

/*******************************************************************************
 *
 *                     Celestica FPGA Register Definitions
 *
 *  These register definitions are taken from the Seastone2 & Questone2 FPGA
 *  Design Specification, Revision: 0.6, dated May 23, 2018.
 *
 ******************************************************************************/

/*------------------------------------------------------------------------------
 *
 *                         PORT XCVR Registers
 *                           0x4000 - 0x4FFF
 *
 *----------------------------------------------------------------------------*/

#define CEL_SEA2QUE2_PORT_CTRL_REG                        0x0000
  #define CEL_SEA2QUE2_PORT_CTRL_LPMOD_BIT                6
  #define CEL_SEA2QUE2_PORT_CTRL_RST_BIT                  4
  #define CEL_SEA2QUE2_PORT_CTRL_TX_DIS_BIT               0

#define CEL_SEA2QUE2_PORT_STAT_REG                        0x0004
  #define CEL_SEA2QUE2_PORT_STAT_IRQ_BIT                  5
  #define CEL_SEA2QUE2_PORT_STAT_PRESENT_BIT              4
  #define CEL_SEA2QUE2_PORT_STAT_TXFAULT_BIT              2
  #define CEL_SEA2QUE2_PORT_STAT_RXLOS_BIT                1
  #define CEL_SEA2QUE2_PORT_STAT_MODABS_BIT               0

#endif /* CEL_SEA2QUE2_H__ */

