mirror of
https://github.com/Telecominfraproject/oopt-tai-implementations.git
synced 2025-10-29 17:22:39 +00:00
Contribute AC400 TAI Adapter Code
This commit provides the AC400 TAI adapter code. This code was previously open sourced in the Cumulus Network's github organization. This commit moves the code over to the TIP organization. See the README.md file in the tai_ac400 directory for more information.
This commit is contained in:
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "tai_ac400/oopt-tai"]
|
||||
path = tai_ac400/oopt-tai
|
||||
url = https://github.com/Telecominfraproject/oopt-tai.git
|
||||
24
README.md
24
README.md
@@ -1 +1,23 @@
|
||||
# oopt-tai-implementations
|
||||
# oopt-tai-implementations
|
||||
|
||||
This repo contains implementations of the Transponder Abstraction Interface, or
|
||||
TAI, which have been contributed to the Telecom Infrastructure Project, or TIP.
|
||||
|
||||
In summary, TAI is a user-mode device driver interface for transponder modules
|
||||
based upon the Switch Abstraction Interface, or SAI, of the Open Compute
|
||||
Project, or OCP. Although it is not required that the device drivers be
|
||||
open-sourced, some vendors have opened up their code for the benefit of the
|
||||
community.
|
||||
|
||||
Each open sourced component is in a sub-directory of this repo. See the
|
||||
README.md file in each subdirectory for more information about the component and
|
||||
build instructions. The repo currently contains the following components:
|
||||
|
||||
* tai_ac400 - The TAI adapter code for the Acacia AC400 module
|
||||
|
||||
For more information about:
|
||||
* TAI: https://github.com/Telecominfraproject/oopt-tai
|
||||
* TIP: https://telecominfraproject.com/
|
||||
* SAI: https://github.com/opencomputeproject/SAI
|
||||
* OCP: https://www.opencompute.org/
|
||||
|
||||
|
||||
18
tai_ac400/.gitignore
vendored
Normal file
18
tai_ac400/.gitignore
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config/
|
||||
configure
|
||||
libtool
|
||||
src/.deps/
|
||||
src/.libs/
|
||||
src/Makefile
|
||||
src/Makefile.in
|
||||
src/*.lo
|
||||
src/libtai.la
|
||||
stamp-h1
|
||||
2422
tai_ac400/Doxyfile
Normal file
2422
tai_ac400/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
30
tai_ac400/LICENSE
Normal file
30
tai_ac400/LICENSE
Normal file
@@ -0,0 +1,30 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
|
||||
Copyright (C) 2018 Cumulus Networks, Inc. All rights reserved
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
11
tai_ac400/Makefile.am
Normal file
11
tai_ac400/Makefile.am
Normal file
@@ -0,0 +1,11 @@
|
||||
# Makefile.am -- Process this file with automake to produce Makefile.in
|
||||
|
||||
# note that order matters: make the lib first then use it
|
||||
|
||||
SUBDIRS = src
|
||||
DIST_SUBDIRS = src
|
||||
|
||||
.PHONY: doc
|
||||
|
||||
doc:
|
||||
doxygen Doxyfile
|
||||
18
tai_ac400/README.md
Normal file
18
tai_ac400/README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
AC400 TAI implementation
|
||||
============================
|
||||
|
||||
This folder contains the TAI adapter implementation for the Acacia AC400
|
||||
transponder.
|
||||
|
||||
After cloning this project, it can be built with:
|
||||
1. git submodule init
|
||||
2. git submodule update
|
||||
3. ./autogen.sh
|
||||
4. ./configure --enable-debug --prefix=/usr
|
||||
5. make
|
||||
|
||||
The output result is a TAI library, called libtai
|
||||
User applications can then link with this library, in order to use the TAI AC400 implementation.
|
||||
|
||||
More information about TAI is available here: https://github.com/Telecominfraproject/oopt-tai
|
||||
|
||||
8
tai_ac400/autoclean.sh
Executable file
8
tai_ac400/autoclean.sh
Executable file
@@ -0,0 +1,8 @@
|
||||
rm -rf aclocal.m4 autom4te.cache stamp-h1 libtool configure config.* Makefile.in Makefile
|
||||
rm -rf config/*
|
||||
|
||||
for a in src
|
||||
do
|
||||
rm -rf $a/Makefile 2>&1
|
||||
rm -rf $a/Makefile.in 2>&1
|
||||
done
|
||||
75
tai_ac400/autogen.sh
Executable file
75
tai_ac400/autogen.sh
Executable file
@@ -0,0 +1,75 @@
|
||||
#!/bin/bash
|
||||
|
||||
# get two strings of version numbers
|
||||
# parse the two strings and compare
|
||||
function compare_versions() {
|
||||
cat <<EOF > /tmp/$$.awk
|
||||
/[0-9]+\.[0-9]+(\.[0-9]+)?[ ]+[0-9]+\.[0-9]+(\.[0-9]+)?/{
|
||||
vb = "$2";
|
||||
nb = split(vb,b,"[.]");
|
||||
va = "$1";
|
||||
na = split(va,a,"[.]");
|
||||
for (i = na + 1; i < 4; i++) {
|
||||
a[i] = 0;
|
||||
}
|
||||
for (i = nb + 1; i < 4; i++) {
|
||||
b[i] = 0;
|
||||
}
|
||||
for (i = 1; i <= 3; i++) {
|
||||
if (b[i] < a[i]) {
|
||||
# print "FAIL:" va ">" vb " at index:" i;
|
||||
exit(1);
|
||||
} else if (b[i] > a[i]) {
|
||||
# print "OK:" va "<" vb " at index:" i;
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
# print "OK:" va "==" vb;
|
||||
exit(0);
|
||||
}
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
EOF
|
||||
echo "$1 $2 " | awk -f /tmp/$$.awk
|
||||
status=$?
|
||||
rm /tmp/$$.awk
|
||||
return $status
|
||||
}
|
||||
|
||||
cd ${0%*/*}
|
||||
|
||||
# clean old autogen files
|
||||
./autoclean.sh
|
||||
|
||||
# make sure autoconf is up-to-date
|
||||
ac_ver=`autoconf --version | head -n 1 | awk '{print $NF}'`
|
||||
compare_versions 2.59 $ac_ver
|
||||
if test $? = 1; then
|
||||
echo Min autoconf version is 2.59
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# make sure automake is up-to-date
|
||||
am_ver=`automake --version | head -n 1 | awk '{print $NF}'`
|
||||
compare_versions 1.9.2 $am_ver
|
||||
if test $? = 1; then
|
||||
echo Min automake version is 1.9.2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# make sure libtool is up-to-date
|
||||
lt_ver=`libtoolize --version | head -n 1 | awk '{print $4}'`
|
||||
compare_versions 2.4.2 $lt_ver
|
||||
if test $? = 1; then
|
||||
echo Min libtool version is 2.4.2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# handle our own autoconf:
|
||||
echo Visiting `pwd`
|
||||
aclocal -I config 2>&1 | grep -v "Warning: underquoted definition of"
|
||||
libtoolize --force --copy
|
||||
autoheader
|
||||
automake --add-missing --foreign --copy --force
|
||||
autoconf
|
||||
59
tai_ac400/configure.ac
Normal file
59
tai_ac400/configure.ac
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT([ac400_tai], [1.0.0000])
|
||||
AC_CONFIG_SRCDIR([])
|
||||
|
||||
dnl use local config dir for extras
|
||||
AC_CONFIG_AUX_DIR(config)
|
||||
|
||||
dnl we use auto cheader
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl Defines the Language - we need gcc linker ...
|
||||
AC_LANG_C
|
||||
|
||||
dnl Auto make
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
dnl Provides control over re-making of all auto files
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
dnl Required for cases make defines a MAKE=make ??? Why
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_CC
|
||||
|
||||
dnl We will use libtool for making ...
|
||||
#AC_PROG_LIBTOOL
|
||||
LT_INIT([shared disable-static])
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([sys/types.h stdio.h stdlib.h string.h])
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_HEADER_STDBOOL
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
|
||||
dnl Checks for library functions.
|
||||
#AC_CHECK_FUNCS([strchr strstr strtol strtoull regcomp regexec])
|
||||
|
||||
dnl Define an input config option to control debug compile
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug Turn on debugging],
|
||||
[case "${enableval}" in
|
||||
yes) debug=true ;;
|
||||
no) debug=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
|
||||
esac],[debug=false])
|
||||
AM_CONDITIONAL(DEBUG, test x$debug = xtrue)
|
||||
|
||||
CFLAGS_TAI_INTERFACE_COMMON="-Wall -Wswitch -Wunused -Werror -fPIC -fno-strict-aliasing -Wextra -Wunused -Wno-unused-parameter"
|
||||
AC_SUBST(CFLAGS_TAI_INTERFACE_COMMON)
|
||||
|
||||
dnl Create the following Makefiles
|
||||
AC_OUTPUT([Makefile src/Makefile])
|
||||
610
tai_ac400/inc/ac400.h
Normal file
610
tai_ac400/inc/ac400.h
Normal file
@@ -0,0 +1,610 @@
|
||||
/**
|
||||
* @file ac400.h
|
||||
* @brief Acacia AC400 register and field definitions
|
||||
* @author Scott Emery <scotte@cumulusnetworks.com>
|
||||
*
|
||||
* @copyright Copyright (C) 2018 Cumulus Networks, Inc. All rights reserved
|
||||
*
|
||||
* @remark This source code is licensed under the BSD 3-Clause license found in
|
||||
* the LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#ifndef AC400_H__
|
||||
#define AC400_H__
|
||||
|
||||
#define GENMASK(h, l) \
|
||||
(((~0UL) << (l)) & (~0UL >> (sizeof(long)*8 - 1 - (h))))
|
||||
|
||||
/**
|
||||
* @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, e.g. AC400_EXT_MOD_ID_LANE_RATIO_TYPE.
|
||||
* @return The value of the field
|
||||
*/
|
||||
#define AC400_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, e.g. AC400_EXT_MOD_ID_LANE_RATIO_TYPE.
|
||||
* @param [in] _val The value of the field to place within the register.
|
||||
* @return The new register value with the modified field value
|
||||
*/
|
||||
#define AC400_PUT_FIELD(_reg, _field, _val) \
|
||||
(((_reg) & ~GENMASK(_field##_MSB, _field##_LSB)) | ((_val) << _field##_LSB))
|
||||
|
||||
/**
|
||||
* @brief Get the value of a bit in a register. Very similar to
|
||||
* #AC400_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, e.g. AC400_EXT_MOD_ID_CLE_PRESENCE.
|
||||
* @return The of the bit field
|
||||
*/
|
||||
#define AC400_GET_BIT(_reg, _bit) \
|
||||
(((_reg) >> _bit##_BIT) & 1)
|
||||
|
||||
/**
|
||||
* @brief Put the value of a bit in a register. Very similar to
|
||||
* #AC400_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, e.g. AC400_EXT_MOD_ID_CLE_PRESENCE.
|
||||
* @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 AC400_PUT_BIT(_reg, _bit, _val) \
|
||||
(((_reg) & ~(1 << _bit##_BIT)) | ((!!(_val)) << _bit##_BIT))
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
AC400 Regsiter Definitions
|
||||
|
||||
These register definitions are taken from the Acacia 400G Telecom Infra
|
||||
Project Contribution, v1.0, October 27, 2016, Doc #100-0144-00.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
|
||||
NVR 1. Basic ID Registers
|
||||
0x8000 - 0x807F
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
#define AC400_VEND_NAME_BYTE_1_REG 0x8021
|
||||
#define AC400_VEND_NAME_BYTE_2_REG 0x8022
|
||||
#define AC400_VEND_NAME_BYTE_3_REG 0x8023
|
||||
#define AC400_VEND_NAME_BYTE_4_REG 0x8024
|
||||
#define AC400_VEND_NAME_BYTE_5_REG 0x8025
|
||||
#define AC400_VEND_NAME_BYTE_6_REG 0x8026
|
||||
#define AC400_VEND_NAME_BYTE_7_REG 0x8027
|
||||
#define AC400_VEND_NAME_BYTE_8_REG 0x8028
|
||||
#define AC400_VEND_NAME_BYTE_9_REG 0x8029
|
||||
#define AC400_VEND_NAME_BYTE_10_REG 0x802A
|
||||
#define AC400_VEND_NAME_BYTE_11_REG 0x802B
|
||||
#define AC400_VEND_NAME_BYTE_12_REG 0x802C
|
||||
#define AC400_VEND_NAME_BYTE_13_REG 0x802D
|
||||
#define AC400_VEND_NAME_BYTE_14_REG 0x802E
|
||||
#define AC400_VEND_NAME_BYTE_15_REG 0x802F
|
||||
#define AC400_VEND_NAME_BYTE_16_REG 0x8030
|
||||
|
||||
#define AC400_VEND_PN_BYTE_1_REG 0x8034
|
||||
#define AC400_VEND_PN_BYTE_2_REG 0x8035
|
||||
#define AC400_VEND_PN_BYTE_3_REG 0x8036
|
||||
#define AC400_VEND_PN_BYTE_4_REG 0x8037
|
||||
#define AC400_VEND_PN_BYTE_5_REG 0x8038
|
||||
#define AC400_VEND_PN_BYTE_6_REG 0x8039
|
||||
#define AC400_VEND_PN_BYTE_7_REG 0x803A
|
||||
#define AC400_VEND_PN_BYTE_8_REG 0x803B
|
||||
#define AC400_VEND_PN_BYTE_9_REG 0x803C
|
||||
#define AC400_VEND_PN_BYTE_10_REG 0x803D
|
||||
#define AC400_VEND_PN_BYTE_11_REG 0x803E
|
||||
#define AC400_VEND_PN_BYTE_12_REG 0x803F
|
||||
#define AC400_VEND_PN_BYTE_13_REG 0x8040
|
||||
#define AC400_VEND_PN_BYTE_14_REG 0x8041
|
||||
#define AC400_VEND_PN_BYTE_15_REG 0x8042
|
||||
#define AC400_VEND_PN_BYTE_16_REG 0x8043
|
||||
|
||||
#define AC400_VEND_SN_BYTE_1_REG 0x8044
|
||||
#define AC400_VEND_SN_BYTE_2_REG 0x8045
|
||||
#define AC400_VEND_SN_BYTE_3_REG 0x8046
|
||||
#define AC400_VEND_SN_BYTE_4_REG 0x8047
|
||||
#define AC400_VEND_SN_BYTE_5_REG 0x8048
|
||||
#define AC400_VEND_SN_BYTE_6_REG 0x8049
|
||||
#define AC400_VEND_SN_BYTE_7_REG 0x804A
|
||||
#define AC400_VEND_SN_BYTE_8_REG 0x804B
|
||||
#define AC400_VEND_SN_BYTE_9_REG 0x804C
|
||||
#define AC400_VEND_SN_BYTE_10_REG 0x804D
|
||||
#define AC400_VEND_SN_BYTE_11_REG 0x804E
|
||||
#define AC400_VEND_SN_BYTE_12_REG 0x804F
|
||||
#define AC400_VEND_SN_BYTE_13_REG 0x8050
|
||||
#define AC400_VEND_SN_BYTE_14_REG 0x8051
|
||||
#define AC400_VEND_SN_BYTE_15_REG 0x8052
|
||||
#define AC400_VEND_SN_BYTE_16_REG 0x8053
|
||||
|
||||
#define AC400_FIRM_A_VER_NUM_X_REG 0x806C
|
||||
#define AC400_FIRM_A_VER_NUM_Y_REG 0x806D
|
||||
|
||||
#define AC400_FIRM_B_VER_NUM_X_REG 0x807B
|
||||
#define AC400_FIRM_B_VER_NUM_Y_REG 0x807C
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
|
||||
NVR 4. MSA-100GLH Extended ID Registers
|
||||
0x8180 - 0x81FF
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
#define AC400_TX_RX_MIN_LASER_FREQ_1_MSB_REG 0x818A
|
||||
#define AC400_TX_RX_MIN_LASER_FREQ_1_LSB_REG 0x818B
|
||||
|
||||
#define AC400_TX_RX_MIN_LASER_FREQ_2_MSB_REG 0x818C
|
||||
#define AC400_TX_RX_MIN_LASER_FREQ_2_LSB_REG 0x818D
|
||||
|
||||
#define AC400_TX_RX_MAX_LASER_FREQ_1_MSB_REG 0x818E
|
||||
#define AC400_TX_RX_MAX_LASER_FREQ_1_LSB_REG 0x818F
|
||||
|
||||
#define AC400_TX_RX_MAX_LASER_FREQ_2_MSB_REG 0x8190
|
||||
#define AC400_TX_RX_MAX_LASER_FREQ_2_LSB_REG 0x8191
|
||||
|
||||
#define AC400_TX_LASER_FTF_RANGE_MSB_REG 0x8194
|
||||
#define AC400_TX_LASER_FTF_RANGE_LSB_REG 0x8195
|
||||
|
||||
#define AC400_LASER_TUNE_CAP_MSB_REG 0x8196
|
||||
# define AC400_LASER_TUNE_CAP_MSB_GRID_SPACING_6P25_GHZ_BIT 7
|
||||
# define AC400_LASER_TUNE_CAP_MSB_GRID_SPACING_12P5_GHZ_BIT 6
|
||||
# define AC400_LASER_TUNE_CAP_MSB_GRID_SPACING_25_GHZ_BIT 5
|
||||
# define AC400_LASER_TUNE_CAP_MSB_GRID_SPACING_33_GHZ_BIT 4
|
||||
# define AC400_LASER_TUNE_CAP_MSB_GRID_SPACING_50_GHZ_BIT 3
|
||||
# define AC400_LASER_TUNE_CAP_MSB_GRID_SPACING_100_GHZ_BIT 2
|
||||
# define AC400_LASER_TUNE_CAP_MSB_MAX_CHANS_BITS_9_TO_8_MSB 1
|
||||
# define AC400_LASER_TUNE_CAP_MSB_MAX_CHANS_BITS_9_TO_8_LSB 0
|
||||
|
||||
#define AC400_LASER_TUNE_CAP_LSB_REG 0x8197
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
|
||||
MSA-100GLH VR1. Command/Setup/Control/FAWS Registers
|
||||
0xB000 - 0xB07F
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
#define AC400_MOD_STATE_REG 0xB016
|
||||
# define AC400_MOD_STATE_HI_PWR_DWN_BIT 8
|
||||
# define AC400_MOD_STATE_TX_TURN_OFF_BIT 7
|
||||
# define AC400_MOD_STATE_FAULT_BIT 6
|
||||
# define AC400_MOD_STATE_READY_BIT 5
|
||||
# define AC400_MOD_STATE_TX_TURN_ON_BIT 4
|
||||
# define AC400_MOD_STATE_TX_OFF_BIT 3
|
||||
# define AC400_MOD_STATE_HI_PWR_UP_BIT 2
|
||||
# define AC400_MOD_STATE_LOW_PWR_BIT 1
|
||||
# define AC400_MOD_STATE_INIT_BIT 0
|
||||
|
||||
#define AC400_GLB_ALRM_SUM_REG 0xB018
|
||||
# define AC400_GLB_ALRM_SUM_GLB_ALRM_ASRT_STAT_BIT 15
|
||||
# define AC400_GLB_ALRM_SUM_HOST_LANE_FLT_STAT_SUM_BIT 14
|
||||
# define AC400_GLB_ALRM_SUM_NTWK_LANE_FLT_STAT_SUM_BIT 13
|
||||
# define AC400_GLB_ALRM_SUM_NTWK_LANE_ALRM_WARN_1_SUM_BIT 12
|
||||
# define AC400_GLB_ALRM_SUM_MOD_ALRM_WARN_1_SUM_BIT 10
|
||||
# define AC400_GLB_ALRM_SUM_MOD_FLT_SUM_BIT 9
|
||||
# define AC400_GLB_ALRM_SUM_MOD_GEN_STAT_SUM_BIT 8
|
||||
# define AC400_GLB_ALRM_SUM_MOD_STATE_SUM_BIT 7
|
||||
# define AC400_GLB_ALRM_SUM_NTWK_LANE_ALRM_WARN_2_SUM_BIT 6
|
||||
# define AC400_GLB_ALRM_SUM_NTWK_HOST_ALRM_STAT_SUM_BIT 5
|
||||
# define AC400_GLB_ALRM_SUM_MOD_EXT_FUNCS_STAT_SUM_BIT 4
|
||||
# define AC400_GLB_ALRM_SUM_VENDOR_SPFC_FAWS_SUM_BIT 3
|
||||
# define AC400_GLB_ALRM_SUM_SOFT_GLB_ALRM_TEST_STAT_BIT 0
|
||||
|
||||
#define AC400_MOD_FLT_STAT_REG 0xB01E
|
||||
# define AC400_MOD_FLT_STAT_MOD_TEMP_FLT_BIT 8
|
||||
# define AC400_MOD_FLT_STAT_SPFC_HW_FLT_BIT 7
|
||||
# define AC400_MOD_FLT_STAT_PLD_FLASH_INIT_FLT_BIT 6
|
||||
# define AC400_MOD_FLT_STAT_PS_FLT_BIT 5
|
||||
# define AC400_MOD_FLT_STAT_CHKSUM_FLT_BIT 1
|
||||
|
||||
#define AC400_MOD_ALRM_WARN_1_REG 0xB01F
|
||||
# define AC400_MOD_ALRM_WARN_1_TEMP_HI_ALRM_BIT 11
|
||||
# define AC400_MOD_ALRM_WARN_1_TEMP_HI_WARN_BIT 10
|
||||
# define AC400_MOD_ALRM_WARN_1_TEMP_LO_WARN_BIT 9
|
||||
# define AC400_MOD_ALRM_WARN_1_TEMP_LO_ALRM_BIT 8
|
||||
# define AC400_MOD_ALRM_WARN_1_VCC_HI_ALRM_BIT 7
|
||||
# define AC400_MOD_ALRM_WARN_1_VCC_HI_WARN_BIT 6
|
||||
# define AC400_MOD_ALRM_WARN_1_VCC_LO_WARN_BIT 5
|
||||
# define AC400_MOD_ALRM_WARN_1_VCC_LO_ALRM_BIT 4
|
||||
|
||||
#define AC400_TEMP_MON_A2D_VAL_REG 0xB02F
|
||||
|
||||
#define AC400_MOD_PS_MON_A2D_VAL_REG 0xB030
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
|
||||
MSA-100GLH VR2. Network Lane Control/Data Registers
|
||||
0xB300 - 0xB57F
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
#define AC400_NTWK_RX_CUR_IN_PWR_LN_0_REG 0xB4E0
|
||||
#define AC400_NTWK_RX_CUR_IN_PWR_LN_1_REG 0xB4E1
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
|
||||
MSA-100GLH VR1. Host Lane FAWS/Control/Status Registers
|
||||
0xB600 - 0xB6FF
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
#define AC400_HOST_FLT_STAT_LN_0_REG 0xB600
|
||||
#define AC400_HOST_FLT_STAT_LN_1_REG 0xB601
|
||||
#define AC400_HOST_FLT_STAT_LN_2_REG 0xB602
|
||||
#define AC400_HOST_FLT_STAT_LN_3_REG 0xB603
|
||||
#define AC400_HOST_FLT_STAT_LN_4_REG 0xB604
|
||||
#define AC400_HOST_FLT_STAT_LN_5_REG 0xB605
|
||||
#define AC400_HOST_FLT_STAT_LN_6_REG 0xB606
|
||||
#define AC400_HOST_FLT_STAT_LN_7_REG 0xB607
|
||||
#define AC400_HOST_FLT_STAT_LN_8_REG 0xB608
|
||||
#define AC400_HOST_FLT_STAT_LN_9_REG 0xB609
|
||||
#define AC400_HOST_FLT_STAT_LN_10_REG 0xB60A
|
||||
#define AC400_HOST_FLT_STAT_LN_11_REG 0xB60B
|
||||
#define AC400_HOST_FLT_STAT_LN_12_REG 0xB60C
|
||||
#define AC400_HOST_FLT_STAT_LN_13_REG 0xB60D
|
||||
#define AC400_HOST_FLT_STAT_LN_14_REG 0xB60E
|
||||
#define AC400_HOST_FLT_STAT_LN_15_REG 0xB60F
|
||||
# define AC400_HOST_FLT_STAT_LN_TX_HOST_LOL_BIT 0
|
||||
|
||||
#define AC400_HOST_PRBS_TX_ERR_CNT_LN_0_REG 0xB630
|
||||
#define AC400_HOST_PRBS_TX_ERR_CNT_LN_1_REG 0xB631
|
||||
#define AC400_HOST_PRBS_TX_ERR_CNT_LN_2_REG 0xB632
|
||||
#define AC400_HOST_PRBS_TX_ERR_CNT_LN_3_REG 0xB633
|
||||
#define AC400_HOST_PRBS_TX_ERR_CNT_LN_4_REG 0xB634
|
||||
#define AC400_HOST_PRBS_TX_ERR_CNT_LN_5_REG 0xB635
|
||||
#define AC400_HOST_PRBS_TX_ERR_CNT_LN_6_REG 0xB636
|
||||
#define AC400_HOST_PRBS_TX_ERR_CNT_LN_7_REG 0xB637
|
||||
#define AC400_HOST_PRBS_TX_ERR_CNT_LN_8_REG 0xB638
|
||||
#define AC400_HOST_PRBS_TX_ERR_CNT_LN_9_REG 0xB639
|
||||
#define AC400_HOST_PRBS_TX_ERR_CNT_LN_10_REG 0xB63A
|
||||
#define AC400_HOST_PRBS_TX_ERR_CNT_LN_11_REG 0xB63B
|
||||
#define AC400_HOST_PRBS_TX_ERR_CNT_LN_12_REG 0xB63C
|
||||
#define AC400_HOST_PRBS_TX_ERR_CNT_LN_13_REG 0xB63D
|
||||
#define AC400_HOST_PRBS_TX_ERR_CNT_LN_14_REG 0xB63E
|
||||
#define AC400_HOST_PRBS_TX_ERR_CNT_LN_15_REG 0xB63F
|
||||
# define AC400_HOST_PRBS_TX_ERR_CNT_LN_EXPONENT_MSB 15
|
||||
# define AC400_HOST_PRBS_TX_ERR_CNT_LN_EXPONENT_LSB 10
|
||||
# define AC400_HOST_PRBS_TX_ERR_CNT_LN_MANTISSA_MSB 9
|
||||
# define AC400_HOST_PRBS_TX_ERR_CNT_LN_MANTISSA_LSB 0
|
||||
|
||||
#define AC400_CLIENT_TX_ALGN_STAT_INTF_0_REG 0xB650
|
||||
#define AC400_CLIENT_TX_ALGN_STAT_INTF_1_REG 0xB651
|
||||
#define AC400_CLIENT_TX_ALGN_STAT_INTF_2_REG 0xB652
|
||||
#define AC400_CLIENT_TX_ALGN_STAT_INTF_3_REG 0xB653
|
||||
# define AC400_CLIENT_TX_ALGN_STAT_INTF_CDR_LOCK_FLT_BIT 15
|
||||
# define AC400_CLIENT_TX_ALGN_STAT_INTF_LOSS_OF_ALGN_BIT 14
|
||||
# define AC400_CLIENT_TX_ALGN_STAT_INTF_OUT_OF_ALGN_BIT 13
|
||||
# define AC400_CLIENT_TX_ALGN_STAT_INTF_DESKW_LCK_FLT_BIT 12
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
|
||||
AC400 Specific Management Interface (Vendor Private Use)
|
||||
0x9000 - 0x9FFF
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
#define AC400_NTWK_TX_TURN_UP_STATE_LN_0_REG 0x9110
|
||||
#define AC400_NTWK_TX_TURN_UP_STATE_LN_1_REG 0x9111
|
||||
# define AC400_NTWK_TX_TURN_UP_STATE_LN_TX_OUT_PWR_ADJ_BIT 5
|
||||
# define AC400_NTWK_TX_TURN_UP_STATE_LN_TX_MODULATOR_CONVERGE_BIT 4
|
||||
# define AC400_NTWK_TX_TURN_UP_STATE_LN_TX_LASER_READY_BIT 3
|
||||
# define AC400_NTWK_TX_TURN_UP_STATE_LN_TX_LAS_READY_OFF_BIT 2
|
||||
# define AC400_NTWK_TX_TURN_UP_STATE_LN_ASIC_TX_READY_BIT 1
|
||||
# define AC400_NTWK_TX_TURN_UP_STATE_LN_TX_INIT_BIT 0
|
||||
|
||||
#define AC400_NTWK_RX_TURN_UP_STATE_LN_0_REG 0x9118
|
||||
#define AC400_NTWK_RX_TURN_UP_STATE_LN_1_REG 0x9119
|
||||
# define AC400_NTWK_RX_TURN_UP_STATE_LN_RX_DEMOD_LOCK_BIT 5
|
||||
# define AC400_NTWK_RX_TURN_UP_STATE_LN_DISPERSION_LOCK_BIT 4
|
||||
# define AC400_NTWK_RX_TURN_UP_STATE_LN_ADC_OUTPUT_BIT 3
|
||||
# define AC400_NTWK_RX_TURN_UP_STATE_LN_OPTICAL_INPUT_BIT 2
|
||||
# define AC400_NTWK_RX_TURN_UP_STATE_LN_ASIC_RX_READY_BIT 1
|
||||
# define AC400_NTWK_RX_TURN_UP_STATE_LN_RX_INIT_BIT 0
|
||||
|
||||
#define AC400_NTWK_ALRM_WARN_1_LN_0_REG 0xB180
|
||||
#define AC400_NTWK_ALRM_WARN_1_LN_1_REG 0xB181
|
||||
# define AC400_NTWK_ALRM_WARN_1_LN_BIAS_HI_ALRM_BIT 15
|
||||
# define AC400_NTWK_ALRM_WARN_1_LN_BIAS_HI_WARN_BIT 14
|
||||
# define AC400_NTWK_ALRM_WARN_1_LN_BIAS_LO_WARN_BIT 13
|
||||
# define AC400_NTWK_ALRM_WARN_1_LN_BIAS_LO_ALRM_BIT 12
|
||||
# define AC400_NTWK_ALRM_WARN_1_LN_TX_PWR_HI_ALRM_BIT 11
|
||||
# define AC400_NTWK_ALRM_WARN_1_LN_TX_PWR_HI_WARN_BIT 10
|
||||
# define AC400_NTWK_ALRM_WARN_1_LN_TX_PWR_LO_WARN_BIT 9
|
||||
# define AC400_NTWK_ALRM_WARN_1_LN_TX_PWR_LO_ALRM_BIT 8
|
||||
# define AC400_NTWK_ALRM_WARN_1_LN_LAS_TEMP_HI_ALRM_BIT 7
|
||||
# define AC400_NTWK_ALRM_WARN_1_LN_LAS_TEMP_HI_WARN_BIT 6
|
||||
# define AC400_NTWK_ALRM_WARN_1_LN_LAS_TEMP_LO_WARN_BIT 5
|
||||
# define AC400_NTWK_ALRM_WARN_1_LN_LAS_TEMP_LO_ALRM_BIT 4
|
||||
# define AC400_NTWK_ALRM_WARN_1_LN_RX_PWR_HI_ALRM_BIT 3
|
||||
# define AC400_NTWK_ALRM_WARN_1_LN_RX_PWR_HI_WARN_BIT 2
|
||||
# define AC400_NTWK_ALRM_WARN_1_LN_RX_PWR_LO_WARN_BIT 1
|
||||
# define AC400_NTWK_ALRM_WARN_1_LN_RX_PWR_LO_ALRM_BIT 0
|
||||
|
||||
#define AC400_NTWK_ALRM_WARN_2_LN_0_REG 0xB190
|
||||
#define AC400_NTWK_ALRM_WARN_2_LN_1_REG 0xB191
|
||||
# define AC400_NTWK_ALRM_WARN_2_LN_TX_MOD_BIAS_HI_ALRM_BIT 3
|
||||
# define AC400_NTWK_ALRM_WARN_2_LN_TX_MOD_BIAS_HI_WARN_BIT 2
|
||||
# define AC400_NTWK_ALRM_WARN_2_LN_TX_MOD_BIAS_LO_WARN_BIT 1
|
||||
# define AC400_NTWK_ALRM_WARN_2_LN_TX_MOD_BIAS_LO_ALRM_BIT 0
|
||||
|
||||
#define AC400_NTWK_TX_ALGN_STAT_LN_0_REG 0xB210
|
||||
#define AC400_NTWK_TX_ALGN_STAT_LN_1_REG 0xB211
|
||||
# define AC400_NTWK_TX_ALGN_STAT_LN_OUT_OF_ALGN_BIT 14
|
||||
# define AC400_NTWK_TX_ALGN_STAT_LN_CMU_LCK_FLT_BIT 13
|
||||
# define AC400_NTWK_TX_ALGN_STAT_LN_REF_CLK_FLT_BIT 12
|
||||
|
||||
#define AC400_NTWK_RX_ALGN_STAT_LN_0_REG 0xB250
|
||||
#define AC400_NTWK_RX_ALGN_STAT_LN_1_REG 0xB251
|
||||
# define AC400_NTWK_RX_ALGN_STAT_LN_MODEM_SYNC_DET_FLT_BIT 15
|
||||
# define AC400_NTWK_RX_ALGN_STAT_LN_MODEM_LOCK_FLT_BIT 14
|
||||
# define AC400_NTWK_RX_ALGN_STAT_LN_LOSS_OF_ALGN_FLT_BIT 13
|
||||
# define AC400_NTWK_RX_ALGN_STAT_LN_OUT_OF_ALGN_FLT_BIT 12
|
||||
# define AC400_NTWK_RX_ALGN_STAT_LN_TIMING_FLT_BIT 11
|
||||
|
||||
#define AC400_NTWK_PRBS_RX_ERR_CNT_LN_0_REG 0xB310
|
||||
#define AC400_NTWK_PRBS_RX_ERR_CNT_LN_1_REG 0xB311
|
||||
# define AC400_NTWK_PRBS_RX_ERR_CNT_LN_EXPONENT_MSB 15
|
||||
# define AC400_NTWK_PRBS_RX_ERR_CNT_LN_EXPONENT_LSB 10
|
||||
# define AC400_NTWK_PRBS_RX_ERR_CNT_LN_MANTISSA_MSB 9
|
||||
# define AC400_NTWK_PRBS_RX_ERR_CNT_LN_MANTISSA_LSB 0
|
||||
|
||||
#define AC400_CLIENT_SERDES_PRBS_DATA_CNT_INTF_0_REG 0x9238
|
||||
#define AC400_CLIENT_SERDES_PRBS_DATA_CNT_INTF_1_REG 0x9239
|
||||
#define AC400_CLIENT_SERDES_PRBS_DATA_CNT_INTF_2_REG 0x923A
|
||||
#define AC400_CLIENT_SERDES_PRBS_DATA_CNT_INTF_3_REG 0x923B
|
||||
# define AC400_CLIENT_SERDES_PRBS_DATA_CNT_INTF_EXPONENT_MSB 15
|
||||
# define AC400_CLIENT_SERDES_PRBS_DATA_CNT_INTF_EXPONENT_LSB 10
|
||||
# define AC400_CLIENT_SERDES_PRBS_DATA_CNT_INTF_MANTISSA_MSB 9
|
||||
# define AC400_CLIENT_SERDES_PRBS_DATA_CNT_INTF_MANTISSA_LSB 0
|
||||
|
||||
#define AC400_CLIENT_FRAMED_PRBS_DATA_CNT_INTF_0_REG 0x9248
|
||||
#define AC400_CLIENT_FRAMED_PRBS_DATA_CNT_INTF_1_REG 0x9249
|
||||
#define AC400_CLIENT_FRAMED_PRBS_DATA_CNT_INTF_2_REG 0x924A
|
||||
#define AC400_CLIENT_FRAMED_PRBS_DATA_CNT_INTF_3_REG 0x924B
|
||||
# define AC400_CLIENT_FRAMED_PRBS_DATA_CNT_INTF_EXPONENT_MSB 15
|
||||
# define AC400_CLIENT_FRAMED_PRBS_DATA_CNT_INTF_EXPONENT_LSB 10
|
||||
# define AC400_CLIENT_FRAMED_PRBS_DATA_CNT_INTF_MANTISSA_MSB 9
|
||||
# define AC400_CLIENT_FRAMED_PRBS_DATA_CNT_INTF_MANTISSA_LSB 0
|
||||
|
||||
#define AC400_CLIENT_FRAMED_PRBS_TX_ERR_CNT_INTF_0_REG 0x9250
|
||||
#define AC400_CLIENT_FRAMED_PRBS_TX_ERR_CNT_INTF_1_REG 0x9251
|
||||
#define AC400_CLIENT_FRAMED_PRBS_TX_ERR_CNT_INTF_2_REG 0x9252
|
||||
#define AC400_CLIENT_FRAMED_PRBS_TX_ERR_CNT_INTF_3_REG 0x9253
|
||||
# define AC400_CLIENT_FRAMED_PRBS_TX_ERR_CNT_INTF_EXPONENT_MSB 15
|
||||
# define AC400_CLIENT_FRAMED_PRBS_TX_ERR_CNT_INTF_EXPONENT_LSB 10
|
||||
# define AC400_CLIENT_FRAMED_PRBS_TX_ERR_CNT_INTF_MANTISSA_MSB 9
|
||||
# define AC400_CLIENT_FRAMED_PRBS_TX_ERR_CNT_INTF_MANTISSA_LSB 0
|
||||
|
||||
#define AC400_CLIENT_FRAMED_PRBS_SYNC_STAT_INTF_0_REG 0x9258
|
||||
#define AC400_CLIENT_FRAMED_PRBS_SYNC_STAT_INTF_1_REG 0x9259
|
||||
#define AC400_CLIENT_FRAMED_PRBS_SYNC_STAT_INTF_2_REG 0x925A
|
||||
#define AC400_CLIENT_FRAMED_PRBS_SYNC_STAT_INTF_3_REG 0x925B
|
||||
# define AC400_CLIENT_FRAMED_PRBS_SYNC_STAT_INTF_FRAME_SYNC_BIT 1
|
||||
# define AC400_CLIENT_FRAMED_PRBS_SYNC_STAT_INTF_CHECK_SYNC_BIT 0
|
||||
|
||||
#define AC400_CLIENT_FRAMED_PRBS_LSYNC_WH_INTF_0_REG 0x9260
|
||||
#define AC400_CLIENT_FRAMED_PRBS_LSYNC_WL_INTF_0_REG 0x9261
|
||||
|
||||
#define AC400_CLIENT_FRAMED_PRBS_LSYNC_WH_INTF_1_REG 0x9262
|
||||
#define AC400_CLIENT_FRAMED_PRBS_LSYNC_WL_INTF_1_REG 0x9263
|
||||
|
||||
#define AC400_CLIENT_FRAMED_PRBS_LSYNC_WH_INTF_2_REG 0x9264
|
||||
#define AC400_CLIENT_FRAMED_PRBS_LSYNC_WL_INTF_2_REG 0x9265
|
||||
|
||||
#define AC400_CLIENT_FRAMED_PRBS_LSYNC_WH_INTF_3_REG 0x9266
|
||||
#define AC400_CLIENT_FRAMED_PRBS_LSYNC_WL_INTF_3_REG 0x9267
|
||||
|
||||
#define AC400_CLIENT_PCS_ALRM_STAT_INTF_0_REG 0x92A0
|
||||
#define AC400_CLIENT_PCS_ALRM_STAT_INTF_1_REG 0x92A1
|
||||
#define AC400_CLIENT_PCS_ALRM_STAT_INTF_2_REG 0x92A2
|
||||
#define AC400_CLIENT_PCS_ALRM_STAT_INTF_3_REG 0x92A3
|
||||
# define AC400_CLIENT_PCS_ALRM_STAT_INTF_OPU_CSF_BIT 12
|
||||
# define AC400_CLIENT_PCS_ALRM_STAT_INTF_INGRESS_LOCAL_FLT_BIT 11
|
||||
# define AC400_CLIENT_PCS_ALRM_STAT_INTF_INGRESS_LOA_BIT 10
|
||||
# define AC400_CLIENT_PCS_ALRM_STAT_INTF_INGRESS_AM_LCK_FLT_BIT 9
|
||||
# define AC400_CLIENT_PCS_ALRM_STAT_INTF_INGRESS_BLK_LCK_FLT_BIT 8
|
||||
# define AC400_CLIENT_PCS_ALRM_STAT_INTF_EGRESS_HI_BER_BIT 4
|
||||
# define AC400_CLIENT_PCS_ALRM_STAT_INTF_EGRESS_LOCAL_FLT_BIT 3
|
||||
# define AC400_CLIENT_PCS_ALRM_STAT_INTF_EGRESS_LOA_BIT 2
|
||||
# define AC400_CLIENT_PCS_ALRM_STAT_INTF_EGRESS_AM_LCK_FLT_BIT 1
|
||||
# define AC400_CLIENT_PCS_ALRM_STAT_INTF_EGRESS_BLK_LCK_FLT_BIT 0
|
||||
|
||||
#define AC400_NTWK_CUR_BER_WH_LN_0_REG 0x9300
|
||||
#define AC400_NTWK_CUR_BER_WL_LN_0_REG 0x9301
|
||||
|
||||
#define AC400_NTWK_CUR_BER_WH_LN_1_REG 0x9302
|
||||
#define AC400_NTWK_CUR_BER_WL_LN_1_REG 0x9303
|
||||
|
||||
#define AC400_NTWK_FEC_ACCUM_CNTS_CNTL_LN_0_REG 0x9400
|
||||
#define AC400_NTWK_FEC_ACCUM_CNTS_CNTL_LN_1_REG 0x9401
|
||||
# define AC400_NTWK_FEC_ACCUM_CNTS_CNTL_LN_RST_ALL_ACCUM_COUNTS_BIT 0
|
||||
|
||||
#define AC400_NTWK_FEC_UNCORR_CB_CNT_W1_LN_0_REG 0x9480
|
||||
#define AC400_NTWK_FEC_UNCORR_CB_CNT_W2_LN_0_REG 0x9481
|
||||
#define AC400_NTWK_FEC_UNCORR_CB_CNT_W3_LN_0_REG 0x9482
|
||||
#define AC400_NTWK_FEC_UNCORR_CB_CNT_W4_LN_0_REG 0x9483
|
||||
|
||||
#define AC400_NTWK_FEC_UNCORR_CB_CNT_W1_LN_1_REG 0x9484
|
||||
#define AC400_NTWK_FEC_UNCORR_CB_CNT_W2_LN_1_REG 0x9485
|
||||
#define AC400_NTWK_FEC_UNCORR_CB_CNT_W3_LN_1_REG 0x9486
|
||||
#define AC400_NTWK_FEC_UNCORR_CB_CNT_W4_LN_1_REG 0x9487
|
||||
|
||||
#define AC400_IND_NTWK_LANE_TX_DIS_CNTL_REG 0xB013
|
||||
# define AC400_IND_NTWK_LANE_TX_DIS_CNTL_TX_DIS_LANE_1_BIT 1
|
||||
# define AC400_IND_NTWK_LANE_TX_DIS_CNTL_TX_DIS_LANE_0_BIT 0
|
||||
|
||||
#define AC400_NTWK_TX_CHAN_CNTL_LN_0_REG 0xB400
|
||||
#define AC400_NTWK_TX_CHAN_CNTL_LN_1_REG 0xB401
|
||||
# define AC400_NTWK_TX_CHAN_CNTL_LN_GRID_SPACING_MSB 15
|
||||
# define AC400_NTWK_TX_CHAN_CNTL_LN_GRID_SPACING_LSB 13
|
||||
# define AC400_NTWK_TX_CHAN_CNTL_LN_CHAN_NUM_MSB 9
|
||||
# define AC400_NTWK_TX_CHAN_CNTL_LN_CHAN_NUM_LSB 0
|
||||
|
||||
#define AC400_NTWK_TX_OUTPUT_PWR_LN_0_REG 0xB410
|
||||
#define AC400_NTWK_TX_OUTPUT_PWR_LN_1_REG 0xB411
|
||||
|
||||
#define AC400_NTWK_TX_LASER_FTF_LN_0_REG 0xB430
|
||||
#define AC400_NTWK_TX_LASER_FTF_LN_1_REG 0xB431
|
||||
|
||||
#define AC400_NTWK_TX_FREQ_1_LN_0_REG 0xB450
|
||||
#define AC400_NTWK_TX_FREQ_1_LN_1_REG 0xB451
|
||||
|
||||
#define AC400_NTWK_TX_FREQ_2_LN_0_REG 0xB460
|
||||
#define AC400_NTWK_TX_FREQ_2_LN_1_REG 0xB461
|
||||
|
||||
#define AC400_NTWK_TX_CUR_OUT_PWR_LN_0_REG 0xB4A0
|
||||
#define AC400_NTWK_TX_CUR_OUT_PWR_LN_1_REG 0xB4A1
|
||||
|
||||
#define AC400_DEVICE_SETUP_CNTL_REG 0x9010
|
||||
# define AC400_DEVICE_SETUP_CNTL_DEV_CFG_MSB 1
|
||||
# define AC400_DEVICE_SETUP_CNTL_DEV_CFG_LSB 0
|
||||
|
||||
#define AC400_NTWK_LANES_ENABLE_CNTL_REG 0x9018
|
||||
# define AC400_NTWK_LANES_ENABLE_CNTL_MASTER_EN_LN_1_BIT 1
|
||||
# define AC400_NTWK_LANES_ENABLE_CNTL_MASTER_EN_LN_0_BIT 0
|
||||
|
||||
#define AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_REG 0x9020
|
||||
# define AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_3_EN_BIT 15
|
||||
# define AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_2_EN_BIT 14
|
||||
# define AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_1_EN_BIT 13
|
||||
# define AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_0_EN_BIT 12
|
||||
# define AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_3_LANES_12_TO_15_RATE_SEL_MSB 11
|
||||
# define AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_3_LANES_12_TO_15_RATE_SEL_LSB 9
|
||||
# define AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_2_LANES_8_TO_11_RATE_SEL_MSB 8
|
||||
# define AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_2_LANES_8_TO_11_RATE_SEL_LSB 6
|
||||
# define AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_1_LANES_4_TO_7_RATE_SEL_MSB 5
|
||||
# define AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_1_LANES_4_TO_7_RATE_SEL_LSB 3
|
||||
# define AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_0_LANES_0_TO_3_RATE_SEL_MSB 2
|
||||
# define AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_0_LANES_0_TO_3_RATE_SEL_LSB 0
|
||||
|
||||
#define AC400_NTWK_GEN_MODE_CNTL_LN_0_REG 0x9100
|
||||
#define AC400_NTWK_GEN_MODE_CNTL_LN_1_REG 0x9101
|
||||
# define AC400_NTWK_GEN_MODE_CNTL_LN_MODULATION_FORMAT_MSB 11
|
||||
# define AC400_NTWK_GEN_MODE_CNTL_LN_MODULATION_FORMAT_LSB 8
|
||||
# define AC400_NTWK_GEN_MODE_CNTL_LN_NON_DIFF_EN_BIT 7
|
||||
# define AC400_NTWK_GEN_MODE_CNTL_LN_FEC_MODE_MSB 2
|
||||
# define AC400_NTWK_GEN_MODE_CNTL_LN_FEC_MODE_LSB 0
|
||||
|
||||
#define AC400_NTWK_TX_CNTL_LN_0_REG 0x9120
|
||||
#define AC400_NTWK_TX_CNTL_LN_1_REG 0x9121
|
||||
# define AC400_NTWK_TX_CNTL_LN_PRBS_GEN_EN_BIT 14
|
||||
# define AC400_NTWK_TX_CNTL_LN_PRBS_GEN_PAT_MSB 13
|
||||
# define AC400_NTWK_TX_CNTL_LN_PRBS_GEN_PAT_LSB 12
|
||||
# define AC400_NTWK_TX_CNTL_LN_PRBS_GEN_INV_PAT_BIT 11
|
||||
# define AC400_NTWK_TX_CNTL_LN_TX_FIFO_RST_BIT 10
|
||||
# define AC400_NTWK_TX_CNTL_LN_TX_RESET_BIT 8
|
||||
# define AC400_NTWK_TX_CNTL_LN_TX_MCLK_CNTL_MSB 7
|
||||
# define AC400_NTWK_TX_CNTL_LN_TX_MCLK_CNTL_LSB 5
|
||||
# define AC400_NTWK_TX_CNTL_LN_TX_REF_CLK_RATE_SEL_MSB 4
|
||||
# define AC400_NTWK_TX_CNTL_LN_TX_REF_CLK_RATE_SEL_LSB 2
|
||||
# define AC400_NTWK_TX_CNTL_LN_TX_AIS_MODE_MSB 1
|
||||
# define AC400_NTWK_TX_CNTL_LN_TX_AIS_MODE_LSB 0
|
||||
|
||||
#define AC400_NTWK_RX_CNTL_LN_0_REG 0x9128
|
||||
#define AC400_NTWK_RX_CNTL_LN_1_REG 0x9129
|
||||
# define AC400_NTWK_RX_CNTL_LN_PRBS_CHK_EN_BIT 14
|
||||
# define AC400_NTWK_RX_CNTL_LN_PRBS_CHK_PAT_MSB 13
|
||||
# define AC400_NTWK_RX_CNTL_LN_PRBS_CHK_PAT_LSB 12
|
||||
# define AC400_NTWK_RX_CNTL_LN_PRBS_CHK_INV_PAT_BIT 11
|
||||
# define AC400_NTWK_RX_CNTL_LN_LOOPBACK_EN_BIT 10
|
||||
# define AC400_NTWK_RX_CNTL_LN_RX_RESET_BIT 8
|
||||
# define AC400_NTWK_RX_CNTL_LN_RX_FIFO_RST_BIT 4
|
||||
|
||||
#define AC400_CLIENT_GEN_CNTL_INTF_0_REG 0x9200
|
||||
#define AC400_CLIENT_GEN_CNTL_INTF_1_REG 0x9201
|
||||
#define AC400_CLIENT_GEN_CNTL_INTF_2_REG 0x9202
|
||||
#define AC400_CLIENT_GEN_CNTL_INTF_3_REG 0x9203
|
||||
# define AC400_CLIENT_GEN_CNTL_INTF_TX_FEC_DECODER_DIS_BIT 15
|
||||
# define AC400_CLIENT_GEN_CNTL_INTF_TX_RESET_BIT 11
|
||||
# define AC400_CLIENT_GEN_CNTL_INTF_LOOPBACK_EN_BIT 10
|
||||
# define AC400_CLIENT_GEN_CNTL_INTF_RX_FEC_ENCODER_DIS_BIT 7
|
||||
# define AC400_CLIENT_GEN_CNTL_INTF_RX_RESET_BIT 5
|
||||
# define AC400_CLIENT_GEN_CNTL_INTF_RX_MCLK_CNTL_MSB 4
|
||||
# define AC400_CLIENT_GEN_CNTL_INTF_RX_MCLK_CNTL_LSB 2
|
||||
# define AC400_CLIENT_GEN_CNTL_INTF_RX_AIS_MODE_MSB 1
|
||||
# define AC400_CLIENT_GEN_CNTL_INTF_RX_AIS_MODE_LSB 0
|
||||
|
||||
#define AC400_CLIENT_SERDES_LANES_PRBS_CNTL_INTF_0_REG 0x9210
|
||||
#define AC400_CLIENT_SERDES_LANES_PRBS_CNTL_INTF_1_REG 0x9211
|
||||
#define AC400_CLIENT_SERDES_LANES_PRBS_CNTL_INTF_2_REG 0x9212
|
||||
#define AC400_CLIENT_SERDES_LANES_PRBS_CNTL_INTF_3_REG 0x9213
|
||||
# define AC400_CLIENT_SERDES_LANES_PRBS_CNTL_INTF_TX_CHK_EN_BIT 14
|
||||
# define AC400_CLIENT_SERDES_LANES_PRBS_CNTL_INTF_TX_CHK_PAT_MSB 13
|
||||
# define AC400_CLIENT_SERDES_LANES_PRBS_CNTL_INTF_TX_CHK_PAT_LSB 12
|
||||
# define AC400_CLIENT_SERDES_LANES_PRBS_CNTL_INTF_RX_GEN_EN_BIT 7
|
||||
# define AC400_CLIENT_SERDES_LANES_PRBS_CNTL_INTF_RX_GEN_PAT_MSB 6
|
||||
# define AC400_CLIENT_SERDES_LANES_PRBS_CNTL_INTF_RX_GEN_PAT_LSB 5
|
||||
|
||||
#define AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_0_REG 0x9218
|
||||
#define AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_1_REG 0x9219
|
||||
#define AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_2_REG 0x921A
|
||||
#define AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_3_REG 0x921B
|
||||
# define AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_LF_CTLE_MSB 15
|
||||
# define AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_LF_CTLE_LSB 12
|
||||
# define AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_CTLE_MSB 11
|
||||
# define AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_CTLE_LSB 7
|
||||
# define AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_DFE_MSB 5
|
||||
# define AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_DFE_LSB 0
|
||||
|
||||
#define AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_0_REG 0x9220
|
||||
#define AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_1_REG 0x9221
|
||||
#define AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_2_REG 0x9222
|
||||
#define AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_3_REG 0x9223
|
||||
# define AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_GAIN_MSB 6
|
||||
# define AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_GAIN_LSB 4
|
||||
# define AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_DELAY_MSB 2
|
||||
# define AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_DELAY_LSB 0
|
||||
|
||||
#define AC400_CLIENT_HOST_RX_TAP_1_CNTL_INTF_0_REG 0x9228
|
||||
#define AC400_CLIENT_HOST_RX_TAP_1_CNTL_INTF_1_REG 0x9229
|
||||
#define AC400_CLIENT_HOST_RX_TAP_1_CNTL_INTF_2_REG 0x922A
|
||||
#define AC400_CLIENT_HOST_RX_TAP_1_CNTL_INTF_3_REG 0x922B
|
||||
# define AC400_CLIENT_HOST_RX_TAP_1_CNTL_INTF_GAIN_MSB 6
|
||||
# define AC400_CLIENT_HOST_RX_TAP_1_CNTL_INTF_GAIN_LSB 4
|
||||
|
||||
#define AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_0_REG 0x9230
|
||||
#define AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_1_REG 0x9231
|
||||
#define AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_2_REG 0x9232
|
||||
#define AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_3_REG 0x9233
|
||||
# define AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_GAIN_MSB 7
|
||||
# define AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_GAIN_LSB 4
|
||||
# define AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_DELAY_MSB 2
|
||||
# define AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_DELAY_LSB 0
|
||||
|
||||
#define AC400_CLIENT_FRAMED_PRBS_CNTL_INTF_0_REG 0x9240
|
||||
#define AC400_CLIENT_FRAMED_PRBS_CNTL_INTF_1_REG 0x9241
|
||||
#define AC400_CLIENT_FRAMED_PRBS_CNTL_INTF_2_REG 0x9242
|
||||
#define AC400_CLIENT_FRAMED_PRBS_CNTL_INTF_3_REG 0x9243
|
||||
# define AC400_CLIENT_FRAMED_PRBS_CNTL_INTF_TX_CHK_EN_BIT 14
|
||||
# define AC400_CLIENT_FRAMED_PRBS_CNTL_INTF_TX_CHK_PAT_MSB 13
|
||||
# define AC400_CLIENT_FRAMED_PRBS_CNTL_INTF_TX_CHK_PAT_LSB 12
|
||||
# define AC400_CLIENT_FRAMED_PRBS_CNTL_INTF_TX_CHK_INV_PAT_BIT 11
|
||||
# define AC400_CLIENT_FRAMED_PRBS_CNTL_INTF_TX_CHK_SCRAM_DIS_BIT 10
|
||||
# define AC400_CLIENT_FRAMED_PRBS_CNTL_INTF_RX_GEN_EN_BIT 7
|
||||
# define AC400_CLIENT_FRAMED_PRBS_CNTL_INTF_RX_GEN_PAT_MSB 6
|
||||
# define AC400_CLIENT_FRAMED_PRBS_CNTL_INTF_RX_GEN_PAT_LSB 5
|
||||
# define AC400_CLIENT_FRAMED_PRBS_CNTL_INTF_RX_GEN_INV_PAT_BIT 4
|
||||
# define AC400_CLIENT_FRAMED_PRBS_CNTL_INTF_RX_GEN_SCRAM_DIS_BIT 3
|
||||
# define AC400_CLIENT_FRAMED_PRBS_CNTL_INTF_Mill_BIT 3
|
||||
|
||||
#endif /* AC400_H__ */
|
||||
283
tai_ac400/inc/voyager.h
Normal file
283
tai_ac400/inc/voyager.h
Normal file
@@ -0,0 +1,283 @@
|
||||
/**
|
||||
* @file voyager.h
|
||||
* @brief Voyager platform definitions
|
||||
* @author Scott Emery <scotte@cumulusnetworks.com>
|
||||
*
|
||||
* @copyright Copyright (C) 2018 Cumulus Networks, Inc. All rights reserved
|
||||
*
|
||||
* @remark This source code is licensed under the BSD 3-Clause license found in
|
||||
* the LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#ifndef VOYAGER_H__
|
||||
#define VOYAGER_H__
|
||||
|
||||
/** @brief The number of AC400's in Voyager */
|
||||
#define VOYAGER_NUM_AC400 2
|
||||
|
||||
/** @brief The number of network interfaces on an AC400 */
|
||||
#define AC400_NUM_NETIF 2
|
||||
|
||||
/** @brief The number of host interfaces on an AC400 */
|
||||
#define AC400_NUM_HOSTIF 4
|
||||
|
||||
/** @brief The number of host lanes per host interface */
|
||||
#define AC400_NUM_HOST_LANES 4
|
||||
|
||||
/** @brief The number of network interfaces on Voyager */
|
||||
#define VOYAGER_NUM_NETIF (VOYAGER_NUM_AC400*AC400_NUM_NETIF)
|
||||
|
||||
/** @brief The number of host interfaces on Voyager */
|
||||
#define VOYAGER_NUM_HOSTIF (VOYAGER_NUM_AC400*AC400_NUM_HOSTIF)
|
||||
|
||||
/** @brief The path to the CPLD's sysfs attributes */
|
||||
#define CPLD_PATH "/sys/bus/platform/devices/syscpld"
|
||||
|
||||
/** @brief The AC400 TAI adapter uses the following format for object ids */
|
||||
typedef struct _ac400_object_id_t {
|
||||
uint8_t type;
|
||||
uint8_t reserved;
|
||||
uint32_t value;
|
||||
} ac400_object_id_t;
|
||||
|
||||
/** @brief The supported AC400 part numbers */
|
||||
#define VEND_PN_EXPECT_1 "AC400-003"
|
||||
#define VEND_PN_EXPECT_2 "AC400-004"
|
||||
|
||||
/**
|
||||
* @brief Return the value of the global alarm signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [out] glb_alrm A pointer to a bool to place the current global alarm
|
||||
* value.
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_get_glb_alrm(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Out_ bool *glb_alrm) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Return the value of the RXLOS signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] networkif The number of the network interface, 1 or 2
|
||||
* @param [out] rxlos A pointer to a bool to place the current rxlos value.
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_get_rxlos(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ int networkif,
|
||||
_Out_ bool *rxlos) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Return the value of the MOD_ABS ignal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [out] mod_abs A pointer to a bool to place the current mod_abs value.
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_get_mod_abs(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Out_ bool *mod_abs) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Return the value of the TXDIS signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] networkif The number of the network interface, 1 or 2
|
||||
* @param [out] txdis A pointer to a bool to place the current txdis value.
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_get_txdis(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ int networkif,
|
||||
_Out_ bool *txdis) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Set the value of the TXDIS signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] networkif The number of the network interface, 1 or 2
|
||||
* @param [in] txdis The value to set the txdis signal
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_set_txdis(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ int networkif,
|
||||
_In_ bool txdis) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Return the value of the MOD_LOPWR signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [out] mod_lopwr A pointer to a bool to place the current mod_lopwr
|
||||
* value.
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_get_mod_lopwr(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Out_ bool *mod_lopwr) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Set the value of the MOD_LOPWR signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] mod_lopwr The value to set the mod_lopwr signal
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_set_mod_lopwr(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ bool mod_lowwr) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Return the value of the PM_SYNC signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [out] pm_sync A pointer to a bool to place the current pm_sync value.
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_get_pm_sync(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Out_ bool *pm_sync) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Set the value of the PM_SYNC signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] pm_sync The value to set the pm_sync signal
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_set_pm_sync(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ bool pm_sync) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Return the value of the RESET signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [out] reset A pointer to a bool to place the current reset value.
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_get_reset(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Out_ bool *reset) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Set the value of the RESET signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] reset The value to set the reset signal
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_set_reset(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ bool reset) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Return the value of the POWER signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [out] power A pointer to a bool to place the current power value.
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_get_power(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Out_ bool *power) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Set the value of the POWER signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] power The value to set the power signal
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_set_power(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ bool power) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Return the value of the MDIO device_type
|
||||
*
|
||||
* @param [out] type A pointer to an int to place the current MDIO device_type.
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_get_device_type(
|
||||
_Out_ int *type) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Set the value of the MDIO device_type
|
||||
*
|
||||
* @param [in] type The value to set the MDIO device type
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_set_device_type(
|
||||
_In_ int type) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Perform an MDIO read from the AC400 module
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] reg The MDIO address of the register to read
|
||||
* @param [out] value A pointer to a u16 to place the value read from the AC400
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_mdio_read(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ uint16_t reg,
|
||||
_Out_ uint16_t *value) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Perform an MDIO write to the AC400 module
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] reg The MDIO address of the register to write
|
||||
* @param [out] value A u16 value to write to the AC400
|
||||
*
|
||||
* @return 0 on sucess, < 0 Linux error code
|
||||
*/
|
||||
extern int ac400_mdio_write(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ uint16_t reg,
|
||||
_In_ uint16_t value) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Validate the module location and initialize the module_id handle.
|
||||
*
|
||||
* @param [in] mod_addr A pointer to an s8list (string) which gives the module
|
||||
* index, either "1" or "2".
|
||||
* @param [out] module_id A pointer to the object id for the module object.
|
||||
*
|
||||
* @return 0 on success, or -1 on failure.
|
||||
*/
|
||||
extern int ac400_set_module_id(_In_ const tai_attribute_value_t * mod_addr,
|
||||
_Out_ tai_object_id_t * module_id)
|
||||
__attribute__ ((visibility ("hidden")));
|
||||
|
||||
/**
|
||||
* @brief Given a module_id, return the module location.
|
||||
*
|
||||
* @param [in] module_id A pointer to a module object id.
|
||||
* @param [out] location A pointer to location where the module location will be
|
||||
* stored.
|
||||
*/
|
||||
extern void ac400_get_module_location(_In_ tai_object_id_t module_id,
|
||||
_Out_ char * location)
|
||||
__attribute__ ((visibility ("hidden")));
|
||||
|
||||
#endif /* VOYAGER_H__ */
|
||||
367
tai_ac400/inc/voyager_tai_adapter.h
Normal file
367
tai_ac400/inc/voyager_tai_adapter.h
Normal file
@@ -0,0 +1,367 @@
|
||||
/**
|
||||
* @file voyager_tai_adapter.h
|
||||
* @brief Voyager TAI adapter defines
|
||||
* @author Scott Emery <scotte@cumulusnetworks.com>
|
||||
*
|
||||
* @copyright Copyright (C) 2018 Cumulus Networks, Inc. All rights reserved
|
||||
*
|
||||
* @remark This source code is licensed under the BSD 3-Clause license found in
|
||||
* the LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#ifndef VOYAGER_TAI_ADAPTER_H__
|
||||
#define VOYAGER_TAI_ADAPTER_H__
|
||||
|
||||
#include "tai.h"
|
||||
#include "ac400.h"
|
||||
#include "voyager.h"
|
||||
|
||||
/*
|
||||
* Support for custom TAI module attributes for the AC400
|
||||
*/
|
||||
/**
|
||||
* @brief Configuration modes for the network interfaces
|
||||
*/
|
||||
typedef enum _tai_module_network_mode_t
|
||||
{
|
||||
TAI_MODULE_NETWORK_MODE_UNKNOWN,
|
||||
TAI_MODULE_NETWORK_MODE_INDEPENDENT,
|
||||
TAI_MODULE_NETWORK_MODE_COUPLED,
|
||||
TAI_MODULE_NETWORK_MODE_MAX
|
||||
} tai_module_network_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Attribute Id in tai_set_module_attribute() and
|
||||
* tai_get_module_attribute() calls for AC400 custom attributes.
|
||||
*/
|
||||
typedef enum _tai_module_ac400_custom_attr_t
|
||||
{
|
||||
/**
|
||||
* @brief The operational mode of the network interfaces
|
||||
*
|
||||
* @type #tai_module_network_mode_t
|
||||
*/
|
||||
TAI_MODULE_ATTR_NETWORK_MODE = TAI_MODULE_ATTR_CUSTOM_RANGE_START
|
||||
} tai_module_ac400_custom_attr_t;
|
||||
|
||||
/*
|
||||
* Support for custom TAI network interface attributes for the AC400
|
||||
*/
|
||||
/** @brief The transmit turn-up state */
|
||||
typedef enum _tai_network_interface_tx_turn_up_state_t
|
||||
{
|
||||
TAI_NETWORK_INTERFACE_TX_TURN_UP_PATH_INIT = 0x01,
|
||||
TAI_NETWORK_INTERFACE_TX_TURN_UP_DATA_PATH = 0x02,
|
||||
TAI_NETWORK_INTERFACE_TX_TURN_UP_LASER_OFF = 0x04,
|
||||
TAI_NETWORK_INTERFACE_TX_TURN_UP_LASER_READY = 0x08,
|
||||
TAI_NETWORK_INTERFACE_TX_TURN_UP_MODULATOR_CONV = 0x10,
|
||||
TAI_NETWORK_INTERFACE_TX_TURN_UP_POWER_ADJUST = 0x20
|
||||
} tai_network_interface_tx_turn_up_state_t;
|
||||
|
||||
/** @brief The receive turn-up state */
|
||||
typedef enum _tai_network_interface_rx_turn_up_state_t
|
||||
{
|
||||
TAI_NETWORK_INTERFACE_RX_TURN_UP_PATH_INIT = 0x01,
|
||||
TAI_NETWORK_INTERFACE_RX_TURN_UP_DATA_PATH = 0x02,
|
||||
TAI_NETWORK_INTERFACE_RX_TURN_UP_OPTICAL_SIGNAL = 0x04,
|
||||
TAI_NETWORK_INTERFACE_RX_TURN_UP_ADC_OUTPUT = 0x08,
|
||||
TAI_NETWORK_INTERFACE_RX_TURN_UP_GOOD_DISP = 0x10,
|
||||
TAI_NETWORK_INTERFACE_RX_TURN_UP_DEMOD_LOCK = 0x20
|
||||
} tai_network_interface_rx_turn_up_state_t;
|
||||
|
||||
/** @brief The forward error correction mode */
|
||||
typedef enum _tai_network_interface_fec_mode_t
|
||||
{
|
||||
TAI_NETWORK_INTERFACE_FEC_MODE_UNKNOWN,
|
||||
TAI_NETWORK_INTERFACE_FEC_MODE_15,
|
||||
TAI_NETWORK_INTERFACE_FEC_MODE_15_NON_STD,
|
||||
TAI_NETWORK_INTERFACE_FEC_MODE_25,
|
||||
TAI_NETWORK_INTERFACE_FEC_MODE_MAX
|
||||
} tai_network_interface_fec_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Attribute Id in tai_set_network_interface_attribute() and
|
||||
* tai_get_network_interface_attribute() calls for AC400 custom
|
||||
* attributes.
|
||||
*/
|
||||
typedef enum _tai_network_interface_ac400_custom_attr_t
|
||||
{
|
||||
/**
|
||||
* @brief The transmit turn-up state
|
||||
*
|
||||
* A bit in this attribute is set for each state successfully completed
|
||||
* during TX turn-up.
|
||||
*
|
||||
* @type #tai_network_interface_tx_turn_up_state_t
|
||||
* @flags READ_ONLY
|
||||
*/
|
||||
TAI_NETWORK_INTERFACE_ATTR_TX_TURN_UP_STATE = TAI_NETWORK_INTERFACE_ATTR_CUSTOM_RANGE_START,
|
||||
|
||||
/**
|
||||
* @brief The receive turn-up state
|
||||
*
|
||||
* A bit in this attribute is set for each state successfully completed
|
||||
* during RX turn-up.
|
||||
*
|
||||
* @type #tai_network_interface_rx_turn_up_state_t
|
||||
* @flags READ_ONLY
|
||||
*/
|
||||
TAI_NETWORK_INTERFACE_ATTR_RX_TURN_UP_STATE,
|
||||
|
||||
/**
|
||||
* @brief Clear FEC accumuluative counters
|
||||
*
|
||||
* @type bool
|
||||
*/
|
||||
TAI_NETWORK_INTERFACE_ATTR_CLEAR_FEC_COUNTERS,
|
||||
|
||||
/**
|
||||
* @brief FEC Uncorrectable code blocks since reset
|
||||
*
|
||||
* @type #tai_uint64_t
|
||||
* @flags READ_ONLY
|
||||
*/
|
||||
TAI_NETWORK_INTERFACE_ATTR_FEC_UNCORRECTABLE,
|
||||
|
||||
/**
|
||||
* @brief Master Enable, when enabled the modem will turn-up if low power is
|
||||
* de-asserted.
|
||||
*
|
||||
* @type bool
|
||||
*/
|
||||
TAI_NETWORK_INTERFACE_ATTR_MASTER_ENABLE,
|
||||
|
||||
/**
|
||||
* @brief FEC mode
|
||||
*
|
||||
* @type #tai_network_interface_fec_mode_t
|
||||
*/
|
||||
TAI_NETWORK_INTERFACE_ATTR_FEC_MODE,
|
||||
|
||||
/**
|
||||
* @brief TX Reset
|
||||
*
|
||||
* @type bool
|
||||
*/
|
||||
TAI_NETWORK_INTERFACE_ATTR_TX_RESET,
|
||||
|
||||
/**
|
||||
* @brief TX FIFO Reset
|
||||
*
|
||||
* @type bool
|
||||
*/
|
||||
TAI_NETWORK_INTERFACE_ATTR_TX_FIFO_RESET,
|
||||
|
||||
/**
|
||||
* @brief RX Reset
|
||||
*
|
||||
* @type bool
|
||||
*/
|
||||
TAI_NETWORK_INTERFACE_ATTR_RX_RESET,
|
||||
|
||||
/**
|
||||
* @brief RX FIFO Reset
|
||||
*
|
||||
* @type bool
|
||||
*/
|
||||
TAI_NETWORK_INTERFACE_ATTR_RX_FIFO_RESET,
|
||||
|
||||
/**
|
||||
* @brief The current measured RX input power in dBm
|
||||
*
|
||||
* @type #tai_float_t
|
||||
* @flags READ_ONLY
|
||||
*/
|
||||
TAI_NETWORK_INTERFACE_ATTR_CURRENT_INPUT_POWER,
|
||||
|
||||
/**
|
||||
* @brief The TX laser fine tune frequency range in Hz
|
||||
*
|
||||
* @type #tai_uint64_t
|
||||
* @flags READ_ONLY
|
||||
*/
|
||||
TAI_NETWORK_INTERFACE_ATTR_FINE_TUNE_LASER_FREQ,
|
||||
|
||||
|
||||
/**
|
||||
* @brief The maximum number of laser tuning channels
|
||||
*
|
||||
* @type #tai_uint32_t
|
||||
* @flags READ_ONLY
|
||||
*/
|
||||
TAI_NETWORK_INTERFACE_ATTR_MAX_LASER_CHANNELS
|
||||
|
||||
} tai_network_interface_ac400_custom_attr_t;
|
||||
|
||||
/*
|
||||
* Support for custom TAI host interface attributes for the AC400
|
||||
*/
|
||||
/** @brief The interface rate */
|
||||
typedef enum _tai_host_interface_rate_t
|
||||
{
|
||||
TAI_HOST_INTERFACE_RATE_OTU4_27_95G,
|
||||
TAI_HOST_INTERFACE_RATE_100GE_25_78G
|
||||
} tai_host_interface_rate_t;
|
||||
|
||||
/**
|
||||
* @brief Attribute Id in tai_set_host_interface_attribute() and
|
||||
* tai_get_host_interface_attribute() calls for AC400 custom
|
||||
* attributes.
|
||||
*/
|
||||
typedef enum _tai_host_interface_ac400_custom_attr_t
|
||||
{
|
||||
/**
|
||||
* @brief Speed of the host interface
|
||||
*
|
||||
* @type #tai_host_interface_rate_t
|
||||
*/
|
||||
TAI_HOST_INTERFACE_ATTR_RATE = TAI_HOST_INTERFACE_ATTR_CUSTOM_RANGE_START,
|
||||
|
||||
/**
|
||||
* @brief Host interface enable
|
||||
*
|
||||
* Enables (true) or disables (false) a host interface.
|
||||
*
|
||||
* @type bool
|
||||
*/
|
||||
TAI_HOST_INTERFACE_ATTR_ENABLE,
|
||||
|
||||
/**
|
||||
* @brief FEC decoder enable
|
||||
*
|
||||
* Enables (true) or disables (false) the FEC decoder (host to module)
|
||||
*
|
||||
* @type bool
|
||||
*/
|
||||
TAI_HOST_INTERFACE_ATTR_FEC_DECODER,
|
||||
|
||||
/**
|
||||
* @brief FEC encoder enable
|
||||
*
|
||||
* Enables (true) or disables (false) the FEC encoder (module to host)
|
||||
*
|
||||
* @type bool
|
||||
*/
|
||||
TAI_HOST_INTERFACE_ATTR_FEC_ENCODER,
|
||||
|
||||
/**
|
||||
* @brief TX reset
|
||||
*
|
||||
* Enables (true) or disables (false) the TX host interface reset
|
||||
*
|
||||
* @type bool
|
||||
*/
|
||||
TAI_HOST_INTERFACE_ATTR_TX_RESET,
|
||||
|
||||
/**
|
||||
* @brief RX reset
|
||||
*
|
||||
* Enables (true) or disables (false) the RX host interface reset
|
||||
*
|
||||
* @type bool
|
||||
*/
|
||||
TAI_HOST_INTERFACE_ATTR_RX_RESET,
|
||||
|
||||
/**
|
||||
* @brief TX Deserializer equalization LF_CTLE gain
|
||||
*
|
||||
* @type #tai_uint16_t
|
||||
*/
|
||||
TAI_HOST_INTERFACE_ATTR_TX_DESERIAL_LF_CTLE_GAIN,
|
||||
|
||||
/**
|
||||
* @brief TX Deserializer equalization CTLE gain
|
||||
*
|
||||
* @type #tai_uint16_t
|
||||
*/
|
||||
TAI_HOST_INTERFACE_ATTR_TX_DESERIAL_CTLE_GAIN,
|
||||
|
||||
/**
|
||||
* @brief TX Deserializer equalization DFE tap coefficient
|
||||
*
|
||||
* @type #tai_uint16_t
|
||||
*/
|
||||
TAI_HOST_INTERFACE_ATTR_TX_DESERIAL_DFE_COEFFICIENT,
|
||||
|
||||
/**
|
||||
* @brief RX Serializer Tap 0 gain
|
||||
*
|
||||
* @type #tai_uint16_t
|
||||
*/
|
||||
TAI_HOST_INTERFACE_ATTR_RX_SERIAL_TAP0_GAIN,
|
||||
|
||||
/**
|
||||
* @brief RX Serializer Tap 0 delay
|
||||
*
|
||||
* @type #tai_uint16_t
|
||||
*/
|
||||
TAI_HOST_INTERFACE_ATTR_RX_SERIAL_TAP0_DELAY,
|
||||
|
||||
/**
|
||||
* @brief RX Serializer Tap 1 gain
|
||||
*
|
||||
* @type #tai_uint16_t
|
||||
*/
|
||||
TAI_HOST_INTERFACE_ATTR_RX_SERIAL_TAP1_GAIN,
|
||||
|
||||
/**
|
||||
* @brief RX Serializer Tap 2 gain
|
||||
*
|
||||
* @type #tai_uint16_t
|
||||
*/
|
||||
TAI_HOST_INTERFACE_ATTR_RX_SERIAL_TAP2_GAIN,
|
||||
|
||||
/**
|
||||
* @brief RX Serializer Tap 2 delay
|
||||
*
|
||||
* @type #tai_uint16_t
|
||||
*/
|
||||
TAI_HOST_INTERFACE_ATTR_RX_SERIAL_TAP2_DELAY
|
||||
|
||||
} tai_host_interface_ac400_custom_attr_t;
|
||||
|
||||
#define TAI_SYSLOG(lvl, ...) tai_syslog(__TAI_MODULE__, lvl, __VA_ARGS__)
|
||||
#define TAI_SYSLOG_DEBUG(...) TAI_SYSLOG(TAI_LOG_LEVEL_DEBUG, __VA_ARGS__)
|
||||
#define TAI_SYSLOG_INFO(...) TAI_SYSLOG(TAI_LOG_LEVEL_INFO, __VA_ARGS__)
|
||||
#define TAI_SYSLOG_NOTICE(...) TAI_SYSLOG(TAI_LOG_LEVEL_NOTICE, __VA_ARGS__)
|
||||
#define TAI_SYSLOG_WARN(...) TAI_SYSLOG(TAI_LOG_LEVEL_WARN, __VA_ARGS__)
|
||||
#define TAI_SYSLOG_ERROR(...) TAI_SYSLOG(TAI_LOG_LEVEL_ERROR, __VA_ARGS__)
|
||||
#define TAI_SYSLOG_CRITICAL(...) TAI_SYSLOG(TAI_LOG_LEVEL_CRITICAL, __VA_ARGS__)
|
||||
|
||||
extern void tai_syslog(_In_ tai_api_t tai_api_id, _In_ tai_log_level_t log_level,
|
||||
_In_ const char *format, ...) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
extern const tai_attribute_value_t * find_attribute_in_list(
|
||||
_In_ tai_attr_id_t attr_id,
|
||||
_In_ uint32_t attr_count,
|
||||
_In_ const tai_attribute_t *attr_list) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
extern tai_status_t convert_tai_error_to_list(_In_ tai_status_t err, _In_ uint32_t idx) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
extern tai_status_t ac400_get_string(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Inout_ tai_attribute_t *attr,
|
||||
_In_ uint16_t reg_addr,
|
||||
_In_ uint32_t str_len) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
extern int ac400_get_transition_time(
|
||||
tai_network_interface_oper_status_t prevState,
|
||||
tai_network_interface_oper_status_t nextState) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
extern tai_status_t ac400_get_module_oper_status(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Inout_ tai_attribute_t *attr) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
tai_status_t ac400_set_module_oper_status(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ const tai_attribute_t *attr) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
tai_status_t ac400_get_network_mode(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Inout_ tai_attribute_t *attr) __attribute__ ((visibility ("hidden")));
|
||||
|
||||
extern tai_module_api_t ac400_module_api __attribute__ ((visibility ("hidden")));
|
||||
extern tai_host_interface_api_t ac400_host_interface_api __attribute__ ((visibility ("hidden")));
|
||||
extern tai_network_interface_api_t ac400_network_interface_api __attribute__ ((visibility ("hidden")));
|
||||
|
||||
#endif /* VOYAGER_TAI_ADAPTER_H__ */
|
||||
1
tai_ac400/oopt-tai
Submodule
1
tai_ac400/oopt-tai
Submodule
Submodule tai_ac400/oopt-tai added at 6e23c3dce3
36
tai_ac400/src/Makefile.am
Normal file
36
tai_ac400/src/Makefile.am
Normal file
@@ -0,0 +1,36 @@
|
||||
# Makefile.am -- Process this file with automake to produce Makefile.in
|
||||
|
||||
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(srcdir) \
|
||||
-I$(srcdir)/../inc \
|
||||
-I$(APP_LIB_PATH)/include
|
||||
|
||||
# Path to TAI include files
|
||||
INCLUDES += -I$(top_srcdir)/oopt-tai/inc
|
||||
|
||||
if DEBUG
|
||||
DBGFLAGS = -ggdb -D_DEBUG_
|
||||
else
|
||||
DBGFLAGS = -g
|
||||
endif
|
||||
|
||||
CFLAGS = @CFLAGS@ $(CFLAGS_TAI_INTERFACE_COMMON) $(DBGFLAGS)
|
||||
|
||||
lib_LTLIBRARIES = libtai.la
|
||||
|
||||
libtai_la_SOURCES = \
|
||||
ac400_tai_interface.c \
|
||||
ac400_tai_module.c \
|
||||
ac400_tai_networkif.c \
|
||||
ac400_tai_hostif.c \
|
||||
ac400_tai_utils.c \
|
||||
ac400_voyager.c
|
||||
|
||||
|
||||
libtai_la_LIBADD =
|
||||
|
||||
libtai_apiincludedir = $(includedir)/tai
|
||||
libtai_apiinclude_HEADERS = $(top_srcdir)/oopt-tai/inc/*.h
|
||||
|
||||
|
||||
libtai_api_version=$(shell grep LIBVERSION= $(top_srcdir)/tai_interface.ver | sed 's/LIBVERSION=//')
|
||||
libtai_la_LDFLAGS = -version-info $(libtai_api_version)
|
||||
721
tai_ac400/src/ac400_tai_hostif.c
Normal file
721
tai_ac400/src/ac400_tai_hostif.c
Normal file
@@ -0,0 +1,721 @@
|
||||
/**
|
||||
* @file ac400_tai_hostif.c
|
||||
* @brief The TAI host interface routines
|
||||
* @author Scott Emery <scotte@cumulusnetworks.com>
|
||||
*
|
||||
* @copyright Copyright (C) 2018 Cumulus Networks, Inc. All rights reserved
|
||||
*
|
||||
* @remark This source code is licensed under the BSD 3-Clause license found
|
||||
* in the LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "voyager_tai_adapter.h"
|
||||
|
||||
#undef __TAI_MODULE__
|
||||
#define __TAI_MODULE__ TAI_API_HOSTIF
|
||||
|
||||
typedef struct _host_interface_info_t {
|
||||
bool initialized;
|
||||
tai_object_id_t module_id; /* module handle */
|
||||
int hostif_idx; /* zero-based index on the module */
|
||||
} host_interface_info_t;
|
||||
|
||||
static host_interface_info_t hostif_info[VOYAGER_NUM_HOSTIF];
|
||||
|
||||
/**
|
||||
* @brief Retrieve the lane faults list
|
||||
*
|
||||
* @param [in] host_interface_id The host interface identifier
|
||||
* @param [in,out] attr The attribute into which the lane fault status will be
|
||||
* placed (#tai_u32_list_t of #tai_host_interface_lane_faults_t)
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
static tai_status_t ac400_get_lane_faults(
|
||||
_In_ tai_object_id_t host_interface_id,
|
||||
_Inout_ tai_attribute_t *attr)
|
||||
{
|
||||
ac400_object_id_t *hostif_obj = (ac400_object_id_t *)&host_interface_id;
|
||||
tai_object_id_t module_id = hostif_info[hostif_obj->value].module_id;
|
||||
tai_host_interface_lane_faults_t *cp;
|
||||
uint16_t reg_addr = AC400_HOST_FLT_STAT_LN_0_REG +
|
||||
AC400_NUM_HOST_LANES*hostif_info[hostif_obj->value].hostif_idx;
|
||||
uint32_t num_lanes = AC400_NUM_HOST_LANES;
|
||||
uint16_t word1;
|
||||
|
||||
/* Is there enough room in the attribute array? */
|
||||
if (attr->value.u32list.count < num_lanes) {
|
||||
attr->value.u32list.count = num_lanes;
|
||||
return TAI_STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
attr->value.u32list.count = num_lanes;
|
||||
cp = attr->value.u32list.list;
|
||||
|
||||
while (num_lanes--) {
|
||||
if (ac400_mdio_read(module_id, reg_addr++, &word1)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
*cp = (word1 & AC400_HOST_FLT_STAT_LN_TX_HOST_LOL_BIT) ?
|
||||
TAI_HOST_INTERFACE_LANE_FAULT_LOSS_OF_LOCK : 0;
|
||||
*cp++ |= (word1 & 0x0002) ?
|
||||
TAI_HOST_INTERFACE_LANE_FAULT_TX_FIFIO_ERR : 0;
|
||||
}
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the TX alignment status
|
||||
*
|
||||
* @param [in] host_interface_id The host interface identifier
|
||||
* @param [in,out] attr The attribute into which the client interface tx
|
||||
* alignment status is placed (#tai_host_interface_tx_align_status_t).
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
static tai_status_t ac400_get_tx_align(
|
||||
_In_ tai_object_id_t host_interface_id,
|
||||
_Inout_ tai_attribute_t *attr)
|
||||
{
|
||||
ac400_object_id_t *hostif_obj = (ac400_object_id_t *)&host_interface_id;
|
||||
tai_object_id_t module_id = hostif_info[hostif_obj->value].module_id;
|
||||
uint16_t word1;
|
||||
|
||||
if (ac400_mdio_read(module_id, AC400_CLIENT_TX_ALGN_STAT_INTF_0_REG +
|
||||
hostif_info[hostif_obj->value].hostif_idx, &word1)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
attr->value.u32 = (word1 & AC400_CLIENT_TX_ALGN_STAT_INTF_LOSS_OF_ALGN_BIT) ?
|
||||
TAI_HOST_INTERFACE_TX_ALIGN_LOSS : 0;
|
||||
attr->value.u32 |= (word1 & AC400_CLIENT_TX_ALGN_STAT_INTF_OUT_OF_ALGN_BIT) ?
|
||||
TAI_HOST_INTERFACE_TX_ALIGN_OUT : 0;
|
||||
attr->value.u32 |= (word1 & AC400_CLIENT_TX_ALGN_STAT_INTF_DESKW_LCK_FLT_BIT) ?
|
||||
TAI_HOST_INTERFACE_TX_ALIGN_DESKEW_LOCK : 0;
|
||||
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the interface rate
|
||||
*
|
||||
* @param [in] host_interface_id The host interface identifier
|
||||
* @param [in,out] attr The attribute into which the client interface rate is
|
||||
* placed (#tai_host_interface_rate_t).
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
static tai_status_t ac400_get_rate(
|
||||
_In_ tai_object_id_t host_interface_id,
|
||||
_Inout_ tai_attribute_t *attr)
|
||||
{
|
||||
ac400_object_id_t *hostif_obj = (ac400_object_id_t *)&host_interface_id;
|
||||
tai_object_id_t module_id = hostif_info[hostif_obj->value].module_id;
|
||||
uint16_t word1;
|
||||
uint16_t ac400_rate;
|
||||
|
||||
if (ac400_mdio_read(module_id, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_REG, &word1)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
switch (hostif_info[hostif_obj->value].hostif_idx) {
|
||||
case 0:
|
||||
ac400_rate = AC400_GET_FIELD(word1, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_0_LANES_0_TO_3_RATE_SEL);
|
||||
break;
|
||||
case 1:
|
||||
ac400_rate = AC400_GET_FIELD(word1, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_1_LANES_4_TO_7_RATE_SEL);
|
||||
break;
|
||||
case 2:
|
||||
ac400_rate = AC400_GET_FIELD(word1, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_2_LANES_8_TO_11_RATE_SEL);
|
||||
break;
|
||||
case 3:
|
||||
ac400_rate = AC400_GET_FIELD(word1, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_3_LANES_12_TO_15_RATE_SEL);
|
||||
break;
|
||||
default:
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
switch (ac400_rate) {
|
||||
case 0:
|
||||
attr->value.u32 = TAI_HOST_INTERFACE_RATE_OTU4_27_95G;
|
||||
break;
|
||||
case 1:
|
||||
attr->value.u32 = TAI_HOST_INTERFACE_RATE_100GE_25_78G;
|
||||
break;
|
||||
default:
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the interface rate
|
||||
*
|
||||
* @param [in] host_interface_id The host interface identifier
|
||||
* @param [in] attr The attribute which contains the client interface rate
|
||||
* (#tai_host_interface_rate_t).
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
static tai_status_t ac400_set_rate(
|
||||
_In_ tai_object_id_t host_interface_id,
|
||||
_In_ const tai_attribute_t *attr)
|
||||
{
|
||||
ac400_object_id_t *hostif_obj = (ac400_object_id_t *)&host_interface_id;
|
||||
tai_object_id_t module_id = hostif_info[hostif_obj->value].module_id;
|
||||
uint16_t word1;
|
||||
uint16_t ac400_rate;
|
||||
|
||||
switch (attr->value.u32) {
|
||||
case TAI_HOST_INTERFACE_RATE_OTU4_27_95G:
|
||||
ac400_rate = 0;
|
||||
break;
|
||||
case TAI_HOST_INTERFACE_RATE_100GE_25_78G:
|
||||
ac400_rate = 1;
|
||||
break;
|
||||
default:
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
if (ac400_mdio_read(module_id, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_REG, &word1)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
switch (hostif_info[hostif_obj->value].hostif_idx) {
|
||||
case 0:
|
||||
word1 = AC400_PUT_FIELD(word1, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_0_LANES_0_TO_3_RATE_SEL, ac400_rate);
|
||||
break;
|
||||
case 1:
|
||||
word1 = AC400_PUT_FIELD(word1, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_1_LANES_4_TO_7_RATE_SEL, ac400_rate);
|
||||
break;
|
||||
case 2:
|
||||
word1 = AC400_PUT_FIELD(word1, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_2_LANES_8_TO_11_RATE_SEL, ac400_rate);
|
||||
break;
|
||||
case 3:
|
||||
word1 = AC400_PUT_FIELD(word1, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_3_LANES_12_TO_15_RATE_SEL, ac400_rate);
|
||||
break;
|
||||
default:
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
if (ac400_mdio_write(module_id, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_REG, word1)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the interface enable state
|
||||
*
|
||||
* @param [in] host_interface_id The host interface identifier
|
||||
* @param [in,out] attr The attribute into which the client interface enable
|
||||
* state is placed (bool).
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
static tai_status_t ac400_get_enable(
|
||||
_In_ tai_object_id_t host_interface_id,
|
||||
_Inout_ tai_attribute_t *attr)
|
||||
{
|
||||
ac400_object_id_t *hostif_obj = (ac400_object_id_t *)&host_interface_id;
|
||||
tai_object_id_t module_id = hostif_info[hostif_obj->value].module_id;
|
||||
uint16_t word1;
|
||||
uint16_t enable;
|
||||
|
||||
if (ac400_mdio_read(module_id, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_REG, &word1)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
switch (hostif_info[hostif_obj->value].hostif_idx) {
|
||||
case 0:
|
||||
enable = AC400_GET_BIT(word1, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_0_EN);
|
||||
break;
|
||||
case 1:
|
||||
enable = AC400_GET_BIT(word1, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_1_EN);
|
||||
break;
|
||||
case 2:
|
||||
enable = AC400_GET_BIT(word1, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_2_EN);
|
||||
break;
|
||||
case 3:
|
||||
enable = AC400_GET_BIT(word1, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_3_EN);
|
||||
break;
|
||||
default:
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
attr->value.booldata = (enable != 0);
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the interface enable state
|
||||
*
|
||||
* @param [in] host_interface_id The host interface identifier
|
||||
* @param [in] attr The attribute which contains the client interface enable
|
||||
* state (bool).
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
static tai_status_t ac400_set_enable(
|
||||
_In_ tai_object_id_t host_interface_id,
|
||||
_In_ const tai_attribute_t *attr)
|
||||
{
|
||||
ac400_object_id_t *hostif_obj = (ac400_object_id_t *)&host_interface_id;
|
||||
tai_object_id_t module_id = hostif_info[hostif_obj->value].module_id;
|
||||
uint16_t word1;
|
||||
uint16_t enable;
|
||||
|
||||
enable = (attr->value.booldata) ? 1 : 0;
|
||||
|
||||
if (ac400_mdio_read(module_id, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_REG, &word1)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
switch (hostif_info[hostif_obj->value].hostif_idx) {
|
||||
case 0:
|
||||
word1 = AC400_PUT_BIT(word1, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_0_EN, enable);
|
||||
break;
|
||||
case 1:
|
||||
word1 = AC400_PUT_BIT(word1, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_1_EN, enable);
|
||||
break;
|
||||
case 2:
|
||||
word1 = AC400_PUT_BIT(word1, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_2_EN, enable);
|
||||
break;
|
||||
case 3:
|
||||
word1 = AC400_PUT_BIT(word1, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_INTF_3_EN, enable);
|
||||
break;
|
||||
default:
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
if (ac400_mdio_write(module_id, AC400_HOST_LANES_CLIENT_INTF_DEF_CNTL_REG, word1)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve a field from a sequential list of client interface registers.
|
||||
*
|
||||
* It is common for there to be sequential registers, one for each client
|
||||
* interface, which have the same format. This routine grabs a field from these
|
||||
* registers, given the first register address, host interface index, and lsb
|
||||
* and msb of the field.
|
||||
*
|
||||
* @param [in] host_interface_id The host interface identifier
|
||||
* @param [in,out] field Pointer to the field that is being retrieved
|
||||
* @param [in] reg_base The MDIO address of the first of the list of registers
|
||||
* @param [in] field_msb The most sigificant bit of the field being retrieved
|
||||
* @param [in] field_lsb The least sigificant bit of the field being retrieved
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
static tai_status_t ac400_get_field_from_reg_list(
|
||||
_In_ tai_object_id_t host_interface_id,
|
||||
_Inout_ uint16_t *field,
|
||||
_In_ uint16_t reg_base,
|
||||
_In_ int field_msb,
|
||||
_In_ int field_lsb)
|
||||
{
|
||||
ac400_object_id_t *hostif_obj = (ac400_object_id_t *)&host_interface_id;
|
||||
tai_object_id_t module_id = hostif_info[hostif_obj->value].module_id;
|
||||
uint16_t word1;
|
||||
|
||||
*field = 0;
|
||||
if (ac400_mdio_read(module_id, reg_base +
|
||||
hostif_info[hostif_obj->value].hostif_idx, &word1)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
*field = (word1 & GENMASK(field_msb, field_lsb)) >> field_lsb;
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a field in a sequential list of client interface registers.
|
||||
*
|
||||
* It is common for there to be sequential registers, one for each client
|
||||
* interface, which have the same format. This routine modifies a field in these
|
||||
* registers, given the first register address, host interface index, lsb and
|
||||
* msb of the field, and the field value.
|
||||
*
|
||||
* @param [in] host_interface_id The host interface identifier
|
||||
* @param [in] field The value of the field that is being set
|
||||
* @param [in] reg_base The MDIO address of the first of the list of registers
|
||||
* @param [in] field_msb The most sigificant bit of the field being retrieved
|
||||
* @param [in] field_lsb The least sigificant bit of the field being retrieved
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
static tai_status_t ac400_set_field_from_reg_list(
|
||||
_In_ tai_object_id_t host_interface_id,
|
||||
_In_ uint16_t field,
|
||||
_In_ uint16_t reg_base,
|
||||
_In_ int field_msb,
|
||||
_In_ int field_lsb)
|
||||
{
|
||||
ac400_object_id_t *hostif_obj = (ac400_object_id_t *)&host_interface_id;
|
||||
tai_object_id_t module_id = hostif_info[hostif_obj->value].module_id;
|
||||
uint16_t word1;
|
||||
|
||||
if (ac400_mdio_read(module_id, reg_base +
|
||||
hostif_info[hostif_obj->value].hostif_idx, &word1)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
word1 = (word1 & ~GENMASK(field_msb, field_lsb)) | (field << field_lsb);
|
||||
|
||||
if (ac400_mdio_write(module_id, reg_base +
|
||||
hostif_info[hostif_obj->value].hostif_idx, word1)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the value of an attribute
|
||||
*
|
||||
* @param [in] host_interface_id The host interface ID handle
|
||||
* @param [in,out] attr A pointer to the attribute to be retrieved
|
||||
*
|
||||
* @return TAI_STATUS_SUCCESS on success, failure status code on error
|
||||
*/
|
||||
static tai_status_t ac400_get_host_interface_attribute(
|
||||
_In_ tai_object_id_t host_interface_id,
|
||||
_Inout_ tai_attribute_t *attr)
|
||||
{
|
||||
uint16_t field;
|
||||
tai_status_t ret;
|
||||
ac400_object_id_t *hostif_obj = (ac400_object_id_t *)&host_interface_id;
|
||||
|
||||
TAI_SYSLOG_DEBUG("Retrieving host interface attribute: %d", attr->id);
|
||||
switch (attr->id) {
|
||||
case TAI_HOST_INTERFACE_ATTR_INDEX:
|
||||
attr->value.u32 = hostif_info[hostif_obj->value].hostif_idx;
|
||||
return TAI_STATUS_SUCCESS;
|
||||
case TAI_HOST_INTERFACE_ATTR_LANE_FAULTS:
|
||||
return ac400_get_lane_faults(host_interface_id, attr);
|
||||
case TAI_HOST_INTERFACE_ATTR_TX_ALIGN_STATUS:
|
||||
return ac400_get_tx_align(host_interface_id, attr);
|
||||
case TAI_HOST_INTERFACE_ATTR_RATE:
|
||||
return ac400_get_rate(host_interface_id, attr);
|
||||
case TAI_HOST_INTERFACE_ATTR_ENABLE:
|
||||
return ac400_get_enable(host_interface_id, attr);
|
||||
case TAI_HOST_INTERFACE_ATTR_FEC_DECODER:
|
||||
ret = ac400_get_field_from_reg_list(host_interface_id,
|
||||
&field, AC400_CLIENT_GEN_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_TX_FEC_DECODER_DIS_BIT,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_TX_FEC_DECODER_DIS_BIT);
|
||||
attr->value.booldata = !field;
|
||||
return ret;
|
||||
case TAI_HOST_INTERFACE_ATTR_FEC_ENCODER:
|
||||
ret = ac400_get_field_from_reg_list(host_interface_id,
|
||||
&field, AC400_CLIENT_GEN_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_RX_FEC_ENCODER_DIS_BIT,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_RX_FEC_ENCODER_DIS_BIT);
|
||||
attr->value.booldata = !field;
|
||||
return ret;
|
||||
case TAI_HOST_INTERFACE_ATTR_TX_RESET:
|
||||
ret = ac400_get_field_from_reg_list(host_interface_id,
|
||||
&field, AC400_CLIENT_GEN_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_TX_RESET_BIT,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_TX_RESET_BIT);
|
||||
attr->value.booldata = !!field;
|
||||
return ret;
|
||||
case TAI_HOST_INTERFACE_ATTR_RX_RESET:
|
||||
ret = ac400_get_field_from_reg_list(host_interface_id,
|
||||
&field, AC400_CLIENT_GEN_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_RX_RESET_BIT,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_RX_RESET_BIT);
|
||||
attr->value.booldata = !!field;
|
||||
return ret;
|
||||
case TAI_HOST_INTERFACE_ATTR_TX_DESERIAL_LF_CTLE_GAIN:
|
||||
ret = ac400_get_field_from_reg_list(host_interface_id,
|
||||
&field, AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_LF_CTLE_MSB,
|
||||
AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_LF_CTLE_LSB);
|
||||
attr->value.u16 = field;
|
||||
return ret;
|
||||
case TAI_HOST_INTERFACE_ATTR_TX_DESERIAL_CTLE_GAIN:
|
||||
ret = ac400_get_field_from_reg_list(host_interface_id,
|
||||
&field, AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_CTLE_MSB,
|
||||
AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_CTLE_LSB);
|
||||
attr->value.u16 = field;
|
||||
return ret;
|
||||
case TAI_HOST_INTERFACE_ATTR_TX_DESERIAL_DFE_COEFFICIENT:
|
||||
ret = ac400_get_field_from_reg_list(host_interface_id,
|
||||
&field, AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_DFE_MSB,
|
||||
AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_DFE_LSB);
|
||||
attr->value.u16 = field;
|
||||
return ret;
|
||||
case TAI_HOST_INTERFACE_ATTR_RX_SERIAL_TAP0_GAIN:
|
||||
ret = ac400_get_field_from_reg_list(host_interface_id,
|
||||
&field, AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_GAIN_MSB,
|
||||
AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_GAIN_LSB);
|
||||
attr->value.u16 = field;
|
||||
return ret;
|
||||
case TAI_HOST_INTERFACE_ATTR_RX_SERIAL_TAP0_DELAY:
|
||||
ret = ac400_get_field_from_reg_list(host_interface_id,
|
||||
&field, AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_DELAY_MSB,
|
||||
AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_DELAY_LSB);
|
||||
attr->value.u16 = field;
|
||||
return ret;
|
||||
case TAI_HOST_INTERFACE_ATTR_RX_SERIAL_TAP1_GAIN:
|
||||
ret = ac400_get_field_from_reg_list(host_interface_id,
|
||||
&field, AC400_CLIENT_HOST_RX_TAP_1_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_HOST_RX_TAP_1_CNTL_INTF_GAIN_MSB,
|
||||
AC400_CLIENT_HOST_RX_TAP_1_CNTL_INTF_GAIN_LSB);
|
||||
attr->value.u16 = field;
|
||||
return ret;
|
||||
case TAI_HOST_INTERFACE_ATTR_RX_SERIAL_TAP2_GAIN:
|
||||
ret = ac400_get_field_from_reg_list(host_interface_id,
|
||||
&field, AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_GAIN_MSB,
|
||||
AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_GAIN_LSB);
|
||||
attr->value.u16 = field;
|
||||
return ret;
|
||||
case TAI_HOST_INTERFACE_ATTR_RX_SERIAL_TAP2_DELAY:
|
||||
ret = ac400_get_field_from_reg_list(host_interface_id,
|
||||
&field, AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_DELAY_MSB,
|
||||
AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_DELAY_LSB);
|
||||
attr->value.u16 = field;
|
||||
return ret;
|
||||
}
|
||||
return TAI_STATUS_ATTR_NOT_SUPPORTED_0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve a list of attribute values
|
||||
*
|
||||
* @param [in] host_interface_id The host interface ID handle
|
||||
* @param [in] attr_count A count of the number of elements in the attr_list
|
||||
* @param [in,out] attr_list A list of attributes to be retrieved
|
||||
*
|
||||
* @return TAI_STATUS_SUCCESS on success, failure status code on error
|
||||
*/
|
||||
static tai_status_t ac400_get_host_interface_attributes(
|
||||
_In_ tai_object_id_t host_interface_id,
|
||||
_In_ uint32_t attr_count,
|
||||
_Inout_ tai_attribute_t *attr_list)
|
||||
{
|
||||
uint32_t idx;
|
||||
tai_status_t ret;
|
||||
|
||||
for (idx = 0; idx < attr_count; idx++) {
|
||||
ret = ac400_get_host_interface_attribute(host_interface_id, attr_list++);
|
||||
if (ret) {
|
||||
return convert_tai_error_to_list(ret, idx);
|
||||
}
|
||||
}
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the value of an attribute
|
||||
*
|
||||
* @param [in] host_interface_id The host interface ID handle
|
||||
* @param [in] attr A pointer to the attribute to be set
|
||||
*
|
||||
* @return TAI_STATUS_SUCCESS on success, failure status code on error
|
||||
*/
|
||||
static tai_status_t ac400_set_host_interface_attribute(
|
||||
_In_ tai_object_id_t host_interface_id,
|
||||
_In_ const tai_attribute_t *attr)
|
||||
{
|
||||
uint16_t field;
|
||||
|
||||
TAI_SYSLOG_DEBUG("Setting host interface attribute: %d", attr->id);
|
||||
switch (attr->id) {
|
||||
case TAI_HOST_INTERFACE_ATTR_INDEX:
|
||||
return TAI_STATUS_SUCCESS;
|
||||
case TAI_HOST_INTERFACE_ATTR_LANE_FAULTS:
|
||||
case TAI_HOST_INTERFACE_ATTR_TX_ALIGN_STATUS:
|
||||
return TAI_STATUS_INVALID_ATTRIBUTE_0;
|
||||
case TAI_HOST_INTERFACE_ATTR_RATE:
|
||||
return ac400_set_rate(host_interface_id, attr);
|
||||
case TAI_HOST_INTERFACE_ATTR_ENABLE:
|
||||
return ac400_set_enable(host_interface_id, attr);
|
||||
case TAI_HOST_INTERFACE_ATTR_FEC_DECODER:
|
||||
field = (attr->value.booldata) ? 0 : 1;
|
||||
return ac400_set_field_from_reg_list(host_interface_id, field,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_TX_FEC_DECODER_DIS_BIT,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_TX_FEC_DECODER_DIS_BIT);
|
||||
case TAI_HOST_INTERFACE_ATTR_FEC_ENCODER:
|
||||
field = (attr->value.booldata) ? 0 : 1;
|
||||
return ac400_set_field_from_reg_list(host_interface_id, field,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_RX_FEC_ENCODER_DIS_BIT,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_RX_FEC_ENCODER_DIS_BIT);
|
||||
case TAI_HOST_INTERFACE_ATTR_TX_RESET:
|
||||
field = (attr->value.booldata) ? 1 : 0;
|
||||
return ac400_set_field_from_reg_list(host_interface_id, field,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_TX_RESET_BIT,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_TX_RESET_BIT);
|
||||
case TAI_HOST_INTERFACE_ATTR_RX_RESET:
|
||||
field = (attr->value.booldata) ? 1 : 0;
|
||||
return ac400_set_field_from_reg_list(host_interface_id, field,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_RX_RESET_BIT,
|
||||
AC400_CLIENT_GEN_CNTL_INTF_RX_RESET_BIT);
|
||||
case TAI_HOST_INTERFACE_ATTR_TX_DESERIAL_LF_CTLE_GAIN:
|
||||
return ac400_set_field_from_reg_list(host_interface_id, attr->value.u16,
|
||||
AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_LF_CTLE_MSB,
|
||||
AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_LF_CTLE_LSB);
|
||||
case TAI_HOST_INTERFACE_ATTR_TX_DESERIAL_CTLE_GAIN:
|
||||
return ac400_set_field_from_reg_list(host_interface_id, attr->value.u16,
|
||||
AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_CTLE_MSB,
|
||||
AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_CTLE_LSB);
|
||||
case TAI_HOST_INTERFACE_ATTR_TX_DESERIAL_DFE_COEFFICIENT:
|
||||
return ac400_set_field_from_reg_list(host_interface_id, attr->value.u16,
|
||||
AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_DFE_MSB,
|
||||
AC400_CLIENT_HOST_TX_EQUAL_CNTL_INTF_DFE_LSB);
|
||||
case TAI_HOST_INTERFACE_ATTR_RX_SERIAL_TAP0_GAIN:
|
||||
return ac400_set_field_from_reg_list(host_interface_id, attr->value.u16,
|
||||
AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_GAIN_MSB,
|
||||
AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_GAIN_LSB);
|
||||
case TAI_HOST_INTERFACE_ATTR_RX_SERIAL_TAP0_DELAY:
|
||||
return ac400_set_field_from_reg_list(host_interface_id, attr->value.u16,
|
||||
AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_DELAY_MSB,
|
||||
AC400_CLIENT_HOST_RX_TAP_0_CNTL_INTF_DELAY_LSB);
|
||||
case TAI_HOST_INTERFACE_ATTR_RX_SERIAL_TAP1_GAIN:
|
||||
return ac400_set_field_from_reg_list(host_interface_id, attr->value.u16,
|
||||
AC400_CLIENT_HOST_RX_TAP_1_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_HOST_RX_TAP_1_CNTL_INTF_GAIN_MSB,
|
||||
AC400_CLIENT_HOST_RX_TAP_1_CNTL_INTF_GAIN_LSB);
|
||||
case TAI_HOST_INTERFACE_ATTR_RX_SERIAL_TAP2_GAIN:
|
||||
return ac400_set_field_from_reg_list(host_interface_id, attr->value.u16,
|
||||
AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_GAIN_MSB,
|
||||
AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_GAIN_LSB);
|
||||
case TAI_HOST_INTERFACE_ATTR_RX_SERIAL_TAP2_DELAY:
|
||||
return ac400_set_field_from_reg_list(host_interface_id, attr->value.u16,
|
||||
AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_0_REG,
|
||||
AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_DELAY_MSB,
|
||||
AC400_CLIENT_HOST_RX_TAP_2_CNTL_INTF_DELAY_LSB);
|
||||
}
|
||||
return TAI_STATUS_ATTR_NOT_SUPPORTED_0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the values from a list of attributes
|
||||
*
|
||||
* @param [in] host_interface_id The host interface ID handle
|
||||
* @param [in] attr_count A count of the number of elements in the attr_list
|
||||
* @param [in] attr_list A list of attributes to be set
|
||||
*
|
||||
* @return TAI_STATUS_SUCCESS on success, failure status code on error
|
||||
*/
|
||||
static tai_status_t ac400_set_host_interface_attributes(
|
||||
_In_ tai_object_id_t host_interface_id,
|
||||
_In_ uint32_t attr_count,
|
||||
_In_ const tai_attribute_t *attr_list)
|
||||
{
|
||||
uint32_t idx;
|
||||
tai_status_t ret;
|
||||
|
||||
for (idx = 0; idx < attr_count; idx++) {
|
||||
ret = ac400_set_host_interface_attribute(host_interface_id, attr_list++);
|
||||
if (ret) {
|
||||
return convert_tai_error_to_list(ret, idx);
|
||||
}
|
||||
}
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Host interface initialization. After the call the capability
|
||||
* attributes should be ready for retrieval via
|
||||
* tai_get_host_interface_attribute().
|
||||
*
|
||||
* @param [out] host_interface_id Handle which identifies the host interface
|
||||
* @param [in] module_id Handle which identifies the module on which the host
|
||||
* interface exists
|
||||
* @param [in] attr_count A count of the number of elements in the attr_list
|
||||
* @param [in] attr_list A list of attributes to set during initialization
|
||||
*
|
||||
* @return TAI_STATUS_SUCCESS on success, failure status code on error
|
||||
*/
|
||||
static tai_status_t ac400_create_host_interface(
|
||||
_Out_ tai_object_id_t *host_interface_id,
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ uint32_t attr_count,
|
||||
_In_ const tai_attribute_t *attr_list)
|
||||
{
|
||||
tai_status_t ret;
|
||||
const tai_attribute_value_t * hostif_addr;
|
||||
ac400_object_id_t *hostif_obj = (ac400_object_id_t *)host_interface_id;
|
||||
ac400_object_id_t *mod_obj = (ac400_object_id_t *)&module_id;
|
||||
int idx;
|
||||
|
||||
hostif_addr = find_attribute_in_list(TAI_HOST_INTERFACE_ATTR_INDEX, attr_count, attr_list);
|
||||
if (NULL == hostif_addr) {
|
||||
TAI_SYSLOG_ERROR("The required TAI_HOST_INTERFACE_ATTR_INDEX attribute was not provided");
|
||||
return TAI_STATUS_MANDATORY_ATTRIBUTE_MISSING;
|
||||
}
|
||||
if (AC400_NUM_HOSTIF <= hostif_addr->u32) {
|
||||
TAI_SYSLOG_ERROR("The TAI_HOST_INTERFACE_ATTR_INDEX attribute is out of range");
|
||||
return TAI_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
idx = ((mod_obj->value-1) * AC400_NUM_HOSTIF) + hostif_addr->u32;
|
||||
hostif_obj->type = TAI_OBJECT_TYPE_HOSTIF;
|
||||
hostif_obj->value = idx;
|
||||
hostif_info[idx].initialized = true;
|
||||
hostif_info[idx].module_id = module_id;
|
||||
hostif_info[idx].hostif_idx = hostif_addr->u32;
|
||||
|
||||
ret = ac400_set_host_interface_attributes(*host_interface_id, attr_count, attr_list);
|
||||
if (TAI_STATUS_SUCCESS != ret) {
|
||||
TAI_SYSLOG_ERROR("Error setting host interface attributes");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release all resources associated with previously created host
|
||||
* interface
|
||||
*
|
||||
* @param [in] host_interface_id The host interface ID handle being removed
|
||||
*
|
||||
* @return TAI_STATUS_SUCCESS on success, failure status code on error
|
||||
*/
|
||||
static tai_status_t ac400_remove_host_interface(_In_ tai_object_id_t host_interface_id)
|
||||
{
|
||||
ac400_object_id_t *hostif_obj = (ac400_object_id_t *)&host_interface_id;
|
||||
|
||||
hostif_info[hostif_obj->value].initialized = false;
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The host interface functions. This structure is retrieved via the
|
||||
* #tai_api_query function.
|
||||
*/
|
||||
tai_host_interface_api_t ac400_host_interface_api = {
|
||||
.create_host_interface = ac400_create_host_interface,
|
||||
.remove_host_interface = ac400_remove_host_interface,
|
||||
.set_host_interface_attribute = ac400_set_host_interface_attribute,
|
||||
.set_host_interface_attributes = ac400_set_host_interface_attributes,
|
||||
.get_host_interface_attribute = ac400_get_host_interface_attribute,
|
||||
.get_host_interface_attributes = ac400_get_host_interface_attributes
|
||||
};
|
||||
|
||||
177
tai_ac400/src/ac400_tai_interface.c
Normal file
177
tai_ac400/src/ac400_tai_interface.c
Normal file
@@ -0,0 +1,177 @@
|
||||
/**
|
||||
* @file ac400_tai_interface.c
|
||||
* @brief The main TAI interface routines
|
||||
* @author Scott Emery <scotte@cumulusnetworks.com>
|
||||
*
|
||||
* @copyright Copyright (C) 2018 Cumulus Networks, Inc. All rights reserved
|
||||
*
|
||||
* @remark This source code is licensed under the BSD 3-Clause license found
|
||||
* in the LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include "voyager_tai_adapter.h"
|
||||
|
||||
#undef __TAI_MODULE__
|
||||
#define __TAI_MODULE__ TAI_API_UNSPECIFIED
|
||||
|
||||
static tai_service_method_table_t adapter_host_fns;
|
||||
static bool initialized = false;
|
||||
static pthread_t module_presence_thread;
|
||||
|
||||
/**
|
||||
* @brief A separate thread which monitors the presence of modules and alerts
|
||||
* the adapter when the state changes.
|
||||
*
|
||||
* @param [in, out] param Not used
|
||||
*/
|
||||
void *module_presence(void *param)
|
||||
{
|
||||
bool absent[VOYAGER_NUM_AC400];
|
||||
ac400_object_id_t ac400_obj;
|
||||
tai_object_id_t *module_id = (tai_object_id_t *) &ac400_obj;
|
||||
int mod;
|
||||
bool mod_abs;
|
||||
char location[2];
|
||||
|
||||
for (mod=0; mod < VOYAGER_NUM_AC400; mod++) {
|
||||
absent[mod] = true;
|
||||
}
|
||||
|
||||
ac400_obj.type = TAI_API_MODULE;
|
||||
while (initialized) {
|
||||
for (mod=0; mod < VOYAGER_NUM_AC400; mod++) {
|
||||
ac400_obj.value = mod+1;
|
||||
if (!ac400_get_mod_abs(*module_id, &mod_abs)) {
|
||||
if (absent[mod] != mod_abs) {
|
||||
if (NULL != adapter_host_fns.module_presence) {
|
||||
TAI_SYSLOG_DEBUG("Module %d is now %s", mod+1, mod_abs ? "absent" : "present");
|
||||
snprintf(location, 2, "%d", mod+1);
|
||||
adapter_host_fns.module_presence(!mod_abs, location);
|
||||
}
|
||||
absent[mod] = mod_abs;
|
||||
}
|
||||
}
|
||||
}
|
||||
usleep(500000);
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adapter module initialization call. This is NOT for SDK
|
||||
* initialization.
|
||||
*
|
||||
* @param [in] flags Reserved for future use, must be zero
|
||||
* @param [in] services Methods table with services provided by adapter host
|
||||
*
|
||||
* @return #TAI_STATUS_SUCCESS on success, failure status code on error
|
||||
*/
|
||||
tai_status_t tai_api_initialize(_In_ uint64_t flags,
|
||||
_In_ const tai_service_method_table_t* services)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (0 != flags) {
|
||||
TAI_SYSLOG_ERROR("Invalid flags passed to TAI API initialize");
|
||||
return TAI_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (NULL == services) {
|
||||
TAI_SYSLOG_ERROR("Invalid services handle passed to TAI API initialize");
|
||||
return TAI_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
memcpy(&adapter_host_fns, services, sizeof(adapter_host_fns));
|
||||
/**
|
||||
* @todo Add initialization calls for the APIs
|
||||
*/
|
||||
initialized = true;
|
||||
|
||||
ret = pthread_create(&module_presence_thread, NULL, module_presence, NULL);
|
||||
if (ret) {
|
||||
TAI_SYSLOG_ERROR("Unable to create module presence thread: %d", ret);
|
||||
}
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve a pointer to the C-style method table for desired TAI
|
||||
* functionality as specified by the given tai_api_id.
|
||||
*
|
||||
* @param [in] tai_api_id TAI api ID
|
||||
* @param [out] api_method_table Caller allocated method table. The table must
|
||||
* remain valid until the tai_api_uninitialize() is called.
|
||||
* @return #TAI_STATUS_SUCCESS on success, failure status code on error
|
||||
*/
|
||||
tai_status_t tai_api_query(_In_ tai_api_t tai_api_id,
|
||||
_Out_ void** api_method_table)
|
||||
{
|
||||
if (!initialized) {
|
||||
TAI_SYSLOG_ERROR("TAI API not initialized before calling API query");
|
||||
return TAI_STATUS_UNINITIALIZED;
|
||||
}
|
||||
if (NULL == api_method_table) {
|
||||
TAI_SYSLOG_ERROR("NULL method table passed to TAI API initialize");
|
||||
return TAI_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (tai_api_id) {
|
||||
case TAI_API_MODULE:
|
||||
*(const tai_module_api_t**)api_method_table = &ac400_module_api;
|
||||
return TAI_STATUS_SUCCESS;
|
||||
|
||||
case TAI_API_HOSTIF:
|
||||
*(const tai_host_interface_api_t**)api_method_table =
|
||||
&ac400_host_interface_api;
|
||||
return TAI_STATUS_SUCCESS;
|
||||
|
||||
case TAI_API_NETWORKIF:
|
||||
*(const tai_network_interface_api_t**)api_method_table =
|
||||
&ac400_network_interface_api;
|
||||
return TAI_STATUS_SUCCESS;
|
||||
|
||||
default:
|
||||
TAI_SYSLOG_ERROR("Invalid API type %d", tai_api_id);
|
||||
return TAI_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Uninitialization of the adapter module. TAI functionalities,
|
||||
* retrieved via tai_api_query() cannot be used after this call.
|
||||
*
|
||||
* @return #TAI_STATUS_SUCCESS on success, failure status code on error
|
||||
*/
|
||||
tai_status_t tai_api_uninitialize(void)
|
||||
{
|
||||
initialized = false;
|
||||
pthread_join(module_presence_thread, NULL);
|
||||
memset(&adapter_host_fns, 0, sizeof(adapter_host_fns));
|
||||
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Query tai object type.
|
||||
*
|
||||
* @param [in] tai_object_id
|
||||
*
|
||||
* @return Return #TAI_OBJECT_TYPE_NULL when tai_object_id is not valid.
|
||||
* Otherwise, return a valid tai object type TAI_OBJECT_TYPE_XXX
|
||||
*/
|
||||
tai_object_type_t tai_object_type_query(_In_ tai_object_id_t tai_object_id)
|
||||
{
|
||||
tai_object_type_t type = ((ac400_object_id_t*)&tai_object_id)->type;
|
||||
|
||||
if (TAI_OBJECT_TYPE_MAX > type) {
|
||||
return type;
|
||||
} else {
|
||||
TAI_SYSLOG_ERROR("Unknown type %d", type);
|
||||
return TAI_OBJECT_TYPE_NULL;
|
||||
}
|
||||
}
|
||||
686
tai_ac400/src/ac400_tai_module.c
Normal file
686
tai_ac400/src/ac400_tai_module.c
Normal file
@@ -0,0 +1,686 @@
|
||||
/**
|
||||
* @file ac400_tai_module.c
|
||||
* @brief The TAI module interface routines
|
||||
* @author Scott Emery <scotte@cumulusnetworks.com>
|
||||
*
|
||||
* @copyright Copyright (C) 2017 Cumulus Networks, Inc. All rights reserved
|
||||
*
|
||||
* @remark This source code is licensed under the BSD 3-Clause license found
|
||||
* in the LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "voyager_tai_adapter.h"
|
||||
|
||||
#undef __TAI_MODULE__
|
||||
#define __TAI_MODULE__ TAI_API_MODULE
|
||||
|
||||
static tai_module_notification_t notification_callbacks;
|
||||
static bool module_init[VOYAGER_NUM_AC400];
|
||||
|
||||
/**
|
||||
* @brief Perform initialization of an AC400 module.
|
||||
*
|
||||
* @param [in] module_id The module which is being initialized
|
||||
*
|
||||
* @return tai_status_t #TAI_STATUS_SUCCESS on success or an error code on
|
||||
* failure.
|
||||
*/
|
||||
static tai_status_t ac400_module_init(_In_ tai_object_id_t module_id)
|
||||
{
|
||||
int ret;
|
||||
int reps;
|
||||
bool glb_alrm;
|
||||
|
||||
/* Power on the AC400 and assert reset, low power, and txdis */
|
||||
ret = ac400_set_reset(module_id, true);
|
||||
if (ret) {
|
||||
TAI_SYSLOG_ERROR("Unable to place module in reset");
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
ret = ac400_set_power(module_id, true);
|
||||
if (ret) {
|
||||
TAI_SYSLOG_ERROR("Unable to turn module power on");
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
ret = ac400_set_mod_lopwr(module_id, true);
|
||||
if (ret) {
|
||||
TAI_SYSLOG_ERROR("Unable to assert the module low power signal");
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
ret = ac400_set_txdis(module_id, 1, true);
|
||||
if (ret) {
|
||||
TAI_SYSLOG_ERROR("Unable to disable transmit power for interface 1");
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
ret = ac400_set_txdis(module_id, 2, true);
|
||||
if (ret) {
|
||||
TAI_SYSLOG_ERROR("Unable to disable transmit power for interface 2");
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
/* Take the module out of reset */
|
||||
ret = ac400_set_reset(module_id, false);
|
||||
if (ret) {
|
||||
TAI_SYSLOG_ERROR("Unable to place module in reset");
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
/* Wait until global alarm is asserted (reset complete) */
|
||||
reps = 100;
|
||||
glb_alrm = false;
|
||||
do {
|
||||
ac400_get_glb_alrm(module_id, &glb_alrm);
|
||||
if (glb_alrm)
|
||||
break;
|
||||
usleep(200000);
|
||||
}
|
||||
while (--reps);
|
||||
if (!reps) {
|
||||
TAI_SYSLOG_ERROR("Timed out waiting for module to complete reset");
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
ret = ac400_set_device_type(1);
|
||||
if (ret) {
|
||||
TAI_SYSLOG_ERROR("Unable to set the MDIO device type");
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the firmware versions from the AC400
|
||||
*
|
||||
* The firmware version attribute is a 2 element list of floating point values.
|
||||
*
|
||||
* @param [in] module_id The AC400 module identifier
|
||||
* @param [in,out] attr The attribute into which the firmware version are placed
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
static tai_status_t ac400_get_fw_versions(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Inout_ tai_attribute_t *attr)
|
||||
{
|
||||
uint16_t word1, word2;
|
||||
|
||||
/* Is there enough room in the attribute array? */
|
||||
if (attr->value.floatlist.count < 2) {
|
||||
attr->value.floatlist.count = 2;
|
||||
return TAI_STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
attr->value.floatlist.count = 2;
|
||||
|
||||
/* Get Firmware A version */
|
||||
if (ac400_mdio_read(module_id, AC400_FIRM_A_VER_NUM_X_REG, &word1)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
if (ac400_mdio_read(module_id, AC400_FIRM_A_VER_NUM_Y_REG, &word2)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
if (word2 >= 100) {
|
||||
attr->value.floatlist.list[0] = (float)word1 + (float)word2 / 1000;
|
||||
}
|
||||
else if (word2 >= 10) {
|
||||
attr->value.floatlist.list[0] = (float)word1 + (float)word2 / 100;
|
||||
}
|
||||
else {
|
||||
attr->value.floatlist.list[0] = (float)word1 + (float)word2 / 10;
|
||||
}
|
||||
|
||||
/* Get Firmware B version */
|
||||
if (ac400_mdio_read(module_id, AC400_FIRM_B_VER_NUM_X_REG, &word1)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
if (ac400_mdio_read(module_id, AC400_FIRM_B_VER_NUM_Y_REG, &word2)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
if (word2 >= 100) {
|
||||
attr->value.floatlist.list[1] = (float)word1 + (float)word2 / 1000;
|
||||
}
|
||||
else if (word2 >= 10) {
|
||||
attr->value.floatlist.list[1] = (float)word1 + (float)word2 / 100;
|
||||
}
|
||||
else {
|
||||
attr->value.floatlist.list[1] = (float)word1 + (float)word2 / 10;
|
||||
}
|
||||
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the operational status of the module
|
||||
*
|
||||
* @param [in] module_id The AC400 module identifier
|
||||
* @param [in,out] attr The attribute into which the operational status (enum)
|
||||
* is placed
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
static tai_status_t ac400_get_tai_oper_status(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Inout_ tai_attribute_t *attr)
|
||||
{
|
||||
ac400_object_id_t *ac400_obj = (ac400_object_id_t *)module_id;
|
||||
|
||||
attr->value.u32 = TAI_MODULE_OPER_STATUS_INITIALIZE;
|
||||
if ( module_init[ac400_obj->value - 1] ) {
|
||||
attr->value.u32 = TAI_MODULE_OPER_STATUS_READY;
|
||||
}
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the operational status of a module
|
||||
*
|
||||
* @param [in] module_id The module identifier
|
||||
* @param [in,out] attr The attribute into which the operational status (enum)
|
||||
* is placed
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
tai_status_t ac400_get_module_oper_status(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Inout_ tai_attribute_t *attr)
|
||||
{
|
||||
uint16_t word;
|
||||
bool reset;
|
||||
|
||||
if (ac400_get_reset(module_id, &reset)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
if (reset) {
|
||||
attr->value.u32 = TAI_NETWORK_INTERFACE_OPER_STATUS_RESET;
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (ac400_mdio_read(module_id, AC400_MOD_STATE_REG, &word)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
if (AC400_GET_BIT(word, AC400_MOD_STATE_HI_PWR_DWN))
|
||||
attr->value.u32 = TAI_NETWORK_INTERFACE_OPER_STATUS_HIGH_POWER_DOWN;
|
||||
else if (AC400_GET_BIT(word, AC400_MOD_STATE_TX_TURN_OFF))
|
||||
attr->value.u32 = TAI_NETWORK_INTERFACE_OPER_STATUS_TX_TURN_OFF;
|
||||
else if (AC400_GET_BIT(word, AC400_MOD_STATE_FAULT))
|
||||
attr->value.u32 = TAI_NETWORK_INTERFACE_OPER_STATUS_FAULT;
|
||||
else if (AC400_GET_BIT(word, AC400_MOD_STATE_READY))
|
||||
attr->value.u32 = TAI_NETWORK_INTERFACE_OPER_STATUS_READY;
|
||||
else if (AC400_GET_BIT(word, AC400_MOD_STATE_TX_TURN_ON))
|
||||
attr->value.u32 = TAI_NETWORK_INTERFACE_OPER_STATUS_TX_TURN_ON;
|
||||
else if (AC400_GET_BIT(word, AC400_MOD_STATE_TX_OFF))
|
||||
attr->value.u32 = TAI_NETWORK_INTERFACE_OPER_STATUS_TX_OFF;
|
||||
else if (AC400_GET_BIT(word, AC400_MOD_STATE_HI_PWR_UP))
|
||||
attr->value.u32 = TAI_NETWORK_INTERFACE_OPER_STATUS_HIGH_POWER_UP;
|
||||
else if (AC400_GET_BIT(word, AC400_MOD_STATE_LOW_PWR))
|
||||
attr->value.u32 = TAI_NETWORK_INTERFACE_OPER_STATUS_LOW_POWER;
|
||||
else if (AC400_GET_BIT(word, AC400_MOD_STATE_INIT))
|
||||
attr->value.u32 = TAI_NETWORK_INTERFACE_OPER_STATUS_INITIALIZE;
|
||||
else
|
||||
attr->value.u32 = TAI_NETWORK_INTERFACE_OPER_STATUS_UNKNOWN;
|
||||
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the operational status of the module
|
||||
*
|
||||
* @param [in] module_id The module identifier
|
||||
* @param [in,out] attr The attribute which contains the operational status to
|
||||
* set.
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
tai_status_t ac400_set_module_oper_status(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ const tai_attribute_t *attr)
|
||||
{
|
||||
bool modRst = false;
|
||||
bool modLoPwr = false;
|
||||
bool modTxDis = false;
|
||||
tai_attribute_t prev_state;
|
||||
tai_attribute_t curr_state;
|
||||
int reps;
|
||||
bool glb_alrm;
|
||||
int waitTime;
|
||||
int sleepTime;
|
||||
|
||||
/* Get the current module state */
|
||||
prev_state.id = TAI_NETWORK_INTERFACE_ATTR_OPER_STATUS;
|
||||
if (TAI_STATUS_SUCCESS != ac400_get_module_oper_status(module_id, &prev_state)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
/* Figure out which signals to set/clear */
|
||||
switch (attr->value.u32) {
|
||||
case TAI_NETWORK_INTERFACE_OPER_STATUS_RESET:
|
||||
modRst = true; /* fallthrough */
|
||||
case TAI_NETWORK_INTERFACE_OPER_STATUS_LOW_POWER:
|
||||
modLoPwr = true; /* fallthrough */
|
||||
case TAI_NETWORK_INTERFACE_OPER_STATUS_TX_OFF:
|
||||
modTxDis = true; /* fallthrough */
|
||||
case TAI_NETWORK_INTERFACE_OPER_STATUS_READY:
|
||||
break;
|
||||
default:
|
||||
return TAI_STATUS_INVALID_ATTRIBUTE_0;
|
||||
}
|
||||
|
||||
/* Change the module state */
|
||||
if (ac400_set_reset(module_id, modRst)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
if (ac400_set_mod_lopwr(module_id, modLoPwr)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
if (ac400_set_txdis(module_id, 1, modTxDis)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
if (ac400_set_txdis(module_id, 2, modTxDis)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
/* If coming out of reset, Wait until global alarm is asserted */
|
||||
if (prev_state.value.u32 == TAI_NETWORK_INTERFACE_OPER_STATUS_RESET &&
|
||||
attr->value.u32 != TAI_NETWORK_INTERFACE_OPER_STATUS_RESET) {
|
||||
reps = 100;
|
||||
glb_alrm = false;
|
||||
do {
|
||||
ac400_get_glb_alrm(module_id, &glb_alrm);
|
||||
if (glb_alrm)
|
||||
break;
|
||||
usleep(200000);
|
||||
}
|
||||
while (--reps);
|
||||
if (!reps) {
|
||||
TAI_SYSLOG_ERROR("Timed out waiting for module to complete reset");
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait until the module enters the requested state */
|
||||
sleepTime = 25;
|
||||
waitTime = ac400_get_transition_time(prev_state.value.u32, attr->value.u32) * 1000000;
|
||||
do {
|
||||
/* First time through, don't sleep. */
|
||||
if (25 != sleepTime) {
|
||||
usleep(sleepTime);
|
||||
waitTime -= sleepTime;
|
||||
}
|
||||
/* Double sleep time each loop, with a 1/2 sec max */
|
||||
sleepTime = (sleepTime*2 < 500000) ? sleepTime*2 : 500000;
|
||||
|
||||
curr_state.id = TAI_NETWORK_INTERFACE_ATTR_OPER_STATUS;
|
||||
if (TAI_STATUS_SUCCESS != ac400_get_module_oper_status(module_id, &curr_state)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
if (curr_state.value.u32 == attr->value.u32) {
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
while (waitTime > 0);
|
||||
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the operational mode of the network interfaces
|
||||
*
|
||||
* @param [in] module_id The AC400 module identifier
|
||||
* @param [in,out] attr The attribute into which the operational mode (enum) is
|
||||
* placed
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
tai_status_t ac400_get_network_mode(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Inout_ tai_attribute_t *attr)
|
||||
{
|
||||
uint16_t word;
|
||||
|
||||
if (ac400_mdio_read(module_id, AC400_DEVICE_SETUP_CNTL_REG, &word)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
switch (AC400_GET_FIELD(word, AC400_DEVICE_SETUP_CNTL_DEV_CFG)) {
|
||||
case 0:
|
||||
attr->value.u32 = TAI_MODULE_NETWORK_MODE_INDEPENDENT;
|
||||
break;
|
||||
case 1:
|
||||
attr->value.u32 = TAI_MODULE_NETWORK_MODE_COUPLED;
|
||||
break;
|
||||
default:
|
||||
attr->value.u32 = TAI_MODULE_NETWORK_MODE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the operational mode of the network interfaces
|
||||
*
|
||||
* @param [in] module_id The AC400 module identifier
|
||||
* @param [in,out] attr The attribute which contains the mode to set.
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
static tai_status_t ac400_set_network_mode(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ const tai_attribute_t *attr)
|
||||
{
|
||||
uint16_t mode;
|
||||
tai_status_t ret;
|
||||
tai_attribute_t prev_state;
|
||||
tai_attribute_t lopwr_state;
|
||||
|
||||
switch (attr->value.u32) {
|
||||
case TAI_MODULE_NETWORK_MODE_INDEPENDENT:
|
||||
mode = 0;
|
||||
break;
|
||||
case TAI_MODULE_NETWORK_MODE_COUPLED:
|
||||
mode = 1;
|
||||
break;
|
||||
default:
|
||||
return TAI_STATUS_INVALID_ATTRIBUTE_0;
|
||||
}
|
||||
|
||||
ret = ac400_get_module_oper_status(module_id, &prev_state);
|
||||
if (TAI_STATUS_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
if (TAI_NETWORK_INTERFACE_OPER_STATUS_LOW_POWER != prev_state.value.u32) {
|
||||
lopwr_state.value.u32 = TAI_NETWORK_INTERFACE_OPER_STATUS_LOW_POWER;
|
||||
ret = ac400_set_module_oper_status(module_id, &lopwr_state);
|
||||
if (TAI_STATUS_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (ac400_mdio_write(module_id, AC400_DEVICE_SETUP_CNTL_REG, mode)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
if (TAI_NETWORK_INTERFACE_OPER_STATUS_LOW_POWER != prev_state.value.u32) {
|
||||
ret = ac400_set_module_oper_status(module_id, &prev_state);
|
||||
if (TAI_STATUS_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the temperature of the module, in degrees celsius
|
||||
*
|
||||
* @param [in] module_id The AC400 module identifier
|
||||
* @param [in,out] attr The attribute into which the module temperature (float)
|
||||
* is placed
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
static tai_status_t ac400_get_module_temp(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Inout_ tai_attribute_t *attr)
|
||||
{
|
||||
uint16_t word;
|
||||
|
||||
if (ac400_mdio_read(module_id, AC400_TEMP_MON_A2D_VAL_REG, &word)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
attr->value.flt = (int16_t) word / 256.0;
|
||||
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the power (voltage) supplied to the module
|
||||
*
|
||||
* @param [in] module_id The AC400 module identifier
|
||||
* @param [in,out] attr The attribute into which the module power (float) is
|
||||
* placed
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
static tai_status_t ac400_get_module_power(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Inout_ tai_attribute_t *attr)
|
||||
{
|
||||
uint16_t word;
|
||||
|
||||
if (ac400_mdio_read(module_id, AC400_MOD_PS_MON_A2D_VAL_REG, &word)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
attr->value.flt = word / 1000.0;
|
||||
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the value of an attribute
|
||||
*
|
||||
* @param [in] module_id The module ID handle
|
||||
* @param [in,out] attr A pointer to the attribute to be retrieved
|
||||
*
|
||||
* @return TAI_STATUS_SUCCESS on success, failure status code on error
|
||||
*/
|
||||
static tai_status_t ac400_get_module_attribute(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Inout_ tai_attribute_t *attr)
|
||||
{
|
||||
char location[TAI_MAX_HARDWARE_ID_LEN+1];
|
||||
uint32_t len;
|
||||
|
||||
TAI_SYSLOG_DEBUG("Retrieving module attribute: %d", attr->id);
|
||||
switch (attr->id) {
|
||||
case TAI_MODULE_ATTR_LOCATION:
|
||||
ac400_get_module_location(module_id, location);
|
||||
len = strlen(location);
|
||||
if (attr->value.charlist.count < len+1) {
|
||||
attr->value.charlist.count = len+1;
|
||||
return TAI_STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
attr->value.charlist.count = len+1;
|
||||
strcpy(attr->value.charlist.list, location);
|
||||
return TAI_STATUS_SUCCESS;
|
||||
case TAI_MODULE_ATTR_VENDOR_NAME:
|
||||
return ac400_get_string(module_id, attr, AC400_VEND_NAME_BYTE_1_REG, 16);
|
||||
case TAI_MODULE_ATTR_VENDOR_PART_NUMBER:
|
||||
return ac400_get_string(module_id, attr, AC400_VEND_PN_BYTE_1_REG, 16);
|
||||
case TAI_MODULE_ATTR_VENDOR_SERIAL_NUMBER:
|
||||
return ac400_get_string(module_id, attr, AC400_VEND_SN_BYTE_1_REG, 16);
|
||||
case TAI_MODULE_ATTR_FIRMWARE_VERSIONS:
|
||||
return ac400_get_fw_versions(module_id, attr);
|
||||
case TAI_MODULE_ATTR_OPER_STATUS:
|
||||
return ac400_get_tai_oper_status(module_id, attr);
|
||||
case TAI_MODULE_ATTR_NETWORK_MODE:
|
||||
return ac400_get_network_mode(module_id, attr);
|
||||
case TAI_MODULE_ATTR_TEMP:
|
||||
return ac400_get_module_temp(module_id, attr);
|
||||
case TAI_MODULE_ATTR_POWER:
|
||||
return ac400_get_module_power(module_id, attr);
|
||||
case TAI_MODULE_ATTR_NUM_HOST_INTERFACES:
|
||||
attr->value.u32 = AC400_NUM_HOSTIF;
|
||||
return TAI_STATUS_SUCCESS;
|
||||
case TAI_MODULE_ATTR_NUM_NETWORK_INTERFACES:
|
||||
attr->value.u32 = AC400_NUM_NETIF;
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
return TAI_STATUS_ATTR_NOT_SUPPORTED_0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve a list of attribute values
|
||||
*
|
||||
* @param [in] module_id The module ID handle
|
||||
* @param [in] attr_count A count of the number of elements in the attr_list
|
||||
* @param [in,out] attr_list A list of attributes to be retrieved
|
||||
*
|
||||
* @return TAI_STATUS_SUCCESS on success, failure status code on error
|
||||
*/
|
||||
static tai_status_t ac400_get_module_attributes(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ uint32_t attr_count,
|
||||
_Inout_ tai_attribute_t *attr_list)
|
||||
{
|
||||
uint32_t idx;
|
||||
tai_status_t ret;
|
||||
|
||||
for (idx = 0; idx < attr_count; idx++) {
|
||||
ret = ac400_get_module_attribute(module_id, attr_list++);
|
||||
if (ret) {
|
||||
return convert_tai_error_to_list(ret, idx);
|
||||
}
|
||||
}
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the value of an attribute
|
||||
*
|
||||
* @param [in] module_id The module ID handle
|
||||
* @param [in] attr A pointer to the attribute to be set
|
||||
*
|
||||
* @return TAI_STATUS_SUCCESS on success, failure status code on error
|
||||
*/
|
||||
static tai_status_t ac400_set_module_attribute(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ const tai_attribute_t *attr)
|
||||
{
|
||||
TAI_SYSLOG_DEBUG("Setting module attribute: %d", attr->id);
|
||||
switch (attr->id) {
|
||||
case TAI_MODULE_ATTR_LOCATION:
|
||||
return TAI_STATUS_SUCCESS;
|
||||
case TAI_MODULE_ATTR_VENDOR_NAME:
|
||||
case TAI_MODULE_ATTR_VENDOR_PART_NUMBER:
|
||||
case TAI_MODULE_ATTR_VENDOR_SERIAL_NUMBER:
|
||||
case TAI_MODULE_ATTR_FIRMWARE_VERSIONS:
|
||||
case TAI_MODULE_ATTR_TEMP:
|
||||
case TAI_MODULE_ATTR_POWER:
|
||||
case TAI_MODULE_ATTR_NUM_HOST_INTERFACES:
|
||||
case TAI_MODULE_ATTR_NUM_NETWORK_INTERFACES:
|
||||
case TAI_MODULE_ATTR_OPER_STATUS:
|
||||
return TAI_STATUS_INVALID_ATTRIBUTE_0;
|
||||
case TAI_MODULE_ATTR_NETWORK_MODE:
|
||||
return ac400_set_network_mode(module_id, attr);
|
||||
}
|
||||
return TAI_STATUS_ATTR_NOT_SUPPORTED_0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the values from a list of attributes
|
||||
*
|
||||
* @param [in] module_id The module ID handle
|
||||
* @param [in] attr_count A count of the number of elements in the attr_list
|
||||
* @param [in] attr_list A list of attributes to be set
|
||||
*
|
||||
* @return TAI_STATUS_SUCCESS on success, failure status code on error
|
||||
*/
|
||||
static tai_status_t ac400_set_module_attributes(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ uint32_t attr_count,
|
||||
_In_ const tai_attribute_t *attr_list)
|
||||
{
|
||||
uint32_t idx;
|
||||
tai_status_t ret;
|
||||
|
||||
for (idx = 0; idx < attr_count; idx++) {
|
||||
ret = ac400_set_module_attribute(module_id, attr_list++);
|
||||
if (ret) {
|
||||
return convert_tai_error_to_list(ret, idx);
|
||||
}
|
||||
}
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Module initialization. After the call the capability attributes should
|
||||
* be ready for retrieval via tai_get_module_attribute().
|
||||
*
|
||||
* @param [out] module_id Handle which identifies the module
|
||||
* @param [in] attr_count A count of the number of elements in the attr_list
|
||||
* @param [in] attr_list A list of attributes to set during initialization
|
||||
* @param [in] notifications Function pointers for adapter host notifications
|
||||
*
|
||||
* @return TAI_STATUS_SUCCESS on success, failure status code on error
|
||||
*/
|
||||
static tai_status_t ac400_create_module(
|
||||
_Out_ tai_object_id_t *module_id,
|
||||
_In_ uint32_t attr_count,
|
||||
_In_ const tai_attribute_t *attr_list,
|
||||
_In_ tai_module_notification_t *notifications)
|
||||
{
|
||||
tai_status_t ret;
|
||||
const tai_attribute_value_t * mod_addr;
|
||||
ac400_object_id_t *ac400_obj = (ac400_object_id_t *)module_id;
|
||||
|
||||
if (NULL == notifications) {
|
||||
TAI_SYSLOG_ERROR("NULL module notifications passed to TAI switch initialize");
|
||||
return TAI_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
mod_addr = find_attribute_in_list(TAI_MODULE_ATTR_LOCATION, attr_count, attr_list);
|
||||
if (NULL == mod_addr) {
|
||||
TAI_SYSLOG_ERROR("The required TAI_MODULE_ATTR_LOCATION attribute was not provided");
|
||||
return TAI_STATUS_MANDATORY_ATTRIBUTE_MISSING;
|
||||
}
|
||||
|
||||
ret = ac400_set_module_id(mod_addr, module_id);
|
||||
if (ret) {
|
||||
TAI_SYSLOG_ERROR("Invalid TAI_MODULE_ATTR_LOCATION attribute value.");
|
||||
return TAI_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ret = ac400_module_init(*module_id);
|
||||
if (TAI_STATUS_SUCCESS != ret) {
|
||||
TAI_SYSLOG_ERROR("Module initialization failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
module_init[ac400_obj->value - 1] = true;
|
||||
|
||||
ret = ac400_set_module_attributes(*module_id, attr_count, attr_list);
|
||||
if (TAI_STATUS_SUCCESS != ret) {
|
||||
TAI_SYSLOG_ERROR("Error setting module attributes");
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy(¬ification_callbacks, notifications, sizeof(notification_callbacks));
|
||||
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release all resources associated with previously created module
|
||||
*
|
||||
* @param [in] module_id The module ID handle being removed
|
||||
*
|
||||
* @return TAI_STATUS_SUCCESS on success, failure status code on error
|
||||
*/
|
||||
static tai_status_t ac400_remove_module(_In_ tai_object_id_t module_id)
|
||||
{
|
||||
ac400_object_id_t *ac400_obj = (ac400_object_id_t *)&module_id;
|
||||
|
||||
module_init[ac400_obj->value - 1] = false;
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The module interface functions. This structure is retrieved via the
|
||||
* #tai_api_query function.
|
||||
*/
|
||||
tai_module_api_t ac400_module_api = {
|
||||
.create_module = ac400_create_module,
|
||||
.remove_module = ac400_remove_module,
|
||||
.set_module_attribute = ac400_set_module_attribute,
|
||||
.set_module_attributes = ac400_set_module_attributes,
|
||||
.get_module_attribute = ac400_get_module_attribute,
|
||||
.get_module_attributes = ac400_get_module_attributes
|
||||
};
|
||||
|
||||
1570
tai_ac400/src/ac400_tai_networkif.c
Normal file
1570
tai_ac400/src/ac400_tai_networkif.c
Normal file
File diff suppressed because it is too large
Load Diff
243
tai_ac400/src/ac400_tai_utils.c
Normal file
243
tai_ac400/src/ac400_tai_utils.c
Normal file
@@ -0,0 +1,243 @@
|
||||
/**
|
||||
* @file ac400_tai_utils.c
|
||||
* @brief The TAI utility routines used by various TAI APIs
|
||||
* @author Scott Emery <scotte@cumulusnetworks.com>
|
||||
*
|
||||
* @copyright Copyright (C) 2018 Cumulus Networks, Inc. All rights reserved
|
||||
*
|
||||
* @remark This source code is licensed under the BSD 3-Clause license found
|
||||
* in the LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include "voyager_tai_adapter.h"
|
||||
|
||||
#undef __TAI_MODULE__
|
||||
#define __TAI_MODULE__ TAI_API_UNSPECIFIED
|
||||
|
||||
/**
|
||||
* @brief Given a TAI logging level, convert to a syslog level.
|
||||
*/
|
||||
static int tai_to_syslog_level[TAI_LOG_LEVEL_MAX] = {
|
||||
[TAI_LOG_LEVEL_DEBUG] = LOG_DEBUG,
|
||||
[TAI_LOG_LEVEL_INFO] = LOG_INFO,
|
||||
[TAI_LOG_LEVEL_NOTICE] = LOG_NOTICE,
|
||||
[TAI_LOG_LEVEL_WARN] = LOG_WARNING,
|
||||
[TAI_LOG_LEVEL_ERROR] = LOG_ERR,
|
||||
[TAI_LOG_LEVEL_CRITICAL] = LOG_CRIT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Given a TAI module, retrieve the syslog level for that module. This is
|
||||
* set by calling the #tai_log_set function. The default is WARNING.
|
||||
*/
|
||||
static int api_log_level[TAI_API_MAX] = {
|
||||
[0 ... TAI_API_MAX-1] = LOG_WARNING
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Log a message to the syslog facility. The message may be filtered
|
||||
* based on the TAI API's previously set logging level.
|
||||
*
|
||||
* @param [in] tai_api_id The TAI API logging this message
|
||||
* @param [in] log_level The TAI message priority
|
||||
* @param [in] format A printf-like format string
|
||||
*/
|
||||
void tai_syslog(_In_ tai_api_t tai_api_id, _In_ tai_log_level_t log_level,
|
||||
_In_ const char *format, ...)
|
||||
{
|
||||
int prevmask;
|
||||
va_list arglist;
|
||||
|
||||
if ((TAI_API_UNSPECIFIED > tai_api_id) || (TAI_API_MAX <= tai_api_id)) {
|
||||
tai_api_id = TAI_API_UNSPECIFIED;
|
||||
}
|
||||
if ((TAI_LOG_LEVEL_DEBUG > log_level) || (TAI_LOG_LEVEL_MAX <= log_level)) {
|
||||
log_level = TAI_LOG_LEVEL_ERROR;
|
||||
}
|
||||
prevmask = setlogmask(LOG_UPTO(api_log_level[tai_api_id]));
|
||||
va_start(arglist, format);
|
||||
vsyslog(tai_to_syslog_level[log_level], format, arglist);
|
||||
va_end(arglist);
|
||||
setlogmask(prevmask);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set log level for a tai api module. The default log level is
|
||||
* TAI_LOG_WARN.
|
||||
*
|
||||
* @param [in] tai_api_id - TAI api ID
|
||||
* @param [in] log_level - log level
|
||||
*
|
||||
* @return #TAI_STATUS_SUCCESS on success, failure status code on error
|
||||
*/
|
||||
tai_status_t tai_log_set(_In_ tai_api_t tai_api_id,
|
||||
_In_ tai_log_level_t log_level)
|
||||
{
|
||||
if ((TAI_API_UNSPECIFIED > tai_api_id) || (TAI_API_MAX <= tai_api_id)) {
|
||||
TAI_SYSLOG_ERROR("Invalid API type %d", tai_api_id);
|
||||
return TAI_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((TAI_LOG_LEVEL_DEBUG > log_level) || (TAI_LOG_LEVEL_MAX <= log_level)) {
|
||||
TAI_SYSLOG_ERROR("Invalid log level %d\n", log_level);
|
||||
return TAI_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
api_log_level[tai_api_id] = tai_to_syslog_level[log_level];
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find an attribute in a list of attributes
|
||||
*
|
||||
* @param [in] attr_id The attribute ID to find
|
||||
* @param [in] attr_count The number of attributes in the list
|
||||
* @param [in] attr_list A list of attributes
|
||||
*
|
||||
* @return tai_attribute_value_t* A pointer to the attribute's value, or NULL if
|
||||
* not found.
|
||||
*/
|
||||
const tai_attribute_value_t * find_attribute_in_list(
|
||||
_In_ tai_attr_id_t attr_id,
|
||||
_In_ uint32_t attr_count,
|
||||
_In_ const tai_attribute_t *attr_list)
|
||||
{
|
||||
while (attr_count--) {
|
||||
if (attr_list->id == attr_id) {
|
||||
return &attr_list->value;
|
||||
}
|
||||
attr_list++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a TAI status code to an indexed status code
|
||||
*
|
||||
* If the status code in 'err' is one of the codes for a list of attributes, the
|
||||
* index value is added to that code. Otherwise the 'err' code is returned.
|
||||
*
|
||||
* @param err A TAI_STATUS_* code
|
||||
* @param idx An index into a list of attributes
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
tai_status_t convert_tai_error_to_list( _In_ tai_status_t err, _In_ uint32_t idx)
|
||||
{
|
||||
if (TAI_STATUS_INVALID_ATTRIBUTE_0 == err ||
|
||||
TAI_STATUS_INVALID_ATTR_VALUE_0 == err ||
|
||||
TAI_STATUS_ATTR_NOT_IMPLEMENTED_0 == err ||
|
||||
TAI_STATUS_UNKNOWN_ATTRIBUTE_0 == err ||
|
||||
TAI_STATUS_ATTR_NOT_SUPPORTED_0 == err) {
|
||||
return TAI_STATUS_CODE(TAI_STATUS_CODE(err) + idx);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve a string from the AC400 and store it in a character array
|
||||
* attribute. Trailing spaces, if any, are removed.
|
||||
*
|
||||
* NOTE: A 16-byte string in the AC400 hardware requires a 17-byte character
|
||||
* array attribute, because an extra NULL byte is added at the end.
|
||||
*
|
||||
* @param module_id The module identifier of the AC400 module
|
||||
* @param attr The character array attribute
|
||||
* @param reg_addr The starting MDIO register address of the string
|
||||
* @param str_len The length of the string in the AC400 (does not include any
|
||||
* trailing null)
|
||||
*
|
||||
* @return tai_status_t
|
||||
*/
|
||||
tai_status_t ac400_get_string(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Inout_ tai_attribute_t *attr,
|
||||
_In_ uint16_t reg_addr,
|
||||
_In_ uint32_t str_len)
|
||||
{
|
||||
char *cp;
|
||||
char *last_char;
|
||||
uint16_t word1;
|
||||
|
||||
/* Is there enough room in the attribute array? */
|
||||
if (attr->value.charlist.count <= str_len) {
|
||||
attr->value.charlist.count = str_len+1;
|
||||
return TAI_STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
attr->value.charlist.count = str_len+1;
|
||||
cp = attr->value.charlist.list;
|
||||
last_char = cp-1;
|
||||
|
||||
while (str_len--) {
|
||||
if (ac400_mdio_read(module_id, reg_addr++, &word1)) {
|
||||
return TAI_STATUS_FAILURE;
|
||||
}
|
||||
if ((word1 & 0x00FF) != ' ') {
|
||||
last_char = cp;
|
||||
}
|
||||
*cp++ = word1 & 0x00FF;
|
||||
}
|
||||
*(last_char+1) = 0;
|
||||
return TAI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Retrieves the maximum amount of time, in seconds, it takes to
|
||||
* transition between two AC400 states.
|
||||
*
|
||||
* NOTE: These values were obtained from the AC400 module registers which
|
||||
* specify the maximum amount of time which transitory states can take.
|
||||
*
|
||||
* @param [in] prevState The previous state of the network interface
|
||||
* @param [in] nextState The next state of the network interface
|
||||
*
|
||||
* @return The time, in seconds.
|
||||
*/
|
||||
int ac400_get_transition_time(
|
||||
tai_network_interface_oper_status_t prevState,
|
||||
tai_network_interface_oper_status_t nextState)
|
||||
{
|
||||
/* This 2D array provides the maximum amount of time it takes to
|
||||
transition from one module state to another, through the shortest path.
|
||||
The rows are the previous state and the columns are the new state.
|
||||
Entries are time, in seconds. Since we can only transition to four new
|
||||
states, only four columns are filled out. */
|
||||
int transTime[TAI_NETWORK_INTERFACE_OPER_STATUS_MAX][TAI_NETWORK_INTERFACE_OPER_STATUS_MAX] = {
|
||||
/* New state
|
||||
T H
|
||||
L T x i
|
||||
U o H x T P
|
||||
n w i T u w
|
||||
k R P P T u R r r F
|
||||
n e I o w x r e n D a
|
||||
o s n w r O n a O o u
|
||||
w e i e U f O d f w l
|
||||
Previous State n t t r p f n y f n t */
|
||||
/* TAI_NETWORK_INTERFACE_OPER_STATUS_UNKNOWN */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* TAI_NETWORK_INTERFACE_OPER_STATUS_RESET */ { 0, 0, 0, 20,20,200,200,201,201,200, 0 },
|
||||
/* TAI_NETWORK_INTERFACE_OPER_STATUS_INITIALIZE */ { 0, 0, 0, 20,20,200,200,201,201,200, 0 },
|
||||
/* TAI_NETWORK_INTERFACE_OPER_STATUS_LOW_POWER */ { 0, 0, 0, 0, 0,180,180,181,181,180, 0 },
|
||||
/* TAI_NETWORK_INTERFACE_OPER_STATUS_HIGH_POWER_UP */ { 0, 0, 0,190, 0,180,180,181,181,180, 0 },
|
||||
/* TAI_NETWORK_INTERFACE_OPER_STATUS_TX_OFF */ { 0, 0, 0, 10,10, 0, 0, 1, 1, 0, 0 },
|
||||
/* TAI_NETWORK_INTERFACE_OPER_STATUS_TX_TURN_ON */ { 0, 0, 0, 12,12, 2, 0, 1, 1, 2, 0 },
|
||||
/* TAI_NETWORK_INTERFACE_OPER_STATUS_READY */ { 0, 0, 0, 11,11, 1, 1, 0, 0, 1, 0 },
|
||||
/* TAI_NETWORK_INTERFACE_OPER_STATUS_TX_TURN_OFF */ { 0, 0, 0, 11,11, 1, 1, 2, 0, 1, 0 },
|
||||
/* TAI_NETWORK_INTERFACE_OPER_STATUS_HIGH_POWER_DOWN */ { 0, 0, 0, 10,10,190,190,191,191, 0, 0 },
|
||||
/* TAI_NETWORK_INTERFACE_OPER_STATUS_FAULT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
/* Are the states valid? */
|
||||
if ((TAI_NETWORK_INTERFACE_OPER_STATUS_MAX < prevState) ||
|
||||
(TAI_NETWORK_INTERFACE_OPER_STATUS_MAX < nextState)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return transTime[prevState][nextState];
|
||||
}
|
||||
492
tai_ac400/src/ac400_voyager.c
Normal file
492
tai_ac400/src/ac400_voyager.c
Normal file
@@ -0,0 +1,492 @@
|
||||
/**
|
||||
* @file ac400_voyager.c
|
||||
* @brief Interface routes to the AC400 on a Voyager platform
|
||||
* @author Scott Emery <scotte@cumulusnetworks.com>
|
||||
*
|
||||
* This file contains all of the routines which interface to the AC400 on the
|
||||
* Voyager platform. Any code which is specific to the Voyager platform is
|
||||
* included in this file.
|
||||
*
|
||||
* @copyright Copyright (C) 2018 Cumulus Networks, Inc. All rights reserved
|
||||
*
|
||||
* @remark This source code is licensed under the BSD 3-Clause license found
|
||||
* in the LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include "voyager_tai_adapter.h"
|
||||
|
||||
#undef __TAI_MODULE__
|
||||
#define __TAI_MODULE__ TAI_API_UNSPECIFIED
|
||||
|
||||
static char fname[PATH_MAX];
|
||||
static pthread_mutex_t mod_abs_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/**
|
||||
* @brief Get the value of a given tai object id. Does no error checking.
|
||||
*
|
||||
* @param obj_id [in] The object ID
|
||||
*
|
||||
* @return int The value field from the object id
|
||||
*/
|
||||
static int get_obj_val(_In_ tai_object_id_t obj_id)
|
||||
{
|
||||
ac400_object_id_t *ac400_obj = (ac400_object_id_t *)&obj_id;
|
||||
return ac400_obj->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the value of an integer from a file. The file is expected to
|
||||
* contain only either a decimal, hexadecimal, or octal value.
|
||||
*
|
||||
* @param [in] file The name of the file to read
|
||||
* @param [out] value A pointer to an integer into which the value will be
|
||||
* placed.
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
static int read_int_from_file(_In_ char * file, _Out_ int *value)
|
||||
{
|
||||
FILE *fp;
|
||||
int ret;
|
||||
|
||||
fp = fopen(file, "r");
|
||||
if (NULL == fp) {
|
||||
return EIO;
|
||||
}
|
||||
|
||||
ret = fscanf(fp, "%i", value);
|
||||
fclose(fp);
|
||||
return (1 == ret) ? 0 : EIO;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the value of a signal from a file. The file is expected to
|
||||
* contain either '0' or '1' as the first character.
|
||||
*
|
||||
* @param [in] file The name of the file to read
|
||||
* @param [out] signal A pointer to a boolean into which the signals value (the
|
||||
* first character of the file) will be placed.
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
static int read_signal_from_file(_In_ char * file, _Out_ bool *signal)
|
||||
{
|
||||
int inval;
|
||||
int ret;
|
||||
|
||||
ret = read_int_from_file(file, &inval);
|
||||
*signal = (inval != 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the value of an integer to a file.
|
||||
*
|
||||
* @param [in] file The name of the file to write
|
||||
* @param [in] value An integer to write to the file
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
static int write_int_to_file(_In_ char * file, _In_ int value)
|
||||
{
|
||||
FILE *fp;
|
||||
int ret;
|
||||
|
||||
fp = fopen(file, "w");
|
||||
if (NULL == fp) {
|
||||
return EIO;
|
||||
}
|
||||
|
||||
ret = fprintf(fp, "%d", value);
|
||||
fclose(fp);
|
||||
return (ret >= 0) ? 0 : EIO;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the value of a signal to a file. Either '0' or '1' is written
|
||||
* to the file.
|
||||
*
|
||||
* @param [in] file The name of the file to write
|
||||
* @param [in] signal A boolean which specifies the value of the signal to be
|
||||
* written to the file, false == '0' and true == '1'
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
static int write_signal_to_file(_In_ char * file, _In_ bool signal)
|
||||
{
|
||||
int inval = (signal) ? 1 : 0;
|
||||
return write_int_to_file(file, inval);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the value of the global alarm signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [out] glb_alrm A pointer to a bool to place the current global alarm
|
||||
* value.
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_get_glb_alrm(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Out_ bool *glb_alrm)
|
||||
{
|
||||
snprintf(fname, PATH_MAX, "%s/ac400_%d_glb_alarm", CPLD_PATH,
|
||||
get_obj_val(module_id));
|
||||
return read_signal_from_file(fname, glb_alrm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the value of the RXLOS signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] networkif The number of the network interface, 1 or 2
|
||||
* @param [out] rxlos A pointer to a bool to place the current rxlos value.
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_get_rxlos(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ int networkif,
|
||||
_Out_ bool *rxlos)
|
||||
{
|
||||
snprintf(fname, PATH_MAX, "%s/ac400_%d_rxlos%d", CPLD_PATH,
|
||||
get_obj_val(module_id), networkif);
|
||||
return read_signal_from_file(fname, rxlos);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the value of the MOD_ABS ignal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [out] mod_abs A pointer to a bool to place the current mod_abs value.
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_get_mod_abs(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Out_ bool *mod_abs)
|
||||
{
|
||||
char fname[PATH_MAX];
|
||||
int ret;
|
||||
|
||||
pthread_mutex_lock(&mod_abs_mutex);
|
||||
snprintf(fname, PATH_MAX, "%s/ac400_%d_mod_absent", CPLD_PATH,
|
||||
get_obj_val(module_id));
|
||||
ret = read_signal_from_file(fname, mod_abs);
|
||||
pthread_mutex_unlock(&mod_abs_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the value of the TXDIS signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] networkif The number of the network interface, 1 or 2
|
||||
* @param [out] txdis A pointer to a bool to place the current txdis value.
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_get_txdis(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ int networkif,
|
||||
_Out_ bool *txdis)
|
||||
{
|
||||
snprintf(fname, PATH_MAX, "%s/ac400_%d_tx_disable%d", CPLD_PATH,
|
||||
get_obj_val(module_id), networkif-1);
|
||||
return read_signal_from_file(fname, txdis);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the value of the TXDIS signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] networkif The number of the network interface, 1 or 2
|
||||
* @param [in] txdis The value to set the txdis signal
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_set_txdis(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ int networkif,
|
||||
_In_ bool txdis)
|
||||
{
|
||||
snprintf(fname, PATH_MAX, "%s/ac400_%d_tx_disable%d", CPLD_PATH,
|
||||
get_obj_val(module_id), networkif-1);
|
||||
return write_signal_to_file(fname, txdis);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the value of the MOD_LOPWR signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [out] mod_lopwr A pointer to a bool to place the current mod_lopwr
|
||||
* value.
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_get_mod_lopwr(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Out_ bool *mod_lopwr)
|
||||
{
|
||||
snprintf(fname, PATH_MAX, "%s/ac400_%d_mod_lopwr", CPLD_PATH,
|
||||
get_obj_val(module_id));
|
||||
return read_signal_from_file(fname, mod_lopwr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the value of the MOD_LOPWR signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] mod_lopwr The value to set the mod_lopwr signal
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_set_mod_lopwr(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ bool mod_lopwr)
|
||||
{
|
||||
snprintf(fname, PATH_MAX, "%s/ac400_%d_mod_lopwr", CPLD_PATH,
|
||||
get_obj_val(module_id));
|
||||
return write_signal_to_file(fname, mod_lopwr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the value of the PM_SYNC signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [out] pm_sync A pointer to a bool to place the current pm_sync value.
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_get_pm_sync(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Out_ bool *pm_sync)
|
||||
{
|
||||
snprintf(fname, PATH_MAX, "%s/ac400_%d_pm_sync", CPLD_PATH,
|
||||
get_obj_val(module_id));
|
||||
return read_signal_from_file(fname, pm_sync);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the value of the PM_SYNC signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] pm_sync The value to set the pm_sync signal
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_set_pm_sync(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ bool pm_sync)
|
||||
{
|
||||
snprintf(fname, PATH_MAX, "%s/ac400_%d_pm_sync", CPLD_PATH,
|
||||
get_obj_val(module_id));
|
||||
return write_signal_to_file(fname, pm_sync);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the value of the RESET signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [out] reset A pointer to a bool to place the current reset value.
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_get_reset(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Out_ bool *reset)
|
||||
{
|
||||
snprintf(fname, PATH_MAX, "%s/reset_ac400_%d", CPLD_PATH,
|
||||
get_obj_val(module_id));
|
||||
return read_signal_from_file(fname, reset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the value of the RESET signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] reset The value to set the reset signal
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_set_reset(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ bool reset)
|
||||
{
|
||||
snprintf(fname, PATH_MAX, "%s/reset_ac400_%d", CPLD_PATH,
|
||||
get_obj_val(module_id));
|
||||
return write_signal_to_file(fname, reset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the value of the POWER signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [out] power A pointer to a bool to place the current power value.
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_get_power(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_Out_ bool *power)
|
||||
{
|
||||
snprintf(fname, PATH_MAX, "%s/pwr_ac400_%d", CPLD_PATH,
|
||||
get_obj_val(module_id));
|
||||
return read_signal_from_file(fname, power);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the value of the POWER signal
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] power The value to set the power signal
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_set_power(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ bool power)
|
||||
{
|
||||
snprintf(fname, PATH_MAX, "%s/pwr_ac400_%d", CPLD_PATH,
|
||||
get_obj_val(module_id));
|
||||
return write_signal_to_file(fname, power);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the value of the MDIO device_type
|
||||
*
|
||||
* @param [out] type A pointer to an int to place the current MDIO device_type.
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_get_device_type(
|
||||
_Out_ int *type)
|
||||
{
|
||||
snprintf(fname, PATH_MAX, "%s/mdio_device_type", CPLD_PATH);
|
||||
return read_int_from_file(fname, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the value of the MDIO device_type
|
||||
*
|
||||
* @param [in] type The value to set the MDIO device type
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_set_device_type(
|
||||
_In_ int type)
|
||||
{
|
||||
snprintf(fname, PATH_MAX, "%s/mdio_device_type", CPLD_PATH);
|
||||
return write_int_to_file(fname, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Perform an MDIO read from the AC400 module
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] reg The MDIO address of the register to read
|
||||
* @param [out] value A pointer to a u16 to place the value read from the AC400
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_mdio_read(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ uint16_t reg,
|
||||
_Out_ uint16_t *value)
|
||||
{
|
||||
int ret;
|
||||
int intval;
|
||||
|
||||
snprintf(fname, PATH_MAX, "%s/mdio_%d_address", CPLD_PATH,
|
||||
get_obj_val(module_id));
|
||||
ret = write_int_to_file(fname, reg);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
snprintf(fname, PATH_MAX, "%s/mdio_%d_data", CPLD_PATH,
|
||||
get_obj_val(module_id));
|
||||
ret = read_int_from_file(fname, &intval);
|
||||
*value = (uint16_t)intval;
|
||||
|
||||
if (reg != 0xb016) {
|
||||
TAI_SYSLOG_DEBUG("ac400_mdio_read: module %d reg 0x%04x value 0x%04x", get_obj_val(module_id), reg, *value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Perform an MDIO write to the AC400 module
|
||||
*
|
||||
* @param [in] module_id The module ID of the module being accessed
|
||||
* @param [in] reg The MDIO address of the register to write
|
||||
* @param [out] value A u16 value to write to the AC400
|
||||
*
|
||||
* @return 0 on success, or a Linux error code on failure.
|
||||
*/
|
||||
int ac400_mdio_write(
|
||||
_In_ tai_object_id_t module_id,
|
||||
_In_ uint16_t reg,
|
||||
_In_ uint16_t value)
|
||||
{
|
||||
int ret;
|
||||
|
||||
TAI_SYSLOG_DEBUG("ac400_mdio_write: module %d reg 0x%04x value 0x%04x", get_obj_val(module_id), reg, value);
|
||||
snprintf(fname, PATH_MAX, "%s/mdio_%d_address", CPLD_PATH,
|
||||
get_obj_val(module_id));
|
||||
ret = write_int_to_file(fname, reg);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
snprintf(fname, PATH_MAX, "%s/mdio_%d_data", CPLD_PATH,
|
||||
get_obj_val(module_id));
|
||||
return write_int_to_file(fname, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Validate the module location and initialize the module_id handle.
|
||||
*
|
||||
* @param [in] mod_addr A pointer to a #tai_char_list_t (string) which gives the
|
||||
* module index, either "1" or "2".
|
||||
* @param [out] module_id A pointer to the object id for the module object.
|
||||
*
|
||||
* @return 0 on success, or -1 on failure.
|
||||
*/
|
||||
int ac400_set_module_id(_In_ const tai_attribute_value_t * mod_addr,
|
||||
_Out_ tai_object_id_t * module_id)
|
||||
{
|
||||
ac400_object_id_t *ac400_obj = (ac400_object_id_t *)module_id;
|
||||
|
||||
if (!strcmp(mod_addr->charlist.list, "1")) {
|
||||
ac400_obj->type = TAI_OBJECT_TYPE_MODULE;
|
||||
ac400_obj->value = 1;
|
||||
}
|
||||
else if (!strcmp(mod_addr->charlist.list, "2")) {
|
||||
ac400_obj->type = TAI_OBJECT_TYPE_MODULE;
|
||||
ac400_obj->value = 2;
|
||||
}
|
||||
else {
|
||||
TAI_SYSLOG_ERROR("Invalid Module Location value for Voyager.");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Given a module_id, return the module location.
|
||||
*
|
||||
* @param [in] module_id A module object id.
|
||||
* @param [out] location A pointer to location where the module location will be
|
||||
* stored.
|
||||
*/
|
||||
void ac400_get_module_location(_In_ tai_object_id_t module_id,
|
||||
_Out_ char * location)
|
||||
{
|
||||
ac400_object_id_t *ac400_obj = (ac400_object_id_t *)&module_id;
|
||||
sprintf(location, "%d", ac400_obj->value);
|
||||
}
|
||||
9
tai_ac400/tai_interface.ver
Normal file
9
tai_ac400/tai_interface.ver
Normal file
@@ -0,0 +1,9 @@
|
||||
# In this file we track the current API version
|
||||
# of the TAI specification.
|
||||
# The version is built of the following
|
||||
# tree numbers:
|
||||
# MAJOR:MINOR:REV
|
||||
# MAJOR - API has completely changed
|
||||
# MINOR - API changes require code fixing
|
||||
# REV - API is compatible with previous versions
|
||||
LIBVERSION=1:0:0
|
||||
Reference in New Issue
Block a user